From aed7432bb2d918d61d429154e973f050bb9a98ca Mon Sep 17 00:00:00 2001 From: Steffen Mecke Date: Tue, 4 Sep 2018 16:41:46 +0200 Subject: [PATCH 001/160] fix magic resistance (bug 2480) --- scripts/tests/e2/spells.lua | 13 +++++++++++++ src/battle.c | 1 - 2 files changed, 13 insertions(+), 1 deletion(-) diff --git a/scripts/tests/e2/spells.lua b/scripts/tests/e2/spells.lua index a9f49d2b8..6a34d98db 100644 --- a/scripts/tests/e2/spells.lua +++ b/scripts/tests/e2/spells.lua @@ -136,3 +136,16 @@ function test_familiar_lynx() assert_equal(1, u:get_skill('magic')) assert_equal(1, u:get_skill('perception')) end + +function test_bug_2480() + local r = region.create(0, 0, "plain") + local f = faction.create("human", "hodor@eressea.de", "de") + local u1 = unit.create(f, r, 1) + local monster = unit.create(get_monsters(), r, 1, "wyrm") + u1.number = 30 + u1.hp = u1.hp_max * u1.number + monster:add_order("ATTACK " .. itoa36(u1.id)) + process_orders() + assert_equal(0, u1.number); + write_reports() +end diff --git a/src/battle.c b/src/battle.c index 9e2f841c0..64808747d 100644 --- a/src/battle.c +++ b/src/battle.c @@ -1169,7 +1169,6 @@ terminate(troop dt, troop at, int type, const char *damage, bool missile) } if (magic) { - res = frac_sub(frac_one, res); res = frac_mul(frac_make(da, 1), res); da = res.sa[0] / res.sa[1]; } From 062abe81026a6afd03950980764dda45184eb023 Mon Sep 17 00:00:00 2001 From: Enno Rehling Date: Sun, 9 Sep 2018 17:10:18 +0200 Subject: [PATCH 002/160] refactor siege property w. getter/setter --- src/battle.c | 6 ++---- src/creport.c | 8 ++++++-- src/economy.c | 2 ++ src/kernel/building.c | 11 +++++++++++ src/kernel/building.h | 5 ++++- src/kernel/unit.c | 8 +++++--- src/laws.c | 9 +++++++-- src/laws.test.c | 3 ++- src/report.c | 16 +++++++++------- src/settings.h | 12 ------------ src/study.h | 1 + src/wormhole.c | 1 - 12 files changed, 49 insertions(+), 33 deletions(-) diff --git a/src/battle.c b/src/battle.c index 9e2f841c0..3f61269a0 100644 --- a/src/battle.c +++ b/src/battle.c @@ -100,9 +100,7 @@ typedef enum combatmagic { #define MINSPELLRANGE 1 #define MAXSPELLRANGE 7 -#ifndef ROW_FACTOR -# define ROW_FACTOR 10 -#endif +#define ROW_FACTOR 3 /* factor for combat row advancement rule */ #define EFFECT_PANIC_SPELL 0.25 #define TROLL_REGENERATION 0.10 @@ -161,7 +159,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; diff --git a/src/creport.c b/src/creport.c index 91d56ca3b..137259083 100644 --- a/src/creport.c +++ b/src/creport.c @@ -645,6 +645,7 @@ static void cr_output_building(struct stream *out, building *b, const unit *owner, int fno, faction *f) { const char *bname, *billusion; + int i; stream_printf(out, "BURG %d\n", b->no); @@ -673,9 +674,12 @@ static void cr_output_building(struct stream *out, building *b, if (fno >= 0) { stream_printf(out, "%d;Partei\n", fno); } - if (b->besieged) { - stream_printf(out, "%d;Belagerer\n", b->besieged); + + i = building_get_siege(b); + if (i) { + stream_printf(out, "%d;Belagerer\n", i); } + cr_output_curses(out, f, b, TYP_BUILDING); } diff --git a/src/economy.c b/src/economy.c index baba6c1ac..cc611d49d 100644 --- a/src/economy.c +++ b/src/economy.c @@ -103,6 +103,8 @@ static void recruit_init(void) } } +#define ENTERTAINFRACTION 20 + int entertainmoney(const region * r) { double n; diff --git a/src/kernel/building.c b/src/kernel/building.c index 75cad30f7..9dfc7db35 100644 --- a/src/kernel/building.c +++ b/src/kernel/building.c @@ -870,3 +870,14 @@ int cmp_current_owner(const building * b, const building * a) } return 0; } + +int building_get_siege(const struct building *b) +{ + return b->_besieged; +} + +int building_add_siege(struct building *b, int delta) +{ + b->_besieged += delta; + return b->_besieged; +} diff --git a/src/kernel/building.h b/src/kernel/building.h index eacf42942..319304d79 100644 --- a/src/kernel/building.h +++ b/src/kernel/building.h @@ -118,7 +118,7 @@ extern "C" { int no; int size; int sizeleft; /* is only used during battle. should be a temporary attribute */ - int besieged; /* should be an attribute */ + int _besieged; /* should be an attribute */ int flags; } building; @@ -134,6 +134,9 @@ extern "C" { int id, int size, struct order *ord); bool building_finished(const struct building *b); + int building_get_siege(const struct building *b); + int building_add_siege(struct building *b, int delta); + int wage(const struct region *r, const struct faction *f, const struct race *rc, int in_turn); diff --git a/src/kernel/unit.c b/src/kernel/unit.c index 770723bea..146761f05 100644 --- a/src/kernel/unit.c +++ b/src/kernel/unit.c @@ -1917,9 +1917,11 @@ int getunit(const region * r, const faction * f, unit **uresult) int besieged(const unit * u) { /* belagert kann man in schiffen und burgen werden */ - return (u && !keyword_disabled(K_BESIEGE) - && u->building && u->building->besieged - && u->building->besieged >= u->building->size * SIEGEFACTOR); + if (u && !keyword_disabled(K_BESIEGE) && u->building) { + building * b = u->building; + return building_get_siege(b) >= b->size * SIEGEFACTOR; + } + return false; } bool has_horses(const unit * u) diff --git a/src/laws.c b/src/laws.c index 68f2894b3..67a44c673 100644 --- a/src/laws.c +++ b/src/laws.c @@ -306,6 +306,11 @@ static void calculate_emigration(region * r) } } +/* Vermehrungsrate Bauern in 1/10000. +* TODO: Evt. Berechnungsfehler, reale Vermehrungsraten scheinen hoeher. */ +#define PEASANTGROWTH 10 +#define PEASANTLUCK 10 +#define PEASANTFORCE 0.75 /* Chance einer Vermehrung trotz 90% Auslastung */ static double peasant_growth_factor(void) { @@ -908,7 +913,7 @@ static int slipthru(const region * r, const unit * u, const building * b) int n, o; /* b ist die burg, in die man hinein oder aus der man heraus will. */ - if (b == NULL || b->besieged < b->size * SIEGEFACTOR) { + if (b == NULL || building_get_siege(b) < b->size * SIEGEFACTOR) { return 1; } @@ -3857,7 +3862,7 @@ int siege_cmd(unit * u, order * ord) usetsiege(u, b); if (katapultiere < bewaffnete) katapultiere = bewaffnete; - b->besieged += katapultiere; + building_add_siege(b, katapultiere); /* definitiver schaden eingeschraenkt */ if (d > b->size - 1) d = b->size - 1; diff --git a/src/laws.test.c b/src/laws.test.c index c7c7a6682..fb644dc90 100644 --- a/src/laws.test.c +++ b/src/laws.test.c @@ -113,7 +113,8 @@ static void test_contact(CuTest * tc) u3 = test_create_unit(test_create_faction(NULL), r); set_level(u3, SK_PERCEPTION, 2); usetsiege(u3, b); - b->besieged = 1; + building_add_siege(b, 1); + CuAssertIntEquals(tc, 1, building_get_siege(b)); CuAssertIntEquals(tc, 1, can_contact(r, u1, u2)); u_set_building(u1, b); diff --git a/src/report.c b/src/report.c index 9f1bfa4bd..7de2550a4 100644 --- a/src/report.c +++ b/src/report.c @@ -1853,14 +1853,16 @@ nr_building(struct stream *out, const region *r, const building *b, const factio sbs_strcat(&sbs, LOC(lang, "nr_building_inprogress")); } - if (b->besieged > 0 && r->seen.mode >= seen_lighthouse) { - msg = msg_message("nr_building_besieged", "soldiers diff", b->besieged, - b->besieged - b->size * SIEGEFACTOR); + if (!keyword_disabled(K_BESIEGE) && r->seen.mode >= seen_lighthouse) { + int s = building_get_siege(b); + if (s > 0) { + msg = msg_message("nr_building_besieged", "soldiers diff", s, + s - b->size * SIEGEFACTOR); + size = nr_render(msg, lang, sbs.end, sbs.size - (sbs.end - sbs.begin), f); + sbs.end += size; - size = nr_render(msg, lang, sbs.end, sbs.size - (sbs.end - sbs.begin), f); - sbs.end += size; - - msg_release(msg); + msg_release(msg); + } } i = 0; if (b->display && b->display[0]) { diff --git a/src/settings.h b/src/settings.h index 57edb1566..498786be9 100644 --- a/src/settings.h +++ b/src/settings.h @@ -10,23 +10,11 @@ without prior permission by the authors of Eressea. */ -#define ENTERTAINFRACTION 20 -#define TEACHDIFFERENCE 2 #define RESOURCE_QUANTITY 0.5 #define RECRUITFRACTION 40 /* 100/RECRUITFRACTION% */ -#define COMBAT_TURNS 5 -#undef NEWATSROI - -/* Vermehrungsrate Bauern in 1/10000. -* TODO: Evt. Berechnungsfehler, reale Vermehrungsraten scheinen hoeher. */ -#define PEASANTGROWTH 10 -#define PEASANTLUCK 10 - -#define ROW_FACTOR 3 /* factor for combat row advancement rule */ /* TODO: move these settings to settings.h or into configuration files */ #define TREESIZE (8) /* space used by trees (in #peasants) */ -#define PEASANTFORCE 0.75 /* Chance einer Vermehrung trotz 90% Auslastung */ /* Gebaeudegroesse = Minimalbelagerer */ #define SIEGEFACTOR 2 diff --git a/src/study.h b/src/study.h index cca0428b7..686677064 100644 --- a/src/study.h +++ b/src/study.h @@ -31,6 +31,7 @@ extern "C" { #define STUDYDAYS 30 #define TEACHNUMBER 10 +#define TEACHDIFFERENCE 2 typedef struct teaching_info { struct selist *teachers; diff --git a/src/wormhole.c b/src/wormhole.c index 197fc346d..2000018ab 100644 --- a/src/wormhole.c +++ b/src/wormhole.c @@ -12,7 +12,6 @@ #include #include -#include "settings.h" #include "wormhole.h" From 2e5e8347aca8b3643139dc3d6a1ad2e16d2fcdd1 Mon Sep 17 00:00:00 2001 From: Enno Rehling Date: Sun, 9 Sep 2018 21:01:10 +0200 Subject: [PATCH 003/160] Bug 2489: Kill the SIEGE command, forever. --- conf/e3/config.json | 1 - conf/keywords.json | 1 - res/core/messages.xml | 55 ---------- res/translations/messages.de.po | 24 ----- res/translations/messages.en.po | 24 ----- res/translations/strings.de.po | 4 - res/translations/strings.en.po | 4 - scripts/tests/bindings.lua | 1 - src/attributes/attributes.c | 9 +- src/battle.c | 11 -- src/bind_process.c | 4 - src/creport.c | 10 -- src/economy.c | 33 ------ src/guard.c | 2 - src/jsonconf.test.c | 6 +- src/kernel/build.c | 13 --- src/kernel/building.c | 11 -- src/kernel/building.h | 4 - src/kernel/order.c | 3 - src/kernel/unit.c | 64 ------------ src/kernel/unit.h | 5 - src/keyword.c | 2 +- src/keyword.h | 2 +- src/laws.c | 177 +------------------------------- src/laws.h | 2 - src/laws.test.c | 33 ------ src/process.pkg | 1 - src/process.pkg.c | 25 ----- src/report.c | 12 --- src/reports.c | 6 -- src/spy.c | 4 - src/spy.test.c | 6 +- src/steal.c | 4 - 33 files changed, 16 insertions(+), 547 deletions(-) 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/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..47d70ecc0 100644 --- a/res/translations/strings.de.po +++ b/res/translations/strings.de.po @@ -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/scripts/tests/bindings.lua b/scripts/tests/bindings.lua index 9aab6fd57..5820e0a47 100644 --- a/scripts/tests/bindings.lua +++ b/scripts/tests/bindings.lua @@ -31,7 +31,6 @@ function test_process() assert_equal("function", _G.type(eressea.process.movement)) assert_equal("function", _G.type(eressea.process.use)) assert_equal("function", _G.type(eressea.process.battle)) - assert_equal("function", _G.type(eressea.process.siege)) assert_equal("function", _G.type(eressea.process.leave)) assert_equal("function", _G.type(eressea.process.promote)) assert_equal("function", _G.type(eressea.process.restack)) diff --git a/src/attributes/attributes.c b/src/attributes/attributes.c index fa6f15d73..6bf78da63 100644 --- a/src/attributes/attributes.c +++ b/src/attributes/attributes.c @@ -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/battle.c b/src/battle.c index 3f61269a0..1e256f9ca 100644 --- a/src/battle.c +++ b/src/battle.c @@ -3577,17 +3577,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)) { diff --git a/src/bind_process.c b/src/bind_process.c index 947458ce5..58f90076f 100755 --- a/src/bind_process.c +++ b/src/bind_process.c @@ -76,10 +76,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/creport.c b/src/creport.c index 137259083..ce67493da 100644 --- a/src/creport.c +++ b/src/creport.c @@ -645,7 +645,6 @@ static void cr_output_building(struct stream *out, building *b, const unit *owner, int fno, faction *f) { const char *bname, *billusion; - int i; stream_printf(out, "BURG %d\n", b->no); @@ -675,11 +674,6 @@ static void cr_output_building(struct stream *out, building *b, stream_printf(out, "%d;Partei\n", fno); } - i = building_get_siege(b); - if (i) { - stream_printf(out, "%d;Belagerer\n", i); - } - cr_output_curses(out, f, b, TYP_BUILDING); } @@ -784,7 +778,6 @@ void cr_output_unit(stream *out, const faction * f, const item_type *lasttype; int pr; item *itm, *show = NULL; - building *b; const char *pzTmp; skill *sv; item result[MAX_INVENTORY]; @@ -883,9 +876,6 @@ void cr_output_unit(stream *out, const faction * f, if (is_guard(u)) { stream_printf(out, "%d;bewacht\n", 1); } - if ((b = usiege(u)) != NULL) { - stream_printf(out, "%d;belagert\n", b->no); - } /* additional information for own units */ if (u->faction == f || omniscient(f)) { order *ord; diff --git a/src/economy.c b/src/economy.c index cc611d49d..f0c930a3f 100644 --- a/src/economy.c +++ b/src/economy.c @@ -980,11 +980,6 @@ static void allocate_resource(unit * u, const resource_type * rtype, int want) } } - if (besieged(u)) { - cmistake(u, u->thisorder, 60, MSG_PRODUCE); - return; - } - if (rtype->modifiers) { message *msg = get_modifiers(u, sk, rtype, &save_mod, &skill_mod); if (msg) { @@ -1606,11 +1601,6 @@ static void buy(unit * u, econ_request ** buyorders, struct order *ord) cmistake(u, ord, 26, MSG_COMMERCE); return; } - if (besieged(u)) { - /* Belagerte Einheiten k�nnen nichts kaufen. */ - cmistake(u, ord, 60, MSG_COMMERCE); - return; - } /* Entweder man ist Insekt in Sumpf/Wueste, oder es muss * einen Handelsposten in der Region geben: */ @@ -1930,12 +1920,6 @@ static bool sell(unit * u, econ_request ** sellorders, struct order *ord) return false; } } - /* Belagerte Einheiten k�nnen nichts verkaufen. */ - - if (besieged(u)) { - ADDMSG(&u->faction->msgs, msg_feedback(u, ord, "error60", "")); - return false; - } /* In der Region mu� es eine Burg geben. */ if (u_race(u) == get_race(RC_INSECT)) { @@ -2409,10 +2393,6 @@ void entertain_cmd(unit * u, struct order *ord) cmistake(u, ord, 58, MSG_INCOME); return; } - if (besieged(u)) { - cmistake(u, ord, 60, MSG_INCOME); - return; - } if (u->ship && is_guarded(r, u)) { cmistake(u, ord, 69, MSG_INCOME); return; @@ -2501,11 +2481,6 @@ static int do_work(unit * u, order * ord, econ_request * o) cmistake(u, ord, 313, MSG_INCOME); return -1; } - if (besieged(u)) { - if (ord) - cmistake(u, ord, 60, MSG_INCOME); - return -1; - } if (u->ship && is_guarded(r, u)) { if (ord) cmistake(u, ord, 69, MSG_INCOME); @@ -2614,10 +2589,6 @@ void tax_cmd(unit * u, struct order *ord, econ_request ** taxorders) return; } - if (besieged(u)) { - cmistake(u, ord, 60, MSG_INCOME); - return; - } n = armedmen(u, false); if (!n) { @@ -2688,10 +2659,6 @@ void loot_cmd(unit * u, struct order *ord, econ_request ** lootorders) return; } - if (besieged(u)) { - cmistake(u, ord, 60, MSG_INCOME); - return; - } n = armedmen(u, false); if (!n) { diff --git a/src/guard.c b/src/guard.c index 118ede5fc..468dd99bc 100644 --- a/src/guard.c +++ b/src/guard.c @@ -105,8 +105,6 @@ static bool is_guardian_r(const unit * guard) { if (guard->number == 0) return false; - if (besieged(guard)) - return false; /* if region_owners exist then they may be guardians: */ if (guard->building && rule_region_owners() && guard == building_owner(guard->building)) { diff --git a/src/jsonconf.test.c b/src/jsonconf.test.c index 7c15b63f1..9e0e8f6b6 100644 --- a/src/jsonconf.test.c +++ b/src/jsonconf.test.c @@ -120,7 +120,7 @@ static void test_disable(CuTest * tc) const char * data = "{\"disabled\": [ " "\"alchemy\"," "\"pay\"," - "\"besiege\"," + "\"attack\"," "\"module\"" "]}"; cJSON *json = cJSON_Parse(data); @@ -129,13 +129,13 @@ static void test_disable(CuTest * tc) CuAssertTrue(tc, skill_enabled(SK_ALCHEMY)); CuAssertTrue(tc, !keyword_disabled(K_BANNER)); CuAssertTrue(tc, !keyword_disabled(K_PAY)); - CuAssertTrue(tc, !keyword_disabled(K_BESIEGE)); + CuAssertTrue(tc, !keyword_disabled(K_ATTACK)); CuAssertIntEquals(tc, 1, config_get_int("module.enabled", 1)); json_config(json); CuAssertTrue(tc, !skill_enabled(SK_ALCHEMY)); CuAssertTrue(tc, !keyword_disabled(K_BANNER)); CuAssertTrue(tc, keyword_disabled(K_PAY)); - CuAssertTrue(tc, keyword_disabled(K_BESIEGE)); + CuAssertTrue(tc, keyword_disabled(K_ATTACK)); CuAssertIntEquals(tc, 0, config_get_int("module.enabled", 1)); cJSON_Delete(json); test_teardown(); diff --git a/src/kernel/build.c b/src/kernel/build.c index 11324f752..4e3dc4721 100644 --- a/src/kernel/build.c +++ b/src/kernel/build.c @@ -279,10 +279,6 @@ void build_road(unit * u, int size, direction_t d) cmistake(u, u->thisorder, 103, MSG_PRODUCE); return; } - if (besieged(u)) { - cmistake(u, u->thisorder, 60, MSG_PRODUCE); - return; - } if (rn == NULL || rn->terrain->max_road < 0) { cmistake(u, u->thisorder, 94, MSG_PRODUCE); @@ -780,11 +776,6 @@ build_building(unit * u, const building_type * btype, int id, int want, order * cmistake(u, ord, 93, MSG_PRODUCE); return 0; } - if (besieged(u)) { - /* units under siege can not build */ - cmistake(u, ord, 60, MSG_PRODUCE); - return 0; - } if (btype->flags & BTF_NOBUILD) { /* special building, cannot be built */ cmistake(u, ord, 221, MSG_PRODUCE); @@ -949,10 +940,6 @@ create_ship(unit * u, const struct ship_type *newtype, int want, cmistake(u, ord, 100, MSG_PRODUCE); return; } - if (besieged(u)) { - cmistake(u, ord, 60, MSG_PRODUCE); - return; - } /* check if skill and material for 1 size is available */ if (effskill(u, cons->skill, 0) < cons->minskill) { diff --git a/src/kernel/building.c b/src/kernel/building.c index 9dfc7db35..75cad30f7 100644 --- a/src/kernel/building.c +++ b/src/kernel/building.c @@ -870,14 +870,3 @@ int cmp_current_owner(const building * b, const building * a) } return 0; } - -int building_get_siege(const struct building *b) -{ - return b->_besieged; -} - -int building_add_siege(struct building *b, int delta) -{ - b->_besieged += delta; - return b->_besieged; -} diff --git a/src/kernel/building.h b/src/kernel/building.h index 319304d79..af605b448 100644 --- a/src/kernel/building.h +++ b/src/kernel/building.h @@ -118,7 +118,6 @@ extern "C" { int no; int size; int sizeleft; /* is only used during battle. should be a temporary attribute */ - int _besieged; /* should be an attribute */ int flags; } building; @@ -134,9 +133,6 @@ extern "C" { int id, int size, struct order *ord); bool building_finished(const struct building *b); - int building_get_siege(const struct building *b); - int building_add_siege(struct building *b, int delta); - int wage(const struct region *r, const struct faction *f, const struct race *rc, int in_turn); diff --git a/src/kernel/order.c b/src/kernel/order.c index c14a2b30b..2fd7c6eb8 100644 --- a/src/kernel/order.c +++ b/src/kernel/order.c @@ -373,7 +373,6 @@ bool is_repeated(keyword_t kwd) case K_ROUTE: case K_DRIVE: case K_WORK: - case K_BESIEGE: case K_ENTERTAIN: case K_TAX: case K_RESEARCH: @@ -414,7 +413,6 @@ bool is_exclusive(const order * ord) case K_ROUTE: case K_DRIVE: case K_WORK: - case K_BESIEGE: case K_ENTERTAIN: case K_TAX: case K_RESEARCH: @@ -456,7 +454,6 @@ bool is_long(keyword_t kwd) case K_ROUTE: case K_DRIVE: case K_WORK: - case K_BESIEGE: case K_ENTERTAIN: case K_TAX: case K_RESEARCH: diff --git a/src/kernel/unit.c b/src/kernel/unit.c index 146761f05..30971310d 100644 --- a/src/kernel/unit.c +++ b/src/kernel/unit.c @@ -530,60 +530,6 @@ attrib_type at_target = { NO_READ }; -/*********************/ -/* at_siege */ -/*********************/ - -void a_writesiege(const variant *var, const void *owner, struct storage *store) -{ - struct building *b = (struct building *)var->v; - write_building_reference(b, store); -} - -int a_readsiege(variant *var, void *owner, gamedata *data) -{ - if (read_building_reference(data, (building **)&var->v, NULL) <= 0) { - return AT_READ_FAIL; - } - return AT_READ_OK; -} - -attrib_type at_siege = { - "siege", - DEFAULT_INIT, - DEFAULT_FINALIZE, - DEFAULT_AGE, - a_writesiege, - a_readsiege -}; - -struct building *usiege(const unit * u) -{ - attrib *a; - if (!fval(u, UFL_SIEGE)) - return NULL; - a = a_find(u->attribs, &at_siege); - assert(a || !"flag set, but no siege found"); - return (struct building *)a->data.v; -} - -void usetsiege(unit * u, const struct building *t) -{ - attrib *a = a_find(u->attribs, &at_siege); - if (!a && t) - a = a_add(&u->attribs, a_new(&at_siege)); - if (a) { - if (!t) { - a_remove(&u->attribs, a); - freset(u, UFL_SIEGE); - } - else { - a->data.v = (void *)t; - fset(u, UFL_SIEGE); - } - } -} - /*********************/ /* at_contact */ /*********************/ @@ -1914,16 +1860,6 @@ int getunit(const region * r, const faction * f, unit **uresult) return result; } -int besieged(const unit * u) -{ - /* belagert kann man in schiffen und burgen werden */ - if (u && !keyword_disabled(K_BESIEGE) && u->building) { - building * b = u->building; - return building_get_siege(b) >= b->size * SIEGEFACTOR; - } - return false; -} - bool has_horses(const unit * u) { item *itm = u->items; diff --git a/src/kernel/unit.h b/src/kernel/unit.h index a6135715c..3f82ef80a 100644 --- a/src/kernel/unit.h +++ b/src/kernel/unit.h @@ -47,7 +47,6 @@ extern "C" { #define UFL_NOTMOVING (1<<9) /* Die Einheit kann sich wg. langen Kampfes nicht bewegen */ #define UFL_DEFENDER (1<<10) #define UFL_HUNGER (1<<11) /* kann im Folgemonat keinen langen Befehl außer ARBEITE ausführen */ -#define UFL_SIEGE (1<<12) /* speedup: belagert eine burg, siehe attribut */ #define UFL_TARGET (1<<13) /* speedup: hat ein target, siehe attribut */ #define UFL_WERE (1<<14) #define UFL_ENTER (1<<15) /* unit has entered a ship/building and will not leave it */ @@ -121,7 +120,6 @@ extern "C" { extern struct attrib_type at_creator; extern struct attrib_type at_alias; - extern struct attrib_type at_siege; extern struct attrib_type at_target; extern struct attrib_type at_potionuser; extern struct attrib_type at_contact; @@ -138,8 +136,6 @@ extern "C" { const struct race *u_irace(const struct unit *u); const struct race *u_race(const struct unit *u); void u_setrace(struct unit *u, const struct race *); - struct building *usiege(const struct unit *u); - void usetsiege(struct unit *u, const struct building *b); const char *uprivate(const struct unit *u); void usetprivate(struct unit *u, const char *c); @@ -257,7 +253,6 @@ extern "C" { int read_unitid(const struct faction *f, const struct region *r); /* !< sets combatstatus of a unit */ - int besieged(const struct unit *u); bool has_horses(const struct unit *u); int maintenance_cost(const struct unit *u); bool has_limited_skills(const struct unit *u); diff --git a/src/keyword.c b/src/keyword.c index 48726bcbc..47fcc3c8e 100644 --- a/src/keyword.c +++ b/src/keyword.c @@ -94,7 +94,7 @@ const char *keywords[MAXKEYWORDS] = { "work", "attack", "steal", - "besiege", + "deprecated_besiege", "name", "use", "describe", diff --git a/src/keyword.h b/src/keyword.h index 6e4832708..bd4ab02d0 100644 --- a/src/keyword.h +++ b/src/keyword.h @@ -17,7 +17,7 @@ extern "C" K_WORK, K_ATTACK, K_STEAL, - K_BESIEGE, + K_BESIEGE_UNUSED, K_NAME, K_USE, K_DISPLAY, diff --git a/src/laws.c b/src/laws.c index 67a44c673..0e9285281 100644 --- a/src/laws.c +++ b/src/laws.c @@ -901,61 +901,6 @@ void demographics(void) immigration(); } -/* ------------------------------------------------------------- */ - -/* test if the unit can slip through a siege undetected. - * returns 0 if siege is successful, or 1 if the building is either - * not besieged or the unit can slip through the siege due to better stealth. - */ -static int slipthru(const region * r, const unit * u, const building * b) -{ - unit *u2; - int n, o; - - /* b ist die burg, in die man hinein oder aus der man heraus will. */ - if (b == NULL || building_get_siege(b) < b->size * SIEGEFACTOR) { - return 1; - } - - /* u wird am hinein- oder herausschluepfen gehindert, wenn STEALTH <= - * OBSERVATION +2 der belagerer u2 ist */ - n = effskill(u, SK_STEALTH, r); - - for (u2 = r->units; u2; u2 = u2->next) { - if (usiege(u2) == b) { - - if (invisible(u, u2) >= u->number) - continue; - - o = effskill(u2, SK_PERCEPTION, r); - - if (o + 2 >= n) { - return 0; /* entdeckt! */ - } - } - } - return 1; -} - -int can_contact(const region * r, const unit * u, const unit * u2) { - - /* hier geht es nur um die belagerung von burgen */ - UNUSED_ARG(r); - if (u->building == u2->building) { - return 1; - } - - /* unit u is trying to contact u2 - unasked for contact. wenn u oder u2 - * nicht in einer burg ist, oder die burg nicht belagert ist, ist - * slipthru () == 1. ansonsten ist es nur 1, wenn man die belagerer */ - - if (slipthru(u->region, u, u->building) && slipthru(u->region, u2, u2->building)) { - return 1; - } - - return (alliedunit(u, u2->faction, HELP_GIVE)); -} - int contact_cmd(unit * u, order * ord) { unit *u2; @@ -966,10 +911,6 @@ int contact_cmd(unit * u, order * ord) u2 = findunit(n); if (u2 != NULL) { - if (!can_contact(u->region, u, u2)) { - cmistake(u, u->thisorder, 23, MSG_EVENT); - return -1; - } usetcontact(u, u2); } return 0; @@ -994,13 +935,7 @@ int leave_cmd(unit * u, struct order *ord) return 0; } } - if (!slipthru(r, u, u->building)) { - ADDMSG(&u->faction->msgs, msg_feedback(u, u->thisorder, "entrance_besieged", - "building", u->building)); - } - else { - leave(u, true); - } + leave(u, true); return 0; } @@ -1148,13 +1083,6 @@ int enter_building(unit * u, order * ord, int id, bool report) } return 0; } - if (!slipthru(r, u, b)) { - if (report) { - ADDMSG(&u->faction->msgs, msg_feedback(u, ord, "entrance_besieged", - "building", b)); - } - return 0; - } if (leave(u, 0)) { fset(u, UFL_ENTER); @@ -3804,98 +3732,6 @@ int armedmen(const unit * u, bool siege_weapons) return n; } -int siege_cmd(unit * u, order * ord) -{ - region *r = u->region; - building *b; - int d, pooled; - int bewaffnete, katapultiere = 0; - resource_type *rt_catapultammo = NULL; - resource_type *rt_catapult = NULL; - - init_order_depr(ord); - b = getbuilding(r); - - if (!b) { - cmistake(u, ord, 31, MSG_BATTLE); - return 31; - } - - if (!playerrace(u_race(u))) { - /* keine Drachen, Illusionen, Untote etc */ - cmistake(u, ord, 166, MSG_BATTLE); - return 166; - } - /* schaden durch katapulte */ - - rt_catapultammo = rt_find("catapultammo"); - rt_catapult = rt_find("catapult"); - - d = i_get(u->items, rt_catapult->itype); - if (d > u->number) d = u->number; - pooled = get_pooled(u, rt_catapultammo, GET_DEFAULT, d); - if (d > pooled) d = pooled; - if (effskill(u, SK_CATAPULT, 0) >= 1) { - katapultiere = d; - d *= effskill(u, SK_CATAPULT, 0); - } - else { - d = 0; - } - - bewaffnete = armedmen(u, true); - if (d == 0 && bewaffnete == 0) { - /* abbruch, falls unbewaffnet oder unfaehig, katapulte zu benutzen */ - cmistake(u, ord, 80, MSG_EVENT); - return 80; - } - - if (!is_guard(u)) { - /* abbruch, wenn die einheit nicht vorher die region bewacht - als - * warnung fuer alle anderen! */ - cmistake(u, ord, 81, MSG_EVENT); - return 81; - } - /* einheit und burg markieren - spart zeit beim behandeln der einheiten - * in der burg, falls die burg auch markiert ist und nicht alle - * einheiten wieder abgesucht werden muessen! */ - - usetsiege(u, b); - if (katapultiere < bewaffnete) katapultiere = bewaffnete; - building_add_siege(b, katapultiere); - - /* definitiver schaden eingeschraenkt */ - if (d > b->size - 1) d = b->size - 1; - - /* meldung, schaden anrichten */ - if (d && !curse_active(get_curse(b->attribs, &ct_magicwalls))) { - b->size -= d; - use_pooled(u, rt_catapultammo, - GET_SLACK | GET_RESERVE | GET_POOLED_SLACK, d); - /* send message to the entire region */ - ADDMSG(&r->msgs, msg_message("siege_catapults", - "unit building destruction", u, b, d)); - } - else { - /* send message to the entire region */ - ADDMSG(&r->msgs, msg_message("siege", "unit building", u, b)); - } - return 0; -} - -void do_siege(region * r) -{ - if (fval(r->terrain, LAND_REGION)) { - unit *u; - - for (u = r->units; u; u = u->next) { - if (getkeyword(u->thisorder) == K_BESIEGE) { - siege_cmd(u, u->thisorder); - } - } - } -} - static void enter_1(region * r) { do_enter(r, 0); @@ -3979,11 +3815,6 @@ void init_processor(void) p += 10; add_proc_global(p, do_battles, "Attackieren"); - if (!keyword_disabled(K_BESIEGE)) { - p += 10; - add_proc_region(p, do_siege, "Belagern"); - } - p += 10; /* can't allow reserve before siege (weapons) */ add_proc_region(p, enter_1, "Betreten (3. Versuch)"); /* to claim a castle after a victory and to be able to DESTROY it in the same turn */ if (config_get_int("rules.reserve.twophase", 0)) { @@ -4201,7 +4032,7 @@ cansee(const faction * f, const region * r, const unit * u, int modifier) } /* simple visibility, just gotta have a viewer in the region to see 'em */ - if (leftship(u) || is_guard(u) || usiege(u) || u->building || u->ship) { + if (leftship(u) || is_guard(u) || u->building || u->ship) { return true; } @@ -4239,7 +4070,7 @@ bool cansee_unit(const unit * u, const unit * target, int modifier) else { int n, rings; - if (is_guard(target) || usiege(target) || target->building + if (is_guard(target) || target->building || target->ship) { return true; } @@ -4282,7 +4113,7 @@ cansee_durchgezogen(const faction * f, const region * r, const unit * u, else { int rings, n; - if (is_guard(u) || usiege(u) || u->building || u->ship) { + if (is_guard(u) || u->building || u->ship) { return true; } diff --git a/src/laws.h b/src/laws.h index 0b5db17c7..b7958891f 100755 --- a/src/laws.h +++ b/src/laws.h @@ -48,7 +48,6 @@ extern "C" { bool renamed_building(const struct building * b); int rename_building(struct unit * u, struct order * ord, struct building * b, const char *name); void get_food(struct region * r); - int can_contact(const struct region *r, const struct unit *u, const struct unit *u2); int enter_building(struct unit *u, struct order *ord, int id, bool report); int enter_ship(struct unit *u, struct order *ord, int id, bool report); @@ -82,7 +81,6 @@ extern "C" { int quit_cmd(struct unit *u, struct order *ord); int name_cmd(struct unit *u, struct order *ord); int use_cmd(struct unit *u, struct order *ord); - int siege_cmd(struct unit *u, struct order *ord); int leave_cmd(struct unit *u, struct order *ord); int pay_cmd(struct unit *u, struct order *ord); int promotion_cmd(struct unit *u, struct order *ord); diff --git a/src/laws.test.c b/src/laws.test.c index fb644dc90..778ee3323 100644 --- a/src/laws.test.c +++ b/src/laws.test.c @@ -95,38 +95,6 @@ static void test_rename_building_twice(CuTest * tc) test_teardown(); } -static void test_contact(CuTest * tc) -{ - region *r; - unit *u1, *u2, *u3; - building *b; - building_type *btype; - ally *al; - - test_setup(); - test_create_locale(); - btype = test_create_buildingtype("castle"); - r = test_create_region(0, 0, NULL); - b = new_building(btype, r, default_locale); - u1 = test_create_unit(test_create_faction(NULL), r); - u2 = test_create_unit(test_create_faction(NULL), r); - u3 = test_create_unit(test_create_faction(NULL), r); - set_level(u3, SK_PERCEPTION, 2); - usetsiege(u3, b); - building_add_siege(b, 1); - CuAssertIntEquals(tc, 1, building_get_siege(b)); - CuAssertIntEquals(tc, 1, can_contact(r, u1, u2)); - - u_set_building(u1, b); - CuAssertIntEquals(tc, 0, can_contact(r, u1, u2)); - al = ally_add(&u1->faction->allies, u2->faction); - al->status = HELP_ALL; - CuAssertIntEquals(tc, HELP_GIVE, can_contact(r, u1, u2)); - u_set_building(u2, b); - CuAssertIntEquals(tc, 1, can_contact(r, u1, u2)); - test_teardown(); -} - static void test_enter_building(CuTest * tc) { unit *u; @@ -1833,7 +1801,6 @@ CuSuite *get_laws_suite(void) SUITE_ADD_TEST(suite, test_pay_cmd_must_be_owner); SUITE_ADD_TEST(suite, test_new_units); SUITE_ADD_TEST(suite, test_cannot_create_unit_above_limit); - SUITE_ADD_TEST(suite, test_contact); SUITE_ADD_TEST(suite, test_enter_building); SUITE_ADD_TEST(suite, test_enter_ship); SUITE_ADD_TEST(suite, test_display_cmd); diff --git a/src/process.pkg b/src/process.pkg index a81917293..89e8f2fa7 100755 --- a/src/process.pkg +++ b/src/process.pkg @@ -21,7 +21,6 @@ module eressea { void process_movement @ movement(void); /* MOVE/FOLLOW/ROUTE */ void process_use @ use(void); /* USE */ void process_battle @ battle(void); /* ATTACK */ - void process_siege @ siege(void); /* SIEGE */ void process_leave @ leave(void); /* LEAVE */ void process_maintenance @ maintenance(void); /* PAY */ void process_promote @ promote(void); /* PROMOTE */ diff --git a/src/process.pkg.c b/src/process.pkg.c index 42dff20ff..3e818f7ce 100644 --- a/src/process.pkg.c +++ b/src/process.pkg.c @@ -435,30 +435,6 @@ static int tolua_process_eressea_process_battle00(lua_State* tolua_S) #endif } -/* function: process_siege */ -static int tolua_process_eressea_process_siege00(lua_State* tolua_S) -{ -#ifndef TOLUA_RELEASE - tolua_Error tolua_err; - if ( - !tolua_isnoobj(tolua_S,1,&tolua_err) - ) - goto tolua_lerror; - else -#endif - { - { - process_siege(); - } - } - return 0; -#ifndef TOLUA_RELEASE - tolua_lerror: - tolua_error(tolua_S,"#ferror in function 'siege'.",&tolua_err); - return 0; -#endif -} - /* function: process_leave */ static int tolua_process_eressea_process_leave00(lua_State* tolua_S) { @@ -993,7 +969,6 @@ LUALIB_API int luaopen_process (lua_State* tolua_S) tolua_function(tolua_S,"movement",tolua_process_eressea_process_movement00); tolua_function(tolua_S,"use",tolua_process_eressea_process_use00); tolua_function(tolua_S,"battle",tolua_process_eressea_process_battle00); - tolua_function(tolua_S,"siege",tolua_process_eressea_process_siege00); tolua_function(tolua_S,"leave",tolua_process_eressea_process_leave00); tolua_function(tolua_S,"maintenance",tolua_process_eressea_process_maintenance00); tolua_function(tolua_S,"promote",tolua_process_eressea_process_promote00); diff --git a/src/report.c b/src/report.c index 7de2550a4..29f124cef 100644 --- a/src/report.c +++ b/src/report.c @@ -1821,7 +1821,6 @@ nr_building(struct stream *out, const region *r, const building *b, const factio const char *name, *bname, *billusion = NULL; const struct locale *lang; char buffer[8192]; - message *msg; size_t size; sbstring sbs; @@ -1853,17 +1852,6 @@ nr_building(struct stream *out, const region *r, const building *b, const factio sbs_strcat(&sbs, LOC(lang, "nr_building_inprogress")); } - if (!keyword_disabled(K_BESIEGE) && r->seen.mode >= seen_lighthouse) { - int s = building_get_siege(b); - if (s > 0) { - msg = msg_message("nr_building_besieged", "soldiers diff", s, - s - b->size * SIEGEFACTOR); - size = nr_render(msg, lang, sbs.end, sbs.size - (sbs.end - sbs.begin), f); - sbs.end += size; - - msg_release(msg); - } - } i = 0; if (b->display && b->display[0]) { sbs_strcat(&sbs, "; "); diff --git a/src/reports.c b/src/reports.c index 9d9ab5f6f..25c331a9f 100644 --- a/src/reports.c +++ b/src/reports.c @@ -683,7 +683,6 @@ bufunit(const faction * f, const unit * u, seen_mode mode, char *buf, int i, dh; int getarnt = fval(u, UFL_ANON_FACTION); const char *pzTmp, *str; - building *b; bool isbattle = (bool)(mode == seen_battle); item *itm, *show = NULL; faction *fv; @@ -807,11 +806,6 @@ bufunit(const faction * f, const unit * u, seen_mode mode, char *buf, bufp = STRLCPY(bufp, LOC(lang, "unit_guards"), size); } - if ((b = usiege(u)) != NULL) { - bufp = STRLCPY(bufp, ", belagert ", size); - bufp = STRLCPY(bufp, buildingname(b), size); - } - dh = 0; if (u->faction == f) { skill *sv; diff --git a/src/spy.c b/src/spy.c index ae70f4db8..9dc9de35a 100644 --- a/src/spy.c +++ b/src/spy.c @@ -137,10 +137,6 @@ int spy_cmd(unit * u, struct order *ord) msg_feedback(u, u->thisorder, "feedback_unit_not_found", "")); return 0; } - if (!can_contact(r, u, target)) { - cmistake(u, u->thisorder, 24, MSG_EVENT); - return 0; - } if (effskill(u, SK_SPY, 0) < 1) { cmistake(u, u->thisorder, 39, MSG_EVENT); return 0; diff --git a/src/spy.test.c b/src/spy.test.c index 0224698a0..d8b879e3f 100644 --- a/src/spy.test.c +++ b/src/spy.test.c @@ -198,17 +198,17 @@ static void test_setstealth_cmd(CuTest *tc) { test_setup(); u = test_create_unit(test_create_faction(NULL), test_create_plain(0, 0)); lang = u->faction->locale; - u->flags = UFL_ANON_FACTION | UFL_SIEGE; + u->flags = UFL_ANON_FACTION | UFL_DEFENDER; u->thisorder = create_order(K_SETSTEALTH, lang, "%s %s", LOC(lang, parameters[P_FACTION]), LOC(lang, parameters[P_NOT])); setstealth_cmd(u, u->thisorder); - CuAssertIntEquals(tc, UFL_SIEGE, u->flags); + CuAssertIntEquals(tc, UFL_DEFENDER, u->flags); free_order(u->thisorder); u->thisorder = create_order(K_SETSTEALTH, lang, "%s", LOC(lang, parameters[P_FACTION])); setstealth_cmd(u, u->thisorder); - CuAssertIntEquals(tc, UFL_SIEGE | UFL_ANON_FACTION, u->flags); + CuAssertIntEquals(tc, UFL_DEFENDER | UFL_ANON_FACTION, u->flags); test_teardown(); } diff --git a/src/steal.c b/src/steal.c index 68a4239ec..8a390c8fb 100644 --- a/src/steal.c +++ b/src/steal.c @@ -188,10 +188,6 @@ void steal_cmd(unit * u, struct order *ord, econ_request ** stealorders) } assert(u->region == u2->region); - if (!can_contact(r, u, u2)) { - ADDMSG(&u->faction->msgs, msg_feedback(u, ord, "error60", "")); - return; - } effsk = effskill(u, SK_STEALTH, 0); n = effsk - max_skill(r, f, SK_PERCEPTION); From d32689bac898bb9614632b55f769bae865f09d5f Mon Sep 17 00:00:00 2001 From: Enno Rehling Date: Mon, 10 Sep 2018 17:58:10 +0200 Subject: [PATCH 004/160] experiments with clang-tidy --- src/academy.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/academy.c b/src/academy.c index 1298e9b57..538d36e06 100644 --- a/src/academy.c +++ b/src/academy.c @@ -16,8 +16,8 @@ ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. **/ -#include -#include +#include "platform.h" +#include "kernel/config.h" #include #include #include From 12fd6435c5346b8d8edd12125a32affe64895140 Mon Sep 17 00:00:00 2001 From: Enno Rehling Date: Mon, 10 Sep 2018 18:17:34 +0200 Subject: [PATCH 005/160] eliminate apparently dead code, and coverity warning. --- src/util/message.c | 8 +------- 1 file changed, 1 insertion(+), 7 deletions(-) diff --git a/src/util/message.c b/src/util/message.c index 8915dca8f..d8c66f5e0 100644 --- a/src/util/message.c +++ b/src/util/message.c @@ -86,13 +86,7 @@ static void mt_register(message_type * mtype) { message_type *mt_create(message_type * mtype, const char *args[], int nparameters) { - if (args != NULL && args[nparameters]) { - /* count the number of parameters */ - do { - ++nparameters; - } while (args[nparameters]); - } - if (nparameters > 0) { + if (args && nparameters > 0) { int i; mtype->nparameters = nparameters; mtype->pnames = (char **)malloc(sizeof(char *) * nparameters); From ecaf72324cdd91597c0f2bccdc7ae77b2f52019a Mon Sep 17 00:00:00 2001 From: Enno Rehling Date: Mon, 10 Sep 2018 19:50:22 +0200 Subject: [PATCH 006/160] Bug 2481: FOLGE wurde durch ZAUBERE verhindert. --- src/move.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/move.c b/src/move.c index b815f5ea5..7f56932d8 100644 --- a/src/move.c +++ b/src/move.c @@ -2633,9 +2633,9 @@ void follow_unit(unit * u) } } if (follow) { - fset(u, UFL_FOLLOWING); fset(u2, UFL_FOLLOWED); /* FOLLOW unit on a (potentially) moving unit prevents long orders */ + fset(u, UFL_FOLLOWING | UFL_LONGACTION); set_order(&u->thisorder, NULL); } } From c15b4c8fbfa61153cbbe278ebc622db48de9afab Mon Sep 17 00:00:00 2001 From: Steffen Mecke Date: Tue, 11 Sep 2018 17:17:47 +0200 Subject: [PATCH 007/160] refactor terminate (calculate_armor/resistance) --- scripts/tests/e2/e2features.lua | 1 + scripts/tests/e2/spells.lua | 3 +- src/battle.c | 156 +++++++++++++++++--------------- src/battle.h | 5 +- src/battle.test.c | 61 +++++++++---- 5 files changed, 130 insertions(+), 96 deletions(-) diff --git a/scripts/tests/e2/e2features.lua b/scripts/tests/e2/e2features.lua index bf90ab6a0..9db76dec9 100644 --- a/scripts/tests/e2/e2features.lua +++ b/scripts/tests/e2/e2features.lua @@ -519,6 +519,7 @@ function test_buy_sell() end function test_seaserpent_attack() + -- FIXME what does this test do? local r = region.create(0, 0, 'ocean') local sh = ship.create(r, 'boat') local us = unit.create(get_monsters(), r, 1, 'seaserpent') diff --git a/scripts/tests/e2/spells.lua b/scripts/tests/e2/spells.lua index 6a34d98db..5d718247a 100644 --- a/scripts/tests/e2/spells.lua +++ b/scripts/tests/e2/spells.lua @@ -139,7 +139,7 @@ end function test_bug_2480() local r = region.create(0, 0, "plain") - local f = faction.create("human", "hodor@eressea.de", "de") + local f = faction.create("human", "2480@eressea.de", "de") local u1 = unit.create(f, r, 1) local monster = unit.create(get_monsters(), r, 1, "wyrm") u1.number = 30 @@ -147,5 +147,4 @@ function test_bug_2480() monster:add_order("ATTACK " .. itoa36(u1.id)) process_orders() assert_equal(0, u1.number); - write_reports() end diff --git a/src/battle.c b/src/battle.c index 64808747d..11d804efb 100644 --- a/src/battle.c +++ b/src/battle.c @@ -555,8 +555,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 +769,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; @@ -1012,85 +1011,87 @@ 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) { +int calculate_armor(troop dt, const weapon_type *dwtype, const weapon_type *awtype, + const armor_type *armor, const armor_type *shield, bool magic) { 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; + return total_armor; +} + +variant calculate_resistance(troop dt, const weapon_type *dwtype, const armor_type *armor, const armor_type *shield) { + fighter *df = dt.fighter; + unit *du = df->unit; + /* calculate damage multiplier for magical damage */ + variant res; - res = frac_sub(frac_one, magic_resistance(du)); + res = 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)) { - 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)); - } - } - - /* gegen Magie wirkt nur natuerliche und magische Ruestung */ - ar = an + am; - if (res.sa[0] >= 0) { - *magres = res; - } - else { - *magres = frac_make(0, 1); - } + 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)); } - - return ar; + 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)); + } + } + if (res.sa[0] >= 0) { + return res; + } else { + return frac_zero; + } } static bool resurrect_troop(troop dt) @@ -1109,7 +1110,7 @@ static bool resurrect_troop(troop dt) } bool -terminate(troop dt, troop at, int type, const char *damage, bool missile) +terminate(troop dt, troop at, int type, const char *damage_formula, bool missile) { item **pitm; fighter *df = dt.fighter; @@ -1120,16 +1121,19 @@ terminate(troop dt, troop at, int type, const char *damage, bool missile) /* Schild */ side *ds = df->side; - int ar; + int armor_value; const weapon_type *dwtype = NULL; const weapon_type *awtype = NULL; const weapon *weapon; - variant res = frac_one; + const armor_type *armor = NULL; + const armor_type *shield = NULL; - int rda, sk = 0, sd; + variant resistance_factor = frac_one; + + int reduced_damage, attskill = 0, defskill; bool magic = false; - int da = dice_rand(damage); + int damage = dice_rand(damage_formula); assert(du->number > 0); ++at.fighter->hits; @@ -1137,14 +1141,14 @@ terminate(troop dt, troop at, int type, const char *damage, bool missile) switch (type) { case AT_STANDARD: weapon = select_weapon(at, true, missile); - sk = weapon_effskill(at, dt, weapon, 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: - sk = weapon_effskill(at, dt, NULL, true, missile); + attskill = weapon_effskill(at, dt, NULL, true, missile); break; case AT_SPELL: case AT_COMBATSPELL: @@ -1154,63 +1158,69 @@ terminate(troop dt, troop at, int type, const char *damage, bool missile) 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); + defskill = 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); + damage += CavalryBonus(au, dt, BONUS_DAMAGE); } - ar = calculate_armor(dt, dwtype, awtype, magic ? &res : 0); - if (ar < 0) { + armor = select_armor(dt, false); + shield = select_armor(dt, true); + + armor_value = calculate_armor(dt, dwtype, awtype, armor, shield, magic); + if (magic) { + resistance_factor = calculate_resistance(dt, dwtype, armor, shield); + } + if (armor_value < 0) { return false; } if (magic) { - res = frac_mul(frac_make(da, 1), res); - da = res.sa[0] / res.sa[1]; + variant reduced_damage = frac_mul(frac_make(damage, 1), resistance_factor); + damage = reduced_damage.sa[0] / reduced_damage.sa[1]; } if (type != AT_COMBATSPELL && type != AT_SPELL) { if (rule_damage & DAMAGE_CRITICAL) { - double kritchance = (sk * 3 - sd) / 200.0; + double kritchance = (attskill * 3 - defskill) / 200.0; int maxk = 4; kritchance = fmax(kritchance, 0.005); kritchance = fmin(0.9, kritchance); while (maxk-- && chance(kritchance)) { - da += dice_rand(damage); + damage += dice_rand(damage_formula); } } - da += rc_specialdamage(au, du, awtype); + damage += 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; + damage += af->person[at.index].damage_rear; } } else { /* melee bonus */ if (rule_damage & DAMAGE_MELEE_BONUS) { - da += af->person[at.index].damage; + damage += af->person[at.index].damage; } } /* Skilldifferenzbonus */ if (rule_damage & DAMAGE_SKILL_BONUS) { - da += MAX(0, (sk - sd) / DAMAGE_QUOTIENT); + damage += MAX(0, (attskill - defskill) / DAMAGE_QUOTIENT); } } - rda = MAX(da - ar, 0); + reduced_damage = MAX(damage - armor_value, 0); if ((u_race(du)->battle_flags & BF_INV_NONMAGIC) && !magic) - rda = 0; + reduced_damage = 0; else { int qi; selist *ql; @@ -1224,23 +1234,23 @@ terminate(troop dt, troop at, int type, const char *damage, bool missile) i |= WTF_BLUNT; if (i && awtype && fval(awtype, i)) - rda /= 2; + reduced_damage /= 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 */ + 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 = rda * (me->effect / 100); - rda -= hp; + 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) { - rda = MAX(rda - me->effect, 0); + reduced_damage = MAX(reduced_damage - me->effect, 0); me->duration--; } } @@ -1248,10 +1258,10 @@ terminate(troop dt, troop at, int type, const char *damage, bool missile) } assert(dt.index >= 0 && dt.index < du->number); - if (rda>0) { - df->person[dt.index].hp -= rda; + if (reduced_damage>0) { + df->person[dt.index].hp -= reduced_damage; if (u_race(au) == get_race(RC_DAEMON)) { - vampirism(at, rda); + vampirism(at, reduced_damage); } if (b->turn>1) { /* someone on the ship got damaged, damage the ship */ diff --git a/src/battle.h b/src/battle.h index 48fa7c63a..c747f49e5 100644 --- a/src/battle.h +++ b/src/battle.h @@ -233,7 +233,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); + union variant calculate_resistance(struct troop dt, const struct weapon_type *dwtype, const struct armor_type *armor, const struct armor_type *shield); 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..3c35ef640 100644 --- a/src/battle.test.c +++ b/src/battle.test.c @@ -365,7 +365,10 @@ 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, "default ac", 0, calculate_armor(dt, 0, 0, select_armor(dt, false), select_armor(dt, true), false)); + magres = calculate_resistance(dt, + select_weapon(dt, false, true) ? select_weapon(dt, false, true)->type : 0, + select_armor(dt, false), select_armor(dt, true)); CuAssertIntEquals_Msg(tc, "magres unmodified", magres.sa[0], magres.sa[1]); free_battle(b); @@ -373,10 +376,10 @@ static void test_calculate_armor(CuTest * tc) 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, calculate_armor(dt, 0, 0, select_armor(dt, false), select_armor(dt, true), 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, calculate_armor(dt, 0, 0, select_armor(dt, false), select_armor(dt, true), false)); rc->armor = 0; free_battle(b); @@ -385,28 +388,34 @@ 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, calculate_armor(dt, 0, 0, select_armor(dt, false), select_armor(dt, true), 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, calculate_armor(dt, 0, 0, select_armor(dt, false), select_armor(dt, true), 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, calculate_armor(dt, 0, 0, select_armor(dt, false), select_armor(dt, true), 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, calculate_armor(dt, 0, wtype, select_armor(dt, false), select_armor(dt, true), 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, calculate_armor(dt, 0, wtype, select_armor(dt, false), select_armor(dt, true), false)); wtype->flags = WTF_NONE; - CuAssertIntEquals_Msg(tc, "magical attack", 3, calculate_armor(dt, 0, 0, &magres)); + CuAssertIntEquals_Msg(tc, "magical attack", 3, calculate_armor(dt, 0, 0, select_armor(dt, false), select_armor(dt, true), true)); + magres = calculate_resistance(dt, + select_weapon(dt, false, true) ? select_weapon(dt, false, true)->type : 0, + select_armor(dt, false), select_armor(dt, true)); CuAssertIntEquals_Msg(tc, "magres unmodified", magres.sa[1], magres.sa[0]); 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 armor", 3, calculate_armor(dt, 0, 0, select_armor(dt, false), select_armor(dt, true), true)); + magres = calculate_resistance(dt, + select_weapon(dt, false, true) ? select_weapon(dt, false, true)->type : 0, + select_armor(dt, false), select_armor(dt, true)); CuAssertIntEquals_Msg(tc, "laen magres bonus", 4, magres.sa[1]); free_battle(b); test_teardown(); @@ -437,14 +446,18 @@ 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); + magres = calculate_resistance(dt, + select_weapon(dt, false, true) ? select_weapon(dt, false, true)->type : 0, + select_armor(dt, false), select_armor(dt, true)); CuAssertIntEquals_Msg(tc, "no magres reduction", magres.sa[1], magres.sa[0]); 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); + magres = calculate_resistance(dt, + select_weapon(dt, false, true) ? select_weapon(dt, false, true)->type : 0, + select_armor(dt, false), select_armor(dt, true)); CuAssert(tc, "laen reduction => 10%%", frac_equal(frac_make(9, 10), magres)); free_battle(b); @@ -455,7 +468,9 @@ 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); + magres = calculate_resistance(dt, + select_weapon(dt, false, true) ? select_weapon(dt, false, true)->type : 0, + select_armor(dt, false), select_armor(dt, true)); CuAssert(tc, "2x laen reduction => 81%%", frac_equal(frac_make(81, 100), magres)); free_battle(b); @@ -464,12 +479,16 @@ 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); + magres = calculate_resistance(dt, + select_weapon(dt, false, true) ? select_weapon(dt, false, true)->type : 0, + select_armor(dt, false), select_armor(dt, true)); CuAssert(tc, "skill reduction => 90%%", frac_equal(magres, frac_make(9, 10))); 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); + magres = calculate_resistance(dt, + select_weapon(dt, false, true) ? select_weapon(dt, false, true)->type : 0, + select_armor(dt, false), select_armor(dt, true)); CuAssert(tc, "race reduction => 40%%", frac_equal(magres, frac_make(4, 10))); magres = magic_resistance(du); CuAssert(tc, "race bonus => 60%%", frac_equal(magres, frac_make(60, 100))); @@ -477,7 +496,9 @@ static void test_magic_resistance(CuTest *tc) 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); + magres = calculate_resistance(dt, + select_weapon(dt, false, true) ? select_weapon(dt, false, true)->type : 0, + select_armor(dt, false), select_armor(dt, true)); CuAssert(tc, "damage reduction is never < 0.1", frac_equal(magres, frac_make(1, 10))); free_battle(b); @@ -513,12 +534,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, calculate_armor(dt, 0, wtype, select_armor(dt, false), select_armor(dt, true), 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, calculate_armor(dt, 0, wtype, select_armor(dt, false), select_armor(dt, true), false)); wtype->flags = WTF_NONE; - CuAssertIntEquals_Msg(tc, "no projectiles", 4, calculate_armor(dt, 0, wtype, 0)); + CuAssertIntEquals_Msg(tc, "no projectiles", 4, calculate_armor(dt, 0, wtype, select_armor(dt, false), select_armor(dt, true), false)); free_battle(b); test_teardown(); } From d9810449533d6d1243d8e3440ce59fcf75eb60c5 Mon Sep 17 00:00:00 2001 From: Steffen Mecke Date: Wed, 12 Sep 2018 09:37:22 +0200 Subject: [PATCH 008/160] refactor calculate_armor --- src/battle.c | 46 ++++++++++++------------- src/battle.h | 2 +- src/battle.test.c | 88 ++++++++++++++++++++--------------------------- 3 files changed, 61 insertions(+), 75 deletions(-) diff --git a/src/battle.c b/src/battle.c index 11d804efb..661982c3e 100644 --- a/src/battle.c +++ b/src/battle.c @@ -1012,8 +1012,9 @@ static int rc_specialdamage(const unit *au, const unit *du, const struct weapon_ } int calculate_armor(troop dt, const weapon_type *dwtype, const weapon_type *awtype, - const armor_type *armor, const armor_type *shield, bool magic) { - fighter *df = dt.fighter; + const armor_type *armor, const armor_type *shield, bool magic) { + + const fighter *df = dt.fighter; unit *du = df->unit; int total_armor = 0, nat_armor, magic_armor; bool missile = awtype && (awtype->flags&WTF_MISSILE); @@ -1067,31 +1068,35 @@ int calculate_armor(troop dt, const weapon_type *dwtype, const weapon_type *awty return total_armor; } -variant calculate_resistance(troop dt, const weapon_type *dwtype, const armor_type *armor, const armor_type *shield) { - fighter *df = dt.fighter; +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 res; - - res = frac_sub(frac_one, magic_resistance(du)); + 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)) { - res = frac_mul(res, frac_sub(frac_one, armor->magres)); + resistance_factor = frac_mul(resistance_factor, frac_sub(frac_one, armor->magres)); } if (shield && fval(shield, ATF_LAEN)) { - res = frac_mul(res, frac_sub(frac_one, shield->magres)); + resistance_factor = frac_mul(resistance_factor, frac_sub(frac_one, shield->magres)); } if (dwtype) { - res = frac_mul(res, frac_sub(frac_one, dwtype->magres)); + resistance_factor = frac_mul(resistance_factor, frac_sub(frac_one, dwtype->magres)); } } - if (res.sa[0] >= 0) { - return res; - } else { - return frac_zero; + 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]; + } static bool resurrect_troop(troop dt) @@ -1129,10 +1134,9 @@ terminate(troop dt, troop at, int type, const char *damage_formula, bool missile const armor_type *armor = NULL; const armor_type *shield = NULL; - variant resistance_factor = frac_one; - - int reduced_damage, attskill = 0, defskill; + int reduced_damage, attskill = 0, defskill = 0; bool magic = false; + int damage = dice_rand(damage_formula); assert(du->number > 0); @@ -1171,17 +1175,11 @@ terminate(troop dt, troop at, int type, const char *damage_formula, bool missile shield = select_armor(dt, true); armor_value = calculate_armor(dt, dwtype, awtype, armor, shield, magic); - if (magic) { - resistance_factor = calculate_resistance(dt, dwtype, armor, shield); - } if (armor_value < 0) { return false; } - if (magic) { - variant reduced_damage = frac_mul(frac_make(damage, 1), resistance_factor); - damage = reduced_damage.sa[0] / reduced_damage.sa[1]; - } + damage = apply_resistance(damage, dt, dwtype, armor, shield, magic); if (type != AT_COMBATSPELL && type != AT_SPELL) { if (rule_damage & DAMAGE_CRITICAL) { diff --git a/src/battle.h b/src/battle.h index c747f49e5..a35a44a0f 100644 --- a/src/battle.h +++ b/src/battle.h @@ -236,7 +236,7 @@ extern "C" { 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); - union variant calculate_resistance(struct troop dt, const struct weapon_type *dwtype, const struct armor_type *armor, const struct armor_type *shield); + 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 3c35ef640..ba0807472 100644 --- a/src/battle.test.c +++ b/src/battle.test.c @@ -339,6 +339,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 +359,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,21 +374,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, select_armor(dt, false), select_armor(dt, true), false)); - magres = calculate_resistance(dt, - select_weapon(dt, false, true) ? select_weapon(dt, false, true)->type : 0, - select_armor(dt, false), select_armor(dt, true)); - 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, select_armor(dt, false), select_armor(dt, true), false)); + 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, select_armor(dt, false), select_armor(dt, true), false)); + CuAssertIntEquals_Msg(tc, "natural armor", 3, test_armor(dt, 0, false)); rc->armor = 0; free_battle(b); @@ -388,35 +395,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, select_armor(dt, false), select_armor(dt, true), false)); + 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, select_armor(dt, false), select_armor(dt, true), false)); + 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, select_armor(dt, false), select_armor(dt, true), false)); + 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, select_armor(dt, false), select_armor(dt, true), false)); + 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, select_armor(dt, false), select_armor(dt, true), false)); + 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, select_armor(dt, false), select_armor(dt, true), true)); - magres = calculate_resistance(dt, - select_weapon(dt, false, true) ? select_weapon(dt, false, true)->type : 0, - select_armor(dt, false), select_armor(dt, true)); - 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; - CuAssertIntEquals_Msg(tc, "laen armor", 3, calculate_armor(dt, 0, 0, select_armor(dt, false), select_armor(dt, true), true)); - magres = calculate_resistance(dt, - select_weapon(dt, false, true) ? select_weapon(dt, false, true)->type : 0, - select_armor(dt, false), select_armor(dt, true)); - 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(); } @@ -446,19 +448,17 @@ static void test_magic_resistance(CuTest *tc) i_change(&du->items, ishield, 1); dt.fighter = setup_fighter(&b, du); - magres = calculate_resistance(dt, - select_weapon(dt, false, true) ? select_weapon(dt, false, true)->type : 0, - select_armor(dt, false), select_armor(dt, true)); - 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; - magres = calculate_resistance(dt, - select_weapon(dt, false, true) ? select_weapon(dt, false, true)->type : 0, - select_armor(dt, false), select_armor(dt, true)); - 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; @@ -468,10 +468,7 @@ static void test_magic_resistance(CuTest *tc) ashield->flags |= ATF_LAEN; ashield->magres = v10p; dt.fighter = setup_fighter(&b, du); - magres = calculate_resistance(dt, - select_weapon(dt, false, true) ? select_weapon(dt, false, true)->type : 0, - select_armor(dt, false), select_armor(dt, true)); - 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; @@ -479,27 +476,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); - magres = calculate_resistance(dt, - select_weapon(dt, false, true) ? select_weapon(dt, false, true)->type : 0, - select_armor(dt, false), select_armor(dt, true)); - 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 */ - magres = calculate_resistance(dt, - select_weapon(dt, false, true) ? select_weapon(dt, false, true)->type : 0, - select_armor(dt, false), select_armor(dt, true)); - 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))); - magres = calculate_resistance(dt, - select_weapon(dt, false, true) ? select_weapon(dt, false, true)->type : 0, - select_armor(dt, false), select_armor(dt, true)); - 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(); @@ -534,12 +522,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, select_armor(dt, false), select_armor(dt, true), false)); + 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, select_armor(dt, false), select_armor(dt, true), false)); + 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, select_armor(dt, false), select_armor(dt, true), false)); + CuAssertIntEquals_Msg(tc, "no projectiles", 4, test_armor(dt, wtype, false)); free_battle(b); test_teardown(); } From 69702df20328c7f0ff8331cf6b720763e6526f02 Mon Sep 17 00:00:00 2001 From: Steffen Mecke Date: Wed, 12 Sep 2018 09:40:34 +0200 Subject: [PATCH 009/160] refactor terminate finished --- src/battle.c | 319 +++++++++++++++++++++++++++------------------- src/battle.h | 1 - src/battle.test.c | 33 +++++ 3 files changed, 224 insertions(+), 129 deletions(-) diff --git a/src/battle.c b/src/battle.c index 661982c3e..c34daeb38 100644 --- a/src/battle.c +++ b/src/battle.c @@ -122,7 +122,7 @@ 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; @@ -169,7 +169,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)) { @@ -949,6 +949,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; @@ -962,6 +965,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 @@ -1114,23 +1127,181 @@ static bool resurrect_troop(troop dt) return false; } +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].defence--; + } + } +} + +static bool survives(fighter *af, troop dt, battle *b) { + const unit *du = af->unit; + const fighter *df = dt.fighter; + + if (df->person[dt.index].hp > 0) { /* Hat �berlebt */ + 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 true; + } + + /* healing potions can avert a killing blow */ + if (resurrect_troop(dt)) { + 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_defence_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 = (attskill * 3 - 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) { - 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 armor_value; const weapon_type *dwtype = NULL; const weapon_type *awtype = NULL; - const weapon *weapon; const armor_type *armor = NULL; const armor_type *shield = NULL; @@ -1142,29 +1313,8 @@ terminate(troop dt, troop at, int type, const char *damage_formula, bool missile assert(du->number > 0); ++at.fighter->hits; - 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; - } - 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; + calculate_attack_type(at, dt, type, missile, &awtype, &attskill, &magic); + calculate_defence_type(at, dt, type, missile, &awtype, &attskill); if (is_riding(at) && (awtype == NULL || (fval(awtype, WTF_HORSEBONUS) && !fval(awtype, WTF_MISSILE)))) { @@ -1182,27 +1332,11 @@ terminate(troop dt, troop at, int type, const char *damage_formula, bool missile damage = apply_resistance(damage, dt, dwtype, armor, shield, magic); if (type != AT_COMBATSPELL && type != AT_SPELL) { - if (rule_damage & DAMAGE_CRITICAL) { - double kritchance = (attskill * 3 - 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); - } - } + damage += crit_damage(attskill, defskill, damage_formula); damage += rc_specialdamage(au, du, awtype); - if (awtype != NULL && fval(awtype, WTF_MISSILE)) { - /* missile weapon bonus */ - if (rule_damage & DAMAGE_MISSILE_BONUS) { - damage += af->person[at.index].damage_rear; - } - } - else { + if (awtype == NULL || !fval(awtype, WTF_MISSILE)) { /* melee bonus */ if (rule_damage & DAMAGE_MELEE_BONUS) { damage += af->person[at.index].damage; @@ -1217,96 +1351,25 @@ terminate(troop dt, troop at, int type, const char *damage_formula, bool missile reduced_damage = MAX(damage - armor_value, 0); - if ((u_race(du)->battle_flags & BF_INV_NONMAGIC) && !magic) - reduced_damage = 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)) - reduced_damage /= 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 <= 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--; - } - } - } - } + 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) { + if (reduced_damage > 0) { df->person[dt.index].hp -= reduced_damage; - if (u_race(au) == get_race(RC_DAEMON)) { - vampirism(at, reduced_damage); - } - 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; + vampirism(at, reduced_damage); + + ship_damage(b->turn, du); } - /* 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; - } + if (survives(af, dt, b)) + return false; - /* healing potions can avert a killing blow */ - if (resurrect_troop(dt)) { - message *m = msg_message("potionsave", "unit", du); - battle_message_faction(b, du->faction, m); - msg_release(m); - 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); - } - } - if (*pitm == itm) { - pitm = &itm->next; - } - } + destroy_items(dt); + kill_troop(dt); return true; diff --git a/src/battle.h b/src/battle.h index a35a44a0f..bad2dd508 100644 --- a/src/battle.h +++ b/src/battle.h @@ -175,7 +175,6 @@ extern "C" { int attack; int defence; int damage; - int damage_rear; int flags; int speed; int reload; diff --git a/src/battle.test.c b/src/battle.test.c index ba0807472..a734f5428 100644 --- a/src/battle.test.c +++ b/src/battle.test.c @@ -565,6 +565,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; @@ -812,6 +844,7 @@ CuSuite *get_battle_suite(void) 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; } From d6e8b38724f4b5164f012c1aacd9e207f6bb4837 Mon Sep 17 00:00:00 2001 From: Enno Rehling Date: Wed, 12 Sep 2018 20:35:27 +0200 Subject: [PATCH 010/160] FOLGE SCHIFF reparieren (hat UFL_LONGORDER getestet). --- scripts/tests/e2/astral.lua | 6 ------ scripts/tests/e2/init.lua | 8 +++++++- scripts/tests/e2/movement.lua | 3 ++- src/move.c | 2 +- 4 files changed, 10 insertions(+), 9 deletions(-) diff --git a/scripts/tests/e2/astral.lua b/scripts/tests/e2/astral.lua index efed6345f..1573c9af2 100644 --- a/scripts/tests/e2/astral.lua +++ b/scripts/tests/e2/astral.lua @@ -13,12 +13,6 @@ function setup() eressea.settings.set("magic.regeneration.enable", "0") end -local function dump_messages(f) - for k, v in ipairs(f.messages) do - print(v) - end -end - function test_fetch_astral() local r = region.create(0, 0, "plain") local f = faction.create("human") diff --git a/scripts/tests/e2/init.lua b/scripts/tests/e2/init.lua index 5c942fc74..55feab5bf 100644 --- a/scripts/tests/e2/init.lua +++ b/scripts/tests/e2/init.lua @@ -1,3 +1,10 @@ +function dump_messages(f) + for k, v in ipairs(f.messages) do + print(v) + end +end + +require 'tests.e2.movement' require 'tests.e2.astral' require 'tests.e2.spells' require 'tests.e2.e2features' @@ -7,7 +14,6 @@ require 'tests.e2.production' require 'tests.e2.adamantium' require 'tests.e2.undead' require 'tests.e2.shiplanding' -require 'tests.e2.movement' require 'tests.e2.destroy' require 'tests.e2.guard' require 'tests.e2.stealth' diff --git a/scripts/tests/e2/movement.lua b/scripts/tests/e2/movement.lua index fb82567af..57d2413c4 100644 --- a/scripts/tests/e2/movement.lua +++ b/scripts/tests/e2/movement.lua @@ -9,7 +9,7 @@ function setup() eressea.settings.set("NewbieImmunity", "0") end - function test_piracy() +function test_piracy() local r = region.create(0, 0, "plain") local r2 = region.create(1, 0, "plain") local r3 = region.create(-1, 0, "ocean") @@ -96,6 +96,7 @@ function test_follow_ship() local f = faction.create("human", "test@example.com", "de") local u1 = unit.create(f, r1, 1) local u2 = unit.create(f, r1, 1) + u2.name = 'Xolgrim' u1:add_item("money", 100) u2:add_item("money", 100) u1.ship = ship.create(r1, "boat") diff --git a/src/move.c b/src/move.c index 7f56932d8..5e8c56235 100644 --- a/src/move.c +++ b/src/move.c @@ -2368,7 +2368,7 @@ static void move_hunters(void) break; } - if (!fval(u, UFL_LONGACTION) && !LongHunger(u) && follow_ship(u, ord)) { + if (!LongHunger(u) && follow_ship(u, ord)) { up = &r->units; break; } From a90ae46d5216c65561e1ed788757dd957f46a714 Mon Sep 17 00:00:00 2001 From: Steffen Mecke Date: Thu, 13 Sep 2018 10:59:15 +0200 Subject: [PATCH 011/160] assert assumption on armor --- src/battle.c | 2 ++ 1 file changed, 2 insertions(+) diff --git a/src/battle.c b/src/battle.c index c34daeb38..e609a1609 100644 --- a/src/battle.c +++ b/src/battle.c @@ -1078,6 +1078,8 @@ int calculate_armor(troop dt, const weapon_type *dwtype, const weapon_type *awty total_armor += magic_armor; + assert(total_armor >= 0 || !"armor < 0 means hit denied"); + return total_armor; } From a876a60b6855c7e034ac3c229657934b741a6158 Mon Sep 17 00:00:00 2001 From: Enno Rehling Date: Thu, 13 Sep 2018 16:16:32 +0200 Subject: [PATCH 012/160] Stop using player email to set faction name. --- src/economy.test.c | 1 + src/gmtool.c | 10 ---------- src/races/races.c | 2 -- src/races/zombies.c | 23 ----------------------- src/tests.c | 24 ++++++++++++++++++++++++ 5 files changed, 25 insertions(+), 35 deletions(-) diff --git a/src/economy.test.c b/src/economy.test.c index 90a4bd260..1a40c03db 100644 --- a/src/economy.test.c +++ b/src/economy.test.c @@ -487,6 +487,7 @@ static void test_recruit_insect(CuTest *tc) { test_setup(); test_create_calendar(); + test_create_terrain("desert", -1); f = test_create_faction(test_create_race("insect")); u = test_create_unit(f, test_create_region(0, 0, NULL)); u->thisorder = create_order(K_RECRUIT, f->locale, "%d", 1); diff --git a/src/gmtool.c b/src/gmtool.c index fdbfd3faa..c2193bd32 100644 --- a/src/gmtool.c +++ b/src/gmtool.c @@ -932,20 +932,10 @@ static void seed_player(state *st, const newfaction *player) { pnormalize(&nx, &ny, st->cursor.pl); r = findregion(nx, ny); if (r) { - const char *at = strchr(player->email, '@'); faction *f; addplayer(r, f = addfaction(player->email, player->password, player->race, player->lang, player->subscription)); - if (at) { - char fname[64]; - size_t len = at - player->email; - if (len>4 && lenemail, len); - fname[len]=0; - faction_setname(f, fname); - } - } } } } diff --git a/src/races/races.c b/src/races/races.c index 120a15dd9..44ca5d95e 100644 --- a/src/races/races.c +++ b/src/races/races.c @@ -30,7 +30,6 @@ void age_firedragon(struct unit *u); void age_dragon(struct unit *u); -void age_undead(struct unit *u); void age_skeleton(struct unit *u); void age_zombie(struct unit *u); void age_ghoul(struct unit *u); @@ -81,7 +80,6 @@ void equip_newunits(struct unit *u) void register_races(void) { /* function age for race->age() */ - register_function((pf_generic)age_undead, "age_undead"); register_function((pf_generic)age_skeleton, "age_skeleton"); register_function((pf_generic)age_zombie, "age_zombie"); register_function((pf_generic)age_ghoul, "age_ghoul"); diff --git a/src/races/zombies.c b/src/races/zombies.c index de3d81972..3c880d819 100644 --- a/src/races/zombies.c +++ b/src/races/zombies.c @@ -40,29 +40,6 @@ void make_undead_unit(unit * u) u->flags |= UFL_ISNEW; } -void age_undead(unit * u) -{ - region *r = u->region; - - /* untote, die einer partei angehoeren, koennen sich - * absplitten, anstatt sich zu vermehren. monster - * untote vermehren sich nur noch */ - - if (u->number > UNDEAD_MIN && !is_monsters(u->faction) - && rng_int() % 100 < UNDEAD_BREAKUP) { - int m, n = 0; - unit *u2; - - for (m = u->number; m; m--) { - if (rng_int() % 100 < UNDEAD_BREAKUP_FRACTION) - ++n; - } - u2 = create_unit(r, get_monsters(), 0, get_race(RC_UNDEAD), 0, NULL, u); - make_undead_unit(u2); - transfermen(u, u2, u->number - n); - } -} - void age_skeleton(unit * u) { if (is_monsters(u->faction) && rng_int() % 100 < age_chance(u->age, 27, 1)) { diff --git a/src/tests.c b/src/tests.c index 4ee38d195..6395b4fcb 100644 --- a/src/tests.c +++ b/src/tests.c @@ -13,6 +13,7 @@ #include #include #include +#include #include #include #include @@ -238,6 +239,29 @@ static void test_reset(void) { free_spellbooks(); free_prefixes(); mt_clear(); +/* + for (i = 0; i != MAXTERRAINS; ++i) { + int flags = 0; + if (i == T_FIREWALL) { + flags |= FORBIDDEN_REGION; + } else { + flags = FLY_INTO | WALK_INTO; + if (i == T_OCEAN) { + flags |= SEA_REGION | SWIM_INTO; + } + else { + flags |= LAND_REGION; + if (i == T_PLAIN) { + flags |= CAVALRY_REGION | FOREST_REGION; + } + else if (i == T_GLACIER || i == T_ICEBERG || i == T_ICEBERG_SLEEP) { + flags |= ARCTIC_REGION; + } + } + } + test_create_terrain(terrainnames[i], flags); + } +*/ for (i = 0; i != MAXSKILLS; ++i) { enable_skill(i, true); } From 681cf32e1f82a650f37ee2eba927b4e9ca57fab0 Mon Sep 17 00:00:00 2001 From: Enno Rehling Date: Sat, 15 Sep 2018 18:35:27 +0200 Subject: [PATCH 013/160] remove besiege from keywords[] array fix broken at_keys attributes remove unused global.attribs --- scripts/tests/e3/rules.lua | 7 ++-- src/attributes/key.c | 79 +++++++++++++++++++++++++++++++++----- src/bindings.c | 25 ------------ src/jsonconf.c | 2 +- src/kernel/config.c | 4 -- src/kernel/config.h | 1 - src/kernel/save.c | 11 ++++-- src/keyword.c | 6 +-- src/tests.c | 4 +- src/util/gamedata.h | 3 +- 10 files changed, 88 insertions(+), 54 deletions(-) diff --git a/scripts/tests/e3/rules.lua b/scripts/tests/e3/rules.lua index 6d3e56d1a..b262f99a6 100644 --- a/scripts/tests/e3/rules.lua +++ b/scripts/tests/e3/rules.lua @@ -953,12 +953,11 @@ function test_bug2083() -- this is a bit weird, but the bug was caused by market code -- being called in two places. We want to make sure this doesn't happen for k, v in pairs(rules) do - set_key("xm09", true) - if 'table' == type(v) then + if 'table' == type(v) then cb = v['update'] - if 'function' == type(cb) then + if 'function' == type(cb) then cb() - end + end end end diff --git a/src/attributes/key.c b/src/attributes/key.c index 75958a6fb..1808c561f 100644 --- a/src/attributes/key.c +++ b/src/attributes/key.c @@ -25,6 +25,7 @@ OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. #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/bindings.c b/src/bindings.c index d72bddac2..bdf03afdf 100755 --- a/src/bindings.c +++ b/src/bindings.c @@ -153,15 +153,6 @@ int tolua_itemlist_next(lua_State * L) return 0; } -static int tolua_getkey(lua_State * L) -{ - const char *name = tolua_tostring(L, 1, 0); - int flag = atoi36(name); - - lua_pushboolean(L, key_get(global.attribs, flag)); - return 1; -} - static int tolua_translate(lua_State * L) { const char *str = tolua_tostring(L, 1, 0); @@ -175,20 +166,6 @@ static int tolua_translate(lua_State * L) return 0; } -static int tolua_setkey(lua_State * L) -{ - const char *name = tolua_tostring(L, 1, 0); - int value = (int)tolua_tonumber(L, 3, 0); - int flag = atoi36(name); - if (value) { - key_set(&global.attribs, flag, value); - } - else { - key_unset(&global.attribs, flag); - } - return 0; -} - static int tolua_random(lua_State * L) { lua_pushinteger(L, rng_int()); @@ -1003,8 +980,6 @@ int tolua_bindings_open(lua_State * L, const dictionary *inifile) tolua_function(L, TOLUA_CAST "update_owners", tolua_update_owners); tolua_function(L, TOLUA_CAST "learn_skill", tolua_learn_skill); tolua_function(L, TOLUA_CAST "create_curse", tolua_create_curse); - tolua_function(L, TOLUA_CAST "get_key", tolua_getkey); - tolua_function(L, TOLUA_CAST "set_key", tolua_setkey); tolua_function(L, TOLUA_CAST "translate", &tolua_translate); tolua_function(L, TOLUA_CAST "spells", tolua_get_spells); tolua_function(L, TOLUA_CAST "equip_newunits", tolua_equip_newunits); diff --git a/src/jsonconf.c b/src/jsonconf.c index fcd6f5c78..51116691f 100644 --- a/src/jsonconf.c +++ b/src/jsonconf.c @@ -846,7 +846,7 @@ static void json_keyword(cJSON *json, struct locale *lang) { } for (child = json->child; child; child = child->next) { keyword_t kwd = findkeyword(child->string); - if (kwd != NOKEYWORD) { + if (kwd != NOKEYWORD && keywords[kwd]) { if (child->type == cJSON_String) { init_keyword(lang, kwd, child->valuestring); locale_setstring(lang, mkname("keyword", keywords[kwd]), child->valuestring); diff --git a/src/kernel/config.c b/src/kernel/config.c index 750d406f6..eee2ec0f5 100644 --- a/src/kernel/config.c +++ b/src/kernel/config.c @@ -767,10 +767,6 @@ void free_gamedata(void) free_borders(); free_alliances(); - while (global.attribs) { - a_remove(&global.attribs, global.attribs); - } - while (planes) { plane *pl = planes; planes = planes->next; diff --git a/src/kernel/config.h b/src/kernel/config.h index 94abcb7f4..e104d4a1a 100644 --- a/src/kernel/config.h +++ b/src/kernel/config.h @@ -109,7 +109,6 @@ extern "C" { /* globale settings des Spieles */ typedef struct settings { - struct attrib *attribs; void *vm_state; } settings; diff --git a/src/kernel/save.c b/src/kernel/save.c index b51e82734..51585f26c 100644 --- a/src/kernel/save.c +++ b/src/kernel/save.c @@ -1392,7 +1392,13 @@ int read_game(gamedata *data) else { READ_STR(store, NULL, 0); } - read_attribs(data, &global.attribs, NULL); + + if (data->version < FIXATKEYS_VERSION) { + attrib *a = NULL; + read_attribs(data, &a, NULL); + a_removeall(&a, NULL); + } + READ_INT(store, &turn); log_debug(" - reading turn %d", turn); rng_init(turn + config_get_int("game.seed", 0)); @@ -1614,9 +1620,6 @@ int write_game(gamedata *data) { WRITE_INT(store, game_id()); WRITE_SECTION(store); - write_attribs(store, global.attribs, NULL); - WRITE_SECTION(store); - WRITE_INT(store, turn); WRITE_INT(store, 0 /* max_unique_id */); WRITE_INT(store, nextborder); diff --git a/src/keyword.c b/src/keyword.c index 47fcc3c8e..e2b5b4775 100644 --- a/src/keyword.c +++ b/src/keyword.c @@ -15,7 +15,7 @@ const char * keyword(keyword_t kwd) { static char result[32]; /* FIXME: static return value */ - if (kwd==NOKEYWORD) { + if (kwd==NOKEYWORD || keywords[kwd] == NULL) { return NULL; } if (!result[0]) { @@ -43,7 +43,7 @@ void init_keywords(const struct locale *lang) { keyword_t findkeyword(const char *s) { int i; for (i = 0; i != MAXKEYWORDS; ++i) { - if (strcmp(s, keywords[i]) == 0) { + if (keywords[i] && (strcmp(s, keywords[i]) == 0)) { return (keyword_t)i; } } @@ -94,7 +94,7 @@ const char *keywords[MAXKEYWORDS] = { "work", "attack", "steal", - "deprecated_besiege", + NULL, "name", "use", "describe", diff --git a/src/tests.c b/src/tests.c index 6395b4fcb..ddd6f7cf5 100644 --- a/src/tests.c +++ b/src/tests.c @@ -147,7 +147,9 @@ struct locale * test_create_locale(void) { locale_setstring(loc, combatstatus[i], combatstatus[i] + 7); } for (i = 0; i != MAXKEYWORDS; ++i) { - locale_setstring(loc, mkname("keyword", keywords[i]), keywords[i]); + if (keywords[i]) { + locale_setstring(loc, mkname("keyword", keywords[i]), keywords[i]); + } } for (i = 0; i != MAXPARAMS; ++i) { locale_setstring(loc, parameters[i], parameters[i]); diff --git a/src/util/gamedata.h b/src/util/gamedata.h index 22c1d9052..2dd4e1342 100644 --- a/src/util/gamedata.h +++ b/src/util/gamedata.h @@ -36,10 +36,11 @@ #define FAMILIAR_FIX_VERSION 359 /* familiar links are fixed */ #define SKILLSORT_VERSION 360 /* u->skills is sorted */ #define LANDDISPLAY_VERSION 360 /* r.display is now in r.land.display */ +#define FIXATKEYS_VERSION 361 /* remove global.attribs, fix at_keys */ /* unfinished: */ #define CRYPT_VERSION 400 /* passwords are encrypted */ -#define RELEASE_VERSION LANDDISPLAY_VERSION /* current datafile */ +#define RELEASE_VERSION FIXATKEYS_VERSION /* current datafile */ #define MIN_VERSION UIDHASH_VERSION /* minimal datafile we support */ #define MAX_VERSION RELEASE_VERSION /* change this if we can need to read the future datafile, and we can do so */ From 658b47aeb4a8302515e26016094bc72463ad3c61 Mon Sep 17 00:00:00 2001 From: Enno Rehling Date: Sat, 15 Sep 2018 19:12:32 +0200 Subject: [PATCH 014/160] remove seaserpent test that is not a test. --- scripts/tests/e2/e2features.lua | 13 ------------- 1 file changed, 13 deletions(-) diff --git a/scripts/tests/e2/e2features.lua b/scripts/tests/e2/e2features.lua index 54033d496..acd2f1e03 100644 --- a/scripts/tests/e2/e2features.lua +++ b/scripts/tests/e2/e2features.lua @@ -541,16 +541,3 @@ function test_buy_sell() assert_equal(4, u:get_item(item)) assert_not_equal(0, u:get_item('money')) end - -function test_seaserpent_attack() - local r = region.create(0, 0, 'ocean') - local sh = ship.create(r, 'boat') - local us = unit.create(get_monsters(), r, 1, 'seaserpent') - local u = unit.create(faction.create('human', 'enno@example.com'), r, 20, 'human') - u.ship = sh - us:clear_orders() - us:add_order('ATTACKIERE ' .. itoa36(u.id)) - us:set_skill('unarmed', 10) - process_orders() - write_reports() -end From 174a91968b248bc3ba8f9af6fc85d60cb73f9a78 Mon Sep 17 00:00:00 2001 From: Enno Rehling Date: Sat, 22 Sep 2018 08:54:17 +0200 Subject: [PATCH 015/160] make herb growth code a little more readable. --- src/laws.c | 10 ++++++---- 1 file changed, 6 insertions(+), 4 deletions(-) diff --git a/src/laws.c b/src/laws.c index 0e9285281..922f4c366 100644 --- a/src/laws.c +++ b/src/laws.c @@ -741,11 +741,13 @@ growing_herbs(region * r, const int current_season, const int last_weeks_season) * Kräuter))% sich zu vermehren. */ UNUSED_ARG(last_weeks_season); if (current_season != SEASON_WINTER) { - int i; - for (i = rherbs(r); i > 0; i--) { - if (rng_int() % 100 < (100 - rherbs(r))) - rsetherbs(r, (short)(rherbs(r) + 1)); + int i, herbs = rherbs(r); + for (i = herbs; i > 0; --i) { + if (rng_int() % 100 < (100 - herbs)) { + ++herbs; + } } + rsetherbs(r, herbs); } } From f609bb01f2638208401f68419c25ca9b4c221859 Mon Sep 17 00:00:00 2001 From: Enno Rehling Date: Sun, 23 Sep 2018 14:01:47 +0200 Subject: [PATCH 016/160] unused variable is never read. --- src/battle.c | 2 -- 1 file changed, 2 deletions(-) diff --git a/src/battle.c b/src/battle.c index 1e256f9ca..8e8c3610b 100644 --- a/src/battle.c +++ b/src/battle.c @@ -3865,7 +3865,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; @@ -3912,7 +3911,6 @@ static void battle_flee(battle * b) ispaniced = EFFECT_PANIC_SPELL; } if (chance(fmin(fleechance(u) + ispaniced, 0.90))) { - ++runners; flee(dt); } } From 91a7b94cec8315f335de5161cdcffd1dd3605eaa Mon Sep 17 00:00:00 2001 From: Enno Rehling Date: Sun, 23 Sep 2018 19:03:28 +0200 Subject: [PATCH 017/160] run iwyu if we have it --- src/CMakeLists.txt | 9 +++++++++ src/gmtool.c | 22 +++++----------------- src/listbox.c | 2 -- 3 files changed, 14 insertions(+), 19 deletions(-) diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt index cf96cfbc2..96351cdc9 100644 --- a/src/CMakeLists.txt +++ b/src/CMakeLists.txt @@ -169,9 +169,18 @@ set (SERVER_SRC ${SERVER_SRC} ) endif(CURSES_FOUND) +find_program(IWYU_PATH NAMES include-what-you-use iwyu) +if(NOT IWYU_PATH) + message(STATUS "Could not find the program include-what-you-use") +endif() + + add_library(version STATIC ${VERSION_SRC}) add_library(game ${ERESSEA_SRC}) add_executable(eressea ${SERVER_SRC}) +if (IWYU_PATH) +set_property(TARGET eressea PROPERTY C_INCLUDE_WHAT_YOU_USE ${IWYU_PATH}) +endif(IWYU_PATH) target_link_libraries(game version) target_link_libraries(eressea game diff --git a/src/gmtool.c b/src/gmtool.c index c2193bd32..48a51d354 100644 --- a/src/gmtool.c +++ b/src/gmtool.c @@ -18,49 +18,37 @@ #include "gmtool.h" -#include -#include -#include #include #include "kernel/building.h" -#include "kernel/calendar.h" #include "kernel/faction.h" #include "kernel/item.h" #include "kernel/plane.h" -#include "kernel/race.h" #include "kernel/region.h" #include "kernel/terrainid.h" #include "kernel/unit.h" -#include "kernel/resources.h" #include "kernel/save.h" #include "kernel/ship.h" #include "kernel/terrain.h" -#include -#include - #include #include #include -#include #include -#include -#include -#include +#include "util/path.h" +#include "util/rng.h" +#include "util/unicode.h" #include "gmtool_structs.h" #include "console.h" #include "listbox.h" -#include "wormhole.h" #include "teleport.h" -#include -#include - #include #include +#include #include +#include #include #include diff --git a/src/listbox.c b/src/listbox.c index afc04b232..cd7118da7 100644 --- a/src/listbox.c +++ b/src/listbox.c @@ -13,12 +13,10 @@ #endif #include -#include #include "listbox.h" #include "gmtool_structs.h" -#include #include #include From dfa9c644650617e269089ebee85a2422b245e41d Mon Sep 17 00:00:00 2001 From: Enno Rehling Date: Sun, 23 Sep 2018 19:44:05 +0200 Subject: [PATCH 018/160] clean includes for bindings --- src/bind_eressea.c | 3 +-- src/bind_faction.c | 8 +++++++- src/bind_gmtool.c | 2 ++ src/bind_message.c | 4 ++++ src/bind_monsters.c | 7 +++---- src/bind_order.c | 1 + src/bind_region.c | 17 ++++++++-------- src/bind_storage.c | 5 +---- src/bind_unit.c | 28 ++++++++++++++++---------- src/bindings.c | 49 +++++++++++++++++++++------------------------ src/gmtool.c | 2 -- src/listbox.c | 1 + 12 files changed, 68 insertions(+), 59 deletions(-) diff --git a/src/bind_eressea.c b/src/bind_eressea.c index 11c03898d..9f73c4a29 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" @@ -16,6 +14,7 @@ #include #include +#include #include diff --git a/src/bind_faction.c b/src/bind_faction.c index ac797093d..eae029f4b 100644 --- a/src/bind_faction.c +++ b/src/bind_faction.c @@ -18,6 +18,7 @@ without prior permission by the authors of Eressea. #include "bind_unit.h" #include "bindings.h" #include "helpers.h" +#include "magic.h" #include #include @@ -29,14 +30,19 @@ without prior permission by the authors of Eressea. #include #include #include -#include +#include "kernel/types.h" #include #include #include #include +#include #include +#include "attributes/key.h" + +#include +#include #include #include #include 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_region.c b/src/bind_region.c index b49ceb078..3b0e7f3a3 100644 --- a/src/bind_region.c +++ b/src/bind_region.c @@ -8,38 +8,37 @@ #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 -#include -#include -#include #include #include -#include #include #include +#include #include -#include +#include +#include +#include +#include #include #include #include +#include #include static int tolua_region_count_msg_type(lua_State *L) { diff --git a/src/bind_storage.c b/src/bind_storage.c index e1339312c..aa7935312 100644 --- a/src/bind_storage.c +++ b/src/bind_storage.c @@ -11,16 +11,13 @@ #include #include -#include -#include -#include #include #include #include -#include #include +#include #include static int tolua_storage_create(lua_State * L) diff --git a/src/bind_unit.c b/src/bind_unit.c index fddcd5608..9f6c39163 100644 --- a/src/bind_unit.c +++ b/src/bind_unit.c @@ -5,15 +5,22 @@ #include "bind_unit.h" #include "alchemy.h" #include "bindings.h" -#include "move.h" #include "reports.h" #include "guard.h" +#include "magic.h" +#include "skill.h" -/* attributes includes */ -#include -#include +/* util includes */ +#include +#include +#include +#include +#include +#include "util/variant.h" /* kernel includes */ +#include "kernel/skills.h" +#include "kernel/types.h" #include #include #include @@ -31,21 +38,20 @@ #include #include -/* util includes */ -#include -#include -#include -#include -#include -#include +/* attributes includes */ +#include +#include #include +#include +#include #include #include #include #include +#include #include #include diff --git a/src/bindings.c b/src/bindings.c index bdf03afdf..60519260a 100755 --- a/src/bindings.c +++ b/src/bindings.c @@ -4,30 +4,38 @@ #include "bindings.h" +#include "magic.h" +#include "skill.h" +#include "helpers.h" +#include "console.h" +#include "reports.h" +#include "study.h" +#include "summary.h" +#include "teleport.h" +#include "laws.h" + #include "kernel/calendar.h" #include "kernel/config.h" #include "kernel/alliance.h" #include "kernel/building.h" +#include "kernel/build.h" #include "kernel/curse.h" #include "kernel/unit.h" #include "kernel/terrain.h" #include "kernel/messages.h" -#include "kernel/region.h" -#include "kernel/building.h" #include "kernel/plane.h" -#include "kernel/race.h" -#include "kernel/item.h" -#include "kernel/order.h" -#include "kernel/ship.h" -#include "kernel/faction.h" +#include "kernel/region.h" #include "kernel/save.h" +#include "kernel/ship.h" #include "kernel/spell.h" +#include "kernel/types.h" +#include "kernel/item.h" +#include "kernel/faction.h" #include "kernel/spellbook.h" #include "races/races.h" #include "bind_unit.h" #include "bind_storage.h" -#include "bind_building.h" #include "bind_message.h" #include "bind_building.h" #include "bind_faction.h" @@ -36,42 +44,31 @@ #include "bind_gmtool.h" #include "bind_region.h" -#include "helpers.h" -#include "console.h" -#include "reports.h" -#include "study.h" -#include "economy.h" -#include "summary.h" -#include "teleport.h" -#include "laws.h" -#include "monsters.h" -#include "market.h" - #include -#include #include #include #include -#include #include #include -#include +#include #include #include #include -#include -#include +#include #include #include #include #include -#include -#include #include +#include +#include +#include +#include +#include #define TOLUA_PKG(NAME) void tolua_##NAME##_open(lua_State * L) diff --git a/src/gmtool.c b/src/gmtool.c index 48a51d354..e4eefd337 100644 --- a/src/gmtool.c +++ b/src/gmtool.c @@ -22,7 +22,6 @@ #include "kernel/building.h" #include "kernel/faction.h" -#include "kernel/item.h" #include "kernel/plane.h" #include "kernel/region.h" #include "kernel/terrainid.h" @@ -45,7 +44,6 @@ #include "teleport.h" #include -#include #include #include #include diff --git a/src/listbox.c b/src/listbox.c index cd7118da7..4aa00adaf 100644 --- a/src/listbox.c +++ b/src/listbox.c @@ -19,6 +19,7 @@ #include +#include #include #include #include From 0759482934e84e4366512b51bad6c285c6c8445f Mon Sep 17 00:00:00 2001 From: Enno Rehling Date: Sun, 23 Sep 2018 19:53:01 +0200 Subject: [PATCH 019/160] clean includes for bindings and main --- src/bind_building.c | 6 ++++-- src/bind_config.c | 4 +--- src/bind_faction.c | 4 ---- src/bind_tolua.c | 2 ++ src/main.c | 18 +++++++++--------- 5 files changed, 16 insertions(+), 18 deletions(-) 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_faction.c b/src/bind_faction.c index eae029f4b..e113d924c 100644 --- a/src/bind_faction.c +++ b/src/bind_faction.c @@ -17,19 +17,16 @@ 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 "kernel/types.h" #include @@ -46,7 +43,6 @@ without prior permission by the authors of Eressea. #include #include #include -#include typedef struct helpmode { const char *name; diff --git a/src/bind_tolua.c b/src/bind_tolua.c index 669d5848b..d681b9088 100644 --- a/src/bind_tolua.c +++ b/src/bind_tolua.c @@ -12,6 +12,8 @@ #include "settings.pkg.c" #pragma warning(pop) +#include + void tolua_bind_open(lua_State * L) { tolua_eressea_open(L); tolua_process_open(L); diff --git a/src/main.c b/src/main.c index bb353fc2f..599fbdd67 100644 --- a/src/main.c +++ b/src/main.c @@ -22,15 +22,11 @@ OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. #include #include -#include #include -#include #include -#include #include #include -#include #include #include "eressea.h" @@ -39,14 +35,18 @@ OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. #endif #include "bindings.h" -#include "races/races.h" -#include "spells.h" + +#include +#include #include -#include + +#include #include +#include +#include +#include #include -#include static const char *logfile = "eressea.log"; static const char *luafile = 0; @@ -302,7 +302,7 @@ void locale_init(void) } } -extern void bind_monsters(struct lua_State *L); +extern void bind_monsters(lua_State *L); int main(int argc, char **argv) { From d70f05f8dbe35877b2550d9d2c27e0c85653e158 Mon Sep 17 00:00:00 2001 From: Enno Rehling Date: Sun, 23 Sep 2018 20:01:12 +0200 Subject: [PATCH 020/160] BUG 2478: Fleeing units cannot move. --- src/battle.c | 62 ++++++++++++++++++++++++++--------------------- src/battle.test.c | 56 +++++++++++++++++++++++++++++++++++++++--- 2 files changed, 87 insertions(+), 31 deletions(-) diff --git a/src/battle.c b/src/battle.c index 8e8c3610b..bf9df9b2b 100644 --- a/src/battle.c +++ b/src/battle.c @@ -101,7 +101,7 @@ typedef enum combatmagic { #define MAXSPELLRANGE 7 #define ROW_FACTOR 3 /* factor for combat row advancement rule */ -#define EFFECT_PANIC_SPELL 0.25 +#define EFFECT_PANIC_SPELL 25 #define TROLL_REGENERATION 0.10 /* Nach dem alten System: */ @@ -126,6 +126,9 @@ const troop no_troop = { 0, 0 }; 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; @@ -144,6 +147,9 @@ 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); @@ -2276,7 +2282,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; @@ -2299,26 +2305,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; @@ -2617,7 +2623,7 @@ static void aftermath(battle * b) } } snumber += du->number; - if (df->alive == 0) { + if (dead == df->unit->number) { flags = UFL_DEAD; } else if (relevant) { @@ -3631,13 +3637,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) { @@ -3881,7 +3895,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); @@ -3906,13 +3919,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))) { - flee(dt); - } + flee(dt); } } } @@ -3966,8 +3973,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.test.c b/src/battle.test.c index 7c7012e77..8cfbb0d2a 100644 --- a/src/battle.test.c +++ b/src/battle.test.c @@ -2,6 +2,8 @@ #include "battle.h" +#include "guard.h" +#include "keyword.h" #include "reports.h" #include "skill.h" @@ -10,6 +12,7 @@ #include #include #include +#include #include #include #include @@ -17,6 +20,7 @@ #include +#include #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; @@ -566,7 +585,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 +616,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 +649,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 +802,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); From 409a3da7cf29aedaabc28d1aad15f10ad433b0de Mon Sep 17 00:00:00 2001 From: Enno Rehling Date: Mon, 24 Sep 2018 11:57:28 +0200 Subject: [PATCH 021/160] more iwyu warnings --- src/console.c | 3 +-- src/helpers.c | 15 ++++++--------- src/helpers.h | 2 -- 3 files changed, 7 insertions(+), 13 deletions(-) diff --git a/src/console.c b/src/console.c index 7a32b83f0..f134b2164 100644 --- a/src/console.c +++ b/src/console.c @@ -5,13 +5,12 @@ /* lua includes */ #include +#include #include -#include /* libc includes */ #include #include -#include #include #include diff --git a/src/helpers.c b/src/helpers.c index 8acabd97c..01fa19abc 100644 --- a/src/helpers.c +++ b/src/helpers.c @@ -17,26 +17,21 @@ without prior permission by the authors of Eressea. #include "helpers.h" #include "vortex.h" #include "alchemy.h" +#include "magic.h" #include -#include #include #include #include #include #include #include -#include +#include -#include #include #include -#include #include -#include -#include #include -#include #include #include @@ -46,8 +41,10 @@ without prior permission by the authors of Eressea. #include #include -#include -#include +#include +#include + +struct order; static int lua_giveitem(unit * s, unit * d, const item_type * itype, int n, struct order *ord) diff --git a/src/helpers.h b/src/helpers.h index d0bbcc58b..a5eccd0f5 100644 --- a/src/helpers.h +++ b/src/helpers.h @@ -14,8 +14,6 @@ without prior permission by the authors of Eressea. extern "C" { #endif - struct lua_State; - void register_tolua_helpers(void); #ifdef __cplusplus From ccc555668210151db807f338ee619b9f9870f58b Mon Sep 17 00:00:00 2001 From: Enno Rehling Date: Mon, 24 Sep 2018 20:18:21 +0200 Subject: [PATCH 022/160] adding code to export faction information. sqlite3 implementation only, not tied to anything yet. add faction.uid remove faction.subscription --- src/battle.c | 2 +- src/bind_faction.c | 6 +- src/bindings.c | 8 --- src/eressea.c | 12 ++++ src/eressea.h | 1 + src/gmtool.c | 3 +- src/kernel/CMakeLists.txt | 16 ++--- src/kernel/connection.c | 2 +- src/kernel/database.c | 5 ++ src/kernel/database.h | 2 + src/kernel/database.test.c | 16 +++++ src/kernel/db/berkeley.c | 5 ++ src/kernel/db/critbit.c | 5 ++ src/kernel/db/driver.h | 1 + src/kernel/db/sqlite.c | 137 ++++++++++++++++++++++++++++--------- src/kernel/faction.c | 8 +-- src/kernel/faction.h | 4 +- src/kernel/faction.test.c | 3 +- src/kernel/save.c | 8 ++- src/laws.c | 27 -------- src/laws.h | 1 - src/main.c | 1 + src/modules/autoseed.c | 12 ++-- src/modules/autoseed.h | 2 +- src/spells.c | 2 +- src/tests.c | 2 +- src/util/gamedata.h | 3 +- 27 files changed, 190 insertions(+), 104 deletions(-) diff --git a/src/battle.c b/src/battle.c index bf9df9b2b..aa5de9f71 100644 --- a/src/battle.c +++ b/src/battle.c @@ -3659,7 +3659,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; } diff --git a/src/bind_faction.c b/src/bind_faction.c index e113d924c..850679933 100644 --- a/src/bind_faction.c +++ b/src/bind_faction.c @@ -432,7 +432,7 @@ static int tolua_faction_create(lua_State * L) 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); @@ -528,14 +528,14 @@ static int tolua_faction_set_name(lua_State * L) static int tolua_faction_get_uid(lua_State * L) { faction *f = (faction *)tolua_tousertype(L, 1, 0); - lua_pushinteger(L, f->subscription); + 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); + f->uid = (int)tolua_tonumber(L, 2, 0); return 0; } diff --git a/src/bindings.c b/src/bindings.c index 60519260a..c549a4801 100755 --- a/src/bindings.c +++ b/src/bindings.c @@ -339,13 +339,6 @@ static int tolua_update_owners(lua_State * L) return 0; } -static int tolua_update_subscriptions(lua_State * L) -{ - UNUSED_ARG(L); - update_subscriptions(); - return 0; -} - static int tolua_remove_empty_units(lua_State * L) { UNUSED_ARG(L); @@ -972,7 +965,6 @@ int tolua_bindings_open(lua_State * L, const dictionary *inifile) tolua_function(L, TOLUA_CAST "dice_roll", tolua_dice_rand); tolua_function(L, TOLUA_CAST "get_nmrs", tolua_get_nmrs); tolua_function(L, TOLUA_CAST "remove_empty_units", tolua_remove_empty_units); - tolua_function(L, TOLUA_CAST "update_subscriptions", tolua_update_subscriptions); tolua_function(L, TOLUA_CAST "update_scores", tolua_update_scores); tolua_function(L, TOLUA_CAST "update_owners", tolua_update_owners); tolua_function(L, TOLUA_CAST "learn_skill", tolua_learn_skill); diff --git a/src/eressea.c b/src/eressea.c index 0bf1454ee..67ab26af5 100644 --- a/src/eressea.c +++ b/src/eressea.c @@ -39,6 +39,18 @@ /* manually free() everything at exit? */ #undef CLEANUP_CODE +void game_write_dbstate(void) +{ + faction *f; + + for (f = factions; f; f = f->next) { + int uid = dblib_save_faction(f, turn); + if (uid > 0) { + f->uid = uid; + } + } +} + void game_done(void) { log_dead_factions(); diff --git a/src/eressea.h b/src/eressea.h index f3ea4d4a5..cfc1b12ef 100755 --- a/src/eressea.h +++ b/src/eressea.h @@ -6,6 +6,7 @@ extern "C" { void game_init(void); void game_done(void); + void game_write_dbstate(void); #ifdef __cplusplus } diff --git a/src/gmtool.c b/src/gmtool.c index e4eefd337..f841fa305 100644 --- a/src/gmtool.c +++ b/src/gmtool.c @@ -920,8 +920,7 @@ static void seed_player(state *st, const newfaction *player) { if (r) { faction *f; addplayer(r, f = addfaction(player->email, player->password, - player->race, player->lang, - player->subscription)); + player->race, player->lang)); } } } diff --git a/src/kernel/CMakeLists.txt b/src/kernel/CMakeLists.txt index 86c2fb90c..db448bf11 100644 --- a/src/kernel/CMakeLists.txt +++ b/src/kernel/CMakeLists.txt @@ -1,6 +1,14 @@ cmake_minimum_required(VERSION 2.6) project(kernel C) +SET(_DBFILES db/critbit.c) + +IF(SQLITE3_FOUND) +SET(_DBFILES db/sqlite.c) +ELSEIF(DB_FOUND) +SET(_DBFILES db/berkeley.c) +ENDIF(SQLITE3_FOUND) + SET(_TEST_FILES alliance.test.c ally.test.c @@ -35,14 +43,6 @@ spell.test.c unit.test.c ) -SET(_DBFILES db/critbit.c) - -IF(SQLITE3_FOUND) -SET(_DBFILES db/sqlite.c) -ELSEIF(DB_FOUND) -SET(_DBFILES db/berkeley.c) -ENDIF(SQLITE3_FOUND) - SET(_FILES ${_DBFILES} alliance.c diff --git a/src/kernel/connection.c b/src/kernel/connection.c index 213700fe1..ddaf163c1 100644 --- a/src/kernel/connection.c +++ b/src/kernel/connection.c @@ -440,7 +440,7 @@ static const char *b_nameillusionwall(const connection * b, const region * r, return (f && fno == f->no) ? "illusionwall" : "wall"; if (gflags & GF_ARTICLE) { return LOC(f->locale, mkname("border", (f - && fno == f->subscription) ? "an_illusionwall" : "a_wall")); + && fno == f->uid) ? "an_illusionwall" : "a_wall")); } return LOC(f->locale, mkname("border", (f && fno == f->no) ? "illusionwall" : "wall")); diff --git a/src/kernel/database.c b/src/kernel/database.c index eaf695613..c27ca21fc 100644 --- a/src/kernel/database.c +++ b/src/kernel/database.c @@ -4,6 +4,7 @@ #include #include +#include #include #include @@ -27,6 +28,10 @@ int dblib_save_order(order_data *od) return 0; } +int dblib_save_faction(const faction *f, int turn) { + return db_driver_faction_save(f->uid, f->no, turn, f->email, f->_password); +} + void dblib_open(void) { db_driver_open(); diff --git a/src/kernel/database.h b/src/kernel/database.h index 0dd5a70fb..e3bdf11d1 100644 --- a/src/kernel/database.h +++ b/src/kernel/database.h @@ -8,12 +8,14 @@ extern "C" { #endif struct order_data; + struct faction; void dblib_open(void); void dblib_close(void); struct order_data *dblib_load_order(int id); int dblib_save_order(struct order_data *od); + int dblib_save_faction(const struct faction *f, int turn); #ifdef __cplusplus } diff --git a/src/kernel/database.test.c b/src/kernel/database.test.c index 2e1104185..cde4edc11 100644 --- a/src/kernel/database.test.c +++ b/src/kernel/database.test.c @@ -1,5 +1,6 @@ #include #include +#include #include "database.h" #include "orderdb.h" @@ -7,6 +8,7 @@ #include #include +#include #include static void test_save_load_order(CuTest *tc) { @@ -31,10 +33,24 @@ static void test_save_load_order(CuTest *tc) { test_teardown(); } +static void test_update_faction(CuTest *tc) { + faction *f; + int uid; + + test_setup(); + f = test_create_faction(NULL); + uid = dblib_save_faction(f, 0); + f->uid = uid; + uid = dblib_save_faction(f, 0); + CuAssertIntEquals(tc, f->uid, uid); + test_teardown(); +} + CuSuite *get_db_suite(void) { CuSuite *suite = CuSuiteNew(); SUITE_ADD_TEST(suite, test_save_load_order); + SUITE_ADD_TEST(suite, test_update_faction); return suite; } diff --git a/src/kernel/db/berkeley.c b/src/kernel/db/berkeley.c index 210c36f01..778e0bfe7 100644 --- a/src/kernel/db/berkeley.c +++ b/src/kernel/db/berkeley.c @@ -53,6 +53,11 @@ int db_driver_order_save(struct order_data *od) return (int)recno; } +int db_driver_faction_save(int id, int no, int turn, const char *email, const char *password) +{ + return -1; +} + struct order_data *db_driver_order_load(int id) { int ret; diff --git a/src/kernel/db/critbit.c b/src/kernel/db/critbit.c index 9afb0926d..69bac159e 100644 --- a/src/kernel/db/critbit.c +++ b/src/kernel/db/critbit.c @@ -44,6 +44,11 @@ int db_driver_order_save(order_data *od) return ent.id; } +int db_driver_faction_save(int id, int no, int turn, const char *email, const char *password) +{ + return -1; +} + static int free_data_cb(const void *match, const void *key, size_t keylen, void *udata) { diff --git a/src/kernel/db/driver.h b/src/kernel/db/driver.h index df839b93d..1e408e37e 100644 --- a/src/kernel/db/driver.h +++ b/src/kernel/db/driver.h @@ -6,3 +6,4 @@ void db_driver_open(void); void db_driver_close(void); int db_driver_order_save(struct order_data *od); struct order_data *db_driver_order_load(int id); +int db_driver_faction_save(int id, int no, int turn, const char *email, const char *password); diff --git a/src/kernel/db/sqlite.c b/src/kernel/db/sqlite.c index b3090cca0..49dbd001e 100644 --- a/src/kernel/db/sqlite.c +++ b/src/kernel/db/sqlite.c @@ -15,9 +15,12 @@ #include #include -static sqlite3 *g_db; -static sqlite3_stmt * g_stmt_insert; -static sqlite3_stmt * g_stmt_select; +static sqlite3 *g_game_db; +static sqlite3 *g_temp_db; +static sqlite3_stmt * g_stmt_insert_order; +static sqlite3_stmt * g_stmt_select_order; +static sqlite3_stmt * g_stmt_update_faction; +static sqlite3_stmt * g_stmt_insert_faction; static int g_order_batchsize; static int g_order_tx_size; @@ -30,21 +33,21 @@ order_data *db_driver_order_load(int id) ERRNO_CHECK(); if (g_order_tx_size > 0) { g_order_tx_size = 0; - err = sqlite3_exec(g_db, "COMMIT", NULL, NULL, NULL); + err = sqlite3_exec(g_temp_db, "COMMIT", NULL, NULL, NULL); assert(err == SQLITE_OK); } - err = sqlite3_reset(g_stmt_select); + err = sqlite3_reset(g_stmt_select_order); assert(err == SQLITE_OK); - err = sqlite3_bind_int(g_stmt_select, 1, id); + err = sqlite3_bind_int(g_stmt_select_order, 1, id); assert(err == SQLITE_OK); do { - err = sqlite3_step(g_stmt_select); + err = sqlite3_step(g_stmt_select_order); if (err == SQLITE_ROW) { const unsigned char *text; int bytes; - bytes = sqlite3_column_bytes(g_stmt_select, 0); + bytes = sqlite3_column_bytes(g_stmt_select_order, 0); assert(bytes > 0); - text = sqlite3_column_text(g_stmt_select, 0); + text = sqlite3_column_text(g_stmt_select_order, 0); odata_create(&od, 1+(size_t)bytes, (const char *)text); ERRNO_CHECK(); return od; @@ -66,23 +69,23 @@ int db_driver_order_save(order_data *od) if (g_order_batchsize > 0) { if (g_order_tx_size == 0) { - err = sqlite3_exec(g_db, "BEGIN TRANSACTION", NULL, NULL, NULL); + err = sqlite3_exec(g_temp_db, "BEGIN TRANSACTION", NULL, NULL, NULL); assert(err == SQLITE_OK); } } - err = sqlite3_reset(g_stmt_insert); + err = sqlite3_reset(g_stmt_insert_order); assert(err == SQLITE_OK); - err = sqlite3_bind_text(g_stmt_insert, 1, od->_str, -1, SQLITE_STATIC); + err = sqlite3_bind_text(g_stmt_insert_order, 1, od->_str, -1, SQLITE_STATIC); assert(err == SQLITE_OK); - err = sqlite3_step(g_stmt_insert); + err = sqlite3_step(g_stmt_insert_order); assert(err == SQLITE_DONE); - id = sqlite3_last_insert_rowid(g_db); + id = sqlite3_last_insert_rowid(g_temp_db); assert(id <= INT_MAX); if (g_order_batchsize > 0) { if (++g_order_tx_size >= g_order_batchsize) { - err = sqlite3_exec(g_db, "COMMIT", NULL, NULL, NULL); + err = sqlite3_exec(g_temp_db, "COMMIT", NULL, NULL, NULL); assert(err == SQLITE_OK); g_order_tx_size = 0; } @@ -91,29 +94,89 @@ int db_driver_order_save(order_data *od) return (int)id; } + +int db_driver_faction_save(int id, int no, int turn, const char *email, const char *password) +{ + sqlite3_int64 row_id; + int err; + + if (!g_game_db) { + return -1; + } + if (id != 0) { + int rows; + + err = sqlite3_reset(g_stmt_update_faction); + assert(err == SQLITE_OK); + err = sqlite3_bind_int(g_stmt_update_faction, 1, no); + assert(err == SQLITE_OK); + err = sqlite3_bind_int(g_stmt_update_faction, 2, turn); + assert(err == SQLITE_OK); + err = sqlite3_bind_text(g_stmt_update_faction, 3, email, -1, SQLITE_STATIC); + assert(err == SQLITE_OK); + err = sqlite3_bind_text(g_stmt_update_faction, 4, password, -1, SQLITE_STATIC); + assert(err == SQLITE_OK); + err = sqlite3_bind_int(g_stmt_update_faction, 5, id); + assert(err == SQLITE_OK); + err = sqlite3_step(g_stmt_update_faction); + assert(err == SQLITE_DONE); + rows = sqlite3_changes(g_game_db); + if (rows != 0) { + return id; + } + } + err = sqlite3_reset(g_stmt_insert_faction); + assert(err == SQLITE_OK); + err = sqlite3_bind_int(g_stmt_insert_faction, 1, no); + assert(err == SQLITE_OK); + err = sqlite3_bind_int(g_stmt_insert_faction, 2, turn); + assert(err == SQLITE_OK); + err = sqlite3_bind_text(g_stmt_insert_faction, 3, email, -1, SQLITE_STATIC); + assert(err == SQLITE_OK); + err = sqlite3_bind_text(g_stmt_insert_faction, 4, password, -1, SQLITE_STATIC); + assert(err == SQLITE_OK); + err = sqlite3_step(g_stmt_insert_faction); + assert(err == SQLITE_DONE); + ERRNO_CHECK(); + + row_id = sqlite3_last_insert_rowid(g_game_db); + assert(row_id <= INT_MAX); + return (int)row_id; +} + void db_driver_open(void) { int err; - const char *dbname; + const char *dbname, *dbtemp; ERRNO_CHECK(); - g_order_batchsize = config_get_int("game.dbbatch", 100); + dbname = config_get("game.dbname"); - if (!dbname) { - dbname = ""; - } - err = sqlite3_open(dbname, &g_db); + if (!dbname) dbname = ""; + err = sqlite3_open(dbname, &g_game_db); assert(err == SQLITE_OK); - err = sqlite3_exec(g_db, "PRAGMA journal_mode=OFF", NULL, NULL, NULL); + err = sqlite3_exec(g_game_db, "CREATE TABLE IF NOT EXISTS factions (id INTEGER PRIMARY KEY, no INTEGER NOT NULL, email VARCHAR(128), password VARCHAR(128), turn INTEGER NOT NULL)", NULL, NULL, NULL); assert(err == SQLITE_OK); - err = sqlite3_exec(g_db, "PRAGMA synchronous=OFF", NULL, NULL, NULL); + err = sqlite3_prepare_v2(g_game_db, "UPDATE factions SET no=?, turn=?, email=?, password=? WHERE id=?", -1, &g_stmt_update_faction, NULL); assert(err == SQLITE_OK); - err = sqlite3_exec(g_db, "CREATE TABLE IF NOT EXISTS orders (id INTEGER PRIMARY KEY, data TEXT NOT NULL)", NULL, NULL, NULL); + err = sqlite3_prepare_v2(g_game_db, "INSERT INTO factions (no, turn, email, password) VALUES (?,?,?,?)", -1, &g_stmt_insert_faction, NULL); assert(err == SQLITE_OK); - err = sqlite3_prepare_v2(g_db, "INSERT INTO orders (data) VALUES (?)", -1, &g_stmt_insert, NULL); + + g_order_batchsize = config_get_int("game.dbbatch", 100); + dbtemp = config_get("game.db.temp"); + err = sqlite3_open(dbtemp ? dbtemp : dbname, &g_temp_db); assert(err == SQLITE_OK); - err = sqlite3_prepare_v2(g_db, "SELECT data FROM orders WHERE id = ?", -1, &g_stmt_select, NULL); + err = sqlite3_exec(g_temp_db, "PRAGMA journal_mode=OFF", NULL, NULL, NULL); assert(err == SQLITE_OK); + err = sqlite3_exec(g_temp_db, "PRAGMA synchronous=OFF", NULL, NULL, NULL); + assert(err == SQLITE_OK); + err = sqlite3_exec(g_temp_db, "CREATE TABLE IF NOT EXISTS orders (id INTEGER PRIMARY KEY, data TEXT NOT NULL)", NULL, NULL, NULL); + assert(err == SQLITE_OK); + err = sqlite3_prepare_v2(g_temp_db, "INSERT INTO orders (data) VALUES (?)", -1, &g_stmt_insert_order, NULL); + assert(err == SQLITE_OK); + err = sqlite3_prepare_v2(g_temp_db, "SELECT data FROM orders WHERE id=?", -1, &g_stmt_select_order, NULL); + assert(err == SQLITE_OK); + ERRNO_CHECK(); } @@ -122,12 +185,22 @@ void db_driver_close(void) int err; ERRNO_CHECK(); - err = sqlite3_finalize(g_stmt_select); - assert(err == SQLITE_OK); - err = sqlite3_finalize(g_stmt_insert); - assert(err == SQLITE_OK); - err = sqlite3_close(g_db); - assert(err == SQLITE_OK); + if (g_temp_db) { + err = sqlite3_finalize(g_stmt_select_order); + assert(err == SQLITE_OK); + err = sqlite3_finalize(g_stmt_insert_order); + assert(err == SQLITE_OK); + err = sqlite3_close(g_temp_db); + assert(err == SQLITE_OK); + } + if (g_game_db) { + err = sqlite3_finalize(g_stmt_update_faction); + assert(err == SQLITE_OK); + err = sqlite3_finalize(g_stmt_insert_faction); + assert(err == SQLITE_OK); + err = sqlite3_close(g_game_db); + assert(err == SQLITE_OK); + } ERRNO_CHECK(); } diff --git a/src/kernel/faction.c b/src/kernel/faction.c index b4dfe51ca..8c77984ba 100755 --- a/src/kernel/faction.c +++ b/src/kernel/faction.c @@ -230,7 +230,7 @@ static int unused_faction_id(void) } faction *addfaction(const char *email, const char *password, - const struct race * frace, const struct locale * loc, int subscription) + const struct race * frace, const struct locale * loc) { faction *f = calloc(sizeof(faction), 1); char buf[128]; @@ -249,7 +249,7 @@ faction *addfaction(const char *email, const char *password, f->race = frace; f->magiegebiet = 0; f->locale = loc; - f->subscription = subscription; + f->uid = 0; f->flags = FFL_ISNEW|FFL_PWMSG; if (!password) password = itoa36(rng_int()); @@ -393,7 +393,7 @@ faction *get_or_create_monsters(void) if (!f) { const race *rc = rc_get_or_create("dragon"); const char *email = config_get("monster.email"); - f = addfaction(email, NULL, rc, default_locale, 0); + f = addfaction(email, NULL, rc, default_locale); renumber_faction(f, MONSTER_ID); faction_setname(f, "Monster"); fset(f, FFL_NPC | FFL_NOIDLEOUT); @@ -839,7 +839,7 @@ int writepasswd(void) for (f = factions; f; f = f->next) { fprintf(F, "%s:%s:%s:%d\n", - itoa36(f->no), faction_getemail(f), f->_password, f->subscription); + itoa36(f->no), faction_getemail(f), f->_password, f->uid); } fclose(F); return 0; diff --git a/src/kernel/faction.h b/src/kernel/faction.h index 8d13f64d1..63c5a9993 100644 --- a/src/kernel/faction.h +++ b/src/kernel/faction.h @@ -61,7 +61,7 @@ extern "C" { struct region *first; struct region *last; int no; - int subscription; + int uid; int flags; char *name; char *banner; @@ -112,7 +112,7 @@ extern "C" { const char *factionname(const struct faction *f); struct unit *addplayer(struct region *r, faction * f); struct faction *addfaction(const char *email, const char *password, - const struct race *frace, const struct locale *loc, int subscription); + const struct race *frace, const struct locale *loc); bool checkpasswd(const faction * f, const char *passwd); int writepasswd(void); void destroyfaction(faction ** f); diff --git a/src/kernel/faction.test.c b/src/kernel/faction.test.c index 37ec70e50..6f3c5cfaf 100644 --- a/src/kernel/faction.test.c +++ b/src/kernel/faction.test.c @@ -112,7 +112,7 @@ static void test_addfaction(CuTest *tc) { test_setup(); rc = rc_get_or_create("human"); lang = test_create_locale(); - f = addfaction("test@eressea.de", "hurrdurr", rc, lang, 1234); + f = addfaction("test@eressea.de", "hurrdurr", rc, lang); CuAssertPtrNotNull(tc, f); CuAssertPtrNotNull(tc, f->name); CuAssertPtrEquals(tc, NULL, (void *)f->units); @@ -124,7 +124,6 @@ static void test_addfaction(CuTest *tc) { CuAssertStrEquals(tc, "test@eressea.de", f->email); CuAssertTrue(tc, checkpasswd(f, "hurrdurr")); CuAssertPtrEquals(tc, (void *)lang, (void *)f->locale); - CuAssertIntEquals(tc, 1234, f->subscription); CuAssertIntEquals(tc, FFL_ISNEW|FFL_PWMSG, f->flags); CuAssertIntEquals(tc, 0, f->age); CuAssertTrue(tc, faction_alive(f)); diff --git a/src/kernel/save.c b/src/kernel/save.c index 51585f26c..922fcc24f 100644 --- a/src/kernel/save.c +++ b/src/kernel/save.c @@ -969,7 +969,10 @@ faction *read_faction(gamedata * data) a_remove(&f->attribs, f->attribs); } } - READ_INT(data->store, &f->subscription); + READ_INT(data->store, &f->uid); + if (data->version < FACTION_UID_VERSION) { + f->uid = 0; + } if (data->version >= SPELL_LEVEL_VERSION) { READ_INT(data->store, &f->max_spelllevel); @@ -1100,7 +1103,7 @@ void write_faction(gamedata *data, const faction * f) assert(f->_alive); assert(f->no > 0 && f->no <= MAX_UNIT_NR); WRITE_INT(data->store, f->no); - WRITE_INT(data->store, f->subscription); + WRITE_INT(data->store, f->uid); #if RELEASE_VERSION >= SPELL_LEVEL_VERSION WRITE_INT(data->store, f->max_spelllevel); #endif @@ -1681,6 +1684,5 @@ int write_game(gamedata *data) { WRITE_SECTION(store); write_borders(store); WRITE_SECTION(store); - return 0; } diff --git a/src/laws.c b/src/laws.c index 922f4c366..fe97931ad 100644 --- a/src/laws.c +++ b/src/laws.c @@ -3974,33 +3974,6 @@ void turn_end(void) update_spells(); } -void update_subscriptions(void) -{ - FILE *F; - char zText[4096]; - - path_join(basepath(), "subscriptions", zText, sizeof(zText)); - F = fopen(zText, "r"); - if (F == NULL) { - log_warning(0, "could not open %s.\n", zText); - return; - } - for (;;) { - char zFaction[5]; - int subscription, fno; - faction *f; - - if (fscanf(F, "%4d %4s", &subscription, zFaction) <= 0) - break; - fno = atoi36(zFaction); - f = findfaction(fno); - if (f != NULL) { - f->subscription = subscription; - } - } - fclose(F); -} - /** determine if unit can be seen by faction * @param f -- the observiong faction * @param u -- the unit that is observed diff --git a/src/laws.h b/src/laws.h index b7958891f..383b099ae 100755 --- a/src/laws.h +++ b/src/laws.h @@ -41,7 +41,6 @@ extern "C" { void demographics(void); void immigration(void); void update_guards(void); - void update_subscriptions(void); void deliverMail(struct faction *f, struct region *r, struct unit *u, const char *s, struct unit *receiver); diff --git a/src/main.c b/src/main.c index 599fbdd67..eae7f440c 100644 --- a/src/main.c +++ b/src/main.c @@ -96,6 +96,7 @@ static const char * valid_keys[] = { "game.era", "game.sender", "game.dbname", + "game.db.", "game.dbbatch", "editor.color", "editor.codepage", diff --git a/src/modules/autoseed.c b/src/modules/autoseed.c index 374b6379c..df4e543ce 100644 --- a/src/modules/autoseed.c +++ b/src/modules/autoseed.c @@ -95,7 +95,7 @@ newfaction *read_newfactions(const char *filename) faction *f; char race[20], email[64], lang[8], password[16]; newfaction *nf, **nfi; - int alliance = 0, subscription = 0; + int alliance = 0, uid = 0; if (fgets(buf, sizeof(buf), F) == NULL) break; @@ -104,7 +104,7 @@ newfaction *read_newfactions(const char *filename) password[0] = '\0'; if (sscanf(buf, "%54s %19s %7s %15s %4d %4d", email, race, lang, - password, &subscription, &alliance) < 3) { + password, &uid, &alliance) < 3) { break; } if (email[0] == '#') { @@ -137,13 +137,13 @@ newfaction *read_newfactions(const char *filename) if (check_email(email) == 0) { nf->email = str_strdup(email); } else { - log_error("Invalid email address for subscription %s: %s\n", itoa36(subscription), email); + log_error("Invalid email address for subscription %s: %s\n", itoa36(uid), email); free(nf); continue; } nf->password = str_strdup(password); nf->race = rc_find(race); - nf->subscription = subscription; + nf->uid = uid; if (alliances != NULL) { struct alliance *al = findalliance(alliance); if (al == NULL) { @@ -557,7 +557,7 @@ int autoseed(newfaction ** players, int nsize, int max_agediff) ++tsize; assert(r->land && r->units == 0); u = addplayer(r, addfaction(nextf->email, nextf->password, nextf->race, - nextf->lang, nextf->subscription)); + nextf->lang)); f = u->faction; fset(f, FFL_ISNEW); f->alliance = nextf->allies; @@ -857,7 +857,7 @@ static void starting_region(newfaction ** players, region * r, region * rn[]) const struct race *rc = nf->race ? nf->race : races; const struct locale *lang = nf->lang ? nf->lang : default_locale; const char * passwd = nf->password ? nf->password : itoa36(rng_int()); - addplayer(r, addfaction(nf->email, passwd, rc, lang, 0)); + addplayer(r, addfaction(nf->email, passwd, rc, lang)); *players = nf->next; free_newfaction(nf); } diff --git a/src/modules/autoseed.h b/src/modules/autoseed.h index 937a1f8b5..74c7409ad 100644 --- a/src/modules/autoseed.h +++ b/src/modules/autoseed.h @@ -24,7 +24,7 @@ extern "C" { char *password; const struct locale *lang; const struct race *race; - int subscription; + int uid; bool oldregions; struct alliance *allies; } newfaction; diff --git a/src/spells.c b/src/spells.c index 8caf29039..02cbe43b5 100644 --- a/src/spells.c +++ b/src/spells.c @@ -4192,7 +4192,7 @@ static int sp_calm_monster(castorder * co) return 0; } - effect = mage->faction->subscription; + effect = mage->faction->uid; c = create_curse(mage, &target->attribs, &ct_calmmonster, force, (int)force, effect, 0); if (c == NULL) { diff --git a/src/tests.c b/src/tests.c index ddd6f7cf5..2dc5bccc6 100644 --- a/src/tests.c +++ b/src/tests.c @@ -166,7 +166,7 @@ struct locale * test_create_locale(void) { struct faction *test_create_faction(const struct race *rc) { struct locale * loc = test_create_locale(); - faction *f = addfaction("nobody@eressea.de", NULL, rc ? rc : test_create_race("human"), loc, 0); + faction *f = addfaction("nobody@eressea.de", NULL, rc ? rc : test_create_race("human"), loc); test_clear_messages(f); return f; } diff --git a/src/util/gamedata.h b/src/util/gamedata.h index 2dd4e1342..191dab054 100644 --- a/src/util/gamedata.h +++ b/src/util/gamedata.h @@ -37,10 +37,11 @@ #define SKILLSORT_VERSION 360 /* u->skills is sorted */ #define LANDDISPLAY_VERSION 360 /* r.display is now in r.land.display */ #define FIXATKEYS_VERSION 361 /* remove global.attribs, fix at_keys */ +#define FACTION_UID_VERSION 362 /* f->uid contains a database id */ /* unfinished: */ #define CRYPT_VERSION 400 /* passwords are encrypted */ -#define RELEASE_VERSION FIXATKEYS_VERSION /* current datafile */ +#define RELEASE_VERSION FACTION_UID_VERSION /* current datafile */ #define MIN_VERSION UIDHASH_VERSION /* minimal datafile we support */ #define MAX_VERSION RELEASE_VERSION /* change this if we can need to read the future datafile, and we can do so */ From 8cccef41ad4976e1e7d8457b3f1a7a744f9698ba Mon Sep 17 00:00:00 2001 From: Enno Rehling Date: Tue, 25 Sep 2018 18:02:00 +0200 Subject: [PATCH 023/160] sort cmakelists filenames --- .editorconfig | 5 ++++ src/CMakeLists.txt | 72 +++++++++++++++++++++++----------------------- 2 files changed, 41 insertions(+), 36 deletions(-) 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/src/CMakeLists.txt b/src/CMakeLists.txt index 96351cdc9..9502cc4bf 100644 --- a/src/CMakeLists.txt +++ b/src/CMakeLists.txt @@ -86,48 +86,48 @@ ENDIF() set (ERESSEA_SRC vortex.c - automate.c - move.c - piracy.c - spells.c - battle.c - alchemy.c academy.c + alchemy.c + automate.c + battle.c chaos.c - upkeep.c - names.c - lighthouse.c - reports.c - teleport.c - guard.c - jsonconf.c - prefix.c - donations.c - eressea.c - direction.c - keyword.c - skill.c - json.c creport.c - report.c - steal.c + direction.c + donations.c economy.c + eressea.c exparse.c give.c + guard.c items.c + json.c + jsonconf.c + keyword.c laws.c + lighthouse.c magic.c market.c + monsters.c morale.c + move.c + names.c orderfile.c + piracy.c + prefix.c randenc.c renumber.c - volcano.c + report.c + reports.c + skill.c + spells.c spy.c + steal.c study.c summary.c travelthru.c - monsters.c + teleport.c + upkeep.c + volcano.c wormhole.c ${SPELLS_SRC} ${RACES_SRC} @@ -141,31 +141,31 @@ set (ERESSEA_SRC ) set(SERVER_SRC - main.c - console.c - helpers.c - bind_tolua.c bind_building.c bind_config.c - bind_locale.c bind_eressea.c bind_faction.c - bind_order.c - bindings.c + bind_locale.c bind_message.c bind_monsters.c + bind_order.c bind_process.c bind_region.c bind_ship.c bind_storage.c + bind_tolua.c bind_unit.c + bindings.c + console.c + helpers.c + main.c ) if (CURSES_FOUND) set (SERVER_SRC ${SERVER_SRC} + bind_gmtool.c gmtool.c listbox.c - bind_gmtool.c ) endif(CURSES_FOUND) @@ -193,8 +193,6 @@ target_link_libraries(eressea ) set(TESTS_SRC - test_eressea.c - tests.c academy.test.c alchemy.test.c automate.test.c @@ -219,13 +217,15 @@ set(TESTS_SRC piracy.test.c prefix.test.c renumber.test.c - reports.test.c report.test.c - summary.test.c + reports.test.c skill.test.c spells.test.c spy.test.c study.test.c + summary.test.c + test_eressea.c + tests.c tests.test.c travelthru.test.c upkeep.test.c From 274d44ee183c3c43b6aa75b02dfd4e20bb6e7a07 Mon Sep 17 00:00:00 2001 From: Enno Rehling Date: Tue, 25 Sep 2018 18:07:02 +0200 Subject: [PATCH 024/160] Move the gamedb to a separate file. --- src/CMakeLists.txt | 1 + src/eressea.c | 12 ------------ src/eressea.h | 1 - src/gamedb.c | 20 ++++++++++++++++++++ src/gamedb.h | 3 +++ 5 files changed, 24 insertions(+), 13 deletions(-) create mode 100644 src/gamedb.c create mode 100644 src/gamedb.h diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt index 9502cc4bf..7b50907f9 100644 --- a/src/CMakeLists.txt +++ b/src/CMakeLists.txt @@ -97,6 +97,7 @@ set (ERESSEA_SRC economy.c eressea.c exparse.c + gamedb.c give.c guard.c items.c diff --git a/src/eressea.c b/src/eressea.c index 67ab26af5..0bf1454ee 100644 --- a/src/eressea.c +++ b/src/eressea.c @@ -39,18 +39,6 @@ /* manually free() everything at exit? */ #undef CLEANUP_CODE -void game_write_dbstate(void) -{ - faction *f; - - for (f = factions; f; f = f->next) { - int uid = dblib_save_faction(f, turn); - if (uid > 0) { - f->uid = uid; - } - } -} - void game_done(void) { log_dead_factions(); diff --git a/src/eressea.h b/src/eressea.h index cfc1b12ef..f3ea4d4a5 100755 --- a/src/eressea.h +++ b/src/eressea.h @@ -6,7 +6,6 @@ extern "C" { void game_init(void); void game_done(void); - void game_write_dbstate(void); #ifdef __cplusplus } diff --git a/src/gamedb.c b/src/gamedb.c new file mode 100644 index 000000000..cf9a922bc --- /dev/null +++ b/src/gamedb.c @@ -0,0 +1,20 @@ +#ifdef _MSC_VER +#include +#endif + +#include "gamedb.h" + +#include "kernel/database.h" +#include "kernel/faction.h" + +void gamedb_update(void) +{ + faction *f; + + for (f = factions; f; f = f->next) { + int uid = dblib_save_faction(f, turn); + if (uid > 0) { + f->uid = uid; + } + } +} diff --git a/src/gamedb.h b/src/gamedb.h new file mode 100644 index 000000000..ea4614298 --- /dev/null +++ b/src/gamedb.h @@ -0,0 +1,3 @@ +#pragma once + +void gamedb_update(void); From 4e5240628ee6f3a3b3adb8d6c492833c0a912a48 Mon Sep 17 00:00:00 2001 From: Enno Rehling Date: Tue, 25 Sep 2018 18:52:29 +0200 Subject: [PATCH 025/160] Extract gamedb open/close to separate functions. --- src/gamedb.c | 20 +++++++++++++++----- src/kernel/database.c | 7 +++++-- src/kernel/db/driver.h | 9 +++++++-- src/kernel/db/sqlite.c | 42 +++++++++++++++++++++++++++++------------- 4 files changed, 56 insertions(+), 22 deletions(-) diff --git a/src/gamedb.c b/src/gamedb.c index cf9a922bc..e3c16b06e 100644 --- a/src/gamedb.c +++ b/src/gamedb.c @@ -4,17 +4,27 @@ #include "gamedb.h" +#include "kernel/db/driver.h" #include "kernel/database.h" #include "kernel/faction.h" -void gamedb_update(void) +int gamedb_update(void) { faction *f; + int err; + const char *dbname; - for (f = factions; f; f = f->next) { - int uid = dblib_save_faction(f, turn); - if (uid > 0) { - f->uid = uid; + dbname = config_get("game.dbname"); + + err = db_driver_open(DB_GAME, dbname); + if (err == 0) { + for (f = factions; f; f = f->next) { + int uid = dblib_save_faction(f, turn); + if (uid > 0) { + f->uid = uid; + } } + db_driver_close(DB_GAME); } + return err; } diff --git a/src/kernel/database.c b/src/kernel/database.c index c27ca21fc..137665e31 100644 --- a/src/kernel/database.c +++ b/src/kernel/database.c @@ -34,10 +34,13 @@ int dblib_save_faction(const faction *f, int turn) { void dblib_open(void) { - db_driver_open(); + const char *dbname; + + dbname = config_get("game.dbswap"); + db_driver_open(DB_SWAP, dbname); } void dblib_close(void) { - db_driver_close(); + db_driver_close(DB_SWAP); } diff --git a/src/kernel/db/driver.h b/src/kernel/db/driver.h index 1e408e37e..26b0461e3 100644 --- a/src/kernel/db/driver.h +++ b/src/kernel/db/driver.h @@ -2,8 +2,13 @@ struct order_data; -void db_driver_open(void); -void db_driver_close(void); +typedef enum database_t { + DB_SWAP, + DB_GAME, +} database_t; + +int db_driver_open(database_t db, const char *dbname); +void db_driver_close(database_t db); int db_driver_order_save(struct order_data *od); struct order_data *db_driver_order_load(int id); int db_driver_faction_save(int id, int no, int turn, const char *email, const char *password); diff --git a/src/kernel/db/sqlite.c b/src/kernel/db/sqlite.c index 49dbd001e..70cacaf48 100644 --- a/src/kernel/db/sqlite.c +++ b/src/kernel/db/sqlite.c @@ -144,15 +144,9 @@ int db_driver_faction_save(int id, int no, int turn, const char *email, const ch return (int)row_id; } -void db_driver_open(void) -{ +static int db_open_game(const char *dbname) { int err; - const char *dbname, *dbtemp; - ERRNO_CHECK(); - - dbname = config_get("game.dbname"); - if (!dbname) dbname = ""; err = sqlite3_open(dbname, &g_game_db); assert(err == SQLITE_OK); err = sqlite3_exec(g_game_db, "CREATE TABLE IF NOT EXISTS factions (id INTEGER PRIMARY KEY, no INTEGER NOT NULL, email VARCHAR(128), password VARCHAR(128), turn INTEGER NOT NULL)", NULL, NULL, NULL); @@ -162,9 +156,16 @@ void db_driver_open(void) err = sqlite3_prepare_v2(g_game_db, "INSERT INTO factions (no, turn, email, password) VALUES (?,?,?,?)", -1, &g_stmt_insert_faction, NULL); assert(err == SQLITE_OK); + ERRNO_CHECK(); + return 0; +} + +static int db_open_swap(const char *dbname) { + int err; + g_order_batchsize = config_get_int("game.dbbatch", 100); - dbtemp = config_get("game.db.temp"); - err = sqlite3_open(dbtemp ? dbtemp : dbname, &g_temp_db); + + err = sqlite3_open(dbname, &g_temp_db); assert(err == SQLITE_OK); err = sqlite3_exec(g_temp_db, "PRAGMA journal_mode=OFF", NULL, NULL, NULL); assert(err == SQLITE_OK); @@ -176,16 +177,30 @@ void db_driver_open(void) assert(err == SQLITE_OK); err = sqlite3_prepare_v2(g_temp_db, "SELECT data FROM orders WHERE id=?", -1, &g_stmt_select_order, NULL); assert(err == SQLITE_OK); - ERRNO_CHECK(); + return 0; } -void db_driver_close(void) +int db_driver_open(database_t db, const char *dbname) +{ + ERRNO_CHECK(); + + if (db == DB_SWAP) { + return db_open_swap(dbname); + } + else if (db == DB_GAME) { + return db_open_game(dbname); + } + return -1; +} + +void db_driver_close(database_t db) { int err; ERRNO_CHECK(); - if (g_temp_db) { + if (db == DB_SWAP) { + assert(g_temp_db); err = sqlite3_finalize(g_stmt_select_order); assert(err == SQLITE_OK); err = sqlite3_finalize(g_stmt_insert_order); @@ -193,7 +208,8 @@ void db_driver_close(void) err = sqlite3_close(g_temp_db); assert(err == SQLITE_OK); } - if (g_game_db) { + else if (db == DB_GAME) { + assert(g_game_db); err = sqlite3_finalize(g_stmt_update_faction); assert(err == SQLITE_OK); err = sqlite3_finalize(g_stmt_insert_faction); From 74aa4bdaf37f1e6e551e86473acd753b536bb05b Mon Sep 17 00:00:00 2001 From: Enno Rehling Date: Tue, 25 Sep 2018 19:15:03 +0200 Subject: [PATCH 026/160] bindings for gamedb_update, run after turn. --- scripts/run-turn.lua | 3 ++- src/bindings.c | 19 ++++++++++++++----- src/gamedb.c | 4 +++- src/gamedb.h | 2 +- src/main.c | 2 +- 5 files changed, 21 insertions(+), 9 deletions(-) diff --git a/scripts/run-turn.lua b/scripts/run-turn.lua index 62d48ec51..35303b038 100644 --- a/scripts/run-turn.lua +++ b/scripts/run-turn.lua @@ -95,8 +95,9 @@ local function write_htpasswd() end local function write_files(locales) + write_database() write_passwords() - write_htpasswd() + -- write_htpasswd() write_reports() write_summary() end diff --git a/src/bindings.c b/src/bindings.c index c549a4801..b2da38eba 100755 --- a/src/bindings.c +++ b/src/bindings.c @@ -4,15 +4,16 @@ #include "bindings.h" -#include "magic.h" -#include "skill.h" -#include "helpers.h" #include "console.h" +#include "gamedb.h" +#include "helpers.h" +#include "laws.h" +#include "magic.h" #include "reports.h" +#include "skill.h" #include "study.h" #include "summary.h" #include "teleport.h" -#include "laws.h" #include "kernel/calendar.h" #include "kernel/config.h" @@ -437,7 +438,14 @@ static int tolua_write_passwords(lua_State * L) { int result = writepasswd(); lua_pushinteger(L, result); - return 0; + return 1; +} + +static int tolua_write_database(lua_State * L) +{ + int result = gamedb_update(); + lua_pushinteger(L, result); + return 1; } static int tolua_write_summary(lua_State * L) @@ -949,6 +957,7 @@ int tolua_bindings_open(lua_State * L, const dictionary *inifile) tolua_function(L, TOLUA_CAST "write_report", tolua_write_report); tolua_function(L, TOLUA_CAST "write_summary", tolua_write_summary); tolua_function(L, TOLUA_CAST "write_passwords", tolua_write_passwords); + tolua_function(L, TOLUA_CAST "write_database", tolua_write_database); tolua_function(L, TOLUA_CAST "message_unit", tolua_message_unit); tolua_function(L, TOLUA_CAST "message_faction", tolua_message_faction); tolua_function(L, TOLUA_CAST "message_region", tolua_message_region); diff --git a/src/gamedb.c b/src/gamedb.c index e3c16b06e..e570d61e8 100644 --- a/src/gamedb.c +++ b/src/gamedb.c @@ -4,9 +4,11 @@ #include "gamedb.h" -#include "kernel/db/driver.h" +#include "kernel/config.h" +#include "kernel/calendar.h" #include "kernel/database.h" #include "kernel/faction.h" +#include "kernel/db/driver.h" int gamedb_update(void) { diff --git a/src/gamedb.h b/src/gamedb.h index ea4614298..01251f356 100644 --- a/src/gamedb.h +++ b/src/gamedb.h @@ -1,3 +1,3 @@ #pragma once -void gamedb_update(void); +int gamedb_update(void); diff --git a/src/main.c b/src/main.c index eae7f440c..5bb4ad4ee 100644 --- a/src/main.c +++ b/src/main.c @@ -96,7 +96,7 @@ static const char * valid_keys[] = { "game.era", "game.sender", "game.dbname", - "game.db.", + "game.dbswap", "game.dbbatch", "editor.color", "editor.codepage", From bbbed8079006828b2ca2c8c5db66cbd2b4647a89 Mon Sep 17 00:00:00 2001 From: Enno Rehling Date: Wed, 26 Sep 2018 15:36:21 +0200 Subject: [PATCH 027/160] add openwall bcrypt sources --- crypt_blowfish/CMakeLists.txt | 24 + crypt_blowfish/LINKS | 29 + crypt_blowfish/PERFORMANCE | 30 ++ crypt_blowfish/README | 68 +++ crypt_blowfish/bcrypt.c | 195 +++++++ crypt_blowfish/bcrypt.h | 97 ++++ crypt_blowfish/crypt.h | 24 + crypt_blowfish/crypt_blowfish.c | 907 ++++++++++++++++++++++++++++++++ crypt_blowfish/crypt_blowfish.h | 27 + crypt_blowfish/crypt_gensalt.c | 124 +++++ crypt_blowfish/crypt_gensalt.h | 30 ++ crypt_blowfish/ow-crypt.h | 43 ++ crypt_blowfish/x86.S | 203 +++++++ 13 files changed, 1801 insertions(+) create mode 100644 crypt_blowfish/CMakeLists.txt create mode 100644 crypt_blowfish/LINKS create mode 100644 crypt_blowfish/PERFORMANCE create mode 100644 crypt_blowfish/README create mode 100644 crypt_blowfish/bcrypt.c create mode 100644 crypt_blowfish/bcrypt.h create mode 100644 crypt_blowfish/crypt.h create mode 100644 crypt_blowfish/crypt_blowfish.c create mode 100644 crypt_blowfish/crypt_blowfish.h create mode 100644 crypt_blowfish/crypt_gensalt.c create mode 100644 crypt_blowfish/crypt_gensalt.h create mode 100644 crypt_blowfish/ow-crypt.h create mode 100644 crypt_blowfish/x86.S diff --git a/crypt_blowfish/CMakeLists.txt b/crypt_blowfish/CMakeLists.txt new file mode 100644 index 000000000..b6f810721 --- /dev/null +++ b/crypt_blowfish/CMakeLists.txt @@ -0,0 +1,24 @@ +cmake_minimum_required(VERSION 2.6) +project (bcrypt C) + +IF (MSVC) + include (MSVC) + MSVC_SET_WARNING_LEVEL(3) +ENDIF (MSVC) + +SET (LIB_SRC crypt_blowfish.c crypt_gensalt.c bcrypt.c) +ADD_LIBRARY (bcrypt ${LIB_SRC}) + +set (CJSON_INCLUDE_DIR ${CMAKE_CURRENT_SOURCE_DIR} CACHE INTERNAL "cJSON headers") +set (CJSON_LIBRARIES bcrypt CACHE INTERNAL "bcrypt libraries") + +IF(UNIX AND NOT APPLE) + FIND_LIBRARY(UNIX_MATH_LIBRARY m) + SET(BCRYPT_LIBRARIES ${BCRYPT_LIBRARIES} ${UNIX_MATH_LIBRARY} CACHE + INTERNAL "bcrypt libraries") +ENDIF() + +IF (MSVC) + MSVC_CRT_SECURE_NO_WARNINGS (bcrypt) +ENDIF (MSVC) + diff --git a/crypt_blowfish/LINKS b/crypt_blowfish/LINKS new file mode 100644 index 000000000..a6cb7e1c3 --- /dev/null +++ b/crypt_blowfish/LINKS @@ -0,0 +1,29 @@ +New versions of this package (crypt_blowfish): + + http://www.openwall.com/crypt/ + +A paper on the algorithm that explains its design decisions: + + http://www.usenix.org/events/usenix99/provos.html + +Unix Seventh Edition Manual, Volume 2: the password scheme (1978): + + http://plan9.bell-labs.com/7thEdMan/vol2/password + +The Openwall GNU/*/Linux (Owl) tcb suite implementing the alternative +password shadowing scheme. This includes a PAM module which +supersedes pam_unix and uses the password hashing framework provided +with crypt_blowfish when setting new passwords. + + http://www.openwall.com/tcb/ + +pam_passwdqc, a password strength checking and policy enforcement +module for PAM-aware password changing programs: + + http://www.openwall.com/passwdqc/ + +John the Ripper password cracker: + + http://www.openwall.com/john/ + +$Owl: Owl/packages/glibc/crypt_blowfish/LINKS,v 1.4 2005/11/16 13:09:47 solar Exp $ diff --git a/crypt_blowfish/PERFORMANCE b/crypt_blowfish/PERFORMANCE new file mode 100644 index 000000000..9d6fe4ef5 --- /dev/null +++ b/crypt_blowfish/PERFORMANCE @@ -0,0 +1,30 @@ +These numbers are for 32 iterations ("$2a$05"): + + OpenBSD 3.0 bcrypt(*) crypt_blowfish 0.4.4 +Pentium III, 840 MHz 99 c/s 121 c/s (+22%) +Alpha 21164PC, 533 MHz 55.5 c/s 76.9 c/s (+38%) +UltraSparc IIi, 400 MHz 49.9 c/s 52.5 c/s (+5%) +Pentium, 120 MHz 8.8 c/s 20.1 c/s (+128%) +PA-RISC 7100LC, 80 MHz 8.5 c/s 16.3 c/s (+92%) + +(*) built with -fomit-frame-pointer -funroll-loops, which I don't +think happens for libcrypt. + +Starting with version 1.1 released in June 2011, default builds of +crypt_blowfish invoke a quick self-test on every hash computation. +This has roughly a 4.8% performance impact at "$2a$05", but only a 0.6% +impact at a more typical setting of "$2a$08". + +The large speedup for the original Pentium is due to the assembly +code and the weird optimizations this processor requires. + +The numbers for password cracking are 2 to 10% higher than those for +crypt_blowfish as certain things may be done out of the loop and the +code doesn't need to be reentrant. + +Recent versions of John the Ripper (1.6.25-dev and newer) achieve an +additional 15% speedup on the Pentium Pro family of processors (which +includes Pentium III) with a separate version of the assembly code and +run-time CPU detection. + +$Owl: Owl/packages/glibc/crypt_blowfish/PERFORMANCE,v 1.6 2011/06/21 12:09:20 solar Exp $ diff --git a/crypt_blowfish/README b/crypt_blowfish/README new file mode 100644 index 000000000..e95da230e --- /dev/null +++ b/crypt_blowfish/README @@ -0,0 +1,68 @@ +This is an implementation of a password hashing method, provided via the +crypt(3) and a reentrant interface. It is fully compatible with +OpenBSD's bcrypt.c for prefix "$2b$", originally by Niels Provos and +David Mazieres. (Please refer to the included crypt(3) man page for +information on minor compatibility issues for other bcrypt prefixes.) + +I've placed this code in the public domain, with fallback to a +permissive license. Please see the comment in crypt_blowfish.c for +more information. + +You can use the provided routines in your own packages, or link them +into a C library. I've provided hooks for linking into GNU libc, but +it shouldn't be too hard to get this into another C library. Note +that simply adding this code into your libc is probably not enough to +make your system use the new password hashing algorithm. Changes to +passwd(1), PAM modules, or whatever else your system uses will likely +be needed as well. These are not a part of this package, but see +LINKS for a pointer to our tcb suite. + +Instructions on using the routines in one of the two common ways are +given below. It is recommended that you test the routines on your +system before you start. Type "make check" or "make check_threads" +(if you have the POSIX threads library), then "make clean". + + +1. Using the routines in your programs. + +The available interfaces are in ow-crypt.h, and this is the file you +should include. You won't need crypt.h. When linking, add all of the +C files and x86.S (you can compile and link it even on a non-x86, it +will produce no code in this case). + + +2. Building the routines into GNU C library. + +For versions 2.13 and 2.14 (and likely other nearby ones), extract the +library sources as usual. Apply the patch for glibc 2.14 provided in +this package. Enter crypt/ and rename crypt.h to gnu-crypt.h within +that directory. Copy the C sources, header, and assembly (x86.S) files +from this package in there as well (but be sure you don't overwrite the +Makefile). Configure, build, and install the library as usual. + +For versions 2.2 to 2.3.6 (and likely also for some newer ones), +extract the library sources and maybe its optional add-ons as usual. +Apply the patch for glibc 2.3.6 provided in this package. Enter +crypt/ and rename crypt.h to gnu-crypt.h within that directory. Copy +the C sources, header, and assembly (x86.S) files from this package in +there as well (but be sure you don't overwrite the Makefile). +Configure, build, and install the library as usual. + +For versions 2.1 to 2.1.3, extract the library sources and the crypt +and linuxthreads add-ons as usual. Apply the patch for glibc 2.1.3 +provided in this package. Enter crypt/sysdeps/unix/, and rename +crypt.h to gnu-crypt.h within that directory. Copy C sources, header, +and assembly (x86.S) files from this package in there as well (but be +sure you don't overwrite the Makefile). Configure, build, and install +the library as usual. + +Programs that want to use the provided interfaces will need to include +crypt.h (but not ow-crypt.h directly). By default, prototypes for the +new routines aren't defined (but the extra functionality of crypt(3) +is indeed available). You need to define _OW_SOURCE to obtain the new +routines as well. + +-- +Solar Designer + +$Owl: Owl/packages/glibc/crypt_blowfish/README,v 1.10 2014/07/07 15:19:04 solar Exp $ diff --git a/crypt_blowfish/bcrypt.c b/crypt_blowfish/bcrypt.c new file mode 100644 index 000000000..a4c992258 --- /dev/null +++ b/crypt_blowfish/bcrypt.c @@ -0,0 +1,195 @@ +/* + * bcrypt wrapper library + * + * Written in 2011, 2013, 2014, 2015 by Ricardo Garcia + * + * To the extent possible under law, the author(s) have dedicated all copyright + * and related and neighboring rights to this software to the public domain + * worldwide. This software is distributed without any warranty. + * + * You should have received a copy of the CC0 Public Domain Dedication along + * with this software. If not, see + * . + */ +#include +#include +#include +#include +#include +#include + +#include "bcrypt.h" +#include "ow-crypt.h" + +#define RANDBYTES (16) + +static int try_close(int fd) +{ + int ret; + for (;;) { + errno = 0; + ret = close(fd); + if (ret == -1 && errno == EINTR) + continue; + break; + } + return ret; +} + +static int try_read(int fd, char *out, size_t count) +{ + size_t total; + ssize_t partial; + + total = 0; + while (total < count) + { + for (;;) { + errno = 0; + partial = read(fd, out + total, count - total); + if (partial == -1 && errno == EINTR) + continue; + break; + } + + if (partial < 1) + return -1; + + total += partial; + } + + return 0; +} + +/* + * This is a best effort implementation. Nothing prevents a compiler from + * optimizing this function and making it vulnerable to timing attacks, but + * this method is commonly used in crypto libraries like NaCl. + * + * Return value is zero if both strings are equal and nonzero otherwise. +*/ +static int timing_safe_strcmp(const char *str1, const char *str2) +{ + const unsigned char *u1; + const unsigned char *u2; + int ret; + int i; + + int len1 = strlen(str1); + int len2 = strlen(str2); + + /* In our context both strings should always have the same length + * because they will be hashed passwords. */ + if (len1 != len2) + return 1; + + /* Force unsigned for bitwise operations. */ + u1 = (const unsigned char *)str1; + u2 = (const unsigned char *)str2; + + ret = 0; + for (i = 0; i < len1; ++i) + ret |= (u1[i] ^ u2[i]); + + return ret; +} + +int bcrypt_gensalt(int factor, char salt[BCRYPT_HASHSIZE]) +{ + int fd; + char input[RANDBYTES]; + int workf; + char *aux; + + fd = open("/dev/urandom", O_RDONLY); + if (fd == -1) + return 1; + + if (try_read(fd, input, RANDBYTES) != 0) { + if (try_close(fd) != 0) + return 4; + return 2; + } + + if (try_close(fd) != 0) + return 3; + + /* Generate salt. */ + workf = (factor < 4 || factor > 31)?12:factor; + aux = crypt_gensalt_rn("$2a$", workf, input, RANDBYTES, + salt, BCRYPT_HASHSIZE); + return (aux == NULL)?5:0; +} + +int bcrypt_hashpw(const char *passwd, const char salt[BCRYPT_HASHSIZE], char hash[BCRYPT_HASHSIZE]) +{ + char *aux; + aux = crypt_rn(passwd, salt, hash, BCRYPT_HASHSIZE); + return (aux == NULL)?1:0; +} + +int bcrypt_checkpw(const char *passwd, const char hash[BCRYPT_HASHSIZE]) +{ + int ret; + char outhash[BCRYPT_HASHSIZE]; + + ret = bcrypt_hashpw(passwd, hash, outhash); + if (ret != 0) + return -1; + + return timing_safe_strcmp(hash, outhash); +} + +#ifdef TEST_BCRYPT +#include +#include +#include +#include + +int main(void) +{ + clock_t before; + clock_t after; + char salt[BCRYPT_HASHSIZE]; + char hash[BCRYPT_HASHSIZE]; + int ret; + + const char pass[] = "hi,mom"; + const char hash1[] = "$2a$10$VEVmGHy4F4XQMJ3eOZJAUeb.MedU0W10pTPCuf53eHdKJPiSE8sMK"; + const char hash2[] = "$2a$10$3F0BVk5t8/aoS.3ddaB3l.fxg5qvafQ9NybxcpXLzMeAt.nVWn.NO"; + + ret = bcrypt_gensalt(12, salt); + assert(ret == 0); + printf("Generated salt: %s\n", salt); + before = clock(); + ret = bcrypt_hashpw("testtesttest", salt, hash); + assert(ret == 0); + after = clock(); + printf("Hashed password: %s\n", hash); + printf("Time taken: %f seconds\n", + (double)(after - before) / CLOCKS_PER_SEC); + + ret = bcrypt_hashpw(pass, hash1, hash); + assert(ret == 0); + printf("First hash check: %s\n", (strcmp(hash1, hash) == 0)?"OK":"FAIL"); + ret = bcrypt_hashpw(pass, hash2, hash); + assert(ret == 0); + printf("Second hash check: %s\n", (strcmp(hash2, hash) == 0)?"OK":"FAIL"); + + before = clock(); + ret = (bcrypt_checkpw(pass, hash1) == 0); + after = clock(); + printf("First hash check with bcrypt_checkpw: %s\n", ret?"OK":"FAIL"); + printf("Time taken: %f seconds\n", + (double)(after - before) / CLOCKS_PER_SEC); + + before = clock(); + ret = (bcrypt_checkpw(pass, hash2) == 0); + after = clock(); + printf("Second hash check with bcrypt_checkpw: %s\n", ret?"OK":"FAIL"); + printf("Time taken: %f seconds\n", + (double)(after - before) / CLOCKS_PER_SEC); + + return 0; +} +#endif diff --git a/crypt_blowfish/bcrypt.h b/crypt_blowfish/bcrypt.h new file mode 100644 index 000000000..e45b3ca13 --- /dev/null +++ b/crypt_blowfish/bcrypt.h @@ -0,0 +1,97 @@ +#ifndef BCRYPT_H_ +#define BCRYPT_H_ +/* + * bcrypt wrapper library + * + * Written in 2011, 2013, 2014, 2015 by Ricardo Garcia + * + * To the extent possible under law, the author(s) have dedicated all copyright + * and related and neighboring rights to this software to the public domain + * worldwide. This software is distributed without any warranty. + * + * You should have received a copy of the CC0 Public Domain Dedication along + * with this software. If not, see + * . + */ + +#define BCRYPT_HASHSIZE (64) + +#ifdef __cplusplus +extern "C" { +#endif + +/* + * This function expects a work factor between 4 and 31 and a char array to + * store the resulting generated salt. The char array should typically have + * BCRYPT_HASHSIZE bytes at least. If the provided work factor is not in the + * previous range, it will default to 12. + * + * The return value is zero if the salt could be correctly generated and + * nonzero otherwise. + * + */ +int bcrypt_gensalt(int workfactor, char salt[BCRYPT_HASHSIZE]); + +/* + * This function expects a password to be hashed, a salt to hash the password + * with and a char array to leave the result. Both the salt and the hash + * parameters should have room for BCRYPT_HASHSIZE characters at least. + * + * It can also be used to verify a hashed password. In that case, provide the + * expected hash in the salt parameter and verify the output hash is the same + * as the input hash. However, to avoid timing attacks, it's better to use + * bcrypt_checkpw when verifying a password. + * + * The return value is zero if the password could be hashed and nonzero + * otherwise. + */ +int bcrypt_hashpw(const char *passwd, const char salt[BCRYPT_HASHSIZE], + char hash[BCRYPT_HASHSIZE]); + +/* + * This function expects a password and a hash to verify the password against. + * The internal implementation is tuned to avoid timing attacks. + * + * The return value will be -1 in case of errors, zero if the provided password + * matches the given hash and greater than zero if no errors are found and the + * passwords don't match. + * + */ +int bcrypt_checkpw(const char *passwd, const char hash[BCRYPT_HASHSIZE]); + +/* + * Brief Example + * ------------- + * + * Hashing a password: + * + * char salt[BCRYPT_HASHSIZE]; + * char hash[BCRYPT_HASHSIZE]; + * int ret; + * + * ret = bcrypt_gensalt(12, salt); + * assert(ret == 0); + * ret = bcrypt_hashpw("thepassword", salt, hash); + * assert(ret == 0); + * + * + * Verifying a password: + * + * int ret; + * + * ret = bcrypt_checkpw("thepassword", "expectedhash"); + * assert(ret != -1); + * + * if (ret == 0) { + * printf("The password matches\n"); + * } else { + * printf("The password does NOT match\n"); + * } + * + */ + +#ifdef __cplusplus +} +#endif + +#endif diff --git a/crypt_blowfish/crypt.h b/crypt_blowfish/crypt.h new file mode 100644 index 000000000..12e67055b --- /dev/null +++ b/crypt_blowfish/crypt.h @@ -0,0 +1,24 @@ +/* + * Written by Solar Designer in 2000-2002. + * No copyright is claimed, and the software is hereby placed in the public + * domain. In case this attempt to disclaim copyright and place the software + * in the public domain is deemed null and void, then the software is + * Copyright (c) 2000-2002 Solar Designer and it is hereby released to the + * general public under the following terms: + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted. + * + * There's ABSOLUTELY NO WARRANTY, express or implied. + * + * See crypt_blowfish.c for more information. + */ + +#include + +#if defined(_OW_SOURCE) || defined(__USE_OW) +#define __SKIP_GNU +#undef __SKIP_OW +#include +#undef __SKIP_GNU +#endif diff --git a/crypt_blowfish/crypt_blowfish.c b/crypt_blowfish/crypt_blowfish.c new file mode 100644 index 000000000..9d3f3be82 --- /dev/null +++ b/crypt_blowfish/crypt_blowfish.c @@ -0,0 +1,907 @@ +/* + * The crypt_blowfish homepage is: + * + * http://www.openwall.com/crypt/ + * + * This code comes from John the Ripper password cracker, with reentrant + * and crypt(3) interfaces added, but optimizations specific to password + * cracking removed. + * + * Written by Solar Designer in 1998-2014. + * No copyright is claimed, and the software is hereby placed in the public + * domain. In case this attempt to disclaim copyright and place the software + * in the public domain is deemed null and void, then the software is + * Copyright (c) 1998-2014 Solar Designer and it is hereby released to the + * general public under the following terms: + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted. + * + * There's ABSOLUTELY NO WARRANTY, express or implied. + * + * It is my intent that you should be able to use this on your system, + * as part of a software package, or anywhere else to improve security, + * ensure compatibility, or for any other purpose. I would appreciate + * it if you give credit where it is due and keep your modifications in + * the public domain as well, but I don't require that in order to let + * you place this code and any modifications you make under a license + * of your choice. + * + * This implementation is fully compatible with OpenBSD's bcrypt.c for prefix + * "$2b$", originally by Niels Provos , and it uses + * some of his ideas. The password hashing algorithm was designed by David + * Mazieres . For information on the level of + * compatibility for bcrypt hash prefixes other than "$2b$", please refer to + * the comments in BF_set_key() below and to the included crypt(3) man page. + * + * There's a paper on the algorithm that explains its design decisions: + * + * http://www.usenix.org/events/usenix99/provos.html + * + * Some of the tricks in BF_ROUND might be inspired by Eric Young's + * Blowfish library (I can't be sure if I would think of something if I + * hadn't seen his code). + */ + +#include + +#include +#ifndef __set_errno +#define __set_errno(val) errno = (val) +#endif + +/* Just to make sure the prototypes match the actual definitions */ +#include "crypt_blowfish.h" + +#ifdef __i386__ +#define BF_ASM 1 +#define BF_SCALE 1 +#elif defined(__x86_64__) || defined(__alpha__) || defined(__hppa__) +#define BF_ASM 0 +#define BF_SCALE 1 +#else +#define BF_ASM 0 +#define BF_SCALE 0 +#endif + +typedef unsigned int BF_word; +typedef signed int BF_word_signed; + +/* Number of Blowfish rounds, this is also hardcoded into a few places */ +#define BF_N 16 + +typedef BF_word BF_key[BF_N + 2]; + +typedef struct { + BF_word S[4][0x100]; + BF_key P; +} BF_ctx; + +/* + * Magic IV for 64 Blowfish encryptions that we do at the end. + * The string is "OrpheanBeholderScryDoubt" on big-endian. + */ +static BF_word BF_magic_w[6] = { + 0x4F727068, 0x65616E42, 0x65686F6C, + 0x64657253, 0x63727944, 0x6F756274 +}; + +/* + * P-box and S-box tables initialized with digits of Pi. + */ +static BF_ctx BF_init_state = { + { + { + 0xd1310ba6, 0x98dfb5ac, 0x2ffd72db, 0xd01adfb7, + 0xb8e1afed, 0x6a267e96, 0xba7c9045, 0xf12c7f99, + 0x24a19947, 0xb3916cf7, 0x0801f2e2, 0x858efc16, + 0x636920d8, 0x71574e69, 0xa458fea3, 0xf4933d7e, + 0x0d95748f, 0x728eb658, 0x718bcd58, 0x82154aee, + 0x7b54a41d, 0xc25a59b5, 0x9c30d539, 0x2af26013, + 0xc5d1b023, 0x286085f0, 0xca417918, 0xb8db38ef, + 0x8e79dcb0, 0x603a180e, 0x6c9e0e8b, 0xb01e8a3e, + 0xd71577c1, 0xbd314b27, 0x78af2fda, 0x55605c60, + 0xe65525f3, 0xaa55ab94, 0x57489862, 0x63e81440, + 0x55ca396a, 0x2aab10b6, 0xb4cc5c34, 0x1141e8ce, + 0xa15486af, 0x7c72e993, 0xb3ee1411, 0x636fbc2a, + 0x2ba9c55d, 0x741831f6, 0xce5c3e16, 0x9b87931e, + 0xafd6ba33, 0x6c24cf5c, 0x7a325381, 0x28958677, + 0x3b8f4898, 0x6b4bb9af, 0xc4bfe81b, 0x66282193, + 0x61d809cc, 0xfb21a991, 0x487cac60, 0x5dec8032, + 0xef845d5d, 0xe98575b1, 0xdc262302, 0xeb651b88, + 0x23893e81, 0xd396acc5, 0x0f6d6ff3, 0x83f44239, + 0x2e0b4482, 0xa4842004, 0x69c8f04a, 0x9e1f9b5e, + 0x21c66842, 0xf6e96c9a, 0x670c9c61, 0xabd388f0, + 0x6a51a0d2, 0xd8542f68, 0x960fa728, 0xab5133a3, + 0x6eef0b6c, 0x137a3be4, 0xba3bf050, 0x7efb2a98, + 0xa1f1651d, 0x39af0176, 0x66ca593e, 0x82430e88, + 0x8cee8619, 0x456f9fb4, 0x7d84a5c3, 0x3b8b5ebe, + 0xe06f75d8, 0x85c12073, 0x401a449f, 0x56c16aa6, + 0x4ed3aa62, 0x363f7706, 0x1bfedf72, 0x429b023d, + 0x37d0d724, 0xd00a1248, 0xdb0fead3, 0x49f1c09b, + 0x075372c9, 0x80991b7b, 0x25d479d8, 0xf6e8def7, + 0xe3fe501a, 0xb6794c3b, 0x976ce0bd, 0x04c006ba, + 0xc1a94fb6, 0x409f60c4, 0x5e5c9ec2, 0x196a2463, + 0x68fb6faf, 0x3e6c53b5, 0x1339b2eb, 0x3b52ec6f, + 0x6dfc511f, 0x9b30952c, 0xcc814544, 0xaf5ebd09, + 0xbee3d004, 0xde334afd, 0x660f2807, 0x192e4bb3, + 0xc0cba857, 0x45c8740f, 0xd20b5f39, 0xb9d3fbdb, + 0x5579c0bd, 0x1a60320a, 0xd6a100c6, 0x402c7279, + 0x679f25fe, 0xfb1fa3cc, 0x8ea5e9f8, 0xdb3222f8, + 0x3c7516df, 0xfd616b15, 0x2f501ec8, 0xad0552ab, + 0x323db5fa, 0xfd238760, 0x53317b48, 0x3e00df82, + 0x9e5c57bb, 0xca6f8ca0, 0x1a87562e, 0xdf1769db, + 0xd542a8f6, 0x287effc3, 0xac6732c6, 0x8c4f5573, + 0x695b27b0, 0xbbca58c8, 0xe1ffa35d, 0xb8f011a0, + 0x10fa3d98, 0xfd2183b8, 0x4afcb56c, 0x2dd1d35b, + 0x9a53e479, 0xb6f84565, 0xd28e49bc, 0x4bfb9790, + 0xe1ddf2da, 0xa4cb7e33, 0x62fb1341, 0xcee4c6e8, + 0xef20cada, 0x36774c01, 0xd07e9efe, 0x2bf11fb4, + 0x95dbda4d, 0xae909198, 0xeaad8e71, 0x6b93d5a0, + 0xd08ed1d0, 0xafc725e0, 0x8e3c5b2f, 0x8e7594b7, + 0x8ff6e2fb, 0xf2122b64, 0x8888b812, 0x900df01c, + 0x4fad5ea0, 0x688fc31c, 0xd1cff191, 0xb3a8c1ad, + 0x2f2f2218, 0xbe0e1777, 0xea752dfe, 0x8b021fa1, + 0xe5a0cc0f, 0xb56f74e8, 0x18acf3d6, 0xce89e299, + 0xb4a84fe0, 0xfd13e0b7, 0x7cc43b81, 0xd2ada8d9, + 0x165fa266, 0x80957705, 0x93cc7314, 0x211a1477, + 0xe6ad2065, 0x77b5fa86, 0xc75442f5, 0xfb9d35cf, + 0xebcdaf0c, 0x7b3e89a0, 0xd6411bd3, 0xae1e7e49, + 0x00250e2d, 0x2071b35e, 0x226800bb, 0x57b8e0af, + 0x2464369b, 0xf009b91e, 0x5563911d, 0x59dfa6aa, + 0x78c14389, 0xd95a537f, 0x207d5ba2, 0x02e5b9c5, + 0x83260376, 0x6295cfa9, 0x11c81968, 0x4e734a41, + 0xb3472dca, 0x7b14a94a, 0x1b510052, 0x9a532915, + 0xd60f573f, 0xbc9bc6e4, 0x2b60a476, 0x81e67400, + 0x08ba6fb5, 0x571be91f, 0xf296ec6b, 0x2a0dd915, + 0xb6636521, 0xe7b9f9b6, 0xff34052e, 0xc5855664, + 0x53b02d5d, 0xa99f8fa1, 0x08ba4799, 0x6e85076a + }, { + 0x4b7a70e9, 0xb5b32944, 0xdb75092e, 0xc4192623, + 0xad6ea6b0, 0x49a7df7d, 0x9cee60b8, 0x8fedb266, + 0xecaa8c71, 0x699a17ff, 0x5664526c, 0xc2b19ee1, + 0x193602a5, 0x75094c29, 0xa0591340, 0xe4183a3e, + 0x3f54989a, 0x5b429d65, 0x6b8fe4d6, 0x99f73fd6, + 0xa1d29c07, 0xefe830f5, 0x4d2d38e6, 0xf0255dc1, + 0x4cdd2086, 0x8470eb26, 0x6382e9c6, 0x021ecc5e, + 0x09686b3f, 0x3ebaefc9, 0x3c971814, 0x6b6a70a1, + 0x687f3584, 0x52a0e286, 0xb79c5305, 0xaa500737, + 0x3e07841c, 0x7fdeae5c, 0x8e7d44ec, 0x5716f2b8, + 0xb03ada37, 0xf0500c0d, 0xf01c1f04, 0x0200b3ff, + 0xae0cf51a, 0x3cb574b2, 0x25837a58, 0xdc0921bd, + 0xd19113f9, 0x7ca92ff6, 0x94324773, 0x22f54701, + 0x3ae5e581, 0x37c2dadc, 0xc8b57634, 0x9af3dda7, + 0xa9446146, 0x0fd0030e, 0xecc8c73e, 0xa4751e41, + 0xe238cd99, 0x3bea0e2f, 0x3280bba1, 0x183eb331, + 0x4e548b38, 0x4f6db908, 0x6f420d03, 0xf60a04bf, + 0x2cb81290, 0x24977c79, 0x5679b072, 0xbcaf89af, + 0xde9a771f, 0xd9930810, 0xb38bae12, 0xdccf3f2e, + 0x5512721f, 0x2e6b7124, 0x501adde6, 0x9f84cd87, + 0x7a584718, 0x7408da17, 0xbc9f9abc, 0xe94b7d8c, + 0xec7aec3a, 0xdb851dfa, 0x63094366, 0xc464c3d2, + 0xef1c1847, 0x3215d908, 0xdd433b37, 0x24c2ba16, + 0x12a14d43, 0x2a65c451, 0x50940002, 0x133ae4dd, + 0x71dff89e, 0x10314e55, 0x81ac77d6, 0x5f11199b, + 0x043556f1, 0xd7a3c76b, 0x3c11183b, 0x5924a509, + 0xf28fe6ed, 0x97f1fbfa, 0x9ebabf2c, 0x1e153c6e, + 0x86e34570, 0xeae96fb1, 0x860e5e0a, 0x5a3e2ab3, + 0x771fe71c, 0x4e3d06fa, 0x2965dcb9, 0x99e71d0f, + 0x803e89d6, 0x5266c825, 0x2e4cc978, 0x9c10b36a, + 0xc6150eba, 0x94e2ea78, 0xa5fc3c53, 0x1e0a2df4, + 0xf2f74ea7, 0x361d2b3d, 0x1939260f, 0x19c27960, + 0x5223a708, 0xf71312b6, 0xebadfe6e, 0xeac31f66, + 0xe3bc4595, 0xa67bc883, 0xb17f37d1, 0x018cff28, + 0xc332ddef, 0xbe6c5aa5, 0x65582185, 0x68ab9802, + 0xeecea50f, 0xdb2f953b, 0x2aef7dad, 0x5b6e2f84, + 0x1521b628, 0x29076170, 0xecdd4775, 0x619f1510, + 0x13cca830, 0xeb61bd96, 0x0334fe1e, 0xaa0363cf, + 0xb5735c90, 0x4c70a239, 0xd59e9e0b, 0xcbaade14, + 0xeecc86bc, 0x60622ca7, 0x9cab5cab, 0xb2f3846e, + 0x648b1eaf, 0x19bdf0ca, 0xa02369b9, 0x655abb50, + 0x40685a32, 0x3c2ab4b3, 0x319ee9d5, 0xc021b8f7, + 0x9b540b19, 0x875fa099, 0x95f7997e, 0x623d7da8, + 0xf837889a, 0x97e32d77, 0x11ed935f, 0x16681281, + 0x0e358829, 0xc7e61fd6, 0x96dedfa1, 0x7858ba99, + 0x57f584a5, 0x1b227263, 0x9b83c3ff, 0x1ac24696, + 0xcdb30aeb, 0x532e3054, 0x8fd948e4, 0x6dbc3128, + 0x58ebf2ef, 0x34c6ffea, 0xfe28ed61, 0xee7c3c73, + 0x5d4a14d9, 0xe864b7e3, 0x42105d14, 0x203e13e0, + 0x45eee2b6, 0xa3aaabea, 0xdb6c4f15, 0xfacb4fd0, + 0xc742f442, 0xef6abbb5, 0x654f3b1d, 0x41cd2105, + 0xd81e799e, 0x86854dc7, 0xe44b476a, 0x3d816250, + 0xcf62a1f2, 0x5b8d2646, 0xfc8883a0, 0xc1c7b6a3, + 0x7f1524c3, 0x69cb7492, 0x47848a0b, 0x5692b285, + 0x095bbf00, 0xad19489d, 0x1462b174, 0x23820e00, + 0x58428d2a, 0x0c55f5ea, 0x1dadf43e, 0x233f7061, + 0x3372f092, 0x8d937e41, 0xd65fecf1, 0x6c223bdb, + 0x7cde3759, 0xcbee7460, 0x4085f2a7, 0xce77326e, + 0xa6078084, 0x19f8509e, 0xe8efd855, 0x61d99735, + 0xa969a7aa, 0xc50c06c2, 0x5a04abfc, 0x800bcadc, + 0x9e447a2e, 0xc3453484, 0xfdd56705, 0x0e1e9ec9, + 0xdb73dbd3, 0x105588cd, 0x675fda79, 0xe3674340, + 0xc5c43465, 0x713e38d8, 0x3d28f89e, 0xf16dff20, + 0x153e21e7, 0x8fb03d4a, 0xe6e39f2b, 0xdb83adf7 + }, { + 0xe93d5a68, 0x948140f7, 0xf64c261c, 0x94692934, + 0x411520f7, 0x7602d4f7, 0xbcf46b2e, 0xd4a20068, + 0xd4082471, 0x3320f46a, 0x43b7d4b7, 0x500061af, + 0x1e39f62e, 0x97244546, 0x14214f74, 0xbf8b8840, + 0x4d95fc1d, 0x96b591af, 0x70f4ddd3, 0x66a02f45, + 0xbfbc09ec, 0x03bd9785, 0x7fac6dd0, 0x31cb8504, + 0x96eb27b3, 0x55fd3941, 0xda2547e6, 0xabca0a9a, + 0x28507825, 0x530429f4, 0x0a2c86da, 0xe9b66dfb, + 0x68dc1462, 0xd7486900, 0x680ec0a4, 0x27a18dee, + 0x4f3ffea2, 0xe887ad8c, 0xb58ce006, 0x7af4d6b6, + 0xaace1e7c, 0xd3375fec, 0xce78a399, 0x406b2a42, + 0x20fe9e35, 0xd9f385b9, 0xee39d7ab, 0x3b124e8b, + 0x1dc9faf7, 0x4b6d1856, 0x26a36631, 0xeae397b2, + 0x3a6efa74, 0xdd5b4332, 0x6841e7f7, 0xca7820fb, + 0xfb0af54e, 0xd8feb397, 0x454056ac, 0xba489527, + 0x55533a3a, 0x20838d87, 0xfe6ba9b7, 0xd096954b, + 0x55a867bc, 0xa1159a58, 0xcca92963, 0x99e1db33, + 0xa62a4a56, 0x3f3125f9, 0x5ef47e1c, 0x9029317c, + 0xfdf8e802, 0x04272f70, 0x80bb155c, 0x05282ce3, + 0x95c11548, 0xe4c66d22, 0x48c1133f, 0xc70f86dc, + 0x07f9c9ee, 0x41041f0f, 0x404779a4, 0x5d886e17, + 0x325f51eb, 0xd59bc0d1, 0xf2bcc18f, 0x41113564, + 0x257b7834, 0x602a9c60, 0xdff8e8a3, 0x1f636c1b, + 0x0e12b4c2, 0x02e1329e, 0xaf664fd1, 0xcad18115, + 0x6b2395e0, 0x333e92e1, 0x3b240b62, 0xeebeb922, + 0x85b2a20e, 0xe6ba0d99, 0xde720c8c, 0x2da2f728, + 0xd0127845, 0x95b794fd, 0x647d0862, 0xe7ccf5f0, + 0x5449a36f, 0x877d48fa, 0xc39dfd27, 0xf33e8d1e, + 0x0a476341, 0x992eff74, 0x3a6f6eab, 0xf4f8fd37, + 0xa812dc60, 0xa1ebddf8, 0x991be14c, 0xdb6e6b0d, + 0xc67b5510, 0x6d672c37, 0x2765d43b, 0xdcd0e804, + 0xf1290dc7, 0xcc00ffa3, 0xb5390f92, 0x690fed0b, + 0x667b9ffb, 0xcedb7d9c, 0xa091cf0b, 0xd9155ea3, + 0xbb132f88, 0x515bad24, 0x7b9479bf, 0x763bd6eb, + 0x37392eb3, 0xcc115979, 0x8026e297, 0xf42e312d, + 0x6842ada7, 0xc66a2b3b, 0x12754ccc, 0x782ef11c, + 0x6a124237, 0xb79251e7, 0x06a1bbe6, 0x4bfb6350, + 0x1a6b1018, 0x11caedfa, 0x3d25bdd8, 0xe2e1c3c9, + 0x44421659, 0x0a121386, 0xd90cec6e, 0xd5abea2a, + 0x64af674e, 0xda86a85f, 0xbebfe988, 0x64e4c3fe, + 0x9dbc8057, 0xf0f7c086, 0x60787bf8, 0x6003604d, + 0xd1fd8346, 0xf6381fb0, 0x7745ae04, 0xd736fccc, + 0x83426b33, 0xf01eab71, 0xb0804187, 0x3c005e5f, + 0x77a057be, 0xbde8ae24, 0x55464299, 0xbf582e61, + 0x4e58f48f, 0xf2ddfda2, 0xf474ef38, 0x8789bdc2, + 0x5366f9c3, 0xc8b38e74, 0xb475f255, 0x46fcd9b9, + 0x7aeb2661, 0x8b1ddf84, 0x846a0e79, 0x915f95e2, + 0x466e598e, 0x20b45770, 0x8cd55591, 0xc902de4c, + 0xb90bace1, 0xbb8205d0, 0x11a86248, 0x7574a99e, + 0xb77f19b6, 0xe0a9dc09, 0x662d09a1, 0xc4324633, + 0xe85a1f02, 0x09f0be8c, 0x4a99a025, 0x1d6efe10, + 0x1ab93d1d, 0x0ba5a4df, 0xa186f20f, 0x2868f169, + 0xdcb7da83, 0x573906fe, 0xa1e2ce9b, 0x4fcd7f52, + 0x50115e01, 0xa70683fa, 0xa002b5c4, 0x0de6d027, + 0x9af88c27, 0x773f8641, 0xc3604c06, 0x61a806b5, + 0xf0177a28, 0xc0f586e0, 0x006058aa, 0x30dc7d62, + 0x11e69ed7, 0x2338ea63, 0x53c2dd94, 0xc2c21634, + 0xbbcbee56, 0x90bcb6de, 0xebfc7da1, 0xce591d76, + 0x6f05e409, 0x4b7c0188, 0x39720a3d, 0x7c927c24, + 0x86e3725f, 0x724d9db9, 0x1ac15bb4, 0xd39eb8fc, + 0xed545578, 0x08fca5b5, 0xd83d7cd3, 0x4dad0fc4, + 0x1e50ef5e, 0xb161e6f8, 0xa28514d9, 0x6c51133c, + 0x6fd5c7e7, 0x56e14ec4, 0x362abfce, 0xddc6c837, + 0xd79a3234, 0x92638212, 0x670efa8e, 0x406000e0 + }, { + 0x3a39ce37, 0xd3faf5cf, 0xabc27737, 0x5ac52d1b, + 0x5cb0679e, 0x4fa33742, 0xd3822740, 0x99bc9bbe, + 0xd5118e9d, 0xbf0f7315, 0xd62d1c7e, 0xc700c47b, + 0xb78c1b6b, 0x21a19045, 0xb26eb1be, 0x6a366eb4, + 0x5748ab2f, 0xbc946e79, 0xc6a376d2, 0x6549c2c8, + 0x530ff8ee, 0x468dde7d, 0xd5730a1d, 0x4cd04dc6, + 0x2939bbdb, 0xa9ba4650, 0xac9526e8, 0xbe5ee304, + 0xa1fad5f0, 0x6a2d519a, 0x63ef8ce2, 0x9a86ee22, + 0xc089c2b8, 0x43242ef6, 0xa51e03aa, 0x9cf2d0a4, + 0x83c061ba, 0x9be96a4d, 0x8fe51550, 0xba645bd6, + 0x2826a2f9, 0xa73a3ae1, 0x4ba99586, 0xef5562e9, + 0xc72fefd3, 0xf752f7da, 0x3f046f69, 0x77fa0a59, + 0x80e4a915, 0x87b08601, 0x9b09e6ad, 0x3b3ee593, + 0xe990fd5a, 0x9e34d797, 0x2cf0b7d9, 0x022b8b51, + 0x96d5ac3a, 0x017da67d, 0xd1cf3ed6, 0x7c7d2d28, + 0x1f9f25cf, 0xadf2b89b, 0x5ad6b472, 0x5a88f54c, + 0xe029ac71, 0xe019a5e6, 0x47b0acfd, 0xed93fa9b, + 0xe8d3c48d, 0x283b57cc, 0xf8d56629, 0x79132e28, + 0x785f0191, 0xed756055, 0xf7960e44, 0xe3d35e8c, + 0x15056dd4, 0x88f46dba, 0x03a16125, 0x0564f0bd, + 0xc3eb9e15, 0x3c9057a2, 0x97271aec, 0xa93a072a, + 0x1b3f6d9b, 0x1e6321f5, 0xf59c66fb, 0x26dcf319, + 0x7533d928, 0xb155fdf5, 0x03563482, 0x8aba3cbb, + 0x28517711, 0xc20ad9f8, 0xabcc5167, 0xccad925f, + 0x4de81751, 0x3830dc8e, 0x379d5862, 0x9320f991, + 0xea7a90c2, 0xfb3e7bce, 0x5121ce64, 0x774fbe32, + 0xa8b6e37e, 0xc3293d46, 0x48de5369, 0x6413e680, + 0xa2ae0810, 0xdd6db224, 0x69852dfd, 0x09072166, + 0xb39a460a, 0x6445c0dd, 0x586cdecf, 0x1c20c8ae, + 0x5bbef7dd, 0x1b588d40, 0xccd2017f, 0x6bb4e3bb, + 0xdda26a7e, 0x3a59ff45, 0x3e350a44, 0xbcb4cdd5, + 0x72eacea8, 0xfa6484bb, 0x8d6612ae, 0xbf3c6f47, + 0xd29be463, 0x542f5d9e, 0xaec2771b, 0xf64e6370, + 0x740e0d8d, 0xe75b1357, 0xf8721671, 0xaf537d5d, + 0x4040cb08, 0x4eb4e2cc, 0x34d2466a, 0x0115af84, + 0xe1b00428, 0x95983a1d, 0x06b89fb4, 0xce6ea048, + 0x6f3f3b82, 0x3520ab82, 0x011a1d4b, 0x277227f8, + 0x611560b1, 0xe7933fdc, 0xbb3a792b, 0x344525bd, + 0xa08839e1, 0x51ce794b, 0x2f32c9b7, 0xa01fbac9, + 0xe01cc87e, 0xbcc7d1f6, 0xcf0111c3, 0xa1e8aac7, + 0x1a908749, 0xd44fbd9a, 0xd0dadecb, 0xd50ada38, + 0x0339c32a, 0xc6913667, 0x8df9317c, 0xe0b12b4f, + 0xf79e59b7, 0x43f5bb3a, 0xf2d519ff, 0x27d9459c, + 0xbf97222c, 0x15e6fc2a, 0x0f91fc71, 0x9b941525, + 0xfae59361, 0xceb69ceb, 0xc2a86459, 0x12baa8d1, + 0xb6c1075e, 0xe3056a0c, 0x10d25065, 0xcb03a442, + 0xe0ec6e0e, 0x1698db3b, 0x4c98a0be, 0x3278e964, + 0x9f1f9532, 0xe0d392df, 0xd3a0342b, 0x8971f21e, + 0x1b0a7441, 0x4ba3348c, 0xc5be7120, 0xc37632d8, + 0xdf359f8d, 0x9b992f2e, 0xe60b6f47, 0x0fe3f11d, + 0xe54cda54, 0x1edad891, 0xce6279cf, 0xcd3e7e6f, + 0x1618b166, 0xfd2c1d05, 0x848fd2c5, 0xf6fb2299, + 0xf523f357, 0xa6327623, 0x93a83531, 0x56cccd02, + 0xacf08162, 0x5a75ebb5, 0x6e163697, 0x88d273cc, + 0xde966292, 0x81b949d0, 0x4c50901b, 0x71c65614, + 0xe6c6c7bd, 0x327a140a, 0x45e1d006, 0xc3f27b9a, + 0xc9aa53fd, 0x62a80f00, 0xbb25bfe2, 0x35bdd2f6, + 0x71126905, 0xb2040222, 0xb6cbcf7c, 0xcd769c2b, + 0x53113ec0, 0x1640e3d3, 0x38abbd60, 0x2547adf0, + 0xba38209c, 0xf746ce76, 0x77afa1c5, 0x20756060, + 0x85cbfe4e, 0x8ae88dd8, 0x7aaaf9b0, 0x4cf9aa7e, + 0x1948c25c, 0x02fb8a8c, 0x01c36ae4, 0xd6ebe1f9, + 0x90d4f869, 0xa65cdea0, 0x3f09252d, 0xc208e69f, + 0xb74e6132, 0xce77e25b, 0x578fdfe3, 0x3ac372e6 + } + }, { + 0x243f6a88, 0x85a308d3, 0x13198a2e, 0x03707344, + 0xa4093822, 0x299f31d0, 0x082efa98, 0xec4e6c89, + 0x452821e6, 0x38d01377, 0xbe5466cf, 0x34e90c6c, + 0xc0ac29b7, 0xc97c50dd, 0x3f84d5b5, 0xb5470917, + 0x9216d5d9, 0x8979fb1b + } +}; + +static unsigned char BF_itoa64[64 + 1] = + "./ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789"; + +static unsigned char BF_atoi64[0x60] = { + 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 0, 1, + 54, 55, 56, 57, 58, 59, 60, 61, 62, 63, 64, 64, 64, 64, 64, 64, + 64, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, + 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 64, 64, 64, 64, 64, + 64, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, + 43, 44, 45, 46, 47, 48, 49, 50, 51, 52, 53, 64, 64, 64, 64, 64 +}; + +#define BF_safe_atoi64(dst, src) \ +{ \ + tmp = (unsigned char)(src); \ + if ((unsigned int)(tmp -= 0x20) >= 0x60) return -1; \ + tmp = BF_atoi64[tmp]; \ + if (tmp > 63) return -1; \ + (dst) = tmp; \ +} + +static int BF_decode(BF_word *dst, const char *src, int size) +{ + unsigned char *dptr = (unsigned char *)dst; + unsigned char *end = dptr + size; + const unsigned char *sptr = (const unsigned char *)src; + unsigned int tmp, c1, c2, c3, c4; + + do { + BF_safe_atoi64(c1, *sptr++); + BF_safe_atoi64(c2, *sptr++); + *dptr++ = (c1 << 2) | ((c2 & 0x30) >> 4); + if (dptr >= end) break; + + BF_safe_atoi64(c3, *sptr++); + *dptr++ = ((c2 & 0x0F) << 4) | ((c3 & 0x3C) >> 2); + if (dptr >= end) break; + + BF_safe_atoi64(c4, *sptr++); + *dptr++ = ((c3 & 0x03) << 6) | c4; + } while (dptr < end); + + return 0; +} + +static void BF_encode(char *dst, const BF_word *src, int size) +{ + const unsigned char *sptr = (const unsigned char *)src; + const unsigned char *end = sptr + size; + unsigned char *dptr = (unsigned char *)dst; + unsigned int c1, c2; + + do { + c1 = *sptr++; + *dptr++ = BF_itoa64[c1 >> 2]; + c1 = (c1 & 0x03) << 4; + if (sptr >= end) { + *dptr++ = BF_itoa64[c1]; + break; + } + + c2 = *sptr++; + c1 |= c2 >> 4; + *dptr++ = BF_itoa64[c1]; + c1 = (c2 & 0x0f) << 2; + if (sptr >= end) { + *dptr++ = BF_itoa64[c1]; + break; + } + + c2 = *sptr++; + c1 |= c2 >> 6; + *dptr++ = BF_itoa64[c1]; + *dptr++ = BF_itoa64[c2 & 0x3f]; + } while (sptr < end); +} + +static void BF_swap(BF_word *x, int count) +{ + static int endianness_check = 1; + char *is_little_endian = (char *)&endianness_check; + BF_word tmp; + + if (*is_little_endian) + do { + tmp = *x; + tmp = (tmp << 16) | (tmp >> 16); + *x++ = ((tmp & 0x00FF00FF) << 8) | ((tmp >> 8) & 0x00FF00FF); + } while (--count); +} + +#if BF_SCALE +/* Architectures which can shift addresses left by 2 bits with no extra cost */ +#define BF_ROUND(L, R, N) \ + tmp1 = L & 0xFF; \ + tmp2 = L >> 8; \ + tmp2 &= 0xFF; \ + tmp3 = L >> 16; \ + tmp3 &= 0xFF; \ + tmp4 = L >> 24; \ + tmp1 = data.ctx.S[3][tmp1]; \ + tmp2 = data.ctx.S[2][tmp2]; \ + tmp3 = data.ctx.S[1][tmp3]; \ + tmp3 += data.ctx.S[0][tmp4]; \ + tmp3 ^= tmp2; \ + R ^= data.ctx.P[N + 1]; \ + tmp3 += tmp1; \ + R ^= tmp3; +#else +/* Architectures with no complicated addressing modes supported */ +#define BF_INDEX(S, i) \ + (*((BF_word *)(((unsigned char *)S) + (i)))) +#define BF_ROUND(L, R, N) \ + tmp1 = L & 0xFF; \ + tmp1 <<= 2; \ + tmp2 = L >> 6; \ + tmp2 &= 0x3FC; \ + tmp3 = L >> 14; \ + tmp3 &= 0x3FC; \ + tmp4 = L >> 22; \ + tmp4 &= 0x3FC; \ + tmp1 = BF_INDEX(data.ctx.S[3], tmp1); \ + tmp2 = BF_INDEX(data.ctx.S[2], tmp2); \ + tmp3 = BF_INDEX(data.ctx.S[1], tmp3); \ + tmp3 += BF_INDEX(data.ctx.S[0], tmp4); \ + tmp3 ^= tmp2; \ + R ^= data.ctx.P[N + 1]; \ + tmp3 += tmp1; \ + R ^= tmp3; +#endif + +/* + * Encrypt one block, BF_N is hardcoded here. + */ +#define BF_ENCRYPT \ + L ^= data.ctx.P[0]; \ + BF_ROUND(L, R, 0); \ + BF_ROUND(R, L, 1); \ + BF_ROUND(L, R, 2); \ + BF_ROUND(R, L, 3); \ + BF_ROUND(L, R, 4); \ + BF_ROUND(R, L, 5); \ + BF_ROUND(L, R, 6); \ + BF_ROUND(R, L, 7); \ + BF_ROUND(L, R, 8); \ + BF_ROUND(R, L, 9); \ + BF_ROUND(L, R, 10); \ + BF_ROUND(R, L, 11); \ + BF_ROUND(L, R, 12); \ + BF_ROUND(R, L, 13); \ + BF_ROUND(L, R, 14); \ + BF_ROUND(R, L, 15); \ + tmp4 = R; \ + R = L; \ + L = tmp4 ^ data.ctx.P[BF_N + 1]; + +#if BF_ASM +#define BF_body() \ + _BF_body_r(&data.ctx); +#else +#define BF_body() \ + L = R = 0; \ + ptr = data.ctx.P; \ + do { \ + ptr += 2; \ + BF_ENCRYPT; \ + *(ptr - 2) = L; \ + *(ptr - 1) = R; \ + } while (ptr < &data.ctx.P[BF_N + 2]); \ +\ + ptr = data.ctx.S[0]; \ + do { \ + ptr += 2; \ + BF_ENCRYPT; \ + *(ptr - 2) = L; \ + *(ptr - 1) = R; \ + } while (ptr < &data.ctx.S[3][0xFF]); +#endif + +static void BF_set_key(const char *key, BF_key expanded, BF_key initial, + unsigned char flags) +{ + const char *ptr = key; + unsigned int bug, i, j; + BF_word safety, sign, diff, tmp[2]; + +/* + * There was a sign extension bug in older revisions of this function. While + * we would have liked to simply fix the bug and move on, we have to provide + * a backwards compatibility feature (essentially the bug) for some systems and + * a safety measure for some others. The latter is needed because for certain + * multiple inputs to the buggy algorithm there exist easily found inputs to + * the correct algorithm that produce the same hash. Thus, we optionally + * deviate from the correct algorithm just enough to avoid such collisions. + * While the bug itself affected the majority of passwords containing + * characters with the 8th bit set (although only a percentage of those in a + * collision-producing way), the anti-collision safety measure affects + * only a subset of passwords containing the '\xff' character (not even all of + * those passwords, just some of them). This character is not found in valid + * UTF-8 sequences and is rarely used in popular 8-bit character encodings. + * Thus, the safety measure is unlikely to cause much annoyance, and is a + * reasonable tradeoff to use when authenticating against existing hashes that + * are not reliably known to have been computed with the correct algorithm. + * + * We use an approach that tries to minimize side-channel leaks of password + * information - that is, we mostly use fixed-cost bitwise operations instead + * of branches or table lookups. (One conditional branch based on password + * length remains. It is not part of the bug aftermath, though, and is + * difficult and possibly unreasonable to avoid given the use of C strings by + * the caller, which results in similar timing leaks anyway.) + * + * For actual implementation, we set an array index in the variable "bug" + * (0 means no bug, 1 means sign extension bug emulation) and a flag in the + * variable "safety" (bit 16 is set when the safety measure is requested). + * Valid combinations of settings are: + * + * Prefix "$2a$": bug = 0, safety = 0x10000 + * Prefix "$2b$": bug = 0, safety = 0 + * Prefix "$2x$": bug = 1, safety = 0 + * Prefix "$2y$": bug = 0, safety = 0 + */ + bug = (unsigned int)flags & 1; + safety = ((BF_word)flags & 2) << 15; + + sign = diff = 0; + + for (i = 0; i < BF_N + 2; i++) { + tmp[0] = tmp[1] = 0; + for (j = 0; j < 4; j++) { + tmp[0] <<= 8; + tmp[0] |= (unsigned char)*ptr; /* correct */ + tmp[1] <<= 8; + tmp[1] |= (BF_word_signed)(signed char)*ptr; /* bug */ +/* + * Sign extension in the first char has no effect - nothing to overwrite yet, + * and those extra 24 bits will be fully shifted out of the 32-bit word. For + * chars 2, 3, 4 in each four-char block, we set bit 7 of "sign" if sign + * extension in tmp[1] occurs. Once this flag is set, it remains set. + */ + if (j) + sign |= tmp[1] & 0x80; + if (!*ptr) + ptr = key; + else + ptr++; + } + diff |= tmp[0] ^ tmp[1]; /* Non-zero on any differences */ + + expanded[i] = tmp[bug]; + initial[i] = BF_init_state.P[i] ^ tmp[bug]; + } + +/* + * At this point, "diff" is zero iff the correct and buggy algorithms produced + * exactly the same result. If so and if "sign" is non-zero, which indicates + * that there was a non-benign sign extension, this means that we have a + * collision between the correctly computed hash for this password and a set of + * passwords that could be supplied to the buggy algorithm. Our safety measure + * is meant to protect from such many-buggy to one-correct collisions, by + * deviating from the correct algorithm in such cases. Let's check for this. + */ + diff |= diff >> 16; /* still zero iff exact match */ + diff &= 0xffff; /* ditto */ + diff += 0xffff; /* bit 16 set iff "diff" was non-zero (on non-match) */ + sign <<= 9; /* move the non-benign sign extension flag to bit 16 */ + sign &= ~diff & safety; /* action needed? */ + +/* + * If we have determined that we need to deviate from the correct algorithm, + * flip bit 16 in initial expanded key. (The choice of 16 is arbitrary, but + * let's stick to it now. It came out of the approach we used above, and it's + * not any worse than any other choice we could make.) + * + * It is crucial that we don't do the same to the expanded key used in the main + * Eksblowfish loop. By doing it to only one of these two, we deviate from a + * state that could be directly specified by a password to the buggy algorithm + * (and to the fully correct one as well, but that's a side-effect). + */ + initial[0] ^= sign; +} + +static const unsigned char flags_by_subtype[26] = + {2, 4, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 4, 0}; + +static char *BF_crypt(const char *key, const char *setting, + char *output, int size, + BF_word min) +{ +#if BF_ASM + extern void _BF_body_r(BF_ctx *ctx); +#endif + struct { + BF_ctx ctx; + BF_key expanded_key; + union { + BF_word salt[4]; + BF_word output[6]; + } binary; + } data; + BF_word L, R; + BF_word tmp1, tmp2, tmp3, tmp4; + BF_word *ptr; + BF_word count; + int i; + + if (size < 7 + 22 + 31 + 1) { + __set_errno(ERANGE); + return NULL; + } + + if (setting[0] != '$' || + setting[1] != '2' || + setting[2] < 'a' || setting[2] > 'z' || + !flags_by_subtype[(unsigned int)(unsigned char)setting[2] - 'a'] || + setting[3] != '$' || + setting[4] < '0' || setting[4] > '3' || + setting[5] < '0' || setting[5] > '9' || + (setting[4] == '3' && setting[5] > '1') || + setting[6] != '$') { + __set_errno(EINVAL); + return NULL; + } + + count = (BF_word)1 << ((setting[4] - '0') * 10 + (setting[5] - '0')); + if (count < min || BF_decode(data.binary.salt, &setting[7], 16)) { + __set_errno(EINVAL); + return NULL; + } + BF_swap(data.binary.salt, 4); + + BF_set_key(key, data.expanded_key, data.ctx.P, + flags_by_subtype[(unsigned int)(unsigned char)setting[2] - 'a']); + + memcpy(data.ctx.S, BF_init_state.S, sizeof(data.ctx.S)); + + L = R = 0; + for (i = 0; i < BF_N + 2; i += 2) { + L ^= data.binary.salt[i & 2]; + R ^= data.binary.salt[(i & 2) + 1]; + BF_ENCRYPT; + data.ctx.P[i] = L; + data.ctx.P[i + 1] = R; + } + + ptr = data.ctx.S[0]; + do { + ptr += 4; + L ^= data.binary.salt[(BF_N + 2) & 3]; + R ^= data.binary.salt[(BF_N + 3) & 3]; + BF_ENCRYPT; + *(ptr - 4) = L; + *(ptr - 3) = R; + + L ^= data.binary.salt[(BF_N + 4) & 3]; + R ^= data.binary.salt[(BF_N + 5) & 3]; + BF_ENCRYPT; + *(ptr - 2) = L; + *(ptr - 1) = R; + } while (ptr < &data.ctx.S[3][0xFF]); + + do { + int done; + + for (i = 0; i < BF_N + 2; i += 2) { + data.ctx.P[i] ^= data.expanded_key[i]; + data.ctx.P[i + 1] ^= data.expanded_key[i + 1]; + } + + done = 0; + do { + BF_body(); + if (done) + break; + done = 1; + + tmp1 = data.binary.salt[0]; + tmp2 = data.binary.salt[1]; + tmp3 = data.binary.salt[2]; + tmp4 = data.binary.salt[3]; + for (i = 0; i < BF_N; i += 4) { + data.ctx.P[i] ^= tmp1; + data.ctx.P[i + 1] ^= tmp2; + data.ctx.P[i + 2] ^= tmp3; + data.ctx.P[i + 3] ^= tmp4; + } + data.ctx.P[16] ^= tmp1; + data.ctx.P[17] ^= tmp2; + } while (1); + } while (--count); + + for (i = 0; i < 6; i += 2) { + L = BF_magic_w[i]; + R = BF_magic_w[i + 1]; + + count = 64; + do { + BF_ENCRYPT; + } while (--count); + + data.binary.output[i] = L; + data.binary.output[i + 1] = R; + } + + memcpy(output, setting, 7 + 22 - 1); + output[7 + 22 - 1] = BF_itoa64[(int) + BF_atoi64[(int)setting[7 + 22 - 1] - 0x20] & 0x30]; + +/* This has to be bug-compatible with the original implementation, so + * only encode 23 of the 24 bytes. :-) */ + BF_swap(data.binary.output, 6); + BF_encode(&output[7 + 22], data.binary.output, 23); + output[7 + 22 + 31] = '\0'; + + return output; +} + +int _crypt_output_magic(const char *setting, char *output, int size) +{ + if (size < 3) + return -1; + + output[0] = '*'; + output[1] = '0'; + output[2] = '\0'; + + if (setting[0] == '*' && setting[1] == '0') + output[1] = '1'; + + return 0; +} + +/* + * Please preserve the runtime self-test. It serves two purposes at once: + * + * 1. We really can't afford the risk of producing incompatible hashes e.g. + * when there's something like gcc bug 26587 again, whereas an application or + * library integrating this code might not also integrate our external tests or + * it might not run them after every build. Even if it does, the miscompile + * might only occur on the production build, but not on a testing build (such + * as because of different optimization settings). It is painful to recover + * from incorrectly-computed hashes - merely fixing whatever broke is not + * enough. Thus, a proactive measure like this self-test is needed. + * + * 2. We don't want to leave sensitive data from our actual password hash + * computation on the stack or in registers. Previous revisions of the code + * would do explicit cleanups, but simply running the self-test after hash + * computation is more reliable. + * + * The performance cost of this quick self-test is around 0.6% at the "$2a$08" + * setting. + */ +char *_crypt_blowfish_rn(const char *key, const char *setting, + char *output, int size) +{ + const char *test_key = "8b \xd0\xc1\xd2\xcf\xcc\xd8"; + const char *test_setting = "$2a$00$abcdefghijklmnopqrstuu"; + static const char * const test_hashes[2] = + {"i1D709vfamulimlGcq0qq3UvuUasvEa\0\x55", /* 'a', 'b', 'y' */ + "VUrPmXD6q/nVSSp7pNDhCR9071IfIRe\0\x55"}; /* 'x' */ + const char *test_hash = test_hashes[0]; + char *retval; + const char *p; + int save_errno, ok; + struct { + char s[7 + 22 + 1]; + char o[7 + 22 + 31 + 1 + 1 + 1]; + } buf; + +/* Hash the supplied password */ + _crypt_output_magic(setting, output, size); + retval = BF_crypt(key, setting, output, size, 16); + save_errno = errno; + +/* + * Do a quick self-test. It is important that we make both calls to BF_crypt() + * from the same scope such that they likely use the same stack locations, + * which makes the second call overwrite the first call's sensitive data on the + * stack and makes it more likely that any alignment related issues would be + * detected by the self-test. + */ + memcpy(buf.s, test_setting, sizeof(buf.s)); + if (retval) { + unsigned int flags = flags_by_subtype[ + (unsigned int)(unsigned char)setting[2] - 'a']; + test_hash = test_hashes[flags & 1]; + buf.s[2] = setting[2]; + } + memset(buf.o, 0x55, sizeof(buf.o)); + buf.o[sizeof(buf.o) - 1] = 0; + p = BF_crypt(test_key, buf.s, buf.o, sizeof(buf.o) - (1 + 1), 1); + + ok = (p == buf.o && + !memcmp(p, buf.s, 7 + 22) && + !memcmp(p + (7 + 22), test_hash, 31 + 1 + 1 + 1)); + + { + const char *k = "\xff\xa3" "34" "\xff\xff\xff\xa3" "345"; + BF_key ae, ai, ye, yi; + BF_set_key(k, ae, ai, 2); /* $2a$ */ + BF_set_key(k, ye, yi, 4); /* $2y$ */ + ai[0] ^= 0x10000; /* undo the safety (for comparison) */ + ok = ok && ai[0] == 0xdb9c59bc && ye[17] == 0x33343500 && + !memcmp(ae, ye, sizeof(ae)) && + !memcmp(ai, yi, sizeof(ai)); + } + + __set_errno(save_errno); + if (ok) + return retval; + +/* Should not happen */ + _crypt_output_magic(setting, output, size); + __set_errno(EINVAL); /* pretend we don't support this hash type */ + return NULL; +} + +char *_crypt_gensalt_blowfish_rn(const char *prefix, unsigned long count, + const char *input, int size, char *output, int output_size) +{ + if (size < 16 || output_size < 7 + 22 + 1 || + (count && (count < 4 || count > 31)) || + prefix[0] != '$' || prefix[1] != '2' || + (prefix[2] != 'a' && prefix[2] != 'b' && prefix[2] != 'y')) { + if (output_size > 0) output[0] = '\0'; + __set_errno((output_size < 7 + 22 + 1) ? ERANGE : EINVAL); + return NULL; + } + + if (!count) count = 5; + + output[0] = '$'; + output[1] = '2'; + output[2] = prefix[2]; + output[3] = '$'; + output[4] = '0' + count / 10; + output[5] = '0' + count % 10; + output[6] = '$'; + + BF_encode(&output[7], (const BF_word *)input, 16); + output[7 + 22] = '\0'; + + return output; +} diff --git a/crypt_blowfish/crypt_blowfish.h b/crypt_blowfish/crypt_blowfish.h new file mode 100644 index 000000000..2ee0d8c1d --- /dev/null +++ b/crypt_blowfish/crypt_blowfish.h @@ -0,0 +1,27 @@ +/* + * Written by Solar Designer in 2000-2011. + * No copyright is claimed, and the software is hereby placed in the public + * domain. In case this attempt to disclaim copyright and place the software + * in the public domain is deemed null and void, then the software is + * Copyright (c) 2000-2011 Solar Designer and it is hereby released to the + * general public under the following terms: + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted. + * + * There's ABSOLUTELY NO WARRANTY, express or implied. + * + * See crypt_blowfish.c for more information. + */ + +#ifndef _CRYPT_BLOWFISH_H +#define _CRYPT_BLOWFISH_H + +extern int _crypt_output_magic(const char *setting, char *output, int size); +extern char *_crypt_blowfish_rn(const char *key, const char *setting, + char *output, int size); +extern char *_crypt_gensalt_blowfish_rn(const char *prefix, + unsigned long count, + const char *input, int size, char *output, int output_size); + +#endif diff --git a/crypt_blowfish/crypt_gensalt.c b/crypt_blowfish/crypt_gensalt.c new file mode 100644 index 000000000..73c15a1ad --- /dev/null +++ b/crypt_blowfish/crypt_gensalt.c @@ -0,0 +1,124 @@ +/* + * Written by Solar Designer in 2000-2011. + * No copyright is claimed, and the software is hereby placed in the public + * domain. In case this attempt to disclaim copyright and place the software + * in the public domain is deemed null and void, then the software is + * Copyright (c) 2000-2011 Solar Designer and it is hereby released to the + * general public under the following terms: + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted. + * + * There's ABSOLUTELY NO WARRANTY, express or implied. + * + * See crypt_blowfish.c for more information. + * + * This file contains salt generation functions for the traditional and + * other common crypt(3) algorithms, except for bcrypt which is defined + * entirely in crypt_blowfish.c. + */ + +#include + +#include +#ifndef __set_errno +#define __set_errno(val) errno = (val) +#endif + +/* Just to make sure the prototypes match the actual definitions */ +#include "crypt_gensalt.h" + +unsigned char _crypt_itoa64[64 + 1] = + "./0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz"; + +char *_crypt_gensalt_traditional_rn(const char *prefix, unsigned long count, + const char *input, int size, char *output, int output_size) +{ + (void) prefix; + + if (size < 2 || output_size < 2 + 1 || (count && count != 25)) { + if (output_size > 0) output[0] = '\0'; + __set_errno((output_size < 2 + 1) ? ERANGE : EINVAL); + return NULL; + } + + output[0] = _crypt_itoa64[(unsigned int)input[0] & 0x3f]; + output[1] = _crypt_itoa64[(unsigned int)input[1] & 0x3f]; + output[2] = '\0'; + + return output; +} + +char *_crypt_gensalt_extended_rn(const char *prefix, unsigned long count, + const char *input, int size, char *output, int output_size) +{ + unsigned long value; + + (void) prefix; + +/* Even iteration counts make it easier to detect weak DES keys from a look + * at the hash, so they should be avoided */ + if (size < 3 || output_size < 1 + 4 + 4 + 1 || + (count && (count > 0xffffff || !(count & 1)))) { + if (output_size > 0) output[0] = '\0'; + __set_errno((output_size < 1 + 4 + 4 + 1) ? ERANGE : EINVAL); + return NULL; + } + + if (!count) count = 725; + + output[0] = '_'; + output[1] = _crypt_itoa64[count & 0x3f]; + output[2] = _crypt_itoa64[(count >> 6) & 0x3f]; + output[3] = _crypt_itoa64[(count >> 12) & 0x3f]; + output[4] = _crypt_itoa64[(count >> 18) & 0x3f]; + value = (unsigned long)(unsigned char)input[0] | + ((unsigned long)(unsigned char)input[1] << 8) | + ((unsigned long)(unsigned char)input[2] << 16); + output[5] = _crypt_itoa64[value & 0x3f]; + output[6] = _crypt_itoa64[(value >> 6) & 0x3f]; + output[7] = _crypt_itoa64[(value >> 12) & 0x3f]; + output[8] = _crypt_itoa64[(value >> 18) & 0x3f]; + output[9] = '\0'; + + return output; +} + +char *_crypt_gensalt_md5_rn(const char *prefix, unsigned long count, + const char *input, int size, char *output, int output_size) +{ + unsigned long value; + + (void) prefix; + + if (size < 3 || output_size < 3 + 4 + 1 || (count && count != 1000)) { + if (output_size > 0) output[0] = '\0'; + __set_errno((output_size < 3 + 4 + 1) ? ERANGE : EINVAL); + return NULL; + } + + output[0] = '$'; + output[1] = '1'; + output[2] = '$'; + value = (unsigned long)(unsigned char)input[0] | + ((unsigned long)(unsigned char)input[1] << 8) | + ((unsigned long)(unsigned char)input[2] << 16); + output[3] = _crypt_itoa64[value & 0x3f]; + output[4] = _crypt_itoa64[(value >> 6) & 0x3f]; + output[5] = _crypt_itoa64[(value >> 12) & 0x3f]; + output[6] = _crypt_itoa64[(value >> 18) & 0x3f]; + output[7] = '\0'; + + if (size >= 6 && output_size >= 3 + 4 + 4 + 1) { + value = (unsigned long)(unsigned char)input[3] | + ((unsigned long)(unsigned char)input[4] << 8) | + ((unsigned long)(unsigned char)input[5] << 16); + output[7] = _crypt_itoa64[value & 0x3f]; + output[8] = _crypt_itoa64[(value >> 6) & 0x3f]; + output[9] = _crypt_itoa64[(value >> 12) & 0x3f]; + output[10] = _crypt_itoa64[(value >> 18) & 0x3f]; + output[11] = '\0'; + } + + return output; +} diff --git a/crypt_blowfish/crypt_gensalt.h b/crypt_blowfish/crypt_gensalt.h new file mode 100644 index 000000000..457bbfe29 --- /dev/null +++ b/crypt_blowfish/crypt_gensalt.h @@ -0,0 +1,30 @@ +/* + * Written by Solar Designer in 2000-2011. + * No copyright is claimed, and the software is hereby placed in the public + * domain. In case this attempt to disclaim copyright and place the software + * in the public domain is deemed null and void, then the software is + * Copyright (c) 2000-2011 Solar Designer and it is hereby released to the + * general public under the following terms: + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted. + * + * There's ABSOLUTELY NO WARRANTY, express or implied. + * + * See crypt_blowfish.c for more information. + */ + +#ifndef _CRYPT_GENSALT_H +#define _CRYPT_GENSALT_H + +extern unsigned char _crypt_itoa64[]; +extern char *_crypt_gensalt_traditional_rn(const char *prefix, + unsigned long count, + const char *input, int size, char *output, int output_size); +extern char *_crypt_gensalt_extended_rn(const char *prefix, + unsigned long count, + const char *input, int size, char *output, int output_size); +extern char *_crypt_gensalt_md5_rn(const char *prefix, unsigned long count, + const char *input, int size, char *output, int output_size); + +#endif diff --git a/crypt_blowfish/ow-crypt.h b/crypt_blowfish/ow-crypt.h new file mode 100644 index 000000000..2e4879426 --- /dev/null +++ b/crypt_blowfish/ow-crypt.h @@ -0,0 +1,43 @@ +/* + * Written by Solar Designer in 2000-2011. + * No copyright is claimed, and the software is hereby placed in the public + * domain. In case this attempt to disclaim copyright and place the software + * in the public domain is deemed null and void, then the software is + * Copyright (c) 2000-2011 Solar Designer and it is hereby released to the + * general public under the following terms: + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted. + * + * There's ABSOLUTELY NO WARRANTY, express or implied. + * + * See crypt_blowfish.c for more information. + */ + +#ifndef _OW_CRYPT_H +#define _OW_CRYPT_H + +#ifndef __GNUC__ +#undef __const +#define __const const +#endif + +#ifndef __SKIP_GNU +extern char *crypt(__const char *key, __const char *setting); +extern char *crypt_r(__const char *key, __const char *setting, void *data); +#endif + +#ifndef __SKIP_OW +extern char *crypt_rn(__const char *key, __const char *setting, + void *data, int size); +extern char *crypt_ra(__const char *key, __const char *setting, + void **data, int *size); +extern char *crypt_gensalt(__const char *prefix, unsigned long count, + __const char *input, int size); +extern char *crypt_gensalt_rn(__const char *prefix, unsigned long count, + __const char *input, int size, char *output, int output_size); +extern char *crypt_gensalt_ra(__const char *prefix, unsigned long count, + __const char *input, int size); +#endif + +#endif diff --git a/crypt_blowfish/x86.S b/crypt_blowfish/x86.S new file mode 100644 index 000000000..b0f1cd2ef --- /dev/null +++ b/crypt_blowfish/x86.S @@ -0,0 +1,203 @@ +/* + * Written by Solar Designer in 1998-2010. + * No copyright is claimed, and the software is hereby placed in the public + * domain. In case this attempt to disclaim copyright and place the software + * in the public domain is deemed null and void, then the software is + * Copyright (c) 1998-2010 Solar Designer and it is hereby released to the + * general public under the following terms: + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted. + * + * There's ABSOLUTELY NO WARRANTY, express or implied. + * + * See crypt_blowfish.c for more information. + */ + +#ifdef __i386__ + +#if defined(__OpenBSD__) && !defined(__ELF__) +#define UNDERSCORES +#define ALIGN_LOG +#endif + +#if defined(__CYGWIN32__) || defined(__MINGW32__) +#define UNDERSCORES +#endif + +#ifdef __DJGPP__ +#define UNDERSCORES +#define ALIGN_LOG +#endif + +#ifdef UNDERSCORES +#define _BF_body_r __BF_body_r +#endif + +#ifdef ALIGN_LOG +#define DO_ALIGN(log) .align (log) +#elif defined(DUMBAS) +#define DO_ALIGN(log) .align 1 << log +#else +#define DO_ALIGN(log) .align (1 << (log)) +#endif + +#define BF_FRAME 0x200 +#define ctx %esp + +#define BF_ptr (ctx) + +#define S(N, r) N+BF_FRAME(ctx,r,4) +#ifdef DUMBAS +#define P(N) 0x1000+N+N+N+N+BF_FRAME(ctx) +#else +#define P(N) 0x1000+4*N+BF_FRAME(ctx) +#endif + +/* + * This version of the assembly code is optimized primarily for the original + * Intel Pentium but is also careful to avoid partial register stalls on the + * Pentium Pro family of processors (tested up to Pentium III Coppermine). + * + * It is possible to do 15% faster on the Pentium Pro family and probably on + * many non-Intel x86 processors, but, unfortunately, that would make things + * twice slower for the original Pentium. + * + * An additional 2% speedup may be achieved with non-reentrant code. + */ + +#define L %esi +#define R %edi +#define tmp1 %eax +#define tmp1_lo %al +#define tmp2 %ecx +#define tmp2_hi %ch +#define tmp3 %edx +#define tmp3_lo %dl +#define tmp4 %ebx +#define tmp4_hi %bh +#define tmp5 %ebp + +.text + +#define BF_ROUND(L, R, N) \ + xorl L,tmp2; \ + xorl tmp1,tmp1; \ + movl tmp2,L; \ + shrl $16,tmp2; \ + movl L,tmp4; \ + movb tmp2_hi,tmp1_lo; \ + andl $0xFF,tmp2; \ + movb tmp4_hi,tmp3_lo; \ + andl $0xFF,tmp4; \ + movl S(0,tmp1),tmp1; \ + movl S(0x400,tmp2),tmp5; \ + addl tmp5,tmp1; \ + movl S(0x800,tmp3),tmp5; \ + xorl tmp5,tmp1; \ + movl S(0xC00,tmp4),tmp5; \ + addl tmp1,tmp5; \ + movl 4+P(N),tmp2; \ + xorl tmp5,R + +#define BF_ENCRYPT_START \ + BF_ROUND(L, R, 0); \ + BF_ROUND(R, L, 1); \ + BF_ROUND(L, R, 2); \ + BF_ROUND(R, L, 3); \ + BF_ROUND(L, R, 4); \ + BF_ROUND(R, L, 5); \ + BF_ROUND(L, R, 6); \ + BF_ROUND(R, L, 7); \ + BF_ROUND(L, R, 8); \ + BF_ROUND(R, L, 9); \ + BF_ROUND(L, R, 10); \ + BF_ROUND(R, L, 11); \ + BF_ROUND(L, R, 12); \ + BF_ROUND(R, L, 13); \ + BF_ROUND(L, R, 14); \ + BF_ROUND(R, L, 15); \ + movl BF_ptr,tmp5; \ + xorl L,tmp2; \ + movl P(17),L + +#define BF_ENCRYPT_END \ + xorl R,L; \ + movl tmp2,R + +DO_ALIGN(5) +.globl _BF_body_r +_BF_body_r: + movl 4(%esp),%eax + pushl %ebp + pushl %ebx + pushl %esi + pushl %edi + subl $BF_FRAME-8,%eax + xorl L,L + cmpl %esp,%eax + ja BF_die + xchgl %eax,%esp + xorl R,R + pushl %eax + leal 0x1000+BF_FRAME-4(ctx),%eax + movl 0x1000+BF_FRAME-4(ctx),tmp2 + pushl %eax + xorl tmp3,tmp3 +BF_loop_P: + BF_ENCRYPT_START + addl $8,tmp5 + BF_ENCRYPT_END + leal 0x1000+18*4+BF_FRAME(ctx),tmp1 + movl tmp5,BF_ptr + cmpl tmp5,tmp1 + movl L,-8(tmp5) + movl R,-4(tmp5) + movl P(0),tmp2 + ja BF_loop_P + leal BF_FRAME(ctx),tmp5 + xorl tmp3,tmp3 + movl tmp5,BF_ptr +BF_loop_S: + BF_ENCRYPT_START + BF_ENCRYPT_END + movl P(0),tmp2 + movl L,(tmp5) + movl R,4(tmp5) + BF_ENCRYPT_START + BF_ENCRYPT_END + movl P(0),tmp2 + movl L,8(tmp5) + movl R,12(tmp5) + BF_ENCRYPT_START + BF_ENCRYPT_END + movl P(0),tmp2 + movl L,16(tmp5) + movl R,20(tmp5) + BF_ENCRYPT_START + addl $32,tmp5 + BF_ENCRYPT_END + leal 0x1000+BF_FRAME(ctx),tmp1 + movl tmp5,BF_ptr + cmpl tmp5,tmp1 + movl P(0),tmp2 + movl L,-8(tmp5) + movl R,-4(tmp5) + ja BF_loop_S + movl 4(%esp),%esp + popl %edi + popl %esi + popl %ebx + popl %ebp + ret + +BF_die: +/* Oops, need to re-compile with a larger BF_FRAME. */ + hlt + jmp BF_die + +#endif + +#if defined(__ELF__) && defined(__linux__) +.section .note.GNU-stack,"",@progbits +#endif From 53afc86e009deef9cb4d5c43a65df6e7a2c8b9a1 Mon Sep 17 00:00:00 2001 From: Enno Rehling Date: Wed, 26 Sep 2018 17:09:29 +0200 Subject: [PATCH 028/160] fix bcrypt library, add to password.c (works on mac) --- CMakeLists.txt | 1 + crypt_blowfish/CMakeLists.txt | 6 +- crypt_blowfish/wrapper.c | 551 ++++++++++++++++++++++++++++++++++ src/CMakeLists.txt | 3 + src/util/password.c | 25 +- src/util/password.h | 9 +- 6 files changed, 587 insertions(+), 8 deletions(-) create mode 100644 crypt_blowfish/wrapper.c diff --git a/CMakeLists.txt b/CMakeLists.txt index 4b91565da..71d44ea9f 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -62,6 +62,7 @@ endif(TOLUA_FOUND) enable_testing() +add_subdirectory (crypt_blowfish) add_subdirectory (cJSON) add_subdirectory (storage) add_subdirectory (iniparser) diff --git a/crypt_blowfish/CMakeLists.txt b/crypt_blowfish/CMakeLists.txt index b6f810721..21cc29dea 100644 --- a/crypt_blowfish/CMakeLists.txt +++ b/crypt_blowfish/CMakeLists.txt @@ -6,11 +6,11 @@ IF (MSVC) MSVC_SET_WARNING_LEVEL(3) ENDIF (MSVC) -SET (LIB_SRC crypt_blowfish.c crypt_gensalt.c bcrypt.c) +SET (LIB_SRC bcrypt.c wrapper.c crypt_blowfish.c crypt_gensalt.c) ADD_LIBRARY (bcrypt ${LIB_SRC}) -set (CJSON_INCLUDE_DIR ${CMAKE_CURRENT_SOURCE_DIR} CACHE INTERNAL "cJSON headers") -set (CJSON_LIBRARIES bcrypt CACHE INTERNAL "bcrypt libraries") +set (BCRYPT_INCLUDE_DIR ${CMAKE_CURRENT_SOURCE_DIR} CACHE INTERNAL "cJSON headers") +set (BCRYPT_LIBRARIES bcrypt CACHE INTERNAL "bcrypt libraries") IF(UNIX AND NOT APPLE) FIND_LIBRARY(UNIX_MATH_LIBRARY m) diff --git a/crypt_blowfish/wrapper.c b/crypt_blowfish/wrapper.c new file mode 100644 index 000000000..1e49c90d8 --- /dev/null +++ b/crypt_blowfish/wrapper.c @@ -0,0 +1,551 @@ +/* + * Written by Solar Designer in 2000-2014. + * No copyright is claimed, and the software is hereby placed in the public + * domain. In case this attempt to disclaim copyright and place the software + * in the public domain is deemed null and void, then the software is + * Copyright (c) 2000-2014 Solar Designer and it is hereby released to the + * general public under the following terms: + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted. + * + * There's ABSOLUTELY NO WARRANTY, express or implied. + * + * See crypt_blowfish.c for more information. + */ + +#include +#include + +#include +#ifndef __set_errno +#define __set_errno(val) errno = (val) +#endif + +#ifdef TEST +#include +#include +#include +#include +#include +#include +#ifdef TEST_THREADS +#include +#endif +#endif + +#define CRYPT_OUTPUT_SIZE (7 + 22 + 31 + 1) +#define CRYPT_GENSALT_OUTPUT_SIZE (7 + 22 + 1) + +#if defined(__GLIBC__) && defined(_LIBC) +#define __SKIP_GNU +#endif +#include "ow-crypt.h" + +#include "crypt_blowfish.h" +#include "crypt_gensalt.h" + +#if defined(__GLIBC__) && defined(_LIBC) +/* crypt.h from glibc-crypt-2.1 will define struct crypt_data for us */ +#include "crypt.h" +extern char *__md5_crypt_r(const char *key, const char *salt, + char *buffer, int buflen); +/* crypt-entry.c needs to be patched to define __des_crypt_r rather than + * __crypt_r, and not define crypt_r and crypt at all */ +extern char *__des_crypt_r(const char *key, const char *salt, + struct crypt_data *data); +extern struct crypt_data _ufc_foobar; +#endif + +static int _crypt_data_alloc(void **data, int *size, int need) +{ + void *updated; + + if (*data && *size >= need) return 0; + + updated = realloc(*data, need); + + if (!updated) { +#ifndef __GLIBC__ + /* realloc(3) on glibc sets errno, so we don't need to bother */ + __set_errno(ENOMEM); +#endif + return -1; + } + +#if defined(__GLIBC__) && defined(_LIBC) + if (need >= sizeof(struct crypt_data)) + ((struct crypt_data *)updated)->initialized = 0; +#endif + + *data = updated; + *size = need; + + return 0; +} + +static char *_crypt_retval_magic(char *retval, const char *setting, + char *output, int size) +{ + if (retval) + return retval; + + if (_crypt_output_magic(setting, output, size)) + return NULL; /* shouldn't happen */ + + return output; +} + +#if defined(__GLIBC__) && defined(_LIBC) +/* + * Applications may re-use the same instance of struct crypt_data without + * resetting the initialized field in order to let crypt_r() skip some of + * its initialization code. Thus, it is important that our multiple hashing + * algorithms either don't conflict with each other in their use of the + * data area or reset the initialized field themselves whenever required. + * Currently, the hashing algorithms simply have no conflicts: the first + * field of struct crypt_data is the 128-byte large DES key schedule which + * __des_crypt_r() calculates each time it is called while the two other + * hashing algorithms use less than 128 bytes of the data area. + */ + +char *__crypt_rn(__const char *key, __const char *setting, + void *data, int size) +{ + if (setting[0] == '$' && setting[1] == '2') + return _crypt_blowfish_rn(key, setting, (char *)data, size); + if (setting[0] == '$' && setting[1] == '1') + return __md5_crypt_r(key, setting, (char *)data, size); + if (setting[0] == '$' || setting[0] == '_') { + __set_errno(EINVAL); + return NULL; + } + if (size >= sizeof(struct crypt_data)) + return __des_crypt_r(key, setting, (struct crypt_data *)data); + __set_errno(ERANGE); + return NULL; +} + +char *__crypt_ra(__const char *key, __const char *setting, + void **data, int *size) +{ + if (setting[0] == '$' && setting[1] == '2') { + if (_crypt_data_alloc(data, size, CRYPT_OUTPUT_SIZE)) + return NULL; + return _crypt_blowfish_rn(key, setting, (char *)*data, *size); + } + if (setting[0] == '$' && setting[1] == '1') { + if (_crypt_data_alloc(data, size, CRYPT_OUTPUT_SIZE)) + return NULL; + return __md5_crypt_r(key, setting, (char *)*data, *size); + } + if (setting[0] == '$' || setting[0] == '_') { + __set_errno(EINVAL); + return NULL; + } + if (_crypt_data_alloc(data, size, sizeof(struct crypt_data))) + return NULL; + return __des_crypt_r(key, setting, (struct crypt_data *)*data); +} + +char *__crypt_r(__const char *key, __const char *setting, + struct crypt_data *data) +{ + return _crypt_retval_magic( + __crypt_rn(key, setting, data, sizeof(*data)), + setting, (char *)data, sizeof(*data)); +} + +char *__crypt(__const char *key, __const char *setting) +{ + return _crypt_retval_magic( + __crypt_rn(key, setting, &_ufc_foobar, sizeof(_ufc_foobar)), + setting, (char *)&_ufc_foobar, sizeof(_ufc_foobar)); +} +#else +char *crypt_rn(const char *key, const char *setting, void *data, int size) +{ + return _crypt_blowfish_rn(key, setting, (char *)data, size); +} + +char *crypt_ra(const char *key, const char *setting, + void **data, int *size) +{ + if (_crypt_data_alloc(data, size, CRYPT_OUTPUT_SIZE)) + return NULL; + return _crypt_blowfish_rn(key, setting, (char *)*data, *size); +} + +char *crypt_r(const char *key, const char *setting, void *data) +{ + return _crypt_retval_magic( + crypt_rn(key, setting, data, CRYPT_OUTPUT_SIZE), + setting, (char *)data, CRYPT_OUTPUT_SIZE); +} + +char *crypt(const char *key, const char *setting) +{ + static char output[CRYPT_OUTPUT_SIZE]; + + return _crypt_retval_magic( + crypt_rn(key, setting, output, sizeof(output)), + setting, output, sizeof(output)); +} + +#define __crypt_gensalt_rn crypt_gensalt_rn +#define __crypt_gensalt_ra crypt_gensalt_ra +#define __crypt_gensalt crypt_gensalt +#endif + +char *__crypt_gensalt_rn(const char *prefix, unsigned long count, + const char *input, int size, char *output, int output_size) +{ + char *(*use)(const char *_prefix, unsigned long _count, + const char *_input, int _size, + char *_output, int _output_size); + + /* This may be supported on some platforms in the future */ + if (!input) { + __set_errno(EINVAL); + return NULL; + } + + if (!strncmp(prefix, "$2a$", 4) || !strncmp(prefix, "$2b$", 4) || + !strncmp(prefix, "$2y$", 4)) + use = _crypt_gensalt_blowfish_rn; + else + if (!strncmp(prefix, "$1$", 3)) + use = _crypt_gensalt_md5_rn; + else + if (prefix[0] == '_') + use = _crypt_gensalt_extended_rn; + else + if (!prefix[0] || + (prefix[0] && prefix[1] && + memchr(_crypt_itoa64, prefix[0], 64) && + memchr(_crypt_itoa64, prefix[1], 64))) + use = _crypt_gensalt_traditional_rn; + else { + __set_errno(EINVAL); + return NULL; + } + + return use(prefix, count, input, size, output, output_size); +} + +char *__crypt_gensalt_ra(const char *prefix, unsigned long count, + const char *input, int size) +{ + char output[CRYPT_GENSALT_OUTPUT_SIZE]; + char *retval; + + retval = __crypt_gensalt_rn(prefix, count, + input, size, output, sizeof(output)); + + if (retval) { + retval = strdup(retval); +#ifndef __GLIBC__ + /* strdup(3) on glibc sets errno, so we don't need to bother */ + if (!retval) + __set_errno(ENOMEM); +#endif + } + + return retval; +} + +char *__crypt_gensalt(const char *prefix, unsigned long count, + const char *input, int size) +{ + static char output[CRYPT_GENSALT_OUTPUT_SIZE]; + + return __crypt_gensalt_rn(prefix, count, + input, size, output, sizeof(output)); +} + +#if defined(__GLIBC__) && defined(_LIBC) +weak_alias(__crypt_rn, crypt_rn) +weak_alias(__crypt_ra, crypt_ra) +weak_alias(__crypt_r, crypt_r) +weak_alias(__crypt, crypt) +weak_alias(__crypt_gensalt_rn, crypt_gensalt_rn) +weak_alias(__crypt_gensalt_ra, crypt_gensalt_ra) +weak_alias(__crypt_gensalt, crypt_gensalt) +weak_alias(crypt, fcrypt) +#endif + +#ifdef TEST +static const char *tests[][3] = { + {"$2a$05$CCCCCCCCCCCCCCCCCCCCC.E5YPO9kmyuRGyh0XouQYb4YMJKvyOeW", + "U*U"}, + {"$2a$05$CCCCCCCCCCCCCCCCCCCCC.VGOzA784oUp/Z0DY336zx7pLYAy0lwK", + "U*U*"}, + {"$2a$05$XXXXXXXXXXXXXXXXXXXXXOAcXxm9kjPGEMsLznoKqmqw7tc8WCx4a", + "U*U*U"}, + {"$2a$05$abcdefghijklmnopqrstuu5s2v8.iXieOjg/.AySBTTZIIVFJeBui", + "0123456789abcdefghijklmnopqrstuvwxyz" + "ABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789" + "chars after 72 are ignored"}, + {"$2x$05$/OK.fbVrR/bpIqNJ5ianF.CE5elHaaO4EbggVDjb8P19RukzXSM3e", + "\xa3"}, + {"$2x$05$/OK.fbVrR/bpIqNJ5ianF.CE5elHaaO4EbggVDjb8P19RukzXSM3e", + "\xff\xff\xa3"}, + {"$2y$05$/OK.fbVrR/bpIqNJ5ianF.CE5elHaaO4EbggVDjb8P19RukzXSM3e", + "\xff\xff\xa3"}, + {"$2a$05$/OK.fbVrR/bpIqNJ5ianF.nqd1wy.pTMdcvrRWxyiGL2eMz.2a85.", + "\xff\xff\xa3"}, + {"$2b$05$/OK.fbVrR/bpIqNJ5ianF.CE5elHaaO4EbggVDjb8P19RukzXSM3e", + "\xff\xff\xa3"}, + {"$2y$05$/OK.fbVrR/bpIqNJ5ianF.Sa7shbm4.OzKpvFnX1pQLmQW96oUlCq", + "\xa3"}, + {"$2a$05$/OK.fbVrR/bpIqNJ5ianF.Sa7shbm4.OzKpvFnX1pQLmQW96oUlCq", + "\xa3"}, + {"$2b$05$/OK.fbVrR/bpIqNJ5ianF.Sa7shbm4.OzKpvFnX1pQLmQW96oUlCq", + "\xa3"}, + {"$2x$05$/OK.fbVrR/bpIqNJ5ianF.o./n25XVfn6oAPaUvHe.Csk4zRfsYPi", + "1\xa3" "345"}, + {"$2x$05$/OK.fbVrR/bpIqNJ5ianF.o./n25XVfn6oAPaUvHe.Csk4zRfsYPi", + "\xff\xa3" "345"}, + {"$2x$05$/OK.fbVrR/bpIqNJ5ianF.o./n25XVfn6oAPaUvHe.Csk4zRfsYPi", + "\xff\xa3" "34" "\xff\xff\xff\xa3" "345"}, + {"$2y$05$/OK.fbVrR/bpIqNJ5ianF.o./n25XVfn6oAPaUvHe.Csk4zRfsYPi", + "\xff\xa3" "34" "\xff\xff\xff\xa3" "345"}, + {"$2a$05$/OK.fbVrR/bpIqNJ5ianF.ZC1JEJ8Z4gPfpe1JOr/oyPXTWl9EFd.", + "\xff\xa3" "34" "\xff\xff\xff\xa3" "345"}, + {"$2y$05$/OK.fbVrR/bpIqNJ5ianF.nRht2l/HRhr6zmCp9vYUvvsqynflf9e", + "\xff\xa3" "345"}, + {"$2a$05$/OK.fbVrR/bpIqNJ5ianF.nRht2l/HRhr6zmCp9vYUvvsqynflf9e", + "\xff\xa3" "345"}, + {"$2a$05$/OK.fbVrR/bpIqNJ5ianF.6IflQkJytoRVc1yuaNtHfiuq.FRlSIS", + "\xa3" "ab"}, + {"$2x$05$/OK.fbVrR/bpIqNJ5ianF.6IflQkJytoRVc1yuaNtHfiuq.FRlSIS", + "\xa3" "ab"}, + {"$2y$05$/OK.fbVrR/bpIqNJ5ianF.6IflQkJytoRVc1yuaNtHfiuq.FRlSIS", + "\xa3" "ab"}, + {"$2x$05$6bNw2HLQYeqHYyBfLMsv/OiwqTymGIGzFsA4hOTWebfehXHNprcAS", + "\xd1\x91"}, + {"$2x$05$6bNw2HLQYeqHYyBfLMsv/O9LIGgn8OMzuDoHfof8AQimSGfcSWxnS", + "\xd0\xc1\xd2\xcf\xcc\xd8"}, + {"$2a$05$/OK.fbVrR/bpIqNJ5ianF.swQOIzjOiJ9GHEPuhEkvqrUyvWhEMx6", + "\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa" + "\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa" + "\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa" + "\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa" + "\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa" + "\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa" + "chars after 72 are ignored as usual"}, + {"$2a$05$/OK.fbVrR/bpIqNJ5ianF.R9xrDjiycxMbQE2bp.vgqlYpW5wx2yy", + "\xaa\x55\xaa\x55\xaa\x55\xaa\x55\xaa\x55\xaa\x55" + "\xaa\x55\xaa\x55\xaa\x55\xaa\x55\xaa\x55\xaa\x55" + "\xaa\x55\xaa\x55\xaa\x55\xaa\x55\xaa\x55\xaa\x55" + "\xaa\x55\xaa\x55\xaa\x55\xaa\x55\xaa\x55\xaa\x55" + "\xaa\x55\xaa\x55\xaa\x55\xaa\x55\xaa\x55\xaa\x55" + "\xaa\x55\xaa\x55\xaa\x55\xaa\x55\xaa\x55\xaa\x55"}, + {"$2a$05$/OK.fbVrR/bpIqNJ5ianF.9tQZzcJfm3uj2NvJ/n5xkhpqLrMpWCe", + "\x55\xaa\xff\x55\xaa\xff\x55\xaa\xff\x55\xaa\xff" + "\x55\xaa\xff\x55\xaa\xff\x55\xaa\xff\x55\xaa\xff" + "\x55\xaa\xff\x55\xaa\xff\x55\xaa\xff\x55\xaa\xff" + "\x55\xaa\xff\x55\xaa\xff\x55\xaa\xff\x55\xaa\xff" + "\x55\xaa\xff\x55\xaa\xff\x55\xaa\xff\x55\xaa\xff" + "\x55\xaa\xff\x55\xaa\xff\x55\xaa\xff\x55\xaa\xff"}, + {"$2a$05$CCCCCCCCCCCCCCCCCCCCC.7uG0VCzI2bS7j6ymqJi9CdcdxiRTWNy", + ""}, + {"*0", "", "$2a$03$CCCCCCCCCCCCCCCCCCCCC."}, + {"*0", "", "$2a$32$CCCCCCCCCCCCCCCCCCCCC."}, + {"*0", "", "$2c$05$CCCCCCCCCCCCCCCCCCCCC."}, + {"*0", "", "$2z$05$CCCCCCCCCCCCCCCCCCCCC."}, + {"*0", "", "$2`$05$CCCCCCCCCCCCCCCCCCCCC."}, + {"*0", "", "$2{$05$CCCCCCCCCCCCCCCCCCCCC."}, + {"*1", "", "*0"}, + {NULL} +}; + +#define which tests[0] + +static volatile sig_atomic_t running; + +static void handle_timer(int signum) +{ + (void) signum; + running = 0; +} + +static void *run(void *arg) +{ + unsigned long count = 0; + int i = 0; + void *data = NULL; + int size = 0x12345678; + + do { + const char *hash = tests[i][0]; + const char *key = tests[i][1]; + const char *setting = tests[i][2]; + + if (!tests[++i][0]) + i = 0; + + if (setting && strlen(hash) < 30) /* not for benchmark */ + continue; + + if (strcmp(crypt_ra(key, hash, &data, &size), hash)) { + printf("%d: FAILED (crypt_ra/%d/%lu)\n", + (int)((char *)arg - (char *)0), i, count); + free(data); + return NULL; + } + count++; + } while (running); + + free(data); + return count + (char *)0; +} + +int main(void) +{ + struct itimerval it; + struct tms buf; + clock_t clk_tck, start_real, start_virtual, end_real, end_virtual; + unsigned long count; + void *data; + int size; + char *setting1, *setting2; + int i; +#ifdef TEST_THREADS + pthread_t t[TEST_THREADS]; + void *t_retval; +#endif + + data = NULL; + size = 0x12345678; + + for (i = 0; tests[i][0]; i++) { + const char *hash = tests[i][0]; + const char *key = tests[i][1]; + const char *setting = tests[i][2]; + const char *p; + int ok = !setting || strlen(hash) >= 30; + int o_size; + char s_buf[30], o_buf[61]; + if (!setting) { + memcpy(s_buf, hash, sizeof(s_buf) - 1); + s_buf[sizeof(s_buf) - 1] = 0; + setting = s_buf; + } + + __set_errno(0); + p = crypt(key, setting); + if ((!ok && !errno) || strcmp(p, hash)) { + printf("FAILED (crypt/%d)\n", i); + return 1; + } + + if (ok && strcmp(crypt(key, hash), hash)) { + printf("FAILED (crypt/%d)\n", i); + return 1; + } + + for (o_size = -1; o_size <= (int)sizeof(o_buf); o_size++) { + int ok_n = ok && o_size == (int)sizeof(o_buf); + const char *x = "abc"; + strcpy(o_buf, x); + if (o_size >= 3) { + x = "*0"; + if (setting[0] == '*' && setting[1] == '0') + x = "*1"; + } + __set_errno(0); + p = crypt_rn(key, setting, o_buf, o_size); + if ((ok_n && (!p || strcmp(p, hash))) || + (!ok_n && (!errno || p || strcmp(o_buf, x)))) { + printf("FAILED (crypt_rn/%d)\n", i); + return 1; + } + } + + __set_errno(0); + p = crypt_ra(key, setting, &data, &size); + if ((ok && (!p || strcmp(p, hash))) || + (!ok && (!errno || p || strcmp((char *)data, hash)))) { + printf("FAILED (crypt_ra/%d)\n", i); + return 1; + } + } + + setting1 = crypt_gensalt(which[0], 12, data, size); + if (!setting1 || strncmp(setting1, "$2a$12$", 7)) { + puts("FAILED (crypt_gensalt)\n"); + return 1; + } + + setting2 = crypt_gensalt_ra(setting1, 12, data, size); + if (strcmp(setting1, setting2)) { + puts("FAILED (crypt_gensalt_ra/1)\n"); + return 1; + } + + (*(char *)data)++; + setting1 = crypt_gensalt_ra(setting2, 12, data, size); + if (!strcmp(setting1, setting2)) { + puts("FAILED (crypt_gensalt_ra/2)\n"); + return 1; + } + + free(setting1); + free(setting2); + free(data); + +#if defined(_SC_CLK_TCK) || !defined(CLK_TCK) + clk_tck = sysconf(_SC_CLK_TCK); +#else + clk_tck = CLK_TCK; +#endif + + running = 1; + signal(SIGALRM, handle_timer); + + memset(&it, 0, sizeof(it)); + it.it_value.tv_sec = 5; + setitimer(ITIMER_REAL, &it, NULL); + + start_real = times(&buf); + start_virtual = buf.tms_utime + buf.tms_stime; + + count = (char *)run((char *)0) - (char *)0; + + end_real = times(&buf); + end_virtual = buf.tms_utime + buf.tms_stime; + if (end_virtual == start_virtual) end_virtual++; + + printf("%.1f c/s real, %.1f c/s virtual\n", + (float)count * clk_tck / (end_real - start_real), + (float)count * clk_tck / (end_virtual - start_virtual)); + +#ifdef TEST_THREADS + running = 1; + it.it_value.tv_sec = 60; + setitimer(ITIMER_REAL, &it, NULL); + start_real = times(&buf); + + for (i = 0; i < TEST_THREADS; i++) + if (pthread_create(&t[i], NULL, run, i + (char *)0)) { + perror("pthread_create"); + return 1; + } + + for (i = 0; i < TEST_THREADS; i++) { + if (pthread_join(t[i], &t_retval)) { + perror("pthread_join"); + continue; + } + if (!t_retval) continue; + count = (char *)t_retval - (char *)0; + end_real = times(&buf); + printf("%d: %.1f c/s real\n", i, + (float)count * clk_tck / (end_real - start_real)); + } +#endif + + return 0; +} +#endif diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt index cf96cfbc2..c6ffe4a1e 100644 --- a/src/CMakeLists.txt +++ b/src/CMakeLists.txt @@ -3,6 +3,7 @@ project (server C) include_directories (${CMAKE_CURRENT_SOURCE_DIR}) include_directories (${CJSON_INCLUDE_DIR}) +include_directories (${BCRYPT_INCLUDE_DIR}) include_directories (${CLIBS_INCLUDE_DIR}) include_directories (${STORAGE_INCLUDE_DIR}) include_directories (${TOLUA_INCLUDE_DIR}) @@ -179,6 +180,7 @@ target_link_libraries(eressea ${LUA_LIBRARIES} ${STORAGE_LIBRARIES} ${CLIBS_LIBRARIES} + ${BCRYPT_LIBRARIES} ${CJSON_LIBRARIES} ${INIPARSER_LIBRARIES} ) @@ -239,6 +241,7 @@ target_link_libraries(test_eressea ${LUA_LIBRARIES} ${CLIBS_LIBRARIES} ${STORAGE_LIBRARIES} + ${BCRYPT_LIBRARIES} ${CJSON_LIBRARIES} ${INIPARSER_LIBRARIES} ) diff --git a/src/util/password.c b/src/util/password.c index ac482d1f4..eb976ac8d 100644 --- a/src/util/password.c +++ b/src/util/password.c @@ -1,18 +1,39 @@ +#ifdef _MSC_VER #include +#endif #include "password.h" +#include + #include #include #include -bool password_is_implemented(int algo) { +bool password_is_implemented(cryptalgo_t algo) { + if (algo == PASSWORD_BCRYPT) return true; return algo == PASSWORD_PLAINTEXT; } -const char * password_encode(const char * passwd, int algo) { +const char * password_encode(const char * passwd, cryptalgo_t algo) { + if (algo == PASSWORD_BCRYPT) { + char salt[BCRYPT_HASHSIZE]; + static char hash[BCRYPT_HASHSIZE]; + int ret; + bcrypt_gensalt(12, salt); + ret = bcrypt_hashpw(passwd, salt, hash); + assert(ret == 0); + return hash; + } return passwd; } int password_verify(const char * pwhash, const char * passwd) { + if (pwhash[0] == '$') { + if (pwhash[1] == '2') { + int ret = bcrypt_checkpw(passwd, pwhash); + assert(ret != -1); + return (ret == 0) ? VERIFY_OK : VERIFY_FAIL; + } + } return (strcmp(passwd, pwhash) == 0) ? VERIFY_OK : VERIFY_FAIL; } diff --git a/src/util/password.h b/src/util/password.h index ba55f6cb9..acd695954 100644 --- a/src/util/password.h +++ b/src/util/password.h @@ -1,12 +1,15 @@ #pragma once #include -#define PASSWORD_PLAINTEXT 0 +typedef enum cryptalgo_t { + PASSWORD_PLAINTEXT, + PASSWORD_BCRYPT +} cryptalgo_t; #define PASSWORD_DEFAULT PASSWORD_PLAINTEXT #define VERIFY_OK 0 #define VERIFY_FAIL 1 #define VERIFY_UNKNOWN 2 int password_verify(const char *hash, const char *passwd); -const char * password_encode(const char *passwd, int algo); -bool password_is_implemented(int algo); +const char * password_encode(const char *passwd, cryptalgo_t algo); +bool password_is_implemented(cryptalgo_t algo); From 21e54e09330da511d80db9691b7623eba93deccd Mon Sep 17 00:00:00 2001 From: Enno Rehling Date: Wed, 26 Sep 2018 18:33:38 +0200 Subject: [PATCH 029/160] move crypto implementations to util/crypto for easier inclusion --- CMakeLists.txt | 1 - crypt_blowfish/CMakeLists.txt | 24 ---------------- src/CMakeLists.txt | 6 ++-- src/util/CMakeLists.txt | 2 ++ src/util/crypto/CMakeLists.txt | 28 +++++++++++++++++++ {crypt_blowfish => src/util/crypto}/bcrypt.c | 2 +- {crypt_blowfish => src/util/crypto}/bcrypt.h | 0 .../util/crypto/crypt_blowfish}/LINKS | 0 .../util/crypto/crypt_blowfish}/PERFORMANCE | 0 .../util/crypto/crypt_blowfish}/README | 0 .../util/crypto/crypt_blowfish}/crypt.h | 0 .../crypto/crypt_blowfish}/crypt_blowfish.c | 0 .../crypto/crypt_blowfish}/crypt_blowfish.h | 0 .../crypto/crypt_blowfish}/crypt_gensalt.c | 0 .../crypto/crypt_blowfish}/crypt_gensalt.h | 0 .../util/crypto/crypt_blowfish}/ow-crypt.h | 0 .../util/crypto/crypt_blowfish}/wrapper.c | 0 .../util/crypto/crypt_blowfish}/x86.S | 0 src/util/password.c | 2 +- 19 files changed, 35 insertions(+), 30 deletions(-) delete mode 100644 crypt_blowfish/CMakeLists.txt create mode 100644 src/util/crypto/CMakeLists.txt rename {crypt_blowfish => src/util/crypto}/bcrypt.c (99%) rename {crypt_blowfish => src/util/crypto}/bcrypt.h (100%) rename {crypt_blowfish => src/util/crypto/crypt_blowfish}/LINKS (100%) rename {crypt_blowfish => src/util/crypto/crypt_blowfish}/PERFORMANCE (100%) rename {crypt_blowfish => src/util/crypto/crypt_blowfish}/README (100%) rename {crypt_blowfish => src/util/crypto/crypt_blowfish}/crypt.h (100%) rename {crypt_blowfish => src/util/crypto/crypt_blowfish}/crypt_blowfish.c (100%) rename {crypt_blowfish => src/util/crypto/crypt_blowfish}/crypt_blowfish.h (100%) rename {crypt_blowfish => src/util/crypto/crypt_blowfish}/crypt_gensalt.c (100%) rename {crypt_blowfish => src/util/crypto/crypt_blowfish}/crypt_gensalt.h (100%) rename {crypt_blowfish => src/util/crypto/crypt_blowfish}/ow-crypt.h (100%) rename {crypt_blowfish => src/util/crypto/crypt_blowfish}/wrapper.c (100%) rename {crypt_blowfish => src/util/crypto/crypt_blowfish}/x86.S (100%) diff --git a/CMakeLists.txt b/CMakeLists.txt index 71d44ea9f..4b91565da 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -62,7 +62,6 @@ endif(TOLUA_FOUND) enable_testing() -add_subdirectory (crypt_blowfish) add_subdirectory (cJSON) add_subdirectory (storage) add_subdirectory (iniparser) diff --git a/crypt_blowfish/CMakeLists.txt b/crypt_blowfish/CMakeLists.txt deleted file mode 100644 index 21cc29dea..000000000 --- a/crypt_blowfish/CMakeLists.txt +++ /dev/null @@ -1,24 +0,0 @@ -cmake_minimum_required(VERSION 2.6) -project (bcrypt C) - -IF (MSVC) - include (MSVC) - MSVC_SET_WARNING_LEVEL(3) -ENDIF (MSVC) - -SET (LIB_SRC bcrypt.c wrapper.c crypt_blowfish.c crypt_gensalt.c) -ADD_LIBRARY (bcrypt ${LIB_SRC}) - -set (BCRYPT_INCLUDE_DIR ${CMAKE_CURRENT_SOURCE_DIR} CACHE INTERNAL "cJSON headers") -set (BCRYPT_LIBRARIES bcrypt CACHE INTERNAL "bcrypt libraries") - -IF(UNIX AND NOT APPLE) - FIND_LIBRARY(UNIX_MATH_LIBRARY m) - SET(BCRYPT_LIBRARIES ${BCRYPT_LIBRARIES} ${UNIX_MATH_LIBRARY} CACHE - INTERNAL "bcrypt libraries") -ENDIF() - -IF (MSVC) - MSVC_CRT_SECURE_NO_WARNINGS (bcrypt) -ENDIF (MSVC) - diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt index c6ffe4a1e..506f35473 100644 --- a/src/CMakeLists.txt +++ b/src/CMakeLists.txt @@ -3,7 +3,7 @@ project (server C) include_directories (${CMAKE_CURRENT_SOURCE_DIR}) include_directories (${CJSON_INCLUDE_DIR}) -include_directories (${BCRYPT_INCLUDE_DIR}) +include_directories (${CRYPTO_INCLUDE_DIR}) include_directories (${CLIBS_INCLUDE_DIR}) include_directories (${STORAGE_INCLUDE_DIR}) include_directories (${TOLUA_INCLUDE_DIR}) @@ -180,7 +180,7 @@ target_link_libraries(eressea ${LUA_LIBRARIES} ${STORAGE_LIBRARIES} ${CLIBS_LIBRARIES} - ${BCRYPT_LIBRARIES} + ${CRYPTO_LIBRARIES} ${CJSON_LIBRARIES} ${INIPARSER_LIBRARIES} ) @@ -241,7 +241,7 @@ target_link_libraries(test_eressea ${LUA_LIBRARIES} ${CLIBS_LIBRARIES} ${STORAGE_LIBRARIES} - ${BCRYPT_LIBRARIES} + ${CRYPTO_LIBRARIES} ${CJSON_LIBRARIES} ${INIPARSER_LIBRARIES} ) diff --git a/src/util/CMakeLists.txt b/src/util/CMakeLists.txt index b462d2bd3..90059666a 100644 --- a/src/util/CMakeLists.txt +++ b/src/util/CMakeLists.txt @@ -1,5 +1,7 @@ project(util C) +add_subdirectory (crypto) + SET(_TEST_FILES attrib.test.c base36.test.c diff --git a/src/util/crypto/CMakeLists.txt b/src/util/crypto/CMakeLists.txt new file mode 100644 index 000000000..925c73380 --- /dev/null +++ b/src/util/crypto/CMakeLists.txt @@ -0,0 +1,28 @@ +cmake_minimum_required(VERSION 2.6) +project (crypto C) + +IF (MSVC) + include (MSVC) + MSVC_SET_WARNING_LEVEL(3) +ENDIF (MSVC) + +SET (LIB_SRC + bcrypt.c + crypt_blowfish/wrapper.c + crypt_blowfish/crypt_blowfish.c + crypt_blowfish/crypt_gensalt.c +) +ADD_LIBRARY (crypto ${LIB_SRC}) + +set (CRYPTO_INCLUDE_DIR ${CMAKE_CURRENT_SOURCE_DIR} CACHE INTERNAL "cJSON headers") +set (CRYPTO_LIBRARIES crypto CACHE INTERNAL "crypto libraries") + +IF(WIN32) + FIND_LIBRARY(WIN32_CNG_LIBRARY bcrypt) + SET(CRYPTO_LIBRARIES ${CRYPTO_LIBRARIES} ${WIN32_CNG_LIBRARY} CACHE + INTERNAL "crypto libraries") +ENDIF() + +IF (MSVC) + MSVC_CRT_SECURE_NO_WARNINGS (crypto) +ENDIF (MSVC) diff --git a/crypt_blowfish/bcrypt.c b/src/util/crypto/bcrypt.c similarity index 99% rename from crypt_blowfish/bcrypt.c rename to src/util/crypto/bcrypt.c index a4c992258..bd8722beb 100644 --- a/crypt_blowfish/bcrypt.c +++ b/src/util/crypto/bcrypt.c @@ -19,7 +19,7 @@ #include #include "bcrypt.h" -#include "ow-crypt.h" +#include "crypt_blowfish/ow-crypt.h" #define RANDBYTES (16) diff --git a/crypt_blowfish/bcrypt.h b/src/util/crypto/bcrypt.h similarity index 100% rename from crypt_blowfish/bcrypt.h rename to src/util/crypto/bcrypt.h diff --git a/crypt_blowfish/LINKS b/src/util/crypto/crypt_blowfish/LINKS similarity index 100% rename from crypt_blowfish/LINKS rename to src/util/crypto/crypt_blowfish/LINKS diff --git a/crypt_blowfish/PERFORMANCE b/src/util/crypto/crypt_blowfish/PERFORMANCE similarity index 100% rename from crypt_blowfish/PERFORMANCE rename to src/util/crypto/crypt_blowfish/PERFORMANCE diff --git a/crypt_blowfish/README b/src/util/crypto/crypt_blowfish/README similarity index 100% rename from crypt_blowfish/README rename to src/util/crypto/crypt_blowfish/README diff --git a/crypt_blowfish/crypt.h b/src/util/crypto/crypt_blowfish/crypt.h similarity index 100% rename from crypt_blowfish/crypt.h rename to src/util/crypto/crypt_blowfish/crypt.h diff --git a/crypt_blowfish/crypt_blowfish.c b/src/util/crypto/crypt_blowfish/crypt_blowfish.c similarity index 100% rename from crypt_blowfish/crypt_blowfish.c rename to src/util/crypto/crypt_blowfish/crypt_blowfish.c diff --git a/crypt_blowfish/crypt_blowfish.h b/src/util/crypto/crypt_blowfish/crypt_blowfish.h similarity index 100% rename from crypt_blowfish/crypt_blowfish.h rename to src/util/crypto/crypt_blowfish/crypt_blowfish.h diff --git a/crypt_blowfish/crypt_gensalt.c b/src/util/crypto/crypt_blowfish/crypt_gensalt.c similarity index 100% rename from crypt_blowfish/crypt_gensalt.c rename to src/util/crypto/crypt_blowfish/crypt_gensalt.c diff --git a/crypt_blowfish/crypt_gensalt.h b/src/util/crypto/crypt_blowfish/crypt_gensalt.h similarity index 100% rename from crypt_blowfish/crypt_gensalt.h rename to src/util/crypto/crypt_blowfish/crypt_gensalt.h diff --git a/crypt_blowfish/ow-crypt.h b/src/util/crypto/crypt_blowfish/ow-crypt.h similarity index 100% rename from crypt_blowfish/ow-crypt.h rename to src/util/crypto/crypt_blowfish/ow-crypt.h diff --git a/crypt_blowfish/wrapper.c b/src/util/crypto/crypt_blowfish/wrapper.c similarity index 100% rename from crypt_blowfish/wrapper.c rename to src/util/crypto/crypt_blowfish/wrapper.c diff --git a/crypt_blowfish/x86.S b/src/util/crypto/crypt_blowfish/x86.S similarity index 100% rename from crypt_blowfish/x86.S rename to src/util/crypto/crypt_blowfish/x86.S diff --git a/src/util/password.c b/src/util/password.c index eb976ac8d..73e02c551 100644 --- a/src/util/password.c +++ b/src/util/password.c @@ -3,7 +3,7 @@ #endif #include "password.h" -#include +#include "crypto/bcrypt.h" #include #include From 3c50a4260b5919d65ed50149cc7bc3327aa4cab0 Mon Sep 17 00:00:00 2001 From: Enno Rehling Date: Wed, 26 Sep 2018 18:43:30 +0200 Subject: [PATCH 030/160] add some WIN32 workarounds, tests --- src/util/crypto/bcrypt.c | 20 ++++++++++++++----- .../crypto/crypt_blowfish/crypt_blowfish.c | 2 +- src/util/password.test.c | 20 ++++++++++++------- 3 files changed, 29 insertions(+), 13 deletions(-) diff --git a/src/util/crypto/bcrypt.c b/src/util/crypto/bcrypt.c index bd8722beb..c8cc14e23 100644 --- a/src/util/crypto/bcrypt.c +++ b/src/util/crypto/bcrypt.c @@ -15,14 +15,21 @@ #include #include #include -#include #include +#ifdef WIN32 +#include +#include +#else +#include +#endif + #include "bcrypt.h" #include "crypt_blowfish/ow-crypt.h" #define RANDBYTES (16) +#ifndef WIN32 static int try_close(int fd) { int ret; @@ -60,7 +67,7 @@ static int try_read(int fd, char *out, size_t count) return 0; } - +#endif /* * This is a best effort implementation. Nothing prevents a compiler from * optimizing this function and making it vulnerable to timing attacks, but @@ -96,12 +103,15 @@ static int timing_safe_strcmp(const char *str1, const char *str2) int bcrypt_gensalt(int factor, char salt[BCRYPT_HASHSIZE]) { - int fd; char input[RANDBYTES]; int workf; char *aux; - fd = open("/dev/urandom", O_RDONLY); +#ifdef WIN32 + BCryptGenRandom(NULL, input, RANDBYTES, BCRYPT_USE_SYSTEM_PREFERRED_RNG); +#else + int fd; + fd = open("/dev/urandom", O_RDONLY); if (fd == -1) return 1; @@ -113,7 +123,7 @@ int bcrypt_gensalt(int factor, char salt[BCRYPT_HASHSIZE]) if (try_close(fd) != 0) return 3; - +#endif /* Generate salt. */ workf = (factor < 4 || factor > 31)?12:factor; aux = crypt_gensalt_rn("$2a$", workf, input, RANDBYTES, diff --git a/src/util/crypto/crypt_blowfish/crypt_blowfish.c b/src/util/crypto/crypt_blowfish/crypt_blowfish.c index 9d3f3be82..b0b11d3ad 100644 --- a/src/util/crypto/crypt_blowfish/crypt_blowfish.c +++ b/src/util/crypto/crypt_blowfish/crypt_blowfish.c @@ -896,7 +896,7 @@ char *_crypt_gensalt_blowfish_rn(const char *prefix, unsigned long count, output[1] = '2'; output[2] = prefix[2]; output[3] = '$'; - output[4] = '0' + count / 10; + output[4] = '0' + (char)count / 10; output[5] = '0' + count % 10; output[6] = '$'; diff --git a/src/util/password.test.c b/src/util/password.test.c index 8efe5b107..34a252531 100644 --- a/src/util/password.test.c +++ b/src/util/password.test.c @@ -4,17 +4,23 @@ #include static void test_passwords(CuTest *tc) { - const char *hash, *expect; + const char *hash; - expect = "password"; + if (password_is_implemented(PASSWORD_BCRYPT)) { + hash = password_encode("password", PASSWORD_BCRYPT); + CuAssertPtrNotNull(tc, hash); + CuAssertIntEquals(tc, '$', hash[0]); + CuAssertIntEquals(tc, '2', hash[1]); + CuAssertIntEquals(tc, '$', hash[3]); + CuAssertIntEquals(tc, VERIFY_OK, password_verify(hash, "password")); + CuAssertIntEquals(tc, VERIFY_FAIL, password_verify(hash, "arseword")); + } if (password_is_implemented(PASSWORD_PLAINTEXT)) { hash = password_encode("password", PASSWORD_PLAINTEXT); CuAssertPtrNotNull(tc, hash); - CuAssertStrEquals(tc, hash, expect); - CuAssertIntEquals(tc, VERIFY_OK, password_verify(expect, "password")); - CuAssertIntEquals(tc, VERIFY_FAIL, password_verify(expect, "arseword")); - } else { - CuAssertIntEquals(tc, VERIFY_UNKNOWN, password_verify(expect, "password")); + CuAssertStrEquals(tc, hash, "password"); + CuAssertIntEquals(tc, VERIFY_OK, password_verify(hash, "password")); + CuAssertIntEquals(tc, VERIFY_FAIL, password_verify(hash, "arseword")); } } From 2e9bde0261ca2e1374db27c5d63c0485fc21eec6 Mon Sep 17 00:00:00 2001 From: Enno Rehling Date: Wed, 26 Sep 2018 19:05:49 +0200 Subject: [PATCH 031/160] More WIN32 adaptations, configurable work factor. --- src/CMakeLists.txt | 2 +- src/platform.h | 1 + src/util/crypto/CMakeLists.txt | 5 ++--- src/util/crypto/crypt_blowfish/wrapper.c | 10 ++++++---- src/util/crypto/{bcrypt.c => crypto.c} | 2 +- src/util/crypto/{bcrypt.h => crypto.h} | 0 src/util/password.c | 6 ++++-- src/util/password.h | 2 ++ src/util/password.test.c | 4 ++++ 9 files changed, 21 insertions(+), 11 deletions(-) rename src/util/crypto/{bcrypt.c => crypto.c} (99%) rename src/util/crypto/{bcrypt.h => crypto.h} (100%) diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt index 506f35473..9a7e4a8ab 100644 --- a/src/CMakeLists.txt +++ b/src/CMakeLists.txt @@ -28,7 +28,7 @@ IF (CMAKE_COMPILER_IS_GNUCC OR CMAKE_C_COMPILER_ID MATCHES "Clang") SET(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -Wsign-compare -Wall -Werror -Wno-unknown-pragmas -Wstrict-prototypes -Wpointer-arith -Wno-char-subscripts -Wno-long-long") # SET(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -std=c89") ELSEIF(MSVC) - SET(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} /W4 /WX /MP /Za /D_CRT_SECURE_NO_WARNINGS /D_USE_MATH_DEFINES") + SET(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} /W4 /WX /MP /D_CRT_SECURE_NO_WARNINGS /D_USE_MATH_DEFINES") set(CMAKE_EXE_LINKER_FLAGS_DEBUG "${CMAKE_EXE_LINKER_FLAGS_DEBUG} /NODEFAULTLIB:libc.lib /NODEFAULTLIB:libcmt.lib /NODEFAULTLIB:libcd.lib /NODEFAULTLIB:libcmtd.lib /NODEFAULTLIB:msvcrt.lib") set(CMAKE_EXE_LINKER_FLAGS_RELEASE diff --git a/src/platform.h b/src/platform.h index fb1ace65a..fdc3760f9 100644 --- a/src/platform.h +++ b/src/platform.h @@ -14,6 +14,7 @@ #pragma warning(disable: 4457) // declaration hides function parameter #pragma warning(disable: 4459) // declaration hides global #pragma warning(disable: 4224) // formal parameter was previously defined as a type +#pragma warning(disable: 4214) // bit field types other than int #endif /* @see https://insanecoding.blogspot.no/2007/11/pathmax-simply-isnt.html */ diff --git a/src/util/crypto/CMakeLists.txt b/src/util/crypto/CMakeLists.txt index 925c73380..195eb02b4 100644 --- a/src/util/crypto/CMakeLists.txt +++ b/src/util/crypto/CMakeLists.txt @@ -7,7 +7,7 @@ IF (MSVC) ENDIF (MSVC) SET (LIB_SRC - bcrypt.c + crypto.c crypt_blowfish/wrapper.c crypt_blowfish/crypt_blowfish.c crypt_blowfish/crypt_gensalt.c @@ -18,8 +18,7 @@ set (CRYPTO_INCLUDE_DIR ${CMAKE_CURRENT_SOURCE_DIR} CACHE INTERNAL "cJSON header set (CRYPTO_LIBRARIES crypto CACHE INTERNAL "crypto libraries") IF(WIN32) - FIND_LIBRARY(WIN32_CNG_LIBRARY bcrypt) - SET(CRYPTO_LIBRARIES ${CRYPTO_LIBRARIES} ${WIN32_CNG_LIBRARY} CACHE + SET(CRYPTO_LIBRARIES ${CRYPTO_LIBRARIES} bcrypt CACHE INTERNAL "crypto libraries") ENDIF() diff --git a/src/util/crypto/crypt_blowfish/wrapper.c b/src/util/crypto/crypt_blowfish/wrapper.c index 1e49c90d8..b69ba7ae6 100644 --- a/src/util/crypto/crypt_blowfish/wrapper.c +++ b/src/util/crypto/crypt_blowfish/wrapper.c @@ -243,13 +243,15 @@ char *__crypt_gensalt_ra(const char *prefix, unsigned long count, input, size, output, sizeof(output)); if (retval) { - retval = strdup(retval); + size_t len = 1 + strlen(retval); + char * dst = malloc(len); #ifndef __GLIBC__ - /* strdup(3) on glibc sets errno, so we don't need to bother */ - if (!retval) + /* malloc(3) on glibc sets errno, so we don't need to bother */ + if (!dst) __set_errno(ENOMEM); #endif - } + retval = memcpy(dst, retval, len); + } return retval; } diff --git a/src/util/crypto/bcrypt.c b/src/util/crypto/crypto.c similarity index 99% rename from src/util/crypto/bcrypt.c rename to src/util/crypto/crypto.c index c8cc14e23..75129a826 100644 --- a/src/util/crypto/bcrypt.c +++ b/src/util/crypto/crypto.c @@ -24,7 +24,7 @@ #include #endif -#include "bcrypt.h" +#include "crypto.h" #include "crypt_blowfish/ow-crypt.h" #define RANDBYTES (16) diff --git a/src/util/crypto/bcrypt.h b/src/util/crypto/crypto.h similarity index 100% rename from src/util/crypto/bcrypt.h rename to src/util/crypto/crypto.h diff --git a/src/util/password.c b/src/util/password.c index 73e02c551..a7e14c98b 100644 --- a/src/util/password.c +++ b/src/util/password.c @@ -3,12 +3,14 @@ #endif #include "password.h" -#include "crypto/bcrypt.h" +#include "crypto/crypto.h" #include #include #include +int bcrypt_workfactor = 8; + bool password_is_implemented(cryptalgo_t algo) { if (algo == PASSWORD_BCRYPT) return true; return algo == PASSWORD_PLAINTEXT; @@ -19,7 +21,7 @@ const char * password_encode(const char * passwd, cryptalgo_t algo) { char salt[BCRYPT_HASHSIZE]; static char hash[BCRYPT_HASHSIZE]; int ret; - bcrypt_gensalt(12, salt); + bcrypt_gensalt(bcrypt_workfactor, salt); ret = bcrypt_hashpw(passwd, salt, hash); assert(ret == 0); return hash; diff --git a/src/util/password.h b/src/util/password.h index acd695954..7deb46430 100644 --- a/src/util/password.h +++ b/src/util/password.h @@ -7,6 +7,8 @@ typedef enum cryptalgo_t { } cryptalgo_t; #define PASSWORD_DEFAULT PASSWORD_PLAINTEXT +extern int bcrypt_workfactor; + #define VERIFY_OK 0 #define VERIFY_FAIL 1 #define VERIFY_UNKNOWN 2 diff --git a/src/util/password.test.c b/src/util/password.test.c index 34a252531..9740b4080 100644 --- a/src/util/password.test.c +++ b/src/util/password.test.c @@ -7,11 +7,15 @@ static void test_passwords(CuTest *tc) { const char *hash; if (password_is_implemented(PASSWORD_BCRYPT)) { + bcrypt_workfactor = 4; hash = password_encode("password", PASSWORD_BCRYPT); CuAssertPtrNotNull(tc, hash); CuAssertIntEquals(tc, '$', hash[0]); CuAssertIntEquals(tc, '2', hash[1]); CuAssertIntEquals(tc, '$', hash[3]); + CuAssertIntEquals(tc, '0', hash[4]); + CuAssertIntEquals(tc, '4', hash[5]); + CuAssertIntEquals(tc, '$', hash[6]); CuAssertIntEquals(tc, VERIFY_OK, password_verify(hash, "password")); CuAssertIntEquals(tc, VERIFY_FAIL, password_verify(hash, "arseword")); } From ae05d6d9e92904214806ef3c9cdca6afb78042c7 Mon Sep 17 00:00:00 2001 From: Enno Rehling Date: Wed, 26 Sep 2018 20:08:38 +0200 Subject: [PATCH 032/160] work factor 12 is incredibly slow, don't use it in tests. --- src/economy.test.c | 1 + src/kernel/save.test.c | 5 ++--- src/test_eressea.c | 2 ++ src/util/gamedata.h | 5 ++--- src/util/password.h | 2 +- src/util/password.test.c | 2 ++ 6 files changed, 10 insertions(+), 7 deletions(-) diff --git a/src/economy.test.c b/src/economy.test.c index 90a4bd260..1a40c03db 100644 --- a/src/economy.test.c +++ b/src/economy.test.c @@ -487,6 +487,7 @@ static void test_recruit_insect(CuTest *tc) { test_setup(); test_create_calendar(); + test_create_terrain("desert", -1); f = test_create_faction(test_create_race("insect")); u = test_create_unit(f, test_create_region(0, 0, NULL)); u->thisorder = create_order(K_RECRUIT, f->locale, "%d", 1); diff --git a/src/kernel/save.test.c b/src/kernel/save.test.c index 4e6e0e2d4..036ad00c5 100644 --- a/src/kernel/save.test.c +++ b/src/kernel/save.test.c @@ -441,16 +441,15 @@ static void test_read_password_external(CuTest *tc) { data.strm.api->rewind(data.strm.handle); data.version = NOCRYPT_VERSION; _test_read_password(&data, f); - CuAssertStrEquals(tc, "newpassword", f->_password); + CuAssertTrue(tc, checkpasswd(f, "newpassword")); data.version = BADCRYPT_VERSION; _test_read_password(&data, f); - CuAssertStrEquals(tc, "secret", f->_password); + CuAssertTrue(tc, checkpasswd(f, "secret")); F = fopen(pwfile, "wt"); fprintf(F, "%s:pwfile\n", itoa36(f->no)); fclose(F); CuAssertTrue(tc, checkpasswd(f, "secret")); _test_read_password(&data, f); - CuAssertStrEquals(tc, "pwfile", f->_password); CuAssertTrue(tc, checkpasswd(f, "pwfile")); mstream_done(&data.strm); gamedata_done(&data); diff --git a/src/test_eressea.c b/src/test_eressea.c index 5684a8ad4..d91c225ae 100644 --- a/src/test_eressea.c +++ b/src/test_eressea.c @@ -7,6 +7,7 @@ #include #include #include +#include #include #include @@ -159,6 +160,7 @@ int RunAllTests(int argc, char *argv[]) CuSuite *summary = CuSuiteNew(); int fail_count; game_init(); + bcrypt_workfactor = 4; while (suites) { suite *s = suites->next; RunTests(suites->csuite, suites->name); diff --git a/src/util/gamedata.h b/src/util/gamedata.h index 22c1d9052..769d44b90 100644 --- a/src/util/gamedata.h +++ b/src/util/gamedata.h @@ -36,10 +36,9 @@ #define FAMILIAR_FIX_VERSION 359 /* familiar links are fixed */ #define SKILLSORT_VERSION 360 /* u->skills is sorted */ #define LANDDISPLAY_VERSION 360 /* r.display is now in r.land.display */ -/* unfinished: */ -#define CRYPT_VERSION 400 /* passwords are encrypted */ +#define CRYPT_VERSION 361 /* passwords are encrypted */ -#define RELEASE_VERSION LANDDISPLAY_VERSION /* current datafile */ +#define RELEASE_VERSION CRYPT_VERSION /* current datafile */ #define MIN_VERSION UIDHASH_VERSION /* minimal datafile we support */ #define MAX_VERSION RELEASE_VERSION /* change this if we can need to read the future datafile, and we can do so */ diff --git a/src/util/password.h b/src/util/password.h index 7deb46430..61abc588f 100644 --- a/src/util/password.h +++ b/src/util/password.h @@ -5,7 +5,7 @@ typedef enum cryptalgo_t { PASSWORD_PLAINTEXT, PASSWORD_BCRYPT } cryptalgo_t; -#define PASSWORD_DEFAULT PASSWORD_PLAINTEXT +#define PASSWORD_DEFAULT PASSWORD_BCRYPT extern int bcrypt_workfactor; diff --git a/src/util/password.test.c b/src/util/password.test.c index 9740b4080..f22ef5971 100644 --- a/src/util/password.test.c +++ b/src/util/password.test.c @@ -7,6 +7,7 @@ static void test_passwords(CuTest *tc) { const char *hash; if (password_is_implemented(PASSWORD_BCRYPT)) { + int wf = bcrypt_workfactor; bcrypt_workfactor = 4; hash = password_encode("password", PASSWORD_BCRYPT); CuAssertPtrNotNull(tc, hash); @@ -18,6 +19,7 @@ static void test_passwords(CuTest *tc) { CuAssertIntEquals(tc, '$', hash[6]); CuAssertIntEquals(tc, VERIFY_OK, password_verify(hash, "password")); CuAssertIntEquals(tc, VERIFY_FAIL, password_verify(hash, "arseword")); + bcrypt_workfactor = wf; } if (password_is_implemented(PASSWORD_PLAINTEXT)) { hash = password_encode("password", PASSWORD_PLAINTEXT); From f513c2c68a3da9505a9cc6ddc1ead2b6313c3269 Mon Sep 17 00:00:00 2001 From: Enno Rehling Date: Wed, 26 Sep 2018 20:19:59 +0200 Subject: [PATCH 033/160] skip excessive password generation in tests. --- src/gmtool.c | 3 ++- src/kernel/faction.c | 8 +++++--- src/kernel/faction.test.c | 2 +- src/modules/autoseed.c | 4 +++- 4 files changed, 11 insertions(+), 6 deletions(-) diff --git a/src/gmtool.c b/src/gmtool.c index fdbfd3faa..e75f22612 100644 --- a/src/gmtool.c +++ b/src/gmtool.c @@ -934,7 +934,8 @@ static void seed_player(state *st, const newfaction *player) { if (r) { const char *at = strchr(player->email, '@'); faction *f; - addplayer(r, f = addfaction(player->email, player->password, + const char *password = player->password ? player->password : itoa36(rng_int()); + addplayer(r, f = addfaction(player->email, password, player->race, player->lang, player->subscription)); if (at) { diff --git a/src/kernel/faction.c b/src/kernel/faction.c index b4dfe51ca..5e6c98602 100755 --- a/src/kernel/faction.c +++ b/src/kernel/faction.c @@ -245,6 +245,7 @@ faction *addfaction(const char *email, const char *password, f->alliance_joindate = turn; f->lastorders = turn; f->_alive = true; + f->_password = NULL; f->age = 0; f->race = frace; f->magiegebiet = 0; @@ -252,9 +253,10 @@ faction *addfaction(const char *email, const char *password, f->subscription = subscription; f->flags = FFL_ISNEW|FFL_PWMSG; - if (!password) password = itoa36(rng_int()); - faction_setpassword(f, password_encode(password, PASSWORD_DEFAULT)); - ADDMSG(&f->msgs, msg_message("changepasswd", "value", password)); + if (password) { + faction_setpassword(f, password_encode(password, PASSWORD_DEFAULT)); + ADDMSG(&f->msgs, msg_message("changepasswd", "value", password)); + } f->options = WANT_OPTION(O_REPORT) | WANT_OPTION(O_ZUGVORLAGE) | diff --git a/src/kernel/faction.test.c b/src/kernel/faction.test.c index 37ec70e50..75c455e7d 100644 --- a/src/kernel/faction.test.c +++ b/src/kernel/faction.test.c @@ -112,7 +112,7 @@ static void test_addfaction(CuTest *tc) { test_setup(); rc = rc_get_or_create("human"); lang = test_create_locale(); - f = addfaction("test@eressea.de", "hurrdurr", rc, lang, 1234); + f = addfaction("test@eressea.de", NULL, rc, lang, 1234); CuAssertPtrNotNull(tc, f); CuAssertPtrNotNull(tc, f->name); CuAssertPtrEquals(tc, NULL, (void *)f->units); diff --git a/src/modules/autoseed.c b/src/modules/autoseed.c index 374b6379c..439bf35d1 100644 --- a/src/modules/autoseed.c +++ b/src/modules/autoseed.c @@ -550,13 +550,15 @@ int autoseed(newfaction ** players, int nsize, int max_agediff) newfaction **nfp, *nextf = *players; faction *f; unit *u; + const char * password; isize += REGIONS_PER_FACTION; terraform_region(r, preferred_terrain(nextf->race)); prepare_starting_region(r); ++tsize; assert(r->land && r->units == 0); - u = addplayer(r, addfaction(nextf->email, nextf->password, nextf->race, + password = nextf->password ? nextf->password : itoa36(rng_int()); + u = addplayer(r, addfaction(nextf->email, password, nextf->race, nextf->lang, nextf->subscription)); f = u->faction; fset(f, FFL_ISNEW); From e234a0db6f4c0747dc7b2ff633ae0316a0cb926e Mon Sep 17 00:00:00 2001 From: Enno Rehling Date: Wed, 26 Sep 2018 20:21:56 +0200 Subject: [PATCH 034/160] write the htpasswd file, again --- scripts/run-turn.lua | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/scripts/run-turn.lua b/scripts/run-turn.lua index 35303b038..0540d2321 100644 --- a/scripts/run-turn.lua +++ b/scripts/run-turn.lua @@ -97,7 +97,7 @@ end local function write_files(locales) write_database() write_passwords() - -- write_htpasswd() + write_htpasswd() write_reports() write_summary() end From e462529596f8065119cbd038a952087c45bebf3a Mon Sep 17 00:00:00 2001 From: Enno Rehling Date: Wed, 26 Sep 2018 20:36:27 +0200 Subject: [PATCH 035/160] fix merge conflict choose sqlite as default database --- s/cmake-init | 5 +---- src/modules/autoseed.c | 11 +++++------ src/modules/autoseed.h | 1 - 3 files changed, 6 insertions(+), 11 deletions(-) diff --git a/s/cmake-init b/s/cmake-init index 337490f07..781db1ea7 100755 --- a/s/cmake-init +++ b/s/cmake-init @@ -1,10 +1,7 @@ #!/bin/sh ERESSEA_DB=db -if [ -e /usr/include/sqlite3.h ] ; then -ERESSEA_DB=sqlite -fi - +pkg-config --exists sqlite3 && ERESSEA_DB=sqlite # Parse command line arguments while [ ! -z "$1" ] ; do if [ "$1" = "--with-db" ] ; then diff --git a/src/modules/autoseed.c b/src/modules/autoseed.c index 2380e9bdd..88240d0b3 100644 --- a/src/modules/autoseed.c +++ b/src/modules/autoseed.c @@ -95,7 +95,7 @@ newfaction *read_newfactions(const char *filename) faction *f; char race[20], email[64], lang[8], password[16]; newfaction *nf, **nfi; - int alliance = 0, uid = 0; + int alliance = 0; if (fgets(buf, sizeof(buf), F) == NULL) break; @@ -103,8 +103,8 @@ newfaction *read_newfactions(const char *filename) email[0] = '\0'; password[0] = '\0'; - if (sscanf(buf, "%54s %19s %7s %15s %4d %4d", email, race, lang, - password, &uid, &alliance) < 3) { + if (sscanf(buf, "%54s %19s %7s %15s %4d", email, race, lang, + password, &alliance) < 3) { break; } if (email[0] == '#') { @@ -137,13 +137,12 @@ newfaction *read_newfactions(const char *filename) if (check_email(email) == 0) { nf->email = str_strdup(email); } else { - log_error("Invalid email address for subscription %s: %s\n", itoa36(uid), email); + log_error("Invalid email address for new faction: %s\n", email); free(nf); continue; } nf->password = str_strdup(password); nf->race = rc_find(race); - nf->uid = uid; if (alliances != NULL) { struct alliance *al = findalliance(alliance); if (al == NULL) { @@ -559,7 +558,7 @@ int autoseed(newfaction ** players, int nsize, int max_agediff) assert(r->land && r->units == 0); password = nextf->password ? nextf->password : itoa36(rng_int()); u = addplayer(r, addfaction(nextf->email, password, nextf->race, - nextf->lang, nextf)); + nextf->lang)); f = u->faction; fset(f, FFL_ISNEW); f->alliance = nextf->allies; diff --git a/src/modules/autoseed.h b/src/modules/autoseed.h index 74c7409ad..b78a2df55 100644 --- a/src/modules/autoseed.h +++ b/src/modules/autoseed.h @@ -24,7 +24,6 @@ extern "C" { char *password; const struct locale *lang; const struct race *race; - int uid; bool oldregions; struct alliance *allies; } newfaction; From 04b8068979527a501496b46ba65f208571de499f Mon Sep 17 00:00:00 2001 From: Enno Rehling Date: Wed, 26 Sep 2018 21:06:56 +0200 Subject: [PATCH 036/160] rename password functions to match PHP. --- src/bind_faction.c | 2 +- src/kernel/faction.c | 2 +- src/kernel/faction.test.c | 2 +- src/kernel/save.c | 4 ++-- src/kernel/save.test.c | 4 ++-- src/laws.c | 2 +- src/util/password.c | 2 +- src/util/password.h | 2 +- src/util/password.test.c | 4 ++-- 9 files changed, 12 insertions(+), 12 deletions(-) diff --git a/src/bind_faction.c b/src/bind_faction.c index 850679933..632fcec3d 100644 --- a/src/bind_faction.c +++ b/src/bind_faction.c @@ -452,7 +452,7 @@ 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_setpassword(self, password_hash(passw, PASSWORD_DEFAULT)); return 0; } diff --git a/src/kernel/faction.c b/src/kernel/faction.c index 7284db52d..6e85988f4 100755 --- a/src/kernel/faction.c +++ b/src/kernel/faction.c @@ -254,7 +254,7 @@ faction *addfaction(const char *email, const char *password, f->flags = FFL_ISNEW|FFL_PWMSG; if (password) { - faction_setpassword(f, password_encode(password, PASSWORD_DEFAULT)); + faction_setpassword(f, password_hash(password, PASSWORD_DEFAULT)); ADDMSG(&f->msgs, msg_message("changepasswd", "value", password)); } diff --git a/src/kernel/faction.test.c b/src/kernel/faction.test.c index 04a2b1e97..9cd5d9de8 100644 --- a/src/kernel/faction.test.c +++ b/src/kernel/faction.test.c @@ -137,7 +137,7 @@ static void test_check_passwd(CuTest *tc) { faction *f; f = test_create_faction(NULL); - faction_setpassword(f, password_encode("password", PASSWORD_DEFAULT)); + faction_setpassword(f, password_hash("password", PASSWORD_DEFAULT)); CuAssertTrue(tc, checkpasswd(f, "password")); CuAssertTrue(tc, !checkpasswd(f, "assword")); CuAssertTrue(tc, !checkpasswd(f, "PASSWORD")); diff --git a/src/kernel/save.c b/src/kernel/save.c index 922fcc24f..e7cb90d2a 100644 --- a/src/kernel/save.c +++ b/src/kernel/save.c @@ -924,7 +924,7 @@ static void read_password(gamedata *data, faction *f) { if (name[0] == '$' && data->version == BADCRYPT_VERSION) { char * pass = getpasswd(f->no); if (pass) { - faction_setpassword(f, password_encode(pass, PASSWORD_DEFAULT)); + faction_setpassword(f, password_hash(pass, PASSWORD_DEFAULT)); free(pass); /* TODO: remove this allocation! */ } else { @@ -932,7 +932,7 @@ static void read_password(gamedata *data, faction *f) { } } else { - faction_setpassword(f, (data->version >= CRYPT_VERSION) ? name : password_encode(name, PASSWORD_DEFAULT)); + faction_setpassword(f, (data->version >= CRYPT_VERSION) ? name : password_hash(name, PASSWORD_DEFAULT)); } (void)_test_read_password; } diff --git a/src/kernel/save.test.c b/src/kernel/save.test.c index 036ad00c5..d9ba52862 100644 --- a/src/kernel/save.test.c +++ b/src/kernel/save.test.c @@ -407,7 +407,7 @@ static void test_read_password(CuTest *tc) { test_setup(); f = test_create_faction(NULL); - faction_setpassword(f, password_encode("secret", PASSWORD_DEFAULT)); + faction_setpassword(f, password_hash("secret", PASSWORD_DEFAULT)); mstream_init(&data.strm); gamedata_init(&data, &store, RELEASE_VERSION); _test_write_password(&data, f); @@ -431,7 +431,7 @@ static void test_read_password_external(CuTest *tc) { errno = 0; } f = test_create_faction(NULL); - faction_setpassword(f, password_encode("secret", PASSWORD_DEFAULT)); + faction_setpassword(f, password_hash("secret", PASSWORD_DEFAULT)); CuAssertPtrNotNull(tc, f->_password); mstream_init(&data.strm); gamedata_init(&data, &store, RELEASE_VERSION); diff --git a/src/laws.c b/src/laws.c index fe97931ad..d9e05917a 100644 --- a/src/laws.c +++ b/src/laws.c @@ -2135,7 +2135,7 @@ int password_cmd(unit * u, struct order *ord) cmistake(u, ord, 283, MSG_EVENT); str_strlcpy(pwbuf, itoa36(rng_int()), sizeof(pwbuf)); } - faction_setpassword(u->faction, password_encode(pwbuf, PASSWORD_DEFAULT)); + faction_setpassword(u->faction, password_hash(pwbuf, PASSWORD_DEFAULT)); ADDMSG(&u->faction->msgs, msg_message("changepasswd", "value", pwbuf)); u->faction->flags |= FFL_PWMSG; diff --git a/src/util/password.c b/src/util/password.c index a7e14c98b..61ae8f2a0 100644 --- a/src/util/password.c +++ b/src/util/password.c @@ -16,7 +16,7 @@ bool password_is_implemented(cryptalgo_t algo) { return algo == PASSWORD_PLAINTEXT; } -const char * password_encode(const char * passwd, cryptalgo_t algo) { +const char * password_hash(const char * passwd, cryptalgo_t algo) { if (algo == PASSWORD_BCRYPT) { char salt[BCRYPT_HASHSIZE]; static char hash[BCRYPT_HASHSIZE]; diff --git a/src/util/password.h b/src/util/password.h index 61abc588f..7309e0c0e 100644 --- a/src/util/password.h +++ b/src/util/password.h @@ -13,5 +13,5 @@ extern int bcrypt_workfactor; #define VERIFY_FAIL 1 #define VERIFY_UNKNOWN 2 int password_verify(const char *hash, const char *passwd); -const char * password_encode(const char *passwd, cryptalgo_t algo); +const char * password_hash(const char *passwd, cryptalgo_t algo); bool password_is_implemented(cryptalgo_t algo); diff --git a/src/util/password.test.c b/src/util/password.test.c index f22ef5971..7ce2d0682 100644 --- a/src/util/password.test.c +++ b/src/util/password.test.c @@ -9,7 +9,7 @@ static void test_passwords(CuTest *tc) { if (password_is_implemented(PASSWORD_BCRYPT)) { int wf = bcrypt_workfactor; bcrypt_workfactor = 4; - hash = password_encode("password", PASSWORD_BCRYPT); + hash = password_hash("password", PASSWORD_BCRYPT); CuAssertPtrNotNull(tc, hash); CuAssertIntEquals(tc, '$', hash[0]); CuAssertIntEquals(tc, '2', hash[1]); @@ -22,7 +22,7 @@ static void test_passwords(CuTest *tc) { bcrypt_workfactor = wf; } if (password_is_implemented(PASSWORD_PLAINTEXT)) { - hash = password_encode("password", PASSWORD_PLAINTEXT); + hash = password_hash("password", PASSWORD_PLAINTEXT); CuAssertPtrNotNull(tc, hash); CuAssertStrEquals(tc, hash, "password"); CuAssertIntEquals(tc, VERIFY_OK, password_verify(hash, "password")); From 5a1c96bd936da8b330d5bd2392c34ba58659caa4 Mon Sep 17 00:00:00 2001 From: Enno Rehling Date: Thu, 27 Sep 2018 16:57:39 +0200 Subject: [PATCH 037/160] make python password checks use the database and bcrypt --- process/checkpasswd.py | 13 +++-- process/epasswd.py | 111 +++++++++++++++++++++++++------------- process/process-orders.py | 6 ++- process/sendreport.sh | 6 ++- 4 files changed, 92 insertions(+), 44 deletions(-) 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..4798967a9 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(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/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/sendreport.sh b/process/sendreport.sh index d98ed505e..d8fe79d47 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 From 88f0504f48572b721f766fe0cd344ac670bb06e3 Mon Sep 17 00:00:00 2001 From: Enno Rehling Date: Thu, 27 Sep 2018 17:08:04 +0200 Subject: [PATCH 038/160] no such file sendpasswd.py (and no suppor for feature possible) --- process/procmail/rules | 20 -------------------- 1 file changed, 20 deletions(-) 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 From 17f7aa2c0af472331b0b54141526681e44830719 Mon Sep 17 00:00:00 2001 From: Enno Rehling Date: Thu, 27 Sep 2018 19:52:54 +0200 Subject: [PATCH 039/160] start new branch for a syntax checker --- src/CMakeLists.txt | 10 +++++++--- src/checker.c | 8 ++++++++ 2 files changed, 15 insertions(+), 3 deletions(-) create mode 100644 src/checker.c diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt index eacc879e5..e84a1bb18 100644 --- a/src/CMakeLists.txt +++ b/src/CMakeLists.txt @@ -140,7 +140,11 @@ set (ERESSEA_SRC ${KERNEL_SRC} ${DB_SRC} ${UTIL_SRC} -) + ) + +set(CHECK_SRC + checker.c + ) set(SERVER_SRC bind_building.c @@ -161,7 +165,7 @@ set(SERVER_SRC console.c helpers.c main.c -) + ) if (CURSES_FOUND) set (SERVER_SRC ${SERVER_SRC} @@ -176,10 +180,10 @@ if(NOT IWYU_PATH) message(STATUS "Could not find the program include-what-you-use") endif() - add_library(version STATIC ${VERSION_SRC}) add_library(game ${ERESSEA_SRC}) add_executable(eressea ${SERVER_SRC}) +add_executable(checker ${CHECK_SRC}) if (IWYU_PATH) set_property(TARGET eressea PROPERTY C_INCLUDE_WHAT_YOU_USE ${IWYU_PATH}) endif(IWYU_PATH) diff --git a/src/checker.c b/src/checker.c new file mode 100644 index 000000000..eec1db26f --- /dev/null +++ b/src/checker.c @@ -0,0 +1,8 @@ +#ifdef _MSV_VER +#include +#endif + +int main(int argc, char **argv) { + return 0; +} + From 7b9e72e559f43a62c6fe38f22e90cd30354fc928 Mon Sep 17 00:00:00 2001 From: Enno Rehling Date: Fri, 28 Sep 2018 20:50:24 +0200 Subject: [PATCH 040/160] reduce dependeny spaghetti for database code. --- src/CMakeLists.txt | 1 + src/bind_eressea.c | 9 +++++++- src/checker.c | 14 ++++++++++++ src/eressea.c | 10 ++++----- src/gamedb.c | 3 +-- src/kernel/CMakeLists.txt | 1 - src/kernel/database.c | 46 -------------------------------------- src/kernel/database.h | 23 ------------------- src/kernel/database.test.c | 6 ++--- src/kernel/db/berkeley.c | 45 ++++++++++++++++++------------------- src/kernel/db/driver.h | 6 ++++- src/kernel/db/sqlite.c | 12 +++++----- src/kernel/orderdb.c | 28 ++++++++++++++++++++--- src/kernel/orderdb.h | 3 +++ src/orderfile.c | 9 +------- src/orderfile.h | 4 ++-- src/test_eressea.c | 1 - tests/orders.txt | 3 +++ 18 files changed, 98 insertions(+), 126 deletions(-) delete mode 100644 src/kernel/database.c delete mode 100644 src/kernel/database.h create mode 100644 tests/orders.txt diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt index e84a1bb18..fb21a9d50 100644 --- a/src/CMakeLists.txt +++ b/src/CMakeLists.txt @@ -144,6 +144,7 @@ set (ERESSEA_SRC set(CHECK_SRC checker.c + orderfile.c ) set(SERVER_SRC diff --git a/src/bind_eressea.c b/src/bind_eressea.c index 9f73c4a29..34640137b 100755 --- a/src/bind_eressea.c +++ b/src/bind_eressea.c @@ -12,6 +12,7 @@ #include #include +#include #include #include @@ -34,7 +35,13 @@ int eressea_write_game(const char * filename) { } int eressea_read_orders(const char * filename) { - return readorders(filename); + FILE * F = fopen(filename, "r"); + if (!F) { + perror(filename); + return -1; + } + log_info("reading orders from %s", filename); + return readorders(F); } int eressea_export_json(const char * filename, int flags) { diff --git a/src/checker.c b/src/checker.c index eec1db26f..1a07897a0 100644 --- a/src/checker.c +++ b/src/checker.c @@ -2,7 +2,21 @@ #include #endif +#include +#include "orderfile.h" + int main(int argc, char **argv) { + FILE * F = stdin; + if (argc >= 1) { + const char *filename = argv[1]; + F = fopen(filename, "r"); + if (!F) { + perror(filename); + return -1; + } + readorders(F); + fclose(F); + } return 0; } diff --git a/src/eressea.c b/src/eressea.c index 0bf1454ee..382e23fa3 100644 --- a/src/eressea.c +++ b/src/eressea.c @@ -1,14 +1,14 @@ #include #include "eressea.h" +#include "kernel/building.h" #include "kernel/calendar.h" #include "kernel/config.h" #include "kernel/curse.h" -#include "kernel/faction.h" -#include "kernel/building.h" #include "kernel/equipment.h" +#include "kernel/faction.h" #include "kernel/item.h" -#include "kernel/database.h" +#include "kernel/orderdb.h" #include "util/functions.h" #include "util/language.h" @@ -54,12 +54,12 @@ void game_done(void) free_locales(); #endif kernel_done(); - dblib_close(); + orderdb_close(); } void game_init(void) { - dblib_open(); + orderdb_open(); errno = 0; kernel_init(); register_triggers(); diff --git a/src/gamedb.c b/src/gamedb.c index e570d61e8..2ca2dba73 100644 --- a/src/gamedb.c +++ b/src/gamedb.c @@ -6,7 +6,6 @@ #include "kernel/config.h" #include "kernel/calendar.h" -#include "kernel/database.h" #include "kernel/faction.h" #include "kernel/db/driver.h" @@ -21,7 +20,7 @@ int gamedb_update(void) err = db_driver_open(DB_GAME, dbname); if (err == 0) { for (f = factions; f; f = f->next) { - int uid = dblib_save_faction(f, turn); + int uid = db_driver_faction_save(f->uid, f->no, turn, f->email, f->_password); if (uid > 0) { f->uid = uid; } diff --git a/src/kernel/CMakeLists.txt b/src/kernel/CMakeLists.txt index db448bf11..53161efe7 100644 --- a/src/kernel/CMakeLists.txt +++ b/src/kernel/CMakeLists.txt @@ -55,7 +55,6 @@ command.c config.c connection.c curse.c -database.c equipment.c faction.c group.c diff --git a/src/kernel/database.c b/src/kernel/database.c deleted file mode 100644 index 137665e31..000000000 --- a/src/kernel/database.c +++ /dev/null @@ -1,46 +0,0 @@ -#include -#include "database.h" - -#include - -#include -#include -#include -#include - -#include - -#include "db/driver.h" - -order_data *dblib_load_order(int id) -{ - if (id > 0) { - return db_driver_order_load(id); - } - return NULL; -} - -int dblib_save_order(order_data *od) -{ - if (od->_str) { - return db_driver_order_save(od); - } - return 0; -} - -int dblib_save_faction(const faction *f, int turn) { - return db_driver_faction_save(f->uid, f->no, turn, f->email, f->_password); -} - -void dblib_open(void) -{ - const char *dbname; - - dbname = config_get("game.dbswap"); - db_driver_open(DB_SWAP, dbname); -} - -void dblib_close(void) -{ - db_driver_close(DB_SWAP); -} diff --git a/src/kernel/database.h b/src/kernel/database.h deleted file mode 100644 index e3bdf11d1..000000000 --- a/src/kernel/database.h +++ /dev/null @@ -1,23 +0,0 @@ -#ifndef H_DATABASE -#define H_DATABASE - -#include - -#ifdef __cplusplus -extern "C" { -#endif - - struct order_data; - struct faction; - - void dblib_open(void); - void dblib_close(void); - - struct order_data *dblib_load_order(int id); - int dblib_save_order(struct order_data *od); - int dblib_save_faction(const struct faction *f, int turn); - -#ifdef __cplusplus -} -#endif -#endif diff --git a/src/kernel/database.test.c b/src/kernel/database.test.c index cde4edc11..df777a580 100644 --- a/src/kernel/database.test.c +++ b/src/kernel/database.test.c @@ -2,7 +2,7 @@ #include #include -#include "database.h" +#include "db/driver.h" #include "orderdb.h" #include @@ -39,9 +39,9 @@ static void test_update_faction(CuTest *tc) { test_setup(); f = test_create_faction(NULL); - uid = dblib_save_faction(f, 0); + uid = db_driver_faction_save(f->uid, f->no, 0, f->email, f->_password); f->uid = uid; - uid = dblib_save_faction(f, 0); + uid = db_driver_faction_save(f->uid, f->no, 0, f->email, f->_password); CuAssertIntEquals(tc, f->uid, uid); test_teardown(); } diff --git a/src/kernel/db/berkeley.c b/src/kernel/db/berkeley.c index 778e0bfe7..9a10e4bf8 100644 --- a/src/kernel/db/berkeley.c +++ b/src/kernel/db/berkeley.c @@ -4,36 +4,35 @@ #include #include "driver.h" -#include -#include - #include #include static DB *g_dbp; -void db_driver_open(void) +void db_driver_open(database_t db, const char *dbname) { - int ret; - u_int32_t flags = DB_CREATE; - const char * dbname; + if (db == DB_SWAP) { + int ret; + u_int32_t flags = DB_CREATE; - dbname = config_get("game.dbname"); - ret = db_create(&g_dbp, NULL, 0); - assert(ret==0); + ret = db_create(&g_dbp, NULL, 0); + assert(ret == 0); - ret = g_dbp->open(g_dbp, NULL, dbname, NULL, DB_RECNO, flags, 0); - assert(ret==0); + ret = g_dbp->open(g_dbp, NULL, dbname, NULL, DB_RECNO, flags, 0); + assert(ret == 0); + } } -void db_driver_close(void) +void db_driver_close(database_t db) { - int ret; - ret = g_dbp->close(g_dbp, 0); - assert(ret==0); + if (db == DB_SWAP) { + int ret; + ret = g_dbp->close(g_dbp, 0); + assert(ret == 0); + } } -int db_driver_order_save(struct order_data *od) +int db_driver_order_save(const char *str) { int ret; DBT key, data; @@ -46,18 +45,13 @@ int db_driver_order_save(struct order_data *od) key.size = key.ulen = sizeof(recno); key.flags = DB_DBT_USERMEM; data.data = (void *)od->_str; - data.size = data.ulen = strlen(od->_str) + 1; + data.size = data.ulen = strlen(str) + 1; data.flags = DB_DBT_USERMEM; ret = g_dbp->put(g_dbp, NULL, &key, &data, DB_APPEND); assert(ret == 0); return (int)recno; } -int db_driver_faction_save(int id, int no, int turn, const char *email, const char *password) -{ - return -1; -} - struct order_data *db_driver_order_load(int id) { int ret; @@ -79,3 +73,8 @@ struct order_data *db_driver_order_load(int id) return od; } +int db_driver_faction_save(int id, int no, int turn, const char *email, const char *password) +{ + return -1; +} + diff --git a/src/kernel/db/driver.h b/src/kernel/db/driver.h index 26b0461e3..9632cb5db 100644 --- a/src/kernel/db/driver.h +++ b/src/kernel/db/driver.h @@ -1,7 +1,11 @@ #pragma once +#include + struct order_data; +extern void odata_create(struct order_data **pdata, size_t len, const char *str); + typedef enum database_t { DB_SWAP, DB_GAME, @@ -9,6 +13,6 @@ typedef enum database_t { int db_driver_open(database_t db, const char *dbname); void db_driver_close(database_t db); -int db_driver_order_save(struct order_data *od); +int db_driver_order_save(const char *str); struct order_data *db_driver_order_load(int id); int db_driver_faction_save(int id, int no, int turn, const char *email, const char *password); diff --git a/src/kernel/db/sqlite.c b/src/kernel/db/sqlite.c index 70cacaf48..ffdcc8e67 100644 --- a/src/kernel/db/sqlite.c +++ b/src/kernel/db/sqlite.c @@ -1,8 +1,6 @@ #include #include -#include -#include #include @@ -25,9 +23,9 @@ static sqlite3_stmt * g_stmt_insert_faction; static int g_order_batchsize; static int g_order_tx_size; -order_data *db_driver_order_load(int id) +struct order_data *db_driver_order_load(int id) { - order_data * od = NULL; + struct order_data * od = NULL; int err; ERRNO_CHECK(); @@ -58,12 +56,12 @@ order_data *db_driver_order_load(int id) return NULL; } -int db_driver_order_save(order_data *od) +int db_driver_order_save(const char *str) { int err; sqlite3_int64 id; - assert(od && od->_str); + assert(str); ERRNO_CHECK(); @@ -76,7 +74,7 @@ int db_driver_order_save(order_data *od) err = sqlite3_reset(g_stmt_insert_order); assert(err == SQLITE_OK); - err = sqlite3_bind_text(g_stmt_insert_order, 1, od->_str, -1, SQLITE_STATIC); + err = sqlite3_bind_text(g_stmt_insert_order, 1, str, -1, SQLITE_STATIC); assert(err == SQLITE_OK); err = sqlite3_step(g_stmt_insert_order); assert(err == SQLITE_DONE); diff --git a/src/kernel/orderdb.c b/src/kernel/orderdb.c index b30131be4..c4c4746f0 100644 --- a/src/kernel/orderdb.c +++ b/src/kernel/orderdb.c @@ -1,5 +1,8 @@ #include -#include "database.h" + +#include "config.h" +#include "db/driver.h" + #include "orderdb.h" #include @@ -10,6 +13,19 @@ #include #include +void orderdb_open(void) +{ + const char *dbname; + + dbname = config_get("game.dbswap"); + db_driver_open(DB_SWAP, dbname); +} + +void orderdb_close(void) +{ + db_driver_close(DB_SWAP); +} + void odata_create(order_data **pdata, size_t len, const char *str) { order_data *data; @@ -42,10 +58,16 @@ void odata_addref(order_data *od) order_data *odata_load(int id) { - return dblib_load_order(id); + if (id > 0) { + return db_driver_order_load(id); + } + return NULL; } int odata_save(order_data *od) { - return dblib_save_order(od); + if (od->_str) { + return db_driver_order_save(od->_str); + } + return 0; } diff --git a/src/kernel/orderdb.h b/src/kernel/orderdb.h index 800732c5e..33f8b6fce 100644 --- a/src/kernel/orderdb.h +++ b/src/kernel/orderdb.h @@ -19,6 +19,9 @@ extern "C" { order_data *odata_load(int id); int odata_save(order_data *od); + void orderdb_open(void); + void orderdb_close(void); + #ifdef __cplusplus } #endif diff --git a/src/orderfile.c b/src/orderfile.c index 9771b7e14..a2c7a6c87 100644 --- a/src/orderfile.c +++ b/src/orderfile.c @@ -226,20 +226,13 @@ static const char * file_getbuf(void *data) return getbuf(F, ENCODING_UTF8); } -int readorders(const char *filename) +int readorders(FILE *F) { input in; int result; - FILE *F = fopen(filename, "r"); - if (!F) { - perror(filename); - return -1; - } - log_info("reading orders from %s", filename); in.getbuf = file_getbuf; in.data = F; result = read_orders(&in); - fclose(F); return result; } diff --git a/src/orderfile.h b/src/orderfile.h index 43b86042e..fa051993e 100644 --- a/src/orderfile.h +++ b/src/orderfile.h @@ -1,7 +1,7 @@ #ifndef H_ORDERFILE #define H_ORDERFILE -#include +#include #ifdef __cplusplus extern "C" { @@ -13,7 +13,7 @@ extern "C" { } input; int read_orders(struct input *in); - int readorders(const char *filename); + int readorders(FILE *F); #ifdef __cplusplus } diff --git a/src/test_eressea.c b/src/test_eressea.c index d91c225ae..439fee1d6 100644 --- a/src/test_eressea.c +++ b/src/test_eressea.c @@ -1,7 +1,6 @@ #include #include #include -#include #include #include #include diff --git a/tests/orders.txt b/tests/orders.txt new file mode 100644 index 000000000..a4a4f7456 --- /dev/null +++ b/tests/orders.txt @@ -0,0 +1,3 @@ +ERESSEA uhfr "Hodor" +EINHEIT 8bz3 +BENENNEN EINHEIT 'Goldene Herde' From 91c49659ef2983edd5f0fba814f3fdf13f2a5667 Mon Sep 17 00:00:00 2001 From: Enno Rehling Date: Fri, 28 Sep 2018 21:02:32 +0200 Subject: [PATCH 041/160] orderdb is glue code, belongs outside of kernel. --- src/CMakeLists.txt | 2 ++ src/eressea.c | 2 +- src/kernel/CMakeLists.txt | 2 -- src/kernel/database.test.c | 1 + src/kernel/order.c | 31 +++++++++++++++++++++++- src/kernel/order.h | 12 +++++++++ src/kernel/orderdb.c | 34 ++------------------------ src/kernel/orderdb.h | 12 --------- src/orderdb.c | 43 +++++++++++++++++++++++++++++++++ src/orderdb.h | 25 +++++++++++++++++++ src/{kernel => }/orderdb.test.c | 0 11 files changed, 116 insertions(+), 48 deletions(-) create mode 100644 src/orderdb.c create mode 100644 src/orderdb.h rename src/{kernel => }/orderdb.test.c (100%) diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt index fb21a9d50..5800d1814 100644 --- a/src/CMakeLists.txt +++ b/src/CMakeLists.txt @@ -113,6 +113,7 @@ set (ERESSEA_SRC morale.c move.c names.c + orderdb.c orderfile.c piracy.c prefix.c @@ -221,6 +222,7 @@ set(TESTS_SRC monsters.test.c move.test.c names.test.c + orderdb.test.c orderfile.test.c piracy.test.c prefix.test.c diff --git a/src/eressea.c b/src/eressea.c index 382e23fa3..e1767811c 100644 --- a/src/eressea.c +++ b/src/eressea.c @@ -8,7 +8,6 @@ #include "kernel/equipment.h" #include "kernel/faction.h" #include "kernel/item.h" -#include "kernel/orderdb.h" #include "util/functions.h" #include "util/language.h" @@ -28,6 +27,7 @@ #include "creport.h" #include "report.h" #include "names.h" +#include "orderdb.h" #include "reports.h" #include "spells.h" #include "vortex.h" diff --git a/src/kernel/CMakeLists.txt b/src/kernel/CMakeLists.txt index 53161efe7..562562d8a 100644 --- a/src/kernel/CMakeLists.txt +++ b/src/kernel/CMakeLists.txt @@ -27,7 +27,6 @@ group.test.c item.test.c messages.test.c order.test.c -orderdb.test.c # pathfinder.test.c plane.test.c pool.test.c @@ -61,7 +60,6 @@ group.c item.c messages.c order.c -orderdb.c pathfinder.c plane.c pool.c diff --git a/src/kernel/database.test.c b/src/kernel/database.test.c index df777a580..3ec44896e 100644 --- a/src/kernel/database.test.c +++ b/src/kernel/database.test.c @@ -1,6 +1,7 @@ #include #include #include +#include #include "db/driver.h" #include "orderdb.h" diff --git a/src/kernel/order.c b/src/kernel/order.c index 2fd7c6eb8..e30ea6097 100644 --- a/src/kernel/order.c +++ b/src/kernel/order.c @@ -14,7 +14,6 @@ #include #include "order.h" -#include "orderdb.h" #include "skill.h" #include "keyword.h" @@ -36,6 +35,36 @@ # define ORD_KEYWORD(ord) (keyword_t)((ord)->command & 0xFFFF) # define OD_STRING(odata) ((odata) ? (odata)->_str : NULL) +void odata_create(order_data **pdata, size_t len, const char *str) +{ + order_data *data; + char *result; + + assert(pdata); + data = malloc(sizeof(order_data) + len + 1); + data->_refcount = 1; + result = (char *)(data + 1); + data->_str = (len > 0) ? result : NULL; + if (str) { + strcpy(result, str); + } + *pdata = data; +} + +void odata_release(order_data * od) +{ + if (od) { + if (--od->_refcount == 0) { + free(od); + } + } +} + +void odata_addref(order_data *od) +{ + ++od->_refcount; +} + void replace_order(order ** dlist, order * orig, const order * src) { assert(src); diff --git a/src/kernel/order.h b/src/kernel/order.h index b0d771b67..c5406b39e 100644 --- a/src/kernel/order.h +++ b/src/kernel/order.h @@ -37,6 +37,18 @@ extern "C" { #define CMD_PERSIST 0x020000 #define CMD_DEFAULT 0x040000 + typedef struct order_data { + const char *_str; + int _refcount; + } order_data; + + extern order_data *odata_load(int id); + extern int odata_save(order_data *od); + + void odata_create(order_data **pdata, size_t len, const char *str); + void odata_release(order_data * od); + void odata_addref(order_data *od); + typedef struct order { struct order *next; /* do not access this data: */ diff --git a/src/kernel/orderdb.c b/src/kernel/orderdb.c index c4c4746f0..42248c0ef 100644 --- a/src/kernel/orderdb.c +++ b/src/kernel/orderdb.c @@ -1,7 +1,7 @@ #include -#include "config.h" -#include "db/driver.h" +#include "kernel/config.h" +#include "kernel/db/driver.h" #include "orderdb.h" @@ -26,36 +26,6 @@ void orderdb_close(void) db_driver_close(DB_SWAP); } -void odata_create(order_data **pdata, size_t len, const char *str) -{ - order_data *data; - char *result; - - assert(pdata); - data = malloc(sizeof(order_data) + len + 1); - data->_refcount = 1; - result = (char *)(data + 1); - data->_str = (len > 0) ? result : NULL; - if (str) { - strcpy(result, str); - } - *pdata = data; -} - -void odata_release(order_data * od) -{ - if (od) { - if (--od->_refcount == 0) { - free(od); - } - } -} - -void odata_addref(order_data *od) -{ - ++od->_refcount; -} - order_data *odata_load(int id) { if (id > 0) { diff --git a/src/kernel/orderdb.h b/src/kernel/orderdb.h index 33f8b6fce..e17bdfea8 100644 --- a/src/kernel/orderdb.h +++ b/src/kernel/orderdb.h @@ -7,18 +7,6 @@ extern "C" { #endif - typedef struct order_data { - const char *_str; - int _refcount; - } order_data; - - void odata_create(order_data **pdata, size_t len, const char *str); - void odata_release(order_data * od); - void odata_addref(order_data *od); - - order_data *odata_load(int id); - int odata_save(order_data *od); - void orderdb_open(void); void orderdb_close(void); diff --git a/src/orderdb.c b/src/orderdb.c new file mode 100644 index 000000000..42248c0ef --- /dev/null +++ b/src/orderdb.c @@ -0,0 +1,43 @@ +#include + +#include "kernel/config.h" +#include "kernel/db/driver.h" + +#include "orderdb.h" + +#include + +#include + +#include +#include +#include + +void orderdb_open(void) +{ + const char *dbname; + + dbname = config_get("game.dbswap"); + db_driver_open(DB_SWAP, dbname); +} + +void orderdb_close(void) +{ + db_driver_close(DB_SWAP); +} + +order_data *odata_load(int id) +{ + if (id > 0) { + return db_driver_order_load(id); + } + return NULL; +} + +int odata_save(order_data *od) +{ + if (od->_str) { + return db_driver_order_save(od->_str); + } + return 0; +} diff --git a/src/orderdb.h b/src/orderdb.h new file mode 100644 index 000000000..cc809b1a6 --- /dev/null +++ b/src/orderdb.h @@ -0,0 +1,25 @@ +#ifndef H_ORDERDB +#define H_ORDERDB + +#include + +#ifdef __cplusplus +extern "C" { +#endif + + typedef struct order_data { + const char *_str; + int _refcount; + } order_data; + + void odata_create(order_data **pdata, size_t len, const char *str); + void odata_release(order_data * od); + void odata_addref(order_data *od); + + void orderdb_open(void); + void orderdb_close(void); + +#ifdef __cplusplus +} +#endif +#endif diff --git a/src/kernel/orderdb.test.c b/src/orderdb.test.c similarity index 100% rename from src/kernel/orderdb.test.c rename to src/orderdb.test.c From b47a41541f9da29186523a5b7367894c304f3050 Mon Sep 17 00:00:00 2001 From: Enno Rehling Date: Fri, 28 Sep 2018 21:43:20 +0200 Subject: [PATCH 042/160] write a new (expensive) in-memory db driver for orders. --- src/kernel/CMakeLists.txt | 2 +- src/kernel/db/critbit.c | 72 --------------------------------------- src/kernel/db/memory.c | 69 +++++++++++++++++++++++++++++++++++++ 3 files changed, 70 insertions(+), 73 deletions(-) delete mode 100644 src/kernel/db/critbit.c create mode 100644 src/kernel/db/memory.c diff --git a/src/kernel/CMakeLists.txt b/src/kernel/CMakeLists.txt index 562562d8a..756f691cc 100644 --- a/src/kernel/CMakeLists.txt +++ b/src/kernel/CMakeLists.txt @@ -1,7 +1,7 @@ cmake_minimum_required(VERSION 2.6) project(kernel C) -SET(_DBFILES db/critbit.c) +SET(_DBFILES db/memory.c) IF(SQLITE3_FOUND) SET(_DBFILES db/sqlite.c) diff --git a/src/kernel/db/critbit.c b/src/kernel/db/critbit.c deleted file mode 100644 index 69bac159e..000000000 --- a/src/kernel/db/critbit.c +++ /dev/null @@ -1,72 +0,0 @@ -#include -#include "driver.h" - -#include -#include - -#include - -#include -#include -#include - -static critbit_tree cb_orders = { 0 }; -static int auto_id = -1; - -struct cb_entry { - int id; - order_data *data; -}; - -order_data *db_driver_order_load(int id) -{ - void * match; - - assert(id>0); - if (cb_find_prefix(&cb_orders, &id, sizeof(id), &match, 1, 0) > 0) { - struct cb_entry *ent = (struct cb_entry *)match; - order_data * od = ent->data; - ++od->_refcount; - return od; - } - return NULL; -} - -int db_driver_order_save(order_data *od) -{ - struct cb_entry ent; - - assert(od && od->_str); - ++od->_refcount; - ent.id = ++auto_id; - ent.data = od; - cb_insert(&cb_orders, &ent, sizeof(ent)); - return ent.id; -} - -int db_driver_faction_save(int id, int no, int turn, const char *email, const char *password) -{ - return -1; -} - -static int free_data_cb(const void *match, const void *key, size_t keylen, - void *udata) -{ - struct cb_entry * ent = (struct cb_entry *)match; - order_data *od = ent->data; - odata_release(od); - return 0; -} - -void db_driver_open(void) -{ - assert(auto_id == -1); - auto_id = 0; -} - -void db_driver_close(void) -{ - cb_foreach(&cb_orders, NULL, 0, free_data_cb, NULL); - cb_clear(&cb_orders); - auto_id = -1; -} diff --git a/src/kernel/db/memory.c b/src/kernel/db/memory.c new file mode 100644 index 000000000..5fbaade4c --- /dev/null +++ b/src/kernel/db/memory.c @@ -0,0 +1,69 @@ +#include +#include "driver.h" + +#include +#include + +#include + +#include +#include +#include + +static selist * g_orders; +static int auto_id = -1; + +struct order_data *db_driver_order_load(int id) +{ + void * match; + + assert(id>0); + match = selist_get(g_orders, id - 1); + if (match) { + char * str = (char *)match; + struct order_data * od = NULL; + odata_create(&od, strlen(str), str); + return od; + } + return NULL; +} + +int db_driver_order_save(const char * str) +{ + assert(str); + selist_push(&g_orders, str_strdup(str)); + return ++auto_id; +} + +int db_driver_faction_save(int id, int no, int turn, const char *email, const char *password) +{ + return -1; +} + +static int free_data_cb(const void *match) +{ + char *str = (char *)match; + free(str); + return 0; +} + +int db_driver_open(database_t db, const char *dbname) +{ + (void)dbname; + if (db == DB_SWAP) { + assert(auto_id == -1); + auto_id = 0; + return 0; + } + return -1; +} + +void db_driver_close(database_t db) +{ + if (db == DB_SWAP) { + selist_foreach(g_orders, free_data_cb); + selist_free(g_orders); + g_orders = NULL; + auto_id = -1; + } +} From b18f8ca9fb96a48ab752c82c6c2da0953da1154f Mon Sep 17 00:00:00 2001 From: Enno Rehling Date: Sat, 29 Sep 2018 09:56:05 +0200 Subject: [PATCH 043/160] change database selection, fix in-memory db --- s/cmake-init | 35 ++++++++++++++++++++++++++++++++++- src/CMakeLists.txt | 4 +++- src/kernel/db/memory.c | 5 +++-- 3 files changed, 40 insertions(+), 4 deletions(-) diff --git a/s/cmake-init b/s/cmake-init index 781db1ea7..eea222334 100755 --- a/s/cmake-init +++ b/s/cmake-init @@ -1,13 +1,46 @@ #!/bin/sh -ERESSEA_DB=db +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/src/CMakeLists.txt b/src/CMakeLists.txt index 5800d1814..d819675b8 100644 --- a/src/CMakeLists.txt +++ b/src/CMakeLists.txt @@ -184,8 +184,10 @@ endif() add_library(version STATIC ${VERSION_SRC}) add_library(game ${ERESSEA_SRC}) + +#add_executable(checker ${CHECK_SRC}) + add_executable(eressea ${SERVER_SRC}) -add_executable(checker ${CHECK_SRC}) if (IWYU_PATH) set_property(TARGET eressea PROPERTY C_INCLUDE_WHAT_YOU_USE ${IWYU_PATH}) endif(IWYU_PATH) diff --git a/src/kernel/db/memory.c b/src/kernel/db/memory.c index 5fbaade4c..0f572a99e 100644 --- a/src/kernel/db/memory.c +++ b/src/kernel/db/memory.c @@ -1,4 +1,6 @@ +#ifdef _MSC_VER #include +#endif #include "driver.h" #include @@ -40,11 +42,10 @@ int db_driver_faction_save(int id, int no, int turn, const char *email, const ch return -1; } -static int free_data_cb(const void *match) +static void free_data_cb(void *match) { char *str = (char *)match; free(str); - return 0; } int db_driver_open(database_t db, const char *dbname) From 735c890eceafb24304427bfefb35b7b05d387574 Mon Sep 17 00:00:00 2001 From: Enno Rehling Date: Sat, 29 Sep 2018 09:58:23 +0200 Subject: [PATCH 044/160] explicitly build sqlite on travis --- .travis.yml | 1 + s/travis-build | 2 +- 2 files changed, 2 insertions(+), 1 deletion(-) 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/s/travis-build b/s/travis-build index a678b1de2..64b278710 100755 --- a/s/travis-build +++ b/s/travis-build @@ -31,8 +31,8 @@ cppcheck_tests() { set -e [ -z $BUILD ] && BUILD=Debug ; export BUILD -s/cmake-init # cppcheck_tests +s/cmake-init --db=sqlite s/build cd process make From 5dcb9075ac7a1f5a9bc32020af84250ee7cb9b7b Mon Sep 17 00:00:00 2001 From: Enno Rehling Date: Sat, 29 Sep 2018 11:19:59 +0200 Subject: [PATCH 045/160] we have a library that contains the parser --- src/CMakeLists.txt | 21 ++++++++++++++------- 1 file changed, 14 insertions(+), 7 deletions(-) diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt index d819675b8..be26a30a4 100644 --- a/src/CMakeLists.txt +++ b/src/CMakeLists.txt @@ -85,6 +85,11 @@ TOLUA_BINDING(eressea.pkg bind_eressea.h) TOLUA_BINDING(settings.pkg kenel/config.h) ENDIF() +set (PARSER_SRC + ${DB_SRC} + ${UTIL_SRC} + ) + set (ERESSEA_SRC vortex.c academy.c @@ -139,13 +144,10 @@ set (ERESSEA_SRC ${TRIGGERS_SRC} ${ATTRIBUTES_SRC} ${KERNEL_SRC} - ${DB_SRC} - ${UTIL_SRC} ) set(CHECK_SRC checker.c - orderfile.c ) set(SERVER_SRC @@ -183,22 +185,28 @@ if(NOT IWYU_PATH) endif() add_library(version STATIC ${VERSION_SRC}) -add_library(game ${ERESSEA_SRC}) +add_library(parser ${PARSER_SRC}) +target_link_libraries(parser + ${CRYPTO_LIBRARIES} + ) + #add_executable(checker ${CHECK_SRC}) +#target_link_libraries(checker parser) + +add_library(game ${ERESSEA_SRC}) +target_link_libraries(game parser version) add_executable(eressea ${SERVER_SRC}) if (IWYU_PATH) set_property(TARGET eressea PROPERTY C_INCLUDE_WHAT_YOU_USE ${IWYU_PATH}) endif(IWYU_PATH) -target_link_libraries(game version) target_link_libraries(eressea game ${TOLUA_LIBRARIES} ${LUA_LIBRARIES} ${STORAGE_LIBRARIES} ${CLIBS_LIBRARIES} - ${CRYPTO_LIBRARIES} ${CJSON_LIBRARIES} ${INIPARSER_LIBRARIES} ) @@ -260,7 +268,6 @@ target_link_libraries(test_eressea ${LUA_LIBRARIES} ${CLIBS_LIBRARIES} ${STORAGE_LIBRARIES} - ${CRYPTO_LIBRARIES} ${CJSON_LIBRARIES} ${INIPARSER_LIBRARIES} ) From a373807189538a2299b6705587d0aa6f91f41820 Mon Sep 17 00:00:00 2001 From: Enno Rehling Date: Sat, 29 Sep 2018 11:37:17 +0200 Subject: [PATCH 046/160] move attrib and event modules to kernel --- src/alchemy.c | 2 +- src/attributes/attributes.c | 4 ++-- src/attributes/dict.c | 2 +- src/attributes/follow.c | 2 +- src/attributes/hate.c | 2 +- src/attributes/iceberg.c | 2 +- src/attributes/key.c | 2 +- src/attributes/key.test.c | 2 +- src/attributes/movement.c | 2 +- src/attributes/otherfaction.c | 2 +- src/attributes/otherfaction.test.c | 2 +- src/attributes/overrideroads.c | 2 +- src/attributes/racename.c | 2 +- src/attributes/raceprefix.c | 2 +- src/attributes/reduceproduction.c | 2 +- src/attributes/seenspell.c | 2 +- src/attributes/stealth.c | 2 +- src/attributes/targetregion.c | 2 +- src/battle.c | 2 +- src/bind_region.c | 2 +- src/bind_ship.c | 2 +- src/bind_unit.c | 4 ++-- src/bindings.c | 2 +- src/chaos.c | 2 +- src/creport.c | 2 +- src/economy.c | 4 ++-- src/economy.test.c | 2 +- src/give.c | 4 ++-- src/gmtool.c | 2 +- src/helpers.c | 4 ++-- src/items.c | 4 ++-- src/items/speedsail.c | 2 +- src/jsonconf.c | 2 +- src/kernel/CMakeLists.txt | 4 ++++ src/kernel/alliance.c | 2 +- src/kernel/ally.c | 2 +- src/{util => kernel}/attrib.c | 10 +++++----- src/{util => kernel}/attrib.h | 2 +- src/{util => kernel}/attrib.test.c | 0 src/kernel/build.c | 4 ++-- src/kernel/building.c | 4 ++-- src/kernel/config.c | 4 ++-- src/kernel/config.test.c | 2 +- src/kernel/connection.c | 2 +- src/kernel/curse.c | 2 +- src/kernel/curse.test.c | 2 +- src/{util => kernel}/event.c | 8 ++++---- src/{util => kernel}/event.h | 2 +- src/kernel/faction.c | 4 ++-- src/kernel/group.c | 2 +- src/kernel/group.test.c | 2 +- src/kernel/item.c | 2 +- src/kernel/plane.c | 2 +- src/kernel/race.c | 2 +- src/kernel/region.c | 2 +- src/kernel/save.c | 4 ++-- src/kernel/save.test.c | 4 ++-- src/kernel/ship.c | 4 ++-- src/kernel/ship.test.c | 2 +- src/kernel/skills.c | 2 +- src/kernel/terrain.c | 2 +- src/kernel/unit.c | 4 ++-- src/kernel/unit.test.c | 2 +- src/laws.c | 4 ++-- src/laws.test.c | 2 +- src/lighthouse.c | 2 +- src/lighthouse.test.c | 2 +- src/magic.c | 4 ++-- src/magic.test.c | 2 +- src/market.c | 2 +- src/modules/autoseed.c | 2 +- src/modules/gmcmd.c | 2 +- src/modules/museum.c | 2 +- src/modules/xmas.c | 4 ++-- src/monsters.c | 4 ++-- src/monsters.test.c | 2 +- src/move.c | 2 +- src/move.test.c | 2 +- src/piracy.c | 2 +- src/races/races.c | 2 +- src/randenc.c | 2 +- src/renumber.c | 2 +- src/report.c | 2 +- src/reports.c | 2 +- src/reports.test.c | 2 +- src/spells.c | 4 ++-- src/spells.test.c | 2 +- src/spells/borders.c | 2 +- src/spells/combatspells.c | 2 +- src/spells/magicresistance.test.c | 2 +- src/spy.c | 2 +- src/spy.test.c | 2 +- src/study.c | 2 +- src/study.test.c | 2 +- src/travelthru.c | 2 +- src/travelthru.test.c | 2 +- src/triggers/changefaction.c | 4 ++-- src/triggers/changerace.c | 4 ++-- src/triggers/clonedied.c | 4 ++-- src/triggers/createcurse.c | 4 ++-- src/triggers/createunit.c | 4 ++-- src/triggers/gate.c | 4 ++-- src/triggers/giveitem.c | 4 ++-- src/triggers/killunit.c | 4 ++-- src/triggers/shock.c | 4 ++-- src/triggers/shock.test.c | 2 +- src/triggers/timeout.c | 4 ++-- src/triggers/triggers.c | 2 +- src/util/CMakeLists.txt | 4 ---- src/volcano.c | 2 +- src/volcano.test.c | 2 +- src/vortex.c | 2 +- src/wormhole.c | 2 +- src/wormhole.test.c | 2 +- 114 files changed, 151 insertions(+), 151 deletions(-) rename src/{util => kernel}/attrib.c (99%) rename src/{util => kernel}/attrib.h (99%) rename src/{util => kernel}/attrib.test.c (100%) rename src/{util => kernel}/event.c (98%) rename src/{util => kernel}/event.h (99%) diff --git a/src/alchemy.c b/src/alchemy.c index 4b7e961a6..fb0516359 100644 --- a/src/alchemy.c +++ b/src/alchemy.c @@ -33,7 +33,7 @@ OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. #include /* util includes */ -#include +#include #include #include #include diff --git a/src/attributes/attributes.c b/src/attributes/attributes.c index 6bf78da63..cf75efc58 100644 --- a/src/attributes/attributes.c +++ b/src/attributes/attributes.c @@ -53,8 +53,8 @@ OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. #include /* util includes */ -#include -#include +#include +#include #include #include #include diff --git a/src/attributes/dict.c b/src/attributes/dict.c index bc5e94204..aa34886a6 100644 --- a/src/attributes/dict.c +++ b/src/attributes/dict.c @@ -29,7 +29,7 @@ OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. #include /* util includes */ -#include +#include #include #include #include diff --git a/src/attributes/follow.c b/src/attributes/follow.c index 8c5e14526..07fffbfd6 100644 --- a/src/attributes/follow.c +++ b/src/attributes/follow.c @@ -22,7 +22,7 @@ OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. #include #include -#include +#include #include #include diff --git a/src/attributes/hate.c b/src/attributes/hate.c index c260de335..aff71d0e7 100644 --- a/src/attributes/hate.c +++ b/src/attributes/hate.c @@ -22,7 +22,7 @@ OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. #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 1808c561f..462c7a63b 100644 --- a/src/attributes/key.c +++ b/src/attributes/key.c @@ -20,7 +20,7 @@ OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. #include #include "key.h" -#include +#include #include #include #include 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..552ff51aa 100644 --- a/src/attributes/movement.c +++ b/src/attributes/movement.c @@ -20,7 +20,7 @@ OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. #include #include "movement.h" -#include +#include #include #include diff --git a/src/attributes/otherfaction.c b/src/attributes/otherfaction.c index 343460057..87b29f252 100644 --- a/src/attributes/otherfaction.c +++ b/src/attributes/otherfaction.c @@ -23,7 +23,7 @@ OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. #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..6108465cd 100644 --- a/src/attributes/seenspell.c +++ b/src/attributes/seenspell.c @@ -23,7 +23,7 @@ OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. #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..f67689052 100644 --- a/src/attributes/targetregion.c +++ b/src/attributes/targetregion.c @@ -22,7 +22,7 @@ OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. #include #include -#include +#include #include #include diff --git a/src/battle.c b/src/battle.c index aa5de9f71..ae914ab05 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 diff --git a/src/bind_region.c b/src/bind_region.c index 3b0e7f3a3..9d7897829 100644 --- a/src/bind_region.c +++ b/src/bind_region.c @@ -22,7 +22,7 @@ #include #include -#include +#include #include #include #include diff --git a/src/bind_ship.c b/src/bind_ship.c index 2a1d75271..d335d996d 100644 --- a/src/bind_ship.c +++ b/src/bind_ship.c @@ -14,7 +14,7 @@ #include #include -#include +#include #include #include #include diff --git a/src/bind_unit.c b/src/bind_unit.c index 9f6c39163..3f2a037ea 100644 --- a/src/bind_unit.c +++ b/src/bind_unit.c @@ -11,9 +11,9 @@ #include "skill.h" /* util includes */ -#include +#include #include -#include +#include #include #include #include "util/variant.h" diff --git a/src/bindings.c b/src/bindings.c index b2da38eba..caac5b99c 100755 --- a/src/bindings.c +++ b/src/bindings.c @@ -47,7 +47,7 @@ #include -#include +#include #include #include #include diff --git a/src/chaos.c b/src/chaos.c index 1ec431b7e..615113656 100644 --- a/src/chaos.c +++ b/src/chaos.c @@ -34,7 +34,7 @@ OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. #include #include -#include +#include #include #include diff --git a/src/creport.c b/src/creport.c index ce67493da..475a04b1e 100644 --- a/src/creport.c +++ b/src/creport.c @@ -64,7 +64,7 @@ without prior permission by the authors of Eressea. #include "kernel/unit.h" /* util includes */ -#include +#include #include #include #include diff --git a/src/economy.c b/src/economy.c index f0c930a3f..15b907a25 100644 --- a/src/economy.c +++ b/src/economy.c @@ -64,9 +64,9 @@ OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. #include "kernel/unit.h" /* util includes */ -#include +#include #include -#include +#include #include #include #include diff --git a/src/economy.test.c b/src/economy.test.c index 1a40c03db..0b213ba7e 100644 --- a/src/economy.test.c +++ b/src/economy.test.c @@ -19,7 +19,7 @@ #include #include -#include +#include #include #include diff --git a/src/give.c b/src/give.c index c47f9b9e2..02d5c622d 100644 --- a/src/give.c +++ b/src/give.c @@ -41,9 +41,9 @@ #include /* util includes */ -#include +#include #include -#include +#include #include #include #include diff --git a/src/gmtool.c b/src/gmtool.c index 270f0f677..cd0580fcc 100644 --- a/src/gmtool.c +++ b/src/gmtool.c @@ -30,7 +30,7 @@ #include "kernel/ship.h" #include "kernel/terrain.h" -#include +#include #include #include #include diff --git a/src/helpers.c b/src/helpers.c index 01fa19abc..2835b153d 100644 --- a/src/helpers.c +++ b/src/helpers.c @@ -19,8 +19,8 @@ without prior permission by the authors of Eressea. #include "alchemy.h" #include "magic.h" -#include -#include +#include +#include #include #include #include diff --git a/src/items.c b/src/items.c index 574c1da3b..665220e8f 100644 --- a/src/items.c +++ b/src/items.c @@ -33,8 +33,8 @@ #include #include -#include -#include +#include +#include #include #include #include diff --git a/src/items/speedsail.c b/src/items/speedsail.c index b224d6d6d..e6d3d1386 100644 --- a/src/items/speedsail.c +++ b/src/items/speedsail.c @@ -31,7 +31,7 @@ OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. #include /* util includes */ -#include +#include #include #include diff --git a/src/jsonconf.c b/src/jsonconf.c index 51116691f..dc11ee563 100644 --- a/src/jsonconf.c +++ b/src/jsonconf.c @@ -29,7 +29,7 @@ without prior permission by the authors of Eressea. #include "kernel/spellbook.h" /* util includes */ -#include "util/attrib.h" +#include "kernel/attrib.h" #include "util/crmessage.h" #include "util/functions.h" #include "util/language.h" diff --git a/src/kernel/CMakeLists.txt b/src/kernel/CMakeLists.txt index 756f691cc..093a41429 100644 --- a/src/kernel/CMakeLists.txt +++ b/src/kernel/CMakeLists.txt @@ -12,6 +12,7 @@ ENDIF(SQLITE3_FOUND) SET(_TEST_FILES alliance.test.c ally.test.c +attrib.test.c build.test.c building.test.c # callbacks.test.c @@ -22,6 +23,7 @@ config.test.c curse.test.c database.test.c equipment.test.c +# event.test.c faction.test.c group.test.c item.test.c @@ -46,6 +48,7 @@ SET(_FILES ${_DBFILES} alliance.c ally.c +attrib.c build.c building.c callbacks.c @@ -55,6 +58,7 @@ config.c connection.c curse.c equipment.c +event.c faction.c group.c item.c diff --git a/src/kernel/alliance.c b/src/kernel/alliance.c index d5dda0143..1996c5aad 100644 --- a/src/kernel/alliance.c +++ b/src/kernel/alliance.c @@ -27,7 +27,7 @@ without prior permission by the authors of Eressea. #include /* util includes */ -#include +#include #include #include #include diff --git a/src/kernel/ally.c b/src/kernel/ally.c index 4fadf9c04..a2536c7d9 100644 --- a/src/kernel/ally.c +++ b/src/kernel/ally.c @@ -10,7 +10,7 @@ #include "objtypes.h" #include "plane.h" -#include +#include #include #include diff --git a/src/util/attrib.c b/src/kernel/attrib.c similarity index 99% rename from src/util/attrib.c rename to src/kernel/attrib.c index defb4ff1e..375997df4 100644 --- a/src/util/attrib.c +++ b/src/kernel/attrib.c @@ -19,12 +19,12 @@ OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. #include #include "attrib.h" -#include "gamedata.h" -#include "log.h" -#include "variant.h" -#include "storage.h" -#include "strings.h" +#include +#include +#include +#include +#include #include #include diff --git a/src/util/attrib.h b/src/kernel/attrib.h similarity index 99% rename from src/util/attrib.h rename to src/kernel/attrib.h index b7a081d8c..65c41aa71 100644 --- a/src/util/attrib.h +++ b/src/kernel/attrib.h @@ -20,7 +20,7 @@ OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. #define ATTRIB_H #include -#include "variant.h" +#include #ifdef __cplusplus extern "C" { #endif diff --git a/src/util/attrib.test.c b/src/kernel/attrib.test.c similarity index 100% rename from src/util/attrib.test.c rename to src/kernel/attrib.test.c diff --git a/src/kernel/build.c b/src/kernel/build.c index 4e3dc4721..0891f1005 100644 --- a/src/kernel/build.c +++ b/src/kernel/build.c @@ -52,9 +52,9 @@ OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. #include /* from libutil */ -#include +#include #include -#include +#include #include #include #include diff --git a/src/kernel/building.c b/src/kernel/building.c index 75cad30f7..9627567ab 100644 --- a/src/kernel/building.c +++ b/src/kernel/building.c @@ -38,9 +38,9 @@ OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. #include "lighthouse.h" /* util includes */ -#include +#include #include -#include +#include #include #include #include diff --git a/src/kernel/config.c b/src/kernel/config.c index eee2ec0f5..e31564b8d 100644 --- a/src/kernel/config.c +++ b/src/kernel/config.c @@ -50,10 +50,10 @@ OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. #include "unit.h" /* util includes */ -#include +#include #include #include -#include +#include #include #include #include diff --git a/src/kernel/config.test.c b/src/kernel/config.test.c index e99ba9d08..e060a838e 100644 --- a/src/kernel/config.test.c +++ b/src/kernel/config.test.c @@ -7,7 +7,7 @@ #include #include #include -#include +#include #include diff --git a/src/kernel/connection.c b/src/kernel/connection.c index ddaf163c1..c66bd06e0 100644 --- a/src/kernel/connection.c +++ b/src/kernel/connection.c @@ -26,7 +26,7 @@ OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. #include "terrain.h" #include "unit.h" -#include +#include #include #include #include diff --git a/src/kernel/curse.c b/src/kernel/curse.c index f6be51dac..5f0c4a776 100644 --- a/src/kernel/curse.c +++ b/src/kernel/curse.c @@ -34,7 +34,7 @@ OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. #include "unit.h" /* util includes */ -#include +#include #include #include #include diff --git a/src/kernel/curse.test.c b/src/kernel/curse.test.c index 9c74544e1..23a5ad54f 100644 --- a/src/kernel/curse.test.c +++ b/src/kernel/curse.test.c @@ -4,7 +4,7 @@ #include #include #include -#include +#include #include #include #include diff --git a/src/util/event.c b/src/kernel/event.c similarity index 98% rename from src/util/event.c rename to src/kernel/event.c index d6aa6f338..ab095a008 100644 --- a/src/util/event.c +++ b/src/kernel/event.c @@ -18,12 +18,12 @@ OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. #include #include "event.h" +#include "attrib.h" /* util includes */ -#include "attrib.h" -#include "gamedata.h" -#include "log.h" -#include "strings.h" +#include +#include +#include #include diff --git a/src/util/event.h b/src/kernel/event.h similarity index 99% rename from src/util/event.h rename to src/kernel/event.h index ad4ca373d..c6c880c4c 100644 --- a/src/util/event.h +++ b/src/kernel/event.h @@ -22,7 +22,7 @@ OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. extern "C" { #endif -#include "variant.h" +#include struct attrib; struct trigger; diff --git a/src/kernel/faction.c b/src/kernel/faction.c index 6e85988f4..dea4ca54f 100755 --- a/src/kernel/faction.c +++ b/src/kernel/faction.c @@ -42,9 +42,9 @@ 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/kernel/group.c b/src/kernel/group.c index 48434ff5a..9ebbf244d 100755 --- a/src/kernel/group.c +++ b/src/kernel/group.c @@ -30,7 +30,7 @@ OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. #include /* util includes */ -#include +#include #include #include #include diff --git a/src/kernel/group.test.c b/src/kernel/group.test.c index 5581fee69..5d1a28f6b 100644 --- a/src/kernel/group.test.c +++ b/src/kernel/group.test.c @@ -9,7 +9,7 @@ #include "save.h" #include -#include +#include #include #include diff --git a/src/kernel/item.c b/src/kernel/item.c index 4e707a48c..aab734759 100644 --- a/src/kernel/item.c +++ b/src/kernel/item.c @@ -35,7 +35,7 @@ OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. #include "unit.h" /* util includes */ -#include +#include #include #include #include diff --git a/src/kernel/plane.c b/src/kernel/plane.c index 533dab92a..71c0dbd86 100644 --- a/src/kernel/plane.c +++ b/src/kernel/plane.c @@ -25,7 +25,7 @@ OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. #include "faction.h" /* util includes */ -#include +#include #include #include #include diff --git a/src/kernel/race.c b/src/kernel/race.c index ecdb7ae3d..31d437992 100644 --- a/src/kernel/race.c +++ b/src/kernel/race.c @@ -37,7 +37,7 @@ OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. #include "unit.h" /* util includes */ -#include +#include #include #include #include diff --git a/src/kernel/region.c b/src/kernel/region.c index 29f7222e1..2cb93b4a3 100644 --- a/src/kernel/region.c +++ b/src/kernel/region.c @@ -42,7 +42,7 @@ OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. /* util includes */ #include -#include +#include #include #include #include diff --git a/src/kernel/save.c b/src/kernel/save.c index e7cb90d2a..eb731e8d7 100644 --- a/src/kernel/save.c +++ b/src/kernel/save.c @@ -57,9 +57,9 @@ OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. /* util includes */ #include -#include +#include #include -#include +#include #include #include #include diff --git a/src/kernel/save.test.c b/src/kernel/save.test.c index d9ba52862..04ef9b1bb 100644 --- a/src/kernel/save.test.c +++ b/src/kernel/save.test.c @@ -17,9 +17,9 @@ #include #include #include -#include +#include #include -#include +#include #include #include #include diff --git a/src/kernel/ship.c b/src/kernel/ship.c index 4719945b0..20ed49d05 100644 --- a/src/kernel/ship.c +++ b/src/kernel/ship.c @@ -34,9 +34,9 @@ OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. #include "skill.h" /* util includes */ -#include +#include #include -#include +#include #include #include #include diff --git a/src/kernel/ship.test.c b/src/kernel/ship.test.c index 074876dd5..c50fdfa8d 100644 --- a/src/kernel/ship.test.c +++ b/src/kernel/ship.test.c @@ -7,7 +7,7 @@ #include #include -#include +#include #include #include diff --git a/src/kernel/skills.c b/src/kernel/skills.c index a15fb4463..ea2022872 100644 --- a/src/kernel/skills.c +++ b/src/kernel/skills.c @@ -24,7 +24,7 @@ OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. #include "region.h" #include "unit.h" -#include +#include #include #include #include diff --git a/src/kernel/terrain.c b/src/kernel/terrain.c index c7e007891..bec8fa8e8 100644 --- a/src/kernel/terrain.c +++ b/src/kernel/terrain.c @@ -30,7 +30,7 @@ OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. #include "terrainid.h" #include -#include +#include #include /* libc includes */ diff --git a/src/kernel/unit.c b/src/kernel/unit.c index 30971310d..13b2b1bf2 100644 --- a/src/kernel/unit.c +++ b/src/kernel/unit.c @@ -50,9 +50,9 @@ OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. #include "guard.h" /* util includes */ -#include +#include #include -#include +#include #include #include #include diff --git a/src/kernel/unit.test.c b/src/kernel/unit.test.c index 4b0ba2af6..29596f866 100644 --- a/src/kernel/unit.test.c +++ b/src/kernel/unit.test.c @@ -9,7 +9,7 @@ #include #include #include -#include +#include #include #include #include diff --git a/src/laws.c b/src/laws.c index d9e05917a..d7f8c53de 100644 --- a/src/laws.c +++ b/src/laws.c @@ -71,9 +71,9 @@ OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. #include "kernel/unit.h" /* util includes */ -#include +#include #include -#include +#include #include #include #include diff --git a/src/laws.test.c b/src/laws.test.c index 778ee3323..5c799a393 100644 --- a/src/laws.test.c +++ b/src/laws.test.c @@ -20,7 +20,7 @@ #include #include -#include +#include #include #include #include diff --git a/src/lighthouse.c b/src/lighthouse.c index 4ef830cfc..c6c7b9915 100644 --- a/src/lighthouse.c +++ b/src/lighthouse.c @@ -9,7 +9,7 @@ #include #include #include -#include +#include #include #include diff --git a/src/lighthouse.test.c b/src/lighthouse.test.c index d9accd49e..9dc6d2999 100644 --- a/src/lighthouse.test.c +++ b/src/lighthouse.test.c @@ -2,7 +2,7 @@ #include "lighthouse.h" -#include +#include #include #include #include diff --git a/src/magic.c b/src/magic.c index 7464e286d..41aa0dbce 100644 --- a/src/magic.c +++ b/src/magic.c @@ -62,9 +62,9 @@ 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/magic.test.c b/src/magic.test.c index 95c2d250d..1b64cdf53 100644 --- a/src/magic.test.c +++ b/src/magic.test.c @@ -17,7 +17,7 @@ #include #include -#include +#include #include #include diff --git a/src/market.c b/src/market.c index 87be18f95..0bd2fd647 100644 --- a/src/market.c +++ b/src/market.c @@ -16,7 +16,7 @@ without prior permission by the authors of Eressea. #include -#include +#include #include #include diff --git a/src/modules/autoseed.c b/src/modules/autoseed.c index 88240d0b3..65585441c 100644 --- a/src/modules/autoseed.c +++ b/src/modules/autoseed.c @@ -31,7 +31,7 @@ #include /* util includes */ -#include +#include #include #include #include diff --git a/src/modules/gmcmd.c b/src/modules/gmcmd.c index 20e090114..56386f2a6 100644 --- a/src/modules/gmcmd.c +++ b/src/modules/gmcmd.c @@ -32,7 +32,7 @@ #include /* util includes */ -#include +#include #include #include diff --git a/src/modules/museum.c b/src/modules/museum.c index 67ce12bd1..b5cbf05ce 100644 --- a/src/modules/museum.c +++ b/src/modules/museum.c @@ -38,7 +38,7 @@ OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. #include /* util includes */ -#include +#include #include #include #include diff --git a/src/modules/xmas.c b/src/modules/xmas.c index b76f14eab..b4fd2cd24 100644 --- a/src/modules/xmas.c +++ b/src/modules/xmas.c @@ -25,9 +25,9 @@ #include /* util includes */ -#include +#include #include -#include +#include #include #include #include diff --git a/src/monsters.c b/src/monsters.c index d009f8bda..505c6c272 100644 --- a/src/monsters.c +++ b/src/monsters.c @@ -52,9 +52,9 @@ #include "kernel/unit.h" /* util includes */ -#include +#include #include -#include +#include #include #include #include diff --git a/src/monsters.test.c b/src/monsters.test.c index 54b3f7f87..4ea3a32a3 100644 --- a/src/monsters.test.c +++ b/src/monsters.test.c @@ -18,7 +18,7 @@ #include "skill.h" #include "study.h" -#include +#include #include #include #include diff --git a/src/move.c b/src/move.c index 63453d970..b633d0ff7 100644 --- a/src/move.c +++ b/src/move.c @@ -72,7 +72,7 @@ OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. /* util includes */ #include -#include +#include #include #include #include diff --git a/src/move.test.c b/src/move.test.c index f01915e2a..4e9e4760d 100644 --- a/src/move.test.c +++ b/src/move.test.c @@ -17,7 +17,7 @@ #include #include -#include +#include #include #include #include diff --git a/src/piracy.c b/src/piracy.c index 46977c3d8..86b9b4904 100644 --- a/src/piracy.c +++ b/src/piracy.c @@ -15,7 +15,7 @@ #include #include -#include +#include #include #include #include diff --git a/src/races/races.c b/src/races/races.c index 44ca5d95e..7eede1b38 100644 --- a/src/races/races.c +++ b/src/races/races.c @@ -21,7 +21,7 @@ #include #include -#include +#include #include #include diff --git a/src/randenc.c b/src/randenc.c index 820d3760f..79998c14b 100644 --- a/src/randenc.c +++ b/src/randenc.c @@ -56,7 +56,7 @@ OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. #include "kernel/unit.h" /* util includes */ -#include "util/attrib.h" +#include "kernel/attrib.h" #include "util/language.h" #include "util/lists.h" #include "util/log.h" diff --git a/src/renumber.c b/src/renumber.c index 45ee0cccc..8a72be2a5 100644 --- a/src/renumber.c +++ b/src/renumber.c @@ -9,7 +9,7 @@ #include #include -#include +#include #include #include diff --git a/src/report.c b/src/report.c index 29f124cef..bc47cb1a4 100644 --- a/src/report.c +++ b/src/report.c @@ -77,7 +77,7 @@ OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. #include "kernel/alliance.h" /* util includes */ -#include +#include #include #include "util/bsdstring.h" #include diff --git a/src/reports.c b/src/reports.c index 25c331a9f..879e7ad3d 100644 --- a/src/reports.c +++ b/src/reports.c @@ -62,7 +62,7 @@ OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. #include "kernel/unit.h" /* util includes */ -#include "util/attrib.h" +#include "kernel/attrib.h" #include "util/base36.h" #include "util/bsdstring.h" #include "util/functions.h" diff --git a/src/reports.test.c b/src/reports.test.c index 65b5b06b0..29f14c634 100644 --- a/src/reports.test.c +++ b/src/reports.test.c @@ -25,7 +25,7 @@ #include "kernel/spellbook.h" #include "kernel/terrain.h" -#include "util/attrib.h" +#include "kernel/attrib.h" #include "util/language.h" #include "util/lists.h" #include "util/message.h" diff --git a/src/spells.c b/src/spells.c index 02cbe43b5..1238c1dae 100644 --- a/src/spells.c +++ b/src/spells.c @@ -70,9 +70,9 @@ /* util includes */ #include -#include +#include #include -#include +#include #include #include #include diff --git a/src/spells.test.c b/src/spells.test.c index e6150cb46..5950fab16 100644 --- a/src/spells.test.c +++ b/src/spells.test.c @@ -12,7 +12,7 @@ #include #include #include -#include +#include #include #include #include diff --git a/src/spells/borders.c b/src/spells/borders.c index c30726641..ff15ea971 100644 --- a/src/spells/borders.c +++ b/src/spells/borders.c @@ -13,7 +13,7 @@ #include #include -#include +#include #include #include #include diff --git a/src/spells/combatspells.c b/src/spells/combatspells.c index 06a78c4f4..6d6b846c3 100644 --- a/src/spells/combatspells.c +++ b/src/spells/combatspells.c @@ -36,7 +36,7 @@ #include /* util includes */ -#include +#include #include #include #include diff --git a/src/spells/magicresistance.test.c b/src/spells/magicresistance.test.c index cbfdeb4af..390134c56 100644 --- a/src/spells/magicresistance.test.c +++ b/src/spells/magicresistance.test.c @@ -8,7 +8,7 @@ #include #include #include -#include +#include #include #include "spells.h" diff --git a/src/spy.c b/src/spy.c index 9dc9de35a..98245e806 100644 --- a/src/spy.c +++ b/src/spy.c @@ -44,7 +44,7 @@ OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. #include /* util includes */ -#include +#include #include #include #include diff --git a/src/spy.test.c b/src/spy.test.c index d8b879e3f..dfe2886e7 100644 --- a/src/spy.test.c +++ b/src/spy.test.c @@ -11,7 +11,7 @@ #include #include #include -#include +#include #include #include #include diff --git a/src/study.c b/src/study.c index c978e69ad..a3dfa2e33 100644 --- a/src/study.c +++ b/src/study.c @@ -46,7 +46,7 @@ OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. #include /* util includes */ -#include +#include #include #include #include diff --git a/src/study.test.c b/src/study.test.c index a63be7cf1..3a94bf810 100644 --- a/src/study.test.c +++ b/src/study.test.c @@ -11,7 +11,7 @@ #include #include #include -#include +#include #include #include #include diff --git a/src/travelthru.c b/src/travelthru.c index fa6293f53..5a1af28eb 100644 --- a/src/travelthru.c +++ b/src/travelthru.c @@ -27,7 +27,7 @@ OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. #include #include #include -#include +#include #include #include diff --git a/src/travelthru.test.c b/src/travelthru.test.c index 8a38891b1..b4f0e3dca 100644 --- a/src/travelthru.test.c +++ b/src/travelthru.test.c @@ -3,7 +3,7 @@ #include #include #include -#include +#include #include #include "travelthru.h" diff --git a/src/triggers/changefaction.c b/src/triggers/changefaction.c index f34cb98bd..44edec269 100644 --- a/src/triggers/changefaction.c +++ b/src/triggers/changefaction.c @@ -24,9 +24,9 @@ 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/triggers/changerace.c b/src/triggers/changerace.c index abc605c35..758df4dc6 100644 --- a/src/triggers/changerace.c +++ b/src/triggers/changerace.c @@ -24,9 +24,9 @@ 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/triggers/clonedied.c b/src/triggers/clonedied.c index 62c4c3343..5713a2b6c 100644 --- a/src/triggers/clonedied.c +++ b/src/triggers/clonedied.c @@ -26,9 +26,9 @@ 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/triggers/createcurse.c b/src/triggers/createcurse.c index bd7422587..666c82a0f 100644 --- a/src/triggers/createcurse.c +++ b/src/triggers/createcurse.c @@ -24,9 +24,9 @@ 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/triggers/createunit.c b/src/triggers/createunit.c index f152d3766..4ce2730dc 100644 --- a/src/triggers/createunit.c +++ b/src/triggers/createunit.c @@ -26,9 +26,9 @@ 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/triggers/gate.c b/src/triggers/gate.c index 4c2c7a9cd..8690d5752 100644 --- a/src/triggers/gate.c +++ b/src/triggers/gate.c @@ -18,8 +18,8 @@ #include /* util includes */ -#include -#include +#include +#include #include #include #include diff --git a/src/triggers/giveitem.c b/src/triggers/giveitem.c index 08e4f0147..7815350a1 100644 --- a/src/triggers/giveitem.c +++ b/src/triggers/giveitem.c @@ -24,9 +24,9 @@ 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/triggers/killunit.c b/src/triggers/killunit.c index bca630177..37e55b25b 100644 --- a/src/triggers/killunit.c +++ b/src/triggers/killunit.c @@ -23,9 +23,9 @@ 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/triggers/shock.c b/src/triggers/shock.c index 7eae6f31a..767f0fd17 100644 --- a/src/triggers/shock.c +++ b/src/triggers/shock.c @@ -29,9 +29,9 @@ 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/triggers/shock.test.c b/src/triggers/shock.test.c index 43b8d394b..4bbd4de88 100644 --- a/src/triggers/shock.test.c +++ b/src/triggers/shock.test.c @@ -5,7 +5,7 @@ #include #include -#include +#include #include #include diff --git a/src/triggers/timeout.c b/src/triggers/timeout.c index 5179bd832..8acaaa38b 100644 --- a/src/triggers/timeout.c +++ b/src/triggers/timeout.c @@ -20,8 +20,8 @@ OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. #include "timeout.h" /* util includes */ -#include -#include +#include +#include #include #include #include diff --git a/src/triggers/triggers.c b/src/triggers/triggers.c index 8826fcba2..13504f216 100644 --- a/src/triggers/triggers.c +++ b/src/triggers/triggers.c @@ -31,7 +31,7 @@ OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. #include /* util includes */ -#include +#include /* libc includes */ #include diff --git a/src/util/CMakeLists.txt b/src/util/CMakeLists.txt index 90059666a..d0e505af2 100644 --- a/src/util/CMakeLists.txt +++ b/src/util/CMakeLists.txt @@ -3,12 +3,10 @@ project(util C) add_subdirectory (crypto) SET(_TEST_FILES -attrib.test.c base36.test.c # bsdstring.test.c # crmessage.test.c # dice.test.c -# event.test.c # filereader.test.c functions.test.c gamedata.test.c @@ -33,12 +31,10 @@ variant.test.c ) SET(_FILES -attrib.c base36.c bsdstring.c crmessage.c dice.c -event.c filereader.c functions.c gamedata.c diff --git a/src/volcano.c b/src/volcano.c index 7bddd6097..d4d045045 100644 --- a/src/volcano.c +++ b/src/volcano.c @@ -36,7 +36,7 @@ OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. #include /* util includes */ -#include +#include #include #include #include diff --git a/src/volcano.test.c b/src/volcano.test.c index c62febc0d..3ca670c7c 100644 --- a/src/volcano.test.c +++ b/src/volcano.test.c @@ -8,7 +8,7 @@ #include #include -#include +#include #include diff --git a/src/vortex.c b/src/vortex.c index 69d767c1b..948ad80fc 100644 --- a/src/vortex.c +++ b/src/vortex.c @@ -4,7 +4,7 @@ #include #include -#include +#include #include #include #include diff --git a/src/wormhole.c b/src/wormhole.c index 2000018ab..5cf044d92 100644 --- a/src/wormhole.c +++ b/src/wormhole.c @@ -24,7 +24,7 @@ #include /* util includes */ -#include +#include #include #include #include diff --git a/src/wormhole.test.c b/src/wormhole.test.c index b8baaa79a..bec4a5ff8 100644 --- a/src/wormhole.test.c +++ b/src/wormhole.test.c @@ -8,7 +8,7 @@ #include #include -#include +#include #include #include From b22d838a578b1729721efe2c99c0b773803065e4 Mon Sep 17 00:00:00 2001 From: Enno Rehling Date: Sat, 29 Sep 2018 13:21:46 +0200 Subject: [PATCH 047/160] move gamedata.c to kernel --- src/alchemy.c | 2 +- src/attributes/attributes.c | 2 +- src/attributes/dict.c | 2 +- src/attributes/follow.c | 2 +- src/attributes/hate.c | 2 +- src/attributes/key.c | 2 +- src/attributes/movement.c | 2 +- src/attributes/otherfaction.c | 2 +- src/attributes/seenspell.c | 2 +- src/attributes/targetregion.c | 2 +- src/bind_storage.c | 2 +- src/helpers.c | 2 +- src/kernel/CMakeLists.txt | 2 ++ src/kernel/ally.c | 2 +- src/kernel/attrib.c | 2 +- src/kernel/attrib.test.c | 2 +- src/kernel/building.c | 2 +- src/kernel/connection.c | 2 +- src/kernel/curse.c | 2 +- src/kernel/curse.test.c | 2 +- src/kernel/event.c | 2 +- src/kernel/faction.c | 2 +- src/{util => kernel}/gamedata.c | 3 ++- src/{util => kernel}/gamedata.h | 0 src/{util => kernel}/gamedata.test.c | 0 src/kernel/group.c | 2 +- src/kernel/group.test.c | 2 +- src/kernel/region.c | 2 +- src/kernel/save.c | 4 ++-- src/kernel/save.test.c | 2 +- src/kernel/spellbook.c | 2 +- src/kernel/unit.c | 2 +- src/magic.c | 2 +- src/modules/gmcmd.c | 2 +- src/modules/museum.c | 2 +- src/modules/xmas.c | 2 +- src/move.c | 2 +- src/spells.c | 2 +- src/spells/borders.c | 2 +- src/spells/flyingship.c | 2 +- src/spells/unitcurse.c | 2 +- src/triggers/changefaction.c | 2 +- src/triggers/changerace.c | 2 +- src/triggers/clonedied.c | 2 +- src/triggers/createcurse.c | 2 +- src/triggers/createunit.c | 2 +- src/triggers/gate.c | 2 +- src/triggers/giveitem.c | 2 +- src/triggers/killunit.c | 2 +- src/triggers/shock.c | 2 +- src/triggers/timeout.c | 2 +- src/util/CMakeLists.txt | 2 -- src/vortex.c | 2 +- src/wormhole.c | 2 +- tests/orders.txt | 3 --- 55 files changed, 54 insertions(+), 56 deletions(-) rename src/{util => kernel}/gamedata.c (98%) rename src/{util => kernel}/gamedata.h (100%) rename src/{util => kernel}/gamedata.test.c (100%) delete mode 100644 tests/orders.txt diff --git a/src/alchemy.c b/src/alchemy.c index fb0516359..d2dd64a04 100644 --- a/src/alchemy.c +++ b/src/alchemy.c @@ -34,7 +34,7 @@ OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. /* util includes */ #include -#include +#include #include #include #include diff --git a/src/attributes/attributes.c b/src/attributes/attributes.c index cf75efc58..400282ae7 100644 --- a/src/attributes/attributes.c +++ b/src/attributes/attributes.c @@ -55,7 +55,7 @@ OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. /* util includes */ #include #include -#include +#include #include #include diff --git a/src/attributes/dict.c b/src/attributes/dict.c index aa34886a6..70e88219d 100644 --- a/src/attributes/dict.c +++ b/src/attributes/dict.c @@ -32,7 +32,7 @@ OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. #include #include #include -#include +#include #include #include diff --git a/src/attributes/follow.c b/src/attributes/follow.c index 07fffbfd6..caeecee54 100644 --- a/src/attributes/follow.c +++ b/src/attributes/follow.c @@ -23,7 +23,7 @@ OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. #include #include -#include +#include #include #include diff --git a/src/attributes/hate.c b/src/attributes/hate.c index aff71d0e7..cef483cf6 100644 --- a/src/attributes/hate.c +++ b/src/attributes/hate.c @@ -23,7 +23,7 @@ OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. #include #include -#include +#include #include #include diff --git a/src/attributes/key.c b/src/attributes/key.c index 462c7a63b..76a18c876 100644 --- a/src/attributes/key.c +++ b/src/attributes/key.c @@ -21,7 +21,7 @@ OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. #include "key.h" #include -#include +#include #include #include diff --git a/src/attributes/movement.c b/src/attributes/movement.c index 552ff51aa..01c75ffae 100644 --- a/src/attributes/movement.c +++ b/src/attributes/movement.c @@ -21,7 +21,7 @@ OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. #include "movement.h" #include -#include +#include #include #include diff --git a/src/attributes/otherfaction.c b/src/attributes/otherfaction.c index 87b29f252..fcf05da05 100644 --- a/src/attributes/otherfaction.c +++ b/src/attributes/otherfaction.c @@ -24,7 +24,7 @@ OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. #include #include #include -#include +#include #include #include diff --git a/src/attributes/seenspell.c b/src/attributes/seenspell.c index 6108465cd..ae46980c3 100644 --- a/src/attributes/seenspell.c +++ b/src/attributes/seenspell.c @@ -24,7 +24,7 @@ OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. #include #include #include -#include +#include #include #include diff --git a/src/attributes/targetregion.c b/src/attributes/targetregion.c index f67689052..600d2e184 100644 --- a/src/attributes/targetregion.c +++ b/src/attributes/targetregion.c @@ -23,7 +23,7 @@ OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. #include #include -#include +#include #include #include diff --git a/src/bind_storage.c b/src/bind_storage.c index aa7935312..5df148bb4 100644 --- a/src/bind_storage.c +++ b/src/bind_storage.c @@ -6,7 +6,7 @@ #include -#include +#include #include #include diff --git a/src/helpers.c b/src/helpers.c index 2835b153d..223089c9c 100644 --- a/src/helpers.c +++ b/src/helpers.c @@ -22,7 +22,7 @@ without prior permission by the authors of Eressea. #include #include #include -#include +#include #include #include #include diff --git a/src/kernel/CMakeLists.txt b/src/kernel/CMakeLists.txt index 093a41429..06f58fc1b 100644 --- a/src/kernel/CMakeLists.txt +++ b/src/kernel/CMakeLists.txt @@ -25,6 +25,7 @@ database.test.c equipment.test.c # event.test.c faction.test.c +gamedata.test.c group.test.c item.test.c messages.test.c @@ -60,6 +61,7 @@ curse.c equipment.c event.c faction.c +gamedata.c group.c item.c messages.c diff --git a/src/kernel/ally.c b/src/kernel/ally.c index a2536c7d9..1fd7c0efd 100644 --- a/src/kernel/ally.c +++ b/src/kernel/ally.c @@ -12,7 +12,7 @@ #include #include -#include +#include #include diff --git a/src/kernel/attrib.c b/src/kernel/attrib.c index 375997df4..d84a8c8e9 100644 --- a/src/kernel/attrib.c +++ b/src/kernel/attrib.c @@ -22,7 +22,7 @@ OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. #include #include #include -#include +#include #include #include diff --git a/src/kernel/attrib.test.c b/src/kernel/attrib.test.c index d266196e6..918b768fd 100644 --- a/src/kernel/attrib.test.c +++ b/src/kernel/attrib.test.c @@ -1,7 +1,7 @@ #include #include "attrib.h" -#include +#include #include #include diff --git a/src/kernel/building.c b/src/kernel/building.c index 9627567ab..215c304e7 100644 --- a/src/kernel/building.c +++ b/src/kernel/building.c @@ -42,7 +42,7 @@ OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. #include #include #include -#include +#include #include #include #include diff --git a/src/kernel/connection.c b/src/kernel/connection.c index c66bd06e0..7fc1213e0 100644 --- a/src/kernel/connection.c +++ b/src/kernel/connection.c @@ -28,7 +28,7 @@ OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. #include #include -#include +#include #include #include #include diff --git a/src/kernel/curse.c b/src/kernel/curse.c index 5f0c4a776..62e7ab9b2 100644 --- a/src/kernel/curse.c +++ b/src/kernel/curse.c @@ -36,7 +36,7 @@ OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. /* util includes */ #include #include -#include +#include #include #include #include diff --git a/src/kernel/curse.test.c b/src/kernel/curse.test.c index 23a5ad54f..da0806914 100644 --- a/src/kernel/curse.test.c +++ b/src/kernel/curse.test.c @@ -6,7 +6,7 @@ #include #include #include -#include +#include #include #include #include diff --git a/src/kernel/event.c b/src/kernel/event.c index ab095a008..f1ff825f5 100644 --- a/src/kernel/event.c +++ b/src/kernel/event.c @@ -21,7 +21,7 @@ OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. #include "attrib.h" /* util includes */ -#include +#include #include #include diff --git a/src/kernel/faction.c b/src/kernel/faction.c index dea4ca54f..a78cd943a 100755 --- a/src/kernel/faction.c +++ b/src/kernel/faction.c @@ -45,7 +45,7 @@ OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. #include #include #include -#include +#include #include #include #include diff --git a/src/util/gamedata.c b/src/kernel/gamedata.c similarity index 98% rename from src/util/gamedata.c rename to src/kernel/gamedata.c index cd3fa01a7..4173332c4 100644 --- a/src/util/gamedata.c +++ b/src/kernel/gamedata.c @@ -1,7 +1,8 @@ #include #include "gamedata.h" -#include "log.h" + +#include #include #include diff --git a/src/util/gamedata.h b/src/kernel/gamedata.h similarity index 100% rename from src/util/gamedata.h rename to src/kernel/gamedata.h diff --git a/src/util/gamedata.test.c b/src/kernel/gamedata.test.c similarity index 100% rename from src/util/gamedata.test.c rename to src/kernel/gamedata.test.c diff --git a/src/kernel/group.c b/src/kernel/group.c index 9ebbf244d..54aa87aeb 100755 --- a/src/kernel/group.c +++ b/src/kernel/group.c @@ -32,7 +32,7 @@ OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. /* util includes */ #include #include -#include +#include #include #include #include diff --git a/src/kernel/group.test.c b/src/kernel/group.test.c index 5d1a28f6b..1c6d6339e 100644 --- a/src/kernel/group.test.c +++ b/src/kernel/group.test.c @@ -8,7 +8,7 @@ #include "region.h" #include "save.h" -#include +#include #include #include diff --git a/src/kernel/region.c b/src/kernel/region.c index 2cb93b4a3..377bf1e22 100644 --- a/src/kernel/region.c +++ b/src/kernel/region.c @@ -43,7 +43,7 @@ OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. /* util includes */ #include #include -#include +#include #include #include #include diff --git a/src/kernel/save.c b/src/kernel/save.c index eb731e8d7..3bef185c3 100644 --- a/src/kernel/save.c +++ b/src/kernel/save.c @@ -61,9 +61,9 @@ OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. #include #include #include -#include +#include #include -#include +#include #include #include #include diff --git a/src/kernel/save.test.c b/src/kernel/save.test.c index 04ef9b1bb..8e738863f 100644 --- a/src/kernel/save.test.c +++ b/src/kernel/save.test.c @@ -20,7 +20,7 @@ #include #include #include -#include +#include #include #include #include diff --git a/src/kernel/spellbook.c b/src/kernel/spellbook.c index 868f9757c..d230992cf 100644 --- a/src/kernel/spellbook.c +++ b/src/kernel/spellbook.c @@ -4,7 +4,7 @@ #include #include -#include +#include #include #include "spellbook.h" diff --git a/src/kernel/unit.c b/src/kernel/unit.c index 13b2b1bf2..00d0aeece 100644 --- a/src/kernel/unit.c +++ b/src/kernel/unit.c @@ -53,7 +53,7 @@ OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. #include #include #include -#include +#include #include #include #include diff --git a/src/magic.c b/src/magic.c index 41aa0dbce..047ed167b 100644 --- a/src/magic.c +++ b/src/magic.c @@ -65,7 +65,7 @@ OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. #include #include #include -#include +#include #include #include #include diff --git a/src/modules/gmcmd.c b/src/modules/gmcmd.c index 56386f2a6..4cc573f16 100644 --- a/src/modules/gmcmd.c +++ b/src/modules/gmcmd.c @@ -33,7 +33,7 @@ /* util includes */ #include -#include +#include #include #include diff --git a/src/modules/museum.c b/src/modules/museum.c index b5cbf05ce..7e3a04f2d 100644 --- a/src/modules/museum.c +++ b/src/modules/museum.c @@ -41,7 +41,7 @@ OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. #include #include #include -#include +#include #include #include #include diff --git a/src/modules/xmas.c b/src/modules/xmas.c index b4fd2cd24..aa296866a 100644 --- a/src/modules/xmas.c +++ b/src/modules/xmas.c @@ -28,7 +28,7 @@ #include #include #include -#include +#include #include #include diff --git a/src/move.c b/src/move.c index b633d0ff7..8de997480 100644 --- a/src/move.c +++ b/src/move.c @@ -74,7 +74,7 @@ OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. #include #include #include -#include +#include #include #include #include diff --git a/src/spells.c b/src/spells.c index 1238c1dae..00f256f26 100644 --- a/src/spells.c +++ b/src/spells.c @@ -73,7 +73,7 @@ #include #include #include -#include +#include #include #include #include diff --git a/src/spells/borders.c b/src/spells/borders.c index ff15ea971..5d99b1307 100644 --- a/src/spells/borders.c +++ b/src/spells/borders.c @@ -14,7 +14,7 @@ #include #include -#include +#include #include #include #include diff --git a/src/spells/flyingship.c b/src/spells/flyingship.c index e23f6906b..2b830da2e 100644 --- a/src/spells/flyingship.c +++ b/src/spells/flyingship.c @@ -11,7 +11,7 @@ #include #include -#include +#include #include diff --git a/src/spells/unitcurse.c b/src/spells/unitcurse.c index a99eb082c..d0b381050 100644 --- a/src/spells/unitcurse.c +++ b/src/spells/unitcurse.c @@ -23,7 +23,7 @@ #include /* util includes */ -#include +#include #include #include #include diff --git a/src/triggers/changefaction.c b/src/triggers/changefaction.c index 44edec269..8aa73168d 100644 --- a/src/triggers/changefaction.c +++ b/src/triggers/changefaction.c @@ -27,7 +27,7 @@ OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. #include #include #include -#include +#include #include #include #include diff --git a/src/triggers/changerace.c b/src/triggers/changerace.c index 758df4dc6..5a834314a 100644 --- a/src/triggers/changerace.c +++ b/src/triggers/changerace.c @@ -27,7 +27,7 @@ OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. #include #include #include -#include +#include #include #include #include diff --git a/src/triggers/clonedied.c b/src/triggers/clonedied.c index 5713a2b6c..c6593c2a4 100644 --- a/src/triggers/clonedied.c +++ b/src/triggers/clonedied.c @@ -29,7 +29,7 @@ OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. #include #include #include -#include +#include #include #include #include diff --git a/src/triggers/createcurse.c b/src/triggers/createcurse.c index 666c82a0f..544b9aafe 100644 --- a/src/triggers/createcurse.c +++ b/src/triggers/createcurse.c @@ -27,7 +27,7 @@ OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. #include #include #include -#include +#include #include #include #include diff --git a/src/triggers/createunit.c b/src/triggers/createunit.c index 4ce2730dc..d4dd8f983 100644 --- a/src/triggers/createunit.c +++ b/src/triggers/createunit.c @@ -29,7 +29,7 @@ OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. #include #include #include -#include +#include #include #include #include diff --git a/src/triggers/gate.c b/src/triggers/gate.c index 8690d5752..065be8cf8 100644 --- a/src/triggers/gate.c +++ b/src/triggers/gate.c @@ -20,7 +20,7 @@ /* util includes */ #include #include -#include +#include #include #include #include diff --git a/src/triggers/giveitem.c b/src/triggers/giveitem.c index 7815350a1..118497c86 100644 --- a/src/triggers/giveitem.c +++ b/src/triggers/giveitem.c @@ -27,7 +27,7 @@ OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. #include #include #include -#include +#include #include #include #include diff --git a/src/triggers/killunit.c b/src/triggers/killunit.c index 37e55b25b..0338da4af 100644 --- a/src/triggers/killunit.c +++ b/src/triggers/killunit.c @@ -26,7 +26,7 @@ OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. #include #include #include -#include +#include #include #include #include diff --git a/src/triggers/shock.c b/src/triggers/shock.c index 767f0fd17..9a9d1c74b 100644 --- a/src/triggers/shock.c +++ b/src/triggers/shock.c @@ -32,7 +32,7 @@ OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. #include #include #include -#include +#include #include #include #include diff --git a/src/triggers/timeout.c b/src/triggers/timeout.c index 8acaaa38b..8e8a6b9bf 100644 --- a/src/triggers/timeout.c +++ b/src/triggers/timeout.c @@ -22,7 +22,7 @@ OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. /* util includes */ #include #include -#include +#include #include #include diff --git a/src/util/CMakeLists.txt b/src/util/CMakeLists.txt index d0e505af2..4258a5edc 100644 --- a/src/util/CMakeLists.txt +++ b/src/util/CMakeLists.txt @@ -9,7 +9,6 @@ base36.test.c # dice.test.c # filereader.test.c functions.test.c -gamedata.test.c # goodies.test.c language.test.c # lists.test.c @@ -37,7 +36,6 @@ crmessage.c dice.c filereader.c functions.c -gamedata.c goodies.c language.c lists.c diff --git a/src/vortex.c b/src/vortex.c index 948ad80fc..805b407c4 100644 --- a/src/vortex.c +++ b/src/vortex.c @@ -5,7 +5,7 @@ #include #include -#include +#include #include #include #include diff --git a/src/wormhole.c b/src/wormhole.c index 5cf044d92..382e64d16 100644 --- a/src/wormhole.c +++ b/src/wormhole.c @@ -25,7 +25,7 @@ /* util includes */ #include -#include +#include #include #include #include diff --git a/tests/orders.txt b/tests/orders.txt deleted file mode 100644 index a4a4f7456..000000000 --- a/tests/orders.txt +++ /dev/null @@ -1,3 +0,0 @@ -ERESSEA uhfr "Hodor" -EINHEIT 8bz3 -BENENNEN EINHEIT 'Goldene Herde' From 991fe8fd8da2e8b0d466b0941360561cbdce798f Mon Sep 17 00:00:00 2001 From: Enno Rehling Date: Sat, 29 Sep 2018 13:35:49 +0200 Subject: [PATCH 048/160] enable checker build. remove getid aliases from parser.h --- src/CMakeLists.txt | 4 ++-- src/checker.c | 4 ++-- src/kernel/build.c | 2 +- src/laws.c | 2 +- src/move.c | 4 ++-- src/util/parser.h | 3 --- 6 files changed, 8 insertions(+), 11 deletions(-) diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt index be26a30a4..e6b83cfe1 100644 --- a/src/CMakeLists.txt +++ b/src/CMakeLists.txt @@ -191,8 +191,8 @@ target_link_libraries(parser ) -#add_executable(checker ${CHECK_SRC}) -#target_link_libraries(checker parser) +add_executable(checker ${CHECK_SRC}) +target_link_libraries(checker parser) add_library(game ${ERESSEA_SRC}) target_link_libraries(game parser version) diff --git a/src/checker.c b/src/checker.c index 1a07897a0..302c80390 100644 --- a/src/checker.c +++ b/src/checker.c @@ -2,8 +2,9 @@ #include #endif +#include "util/parser.h" + #include -#include "orderfile.h" int main(int argc, char **argv) { FILE * F = stdin; @@ -14,7 +15,6 @@ int main(int argc, char **argv) { perror(filename); return -1; } - readorders(F); fclose(F); } return 0; diff --git a/src/kernel/build.c b/src/kernel/build.c index 0891f1005..82c629b0b 100644 --- a/src/kernel/build.c +++ b/src/kernel/build.c @@ -79,7 +79,7 @@ struct building *getbuilding(const struct region *r) ship *getship(const struct region * r) { - ship *sh, *sx = findship(getshipid()); + ship *sh, *sx = findship(getid()); for (sh = r->ships; sh; sh = sh->next) { if (sh == sx) return sh; diff --git a/src/laws.c b/src/laws.c index d7f8c53de..67e4567a9 100644 --- a/src/laws.c +++ b/src/laws.c @@ -1952,7 +1952,7 @@ int mail_cmd(unit * u, struct order *ord) } case P_FACTION: - n = getfactionid(); + n = getid(); for (u2 = r->units; u2; u2 = u2->next) { if (u2->faction->no == n && seefaction(u->faction, r, u2, 0)) { diff --git a/src/move.c b/src/move.c index 8de997480..124b846ca 100644 --- a/src/move.c +++ b/src/move.c @@ -2265,7 +2265,7 @@ int follow_ship(unit * u, order * ord) return 0; } - id = getshipid(); + id = getid(); if (id <= 0) { cmistake(u, ord, 20, MSG_MOVE); @@ -2549,7 +2549,7 @@ void follow_unit(unit * u) } } else if (p == P_SHIP) { - id = getshipid(); + id = getid(); if (id <= 0) { /* cmistake(u, ord, 20, MSG_MOVE); */ } diff --git a/src/util/parser.h b/src/util/parser.h index 7242da1bb..a540aa2ac 100644 --- a/src/util/parser.h +++ b/src/util/parser.h @@ -33,9 +33,6 @@ extern "C" { int getid(void); unsigned int atoip(const char *s); -#define getshipid() getid() -#define getfactionid() getid() - #ifdef __cplusplus } #endif From bc5f2ea6d1c83db0325d1b2538a4d0d30f2c220f Mon Sep 17 00:00:00 2001 From: Enno Rehling Date: Sat, 29 Sep 2018 18:13:32 +0200 Subject: [PATCH 049/160] move keyword.[hc] to util --- src/CMakeLists.txt | 2 -- src/automate.c | 2 +- src/battle.test.c | 2 +- src/bind_process.c | 18 ++++++++++-------- src/creport.test.c | 2 +- src/items.c | 2 +- src/jsonconf.c | 2 +- src/jsonconf.test.c | 2 +- src/kernel/config.c | 5 +++-- src/kernel/order.c | 2 +- src/kernel/order.h | 3 ++- src/laws.c | 2 +- src/monsters.c | 8 ++++---- src/piracy.c | 4 ++-- src/util/CMakeLists.txt | 4 ++++ src/{ => util}/keyword.c | 0 src/{ => util}/keyword.h | 0 src/{ => util}/keyword.test.c | 0 src/util/order_parser.c | 33 +++++++++++++++++++++++++++++++++ src/util/order_parser.h | 34 ++++++++++++++++++++++++++++++++++ src/util/parser.c | 2 ++ 21 files changed, 102 insertions(+), 27 deletions(-) rename src/{ => util}/keyword.c (100%) rename src/{ => util}/keyword.h (100%) rename src/{ => util}/keyword.test.c (100%) create mode 100644 src/util/order_parser.c create mode 100644 src/util/order_parser.h diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt index e6b83cfe1..9ed0011e6 100644 --- a/src/CMakeLists.txt +++ b/src/CMakeLists.txt @@ -109,7 +109,6 @@ set (ERESSEA_SRC items.c json.c jsonconf.c - keyword.c laws.c lighthouse.c magic.c @@ -224,7 +223,6 @@ set(TESTS_SRC guard.test.c json.test.c jsonconf.test.c - keyword.test.c laws.test.c lighthouse.test.c magic.test.c diff --git a/src/automate.c b/src/automate.c index 6af40d649..530b9ee39 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" diff --git a/src/battle.test.c b/src/battle.test.c index 8cfbb0d2a..a2ea561d4 100644 --- a/src/battle.test.c +++ b/src/battle.test.c @@ -3,7 +3,6 @@ #include "battle.h" #include "guard.h" -#include "keyword.h" #include "reports.h" #include "skill.h" @@ -22,6 +21,7 @@ #include #include +#include "util/keyword.h" #include #include #include diff --git a/src/bind_process.c b/src/bind_process.c index 58f90076f..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 diff --git a/src/creport.test.c b/src/creport.test.c index bacf8def0..6bd5bfba8 100644 --- a/src/creport.test.c +++ b/src/creport.test.c @@ -3,7 +3,6 @@ #include "move.h" #include "spy.h" #include "travelthru.h" -#include "keyword.h" #include #include @@ -17,6 +16,7 @@ #include #include +#include "util/keyword.h" #include #include #include diff --git a/src/items.c b/src/items.c index 665220e8f..72bd6d713 100644 --- a/src/items.c +++ b/src/items.c @@ -5,7 +5,6 @@ #include "alchemy.h" #include "skill.h" -#include "keyword.h" #include "direction.h" #include "study.h" #include "economy.h" @@ -35,6 +34,7 @@ #include #include +#include #include #include #include diff --git a/src/jsonconf.c b/src/jsonconf.c index dc11ee563..ff442f990 100644 --- a/src/jsonconf.c +++ b/src/jsonconf.c @@ -32,6 +32,7 @@ without prior permission by the authors of Eressea. #include "kernel/attrib.h" #include "util/crmessage.h" #include "util/functions.h" +#include "util/keyword.h" #include "util/language.h" #include "util/log.h" #include "util/message.h" @@ -42,7 +43,6 @@ without prior permission by the authors of Eressea. /* game modules */ #include "direction.h" -#include "keyword.h" #include "move.h" #include "prefix.h" #include "skill.h" diff --git a/src/jsonconf.test.c b/src/jsonconf.test.c index 9e0e8f6b6..1fc27d3e6 100644 --- a/src/jsonconf.test.c +++ b/src/jsonconf.test.c @@ -15,11 +15,11 @@ #include "kernel/order.h" #include "kernel/terrain.h" +#include "util/keyword.h" #include "util/language.h" #include "kernel/calendar.h" #include "direction.h" -#include "keyword.h" #include "move.h" #include "prefix.h" diff --git a/src/kernel/config.c b/src/kernel/config.c index e31564b8d..842324fe8 100644 --- a/src/kernel/config.c +++ b/src/kernel/config.c @@ -33,7 +33,6 @@ OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. #include "faction.h" #include "group.h" #include "item.h" -#include "keyword.h" #include "messages.h" #include "move.h" #include "objtypes.h" @@ -51,9 +50,11 @@ OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. /* util includes */ #include +#include + #include #include -#include +#include #include #include #include diff --git a/src/kernel/order.c b/src/kernel/order.c index e30ea6097..6015b823d 100644 --- a/src/kernel/order.c +++ b/src/kernel/order.c @@ -15,9 +15,9 @@ #include "order.h" #include "skill.h" -#include "keyword.h" #include +#include "util/keyword.h" #include #include #include diff --git a/src/kernel/order.h b/src/kernel/order.h index c5406b39e..ca57d0179 100644 --- a/src/kernel/order.h +++ b/src/kernel/order.h @@ -13,7 +13,8 @@ #ifndef KRNL_ORDER_H #define KRNL_ORDER_H -#include "keyword.h" +#include + #include #include diff --git a/src/laws.c b/src/laws.c index 67e4567a9..8cec1e51b 100644 --- a/src/laws.c +++ b/src/laws.c @@ -29,7 +29,6 @@ OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. #include "automate.h" #include "battle.h" #include "economy.h" -#include "keyword.h" #include "market.h" #include "morale.h" #include "monsters.h" @@ -75,6 +74,7 @@ OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. #include #include #include +#include "util/keyword.h" #include #include #include diff --git a/src/monsters.c b/src/monsters.c index 505c6c272..867d601c6 100644 --- a/src/monsters.c +++ b/src/monsters.c @@ -27,17 +27,18 @@ #include "give.h" #include "guard.h" #include "laws.h" -#include "keyword.h" #include "study.h" #include "move.h" /* kernel includes */ +#include "kernel/attrib.h" #include "kernel/build.h" #include "kernel/building.h" #include "kernel/calendar.h" #include "kernel/config.h" #include "kernel/curse.h" #include "kernel/equipment.h" +#include "kernel/event.h" #include "kernel/faction.h" #include "kernel/item.h" #include "kernel/messages.h" @@ -52,10 +53,9 @@ #include "kernel/unit.h" /* util includes */ -#include #include -#include -#include +#include "util/keyword.h" +#include "util/language.h" #include #include #include diff --git a/src/piracy.c b/src/piracy.c index 86b9b4904..b7307c070 100644 --- a/src/piracy.c +++ b/src/piracy.c @@ -2,10 +2,10 @@ #include "piracy.h" #include "direction.h" -#include "keyword.h" #include "move.h" #include +#include #include #include #include @@ -15,9 +15,9 @@ #include #include -#include #include #include +#include "util/keyword.h" #include #include #include diff --git a/src/util/CMakeLists.txt b/src/util/CMakeLists.txt index 4258a5edc..61e2cf745 100644 --- a/src/util/CMakeLists.txt +++ b/src/util/CMakeLists.txt @@ -10,11 +10,13 @@ base36.test.c # filereader.test.c functions.test.c # goodies.test.c +keyword.test.c language.test.c # lists.test.c # log.test.c message.test.c # nrmessage.test.c +# order_parser.test.c parser.test.c password.test.c # rand.test.c @@ -37,12 +39,14 @@ dice.c filereader.c functions.c goodies.c +keyword.c language.c lists.c log.c message.c mt19937ar.c nrmessage.c +order_parser.c parser.c password.c path.c diff --git a/src/keyword.c b/src/util/keyword.c similarity index 100% rename from src/keyword.c rename to src/util/keyword.c diff --git a/src/keyword.h b/src/util/keyword.h similarity index 100% rename from src/keyword.h rename to src/util/keyword.h diff --git a/src/keyword.test.c b/src/util/keyword.test.c similarity index 100% rename from src/keyword.test.c rename to src/util/keyword.test.c diff --git a/src/util/order_parser.c b/src/util/order_parser.c new file mode 100644 index 000000000..691686276 --- /dev/null +++ b/src/util/order_parser.c @@ -0,0 +1,33 @@ +#ifdef _MSC_VER +#include +#endif + +#include "order_parser.h" + +#include + +struct OrderParserStruct { + void *m_userData; + char *m_buffer; + char *m_bufferPtr; + const char *m_bufferEnd; + OP_FactionHandler m_factionHandler; + OP_UnitHandler m_unitHandler; + OP_OrderHandler m_orderHandler; + enum CR_Error m_errorCode; + int m_lineNumber; +}; + +OP_Parser OP_ParserCreate(void) +{ + return NULL; +} + +void OP_ParserFree(OP_Parser op) { + free(op); +} + +enum OP_Status OP_Parse(OP_Parser op, const char *s, int len, int isFinal) +{ + return OP_STATUS_OK; +} diff --git a/src/util/order_parser.h b/src/util/order_parser.h new file mode 100644 index 000000000..ee98b72a6 --- /dev/null +++ b/src/util/order_parser.h @@ -0,0 +1,34 @@ +#pragma once +/* + * +-------------------+ Christian Schlittchen + * | | Enno Rehling + * | Eressea PBEM host | Katja Zedel + * | (c) 1998 - 2007 | + * | | This program may not be used, modified or distributed + * +-------------------+ without prior permission by the authors of Eressea. + * + */ + +#ifndef UTIL_ORDER_PARSER_H +#define UTIL_ORDER_PARSER_H + +#include +#include + +struct OrderParserStruct; +typedef struct OrderParserStruct *OP_Parser; + +enum OP_Status { + OP_STATUS_ERROR = 0, + OP_STATUS_OK = 1 +}; + +typedef void(*OP_FactionHandler) (void *userData, int no, const char *password); +typedef void(*OP_UnitHandler) (void *userData, int no); +typedef void(*OP_OrderHandler) (void *userData, const char *str, size_t len); + +OP_Parser OP_ParserCreate(void); +void OP_ParserFree(OP_Parser op); +enum OP_Status OP_Parse(OP_Parser op, const char *s, int len, int isFinal); + +#endif diff --git a/src/util/parser.c b/src/util/parser.c index 1ba913c2c..edcb5e3d6 100644 --- a/src/util/parser.c +++ b/src/util/parser.c @@ -1,4 +1,6 @@ +#ifdef _MSC_VER #include +#endif #include "parser.h" #include "unicode.h" #include "base36.h" From d3a37179efd165d5ebb0c92d39346519ae3d0348 Mon Sep 17 00:00:00 2001 From: Enno Rehling Date: Sat, 29 Sep 2018 19:32:39 +0200 Subject: [PATCH 050/160] add param.[hc], at last. --- src/economy.c | 8 ++- src/give.c | 5 +- src/give.test.c | 1 + src/kernel/build.c | 7 +- src/kernel/build.test.c | 23 ++++--- src/kernel/building.c | 1 + src/kernel/config.c | 132 +------------------------------------- src/kernel/config.h | 9 --- src/kernel/config.test.c | 5 +- src/kernel/order.c | 1 + src/kernel/order.test.c | 1 + src/kernel/ship.c | 1 + src/kernel/types.h | 54 ---------------- src/kernel/unit.c | 15 ++--- src/laws.c | 13 +++- src/laws.h | 5 +- src/laws.test.c | 1 + src/magic.c | 1 + src/move.c | 5 +- src/orderfile.c | 25 +++++--- src/renumber.c | 5 +- src/renumber.test.c | 1 + src/report.c | 7 +- src/reports.test.c | 2 +- src/skill.c | 2 + src/spy.c | 3 +- src/spy.test.c | 2 + src/study.c | 3 +- src/tests.c | 6 +- src/tests.h | 5 +- src/util/CMakeLists.txt | 2 + src/util/keyword.h | 1 - src/util/param.c | 134 +++++++++++++++++++++++++++++++++++++++ src/util/param.h | 77 ++++++++++++++++++++++ 34 files changed, 317 insertions(+), 246 deletions(-) create mode 100644 src/util/param.c create mode 100644 src/util/param.h diff --git a/src/economy.c b/src/economy.c index 15b907a25..1d3f6685f 100644 --- a/src/economy.c +++ b/src/economy.c @@ -20,7 +20,7 @@ OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. #ifdef _MSC_VER #include #endif -#include + #include "economy.h" #include "alchemy.h" @@ -45,10 +45,13 @@ OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. /* kernel includes */ #include "kernel/ally.h" +#include "kernel/attrib.h" #include "kernel/building.h" #include "kernel/calendar.h" +#include "kernel/config.h" #include "kernel/curse.h" #include "kernel/equipment.h" +#include "kernel/event.h" #include "kernel/faction.h" #include "kernel/item.h" #include "kernel/messages.h" @@ -64,13 +67,12 @@ OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. #include "kernel/unit.h" /* util includes */ -#include #include -#include #include #include #include #include +#include "util/param.h" #include #include diff --git a/src/give.c b/src/give.c index 02d5c622d..4b1dbb0ac 100644 --- a/src/give.c +++ b/src/give.c @@ -25,6 +25,8 @@ #include /* kernel includes */ +#include +#include #include #include #include @@ -41,11 +43,10 @@ #include /* util includes */ -#include #include -#include #include #include +#include #include /* libc includes */ diff --git a/src/give.test.c b/src/give.test.c index 9c07c8cd0..06c0ecf96 100644 --- a/src/give.test.c +++ b/src/give.test.c @@ -16,6 +16,7 @@ #include #include #include +#include #include #include diff --git a/src/kernel/build.c b/src/kernel/build.c index 82c629b0b..a3b1c0e50 100644 --- a/src/kernel/build.c +++ b/src/kernel/build.c @@ -33,10 +33,12 @@ OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. /* kernel includes */ #include #include -#include +#include #include #include +#include #include +#include #include #include #include @@ -52,12 +54,11 @@ OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. #include /* from libutil */ -#include #include -#include #include #include #include +#include #include #include diff --git a/src/kernel/build.test.c b/src/kernel/build.test.c index 9bae742c2..2607b2dfb 100644 --- a/src/kernel/build.test.c +++ b/src/kernel/build.test.c @@ -1,19 +1,24 @@ +#ifdef _MSC_VER #include -#include +#endif -#include #include "alchemy.h" -#include "types.h" #include "build.h" -#include "guard.h" -#include "order.h" -#include "unit.h" #include "building.h" +#include "config.h" #include "faction.h" -#include "region.h" -#include "race.h" +#include "guard.h" #include "item.h" -#include +#include "messages.h" +#include "order.h" +#include "race.h" +#include "region.h" +#include "types.h" +#include "unit.h" + +#include "util/language.h" +#include "util/param.h" + #include #include diff --git a/src/kernel/building.c b/src/kernel/building.c index 215c304e7..d97085345 100644 --- a/src/kernel/building.c +++ b/src/kernel/building.c @@ -45,6 +45,7 @@ OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. #include #include #include +#include #include #include #include diff --git a/src/kernel/config.c b/src/kernel/config.c index 842324fe8..75601e831 100644 --- a/src/kernel/config.c +++ b/src/kernel/config.c @@ -60,6 +60,7 @@ OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. #include #include #include +#include #include #include #include @@ -92,54 +93,6 @@ OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. #endif struct settings global; -const char *parameters[MAXPARAMS] = { - "LOCALE", - "ALLES", - "JEDEM", - "BAUERN", - "BURG", - "EINHEIT", - "PRIVAT", - "HINTEN", - "KOMMANDO", - "KRAEUTER", - "NICHT", - "NAECHSTER", - "PARTEI", - "ERESSEA", - "PERSONEN", - "REGION", - "SCHIFF", - "SILBER", - "STRASSEN", - "TEMP", - "FLIEHE", - "GEBAEUDE", - "GIB", /* HELFE GIB */ - "KAEMPFE", - "DURCHREISE", - "BEWACHE", - "ZAUBER", - "PAUSE", - "VORNE", - "AGGRESSIV", - "DEFENSIV", - "STUFE", - "HELFE", - "FREMDES", - "AURA", - "HINTER", - "VOR", - "ANZAHL", - "GEGENSTAENDE", - "TRAENKE", - "GRUPPE", - "PARTEITARNUNG", - "BAEUME", - "ALLIANZ", - "AUTO" -}; - int findoption(const char *s, const struct locale *lang) { void **tokens = get_translations(lang, UT_OPTIONS); @@ -151,78 +104,6 @@ int findoption(const char *s, const struct locale *lang) return NODIRECTION; } -param_t findparam(const char *s, const struct locale * lang) -{ - param_t result = NOPARAM; - char buffer[64]; - char * str = s ? transliterate(buffer, sizeof(buffer) - sizeof(int), s) : 0; - - if (str && *str) { - int i; - void * match; - void **tokens = get_translations(lang, UT_PARAMS); - critbit_tree *cb = (critbit_tree *)*tokens; - if (!cb) { - log_warning("no parameters defined in locale %s", locale_name(lang)); - } - else if (cb_find_prefix(cb, str, strlen(str), &match, 1, 0)) { - cb_get_kv(match, &i, sizeof(int)); - result = (param_t)i; - } - } - return result; -} - -param_t findparam_block(const char *s, const struct locale *lang, bool any_locale) -{ - param_t p; - if (!s || s[0] == '@') { - return NOPARAM; - } - p = findparam(s, lang); - if (any_locale && p==NOPARAM) { - const struct locale *loc; - for (loc=locales;loc;loc=nextlocale(loc)) { - if (loc!=lang) { - p = findparam(s, loc); - if (p==P_FACTION || p==P_GAMENAME) { - break; - } - } - } - } - return p; -} - -param_t findparam_ex(const char *s, const struct locale * lang) -{ - param_t result = findparam(s, lang); - - if (result == NOPARAM) { - const building_type *btype = findbuildingtype(s, lang); - if (btype != NULL) - return P_GEBAEUDE; - } - return (result == P_BUILDING) ? P_GEBAEUDE : result; -} - -bool isparam(const char *s, const struct locale * lang, param_t param) -{ - assert(s); - if (s[0] > '@') { - param_t p = (param == P_GEBAEUDE) ? findparam_ex(s, lang) : findparam(s, lang); - return p == param; - } - return false; -} - -param_t getparam(const struct locale * lang) -{ - char token[64]; - const char *s = gettoken(token, sizeof(token)); - return s ? findparam(s, lang) : NOPARAM; -} - /* -- Erschaffung neuer Einheiten ------------------------------ */ static const char *forbidden[] = { "t", "te", "tem", "temp", NULL }; @@ -268,17 +149,6 @@ int newcontainerid(void) return random_no; } -static const char * parameter_key(int i) -{ - assert(i < MAXPARAMS && i >= 0); - return parameters[i]; -} - -void init_parameters(struct locale *lang) { - init_translations(lang, UT_PARAMS, parameter_key, MAXPARAMS); -} - - void init_terrains_translation(const struct locale *lang) { void **tokens; const terrain_type *terrain; diff --git a/src/kernel/config.h b/src/kernel/config.h index e104d4a1a..95df10ae9 100644 --- a/src/kernel/config.h +++ b/src/kernel/config.h @@ -44,12 +44,6 @@ extern "C" { int findoption(const char *s, const struct locale *lang); - param_t findparam(const char *s, const struct locale *lang); - param_t findparam_block(const char *s, const struct locale *lang, bool any_locale); - param_t findparam_ex(const char *s, const struct locale * lang); - bool isparam(const char *s, const struct locale * lang, param_t param); - param_t getparam(const struct locale *lang); - const char * game_name(void); const char * game_mailcmd(void); int game_id(void); @@ -132,12 +126,9 @@ extern "C" { struct order *default_order(const struct locale *lang); - void init_parameters(struct locale *lang); - void free_gamedata(void); void free_config(void); - extern const char *parameters[]; extern settings global; #ifdef __cplusplus diff --git a/src/kernel/config.test.c b/src/kernel/config.test.c index e060a838e..f5d29877a 100644 --- a/src/kernel/config.test.c +++ b/src/kernel/config.test.c @@ -5,8 +5,11 @@ #include #include #include -#include + #include +#include +#include + #include #include diff --git a/src/kernel/order.c b/src/kernel/order.c index 6015b823d..c0c1e82fb 100644 --- a/src/kernel/order.c +++ b/src/kernel/order.c @@ -20,6 +20,7 @@ #include "util/keyword.h" #include #include +#include #include #include diff --git a/src/kernel/order.test.c b/src/kernel/order.test.c index c4a55177b..d1dd6a371 100644 --- a/src/kernel/order.test.c +++ b/src/kernel/order.test.c @@ -5,6 +5,7 @@ #include #include +#include "util/param.h" #include #include diff --git a/src/kernel/ship.c b/src/kernel/ship.c index 20ed49d05..6fcea4935 100644 --- a/src/kernel/ship.c +++ b/src/kernel/ship.c @@ -40,6 +40,7 @@ OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. #include #include #include +#include #include #include diff --git a/src/kernel/types.h b/src/kernel/types.h index 48a4326fa..d4f46ae8d 100644 --- a/src/kernel/types.h +++ b/src/kernel/types.h @@ -83,58 +83,6 @@ typedef enum { ST_FLEE } status_t; -/* ----------------- Parameter --------------------------------- */ - -typedef enum { - P_LOCALE, - P_ANY, - P_EACH, - P_PEASANT, - P_BUILDING, - P_UNIT, - P_PRIVAT, - P_BEHIND, - P_CONTROL, - P_HERBS, - P_NOT, - P_NEXT, - P_FACTION, - P_GAMENAME, - P_PERSON, - P_REGION, - P_SHIP, - P_MONEY, - P_ROAD, - P_TEMP, - P_FLEE, - P_GEBAEUDE, - P_GIVE, - P_FIGHT, - P_TRAVEL, - P_GUARD, - P_ZAUBER, - P_PAUSE, - P_VORNE, - P_AGGRO, - P_CHICKEN, - P_LEVEL, - P_HELP, - P_FOREIGN, - P_AURA, - P_AFTER, - P_BEFORE, - P_NUMBER, - P_ITEMS, - P_POTIONS, - P_GROUP, - P_FACTIONSTEALTH, - P_TREES, - P_ALLIANCE, - P_AUTO, - MAXPARAMS, - NOPARAM -} param_t; - typedef enum { /* Fehler und Meldungen im Report */ MSG_BATTLE, MSG_EVENT, @@ -156,8 +104,6 @@ enum { /* Message-Level */ ML_MAX }; -extern const char *parameters[MAXPARAMS]; - /* --------------- Reports Typen ------------------------------- */ enum { diff --git a/src/kernel/unit.c b/src/kernel/unit.c index 00d0aeece..9b6c3e9ee 100644 --- a/src/kernel/unit.c +++ b/src/kernel/unit.c @@ -21,12 +21,16 @@ OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. #include "unit.h" #include "ally.h" +#include "attrib.h" #include "building.h" #include "calendar.h" -#include "faction.h" -#include "group.h" #include "connection.h" #include "curse.h" +#include "event.h" +#include "faction.h" +#include "gamedata.h" +#include "group.h" +#include "guard.h" #include "item.h" #include "move.h" #include "order.h" @@ -47,18 +51,13 @@ OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. #include #include -#include "guard.h" - /* util includes */ -#include #include -#include -#include -#include #include #include #include #include +#include #include #include #include diff --git a/src/laws.c b/src/laws.c index 8cec1e51b..7e2250a59 100644 --- a/src/laws.c +++ b/src/laws.c @@ -80,6 +80,7 @@ OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. #include #include #include +#include #include #include #include @@ -127,7 +128,17 @@ OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. #define DMRISE 0.1F /* weekly chance that demand goes up */ #define DMRISEHAFEN 0.2F /* weekly chance that demand goes up with harbor */ -/* - exported global symbols ----------------------------------- */ +param_t findparam_ex(const char *s, const struct locale * lang) +{ + param_t result = findparam(s, lang); + + if (result == NOPARAM) { + const building_type *btype = findbuildingtype(s, lang); + if (btype != NULL) + return P_GEBAEUDE; + } + return (result == P_BUILDING) ? P_GEBAEUDE : result; +} int NewbieImmunity(void) { diff --git a/src/laws.h b/src/laws.h index 383b099ae..c30479b38 100755 --- a/src/laws.h +++ b/src/laws.h @@ -19,13 +19,14 @@ OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. #ifndef H_GC_LAWS #define H_GC_LAWS -#include #include #ifdef __cplusplus extern "C" { #endif + enum param_t; + struct locale; struct unit; struct region; struct building; @@ -115,6 +116,8 @@ extern "C" { bool IsImmune(const struct faction *f); bool help_enter(struct unit *uo, struct unit *u); + enum param_t findparam_ex(const char *s, const struct locale * lang); + #ifdef __cplusplus } #endif diff --git a/src/laws.test.c b/src/laws.test.c index 5c799a393..774ed6ecf 100644 --- a/src/laws.test.c +++ b/src/laws.test.c @@ -24,6 +24,7 @@ #include #include #include +#include #include #include diff --git a/src/magic.c b/src/magic.c index 047ed167b..99a9ecf86 100644 --- a/src/magic.c +++ b/src/magic.c @@ -70,6 +70,7 @@ OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. #include #include #include +#include #include #include #include diff --git a/src/move.c b/src/move.c index 124b846ca..222588651 100644 --- a/src/move.c +++ b/src/move.c @@ -23,6 +23,7 @@ OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. /* kernel includes */ #include "kernel/ally.h" +#include "kernel/attrib.h" #include "kernel/build.h" #include "kernel/building.h" #include "kernel/calendar.h" @@ -30,6 +31,7 @@ OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. #include "kernel/connection.h" #include "kernel/curse.h" #include "kernel/faction.h" +#include "kernel/gamedata.h" #include "kernel/item.h" #include "kernel/messages.h" #include "kernel/order.h" @@ -72,13 +74,12 @@ OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. /* util includes */ #include -#include #include -#include #include #include #include #include +#include #include #include #include diff --git a/src/orderfile.c b/src/orderfile.c index a2c7a6c87..97008f4db 100644 --- a/src/orderfile.c +++ b/src/orderfile.c @@ -1,5 +1,4 @@ #include -#include #include "orderfile.h" #include "kernel/calendar.h" @@ -8,12 +7,14 @@ #include "kernel/order.h" #include "kernel/unit.h" -#include -#include -#include -#include -#include -#include +#include "util/base36.h" +#include "util/message.h" +#include "util/language.h" +#include "util/log.h" +#include "util/filereader.h" +#include "util/param.h" +#include "util/parser.h" +#include "util/order_parser.h" #include #include @@ -33,9 +34,9 @@ static unit *unitorders(input *in, faction *f) if (u && u->faction == f) { order **ordp; - if (!fval(u, UFL_ORDERS)) { + if (u->flags & UFL_ORDERS) { /* alle wiederholbaren, langen befehle werden gesichert: */ - fset(u, UFL_ORDERS); + u->flags |= UFL_ORDERS; u->old_orders = u->orders; ordp = &u->old_orders; while (*ordp) { @@ -125,7 +126,7 @@ static faction *factionorders(void) int fid = getid(); faction *f = findfaction(fid); - if (f != NULL && !fval(f, FFL_NPC)) { + if (f != NULL && (f->flags & FFL_NPC) == 0) { char token[128]; const char *pass = gettoken(token, sizeof(token)); @@ -151,6 +152,10 @@ int read_orders(input *in) int nfactions = 0; struct faction *f = NULL; const struct locale *lang = default_locale; + OP_Parser parser; + + parser = OP_ParserCreate(); + OP_ParserFree(parser); /* TODO: recognize UTF8 BOM */ b = in->getbuf(in->data); diff --git a/src/renumber.c b/src/renumber.c index 8a72be2a5..a4653e1a0 100644 --- a/src/renumber.c +++ b/src/renumber.c @@ -1,6 +1,9 @@ #include #include "renumber.h" +#include "laws.h" + +#include #include #include #include @@ -9,8 +12,8 @@ #include #include -#include #include +#include #include #include diff --git a/src/renumber.test.c b/src/renumber.test.c index 98ca9b48b..8d44b92da 100644 --- a/src/renumber.test.c +++ b/src/renumber.test.c @@ -10,6 +10,7 @@ #include #include #include +#include #include #include diff --git a/src/report.c b/src/report.c index bc47cb1a4..1d40941c4 100644 --- a/src/report.c +++ b/src/report.c @@ -19,7 +19,6 @@ OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. #ifdef _MSC_VER #include #endif -#include #include "report.h" #include "reports.h" @@ -50,8 +49,11 @@ OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. #include "teleport.h" /* kernel includes */ +#include "kernel/alliance.h" #include "kernel/ally.h" +#include "kernel/attrib.h" #include "kernel/calendar.h" +#include "kernel/config.h" #include "kernel/connection.h" #include "kernel/build.h" #include "kernel/building.h" @@ -74,10 +76,8 @@ OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. #include "kernel/terrain.h" #include "kernel/terrainid.h" #include "kernel/unit.h" -#include "kernel/alliance.h" /* util includes */ -#include #include #include "util/bsdstring.h" #include @@ -86,6 +86,7 @@ OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. #include #include #include +#include "util/param.h" #include #include diff --git a/src/reports.test.c b/src/reports.test.c index 29f14c634..0f5ca6b1f 100644 --- a/src/reports.test.c +++ b/src/reports.test.c @@ -2,7 +2,7 @@ #include "reports.h" #include "guard.h" -#include "keyword.h" +#include "util/keyword.h" #include "lighthouse.h" #include "laws.h" #include "move.h" diff --git a/src/skill.c b/src/skill.c index b279ab488..3d91a2598 100644 --- a/src/skill.c +++ b/src/skill.c @@ -5,6 +5,8 @@ #include #include #include +#include + #include #include diff --git a/src/spy.c b/src/spy.c index 98245e806..53a5b4321 100644 --- a/src/spy.c +++ b/src/spy.c @@ -27,6 +27,7 @@ OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. #include "study.h" /* kernel includes */ +#include #include #include #include @@ -44,8 +45,8 @@ OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. #include /* util includes */ -#include #include +#include #include #include #include diff --git a/src/spy.test.c b/src/spy.test.c index dfe2886e7..d1f616fab 100644 --- a/src/spy.test.c +++ b/src/spy.test.c @@ -12,8 +12,10 @@ #include #include #include + #include #include +#include "util/param.h" #include #include diff --git a/src/study.c b/src/study.c index a3dfa2e33..ff961dc13 100644 --- a/src/study.c +++ b/src/study.c @@ -32,6 +32,7 @@ OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. #include #include +#include #include #include #include @@ -46,10 +47,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/tests.c b/src/tests.c index 2dc5bccc6..f270d9c58 100644 --- a/src/tests.c +++ b/src/tests.c @@ -1,11 +1,10 @@ #include #include "tests.h" -#include "keyword.h" #include "prefix.h" #include "reports.h" -#include "kernel/calendar.h" #include "vortex.h" +#include "kernel/calendar.h" #include #include #include @@ -24,11 +23,14 @@ #include #include #include + #include +#include "util/keyword.h" #include #include #include #include +#include "util/param.h" #include #include diff --git a/src/tests.h b/src/tests.h index 441db9e16..0f3af1972 100644 --- a/src/tests.h +++ b/src/tests.h @@ -1,7 +1,6 @@ #ifndef ERESSEA_TESTS_H #define ERESSEA_TESTS_H -#include #include #ifdef __cplusplus @@ -10,6 +9,8 @@ extern "C" { #define ASSERT_DBL_DELTA 0.001 + enum param_t; + struct region; struct unit; struct faction; @@ -61,7 +62,7 @@ extern "C" { struct spell * test_create_spell(void); int test_set_item(struct unit * u, const struct item_type *itype, int value); - void test_translate_param(const struct locale *lang, param_t param, const char *text); + void test_translate_param(const struct locale *lang, enum param_t param, const char *text); const char * test_get_messagetype(const struct message *msg); struct message * test_find_messagetype_ex(struct message_list *msgs, const char *name, struct message *prev); struct message * test_find_messagetype(struct message_list *msgs, const char *name); diff --git a/src/util/CMakeLists.txt b/src/util/CMakeLists.txt index 61e2cf745..b4d067f57 100644 --- a/src/util/CMakeLists.txt +++ b/src/util/CMakeLists.txt @@ -17,6 +17,7 @@ language.test.c message.test.c # nrmessage.test.c # order_parser.test.c +# param.test.c parser.test.c password.test.c # rand.test.c @@ -47,6 +48,7 @@ message.c mt19937ar.c nrmessage.c order_parser.c +param.c parser.c password.c path.c diff --git a/src/util/keyword.h b/src/util/keyword.h index bd4ab02d0..7bb11c485 100644 --- a/src/util/keyword.h +++ b/src/util/keyword.h @@ -1,7 +1,6 @@ #ifndef H_KEYWORD_H #define H_KEYWORD_H -#include "kernel/types.h" #include #ifdef __cplusplus diff --git a/src/util/param.c b/src/util/param.c new file mode 100644 index 000000000..31066a4a9 --- /dev/null +++ b/src/util/param.c @@ -0,0 +1,134 @@ +#ifdef _MSC_VER +#include +#endif + +#include "language.h" +#include "log.h" +#include "param.h" +#include "parser.h" +#include "umlaut.h" + +#include + +#include +#include + +const char *parameters[MAXPARAMS] = { + "LOCALE", + "ALLES", + "JEDEM", + "BAUERN", + "BURG", + "EINHEIT", + "PRIVAT", + "HINTEN", + "KOMMANDO", + "KRAEUTER", + "NICHT", + "NAECHSTER", + "PARTEI", + "ERESSEA", + "PERSONEN", + "REGION", + "SCHIFF", + "SILBER", + "STRASSEN", + "TEMP", + "FLIEHE", + "GEBAEUDE", + "GIB", /* HELFE GIB */ + "KAEMPFE", + "DURCHREISE", + "BEWACHE", + "ZAUBER", + "PAUSE", + "VORNE", + "AGGRESSIV", + "DEFENSIV", + "STUFE", + "HELFE", + "FREMDES", + "AURA", + "HINTER", + "VOR", + "ANZAHL", + "GEGENSTAENDE", + "TRAENKE", + "GRUPPE", + "PARTEITARNUNG", + "BAEUME", + "ALLIANZ", + "AUTO" +}; + +param_t findparam(const char *s, const struct locale * lang) +{ + param_t result = NOPARAM; + char buffer[64]; + char * str = s ? transliterate(buffer, sizeof(buffer) - sizeof(int), s) : 0; + + if (str && *str) { + int i; + void * match; + void **tokens = get_translations(lang, UT_PARAMS); + critbit_tree *cb = (critbit_tree *)*tokens; + if (!cb) { + log_warning("no parameters defined in locale %s", locale_name(lang)); + } + else if (cb_find_prefix(cb, str, strlen(str), &match, 1, 0)) { + cb_get_kv(match, &i, sizeof(int)); + result = (param_t)i; + } + } + return result; +} + +param_t findparam_block(const char *s, const struct locale *lang, bool any_locale) +{ + param_t p; + if (!s || s[0] == '@') { + return NOPARAM; + } + p = findparam(s, lang); + if (any_locale && p == NOPARAM) { + const struct locale *loc; + for (loc = locales; loc; loc = nextlocale(loc)) { + if (loc != lang) { + p = findparam(s, loc); + if (p == P_FACTION || p == P_GAMENAME) { + break; + } + } + } + } + return p; +} + +bool isparam(const char *s, const struct locale * lang, param_t param) +{ + assert(s); + assert(param != P_GEBAEUDE); + assert(param != P_BUILDING); + if (s[0] > '@') { + param_t p = findparam(s, lang); + return p == param; + } + return false; +} + +param_t getparam(const struct locale * lang) +{ + char token[64]; + const char *s = gettoken(token, sizeof(token)); + return s ? findparam(s, lang) : NOPARAM; +} + +static const char * parameter_key(int i) +{ + assert(i < MAXPARAMS && i >= 0); + return parameters[i]; +} + +void init_parameters(struct locale *lang) { + init_translations(lang, UT_PARAMS, parameter_key, MAXPARAMS); +} diff --git a/src/util/param.h b/src/util/param.h new file mode 100644 index 000000000..42d34ee57 --- /dev/null +++ b/src/util/param.h @@ -0,0 +1,77 @@ +#pragma once + +#ifndef H_PARAM_H +#define H_PARAM_H + +#include + +#ifdef __cplusplus +extern "C" +{ +#endif + + struct locale; + + typedef enum param_t { + P_LOCALE, + P_ANY, + P_EACH, + P_PEASANT, + P_BUILDING, + P_UNIT, + P_PRIVAT, + P_BEHIND, + P_CONTROL, + P_HERBS, + P_NOT, + P_NEXT, + P_FACTION, + P_GAMENAME, + P_PERSON, + P_REGION, + P_SHIP, + P_MONEY, + P_ROAD, + P_TEMP, + P_FLEE, + P_GEBAEUDE, + P_GIVE, + P_FIGHT, + P_TRAVEL, + P_GUARD, + P_ZAUBER, + P_PAUSE, + P_VORNE, + P_AGGRO, + P_CHICKEN, + P_LEVEL, + P_HELP, + P_FOREIGN, + P_AURA, + P_AFTER, + P_BEFORE, + P_NUMBER, + P_ITEMS, + P_POTIONS, + P_GROUP, + P_FACTIONSTEALTH, + P_TREES, + P_ALLIANCE, + P_AUTO, + MAXPARAMS, + NOPARAM + } param_t; + + extern const char *parameters[MAXPARAMS]; + + param_t findparam(const char *s, const struct locale *lang); + param_t findparam_block(const char *s, const struct locale *lang, bool any_locale); + bool isparam(const char *s, const struct locale * lang, param_t param); + param_t getparam(const struct locale *lang); + + void init_parameters(struct locale *lang); + +#ifdef __cplusplus +} +#endif +#endif From b03da543b658dddbea4d7225f9b4a9692c4a5c5b Mon Sep 17 00:00:00 2001 From: Enno Rehling Date: Sat, 29 Sep 2018 20:06:58 +0200 Subject: [PATCH 051/160] make findparam_ex part of laws, where building names are known. --- src/kernel/building.c | 60 ++++++++++++++++++++++++++++++------------- src/laws.test.c | 22 ++++++++++++++++ src/tests.c | 4 ++- 3 files changed, 67 insertions(+), 19 deletions(-) diff --git a/src/kernel/building.c b/src/kernel/building.c index d97085345..fe28b3752 100644 --- a/src/kernel/building.c +++ b/src/kernel/building.c @@ -129,14 +129,6 @@ static void free_buildingtype(void *ptr) { free(btype); } -void free_buildingtypes(void) { - cb_clear(&cb_bldgtypes); - selist_foreach(buildingtypes, free_buildingtype); - selist_free(buildingtypes); - buildingtypes = 0; - ++bt_changes; -} - building_type *bt_get_or_create(const char *name) { assert(name && name[0]); @@ -265,17 +257,28 @@ building *findbuilding(int i) static local_names *bnames; -/* Find the building type for a given localized name (as seen by the user). Useful for parsing - * orders. The inverse of locale_string(lang, btype->_name), sort of. */ -const building_type *findbuildingtype(const char *name, - const struct locale *lang) -{ - variant type; - local_names *bn = bnames; +static void free_bnames() { + while (bnames) { + local_names *bn = bnames; + bnames = bnames->next; + freetokens(bn->names); + free(bn); + } +} +static local_names *get_bnames(const struct locale *lang) +{ + static int config; + local_names *bn; + + if (bt_changed(&config)) { + free_bnames(); + } + bn = bnames; while (bn) { - if (bn->lang == lang) + if (bn->lang == lang) { break; + } bn = bn->next; } if (!bn) { @@ -292,14 +295,26 @@ const building_type *findbuildingtype(const char *name, const char *n = LOC(lang, btype->_name); if (!n) { log_error("building type %s has no translation in %s", - btype->_name, locale_name(lang)); - } else { + btype->_name, locale_name(lang)); + } + else { + variant type; type.v = (void *)btype; addtoken((struct tnode **)&bn->names, n, type); } } bnames = bn; } + return bn; +} + +/* Find the building type for a given localized name (as seen by the user). Useful for parsing + * orders. The inverse of locale_string(lang, btype->_name), sort of. */ +const building_type *findbuildingtype(const char *name, + const struct locale *lang) +{ + variant type; + local_names *bn = get_bnames(lang); if (findtoken(bn->names, name, &type) == E_TOK_NOMATCH) return NULL; return (const building_type *)type.v; @@ -871,3 +886,12 @@ int cmp_current_owner(const building * b, const building * a) } return 0; } + +void free_buildingtypes(void) { + free_bnames(); + cb_clear(&cb_bldgtypes); + selist_foreach(buildingtypes, free_buildingtype); + selist_free(buildingtypes); + buildingtypes = 0; + ++bt_changes; +} diff --git a/src/laws.test.c b/src/laws.test.c index 774ed6ecf..bb26ed872 100644 --- a/src/laws.test.c +++ b/src/laws.test.c @@ -392,6 +392,27 @@ static void test_unit_limit(CuTest * tc) test_teardown(); } +static void test_findparam_ex(CuTest *tc) +{ + struct locale *lang; + struct building_type *btype; + test_setup(); + lang = test_create_locale(); + locale_setstring(lang, "temple", "TEMPEL"); + btype = test_create_buildingtype("temple"); + + CuAssertIntEquals(tc, P_GEBAEUDE, findparam_ex("TEMPEL", lang)); + CuAssertIntEquals(tc, P_GEBAEUDE, findparam_ex( + locale_string(lang, parameters[P_BUILDING], false), lang)); + CuAssertIntEquals(tc, P_SHIP, findparam_ex( + locale_string(lang, parameters[P_SHIP], false), lang)); + CuAssertIntEquals(tc, P_FACTION, findparam_ex( + locale_string(lang, parameters[P_FACTION], false), lang)); + CuAssertIntEquals(tc, P_UNIT, findparam_ex( + locale_string(lang, parameters[P_UNIT], false), lang)); + test_teardown(); +} + static void test_maketemp(CuTest * tc) { faction *f; @@ -1762,6 +1783,7 @@ CuSuite *get_laws_suite(void) CuSuite *suite = CuSuiteNew(); SUITE_ADD_TEST(suite, test_maketemp_default_order); SUITE_ADD_TEST(suite, test_maketemp); + SUITE_ADD_TEST(suite, test_findparam_ex); SUITE_ADD_TEST(suite, test_nmr_warnings); SUITE_ADD_TEST(suite, test_ally_cmd); SUITE_ADD_TEST(suite, test_name_cmd); diff --git a/src/tests.c b/src/tests.c index f270d9c58..cad296e57 100644 --- a/src/tests.c +++ b/src/tests.c @@ -420,7 +420,9 @@ building_type * test_create_buildingtype(const char * name) con->materials[0].rtype = get_resourcetype(R_STONE); } if (default_locale) { - locale_setstring(default_locale, name, name); + if (locale_getstring(default_locale, name) == NULL) { + locale_setstring(default_locale, name, name); + } } return btype; } From 965c8ce990d774e43644536c41c102e038d54913 Mon Sep 17 00:00:00 2001 From: Enno Rehling Date: Sat, 29 Sep 2018 21:19:24 +0200 Subject: [PATCH 052/160] start putting the new parser into the server. --- src/orderfile.c | 148 ++++++++++++++++++++++++++++++++-------- src/util/order_parser.c | 20 +++++- src/util/order_parser.h | 6 +- 3 files changed, 145 insertions(+), 29 deletions(-) diff --git a/src/orderfile.c b/src/orderfile.c index 97008f4db..a4f47a4e3 100644 --- a/src/orderfile.c +++ b/src/orderfile.c @@ -20,6 +20,32 @@ #include #include +static void begin_orders(unit *u) { + if (u->flags & UFL_ORDERS) { + order **ordp; + /* alle wiederholbaren, langen befehle werden gesichert: */ + u->flags |= UFL_ORDERS; + u->old_orders = u->orders; + ordp = &u->old_orders; + while (*ordp) { + order *ord = *ordp; + keyword_t kwd = getkeyword(ord); + if (!is_repeated(kwd)) { + *ordp = ord->next; + ord->next = NULL; + free_order(ord); + } + else { + ordp = &ord->next; + } + } + } + else { + free_orders(&u->orders); + } + u->orders = NULL; +} + static unit *unitorders(input *in, faction *f) { int i; @@ -34,29 +60,7 @@ static unit *unitorders(input *in, faction *f) if (u && u->faction == f) { order **ordp; - if (u->flags & UFL_ORDERS) { - /* alle wiederholbaren, langen befehle werden gesichert: */ - u->flags |= UFL_ORDERS; - u->old_orders = u->orders; - ordp = &u->old_orders; - while (*ordp) { - order *ord = *ordp; - keyword_t kwd = getkeyword(ord); - if (!is_repeated(kwd)) { - *ordp = ord->next; - ord->next = NULL; - free_order(ord); - } - else { - ordp = &ord->next; - } - } - } - else { - free_orders(&u->orders); - } - u->orders = 0; - + begin_orders(u); ordp = &u->orders; for (;;) { @@ -152,10 +156,6 @@ int read_orders(input *in) int nfactions = 0; struct faction *f = NULL; const struct locale *lang = default_locale; - OP_Parser parser; - - parser = OP_ParserCreate(); - OP_ParserFree(parser); /* TODO: recognize UTF8 BOM */ b = in->getbuf(in->data); @@ -231,8 +231,101 @@ static const char * file_getbuf(void *data) return getbuf(F, ENCODING_UTF8); } +typedef struct parser_state { + unit *u; + faction *f; + order **next_order; +} parser_state; + +static void handle_faction(void *userData, int no, const char *password) { + parser_state *state = (parser_state *)userData; + faction * f = state->f = findfaction(no); + if (!f) { + log_debug("orders for unknown faction %s", itoa36(no)); + } + else { + if (!checkpasswd(f, password)) { + log_debug("invalid password for faction %s", itoa36(no)); + ADDMSG(&f->msgs, msg_message("wrongpasswd", "password", password)); + } + } +} + +static void handle_unit(void *userData, int no) { + parser_state *state = (parser_state *)userData; + unit * u = findunit(no); + + state->u = NULL; + if (!u) { + /* TODO: error message */ + } + else if (u->faction != state->f) { + /* TODO: error message */ + } + else { + state->u = u; + begin_orders(u); + state->next_order = &u->orders; + } +} + +static void handle_order(void *userData, const char *str) { + parser_state *state = (parser_state *)userData; + unit * u = state->u; + order *ord; + + ord = parse_order(str, u->faction->locale); + if (ord) { + *state->next_order = ord; + state->next_order = &ord->next; + } + else { + ADDMSG(&u->faction->msgs, msg_message("parse_error", "unit command", u, str)); + } +} + + +int parseorders(FILE *F) +{ + char buf[2048]; + int done = 0, err = 0; + OP_Parser parser; + parser_state state = { NULL, NULL }; + + parser = OP_ParserCreate(); + if (!parser) { + /* TODO: error message */ + return errno; + } + OP_SetUnitHandler(parser, handle_unit); + OP_SetFactionHandler(parser, handle_faction); + OP_SetOrderHandler(parser, handle_order); + OP_SetUserData(parser, &state); + + while (!done) { + size_t len = (int)fread(buf, 1, sizeof(buf), F); + if (ferror(F)) { + /* TODO: error message */ + err = errno; + break; + } + done = feof(F); + if (OP_Parse(parser, buf, len, done) == OP_STATUS_ERROR) { + /* TODO: error message */ + err = -1; + break; + } + } + OP_ParserFree(parser); + return err; +} + int readorders(FILE *F) { +#undef NEW_PARSER +#ifdef NEW_PARSER + return parseorders(F); +#else input in; int result; @@ -240,4 +333,5 @@ int readorders(FILE *F) in.data = F; result = read_orders(&in); return result; +#endif } diff --git a/src/util/order_parser.c b/src/util/order_parser.c index 691686276..363f12c92 100644 --- a/src/util/order_parser.c +++ b/src/util/order_parser.c @@ -18,9 +18,27 @@ struct OrderParserStruct { int m_lineNumber; }; +void OP_SetUnitHandler(OP_Parser op, OP_UnitHandler handler) +{ + op->m_unitHandler = handler; +} + +void OP_SetFactionHandler(OP_Parser op, OP_FactionHandler handler) { + op->m_factionHandler = handler; +} + +void OP_SetOrderHandler(OP_Parser op, OP_OrderHandler handler) { + op->m_orderHandler = handler; +} + +void OP_SetUserData(OP_Parser op, void *userData) { + op->m_userData = userData; +} + OP_Parser OP_ParserCreate(void) { - return NULL; + OP_Parser parser = calloc(1, sizeof(struct OrderParserStruct)); + return parser; } void OP_ParserFree(OP_Parser op) { diff --git a/src/util/order_parser.h b/src/util/order_parser.h index ee98b72a6..7600ee3da 100644 --- a/src/util/order_parser.h +++ b/src/util/order_parser.h @@ -25,10 +25,14 @@ enum OP_Status { typedef void(*OP_FactionHandler) (void *userData, int no, const char *password); typedef void(*OP_UnitHandler) (void *userData, int no); -typedef void(*OP_OrderHandler) (void *userData, const char *str, size_t len); +typedef void(*OP_OrderHandler) (void *userData, const char *str); OP_Parser OP_ParserCreate(void); void OP_ParserFree(OP_Parser op); enum OP_Status OP_Parse(OP_Parser op, const char *s, int len, int isFinal); +void OP_SetUnitHandler(OP_Parser op, OP_UnitHandler handler); +void OP_SetFactionHandler(OP_Parser op, OP_FactionHandler handler); +void OP_SetOrderHandler(OP_Parser op, OP_OrderHandler handler); +void OP_SetUserData(OP_Parser op, void *userData); #endif From 4a6957378683831f7768d1ed9425c42953fb78f6 Mon Sep 17 00:00:00 2001 From: Enno Rehling Date: Sun, 30 Sep 2018 13:36:34 +0200 Subject: [PATCH 053/160] change database selection, fix in-memory db --- s/cmake-init | 35 ++++++++++++++++++++++++++++++++++- src/CMakeLists.txt | 3 +++ 2 files changed, 37 insertions(+), 1 deletion(-) diff --git a/s/cmake-init b/s/cmake-init index 781db1ea7..eea222334 100755 --- a/s/cmake-init +++ b/s/cmake-init @@ -1,13 +1,46 @@ #!/bin/sh -ERESSEA_DB=db +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/src/CMakeLists.txt b/src/CMakeLists.txt index eacc879e5..8a7edbcc4 100644 --- a/src/CMakeLists.txt +++ b/src/CMakeLists.txt @@ -179,6 +179,9 @@ endif() add_library(version STATIC ${VERSION_SRC}) add_library(game ${ERESSEA_SRC}) + +#add_executable(checker ${CHECK_SRC}) + add_executable(eressea ${SERVER_SRC}) if (IWYU_PATH) set_property(TARGET eressea PROPERTY C_INCLUDE_WHAT_YOU_USE ${IWYU_PATH}) From 0c6ec475987a589451a99786959c1aaff450f592 Mon Sep 17 00:00:00 2001 From: Enno Rehling Date: Sun, 30 Sep 2018 13:45:19 +0200 Subject: [PATCH 054/160] fix compilation --- src/kernel/building.c | 2 +- src/laws.test.c | 4 ++-- src/move.test.c | 6 +++--- src/orderfile.c | 1 + src/report.test.c | 3 ++- src/util/order_parser.c | 2 +- src/util/order_parser.h | 6 ++++++ 7 files changed, 16 insertions(+), 8 deletions(-) diff --git a/src/kernel/building.c b/src/kernel/building.c index fe28b3752..f5698eaa9 100644 --- a/src/kernel/building.c +++ b/src/kernel/building.c @@ -257,7 +257,7 @@ building *findbuilding(int i) static local_names *bnames; -static void free_bnames() { +static void free_bnames(void) { while (bnames) { local_names *bn = bnames; bnames = bnames->next; diff --git a/src/laws.test.c b/src/laws.test.c index bb26ed872..e7951a7ce 100644 --- a/src/laws.test.c +++ b/src/laws.test.c @@ -395,11 +395,11 @@ static void test_unit_limit(CuTest * tc) static void test_findparam_ex(CuTest *tc) { struct locale *lang; - struct building_type *btype; + test_setup(); lang = test_create_locale(); locale_setstring(lang, "temple", "TEMPEL"); - btype = test_create_buildingtype("temple"); + test_create_buildingtype("temple"); CuAssertIntEquals(tc, P_GEBAEUDE, findparam_ex("TEMPEL", lang)); CuAssertIntEquals(tc, P_GEBAEUDE, findparam_ex( diff --git a/src/move.test.c b/src/move.test.c index 4e9e4760d..e782bb748 100644 --- a/src/move.test.c +++ b/src/move.test.c @@ -2,12 +2,12 @@ #include #include "move.h" -#include "keyword.h" #include "lighthouse.h" -#include +#include #include #include +#include #include #include #include @@ -17,7 +17,7 @@ #include #include -#include +#include "util/keyword.h" #include #include #include diff --git a/src/orderfile.c b/src/orderfile.c index a4f47a4e3..48cc26a83 100644 --- a/src/orderfile.c +++ b/src/orderfile.c @@ -17,6 +17,7 @@ #include "util/order_parser.h" #include +#include #include #include diff --git a/src/report.test.c b/src/report.test.c index 4fa97825c..3c49b14fc 100644 --- a/src/report.test.c +++ b/src/report.test.c @@ -2,7 +2,6 @@ #include "report.h" #include "move.h" #include "travelthru.h" -#include "keyword.h" #include #include @@ -15,6 +14,8 @@ #include #include +#include "util/keyword.h" +#include "util/param.h" #include #include #include diff --git a/src/util/order_parser.c b/src/util/order_parser.c index 363f12c92..b0d6d2d10 100644 --- a/src/util/order_parser.c +++ b/src/util/order_parser.c @@ -14,7 +14,7 @@ struct OrderParserStruct { OP_FactionHandler m_factionHandler; OP_UnitHandler m_unitHandler; OP_OrderHandler m_orderHandler; - enum CR_Error m_errorCode; + enum OP_Error m_errorCode; int m_lineNumber; }; diff --git a/src/util/order_parser.h b/src/util/order_parser.h index 7600ee3da..c8f20e89e 100644 --- a/src/util/order_parser.h +++ b/src/util/order_parser.h @@ -23,6 +23,12 @@ enum OP_Status { OP_STATUS_OK = 1 }; +enum OP_Error { + OP_ERROR_NONE, + OP_ERROR_NO_MEMORY, + OP_ERROR_SYNTAX +}; + typedef void(*OP_FactionHandler) (void *userData, int no, const char *password); typedef void(*OP_UnitHandler) (void *userData, int no); typedef void(*OP_OrderHandler) (void *userData, const char *str); From f53b1f50ae7a64a0f612d690f41f6656c3889f9e Mon Sep 17 00:00:00 2001 From: Enno Rehling Date: Sun, 30 Sep 2018 14:54:13 +0200 Subject: [PATCH 055/160] cmake init after pull --- s/preview | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/s/preview b/s/preview index 39d5466d0..c4c9a5d42 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." } From fb8507e0d2fc87313006db5bd766394bb74ea07e Mon Sep 17 00:00:00 2001 From: Enno Rehling Date: Sun, 30 Sep 2018 15:02:03 +0200 Subject: [PATCH 056/160] support for non-utf8 encodings has rotted, kill it. --- src/kernel/save.c | 3 - src/orderfile.c | 2 +- src/util/filereader.c | 150 +----------------------------------------- src/util/filereader.h | 5 +- 4 files changed, 4 insertions(+), 156 deletions(-) diff --git a/src/kernel/save.c b/src/kernel/save.c index 3bef185c3..cdc951fad 100644 --- a/src/kernel/save.c +++ b/src/kernel/save.c @@ -101,9 +101,6 @@ OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. /* exported symbols symbols */ int firstx = 0, firsty = 0; -/* TODO: is this still important? */ -int enc_gamedata = ENCODING_UTF8; - static void read_alliances(gamedata *data) { storage *store = data->store; diff --git a/src/orderfile.c b/src/orderfile.c index 48cc26a83..316724338 100644 --- a/src/orderfile.c +++ b/src/orderfile.c @@ -229,7 +229,7 @@ int read_orders(input *in) static const char * file_getbuf(void *data) { FILE *F = (FILE *)data; - return getbuf(F, ENCODING_UTF8); + return getbuf(F); } typedef struct parser_state { diff --git a/src/util/filereader.c b/src/util/filereader.c index e477b445c..5ead2166f 100644 --- a/src/util/filereader.c +++ b/src/util/filereader.c @@ -39,150 +39,6 @@ static int eatwhite(const char *ptr, size_t * total_size) return ret; } -static const char *getbuf_latin1(FILE * F) -{ - bool cont = false; - char quote = 0; - bool comment = false; - char *cp = fbuf; - char *tail = lbuf + MAXLINE - 2; - - tail[1] = '@'; /* if this gets overwritten by fgets then the line was very long. */ - do { - const char *bp = fgets(lbuf, MAXLINE, F); - - if (bp == NULL) - return NULL; - while (*bp && isspace(*(unsigned char *)bp)) - ++bp; /* eatwhite */ - - comment = (bool)(comment && cont); - quote = (bool)(quote && cont); - - if (tail[1] == 0) { - /* we read he maximum number of bytes! */ - if (tail[0] != '\n') { - /* it wasn't enough space to finish the line, eat the rest */ - for (;;) { - tail[1] = '@'; - bp = fgets(lbuf, MAXLINE, F); - if (bp == NULL) - return NULL; - if (tail[1]) { - /* read enough this time to end the line */ - break; - } - } - comment = false; - cont = false; - bp = NULL; - continue; - } - else { - tail[1] = '@'; - } - } - cont = false; - while (*bp && cp < fbuf + MAXLINE) { - int c = *(unsigned char *)bp; - - if (c == '\n' || c == '\r') { - /* line breaks, shmine breaks */ - break; - } - if (c == COMMENT_CHAR && !quote) { - /* comment begins. we need to keep going, to look for CONTINUE_CHAR */ - comment = true; - ++bp; - continue; - } - if (!comment && (c == '"' || c == '\'')) { - if (quote == c) { - quote = 0; - if (cp < fbuf + MAXLINE) - *cp++ = *bp; - ++bp; - continue; - } - else if (!quote) { - quote = *bp++; - if (cp < fbuf + MAXLINE) - *cp++ = quote; - continue; - } - } - - if (iscntrl(c)) { - if (!comment && cp < fbuf + MAXLINE) { - *cp++ = isspace(c) ? ' ' : '?'; - } - ++bp; - continue; - } - else if (isspace(c)) { - if (!quote) { - ++bp; - while (*bp && isspace(*(unsigned char *)bp)) - ++bp; /* eatwhite */ - if (!comment && *bp && *bp != COMMENT_CHAR && cp < fbuf + MAXLINE) - *(cp++) = ' '; - } - else if (!comment && cp + 1 <= fbuf + MAXLINE) { - *(cp++) = *(bp++); - } - else { - ++bp; - } - continue; - } - else if (c == CONTINUE_CHAR) { - const char *handle_end = ++bp; - while (*handle_end && isspace(*(unsigned char *)handle_end)) - ++handle_end; /* eatwhite */ - if (*handle_end == '\0') { - bp = handle_end; - cont = true; - continue; - } - if (comment) { - ++bp; - continue; - } - } - else if (comment) { - ++bp; - continue; - } - - if (c < 0x80) { - if (cp + 1 <= fbuf + MAXLINE) { - *(cp++) = *(bp++); - } - } - else { - char inbuf = (char)c; - size_t inbytes = 1; - size_t outbytes = MAXLINE - (cp - fbuf); - int ret = unicode_latin1_to_utf8(cp, &outbytes, &inbuf, &inbytes); - if (ret > 0) - cp += ret; - else { - log_error("input data was not iso-8859-1! assuming utf-8\n"); - return NULL; - } - - ++bp; - continue; - } - } - if (cp == fbuf + MAXLINE) { - --cp; - } - *cp = 0; - } while (cont || cp == fbuf); - return fbuf; -} - static const char *getbuf_utf8(FILE * F) { bool cont = false; @@ -336,9 +192,7 @@ static const char *getbuf_utf8(FILE * F) return fbuf; } -const char *getbuf(FILE * F, int encoding) +const char *getbuf(FILE * F) { - if (encoding == ENCODING_UTF8) - return getbuf_utf8(F); - return getbuf_latin1(F); + return getbuf_utf8(F); } diff --git a/src/util/filereader.h b/src/util/filereader.h index eb09d14e1..a80afa65f 100644 --- a/src/util/filereader.h +++ b/src/util/filereader.h @@ -15,10 +15,7 @@ extern "C" { #endif -#define ENCODING_UTF8 0 -#define ENCODING_LATIN1 1 - - const char *getbuf(FILE *, int encoding); + const char *getbuf(FILE *); #ifdef __cplusplus } From a4f6c6f0053160884f7be547dc43d99d2465f6b2 Mon Sep 17 00:00:00 2001 From: Enno Rehling Date: Sun, 30 Sep 2018 16:16:32 +0200 Subject: [PATCH 057/160] fix libbsd linking --- src/CMakeLists.txt | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt index 9ed0011e6..0e4c342d4 100644 --- a/src/CMakeLists.txt +++ b/src/CMakeLists.txt @@ -186,6 +186,7 @@ endif() add_library(version STATIC ${VERSION_SRC}) add_library(parser ${PARSER_SRC}) target_link_libraries(parser + bsd ${CRYPTO_LIBRARIES} ) @@ -297,8 +298,7 @@ if (HAVE_STRDUP) endif(HAVE_STRDUP) if (HAVE_LIBBSD) -target_link_libraries(test_eressea bsd) -target_link_libraries(eressea bsd) +target_link_libraries(parser bsd) endif (HAVE_LIBBSD) if (SQLITE3_FOUND) From 0c4d1ec2b246b907d1867407111dfb81b334a184 Mon Sep 17 00:00:00 2001 From: Enno Rehling Date: Sun, 30 Sep 2018 16:18:06 +0200 Subject: [PATCH 058/160] fix libbsd linking (MSVC) --- src/CMakeLists.txt | 1 - 1 file changed, 1 deletion(-) diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt index 0e4c342d4..8bb751258 100644 --- a/src/CMakeLists.txt +++ b/src/CMakeLists.txt @@ -186,7 +186,6 @@ endif() add_library(version STATIC ${VERSION_SRC}) add_library(parser ${PARSER_SRC}) target_link_libraries(parser - bsd ${CRYPTO_LIBRARIES} ) From b1cd9bcfef32668c5daf3b9a3d3b4da1e83781d7 Mon Sep 17 00:00:00 2001 From: Enno Rehling Date: Sun, 30 Sep 2018 19:47:34 +0200 Subject: [PATCH 059/160] Pretty good progress on the OrderParser implementaiton. Still finding bugs by unit-testing, though. --- .gitignore | 1 + src/test_eressea.c | 1 + src/util/CMakeLists.txt | 2 +- src/util/order_parser.c | 199 +++++++++++++++++++++++++++++++++-- src/util/order_parser.h | 13 +-- src/util/order_parser.test.c | 65 ++++++++++++ 6 files changed, 263 insertions(+), 18 deletions(-) create mode 100644 src/util/order_parser.test.c diff --git a/.gitignore b/.gitignore index d5e8e1b10..3dcf24224 100644 --- a/.gitignore +++ b/.gitignore @@ -36,6 +36,7 @@ Thumbs.db *.cfg *.cmd tmp/ +tests/orders.txt tests/config.lua tests/reports/ tests/data/185.dat diff --git a/src/test_eressea.c b/src/test_eressea.c index 439fee1d6..9897c4bf0 100644 --- a/src/test_eressea.c +++ b/src/test_eressea.c @@ -81,6 +81,7 @@ int RunAllTests(int argc, char *argv[]) ADD_SUITE(functions); ADD_SUITE(gamedata); ADD_SUITE(language); + ADD_SUITE(order_parser); ADD_SUITE(parser); ADD_SUITE(password); ADD_SUITE(umlaut); diff --git a/src/util/CMakeLists.txt b/src/util/CMakeLists.txt index b4d067f57..362ee4fb2 100644 --- a/src/util/CMakeLists.txt +++ b/src/util/CMakeLists.txt @@ -16,7 +16,7 @@ language.test.c # log.test.c message.test.c # nrmessage.test.c -# order_parser.test.c +order_parser.test.c # param.test.c parser.test.c password.test.c diff --git a/src/util/order_parser.c b/src/util/order_parser.c index b0d6d2d10..ec40f5615 100644 --- a/src/util/order_parser.c +++ b/src/util/order_parser.c @@ -4,7 +4,10 @@ #include "order_parser.h" +#include +#include #include +#include struct OrderParserStruct { void *m_userData; @@ -18,34 +21,208 @@ struct OrderParserStruct { int m_lineNumber; }; -void OP_SetUnitHandler(OP_Parser op, OP_UnitHandler handler) +void OP_SetUnitHandler(OP_Parser parser, OP_UnitHandler handler) { - op->m_unitHandler = handler; + parser->m_unitHandler = handler; } -void OP_SetFactionHandler(OP_Parser op, OP_FactionHandler handler) { - op->m_factionHandler = handler; +void OP_SetFactionHandler(OP_Parser parser, OP_FactionHandler handler) { + parser->m_factionHandler = handler; } -void OP_SetOrderHandler(OP_Parser op, OP_OrderHandler handler) { - op->m_orderHandler = handler; +void OP_SetOrderHandler(OP_Parser parser, OP_OrderHandler handler) { + parser->m_orderHandler = handler; } -void OP_SetUserData(OP_Parser op, void *userData) { - op->m_userData = userData; +void OP_SetUserData(OP_Parser parser, void *userData) { + parser->m_userData = userData; } +static void buffer_free(OP_Parser parser) +{ + /* TODO: recycle buffers, reduce mallocs. */ + free(parser->m_buffer); + parser->m_bufferEnd = parser->m_bufferPtr = parser->m_buffer = NULL; +} + +void OP_ParserReset(OP_Parser parser) { + parser->m_lineNumber = 1; + buffer_free(parser); +} + + OP_Parser OP_ParserCreate(void) { OP_Parser parser = calloc(1, sizeof(struct OrderParserStruct)); + OP_ParserReset(parser); return parser; } -void OP_ParserFree(OP_Parser op) { - free(op); +void OP_ParserFree(OP_Parser parser) { + free(parser->m_buffer); + free(parser); } -enum OP_Status OP_Parse(OP_Parser op, const char *s, int len, int isFinal) +static enum OP_Error buffer_append(OP_Parser parser, const char *s, int len) { + if (parser->m_buffer == NULL) { + parser->m_buffer = malloc(len + 1); + if (!parser->m_buffer) { + return OP_ERROR_NO_MEMORY; + } + memcpy(parser->m_buffer, s, len); + parser->m_buffer[len] = '\0'; + parser->m_bufferPtr = parser->m_buffer; + parser->m_bufferEnd = parser->m_buffer + len; + } + else { + size_t total = len; + char * buffer; + total += (parser->m_bufferEnd - parser->m_bufferPtr); + /* TODO: recycle buffers, reduce mallocs. */ + buffer = malloc(total + 1); + memcpy(buffer, parser->m_bufferPtr, total - len); + memcpy(buffer + total - len, s, len); + buffer[total] = '\0'; + free(parser->m_buffer); + parser->m_buffer = buffer; + if (!parser->m_buffer) { + return OP_ERROR_NO_MEMORY; + } + parser->m_bufferPtr = parser->m_buffer; + parser->m_bufferEnd = parser->m_buffer + total; + } + return OP_ERROR_NONE; +} + +static enum OP_Error handle_line(OP_Parser parser) { + if (parser->m_orderHandler) { + parser->m_orderHandler(parser->m_userData, parser->m_bufferPtr); + } + return OP_ERROR_NONE; +} + +static char *skip_spaces(char *pos) { + char *next; + for (next = pos; *next && *next != '\n'; ++next) { + /* TODO: handle unicode whitespace */ + if (!isspace(*next)) break; + } + return next; +} + +static enum OP_Status parse_buffer(OP_Parser parser, int isFinal) +{ + char * pos = strpbrk(parser->m_bufferPtr, "\\;\n"); + while (pos) { + enum OP_Error code; + size_t len = pos - parser->m_bufferPtr; + char *next; + + switch (*pos) { + case '\n': + *pos = '\0'; + code = handle_line(parser); + ++parser->m_lineNumber; + if (code != OP_ERROR_NONE) { + parser->m_errorCode = code; + return OP_STATUS_ERROR; + } + parser->m_bufferPtr = pos + 1; + pos = strpbrk(parser->m_bufferPtr, "\\;\n"); + break; + case '\\': + /* if this is the last non-space before the line break, then lines need to be joined */ + next = skip_spaces(pos + 1); + if (*next == '\n') { + ptrdiff_t shift = (next + 1 - pos); + assert(shift > 0); + memmove(parser->m_bufferPtr + shift, parser->m_bufferPtr, len); + parser->m_bufferPtr += shift; + pos = strpbrk(next + 1, "\\;\n"); + ++parser->m_lineNumber; + } + else { + /* this is not multi-line input yet, so do nothing */ + pos = strpbrk(pos + 1, "\\;\n"); + } + break; + case ';': + /* the current line ends in a comment */ + *pos++ = '\0'; + handle_line(parser); + /* find the end of the comment so we can skip it. + * obs: multi-line comments are possible with a backslash. */ + do { + next = strpbrk(pos, "\\\n"); + if (next) { + if (*next == '\n') { + /* no more lines in this comment, we're done: */ + pos = next + 1; + ++parser->m_lineNumber; + break; + } + else { + /* is this backslash the final character? */ + next = skip_spaces(pos + 1); + if (*next == '\n') { + /* we have a multi-line comment! */ + pos = next + 1; + ++parser->m_lineNumber; + } + else { + /* keep looking for a backslash */ + pos = next; + } + } + } + } while (next && *next); + + if (next && pos < parser->m_bufferEnd) { + /* we skip the comment, and there is more data in the buffer */ + parser->m_bufferPtr = pos; + } + else { + /* we exhausted the buffer before we got to the end of the comment */ + if (isFinal) { + /* the input ended on this comment line, which is fine */ + return OP_STATUS_OK; + } + else { + /* skip what we have of the comment, keep the semicolon, keep going */ + ptrdiff_t skip = parser->m_bufferEnd - parser->m_bufferPtr; + if (skip > 1) { + parser->m_bufferPtr += (skip - 1); + parser->m_bufferPtr[0] = ';'; + } + } + } + break; + default: + parser->m_errorCode = OP_ERROR_SYNTAX; + return OP_STATUS_ERROR; + } + } + if (isFinal && parser->m_bufferPtr < parser->m_bufferEnd) { + /* this line ends without a line break */ + handle_line(parser); + } return OP_STATUS_OK; } + +enum OP_Status OP_Parse(OP_Parser parser, const char *s, int len, int isFinal) +{ + enum OP_Error code; + + if (parser->m_bufferPtr >= parser->m_bufferEnd) { + buffer_free(parser); + } + + code = buffer_append(parser, s, len); + if (code != OP_ERROR_NONE) { + parser->m_errorCode = code; + return OP_STATUS_ERROR; + } + + return parse_buffer(parser, isFinal); +} diff --git a/src/util/order_parser.h b/src/util/order_parser.h index c8f20e89e..10a258875 100644 --- a/src/util/order_parser.h +++ b/src/util/order_parser.h @@ -34,11 +34,12 @@ typedef void(*OP_UnitHandler) (void *userData, int no); typedef void(*OP_OrderHandler) (void *userData, const char *str); OP_Parser OP_ParserCreate(void); -void OP_ParserFree(OP_Parser op); -enum OP_Status OP_Parse(OP_Parser op, const char *s, int len, int isFinal); -void OP_SetUnitHandler(OP_Parser op, OP_UnitHandler handler); -void OP_SetFactionHandler(OP_Parser op, OP_FactionHandler handler); -void OP_SetOrderHandler(OP_Parser op, OP_OrderHandler handler); -void OP_SetUserData(OP_Parser op, void *userData); +void OP_ParserFree(OP_Parser parser); +void OP_ParserReset(OP_Parser parser); +enum OP_Status OP_Parse(OP_Parser parser, const char *s, int len, int isFinal); +void OP_SetUnitHandler(OP_Parser parser, OP_UnitHandler handler); +void OP_SetFactionHandler(OP_Parser parser, OP_FactionHandler handler); +void OP_SetOrderHandler(OP_Parser parser, OP_OrderHandler handler); +void OP_SetUserData(OP_Parser parser, void *userData); #endif diff --git a/src/util/order_parser.test.c b/src/util/order_parser.test.c new file mode 100644 index 000000000..a4bc58e97 --- /dev/null +++ b/src/util/order_parser.test.c @@ -0,0 +1,65 @@ +#ifdef _MSC_VER +#include +#endif + +#include "order_parser.h" +#include "strings.h" + +#include + +#include + +static void test_parse_noop(CuTest *tc) { + OP_Parser parser; + parser = OP_ParserCreate(); + CuAssertPtrNotNull(tc, parser); + CuAssertIntEquals(tc, OP_STATUS_OK, OP_Parse(parser, "Hello World", 11, 1)); + OP_ParserFree(parser); +} + +static void copy_line(void *udata, const char *str) { + char *dst = (char *)udata; + if (dst) { + strcpy(dst, str); + } +} + +static void test_parse_orders(CuTest *tc) { + OP_Parser parser; + char lastline[1024]; + + parser = OP_ParserCreate(); + OP_SetUserData(parser, lastline); + OP_SetOrderHandler(parser, copy_line); + CuAssertPtrNotNull(tc, parser); + CuAssertIntEquals(tc, OP_STATUS_OK, OP_Parse(parser, "Hello World", 11, 1)); + CuAssertStrEquals(tc, "Hello World", lastline); + OP_ParserReset(parser); + CuAssertIntEquals(tc, OP_STATUS_OK, OP_Parse(parser, "Hello World\n", 12, 1)); + CuAssertStrEquals(tc, "Hello World", lastline); + OP_ParserReset(parser); + CuAssertIntEquals(tc, OP_STATUS_OK, OP_Parse(parser, "Hello\\\n World", 13, 1)); + CuAssertStrEquals(tc, "Hello World", lastline); + OP_ParserReset(parser); + CuAssertIntEquals(tc, OP_STATUS_OK, OP_Parse(parser, "Hello;World", 11, 1)); + CuAssertStrEquals(tc, "Hello", lastline); + OP_ParserReset(parser); + CuAssertIntEquals(tc, OP_STATUS_OK, OP_Parse(parser, "Hello\\World", 11, 1)); + CuAssertStrEquals(tc, "Hello\\World", lastline); + OP_ParserReset(parser); + CuAssertIntEquals(tc, OP_STATUS_OK, OP_Parse(parser, "Hello ", 6, 0)); + CuAssertIntEquals(tc, OP_STATUS_OK, OP_Parse(parser, "World", 5, 1)); + CuAssertStrEquals(tc, "Hello World", lastline); + OP_ParserReset(parser); + CuAssertIntEquals(tc, OP_STATUS_OK, OP_Parse(parser, "Hello\\World \\", 14, 1)); + CuAssertStrEquals(tc, "Hello\\World ", lastline); + OP_ParserFree(parser); +} + +CuSuite *get_order_parser_suite(void) +{ + CuSuite *suite = CuSuiteNew(); + SUITE_ADD_TEST(suite, test_parse_noop); + SUITE_ADD_TEST(suite, test_parse_orders); + return suite; +} From 90b80aba898cc68e18a42270223e520b880f6427 Mon Sep 17 00:00:00 2001 From: Enno Rehling Date: Mon, 1 Oct 2018 02:26:31 +0200 Subject: [PATCH 060/160] fix some more issues with buffer ending before decisions are finished. --- src/util/order_parser.c | 16 +++++++++++++++- src/util/order_parser.test.c | 12 ++++++++++++ 2 files changed, 27 insertions(+), 1 deletion(-) diff --git a/src/util/order_parser.c b/src/util/order_parser.c index ec40f5615..8bf4c7e8d 100644 --- a/src/util/order_parser.c +++ b/src/util/order_parser.c @@ -144,7 +144,21 @@ static enum OP_Status parse_buffer(OP_Parser parser, int isFinal) } else { /* this is not multi-line input yet, so do nothing */ - pos = strpbrk(pos + 1, "\\;\n"); + if (pos[1] == '\0') { + /* end of available input */ + if (isFinal) { + /* input ends on a pointless backslash, kill it */ + pos[0] = '\0'; + pos = NULL; + } + else { + /* backslash is followed by data that we do not know */ + pos = NULL; + } + } + else { + pos = strpbrk(pos + 1, "\\;\n"); + } } break; case ';': diff --git a/src/util/order_parser.test.c b/src/util/order_parser.test.c index a4bc58e97..e9a37fa76 100644 --- a/src/util/order_parser.test.c +++ b/src/util/order_parser.test.c @@ -32,27 +32,39 @@ static void test_parse_orders(CuTest *tc) { OP_SetUserData(parser, lastline); OP_SetOrderHandler(parser, copy_line); CuAssertPtrNotNull(tc, parser); + lastline[0] = 0; CuAssertIntEquals(tc, OP_STATUS_OK, OP_Parse(parser, "Hello World", 11, 1)); CuAssertStrEquals(tc, "Hello World", lastline); OP_ParserReset(parser); + lastline[0] = 0; CuAssertIntEquals(tc, OP_STATUS_OK, OP_Parse(parser, "Hello World\n", 12, 1)); CuAssertStrEquals(tc, "Hello World", lastline); OP_ParserReset(parser); + lastline[0] = 0; CuAssertIntEquals(tc, OP_STATUS_OK, OP_Parse(parser, "Hello\\\n World", 13, 1)); CuAssertStrEquals(tc, "Hello World", lastline); OP_ParserReset(parser); + lastline[0] = 0; CuAssertIntEquals(tc, OP_STATUS_OK, OP_Parse(parser, "Hello;World", 11, 1)); CuAssertStrEquals(tc, "Hello", lastline); OP_ParserReset(parser); + lastline[0] = 0; CuAssertIntEquals(tc, OP_STATUS_OK, OP_Parse(parser, "Hello\\World", 11, 1)); CuAssertStrEquals(tc, "Hello\\World", lastline); OP_ParserReset(parser); + lastline[0] = 0; CuAssertIntEquals(tc, OP_STATUS_OK, OP_Parse(parser, "Hello ", 6, 0)); CuAssertIntEquals(tc, OP_STATUS_OK, OP_Parse(parser, "World", 5, 1)); CuAssertStrEquals(tc, "Hello World", lastline); OP_ParserReset(parser); + lastline[0] = 0; CuAssertIntEquals(tc, OP_STATUS_OK, OP_Parse(parser, "Hello\\World \\", 14, 1)); CuAssertStrEquals(tc, "Hello\\World ", lastline); + OP_ParserReset(parser); + lastline[0] = 0; + CuAssertIntEquals(tc, OP_STATUS_OK, OP_Parse(parser, "Hello \\", 7, 0)); + CuAssertIntEquals(tc, OP_STATUS_OK, OP_Parse(parser, "\nWorld", 6, 1)); + CuAssertStrEquals(tc, "Hello World", lastline); OP_ParserFree(parser); } From eed3ab3acfc54dce5082a75aa458e0291029ea92 Mon Sep 17 00:00:00 2001 From: Enno Rehling Date: Mon, 1 Oct 2018 21:32:59 +0200 Subject: [PATCH 061/160] finish new order parser, maybe? --- src/orderfile.c | 50 +++++++++++++++++++++++++++++++---------- src/util/order_parser.c | 28 +++++++++-------------- src/util/order_parser.h | 4 ---- 3 files changed, 48 insertions(+), 34 deletions(-) diff --git a/src/orderfile.c b/src/orderfile.c index 316724338..ff19014ea 100644 --- a/src/orderfile.c +++ b/src/orderfile.c @@ -249,6 +249,8 @@ static void handle_faction(void *userData, int no, const char *password) { log_debug("invalid password for faction %s", itoa36(no)); ADDMSG(&f->msgs, msg_message("wrongpasswd", "password", password)); } + state->u = NULL; + state->next_order = NULL; } } @@ -272,20 +274,46 @@ static void handle_unit(void *userData, int no) { static void handle_order(void *userData, const char *str) { parser_state *state = (parser_state *)userData; - unit * u = state->u; - order *ord; + const char * tok, *input = str; + char buffer[16]; + const struct locale *lang; + param_t p; + faction * f = state->f; - ord = parse_order(str, u->faction->locale); - if (ord) { - *state->next_order = ord; - state->next_order = &ord->next; + lang = f ? f->locale : default_locale; + tok = parse_token(&input, buffer, sizeof(buffer)); + p = findparam(tok, lang); + if (p == P_FACTION || p == P_GAMENAME) { + tok = parse_token(&input, buffer, sizeof(buffer)); + if (tok) { + int no = atoi36(tok); + tok = parse_token(&input, buffer, sizeof(buffer)); + handle_faction(userData, no, tok); + } + else { + /* TODO: log_error() */ + } } - else { - ADDMSG(&u->faction->msgs, msg_message("parse_error", "unit command", u, str)); + else if (p == P_UNIT) { + tok = parse_token(&input, buffer, sizeof(buffer)); + if (tok) { + int no = atoi36(tok); + handle_unit(userData, no); + } + } + else if (state->u) { + unit * u = state->u; + order * ord = parse_order(str, lang); + if (ord) { + *state->next_order = ord; + state->next_order = &ord->next; + } + else { + ADDMSG(&u->faction->msgs, msg_message("parse_error", "unit command", u, str)); + } } } - int parseorders(FILE *F) { char buf[2048]; @@ -298,8 +326,6 @@ int parseorders(FILE *F) /* TODO: error message */ return errno; } - OP_SetUnitHandler(parser, handle_unit); - OP_SetFactionHandler(parser, handle_faction); OP_SetOrderHandler(parser, handle_order); OP_SetUserData(parser, &state); @@ -323,7 +349,7 @@ int parseorders(FILE *F) int readorders(FILE *F) { -#undef NEW_PARSER +#define NEW_PARSER #ifdef NEW_PARSER return parseorders(F); #else diff --git a/src/util/order_parser.c b/src/util/order_parser.c index 8bf4c7e8d..f303ff3f1 100644 --- a/src/util/order_parser.c +++ b/src/util/order_parser.c @@ -14,22 +14,11 @@ struct OrderParserStruct { char *m_buffer; char *m_bufferPtr; const char *m_bufferEnd; - OP_FactionHandler m_factionHandler; - OP_UnitHandler m_unitHandler; OP_OrderHandler m_orderHandler; enum OP_Error m_errorCode; int m_lineNumber; }; -void OP_SetUnitHandler(OP_Parser parser, OP_UnitHandler handler) -{ - parser->m_unitHandler = handler; -} - -void OP_SetFactionHandler(OP_Parser parser, OP_FactionHandler handler) { - parser->m_factionHandler = handler; -} - void OP_SetOrderHandler(OP_Parser parser, OP_OrderHandler handler) { parser->m_orderHandler = handler; } @@ -95,13 +84,6 @@ static enum OP_Error buffer_append(OP_Parser parser, const char *s, int len) return OP_ERROR_NONE; } -static enum OP_Error handle_line(OP_Parser parser) { - if (parser->m_orderHandler) { - parser->m_orderHandler(parser->m_userData, parser->m_bufferPtr); - } - return OP_ERROR_NONE; -} - static char *skip_spaces(char *pos) { char *next; for (next = pos; *next && *next != '\n'; ++next) { @@ -111,6 +93,16 @@ static char *skip_spaces(char *pos) { return next; } +static enum OP_Error handle_line(OP_Parser parser) { + if (parser->m_orderHandler) { + char * str = skip_spaces(parser->m_bufferPtr); + if (*str) { + parser->m_orderHandler(parser->m_userData, str); + } + } + return OP_ERROR_NONE; +} + static enum OP_Status parse_buffer(OP_Parser parser, int isFinal) { char * pos = strpbrk(parser->m_bufferPtr, "\\;\n"); diff --git a/src/util/order_parser.h b/src/util/order_parser.h index 10a258875..fde29a380 100644 --- a/src/util/order_parser.h +++ b/src/util/order_parser.h @@ -29,16 +29,12 @@ enum OP_Error { OP_ERROR_SYNTAX }; -typedef void(*OP_FactionHandler) (void *userData, int no, const char *password); -typedef void(*OP_UnitHandler) (void *userData, int no); typedef void(*OP_OrderHandler) (void *userData, const char *str); OP_Parser OP_ParserCreate(void); void OP_ParserFree(OP_Parser parser); void OP_ParserReset(OP_Parser parser); enum OP_Status OP_Parse(OP_Parser parser, const char *s, int len, int isFinal); -void OP_SetUnitHandler(OP_Parser parser, OP_UnitHandler handler); -void OP_SetFactionHandler(OP_Parser parser, OP_FactionHandler handler); void OP_SetOrderHandler(OP_Parser parser, OP_OrderHandler handler); void OP_SetUserData(OP_Parser parser, void *userData); From e6b93ce79a70d6629ac9accccb64e29620785b9f Mon Sep 17 00:00:00 2001 From: Enno Rehling Date: Tue, 2 Oct 2018 18:57:21 +0200 Subject: [PATCH 062/160] reset state when we meet the NEXT command. --- src/orderfile.c | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/src/orderfile.c b/src/orderfile.c index ff19014ea..8fdc75485 100644 --- a/src/orderfile.c +++ b/src/orderfile.c @@ -301,6 +301,15 @@ static void handle_order(void *userData, const char *str) { handle_unit(userData, no); } } + else if (p == P_NEXT) { + state->f = NULL; + state->u = NULL; + state->next_order = NULL; + } + else if (p == P_REGION) { + state->u = NULL; + state->next_order = NULL; + } else if (state->u) { unit * u = state->u; order * ord = parse_order(str, lang); From b439e48a22418b81a15c4b741cff7283c853d70b Mon Sep 17 00:00:00 2001 From: Enno Rehling Date: Tue, 2 Oct 2018 19:02:22 +0200 Subject: [PATCH 063/160] some failing tests --- src/util/order_parser.test.c | 27 ++++++++++++++++++++++++--- 1 file changed, 24 insertions(+), 3 deletions(-) diff --git a/src/util/order_parser.test.c b/src/util/order_parser.test.c index e9a37fa76..2d113655a 100644 --- a/src/util/order_parser.test.c +++ b/src/util/order_parser.test.c @@ -36,31 +36,52 @@ static void test_parse_orders(CuTest *tc) { CuAssertIntEquals(tc, OP_STATUS_OK, OP_Parse(parser, "Hello World", 11, 1)); CuAssertStrEquals(tc, "Hello World", lastline); OP_ParserReset(parser); + lastline[0] = 0; CuAssertIntEquals(tc, OP_STATUS_OK, OP_Parse(parser, "Hello World\n", 12, 1)); CuAssertStrEquals(tc, "Hello World", lastline); OP_ParserReset(parser); + lastline[0] = 0; CuAssertIntEquals(tc, OP_STATUS_OK, OP_Parse(parser, "Hello\\\n World", 13, 1)); CuAssertStrEquals(tc, "Hello World", lastline); OP_ParserReset(parser); + lastline[0] = 0; CuAssertIntEquals(tc, OP_STATUS_OK, OP_Parse(parser, "Hello;World", 11, 1)); CuAssertStrEquals(tc, "Hello", lastline); OP_ParserReset(parser); + lastline[0] = 0; CuAssertIntEquals(tc, OP_STATUS_OK, OP_Parse(parser, "Hello\\World", 11, 1)); CuAssertStrEquals(tc, "Hello\\World", lastline); OP_ParserReset(parser); + lastline[0] = 0; - CuAssertIntEquals(tc, OP_STATUS_OK, OP_Parse(parser, "Hello ", 6, 0)); - CuAssertIntEquals(tc, OP_STATUS_OK, OP_Parse(parser, "World", 5, 1)); - CuAssertStrEquals(tc, "Hello World", lastline); + CuAssertIntEquals(tc, OP_STATUS_OK, OP_Parse(parser, ";Hello \\", 8, 0)); + CuAssertIntEquals(tc, OP_STATUS_OK, OP_Parse(parser, "\nWorld\n", 7, 1)); + CuAssertIntEquals(tc, OP_STATUS_OK, OP_Parse(parser, "Enno", 4, 1)); + CuAssertStrEquals(tc, "Enno", lastline); OP_ParserReset(parser); + + lastline[0] = 0; + CuAssertIntEquals(tc, OP_STATUS_OK, OP_Parse(parser, ";Hello", 6, 0)); + CuAssertIntEquals(tc, OP_STATUS_OK, OP_Parse(parser, "World\n", 6, 1)); + CuAssertIntEquals(tc, OP_STATUS_OK, OP_Parse(parser, "Enno", 4, 1)); + CuAssertStrEquals(tc, "Enno", lastline); + OP_ParserReset(parser); + lastline[0] = 0; CuAssertIntEquals(tc, OP_STATUS_OK, OP_Parse(parser, "Hello\\World \\", 14, 1)); CuAssertStrEquals(tc, "Hello\\World ", lastline); OP_ParserReset(parser); + + lastline[0] = 0; + CuAssertIntEquals(tc, OP_STATUS_OK, OP_Parse(parser, "Hello\n", 6, 0)); + CuAssertIntEquals(tc, OP_STATUS_OK, OP_Parse(parser, "World\n", 6, 1)); + CuAssertStrEquals(tc, "World", lastline); + OP_ParserReset(parser); + lastline[0] = 0; CuAssertIntEquals(tc, OP_STATUS_OK, OP_Parse(parser, "Hello \\", 7, 0)); CuAssertIntEquals(tc, OP_STATUS_OK, OP_Parse(parser, "\nWorld", 6, 1)); From 6c1d266c1279d6230067eca5934012a3c65da91a Mon Sep 17 00:00:00 2001 From: Enno Rehling Date: Tue, 2 Oct 2018 21:40:14 +0200 Subject: [PATCH 064/160] fix comment parsing at end of input --- src/orderfile.c | 2 +- src/util/order_parser.c | 56 +++++++++++++++++++++++++----------- src/util/order_parser.h | 1 + src/util/order_parser.test.c | 15 ++++++++-- 4 files changed, 54 insertions(+), 20 deletions(-) diff --git a/src/orderfile.c b/src/orderfile.c index 8fdc75485..33a9c19f7 100644 --- a/src/orderfile.c +++ b/src/orderfile.c @@ -348,7 +348,7 @@ int parseorders(FILE *F) done = feof(F); if (OP_Parse(parser, buf, len, done) == OP_STATUS_ERROR) { /* TODO: error message */ - err = -1; + err = (int)OP_GetErrorCode(parser); break; } } diff --git a/src/util/order_parser.c b/src/util/order_parser.c index f303ff3f1..88a42f0ab 100644 --- a/src/util/order_parser.c +++ b/src/util/order_parser.c @@ -5,7 +5,7 @@ #include "order_parser.h" #include -#include +#include #include #include @@ -19,6 +19,10 @@ struct OrderParserStruct { int m_lineNumber; }; +enum OP_Error OP_GetErrorCode(OP_Parser parser) { + return parser->m_errorCode; +} + void OP_SetOrderHandler(OP_Parser parser, OP_OrderHandler handler) { parser->m_orderHandler = handler; } @@ -87,8 +91,9 @@ static enum OP_Error buffer_append(OP_Parser parser, const char *s, int len) static char *skip_spaces(char *pos) { char *next; for (next = pos; *next && *next != '\n'; ++next) { + wint_t wch = *(unsigned char *)next; /* TODO: handle unicode whitespace */ - if (!isspace(*next)) break; + if (!iswspace(wch)) break; } return next; } @@ -110,6 +115,7 @@ static enum OP_Status parse_buffer(OP_Parser parser, int isFinal) enum OP_Error code; size_t len = pos - parser->m_bufferPtr; char *next; + int continue_comment = 0; switch (*pos) { case '\n': @@ -164,9 +170,8 @@ static enum OP_Status parse_buffer(OP_Parser parser, int isFinal) if (next) { if (*next == '\n') { /* no more lines in this comment, we're done: */ - pos = next + 1; ++parser->m_lineNumber; - break; + break; /* exit loop */ } else { /* is this backslash the final character? */ @@ -184,25 +189,42 @@ static enum OP_Status parse_buffer(OP_Parser parser, int isFinal) } } while (next && *next); - if (next && pos < parser->m_bufferEnd) { - /* we skip the comment, and there is more data in the buffer */ - parser->m_bufferPtr = pos; - } - else { - /* we exhausted the buffer before we got to the end of the comment */ + if (!next) { + /* we exhausted the buffer before we finished the line */ if (isFinal) { - /* the input ended on this comment line, which is fine */ + /* this comment was at the end of the file, it just has no newline. done! */ return OP_STATUS_OK; } else { - /* skip what we have of the comment, keep the semicolon, keep going */ - ptrdiff_t skip = parser->m_bufferEnd - parser->m_bufferPtr; - if (skip > 1) { - parser->m_bufferPtr += (skip - 1); - parser->m_bufferPtr[0] = ';'; - } + /* there is more of this line in the next buffer, save the semicolon */ + continue_comment = 1; } } + else { + if (*next) { + /* end comment parsing, begin parsing a new line */ + pos = next + 1; + continue_comment = 0; + } + else { + /* reached end of input naturally, need more data to finish */ + continue_comment = 1; + } + } + + if (continue_comment) { + ptrdiff_t skip = parser->m_bufferEnd - parser->m_bufferPtr; + continue_comment = 0; + if (skip > 0) { + /* should always be true */ + parser->m_bufferPtr += (skip - 1); + parser->m_bufferPtr[0] = ';'; + } + return OP_STATUS_OK; + } + /* continue the outer loop */ + parser->m_bufferPtr = pos; + pos = strpbrk(pos, "\\;\n"); break; default: parser->m_errorCode = OP_ERROR_SYNTAX; diff --git a/src/util/order_parser.h b/src/util/order_parser.h index fde29a380..159fd6594 100644 --- a/src/util/order_parser.h +++ b/src/util/order_parser.h @@ -37,5 +37,6 @@ void OP_ParserReset(OP_Parser parser); enum OP_Status OP_Parse(OP_Parser parser, const char *s, int len, int isFinal); void OP_SetOrderHandler(OP_Parser parser, OP_OrderHandler handler); void OP_SetUserData(OP_Parser parser, void *userData); +enum OP_Error OP_GetErrorCode(OP_Parser parser); #endif diff --git a/src/util/order_parser.test.c b/src/util/order_parser.test.c index 2d113655a..630bcc4d4 100644 --- a/src/util/order_parser.test.c +++ b/src/util/order_parser.test.c @@ -57,16 +57,22 @@ static void test_parse_orders(CuTest *tc) { CuAssertStrEquals(tc, "Hello\\World", lastline); OP_ParserReset(parser); + lastline[0] = 0; + CuAssertIntEquals(tc, OP_STATUS_OK, OP_Parse(parser, ";\n", 2, 0)); + CuAssertIntEquals(tc, OP_STATUS_OK, OP_Parse(parser, "Hello World", 11, 1)); + CuAssertStrEquals(tc, "Hello World", lastline); + OP_ParserReset(parser); + lastline[0] = 0; CuAssertIntEquals(tc, OP_STATUS_OK, OP_Parse(parser, ";Hello \\", 8, 0)); - CuAssertIntEquals(tc, OP_STATUS_OK, OP_Parse(parser, "\nWorld\n", 7, 1)); + CuAssertIntEquals(tc, OP_STATUS_OK, OP_Parse(parser, "\nWorld\n", 7, 0)); CuAssertIntEquals(tc, OP_STATUS_OK, OP_Parse(parser, "Enno", 4, 1)); CuAssertStrEquals(tc, "Enno", lastline); OP_ParserReset(parser); lastline[0] = 0; CuAssertIntEquals(tc, OP_STATUS_OK, OP_Parse(parser, ";Hello", 6, 0)); - CuAssertIntEquals(tc, OP_STATUS_OK, OP_Parse(parser, "World\n", 6, 1)); + CuAssertIntEquals(tc, OP_STATUS_OK, OP_Parse(parser, "World\n", 6, 0)); CuAssertIntEquals(tc, OP_STATUS_OK, OP_Parse(parser, "Enno", 4, 1)); CuAssertStrEquals(tc, "Enno", lastline); OP_ParserReset(parser); @@ -82,6 +88,11 @@ static void test_parse_orders(CuTest *tc) { CuAssertStrEquals(tc, "World", lastline); OP_ParserReset(parser); + lastline[0] = 0; + CuAssertIntEquals(tc, OP_STATUS_OK, OP_Parse(parser, "Hello\n", 6, 0)); + CuAssertIntEquals(tc, OP_STATUS_OK, OP_Parse(parser, "World\n", 6, 1)); + CuAssertStrEquals(tc, "World", lastline); + OP_ParserReset(parser); lastline[0] = 0; CuAssertIntEquals(tc, OP_STATUS_OK, OP_Parse(parser, "Hello \\", 7, 0)); CuAssertIntEquals(tc, OP_STATUS_OK, OP_Parse(parser, "\nWorld", 6, 1)); From 854decc4f10548127aa2814d83b014826fc47f1f Mon Sep 17 00:00:00 2001 From: Enno Rehling Date: Wed, 3 Oct 2018 10:37:34 +0200 Subject: [PATCH 065/160] comments split by a backslash are not handled right. --- src/util/order_parser.test.c | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/src/util/order_parser.test.c b/src/util/order_parser.test.c index 630bcc4d4..1034e3d0a 100644 --- a/src/util/order_parser.test.c +++ b/src/util/order_parser.test.c @@ -32,11 +32,17 @@ static void test_parse_orders(CuTest *tc) { OP_SetUserData(parser, lastline); OP_SetOrderHandler(parser, copy_line); CuAssertPtrNotNull(tc, parser); + lastline[0] = 0; CuAssertIntEquals(tc, OP_STATUS_OK, OP_Parse(parser, "Hello World", 11, 1)); CuAssertStrEquals(tc, "Hello World", lastline); OP_ParserReset(parser); + lastline[0] = 0; + CuAssertIntEquals(tc, OP_STATUS_OK, OP_Parse(parser, "Hello World;\nError", 18, 1)); + CuAssertStrEquals(tc, "Hello World", lastline); + OP_ParserReset(parser); + lastline[0] = 0; CuAssertIntEquals(tc, OP_STATUS_OK, OP_Parse(parser, "Hello World\n", 12, 1)); CuAssertStrEquals(tc, "Hello World", lastline); From fbce8f326af1d5ed11da3aafcc773747f584186c Mon Sep 17 00:00:00 2001 From: Enno Rehling Date: Wed, 3 Oct 2018 19:47:32 +0200 Subject: [PATCH 066/160] fix error in multi-line comments at stream border. --- src/orderfile.c | 47 ++++++++++++++++++++++++++++-------- src/util/order_parser.c | 18 ++++++++++---- src/util/order_parser.test.c | 19 ++++++++++++++- 3 files changed, 68 insertions(+), 16 deletions(-) diff --git a/src/orderfile.c b/src/orderfile.c index 33a9c19f7..450e1b0c1 100644 --- a/src/orderfile.c +++ b/src/orderfile.c @@ -21,6 +21,9 @@ #include #include +static FILE *dlog; +static int orders_parsed, units_parsed, factions_parsed; + static void begin_orders(unit *u) { if (u->flags & UFL_ORDERS) { order **ordp; @@ -52,6 +55,7 @@ static unit *unitorders(input *in, faction *f) int i; unit *u; + ++units_parsed; if (!f) return NULL; @@ -109,6 +113,11 @@ static unit *unitorders(input *in, faction *f) } } /* Nun wird der Befehl erzeut und eingeh�ngt */ + ++orders_parsed; + if (dlog) { + fputs(s, dlog); + fputc('\n', dlog); + } *ordp = parse_order(s, u->faction->locale); if (*ordp) { ordp = &(*ordp)->next; @@ -131,6 +140,7 @@ static faction *factionorders(void) int fid = getid(); faction *f = findfaction(fid); + ++factions_parsed; if (f != NULL && (f->flags & FFL_NPC) == 0) { char token[128]; const char *pass = gettoken(token, sizeof(token)); @@ -241,6 +251,7 @@ typedef struct parser_state { static void handle_faction(void *userData, int no, const char *password) { parser_state *state = (parser_state *)userData; faction * f = state->f = findfaction(no); + ++factions_parsed; if (!f) { log_debug("orders for unknown faction %s", itoa36(no)); } @@ -258,6 +269,7 @@ static void handle_unit(void *userData, int no) { parser_state *state = (parser_state *)userData; unit * u = findunit(no); + ++units_parsed; state->u = NULL; if (!u) { /* TODO: error message */ @@ -313,6 +325,11 @@ static void handle_order(void *userData, const char *str) { else if (state->u) { unit * u = state->u; order * ord = parse_order(str, lang); + ++orders_parsed; + if (dlog) { + fputs(str, dlog); + fputc('\n', dlog); + } if (ord) { *state->next_order = ord; state->next_order = &ord->next; @@ -325,7 +342,7 @@ static void handle_order(void *userData, const char *str) { int parseorders(FILE *F) { - char buf[2048]; + char buf[4096]; int done = 0, err = 0; OP_Parser parser; parser_state state = { NULL, NULL }; @@ -356,18 +373,28 @@ int parseorders(FILE *F) return err; } +#define NEW_PARSER int readorders(FILE *F) { -#define NEW_PARSER -#ifdef NEW_PARSER - return parseorders(F); -#else - input in; int result; - in.getbuf = file_getbuf; - in.data = F; - result = read_orders(&in); - return result; + orders_parsed = 0; + units_parsed = 0; + factions_parsed = 0; + +#ifdef NEW_PARSER + dlog = fopen("orders.new.log", "w+"); + result = parseorders(F); +#else + dlog = fopen("orders.old.log", "w+"); + { + input in; + in.getbuf = file_getbuf; + in.data = F; + result = read_orders(&in); + } #endif + fclose(dlog); + log_debug("%d orders read.", orders_parsed); + return result; } diff --git a/src/util/order_parser.c b/src/util/order_parser.c index 88a42f0ab..55b03accd 100644 --- a/src/util/order_parser.c +++ b/src/util/order_parser.c @@ -175,12 +175,16 @@ static enum OP_Status parse_buffer(OP_Parser parser, int isFinal) } else { /* is this backslash the final character? */ - next = skip_spaces(pos + 1); + next = skip_spaces(next + 1); if (*next == '\n') { /* we have a multi-line comment! */ pos = next + 1; ++parser->m_lineNumber; } + else if (*next == '\0') { + /* cannot find the EOL char yet, stream is dry. keep ; and \ */ + continue_comment = 2; + } else { /* keep looking for a backslash */ pos = next; @@ -206,7 +210,7 @@ static enum OP_Status parse_buffer(OP_Parser parser, int isFinal) pos = next + 1; continue_comment = 0; } - else { + else if (!continue_comment) { /* reached end of input naturally, need more data to finish */ continue_comment = 1; } @@ -214,12 +218,16 @@ static enum OP_Status parse_buffer(OP_Parser parser, int isFinal) if (continue_comment) { ptrdiff_t skip = parser->m_bufferEnd - parser->m_bufferPtr; - continue_comment = 0; - if (skip > 0) { + assert(skip >= continue_comment); + if (skip >= continue_comment) { /* should always be true */ - parser->m_bufferPtr += (skip - 1); + parser->m_bufferPtr += (skip - continue_comment); parser->m_bufferPtr[0] = ';'; } + if (continue_comment == 2) { + parser->m_bufferPtr[1] = '\\'; + } + continue_comment = 0; return OP_STATUS_OK; } /* continue the outer loop */ diff --git a/src/util/order_parser.test.c b/src/util/order_parser.test.c index 1034e3d0a..d43f661fb 100644 --- a/src/util/order_parser.test.c +++ b/src/util/order_parser.test.c @@ -39,7 +39,24 @@ static void test_parse_orders(CuTest *tc) { OP_ParserReset(parser); lastline[0] = 0; - CuAssertIntEquals(tc, OP_STATUS_OK, OP_Parse(parser, "Hello World;\nError", 18, 1)); + CuAssertIntEquals(tc, OP_STATUS_OK, OP_Parse(parser, "Error;\nHello World", 18, 1)); + CuAssertStrEquals(tc, "Hello World", lastline); + OP_ParserReset(parser); + + lastline[0] = 0; + CuAssertIntEquals(tc, OP_STATUS_OK, OP_Parse(parser, "Hello World;\\\nError", 19, 1)); + CuAssertStrEquals(tc, "Hello World", lastline); + OP_ParserReset(parser); + + lastline[0] = 0; + CuAssertIntEquals(tc, OP_STATUS_OK, OP_Parse(parser, "Hello World;\\", 13, 0)); + CuAssertIntEquals(tc, OP_STATUS_OK, OP_Parse(parser, "\nError", 6, 1)); + CuAssertStrEquals(tc, "Hello World", lastline); + OP_ParserReset(parser); + + lastline[0] = 0; + CuAssertIntEquals(tc, OP_STATUS_OK, OP_Parse(parser, "Hello \\", 7, 0)); + CuAssertIntEquals(tc, OP_STATUS_OK, OP_Parse(parser, "\nWorld", 6, 1)); CuAssertStrEquals(tc, "Hello World", lastline); OP_ParserReset(parser); From 730b94fa4afd0d0384569b9d3800b08a41f35dfe Mon Sep 17 00:00:00 2001 From: Enno Rehling Date: Wed, 3 Oct 2018 20:29:45 +0200 Subject: [PATCH 067/160] reuse the internal buffer when we don't have to malloc. --- src/util/order_parser.c | 55 +++++++++++++++++++++++++++++------------ 1 file changed, 39 insertions(+), 16 deletions(-) diff --git a/src/util/order_parser.c b/src/util/order_parser.c index 55b03accd..21268f163 100644 --- a/src/util/order_parser.c +++ b/src/util/order_parser.c @@ -13,6 +13,7 @@ struct OrderParserStruct { void *m_userData; char *m_buffer; char *m_bufferPtr; + size_t m_bufferSize; const char *m_bufferEnd; OP_OrderHandler m_orderHandler; enum OP_Error m_errorCode; @@ -35,6 +36,7 @@ static void buffer_free(OP_Parser parser) { /* TODO: recycle buffers, reduce mallocs. */ free(parser->m_buffer); + parser->m_bufferSize = 0; parser->m_bufferEnd = parser->m_bufferPtr = parser->m_buffer = NULL; } @@ -58,8 +60,28 @@ void OP_ParserFree(OP_Parser parser) { static enum OP_Error buffer_append(OP_Parser parser, const char *s, int len) { + size_t total = len + 1; + size_t remain = parser->m_bufferEnd - parser->m_bufferPtr; + total += remain; + if (remain > 0) { + /* there is remaining data in the buffer, should we move it to the front? */ + if (total <= parser->m_bufferSize) { + /* reuse existing buffer */ + memmove(parser->m_buffer, parser->m_bufferPtr, remain); + memcpy(parser->m_buffer + remain, s, len); + parser->m_buffer[total - 1] = '\0'; + parser->m_bufferPtr = parser->m_buffer; + parser->m_bufferEnd = parser->m_bufferPtr + total - 1; + return OP_ERROR_NONE; + } + } + else if (parser->m_bufferPtr >= parser->m_bufferEnd) { + buffer_free(parser); + } + if (parser->m_buffer == NULL) { - parser->m_buffer = malloc(len + 1); + parser->m_bufferSize = len + 1; + parser->m_buffer = malloc(parser->m_bufferSize); if (!parser->m_buffer) { return OP_ERROR_NO_MEMORY; } @@ -69,21 +91,26 @@ static enum OP_Error buffer_append(OP_Parser parser, const char *s, int len) parser->m_bufferEnd = parser->m_buffer + len; } else { - size_t total = len; char * buffer; - total += (parser->m_bufferEnd - parser->m_bufferPtr); /* TODO: recycle buffers, reduce mallocs. */ - buffer = malloc(total + 1); - memcpy(buffer, parser->m_bufferPtr, total - len); - memcpy(buffer + total - len, s, len); - buffer[total] = '\0'; - free(parser->m_buffer); - parser->m_buffer = buffer; - if (!parser->m_buffer) { - return OP_ERROR_NO_MEMORY; + if (parser->m_bufferSize < total) { + parser->m_bufferSize = total; + buffer = malloc(parser->m_bufferSize); + if (!buffer) { + return OP_ERROR_NO_MEMORY; + } + memcpy(buffer, parser->m_bufferPtr, total - len - 1); + memcpy(buffer + total - len - 1, s, len); + free(parser->m_buffer); + parser->m_buffer = buffer; } + else { + memcpy(parser->m_buffer, parser->m_bufferPtr, total - len); + memcpy(parser->m_buffer + total - len, s, len); + } + parser->m_buffer[total - 1] = '\0'; parser->m_bufferPtr = parser->m_buffer; - parser->m_bufferEnd = parser->m_buffer + total; + parser->m_bufferEnd = parser->m_buffer + total - 1; } return OP_ERROR_NONE; } @@ -250,10 +277,6 @@ enum OP_Status OP_Parse(OP_Parser parser, const char *s, int len, int isFinal) { enum OP_Error code; - if (parser->m_bufferPtr >= parser->m_bufferEnd) { - buffer_free(parser); - } - code = buffer_append(parser, s, len); if (code != OP_ERROR_NONE) { parser->m_errorCode = code; From bbd57b6ae99604e131305338f36390513bf78964 Mon Sep 17 00:00:00 2001 From: Enno Rehling Date: Wed, 3 Oct 2018 20:33:53 +0200 Subject: [PATCH 068/160] remove debug stuff, use new parser for the game. --- src/bind_eressea.c | 2 +- src/orderfile.c | 40 ++++------------------------------------ src/orderfile.h | 1 + 3 files changed, 6 insertions(+), 37 deletions(-) diff --git a/src/bind_eressea.c b/src/bind_eressea.c index 34640137b..e5acbac99 100755 --- a/src/bind_eressea.c +++ b/src/bind_eressea.c @@ -41,7 +41,7 @@ int eressea_read_orders(const char * filename) { return -1; } log_info("reading orders from %s", filename); - return readorders(F); + return parseorders(F); } int eressea_export_json(const char * filename, int flags) { diff --git a/src/orderfile.c b/src/orderfile.c index 450e1b0c1..1677321eb 100644 --- a/src/orderfile.c +++ b/src/orderfile.c @@ -21,9 +21,6 @@ #include #include -static FILE *dlog; -static int orders_parsed, units_parsed, factions_parsed; - static void begin_orders(unit *u) { if (u->flags & UFL_ORDERS) { order **ordp; @@ -55,7 +52,6 @@ static unit *unitorders(input *in, faction *f) int i; unit *u; - ++units_parsed; if (!f) return NULL; @@ -113,11 +109,6 @@ static unit *unitorders(input *in, faction *f) } } /* Nun wird der Befehl erzeut und eingeh�ngt */ - ++orders_parsed; - if (dlog) { - fputs(s, dlog); - fputc('\n', dlog); - } *ordp = parse_order(s, u->faction->locale); if (*ordp) { ordp = &(*ordp)->next; @@ -140,7 +131,6 @@ static faction *factionorders(void) int fid = getid(); faction *f = findfaction(fid); - ++factions_parsed; if (f != NULL && (f->flags & FFL_NPC) == 0) { char token[128]; const char *pass = gettoken(token, sizeof(token)); @@ -251,7 +241,6 @@ typedef struct parser_state { static void handle_faction(void *userData, int no, const char *password) { parser_state *state = (parser_state *)userData; faction * f = state->f = findfaction(no); - ++factions_parsed; if (!f) { log_debug("orders for unknown faction %s", itoa36(no)); } @@ -269,7 +258,6 @@ static void handle_unit(void *userData, int no) { parser_state *state = (parser_state *)userData; unit * u = findunit(no); - ++units_parsed; state->u = NULL; if (!u) { /* TODO: error message */ @@ -325,11 +313,6 @@ static void handle_order(void *userData, const char *str) { else if (state->u) { unit * u = state->u; order * ord = parse_order(str, lang); - ++orders_parsed; - if (dlog) { - fputs(str, dlog); - fputc('\n', dlog); - } if (ord) { *state->next_order = ord; state->next_order = &ord->next; @@ -373,28 +356,13 @@ int parseorders(FILE *F) return err; } -#define NEW_PARSER int readorders(FILE *F) { int result; - orders_parsed = 0; - units_parsed = 0; - factions_parsed = 0; - -#ifdef NEW_PARSER - dlog = fopen("orders.new.log", "w+"); - result = parseorders(F); -#else - dlog = fopen("orders.old.log", "w+"); - { - input in; - in.getbuf = file_getbuf; - in.data = F; - result = read_orders(&in); - } -#endif - fclose(dlog); - log_debug("%d orders read.", orders_parsed); + input in; + in.getbuf = file_getbuf; + in.data = F; + result = read_orders(&in); return result; } diff --git a/src/orderfile.h b/src/orderfile.h index fa051993e..f4260aa67 100644 --- a/src/orderfile.h +++ b/src/orderfile.h @@ -14,6 +14,7 @@ extern "C" { int read_orders(struct input *in); int readorders(FILE *F); + int parseorders(FILE *F); #ifdef __cplusplus } From 6b983079b7a92f9e7af9367df39836b47922f97d Mon Sep 17 00:00:00 2001 From: Enno Rehling Date: Thu, 4 Oct 2018 04:47:20 +0200 Subject: [PATCH 069/160] remember to set faction.lastorders (NMR count was off). checker just removes comments now. --- src/checker.c | 46 ++++++++++++++++++++++++++++++++++++++++++++-- src/orderfile.c | 5 ++++- 2 files changed, 48 insertions(+), 3 deletions(-) diff --git a/src/checker.c b/src/checker.c index 302c80390..f87b91891 100644 --- a/src/checker.c +++ b/src/checker.c @@ -2,10 +2,50 @@ #include #endif -#include "util/parser.h" +#include "util/order_parser.h" #include +typedef struct parser_state { + FILE * F; +} parser_state; + +static void handle_order(void *userData, const char *str) { + parser_state * state = (parser_state*)userData; + fputs(str, state->F); + fputc('\n', state->F); +} + +int parsefile(FILE *F) { + OP_Parser parser; + char buf[1024]; + int done = 0, err = 0; + parser_state state = { NULL }; + + state.F = stdout; + + parser = OP_ParserCreate(); + OP_SetOrderHandler(parser, handle_order); + OP_SetUserData(parser, &state); + + while (!done) { + size_t len = (int)fread(buf, 1, sizeof(buf), F); + if (ferror(F)) { + /* TODO: error message */ + err = errno; + break; + } + done = feof(F); + if (OP_Parse(parser, buf, len, done) == OP_STATUS_ERROR) { + /* TODO: error message */ + err = (int)OP_GetErrorCode(parser); + break; + } + } + OP_ParserFree(parser); + return err; +} + int main(int argc, char **argv) { FILE * F = stdin; if (argc >= 1) { @@ -15,8 +55,10 @@ int main(int argc, char **argv) { perror(filename); return -1; } + } + parsefile(F); + if (F != stdin) { fclose(F); } return 0; } - diff --git a/src/orderfile.c b/src/orderfile.c index 1677321eb..90b44477b 100644 --- a/src/orderfile.c +++ b/src/orderfile.c @@ -245,7 +245,10 @@ static void handle_faction(void *userData, int no, const char *password) { log_debug("orders for unknown faction %s", itoa36(no)); } else { - if (!checkpasswd(f, password)) { + if (checkpasswd(f, password)) { + f->lastorders = turn; + } + else { log_debug("invalid password for faction %s", itoa36(no)); ADDMSG(&f->msgs, msg_message("wrongpasswd", "password", password)); } From 9a1bdf444439d0dfb7d18f0c37d3bea6b26a6f00 Mon Sep 17 00:00:00 2001 From: Enno Rehling Date: Thu, 4 Oct 2018 10:49:53 +0200 Subject: [PATCH 070/160] fix checker build and arg parsing --- src/checker.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/checker.c b/src/checker.c index f87b91891..4138a372a 100644 --- a/src/checker.c +++ b/src/checker.c @@ -4,6 +4,7 @@ #include "util/order_parser.h" +#include #include typedef struct parser_state { @@ -48,7 +49,7 @@ int parsefile(FILE *F) { int main(int argc, char **argv) { FILE * F = stdin; - if (argc >= 1) { + if (argc > 1) { const char *filename = argv[1]; F = fopen(filename, "r"); if (!F) { From 4f8dd4cb0f017323688f9bb7bcf30fdc407e920b Mon Sep 17 00:00:00 2001 From: Enno Rehling Date: Sat, 6 Oct 2018 20:47:23 +0200 Subject: [PATCH 071/160] checker is going to use locales, fix them up, too. --- src/CMakeLists.txt | 2 +- src/bind_eressea.c | 2 +- src/checker.c | 26 ++++++++++++++++++++++++++ src/kernel/config.c | 1 + src/platform.h | 7 ------- src/util/language.c | 15 +++------------ src/util/language.h | 4 ++-- src/util/log.c | 3 ++- src/util/path.h | 6 ++++++ 9 files changed, 42 insertions(+), 24 deletions(-) diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt index 8bb751258..4e8db8bf9 100644 --- a/src/CMakeLists.txt +++ b/src/CMakeLists.txt @@ -186,6 +186,7 @@ endif() add_library(version STATIC ${VERSION_SRC}) add_library(parser ${PARSER_SRC}) target_link_libraries(parser + ${CLIBS_LIBRARIES} ${CRYPTO_LIBRARIES} ) @@ -205,7 +206,6 @@ target_link_libraries(eressea ${TOLUA_LIBRARIES} ${LUA_LIBRARIES} ${STORAGE_LIBRARIES} - ${CLIBS_LIBRARIES} ${CJSON_LIBRARIES} ${INIPARSER_LIBRARIES} ) diff --git a/src/bind_eressea.c b/src/bind_eressea.c index e5acbac99..4d3918899 100755 --- a/src/bind_eressea.c +++ b/src/bind_eressea.c @@ -22,7 +22,7 @@ void eressea_free_game(void) { free_gamedata(); init_resources(); - init_locales(); + init_locales(init_locale); } int eressea_read_game(const char * filename) { diff --git a/src/checker.c b/src/checker.c index 4138a372a..a2c29dd7c 100644 --- a/src/checker.c +++ b/src/checker.c @@ -3,9 +3,14 @@ #endif #include "util/order_parser.h" +#include "util/keyword.h" +#include "util/language.h" +#include "util/path.h" +#include "util/pofile.h" #include #include +#include typedef struct parser_state { FILE * F; @@ -47,6 +52,26 @@ int parsefile(FILE *F) { return err; } +static int handle_po(const char *msgid, const char *msgstr, const char *msgctxt, void *data) { + struct locale *lang = (struct locale *)data; + if (msgctxt) { + if (strcmp(msgctxt, "keyword") == 0) { + keyword_t kwd = findkeyword(msgid); + init_keyword(lang, kwd, msgstr); + locale_setstring(lang, mkname("keyword", keywords[kwd]), msgstr); + } + } + return 0; +} + +static void read_config(const char *respath) { + char path[PATH_MAX]; + struct locale *lang; + lang = get_or_create_locale("de"); + path_join(respath, "translations/strings.de.po", path, sizeof(path)); + pofile_read(path, handle_po, lang); +} + int main(int argc, char **argv) { FILE * F = stdin; if (argc > 1) { @@ -57,6 +82,7 @@ int main(int argc, char **argv) { return -1; } } + read_config("../git"); parsefile(F); if (F != stdin) { fclose(F); diff --git a/src/kernel/config.c b/src/kernel/config.c index 75601e831..15387dca7 100644 --- a/src/kernel/config.c +++ b/src/kernel/config.c @@ -239,6 +239,7 @@ static void init_magic(struct locale *lang) free(sstr); } } + void init_locale(struct locale *lang) { init_magic(lang); diff --git a/src/platform.h b/src/platform.h index fdc3760f9..7b52782e3 100644 --- a/src/platform.h +++ b/src/platform.h @@ -4,8 +4,6 @@ #define _LP64 0 /* fix a warning in pdcurses 3.4 */ #endif -#ifdef _MSC_VER - /* @see https://developercommunity.visualstudio.com/content/problem/69874/warning-c4001-in-standard-library-stringh-header.html */ #if _MSC_VER >= 1900 #pragma warning(disable: 4710 4820 4001) @@ -17,10 +15,5 @@ #pragma warning(disable: 4214) // bit field types other than int #endif -/* @see https://insanecoding.blogspot.no/2007/11/pathmax-simply-isnt.html */ -#define PATH_MAX 260 - -#endif - #define MIN(a, b) (((a) < (b)) ? (a) : (b)) #define MAX(a, b) (((a) > (b)) ? (a) : (b)) diff --git a/src/util/language.c b/src/util/language.c index 77a7d2a4e..afc9d01d0 100644 --- a/src/util/language.c +++ b/src/util/language.c @@ -353,29 +353,20 @@ void *get_translation(const struct locale *lang, const char *str, int index) { return NULL; } -void locale_foreach(void(*callback)(const struct locale *, const char *)) { - const locale * lang; - for (lang = locales; lang; lang = lang->next) { - callback(lang, lang->name); - } -} - const char *localenames[] = { "de", "en", NULL }; -extern void init_locale(struct locale *lang); - static int locale_init = 0; -void init_locales(void) +void init_locales(locale_handler init) { locale * lang; if (locale_init) return; assert(locales); - for (lang = locales; lang; lang = lang->next) { - init_locale(lang); + for (lang = locales; lang; lang = nextlocale(lang)) { + init(lang); } locale_init = 1; } diff --git a/src/util/language.h b/src/util/language.h index f269a5f06..735fd4a95 100644 --- a/src/util/language.h +++ b/src/util/language.h @@ -39,7 +39,8 @@ extern "C" { /** managing multiple locales: **/ struct locale *get_locale(const char *name); struct locale *get_or_create_locale(const char *key); - void init_locales(void); + typedef void(*locale_handler)(struct locale *lang); + void init_locales(locale_handler callback); void free_locales(void); void reset_locales(void); @@ -57,7 +58,6 @@ extern "C" { void make_locales(const char *str); - void locale_foreach(void(*callback)(const struct locale *lang, const char *name)); void po_write_msg(FILE *F, const char *id, const char *str, const char *ctxt); #define LOC(lang, s) (lang?locale_string(lang, s, true):s) diff --git a/src/util/log.c b/src/util/log.c index 4b29332a8..b8549d60e 100644 --- a/src/util/log.c +++ b/src/util/log.c @@ -12,8 +12,9 @@ without prior permission by the authors of Eressea. #include #include "log.h" -#include "unicode.h" +#include "path.h" #include "strings.h" +#include "unicode.h" #include #include diff --git a/src/util/path.h b/src/util/path.h index 5a4e22270..649777171 100644 --- a/src/util/path.h +++ b/src/util/path.h @@ -1,4 +1,10 @@ +#pragma once #include +#ifdef _MSC_VER +/* @see https://insanecoding.blogspot.no/2007/11/pathmax-simply-isnt.html */ +#define PATH_MAX 260 +#endif + char * path_join(const char *p1, const char *p2, char *dst, size_t len); From 5964d551e3540e350e025662072a27643ff53047 Mon Sep 17 00:00:00 2001 From: Enno Rehling Date: Sat, 6 Oct 2018 20:53:26 +0200 Subject: [PATCH 072/160] PATH_MAX is just a stupid constant --- src/checker.c | 1 + 1 file changed, 1 insertion(+) diff --git a/src/checker.c b/src/checker.c index a2c29dd7c..27648e7af 100644 --- a/src/checker.c +++ b/src/checker.c @@ -9,6 +9,7 @@ #include "util/pofile.h" #include +#include #include #include From 3327e996e5b2bb7540c5dd52f997f9ad0811b35f Mon Sep 17 00:00:00 2001 From: Enno Rehling Date: Tue, 9 Oct 2018 19:27:33 +0200 Subject: [PATCH 073/160] Bei Neuauswertungen die Befehlsdatei neu erzeugen --- process/create-orders | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/process/create-orders b/process/create-orders index 4740dec2f..58235e2c9 100755 --- a/process/create-orders +++ b/process/create-orders @@ -16,6 +16,7 @@ else mv orders.dir "orders.dir.$TURN" mkdir -p orders.dir fi +rm -f "orders.$TURN" find "orders.dir.$TURN" -maxdepth 1 -type f -printf "%T+\t%p\n" | sort | cut -f2 | while read -r do cat "$REPLY" >> "orders.$TURN" @@ -23,7 +24,7 @@ done lockfile -r3 -l120 orders.queue.lock if [ -e orders.queue ] ; then - mv orders.queue "orders.dir.$TURN/orders.queue" + mv orders.queue "orders.queue.bak.$TURN" fi rm -f orders.queue.lock From ef3ccc8d104271644a10a6d7eacd0d9d6d4acfc0 Mon Sep 17 00:00:00 2001 From: Enno Rehling Date: Tue, 9 Oct 2018 19:40:26 +0200 Subject: [PATCH 074/160] fix use of new database for sendreport et al --- .gitignore | 1 + process/CMakeLists.txt | 4 ++-- process/epasswd.py | 2 +- process/getemail.py | 22 ++++++++++++++++++++++ process/sendreport.sh | 12 ++++-------- 5 files changed, 30 insertions(+), 11 deletions(-) create mode 100755 process/getemail.py diff --git a/.gitignore b/.gitignore index 3dcf24224..75ec9a227 100644 --- a/.gitignore +++ b/.gitignore @@ -25,6 +25,7 @@ ipch/ *.user *~ +*.pyc *.bak bin/ build*/ 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/epasswd.py b/process/epasswd.py index 4798967a9..4cac6e1ce 100755 --- a/process/epasswd.py +++ b/process/epasswd.py @@ -35,7 +35,7 @@ class EPasswd: def __init__(self): self.data = {} - def set_data(no, email, passwd): + def set_data(self, no, email, passwd): lc_id = lower(no) self.data[lc_id] = {} self.data[lc_id]["id"] = no 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/sendreport.sh b/process/sendreport.sh index d8fe79d47..7b1afccf0 100755 --- a/process/sendreport.sh +++ b/process/sendreport.sh @@ -45,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 - From 772386ffc7318fea8d0186fa04c6f4709bffdf2a Mon Sep 17 00:00:00 2001 From: Enno Rehling Date: Fri, 12 Oct 2018 20:46:48 +0200 Subject: [PATCH 075/160] debug logging did not help. nothing unusual here, just weirdly intermittent. --- scripts/tests/e3/buildings.lua | 10 +++------- 1 file changed, 3 insertions(+), 7 deletions(-) diff --git a/scripts/tests/e3/buildings.lua b/scripts/tests/e3/buildings.lua index 9899d138e..d5ea4fa51 100644 --- a/scripts/tests/e3/buildings.lua +++ b/scripts/tests/e3/buildings.lua @@ -34,22 +34,18 @@ function test_build_watch() local u = unit.create(f, r, 1) u.number = 20 - u:add_item("log", 20) + u:add_item("log", 30) u.id = 42 u:set_skill("building", 1) u:add_order("MACHE Wache") process_orders() assert_not_nil(u.building) - if 5 ~= u.building.size then - -- debug logging to find intermittent errors - for k,v in ipairs(f.messages) do - print(v) - end - end + -- stage two needs skill 2, this unit can only build a first stage: assert_equal(5, u.building.size) u:set_skill("building", 2) + u:clear_orders() u:add_order("MACHE Wache " .. itoa36(u.building.id)) process_orders() assert_not_nil(u.building) From 7b682c6a745c5509ebfb33a4b24d7d7d68ffa614 Mon Sep 17 00:00:00 2001 From: Enno Rehling Date: Sat, 13 Oct 2018 20:30:28 +0200 Subject: [PATCH 076/160] rename defence->defense (prefer US spelling). --- src/battle.c | 14 +++++++------- src/battle.h | 2 +- src/battle.test.c | 6 +++--- src/spells/combatspells.c | 8 ++++---- 4 files changed, 15 insertions(+), 15 deletions(-) diff --git a/src/battle.c b/src/battle.c index b7e4b92a3..6ab969c93 100644 --- a/src/battle.c +++ b/src/battle.c @@ -1138,7 +1138,7 @@ static void demon_dazzle(fighter *af, troop dt) { 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].defence--; + df->person[dt.index].defense--; } } } @@ -1191,7 +1191,7 @@ static void destroy_items(troop dt) { } -static void calculate_defence_type(troop dt, troop at, int type, bool missile, +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 */ @@ -1320,7 +1320,7 @@ terminate(troop dt, troop at, int type, const char *damage_formula, bool missile ++at.fighter->hits; calculate_attack_type(at, dt, type, missile, &awtype, &attskill, &magic); - calculate_defence_type(at, dt, type, missile, &awtype, &attskill); + calculate_defense_type(at, dt, type, missile, &awtype, &attskill); if (is_riding(at) && (awtype == NULL || (fval(awtype, WTF_HORSEBONUS) && !fval(awtype, WTF_MISSILE)))) { @@ -1946,7 +1946,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; @@ -2075,7 +2075,7 @@ 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) @@ -2241,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--; } @@ -3184,7 +3184,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; diff --git a/src/battle.h b/src/battle.h index bad2dd508..eb6335bce 100644 --- a/src/battle.h +++ b/src/battle.h @@ -173,7 +173,7 @@ extern "C" { struct person { int hp; /* Trefferpunkte der Personen */ int attack; - int defence; + int defense; int damage; int flags; int speed; diff --git a/src/battle.test.c b/src/battle.test.c index 20b167c1f..53c47f0e5 100644 --- a/src/battle.test.c +++ b/src/battle.test.c @@ -303,7 +303,7 @@ static void test_building_bonus_respects_size(CuTest * tc) test_teardown(); } -static void test_building_defence_bonus(CuTest * tc) +static void test_building_defense_bonus(CuTest * tc) { building_type * btype; @@ -570,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; @@ -888,7 +888,7 @@ 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); diff --git a/src/spells/combatspells.c b/src/spells/combatspells.c index 6d6b846c3..c088dde07 100644 --- a/src/spells/combatspells.c +++ b/src/spells/combatspells.c @@ -956,7 +956,7 @@ int sp_hero(struct castorder * co) if (df) { if (!(df->person[dt.index].flags & FL_COURAGE)) { - df->person[dt.index].defence += df_bonus; + df->person[dt.index].defense += df_bonus; df->person[dt.index].flags = df->person[dt.index].flags | FL_COURAGE; targets++; --force; @@ -1005,7 +1005,7 @@ int sp_berserk(struct castorder * co) if (df) { if (!(df->person[dt.index].flags & FL_COURAGE)) { df->person[dt.index].attack += at_bonus; - df->person[dt.index].defence -= df_malus; + df->person[dt.index].defense -= df_malus; df->person[dt.index].flags = df->person[dt.index].flags | FL_COURAGE; targets++; --force; @@ -1064,7 +1064,7 @@ int sp_frighten(struct castorder * co) } if (!is_magic_resistant(mage, df->unit, 0)) { df->person[dt.index].attack -= at_malus; - df->person[dt.index].defence -= df_malus; + df->person[dt.index].defense -= df_malus; targets++; } --force; @@ -1109,7 +1109,7 @@ int sp_tiredsoldiers(struct castorder * co) if (!(df->person[t.index].flags & FL_TIRED)) { if (!is_magic_resistant(mage, df->unit, 0)) { df->person[t.index].flags = df->person[t.index].flags | FL_TIRED; - df->person[t.index].defence -= 2; + df->person[t.index].defense -= 2; ++n; } } From 7c89b51ff7c0e9f3a23377dd338222e8c24d5535 Mon Sep 17 00:00:00 2001 From: Enno Rehling Date: Sun, 14 Oct 2018 11:31:00 +0200 Subject: [PATCH 077/160] remove reference to preview.db --- s/preview | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/s/preview b/s/preview index c4c9a5d42..2fde22cda 100755 --- a/s/preview +++ b/s/preview @@ -55,7 +55,8 @@ cd $TESTROOT cat >| eressea.ini < Date: Sun, 14 Oct 2018 11:47:59 +0200 Subject: [PATCH 078/160] BUG 2209: Monster, die attackieren, sollen sich in der selben Runde nicht auch noch bewegen. --- src/monsters.c | 53 +++++++++++++++++++++++++-------------------- src/monsters.test.c | 4 ++-- 2 files changed, 31 insertions(+), 26 deletions(-) diff --git a/src/monsters.c b/src/monsters.c index 867d601c6..42ab8938a 100644 --- a/src/monsters.c +++ b/src/monsters.c @@ -56,7 +56,6 @@ #include #include "util/keyword.h" #include "util/language.h" -#include #include #include #include @@ -203,6 +202,7 @@ void monsters_desert(struct faction *monsters) int monster_attacks(unit * monster, bool rich_only) { const race *rc_serpent = get_race(RC_SEASERPENT); + int result = -1; if (monster->status < ST_AVOID) { region *r = monster->region; unit *u2; @@ -220,15 +220,16 @@ int monster_attacks(unit * monster, bool rich_only) if (!rich_only || m > 0) { order *ord = monster_attack(monster, u2); if (ord) { - addlist(&monster->orders, ord); + result = 0; + unit_addorder(monster, ord); money += m; } } } } - return money; + return money > 0 ? money : result; } - return 0; + return result; } static order *get_money_for_dragon(region * r, unit * udragon, int wanted) @@ -249,7 +250,8 @@ static order *get_money_for_dragon(region * r, unit * udragon, int wanted) * und holt sich Silber von Einheiten, vorausgesetzt er bewacht bereits */ money = 0; if (attacks && is_guard(udragon)) { - money += monster_attacks(udragon, true); + int m = monster_attacks(udragon, true); + if (m > 0) money += m; } /* falls die einnahmen erreicht werden, bleibt das monster noch eine */ @@ -737,19 +739,12 @@ void plan_monsters(faction * f) for (r = regions; r; r = r->next) { unit *u; - bool attacking = false; - /* Tiny optimization: Monsters on land only attack randomly when - * they are guarding. If nobody is guarding this region (RF_GUARDED), - * there can't be any random attacks. - */ - if (!r->land || r->flags & RF_GUARDED) { - attacking = chance(attack_chance); - } for (u = r->units; u; u = u->next) { const race *rc = u_race(u); attrib *ta; order *long_order = NULL; + bool can_move = true; /* Ab hier nur noch Befehle f�r NPC-Einheiten. */ if (u->faction!=f) @@ -760,16 +755,19 @@ void plan_monsters(faction * f) u->flags &= ~UFL_ANON_FACTION; } - /* Befehle m�ssen jede Runde neu gegeben werden: */ - free_orders(&u->orders); if (skill_enabled(SK_PERCEPTION)) { /* Monster bekommen jede Runde ein paar Tage Wahrnehmung dazu */ produceexp(u, SK_PERCEPTION, u->number); } - if (attacking && (!r->land || is_guard(u))) { - monster_attacks(u, false); + /* Befehle m�ssen jede Runde neu gegeben werden: */ + free_orders(&u->orders); + + /* All monsters guard the region: */ + if (u->status < ST_FLEE && !monster_is_waiting(u) && r->land) { + unit_addorder(u, create_order(K_GUARD, u->faction->locale, NULL)); } + /* units with a plan to kill get ATTACK orders (even if they don't guard): */ ta = a_find(u->attribs, &at_hate); if (ta && !monster_is_waiting(u)) { @@ -777,7 +775,8 @@ void plan_monsters(faction * f) if (tu && tu->region == r) { order * ord = monster_attack(u, tu); if (ord) { - addlist(&u->orders, ord); + unit_addorder(u, ord); + can_move = false; } } else if (tu) { @@ -786,17 +785,22 @@ void plan_monsters(faction * f) allowed = allowed_fly; } long_order = plan_move_to_target(u, tu->region, 2, allowed); + can_move = false; } else a_remove(&u->attribs, ta); } - /* All monsters guard the region: */ - if (u->status < ST_FLEE && !monster_is_waiting(u) && r->land) { - addlist(&u->orders, create_order(K_GUARD, u->faction->locale, NULL)); + else if (!r->land || is_guard(u)) { + if (chance(attack_chance)) { + int m = monster_attacks(u, false); + if (m >= 0) { + can_move = false; + } + } } /* Einheiten mit Bewegungsplan kriegen ein NACH: */ - if (long_order == NULL) { + if (can_move && long_order == NULL) { ta = a_find(u->attribs, &at_targetregion); if (ta) { if (u->region == (region *)ta->data.v) { @@ -817,7 +821,7 @@ void plan_monsters(faction * f) long_order = plan_dragon(u); } else { - if (rc == get_race(RC_SEASERPENT)) { + if (can_move && rc == get_race(RC_SEASERPENT)) { long_order = create_order(K_PIRACY, f->locale, NULL); } else { @@ -827,6 +831,7 @@ void plan_monsters(faction * f) } } } + if (long_order == NULL && unit_can_study(u)) { /* Einheiten, die Waffenlosen Kampf lernen k�nnten, lernen es um * zu bewachen: */ @@ -840,7 +845,7 @@ void plan_monsters(faction * f) } if (long_order) { - addlist(&u->orders, long_order); + unit_addorder(u, long_order); } } } diff --git a/src/monsters.test.c b/src/monsters.test.c index 4ea3a32a3..75a2cbc97 100644 --- a/src/monsters.test.c +++ b/src/monsters.test.c @@ -123,7 +123,7 @@ static void test_monsters_waiting(CuTest * tc) setguard(m, true); fset(m, UFL_ISNEW); monster_attacks(m, false); - CuAssertPtrEquals(tc, 0, find_order("attack 1", m)); + CuAssertPtrEquals(tc, NULL, find_order("attack 1", m)); test_teardown(); } @@ -173,7 +173,7 @@ static void test_monsters_attack_not(CuTest * tc) plan_monsters(m->faction); - CuAssertPtrEquals(tc, 0, find_order("attack 1", m)); + CuAssertPtrEquals(tc, NULL, find_order("attack 1", m)); test_teardown(); } From a7b9f6dc3e89071a789818a054846476832bf043 Mon Sep 17 00:00:00 2001 From: Enno Rehling Date: Sun, 14 Oct 2018 11:48:21 +0200 Subject: [PATCH 079/160] Do not use 0 to mean NULL pointers. --- clibs | 2 +- src/alchemy.test.c | 24 +++++++------- src/automate.c | 28 +++++++++-------- src/battle.test.c | 8 ++--- src/economy.test.c | 12 +++---- src/give.test.c | 8 ++--- src/guard.test.c | 2 +- src/json.test.c | 6 ++-- src/kernel/alliance.test.c | 28 ++++++++--------- src/kernel/ally.test.c | 6 ++-- src/kernel/attrib.test.c | 22 ++++++------- src/kernel/build.test.c | 8 ++--- src/kernel/command.test.c | 4 +-- src/kernel/faction.test.c | 10 +++--- src/kernel/group.test.c | 12 +++---- src/kernel/item.test.c | 14 ++++----- src/kernel/messages.test.c | 4 +-- src/kernel/order.test.c | 4 +-- src/kernel/plane.test.c | 10 +++--- src/kernel/region.test.c | 4 +-- src/kernel/save.test.c | 24 +++++++------- src/kernel/ship.test.c | 10 +++--- src/kernel/spell.test.c | 10 +++--- src/kernel/spellbook.test.c | 2 +- src/kernel/unit.test.c | 40 ++++++++++++------------ src/laws.test.c | 62 ++++++++++++++++++------------------- src/magic.test.c | 14 ++++----- src/move.test.c | 20 ++++++------ src/piracy.test.c | 6 ++-- src/prefix.test.c | 8 ++--- src/reports.test.c | 30 +++++++++--------- src/spy.test.c | 2 +- src/tests.test.c | 6 ++-- 33 files changed, 226 insertions(+), 224 deletions(-) diff --git a/clibs b/clibs index d86c85254..12139c7ce 160000 --- a/clibs +++ b/clibs @@ -1 +1 @@ -Subproject commit d86c8525489d7f11b7ba13e101bb59ecf160b871 +Subproject commit 12139c7ce25e6731393f863e248ab16aa0578a3a diff --git a/src/alchemy.test.c b/src/alchemy.test.c index 7510933fe..32e0c84a5 100644 --- a/src/alchemy.test.c +++ b/src/alchemy.test.c @@ -45,16 +45,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); @@ -62,9 +62,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); @@ -73,10 +73,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/automate.c b/src/automate.c index 24c34e903..c2b07fbd0 100644 --- a/src/automate.c +++ b/src/automate.c @@ -36,20 +36,22 @@ int autostudy_init(scholar scholars[], int max_scholars, region *r) for (u = r->units; u; u = u->next) { keyword_t kwd = getkeyword(u->thisorder); if (kwd == K_AUTOSTUDY) { - if (long_order_allowed(u) && unit_can_study(u)) { - scholar * st = scholars + nscholars; - init_order(u->thisorder, u->faction->locale); - st->sk = getskill(u->faction->locale); - st->level = effskill_study(u, st->sk); - st->learn = 0; - st->u = u; - if (++nscholars == max_scholars) { - log_fatal("you must increase MAXSCHOLARS"); + if (long_order_allowed(u)) { + if (unit_can_study(u)) { + scholar * st = scholars + nscholars; + init_order(u->thisorder, u->faction->locale); + st->sk = getskill(u->faction->locale); + st->level = effskill_study(u, st->sk); + st->learn = 0; + st->u = u; + if (++nscholars == max_scholars) { + log_fatal("you must increase MAXSCHOLARS"); + } + } + else { + ADDMSG(&u->faction->msgs, msg_feedback(u, u->thisorder, "error_race_nolearn", "race", + u_race(u))); } - } - else { - ADDMSG(&u->faction->msgs, msg_feedback(u, u->thisorder, "error_race_nolearn", "race", - u_race(u))); } } } diff --git a/src/battle.test.c b/src/battle.test.c index 53c47f0e5..92a26e692 100644 --- a/src/battle.test.c +++ b/src/battle.test.c @@ -78,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); @@ -216,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; @@ -261,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(); } @@ -298,7 +298,7 @@ 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(); } diff --git a/src/economy.test.c b/src/economy.test.c index 0b213ba7e..5425ca56f 100644 --- a/src/economy.test.c +++ b/src/economy.test.c @@ -357,7 +357,7 @@ static void test_tax_cmd(CuTest *tc) { set_level(u, SK_TAXING, 1); tax_cmd(u, ord, &taxorders); - CuAssertPtrEquals(tc, 0, test_find_messagetype(u->faction->msgs, "error_no_tax_skill")); + CuAssertPtrEquals(tc, NULL, test_find_messagetype(u->faction->msgs, "error_no_tax_skill")); CuAssertPtrNotNull(tc, taxorders); rsetmoney(r, 11); @@ -415,8 +415,8 @@ static void test_maintain_buildings(CuTest *tc) { b->flags = 0; maintain_buildings(r); CuAssertIntEquals(tc, BLD_MAINTAINED, fval(b, BLD_MAINTAINED)); - CuAssertPtrEquals(tc, 0, f->msgs); - CuAssertPtrEquals(tc, 0, r->msgs); + CuAssertPtrEquals(tc, NULL, f->msgs); + CuAssertPtrEquals(tc, NULL, r->msgs); req = calloc(2, sizeof(maintenance)); req[0].number = 100; @@ -438,8 +438,8 @@ static void test_maintain_buildings(CuTest *tc) { maintain_buildings(r); CuAssertIntEquals(tc, BLD_MAINTAINED, fval(b, BLD_MAINTAINED)); CuAssertIntEquals(tc, 0, i_get(u->items, itype)); - CuAssertPtrEquals(tc, 0, r->msgs); - CuAssertPtrEquals(tc, 0, test_find_messagetype(f->msgs, "maintenance_nowork")); + CuAssertPtrEquals(tc, NULL, r->msgs); + CuAssertPtrEquals(tc, NULL, test_find_messagetype(f->msgs, "maintenance_nowork")); CuAssertPtrNotNull(tc, test_find_messagetype(f->msgs, "maintenance")); test_clear_messagelist(&f->msgs); @@ -448,7 +448,7 @@ static void test_maintain_buildings(CuTest *tc) { b->flags = 0; maintain_buildings(r); CuAssertIntEquals(tc, 0, fval(b, BLD_MAINTAINED)); - CuAssertPtrEquals(tc, 0, f->msgs); + CuAssertPtrEquals(tc, NULL, f->msgs); CuAssertPtrNotNull(tc, test_find_messagetype(r->msgs, "maintenance_noowner")); test_clear_messagelist(&r->msgs); diff --git a/src/give.test.c b/src/give.test.c index 06c0ecf96..806901c46 100644 --- a/src/give.test.c +++ b/src/give.test.c @@ -92,7 +92,7 @@ static void test_give_unit(CuTest * tc) { give_unit(env.src, env.dst, NULL); CuAssertPtrEquals(tc, env.f2, env.src->faction); CuAssertIntEquals(tc, 1, env.f2->newbies); - CuAssertPtrEquals(tc, 0, env.f1->units); + CuAssertPtrEquals(tc, NULL, env.f1->units); CuAssertPtrNotNull(tc, test_find_messagetype(env.f1->msgs, "give_person")); CuAssertPtrNotNull(tc, test_find_messagetype(env.f2->msgs, "receive_person")); test_teardown(); @@ -304,7 +304,7 @@ static void test_give_men_requires_contact(CuTest * tc) { ord = create_order(K_GIVE, env.f1->locale, "%s ALLES PERSONEN", itoa36(env.dst->no)); test_clear_messages(env.f1); give_cmd(env.src, ord); - CuAssertPtrEquals(tc, 0, test_find_messagetype(env.f1->msgs, "give_person")); + CuAssertPtrEquals(tc, NULL, test_find_messagetype(env.f1->msgs, "give_person")); CuAssertPtrNotNull(tc, test_find_messagetype(env.f1->msgs, "feedback_no_contact")); msg_release(msg); @@ -408,7 +408,7 @@ static void test_give_okay(CuTest * tc) { setup_give(&env); config_set("rules.give.flags", "0"); - CuAssertPtrEquals(tc, 0, check_give(env.src, env.dst, NULL)); + CuAssertPtrEquals(tc, NULL, check_give(env.src, env.dst, NULL)); test_teardown(); } @@ -451,7 +451,7 @@ static void test_give_new_unit(CuTest * tc) { setup_give(&env); env.dst->number = 0; fset(env.dst, UFL_ISNEW); - CuAssertPtrEquals(tc, 0, check_give(env.src, env.dst, NULL)); + CuAssertPtrEquals(tc, NULL, check_give(env.src, env.dst, NULL)); test_teardown(); } diff --git a/src/guard.test.c b/src/guard.test.c index 6264aad21..1c4da2d1f 100644 --- a/src/guard.test.c +++ b/src/guard.test.c @@ -29,7 +29,7 @@ static void test_is_guarded(CuTest *tc) { r = test_create_region(0, 0, NULL); u1 = test_create_unit(test_create_faction(NULL), r); u2 = test_create_unit(test_create_faction(rc), r); - CuAssertPtrEquals(tc, 0, is_guarded(r, u1)); + CuAssertPtrEquals(tc, NULL, is_guarded(r, u1)); setguard(u2, true); CuAssertPtrEquals(tc, u2, is_guarded(r, u1)); test_teardown(); diff --git a/src/json.test.c b/src/json.test.c index 48a5e4be6..30d4e072e 100644 --- a/src/json.test.c +++ b/src/json.test.c @@ -71,8 +71,8 @@ static cJSON *export_a_region(CuTest * tc, const struct terrain_type *terrain, r json = cJSON_Parse(buf); CuAssertPtrNotNull(tc, json); CuAssertIntEquals(tc, cJSON_Object, json->type); - CuAssertPtrEquals(tc, 0, cJSON_GetObjectItem(json, "factions")); - CuAssertPtrEquals(tc, 0, cJSON_GetObjectItem(json, "units")); + CuAssertPtrEquals(tc, NULL, cJSON_GetObjectItem(json, "factions")); + CuAssertPtrEquals(tc, NULL, cJSON_GetObjectItem(json, "units")); CuAssertPtrNotNull(tc, regs = cJSON_GetObjectItem(json, "regions")); CuAssertIntEquals(tc, cJSON_Object, regs->type); result = regs->child; @@ -111,7 +111,7 @@ static void test_export_ocean_region(CuTest * tc) { test_setup(); terrain = test_create_terrain("ocean", SEA_REGION); json = export_a_region(tc, terrain, 0); - CuAssertPtrEquals(tc, 0, cJSON_GetObjectItem(json, "name")); + CuAssertPtrEquals(tc, NULL, cJSON_GetObjectItem(json, "name")); cJSON_Delete(json); test_teardown(); } diff --git a/src/kernel/alliance.test.c b/src/kernel/alliance.test.c index 00fe1f4d9..284d57d27 100644 --- a/src/kernel/alliance.test.c +++ b/src/kernel/alliance.test.c @@ -34,14 +34,14 @@ static void test_alliance_make(CuTest *tc) { CuAssertStrEquals(tc, "Hodor", al->name); CuAssertIntEquals(tc, 1, al->id); CuAssertIntEquals(tc, 0, al->flags); - CuAssertPtrEquals(tc, 0, al->members); - CuAssertPtrEquals(tc, 0, al->_leader); - CuAssertPtrEquals(tc, 0, al->allies); + CuAssertPtrEquals(tc, NULL, al->members); + CuAssertPtrEquals(tc, NULL, al->_leader); + CuAssertPtrEquals(tc, NULL, al->allies); CuAssertPtrEquals(tc, al, findalliance(1)); CuAssertPtrEquals(tc, al, alliances); free_alliances(); - CuAssertPtrEquals(tc, 0, findalliance(1)); - CuAssertPtrEquals(tc, 0, alliances); + CuAssertPtrEquals(tc, NULL, findalliance(1)); + CuAssertPtrEquals(tc, NULL, alliances); test_teardown(); } @@ -50,8 +50,8 @@ static void test_alliance_join(CuTest *tc) { alliance * al; setup_alliance(&fix); - CuAssertPtrEquals(tc, 0, fix.f1->alliance); - CuAssertPtrEquals(tc, 0, fix.f2->alliance); + CuAssertPtrEquals(tc, NULL, fix.f1->alliance); + CuAssertPtrEquals(tc, NULL, fix.f2->alliance); al = makealliance(1, "Hodor"); setalliance(fix.f1, al); CuAssertPtrEquals(tc, fix.f1, alliance_get_leader(al)); @@ -99,7 +99,7 @@ static void test_alliance_cmd(CuTest *tc) { unit_addorder(u2, create_order(K_ALLIANCE, u1->faction->locale, "%s %s", alliance_kwd[ALLIANCE_JOIN], itoa36(42))); CuAssertTrue(tc, is_allied(u1->faction, u1->faction)); CuAssertTrue(tc, !is_allied(u1->faction, u2->faction)); - CuAssertPtrEquals(tc, 0, f_get_alliance(u1->faction)); + CuAssertPtrEquals(tc, NULL, f_get_alliance(u1->faction)); alliance_cmd(); al = f_get_alliance(u1->faction); CuAssertPtrNotNull(tc, al); @@ -126,10 +126,10 @@ static void test_alliance_limits(CuTest *tc) { unit_addorder(u1, create_order(K_ALLIANCE, u1->faction->locale, "%s %s", alliance_kwd[ALLIANCE_INVITE], itoa36(u2->faction->no))); unit_addorder(u2, create_order(K_ALLIANCE, u1->faction->locale, "%s %s", alliance_kwd[ALLIANCE_JOIN], itoa36(42))); CuAssertTrue(tc, !is_allied(u1->faction, u2->faction)); - CuAssertPtrEquals(tc, 0, f_get_alliance(u1->faction)); + CuAssertPtrEquals(tc, NULL, f_get_alliance(u1->faction)); alliance_cmd(); CuAssertPtrNotNull(tc, f_get_alliance(u1->faction)); - CuAssertPtrEquals(tc, 0, f_get_alliance(u2->faction)); + CuAssertPtrEquals(tc, NULL, f_get_alliance(u2->faction)); CuAssertTrue(tc, !is_allied(u1->faction, u2->faction)); CuAssertPtrNotNull(tc, test_find_messagetype(u2->faction->msgs, "too_many_units_in_alliance")); test_teardown(); @@ -152,7 +152,7 @@ static void test_alliance_cmd_kick(CuTest *tc) { CuAssertTrue(tc, is_allied(u1->faction, u2->faction)); alliance_cmd(); CuAssertTrue(tc, !is_allied(u1->faction, u2->faction)); - CuAssertPtrEquals(tc, 0, f_get_alliance(u2->faction)); + CuAssertPtrEquals(tc, NULL, f_get_alliance(u2->faction)); test_teardown(); } @@ -168,10 +168,10 @@ static void test_alliance_cmd_no_invite(CuTest *tc) { unit_addorder(u2, create_order(K_ALLIANCE, u1->faction->locale, "%s %s", alliance_kwd[ALLIANCE_JOIN], itoa36(42))); CuAssertTrue(tc, is_allied(u1->faction, u1->faction)); CuAssertTrue(tc, !is_allied(u1->faction, u2->faction)); - CuAssertPtrEquals(tc, 0, f_get_alliance(u1->faction)); + CuAssertPtrEquals(tc, NULL, f_get_alliance(u1->faction)); alliance_cmd(); CuAssertPtrNotNull(tc, f_get_alliance(u1->faction)); - CuAssertPtrEquals(tc, 0, f_get_alliance(u2->faction)); + CuAssertPtrEquals(tc, NULL, f_get_alliance(u2->faction)); CuAssertTrue(tc, !is_allied(u1->faction, u2->faction)); test_teardown(); } @@ -193,7 +193,7 @@ static void test_alliance_cmd_leave(CuTest *tc) { CuAssertTrue(tc, is_allied(u1->faction, u2->faction)); alliance_cmd(); CuAssertTrue(tc, !is_allied(u1->faction, u2->faction)); - CuAssertPtrEquals(tc, 0, f_get_alliance(u1->faction)); + CuAssertPtrEquals(tc, NULL, f_get_alliance(u1->faction)); test_teardown(); } diff --git a/src/kernel/ally.test.c b/src/kernel/ally.test.c index 66542a298..99d220151 100644 --- a/src/kernel/ally.test.c +++ b/src/kernel/ally.test.c @@ -15,8 +15,8 @@ static void test_ally(CuTest * tc) CuAssertPtrEquals(tc, f1, ally_find(al, f1)->faction); ally_remove(&al, f1); - CuAssertPtrEquals(tc, 0, al); - CuAssertPtrEquals(tc, 0, ally_find(al, f1)); + CuAssertPtrEquals(tc, NULL, al); + CuAssertPtrEquals(tc, NULL, ally_find(al, f1)); } static void test_ally_null(CuTest * tc) @@ -28,7 +28,7 @@ static void test_ally_null(CuTest * tc) CuAssertPtrNotNull(tc, a1); CuAssertPtrNotNull(tc, a2); CuAssertPtrEquals(tc, a2, a1->next); - CuAssertPtrEquals(tc, 0, a2->next); + CuAssertPtrEquals(tc, NULL, a2->next); free(a1); free(a2); } diff --git a/src/kernel/attrib.test.c b/src/kernel/attrib.test.c index 918b768fd..de024c46d 100644 --- a/src/kernel/attrib.test.c +++ b/src/kernel/attrib.test.c @@ -15,11 +15,11 @@ static void test_attrib_new(CuTest * tc) attrib_type at_test = { "test" }; attrib * a; CuAssertPtrNotNull(tc, (a = a_new(&at_test))); - CuAssertPtrEquals(tc, 0, a->next); - CuAssertPtrEquals(tc, 0, a->nexttype); + CuAssertPtrEquals(tc, NULL, a->next); + CuAssertPtrEquals(tc, NULL, a->nexttype); CuAssertPtrEquals(tc, (void *)a->type, (void *)&at_test); a_remove(&a, a); - CuAssertPtrEquals(tc, 0, a); + CuAssertPtrEquals(tc, NULL, a); } static void test_attrib_add(CuTest * tc) @@ -51,7 +51,7 @@ static void test_attrib_remove_self(CuTest * tc) { CuAssertPtrNotNull(tc, a_add(&alist, a_new(&at_foo))); CuAssertPtrNotNull(tc, a = a_add(&alist, a_new(&at_foo))); CuAssertPtrEquals(tc, a, alist->next); - CuAssertPtrEquals(tc, 0, alist->nexttype); + CuAssertPtrEquals(tc, NULL, alist->nexttype); CuAssertIntEquals(tc, 1, a_remove(&alist, alist)); CuAssertPtrEquals(tc, a, alist); a_removeall(&alist, NULL); @@ -66,11 +66,11 @@ static void test_attrib_removeall(CuTest * tc) { a_add(&alist, a_new(&at_foo)); a_removeall(&alist, &at_foo); CuAssertPtrEquals(tc, a, alist); - CuAssertPtrEquals(tc, 0, alist->next); + CuAssertPtrEquals(tc, NULL, alist->next); a_add(&alist, a_new(&at_bar)); a_add(&alist, a_new(&at_foo)); a_removeall(&alist, NULL); - CuAssertPtrEquals(tc, 0, alist); + CuAssertPtrEquals(tc, NULL, alist); } static void test_attrib_remove(CuTest * tc) @@ -83,7 +83,7 @@ static void test_attrib_remove(CuTest * tc) CuAssertIntEquals(tc, 1, a_remove(&alist, a)); CuAssertPtrNotNull(tc, alist); CuAssertIntEquals(tc, 1, a_remove(&alist, alist)); - CuAssertPtrEquals(tc, 0, alist); + CuAssertPtrEquals(tc, NULL, alist); } static void test_attrib_nexttype(CuTest * tc) @@ -92,16 +92,16 @@ static void test_attrib_nexttype(CuTest * tc) attrib_type at_bar = { "bar" }; attrib *a, *alist = 0; CuAssertPtrNotNull(tc, (a = a_new(&at_foo))); - CuAssertPtrEquals(tc, 0, a->nexttype); + CuAssertPtrEquals(tc, NULL, a->nexttype); CuAssertPtrEquals(tc, a, a_add(&alist, a)); - CuAssertPtrEquals(tc, 0, alist->nexttype); + CuAssertPtrEquals(tc, NULL, alist->nexttype); CuAssertPtrNotNull(tc, a_add(&alist, a_new(&at_foo))); - CuAssertPtrEquals(tc, 0, alist->nexttype); + CuAssertPtrEquals(tc, NULL, alist->nexttype); CuAssertPtrNotNull(tc, (a = a_add(&alist, a_new(&at_bar)))); CuAssertPtrEquals(tc, a, alist->nexttype); - CuAssertPtrEquals(tc, 0, a->nexttype); + CuAssertPtrEquals(tc, NULL, a->nexttype); a_remove(&alist, alist); CuAssertPtrEquals(tc, a, alist->nexttype); diff --git a/src/kernel/build.test.c b/src/kernel/build.test.c index 2607b2dfb..ae3e47d0d 100644 --- a/src/kernel/build.test.c +++ b/src/kernel/build.test.c @@ -202,8 +202,8 @@ static void test_build_building_no_materials(CuTest *tc) { set_level(u, SK_BUILDING, 1); u->orders = create_order(K_MAKE, u->faction->locale, 0); CuAssertIntEquals(tc, ENOMATERIALS, build_building(u, btype, 0, 4, u->orders)); - CuAssertPtrEquals(tc, 0, u->region->buildings); - CuAssertPtrEquals(tc, 0, u->building); + CuAssertPtrEquals(tc, NULL, u->region->buildings); + CuAssertPtrEquals(tc, NULL, u->building); teardown_build(&bf); } @@ -267,7 +267,7 @@ static void test_build_destroy_road(CuTest *tc) CuAssertIntEquals(tc, 0, destroy_cmd(u, ord)); CuAssertIntEquals(tc, 100, rroad(r, D_EAST)); - CuAssertPtrEquals(tc, 0, test_find_messagetype(f->msgs, "destroy_road")); + CuAssertPtrEquals(tc, NULL, test_find_messagetype(f->msgs, "destroy_road")); set_level(u, SK_ROAD_BUILDING, 1); CuAssertIntEquals(tc, 0, destroy_cmd(u, ord)); @@ -324,7 +324,7 @@ static void test_build_destroy_road_guard(CuTest *tc) CuAssertIntEquals(tc, 0, destroy_cmd(u, ord)); CuAssertIntEquals(tc, 100, rroad(r, D_EAST)); CuAssertPtrNotNull(tc, test_find_messagetype(f->msgs, "error70")); - CuAssertPtrEquals(tc, 0, test_find_messagetype(f->msgs, "destroy_road")); + CuAssertPtrEquals(tc, NULL, test_find_messagetype(f->msgs, "destroy_road")); test_clear_messages(f); setguard(ug, false); diff --git a/src/kernel/command.test.c b/src/kernel/command.test.c index d173474f2..4c7bbb362 100644 --- a/src/kernel/command.test.c +++ b/src/kernel/command.test.c @@ -37,8 +37,8 @@ static void test_command(CuTest * tc) { st = stree_create(); CuAssertPtrNotNull(tc, st); CuAssertPtrEquals(tc, loc, (struct locale *)st->lang); - CuAssertPtrEquals(tc, 0, st->root); - CuAssertPtrEquals(tc, 0, st->next); + CuAssertPtrEquals(tc, NULL, st->root); + CuAssertPtrEquals(tc, NULL, st->next); stree_add(st, "two", parser_two); stree_add(st, "six", parser_six); CuAssertPtrNotNull(tc, st->root); diff --git a/src/kernel/faction.test.c b/src/kernel/faction.test.c index 9cd5d9de8..d2931c669 100644 --- a/src/kernel/faction.test.c +++ b/src/kernel/faction.test.c @@ -57,7 +57,7 @@ static void test_remove_empty_factions_alliance(CuTest *tc) { CuAssertPtrEquals(tc, f, alliance_get_leader(al)); CuAssertIntEquals(tc, 1, selist_length(al->members)); remove_empty_factions(); - CuAssertPtrEquals(tc, 0, al->_leader); + CuAssertPtrEquals(tc, NULL, al->_leader); CuAssertIntEquals(tc, 0, selist_length(al->members)); test_teardown(); } @@ -75,7 +75,7 @@ static void test_remove_empty_factions(CuTest *tc) { CuAssertIntEquals(tc, false, f->_alive); CuAssertPtrEquals(tc, fm, factions); CuAssertPtrEquals(tc, NULL, fm->next); - CuAssertPtrEquals(tc, 0, findfaction(fno)); + CuAssertPtrEquals(tc, NULL, findfaction(fno)); CuAssertPtrEquals(tc, fm, get_monsters()); test_teardown(); } @@ -99,7 +99,7 @@ static void test_remove_dead_factions(CuTest *tc) { f->_alive = false; fno = f->no; remove_empty_factions(); - CuAssertPtrEquals(tc, 0, findfaction(fno)); + CuAssertPtrEquals(tc, NULL, findfaction(fno)); CuAssertPtrEquals(tc, fm, get_monsters()); test_teardown(); } @@ -162,7 +162,7 @@ static void test_set_origin(CuTest *tc) { test_setup(); pl = create_new_plane(0, "", 0, 19, 0, 19, 0); f = test_create_faction(NULL); - CuAssertPtrEquals(tc, 0, f->ursprung); + CuAssertPtrEquals(tc, NULL, f->ursprung); faction_setorigin(f, 0, 1, 1); CuAssertIntEquals(tc, 0, f->ursprung->id); CuAssertIntEquals(tc, 1, f->ursprung->x); @@ -250,7 +250,7 @@ static void test_set_email(CuTest *tc) { faction_setemail(f, "bugs@eressea.de"); CuAssertStrEquals(tc, "bugs@eressea.de", f->email); faction_setemail(f, NULL); - CuAssertPtrEquals(tc, 0, f->email); + CuAssertPtrEquals(tc, NULL, f->email); CuAssertStrEquals(tc, "", faction_getemail(f)); test_teardown(); } diff --git a/src/kernel/group.test.c b/src/kernel/group.test.c index 1c6d6339e..877728780 100644 --- a/src/kernel/group.test.c +++ b/src/kernel/group.test.c @@ -35,7 +35,7 @@ static void test_group_readwrite_dead_faction(CuTest *tc) { f = test_create_faction(NULL); fno = f->no; CuAssertPtrEquals(tc, f, factions); - CuAssertPtrEquals(tc, 0, f->next); + CuAssertPtrEquals(tc, NULL, f->next); f2 = test_create_faction(NULL); CuAssertPtrEquals(tc, f2, factions->next); u = test_create_unit(f2, test_create_region(0, 0, NULL)); @@ -58,14 +58,14 @@ static void test_group_readwrite_dead_faction(CuTest *tc) { read_game(&data); mstream_done(&data.strm); gamedata_done(&data); - CuAssertPtrEquals(tc, 0, findfaction(fno)); + CuAssertPtrEquals(tc, NULL, findfaction(fno)); f2 = factions; CuAssertPtrNotNull(tc, f2); u = f2->units; CuAssertPtrNotNull(tc, u); g = get_group(u); CuAssertPtrNotNull(tc, g); - CuAssertPtrEquals(tc, 0, g->allies); + CuAssertPtrEquals(tc, NULL, g->allies); test_teardown(); } @@ -106,11 +106,11 @@ static void test_group_readwrite(CuTest * tc) CuAssertPtrNotNull(tc, f->groups->next); CuAssertIntEquals(tc, 43, f->groups->next->gid); CuAssertStrEquals(tc, "Egoisten", f->groups->next->name); - CuAssertPtrEquals(tc, 0, f->groups->allies); + CuAssertPtrEquals(tc, NULL, f->groups->allies); g = f->groups->next; CuAssertIntEquals(tc, 44, key_get(g->attribs, 44)); CuAssertPtrNotNull(tc, g->allies); - CuAssertPtrEquals(tc, 0, g->allies->next); + CuAssertPtrEquals(tc, NULL, g->allies->next); CuAssertPtrEquals(tc, f, g->allies->faction); CuAssertIntEquals(tc, HELP_GIVE, g->allies->status); test_teardown(); @@ -135,7 +135,7 @@ static void test_group(CuTest * tc) CuAssertIntEquals(tc, 1, g->members); set_group(u, 0); CuAssertIntEquals(tc, 0, g->members); - CuAssertPtrEquals(tc, 0, get_group(u)); + CuAssertPtrEquals(tc, NULL, get_group(u)); set_group(u, g); CuAssertIntEquals(tc, 1, g->members); CuAssertPtrEquals(tc, g, get_group(u)); diff --git a/src/kernel/item.test.c b/src/kernel/item.test.c index f04a22572..f820f8592 100644 --- a/src/kernel/item.test.c +++ b/src/kernel/item.test.c @@ -61,7 +61,7 @@ static void test_uchange(CuTest * tc, unit * u, const resource_type * rtype) { CuAssertIntEquals(tc, 0, rtype->uchange(u, rtype, -n)); CuAssertPtrNotNull(tc, sl); CuAssertStrEquals(tc, "serious accounting error. number of items is %d.", sl->s); - CuAssertPtrEquals(tc, 0, sl->next); + CuAssertPtrEquals(tc, NULL, sl->next); test_log_stop(log, sl); } @@ -86,7 +86,7 @@ void test_resource_type(CuTest * tc) test_setup(); - CuAssertPtrEquals(tc, 0, rt_find("herpderp")); + CuAssertPtrEquals(tc, NULL, rt_find("herpderp")); test_create_itemtype("herpderp"); test_create_itemtype("herpes"); @@ -122,7 +122,7 @@ void test_findresourcetype(CuTest * tc) locale_setstring(lang, "peasant", "Bauer"); init_resources(); CuAssertPtrNotNull(tc, rt_find("peasant")); - CuAssertPtrEquals(tc, 0, rt_find("log")); + CuAssertPtrEquals(tc, NULL, rt_find("log")); itype = test_create_itemtype("log"); CuAssertPtrEquals(tc, (void*)itype->rtype, (void*)findresourcetype("Holz", lang)); @@ -164,13 +164,13 @@ static void test_core_resources(CuTest *tc) { CuAssertPtrNotNull(tc, rtype->itype); CuAssertPtrNotNull(tc, rtype->uchange); CuAssertPtrNotNull(tc, rtype = rt_find("peasant")); - CuAssertPtrEquals(tc, 0, rtype->itype); + CuAssertPtrEquals(tc, NULL, rtype->itype); CuAssertPtrNotNull(tc, rtype = rt_find("permaura")); - CuAssertPtrEquals(tc, 0, rtype->itype); + CuAssertPtrEquals(tc, NULL, rtype->itype); CuAssertPtrNotNull(tc, rtype = rt_find("hp")); - CuAssertPtrEquals(tc, 0, rtype->itype); + CuAssertPtrEquals(tc, NULL, rtype->itype); CuAssertPtrNotNull(tc, rtype = rt_find("aura")); - CuAssertPtrEquals(tc, 0, rtype->itype); + CuAssertPtrEquals(tc, NULL, rtype->itype); test_teardown(); } diff --git a/src/kernel/messages.test.c b/src/kernel/messages.test.c index 3c9c684c6..e852bbc61 100644 --- a/src/kernel/messages.test.c +++ b/src/kernel/messages.test.c @@ -59,7 +59,7 @@ static void test_merge_split(CuTest *tc) { add_message(&append, msg = msg_message(mtype->name, "")); msg_release(msg); - CuAssertPtrEquals(tc, 0, mlist->begin->next); + CuAssertPtrEquals(tc, NULL, mlist->begin->next); CuAssertPtrEquals(tc, &mlist->begin->next, mlist->end); split = merge_messages(mlist, append); CuAssertPtrNotNull(tc, split); @@ -68,7 +68,7 @@ static void test_merge_split(CuTest *tc) { CuAssertPtrNotNull(tc, mlist->begin->next); CuAssertPtrEquals(tc, append->begin, mlist->begin->next); split_messages(mlist, split); - CuAssertPtrEquals(tc, 0, mlist->begin->next); + CuAssertPtrEquals(tc, NULL, mlist->begin->next); free_messagelist(*split); free_messagelist(mlist->begin); free(mlist); diff --git a/src/kernel/order.test.c b/src/kernel/order.test.c index d1dd6a371..14cdeb157 100644 --- a/src/kernel/order.test.c +++ b/src/kernel/order.test.c @@ -239,11 +239,11 @@ static void test_replace_order(CuTest *tc) { orig = create_order(K_MAKE, lang, NULL); repl = create_order(K_ALLY, lang, NULL); replace_order(&orders, orig, repl); - CuAssertPtrEquals(tc, 0, orders); + CuAssertPtrEquals(tc, NULL, orders); orders = orig; replace_order(&orders, orig, repl); CuAssertPtrNotNull(tc, orders); - CuAssertPtrEquals(tc, 0, orders->next); + CuAssertPtrEquals(tc, NULL, orders->next); CuAssertIntEquals(tc, getkeyword(repl), getkeyword(orders)); free_order(orders); free_order(repl); diff --git a/src/kernel/plane.test.c b/src/kernel/plane.test.c index 8338cc31f..6eb2ff631 100644 --- a/src/kernel/plane.test.c +++ b/src/kernel/plane.test.c @@ -11,15 +11,15 @@ static void test_plane(CuTest *tc) { test_setup(); r = test_create_region(0, 0, NULL); - CuAssertPtrEquals(tc, 0, findplane(0, 0)); - CuAssertPtrEquals(tc, 0, getplane(r)); + CuAssertPtrEquals(tc, NULL, findplane(0, 0)); + CuAssertPtrEquals(tc, NULL, getplane(r)); CuAssertIntEquals(tc, 0, getplaneid(r)); - CuAssertPtrEquals(tc, 0, getplanebyid(0)); + CuAssertPtrEquals(tc, NULL, getplanebyid(0)); CuAssertIntEquals(tc, 0, plane_center_x(0)); CuAssertIntEquals(tc, 0, plane_center_y(0)); CuAssertIntEquals(tc, 0, plane_width(0)); CuAssertIntEquals(tc, 0, plane_height(0)); - CuAssertPtrEquals(tc, 0, get_homeplane()); + CuAssertPtrEquals(tc, NULL, get_homeplane()); pl = create_new_plane(1, "Hell", 4, 8, 40, 80, 15); r = test_create_region(4, 40, 0); @@ -28,7 +28,7 @@ static void test_plane(CuTest *tc) { CuAssertIntEquals(tc, 8, pl->maxx); CuAssertIntEquals(tc, 40, pl->miny); CuAssertIntEquals(tc, 80, pl->maxy); - CuAssertPtrEquals(tc, 0, pl->attribs); + CuAssertPtrEquals(tc, NULL, pl->attribs); CuAssertStrEquals(tc, "Hell", pl->name); CuAssertPtrEquals(tc, pl, findplane(4, 40)); CuAssertPtrEquals(tc, pl, getplane(r)); diff --git a/src/kernel/region.test.c b/src/kernel/region.test.c index d54049b8e..4078b7cbd 100644 --- a/src/kernel/region.test.c +++ b/src/kernel/region.test.c @@ -23,14 +23,14 @@ void test_terraform(CuTest *tc) { t_plain = test_create_terrain("plain", LAND_REGION); t_ocean = test_create_terrain("ocean", SEA_REGION); r = test_create_region(0, 0, t_ocean); - CuAssertPtrEquals(tc, 0, r->land); + CuAssertPtrEquals(tc, NULL, r->land); terraform_region(r, t_plain); CuAssertPtrNotNull(tc, r->land); CuAssertPtrNotNull(tc, r->land->demands); CuAssertPtrEquals(tc, itype, (void *)r->land->demands->type->itype); CuAssertIntEquals(tc, 0, r->land->demands->type->price); terraform_region(r, t_ocean); - CuAssertPtrEquals(tc, 0, r->land); + CuAssertPtrEquals(tc, NULL, r->land); test_teardown(); } diff --git a/src/kernel/save.test.c b/src/kernel/save.test.c index 8e738863f..4844d1189 100644 --- a/src/kernel/save.test.c +++ b/src/kernel/save.test.c @@ -86,7 +86,7 @@ static void test_readwrite_unit(CuTest * tc) CuAssertPtrEquals(tc, f, u->faction); CuAssertStrEquals(tc, "Hodor", u->_name); CuAssertTrue(tc, irace == u_irace(u)); - CuAssertPtrEquals(tc, 0, u->region); + CuAssertPtrEquals(tc, NULL, u->region); mstream_done(&data.strm); gamedata_done(&data); @@ -115,7 +115,7 @@ static void test_readwrite_faction(CuTest * tc) f = read_faction(&data); CuAssertPtrNotNull(tc, f); CuAssertStrEquals(tc, "Hodor", f->name); - CuAssertPtrEquals(tc, 0, f->units); + CuAssertPtrEquals(tc, NULL, f->units); factions = f; mstream_done(&data.strm); @@ -179,7 +179,7 @@ static void test_readwrite_building(CuTest * tc) b = read_building(&data); CuAssertPtrNotNull(tc, b); CuAssertStrEquals(tc, "Hodor", b->name); - CuAssertPtrEquals(tc, 0, b->region); + CuAssertPtrEquals(tc, NULL, b->region); b->region = r; r->buildings = b; @@ -212,7 +212,7 @@ static void test_readwrite_ship(CuTest * tc) sh = read_ship(&data); CuAssertPtrNotNull(tc, sh); CuAssertStrEquals(tc, "Hodor", sh->name); - CuAssertPtrEquals(tc, 0, sh->region); + CuAssertPtrEquals(tc, NULL, sh->region); sh->region = r; r->ships = sh; @@ -233,7 +233,7 @@ static void test_readwrite_attrib(CuTest *tc) { gamedata_init(&data, &store, RELEASE_VERSION); write_attribs(data.store, a, NULL); a_removeall(&a, NULL); - CuAssertPtrEquals(tc, 0, a); + CuAssertPtrEquals(tc, NULL, a); data.strm.api->rewind(data.strm.handle); read_attribs(&data, &a, NULL); @@ -262,7 +262,7 @@ static void test_readwrite_dead_faction_group(CuTest *tc) { f = test_create_faction(NULL); fno = f->no; CuAssertPtrEquals(tc, f, factions); - CuAssertPtrEquals(tc, 0, f->next); + CuAssertPtrEquals(tc, NULL, f->next); f2 = test_create_faction(NULL); CuAssertPtrEquals(tc, f2, factions->next); u = test_create_unit(f2, test_create_region(0, 0, NULL)); @@ -281,14 +281,14 @@ static void test_readwrite_dead_faction_group(CuTest *tc) { f = f2 = NULL; data.strm.api->rewind(data.strm.handle); read_game(&data); - CuAssertPtrEquals(tc, 0, findfaction(fno)); + CuAssertPtrEquals(tc, NULL, findfaction(fno)); f2 = factions; CuAssertPtrNotNull(tc, f2); u = f2->units; CuAssertPtrNotNull(tc, u); g = get_group(u); CuAssertPtrNotNull(tc, g); - CuAssertPtrEquals(tc, 0, g->allies); + CuAssertPtrEquals(tc, NULL, g->allies); mstream_done(&data.strm); gamedata_done(&data); test_teardown(); @@ -319,10 +319,10 @@ static void test_readwrite_dead_faction_regionowner(CuTest *tc) { mstream_done(&data.strm); gamedata_done(&data); f = factions; - CuAssertPtrEquals(tc, 0, f); + CuAssertPtrEquals(tc, NULL, f); r = regions; CuAssertPtrNotNull(tc, r); - CuAssertPtrEquals(tc, 0, region_get_owner(r)); + CuAssertPtrEquals(tc, NULL, region_get_owner(r)); test_teardown(); } @@ -359,7 +359,7 @@ static void test_readwrite_dead_faction_changefaction(CuTest *tc) { CuAssertPtrNotNull(tc, r); u = r->units; CuAssertPtrNotNull(tc, u); - CuAssertPtrEquals(tc, 0, a_find(u->attribs, &at_eventhandler)); + CuAssertPtrEquals(tc, NULL, a_find(u->attribs, &at_eventhandler)); test_teardown(); } @@ -396,7 +396,7 @@ static void test_readwrite_dead_faction_createunit(CuTest *tc) { CuAssertPtrNotNull(tc, r); u = r->units; CuAssertPtrNotNull(tc, u); - CuAssertPtrEquals(tc, 0, a_find(u->attribs, &at_eventhandler)); + CuAssertPtrEquals(tc, NULL, a_find(u->attribs, &at_eventhandler)); test_teardown(); } diff --git a/src/kernel/ship.test.c b/src/kernel/ship.test.c index c50fdfa8d..180b558a2 100644 --- a/src/kernel/ship.test.c +++ b/src/kernel/ship.test.c @@ -278,7 +278,7 @@ static void test_shipowner_goes_to_same_faction_after_leave(CuTest * tc) leave_ship(u3); CuAssertPtrEquals(tc, u2, ship_owner(sh)); leave_ship(u2); - CuAssertPtrEquals(tc, 0, ship_owner(sh)); + CuAssertPtrEquals(tc, NULL, ship_owner(sh)); test_teardown(); } @@ -311,7 +311,7 @@ static void test_shipowner_resets_when_empty(CuTest * tc) u_set_ship(u, sh); CuAssertPtrEquals(tc, u, ship_owner(sh)); u->number = 0; - CuAssertPtrEquals(tc, 0, ship_owner(sh)); + CuAssertPtrEquals(tc, NULL, ship_owner(sh)); u->number = 1; CuAssertPtrEquals(tc, u, ship_owner(sh)); test_teardown(); @@ -353,7 +353,7 @@ void test_shipowner_goes_to_empty_unit_after_leave(CuTest * tc) leave_ship(u1); CuAssertPtrEquals(tc, u3, ship_owner(sh)); leave_ship(u3); - CuAssertPtrEquals(tc, 0, ship_owner(sh)); + CuAssertPtrEquals(tc, NULL, ship_owner(sh)); u2->number = 1; CuAssertPtrEquals(tc, u2, ship_owner(sh)); test_teardown(); @@ -365,8 +365,8 @@ static void test_stype_defaults(CuTest *tc) { stype = st_get_or_create("hodor"); CuAssertPtrNotNull(tc, stype); CuAssertStrEquals(tc, "hodor", stype->_name); - CuAssertPtrEquals(tc, 0, stype->construction); - CuAssertPtrEquals(tc, 0, stype->coasts); + CuAssertPtrEquals(tc, NULL, stype->construction); + CuAssertPtrEquals(tc, NULL, stype->coasts); CuAssertDblEquals(tc, 0.0, stype->damage, 0.0); CuAssertDblEquals(tc, 1.0, stype->storm, 0.0); CuAssertDblEquals(tc, 1.0, stype->tac_bonus, 0.01); diff --git a/src/kernel/spell.test.c b/src/kernel/spell.test.c index 622780e20..d7dfbad7e 100644 --- a/src/kernel/spell.test.c +++ b/src/kernel/spell.test.c @@ -17,8 +17,8 @@ static void test_create_a_spell(CuTest * tc) spell * sp; test_setup(); - CuAssertPtrEquals(tc, 0, spells); - CuAssertPtrEquals(tc, 0, find_spell("testspell")); + CuAssertPtrEquals(tc, NULL, spells); + CuAssertPtrEquals(tc, NULL, find_spell("testspell")); sp = create_spell("testspell"); CuAssertPtrEquals(tc, sp, find_spell("testspell")); @@ -37,13 +37,13 @@ static void test_create_duplicate_spell(CuTest * tc) test_log_stderr(0); /* suppress the "duplicate spell" error message */ log = test_log_start(LOG_CPERROR, &sl); - CuAssertPtrEquals(tc, 0, find_spell("testspell")); + CuAssertPtrEquals(tc, NULL, find_spell("testspell")); sp = create_spell("testspell"); - CuAssertPtrEquals(tc, 0, create_spell("testspell")); + CuAssertPtrEquals(tc, NULL, create_spell("testspell")); CuAssertPtrNotNull(tc, sl); CuAssertStrEquals(tc, "create_spell: duplicate name '%s'", sl->s); - CuAssertPtrEquals(tc, 0, sl->next); + CuAssertPtrEquals(tc, NULL, sl->next); CuAssertPtrEquals(tc, sp, find_spell("testspell")); test_log_stop(log, sl); test_log_stderr(1); /* or teardown complains that stderr logging is off */ diff --git a/src/kernel/spellbook.test.c b/src/kernel/spellbook.test.c index 22ea7c491..d83409797 100644 --- a/src/kernel/spellbook.test.c +++ b/src/kernel/spellbook.test.c @@ -25,7 +25,7 @@ void test_named_spellbooks(CuTest * tc) sb = create_spellbook(0); CuAssertPtrNotNull(tc, sb); - CuAssertPtrEquals(tc, 0, sb->name); + CuAssertPtrEquals(tc, NULL, sb->name); spellbook_clear(sb); free(sb); diff --git a/src/kernel/unit.test.c b/src/kernel/unit.test.c index 29596f866..085e0177a 100644 --- a/src/kernel/unit.test.c +++ b/src/kernel/unit.test.c @@ -42,7 +42,7 @@ static void test_remove_empty_units(CuTest *tc) { CuAssertPtrNotNull(tc, findunit(uid)); u->number = 0; remove_empty_units(); - CuAssertPtrEquals(tc, 0, findunit(uid)); + CuAssertPtrEquals(tc, NULL, findunit(uid)); test_teardown(); } @@ -61,9 +61,9 @@ static void test_remove_empty_units_in_region(CuTest *tc) { CuAssertPtrNotNull(tc, findunit(uid)); u->number = 0; remove_empty_units_in_region(u->region); - CuAssertPtrEquals(tc, 0, findunit(uid)); - CuAssertPtrEquals(tc, 0, u->nextF); - CuAssertPtrEquals(tc, 0, u->region); + CuAssertPtrEquals(tc, NULL, findunit(uid)); + CuAssertPtrEquals(tc, NULL, u->nextF); + CuAssertPtrEquals(tc, NULL, u->region); test_teardown(); } @@ -78,7 +78,7 @@ static void test_remove_units_without_faction(CuTest *tc) { uid = u->no; u_setfaction(u, 0); remove_empty_units_in_region(u->region); - CuAssertPtrEquals(tc, 0, findunit(uid)); + CuAssertPtrEquals(tc, NULL, findunit(uid)); CuAssertIntEquals(tc, 0, u->number); test_teardown(); } @@ -94,7 +94,7 @@ static void test_remove_units_with_dead_faction(CuTest *tc) { uid = u->no; u->faction->_alive = false; remove_empty_units_in_region(u->region); - CuAssertPtrEquals(tc, 0, findunit(uid)); + CuAssertPtrEquals(tc, NULL, findunit(uid)); CuAssertIntEquals(tc, 0, u->number); test_teardown(); } @@ -308,16 +308,16 @@ static void test_inside_building(CuTest *tc) { b->size = 1; scale_number(u, 1); - CuAssertPtrEquals(tc, 0, inside_building(u)); + CuAssertPtrEquals(tc, NULL, inside_building(u)); u->building = b; CuAssertPtrEquals(tc, b, inside_building(u)); scale_number(u, 2); - CuAssertPtrEquals(tc, 0, inside_building(u)); + CuAssertPtrEquals(tc, NULL, inside_building(u)); b->size = 2; CuAssertPtrEquals(tc, b, inside_building(u)); u = test_create_unit(u->faction, u->region); u->building = b; - CuAssertPtrEquals(tc, 0, inside_building(u)); + CuAssertPtrEquals(tc, NULL, inside_building(u)); b->size = 3; CuAssertPtrEquals(tc, b, inside_building(u)); test_teardown(); @@ -397,7 +397,7 @@ static void test_unit_description(CuTest *tc) { rc = test_create_race("hodor"); u = test_create_unit(test_create_faction(rc), test_create_region(0, 0, NULL)); - CuAssertPtrEquals(tc, 0, u->display); + CuAssertPtrEquals(tc, NULL, u->display); CuAssertStrEquals(tc, 0, u_description(u, lang)); u->display = str_strdup("Hodor"); CuAssertStrEquals(tc, "Hodor", u_description(u, NULL)); @@ -428,37 +428,37 @@ static void test_remove_unit(CuTest *tc) { CuAssertPtrEquals(tc, u1, f->units); CuAssertPtrEquals(tc, u2, u1->nextF); CuAssertPtrEquals(tc, u1, u2->prevF); - CuAssertPtrEquals(tc, 0, u2->nextF); + CuAssertPtrEquals(tc, NULL, u2->nextF); uno = u1->no; region_setresource(r, rtype, 0); i_change(&u1->items, rtype->itype, 100); remove_unit(&r->units, u1); CuAssertIntEquals(tc, 0, u1->number); - CuAssertPtrEquals(tc, 0, u1->region); + CuAssertPtrEquals(tc, NULL, u1->region); /* money is given to a survivor: */ - CuAssertPtrEquals(tc, 0, u1->items); + CuAssertPtrEquals(tc, NULL, u1->items); CuAssertIntEquals(tc, 0, region_getresource(r, rtype)); CuAssertIntEquals(tc, 100, i_get(u2->items, rtype->itype)); /* unit is removed from f->units: */ - CuAssertPtrEquals(tc, 0, u1->nextF); + CuAssertPtrEquals(tc, NULL, u1->nextF); CuAssertPtrEquals(tc, u2, f->units); - CuAssertPtrEquals(tc, 0, u2->nextF); - CuAssertPtrEquals(tc, 0, u2->prevF); + CuAssertPtrEquals(tc, NULL, u2->nextF); + CuAssertPtrEquals(tc, NULL, u2->prevF); /* unit is no longer in r->units: */ CuAssertPtrEquals(tc, u2, r->units); - CuAssertPtrEquals(tc, 0, u2->next); + CuAssertPtrEquals(tc, NULL, u2->next); /* unit is in deleted_units: */ - CuAssertPtrEquals(tc, 0, findunit(uno)); + CuAssertPtrEquals(tc, NULL, findunit(uno)); CuAssertPtrEquals(tc, f, dfindhash(uno)); remove_unit(&r->units, u2); /* no survivor, give money to peasants: */ CuAssertIntEquals(tc, 100, region_getresource(r, rtype)); /* there are now no more units: */ - CuAssertPtrEquals(tc, 0, r->units); - CuAssertPtrEquals(tc, 0, f->units); + CuAssertPtrEquals(tc, NULL, r->units); + CuAssertPtrEquals(tc, NULL, f->units); test_teardown(); } diff --git a/src/laws.test.c b/src/laws.test.c index e7951a7ce..fb8929996 100644 --- a/src/laws.test.c +++ b/src/laws.test.c @@ -123,8 +123,8 @@ static void test_enter_building(CuTest * tc) rc->flags = RCF_SWIM; u->building = 0; CuAssertIntEquals(tc, 0, enter_building(u, NULL, b->no, false)); - CuAssertPtrEquals(tc, 0, u->building); - CuAssertPtrEquals(tc, 0, u->faction->msgs); + CuAssertPtrEquals(tc, NULL, u->building); + CuAssertPtrEquals(tc, NULL, u->faction->msgs); CuAssertIntEquals(tc, 0, enter_building(u, NULL, b->no, true)); CuAssertPtrNotNull(tc, u->faction->msgs); @@ -164,8 +164,8 @@ static void test_enter_ship(CuTest * tc) rc->flags = RCF_SWIM; u->ship = 0; CuAssertIntEquals(tc, 0, enter_ship(u, NULL, sh->no, false)); - CuAssertPtrEquals(tc, 0, u->ship); - CuAssertPtrEquals(tc, 0, u->faction->msgs); + CuAssertPtrEquals(tc, NULL, u->ship); + CuAssertPtrEquals(tc, NULL, u->faction->msgs); CuAssertIntEquals(tc, 0, enter_ship(u, NULL, sh->no, true)); CuAssertPtrNotNull(tc, u->faction->msgs); @@ -1040,8 +1040,8 @@ static void test_long_order_normal(CuTest *tc) { CuAssertIntEquals(tc, 0, fval(u, UFL_MOVED)); CuAssertIntEquals(tc, 0, fval(u, UFL_LONGACTION)); CuAssertPtrNotNull(tc, u->orders); - CuAssertPtrEquals(tc, 0, u->faction->msgs); - CuAssertPtrEquals(tc, 0, u->old_orders); + CuAssertPtrEquals(tc, NULL, u->faction->msgs); + CuAssertPtrEquals(tc, NULL, u->old_orders); test_teardown(); } @@ -1051,9 +1051,9 @@ static void test_long_order_none(CuTest *tc) { test_setup(); u = test_create_unit(test_create_faction(NULL), test_create_region(0, 0, NULL)); update_long_order(u); - CuAssertPtrEquals(tc, 0, u->thisorder); - CuAssertPtrEquals(tc, 0, u->orders); - CuAssertPtrEquals(tc, 0, u->faction->msgs); + CuAssertPtrEquals(tc, NULL, u->thisorder); + CuAssertPtrEquals(tc, NULL, u->orders); + CuAssertPtrEquals(tc, NULL, u->faction->msgs); test_teardown(); } @@ -1065,9 +1065,9 @@ static void test_long_order_cast(CuTest *tc) { unit_addorder(u, create_order(K_CAST, u->faction->locale, NULL)); unit_addorder(u, create_order(K_CAST, u->faction->locale, NULL)); update_long_order(u); - CuAssertPtrEquals(tc, 0, u->thisorder); + CuAssertPtrEquals(tc, NULL, u->thisorder); CuAssertPtrNotNull(tc, u->orders); - CuAssertPtrEquals(tc, 0, u->faction->msgs); + CuAssertPtrEquals(tc, NULL, u->faction->msgs); test_teardown(); } @@ -1080,9 +1080,9 @@ static void test_long_order_buy_sell(CuTest *tc) { unit_addorder(u, create_order(K_SELL, u->faction->locale, NULL)); unit_addorder(u, create_order(K_SELL, u->faction->locale, NULL)); update_long_order(u); - CuAssertPtrEquals(tc, 0, u->thisorder); + CuAssertPtrEquals(tc, NULL, u->thisorder); CuAssertPtrNotNull(tc, u->orders); - CuAssertPtrEquals(tc, 0, u->faction->msgs); + CuAssertPtrEquals(tc, NULL, u->faction->msgs); test_teardown(); } @@ -1108,7 +1108,7 @@ static void test_long_order_multi_buy(CuTest *tc) { unit_addorder(u, create_order(K_BUY, u->faction->locale, 0)); unit_addorder(u, create_order(K_BUY, u->faction->locale, 0)); update_long_order(u); - CuAssertPtrEquals(tc, 0, u->thisorder); + CuAssertPtrEquals(tc, NULL, u->thisorder); CuAssertPtrNotNull(tc, u->orders); CuAssertPtrNotNull(tc, test_find_messagetype(u->faction->msgs, "error52")); test_teardown(); @@ -1123,9 +1123,9 @@ static void test_long_order_multi_sell(CuTest *tc) { unit_addorder(u, create_order(K_BUY, u->faction->locale, 0)); unit_addorder(u, create_order(K_SELL, u->faction->locale, 0)); update_long_order(u); - CuAssertPtrEquals(tc, 0, u->thisorder); + CuAssertPtrEquals(tc, NULL, u->thisorder); CuAssertPtrNotNull(tc, u->orders); - CuAssertPtrEquals(tc, 0, u->faction->msgs); + CuAssertPtrEquals(tc, NULL, u->faction->msgs); test_teardown(); } @@ -1137,7 +1137,7 @@ static void test_long_order_buy_cast(CuTest *tc) { unit_addorder(u, create_order(K_BUY, u->faction->locale, 0)); unit_addorder(u, create_order(K_CAST, u->faction->locale, 0)); update_long_order(u); - CuAssertPtrEquals(tc, 0, u->thisorder); + CuAssertPtrEquals(tc, NULL, u->thisorder); CuAssertPtrNotNull(tc, u->orders); CuAssertPtrNotNull(tc, test_find_messagetype(u->faction->msgs, "error52")); test_teardown(); @@ -1155,7 +1155,7 @@ static void test_long_order_hungry(CuTest *tc) { update_long_order(u); CuAssertIntEquals(tc, K_WORK, getkeyword(u->thisorder)); CuAssertPtrNotNull(tc, u->orders); - CuAssertPtrEquals(tc, 0, u->faction->msgs); + CuAssertPtrEquals(tc, NULL, u->faction->msgs); test_teardown(); } @@ -1167,7 +1167,7 @@ static void test_ally_cmd_errors(CuTest *tc) { test_setup(); u = test_create_unit(test_create_faction(NULL), test_create_region(0, 0, NULL)); fid = u->faction->no + 1; - CuAssertPtrEquals(tc, 0, findfaction(fid)); + CuAssertPtrEquals(tc, NULL, findfaction(fid)); ord = create_order(K_ALLY, u->faction->locale, itoa36(fid)); ally_cmd(u, ord); @@ -1264,25 +1264,25 @@ static void test_ally_cmd(CuTest *tc) { ord = create_order(K_ALLY, f->locale, "%s", itoa36(f->no)); ally_cmd(u, ord); - CuAssertPtrEquals(tc, 0, u->faction->msgs); + CuAssertPtrEquals(tc, NULL, u->faction->msgs); CuAssertIntEquals(tc, HELP_ALL, alliedfaction(0, u->faction, f, HELP_ALL)); free_order(ord); ord = create_order(K_ALLY, f->locale, "%s %s", itoa36(f->no), LOC(f->locale, parameters[P_NOT])); ally_cmd(u, ord); - CuAssertPtrEquals(tc, 0, u->faction->msgs); + CuAssertPtrEquals(tc, NULL, u->faction->msgs); CuAssertIntEquals(tc, 0, alliedfaction(0, u->faction, f, HELP_ALL)); free_order(ord); ord = create_order(K_ALLY, f->locale, "%s %s", itoa36(f->no), LOC(f->locale, parameters[P_GUARD])); ally_cmd(u, ord); - CuAssertPtrEquals(tc, 0, u->faction->msgs); + CuAssertPtrEquals(tc, NULL, u->faction->msgs); CuAssertIntEquals(tc, HELP_GUARD, alliedfaction(0, u->faction, f, HELP_ALL)); free_order(ord); ord = create_order(K_ALLY, f->locale, "%s %s %s", itoa36(f->no), LOC(f->locale, parameters[P_GUARD]), LOC(f->locale, parameters[P_NOT])); ally_cmd(u, ord); - CuAssertPtrEquals(tc, 0, u->faction->msgs); + CuAssertPtrEquals(tc, NULL, u->faction->msgs); CuAssertIntEquals(tc, 0, alliedfaction(0, u->faction, f, HELP_ALL)); free_order(ord); @@ -1374,7 +1374,7 @@ static void test_mail_unit_no_msg(CuTest *tc) { f = u->faction; ord = create_order(K_MAIL, f->locale, "%s %s", LOC(f->locale, parameters[P_UNIT]), itoa36(u->no)); mail_cmd(u, ord); - CuAssertPtrEquals(tc, 0, test_find_messagetype(f->msgs, "unitmessage")); + CuAssertPtrEquals(tc, NULL, test_find_messagetype(f->msgs, "unitmessage")); CuAssertPtrNotNull(tc, test_find_messagetype(f->msgs, "error30")); free_order(ord); test_teardown(); @@ -1389,7 +1389,7 @@ static void test_mail_faction_no_msg(CuTest *tc) { f = u->faction; ord = create_order(K_MAIL, f->locale, "%s %s", LOC(f->locale, parameters[P_FACTION]), itoa36(f->no)); mail_cmd(u, ord); - CuAssertPtrEquals(tc, 0, test_find_messagetype(f->msgs, "regionmessage")); + CuAssertPtrEquals(tc, NULL, test_find_messagetype(f->msgs, "regionmessage")); CuAssertPtrNotNull(tc, test_find_messagetype(f->msgs, "error30")); free_order(ord); test_teardown(); @@ -1404,7 +1404,7 @@ static void test_mail_faction_no_target(CuTest *tc) { f = u->faction; ord = create_order(K_MAIL, f->locale, "%s %s", LOC(f->locale, parameters[P_FACTION]), itoa36(f->no+1)); mail_cmd(u, ord); - CuAssertPtrEquals(tc, 0, test_find_messagetype(f->msgs, "regionmessage")); + CuAssertPtrEquals(tc, NULL, test_find_messagetype(f->msgs, "regionmessage")); CuAssertPtrNotNull(tc, test_find_messagetype(f->msgs, "error66")); free_order(ord); test_teardown(); @@ -1419,7 +1419,7 @@ static void test_mail_region_no_msg(CuTest *tc) { f = u->faction; ord = create_order(K_MAIL, f->locale, LOC(f->locale, parameters[P_REGION])); mail_cmd(u, ord); - CuAssertPtrEquals(tc, 0, test_find_messagetype(u->region->msgs, "mail_result")); + CuAssertPtrEquals(tc, NULL, test_find_messagetype(u->region->msgs, "mail_result")); CuAssertPtrNotNull(tc, test_find_messagetype(f->msgs, "error30")); free_order(ord); test_teardown(); @@ -1457,14 +1457,14 @@ static void test_show_without_item(CuTest *tc) locale_setstring(loc, "iteminfo::testitem", "testdescription"); reshow_cmd(u, ord); - CuAssertPtrEquals(tc, 0, test_find_messagetype(f->msgs, "error21")); + CuAssertPtrEquals(tc, NULL, test_find_messagetype(f->msgs, "error21")); CuAssertPtrNotNull(tc, test_find_messagetype(f->msgs, "error36")); test_clear_messages(f); i_add(&(u->items), i_new(itype, 1)); reshow_cmd(u, ord); - CuAssertPtrEquals(tc, 0, test_find_messagetype(f->msgs, "error21")); - CuAssertPtrEquals(tc, 0, test_find_messagetype(f->msgs, "error36")); + CuAssertPtrEquals(tc, NULL, test_find_messagetype(f->msgs, "error21")); + CuAssertPtrEquals(tc, NULL, test_find_messagetype(f->msgs, "error36")); test_clear_messages(f); free_order(ord); @@ -1609,7 +1609,7 @@ static void test_demon_hunger(CuTest * tc) get_food(r); CuAssertIntEquals(tc, 20, i_get(u->items, rtype->itype)); - CuAssertPtrEquals(tc, 0, test_find_messagetype(f->msgs, "malnourish")); + CuAssertPtrEquals(tc, NULL, test_find_messagetype(f->msgs, "malnourish")); config_set("hunger.demon.peasant_tolerance", "0"); diff --git a/src/magic.test.c b/src/magic.test.c index 1b64cdf53..9ca9c013e 100644 --- a/src/magic.test.c +++ b/src/magic.test.c @@ -45,7 +45,7 @@ void test_updatespells(CuTest * tc) CuAssertPtrNotNull(tc, book); spellbook_add(book, sp, 1); - CuAssertPtrEquals(tc, 0, f->spellbook); + CuAssertPtrEquals(tc, NULL, f->spellbook); pick_random_spells(f, 1, book, 1); CuAssertPtrNotNull(tc, f->spellbook); CuAssertIntEquals(tc, 1, selist_length(f->spellbook->spells)); @@ -191,7 +191,7 @@ void test_getspell_unit(CuTest * tc) sp = create_spell("testspell"); locale_setstring(lang, mkname("spell", sp->sname), "Herp-a-derp"); - CuAssertPtrEquals(tc, 0, unit_getspell(u, "Herp-a-derp", lang)); + CuAssertPtrEquals(tc, NULL, unit_getspell(u, "Herp-a-derp", lang)); unit_add_spell(u, 0, sp, 1); CuAssertPtrNotNull(tc, unit_getspell(u, "Herp-a-derp", lang)); @@ -220,7 +220,7 @@ void test_getspell_faction(CuTest * tc) sp = create_spell("testspell"); locale_setstring(lang, mkname("spell", sp->sname), "Herp-a-derp"); - CuAssertPtrEquals(tc, 0, unit_getspell(u, "Herp-a-derp", lang)); + CuAssertPtrEquals(tc, NULL, unit_getspell(u, "Herp-a-derp", lang)); f->spellbook = create_spellbook(0); spellbook_add(f->spellbook, sp, 1); @@ -250,7 +250,7 @@ void test_getspell_school(CuTest * tc) sp = create_spell("testspell"); locale_setstring(lang, mkname("spell", sp->sname), "Herp-a-derp"); - CuAssertPtrEquals(tc, 0, unit_getspell(u, "Herp-a-derp", lang)); + CuAssertPtrEquals(tc, NULL, unit_getspell(u, "Herp-a-derp", lang)); book = faction_get_spellbook(f); CuAssertPtrNotNull(tc, book); @@ -287,7 +287,7 @@ void test_set_pre_combatspell(CuTest * tc) CuAssertIntEquals(tc, 1, get_combatspelllevel(u, index)); unset_combatspell(u, sp); CuAssertIntEquals(tc, 0, get_combatspelllevel(u, index)); - CuAssertPtrEquals(tc, 0, (spell *)get_combatspell(u, index)); + CuAssertPtrEquals(tc, NULL, (spell *)get_combatspell(u, index)); test_teardown(); } @@ -319,7 +319,7 @@ void test_set_main_combatspell(CuTest * tc) CuAssertIntEquals(tc, 1, get_combatspelllevel(u, index)); unset_combatspell(u, sp); CuAssertIntEquals(tc, 0, get_combatspelllevel(u, index)); - CuAssertPtrEquals(tc, 0, (spell *)get_combatspell(u, index)); + CuAssertPtrEquals(tc, NULL, (spell *)get_combatspell(u, index)); test_teardown(); } @@ -351,7 +351,7 @@ void test_set_post_combatspell(CuTest * tc) CuAssertIntEquals(tc, 1, get_combatspelllevel(u, index)); unset_combatspell(u, sp); CuAssertIntEquals(tc, 0, get_combatspelllevel(u, index)); - CuAssertPtrEquals(tc, 0, (spell *)get_combatspell(u, index)); + CuAssertPtrEquals(tc, NULL, (spell *)get_combatspell(u, index)); test_teardown(); } diff --git a/src/move.test.c b/src/move.test.c index e782bb748..a4a65fead 100644 --- a/src/move.test.c +++ b/src/move.test.c @@ -225,16 +225,16 @@ static void test_ship_trails(CuTest *tc) { move_ship(sh, r1, r3, NULL); CuAssertPtrEquals(tc, r3, sh->region); CuAssertPtrEquals(tc, sh, r3->ships); - CuAssertPtrEquals(tc, 0, r1->ships); - CuAssertPtrEquals(tc, 0, a_find(r1->attribs, &at_shiptrail)); - CuAssertPtrEquals(tc, 0, a_find(r3->attribs, &at_shiptrail)); + CuAssertPtrEquals(tc, NULL, r1->ships); + CuAssertPtrEquals(tc, NULL, a_find(r1->attribs, &at_shiptrail)); + CuAssertPtrEquals(tc, NULL, a_find(r3->attribs, &at_shiptrail)); add_regionlist(&route, r3); add_regionlist(&route, r2); move_ship(sh, r3, r1, route); CuAssertPtrEquals(tc, r1, sh->region); CuAssertPtrEquals(tc, sh, r1->ships); - CuAssertPtrEquals(tc, 0, r3->ships); - CuAssertPtrEquals(tc, 0, a_find(r1->attribs, &at_shiptrail)); + CuAssertPtrEquals(tc, NULL, r3->ships); + CuAssertPtrEquals(tc, NULL, a_find(r1->attribs, &at_shiptrail)); CuAssertPtrNotNull(tc, a_find(r2->attribs, &at_shiptrail)); CuAssertPtrNotNull(tc, a_find(r3->attribs, &at_shiptrail)); free_regionlist(route); @@ -258,7 +258,7 @@ static void test_age_trails(CuTest *tc) { a_age(&r1->attribs, r1); CuAssertPtrNotNull(tc, r1->attribs); a_age(&r1->attribs, r1); - CuAssertPtrEquals(tc, 0, r1->attribs); + CuAssertPtrEquals(tc, NULL, r1->attribs); free_regionlist(route); test_teardown(); } @@ -323,7 +323,7 @@ static void test_ship_empty(CuTest *tc) { movement(); CuAssertPtrEquals(tc, fix.sh->region, findregion(0, 0)); CuAssertIntEquals(tc, 2, ship_damage_percent(fix.sh)); - CuAssertPtrEquals(tc, 0, test_find_messagetype(fix.f->msgs, "ship_drift")); + CuAssertPtrEquals(tc, NULL, test_find_messagetype(fix.f->msgs, "ship_drift")); test_teardown(); } @@ -340,7 +340,7 @@ static void test_no_drift_damage(CuTest *tc) { movement(); CuAssertPtrEquals(tc, fix.sh->region, findregion(0, 0)); CuAssertIntEquals(tc, 0, ship_damage_percent(fix.sh)); - CuAssertPtrEquals(tc, 0, test_find_messagetype(fix.f->msgs, "ship_drift")); + CuAssertPtrEquals(tc, NULL, test_find_messagetype(fix.f->msgs, "ship_drift")); test_teardown(); } @@ -386,7 +386,7 @@ static void test_ship_no_real_overload(CuTest *tc) { movement(); CuAssertPtrEquals(tc, fix.u->region, findregion(0, 0)); CuAssertIntEquals(tc, 82, ship_damage_percent(fix.sh)); - CuAssertPtrEquals(tc, 0, test_find_messagetype(fix.f->msgs, "massive_overload")); + CuAssertPtrEquals(tc, NULL, test_find_messagetype(fix.f->msgs, "massive_overload")); test_teardown(); } @@ -431,7 +431,7 @@ static void test_ship_ridiculous_overload_bad(CuTest *tc) { movement(); CuAssertTrue(tc, ship_damage_percent(fix.sh) > 99); CuAssertPtrNotNull(tc, test_find_messagetype(fix.f->msgs, "massive_overload")); - CuAssertPtrEquals(tc, 0, fix.sh->region); + CuAssertPtrEquals(tc, NULL, fix.sh->region); CuAssertPtrNotNull(tc, test_find_messagetype(fix.f->msgs, "shipsink")); test_teardown(); } diff --git a/src/piracy.test.c b/src/piracy.test.c index 096e267b7..7aa57bc2d 100644 --- a/src/piracy.test.c +++ b/src/piracy.test.c @@ -106,7 +106,7 @@ static void test_piracy_cmd(CuTest * tc) { u->thisorder = create_order(K_PIRACY, f->locale, "%s", itoa36(u2->faction->no)); piracy_cmd(u); - CuAssertPtrEquals(tc, 0, u->thisorder); + CuAssertPtrEquals(tc, NULL, u->thisorder); CuAssertTrue(tc, u->region != r); CuAssertPtrEquals(tc, u2->region, u->region); CuAssertPtrEquals(tc, u2->region, u->ship->region); @@ -211,7 +211,7 @@ static void test_piracy_cmd_land_to_land(CuTest * tc) { u->thisorder = create_order(K_PIRACY, f->locale, "%s", itoa36(target)); piracy_cmd(u); - CuAssertPtrEquals(tc, 0, u->thisorder); + CuAssertPtrEquals(tc, NULL, u->thisorder); CuAssertPtrEquals(tc, r, u->region); test_teardown(); @@ -226,7 +226,7 @@ static void test_piracy_cmd_swimmer(CuTest * tc) { r = pirate->region; piracy_cmd(pirate); - CuAssertPtrEquals(tc, 0, pirate->thisorder); + CuAssertPtrEquals(tc, NULL, pirate->thisorder); CuAssertTrue(tc, pirate->region != r); CuAssertPtrEquals(tc, victim->region, pirate->region); CuAssertPtrNotNullMsg(tc, "successful PIRACY message", test_find_messagetype(pirate->faction->msgs, "piratesawvictim")); diff --git a/src/prefix.test.c b/src/prefix.test.c index f131813d7..e95f0c281 100644 --- a/src/prefix.test.c +++ b/src/prefix.test.c @@ -11,17 +11,17 @@ static void test_add_prefix(CuTest *tc) { test_setup(); - CuAssertPtrEquals(tc, 0, race_prefixes); + CuAssertPtrEquals(tc, NULL, race_prefixes); CuAssertIntEquals(tc, 0, add_raceprefix("sea")); CuAssertPtrNotNull(tc, race_prefixes); CuAssertStrEquals(tc, "sea", race_prefixes[0]); - CuAssertPtrEquals(tc, 0, race_prefixes[1]); + CuAssertPtrEquals(tc, NULL, race_prefixes[1]); CuAssertIntEquals(tc, 0, add_raceprefix("moon")); CuAssertStrEquals(tc, "sea", race_prefixes[0]); CuAssertStrEquals(tc, "moon", race_prefixes[1]); - CuAssertPtrEquals(tc, 0, race_prefixes[2]); + CuAssertPtrEquals(tc, NULL, race_prefixes[2]); free_prefixes(); - CuAssertPtrEquals(tc, 0, race_prefixes); + CuAssertPtrEquals(tc, NULL, race_prefixes); test_teardown(); } diff --git a/src/reports.test.c b/src/reports.test.c index 0f5ca6b1f..d402b2b6a 100644 --- a/src/reports.test.c +++ b/src/reports.test.c @@ -76,7 +76,7 @@ static void test_reorder_units(CuTest * tc) CuAssertPtrEquals(tc, u2, u3->next); CuAssertPtrEquals(tc, u1, u2->next); CuAssertPtrEquals(tc, u0, u1->next); - CuAssertPtrEquals(tc, 0, u0->next); + CuAssertPtrEquals(tc, NULL, u0->next); test_teardown(); } @@ -130,19 +130,19 @@ static void test_sparagraph(CuTest *tc) { split_paragraph(&sp, "Hello World", 0, 16, 0); CuAssertPtrNotNull(tc, sp); CuAssertStrEquals(tc, "Hello World", sp->s); - CuAssertPtrEquals(tc, 0, sp->next); + CuAssertPtrEquals(tc, NULL, sp->next); freestrlist(sp); split_paragraph(&sp, "Hello World", 4, 16, 0); CuAssertPtrNotNull(tc, sp); CuAssertStrEquals(tc, " Hello World", sp->s); - CuAssertPtrEquals(tc, 0, sp->next); + CuAssertPtrEquals(tc, NULL, sp->next); freestrlist(sp); split_paragraph(&sp, "Hello World", 4, 16, '*'); CuAssertPtrNotNull(tc, sp); CuAssertStrEquals(tc, " * Hello World", sp->s); - CuAssertPtrEquals(tc, 0, sp->next); + CuAssertPtrEquals(tc, NULL, sp->next); freestrlist(sp); split_paragraph(&sp, "12345678 90 12345678", 0, 8, '*'); @@ -152,7 +152,7 @@ static void test_sparagraph(CuTest *tc) { CuAssertStrEquals(tc, "90", sp->next->s); CuAssertPtrNotNull(tc, sp->next->next); CuAssertStrEquals(tc, "12345678", sp->next->next->s); - CuAssertPtrEquals(tc, 0, sp->next->next->next); + CuAssertPtrEquals(tc, NULL, sp->next->next->next); freestrlist(sp); } @@ -326,7 +326,7 @@ static void test_arg_resources(CuTest *tc) { CuAssertPtrNotNull(tc, res = res->next); CuAssertPtrEquals(tc, itype->rtype, (void *)res->type); CuAssertIntEquals(tc, 5, res->number); - CuAssertPtrEquals(tc, 0, res->next); + CuAssertPtrEquals(tc, NULL, res->next); atype->release(v2); test_teardown(); } @@ -340,7 +340,7 @@ static void test_newbie_password_message(CuTest *tc) { f->flags = 0; prepare_report(&ctx, f); CuAssertIntEquals(tc, 0, f->flags&FFL_PWMSG); - CuAssertPtrEquals(tc, 0, test_find_messagetype(f->msgs, "changepasswd")); + CuAssertPtrEquals(tc, NULL, test_find_messagetype(f->msgs, "changepasswd")); f->age=2; prepare_report(&ctx, f); CuAssertIntEquals(tc, FFL_PWMSG, f->flags&FFL_PWMSG); @@ -511,7 +511,7 @@ void test_prepare_lighthouse_capacity(CuTest *tc) { prepare_report(&ctx, u2->faction); CuAssertPtrEquals(tc, r1, ctx.first); - CuAssertPtrEquals(tc, 0, ctx.last); + CuAssertPtrEquals(tc, NULL, ctx.last); CuAssertIntEquals(tc, seen_unit, r1->seen.mode); CuAssertIntEquals(tc, seen_neighbour, r2->seen.mode); finish_reports(&ctx); @@ -520,7 +520,7 @@ void test_prepare_lighthouse_capacity(CuTest *tc) { config_set_int("rules.lighthouse.unit_capacity", 1); prepare_report(&ctx, u2->faction); CuAssertPtrEquals(tc, r1, ctx.first); - CuAssertPtrEquals(tc, 0, ctx.last); + CuAssertPtrEquals(tc, NULL, ctx.last); CuAssertIntEquals(tc, seen_unit, r1->seen.mode); CuAssertIntEquals(tc, seen_lighthouse, r2->seen.mode); finish_reports(&ctx); @@ -619,15 +619,15 @@ static void test_prepare_report(CuTest *tc) { r = test_create_region(0, 0, NULL); prepare_report(&ctx, f); - CuAssertPtrEquals(tc, 0, ctx.first); - CuAssertPtrEquals(tc, 0, ctx.last); + CuAssertPtrEquals(tc, NULL, ctx.first); + CuAssertPtrEquals(tc, NULL, ctx.last); CuAssertIntEquals(tc, seen_none, r->seen.mode); finish_reports(&ctx); test_create_unit(f, r); prepare_report(&ctx, f); CuAssertPtrEquals(tc, r, ctx.first); - CuAssertPtrEquals(tc, 0, ctx.last); + CuAssertPtrEquals(tc, NULL, ctx.last); CuAssertIntEquals(tc, seen_unit, r->seen.mode); finish_reports(&ctx); CuAssertIntEquals(tc, seen_none, r->seen.mode); @@ -655,7 +655,7 @@ static void test_seen_neighbours(CuTest *tc) { test_create_unit(f, r1); prepare_report(&ctx, f); CuAssertPtrEquals(tc, r1, ctx.first); - CuAssertPtrEquals(tc, 0, ctx.last); + CuAssertPtrEquals(tc, NULL, ctx.last); CuAssertIntEquals(tc, seen_unit, r1->seen.mode); CuAssertIntEquals(tc, seen_neighbour, r2->seen.mode); finish_reports(&ctx); @@ -682,7 +682,7 @@ static void test_seen_travelthru(CuTest *tc) { CuAssertPtrEquals(tc, r3, f->last); prepare_report(&ctx, f); CuAssertPtrEquals(tc, r1, ctx.first); - CuAssertPtrEquals(tc, 0, ctx.last); + CuAssertPtrEquals(tc, NULL, ctx.last); CuAssertIntEquals(tc, seen_unit, r1->seen.mode); CuAssertIntEquals(tc, seen_travel, r2->seen.mode); CuAssertIntEquals(tc, seen_neighbour, r3->seen.mode); @@ -760,7 +760,7 @@ static void test_report_far_vision(CuTest *tc) { report_context ctx; prepare_report(&ctx, f); CuAssertPtrEquals(tc, r1, ctx.first); - CuAssertPtrEquals(tc, 0, ctx.last); + CuAssertPtrEquals(tc, NULL, ctx.last); CuAssertIntEquals(tc, seen_unit, r1->seen.mode); CuAssertIntEquals(tc, seen_spell, r2->seen.mode); finish_reports(&ctx); diff --git a/src/spy.test.c b/src/spy.test.c index d1f616fab..e5a7ec628 100644 --- a/src/spy.test.c +++ b/src/spy.test.c @@ -272,7 +272,7 @@ static void test_sabotage_other_success(CuTest *tc) { assert(ord); set_level(u2, SK_SPY, 1); CuAssertIntEquals(tc, 0, sabotage_cmd(u2, ord)); - CuAssertPtrEquals(tc, 0, r->ships); + CuAssertPtrEquals(tc, NULL, r->ships); free_order(ord); test_teardown(); } diff --git a/src/tests.test.c b/src/tests.test.c index 067772262..885d834e8 100644 --- a/src/tests.test.c +++ b/src/tests.test.c @@ -23,13 +23,13 @@ static void test_resources(CuTest *tc) { CuAssertPtrNotNull(tc, rt_find("permaura")); CuAssertPtrEquals(tc, rt_find("permaura"), (void *)get_resourcetype(R_PERMAURA)); - CuAssertPtrEquals(tc, 0, rt_find("stone")); + CuAssertPtrEquals(tc, NULL, rt_find("stone")); rtype = rt_get_or_create("stone"); CuAssertPtrEquals(tc, (void *)rtype, (void *)rt_find("stone")); CuAssertPtrEquals(tc, (void *)rtype, (void *)get_resourcetype(R_STONE)); free_resources(); - CuAssertPtrEquals(tc, 0, rt_find("stone")); - CuAssertPtrEquals(tc, 0, rt_find("peasant")); + CuAssertPtrEquals(tc, NULL, rt_find("stone")); + CuAssertPtrEquals(tc, NULL, rt_find("peasant")); rtype = rt_get_or_create("stone"); CuAssertPtrEquals(tc, (void *)rtype, (void *)get_resourcetype(R_STONE)); test_teardown(); From f2472248447c4f43a050c39d8ada6d5303bcfc5a Mon Sep 17 00:00:00 2001 From: Enno Rehling Date: Sun, 14 Oct 2018 14:45:05 +0200 Subject: [PATCH 080/160] Switching to VS2017 compiler has found a bug in pofile.c --- src/util/pofile.c | 4 ++-- tests/runtests.bat | 3 ++- vs2015-build.bat | 4 +++- 3 files changed, 7 insertions(+), 4 deletions(-) diff --git a/src/util/pofile.c b/src/util/pofile.c index 8de04364d..e1126ba0e 100644 --- a/src/util/pofile.c +++ b/src/util/pofile.c @@ -77,7 +77,7 @@ int pofile_read(const char *filename, int (*callback)(const char *msgid, const c int err = sscanf(line, "%8s", token); if (err == 1) { char *text = NULL; - size_t size, len = strlen(token); + size_t size = 0, len = strlen(token); line = line + len + 1; if (len == 7 && memcmp(token, "msgctxt", 7) == 0) { @@ -99,7 +99,7 @@ int pofile_read(const char *filename, int (*callback)(const char *msgid, const c msgid[0] = 0; } } - if (text) { + if (size > 0) { line = read_multiline(F, line, text, size); } } diff --git a/tests/runtests.bat b/tests/runtests.bat index 95ac17be4..88afc8d31 100644 --- a/tests/runtests.bat +++ b/tests/runtests.bat @@ -3,7 +3,8 @@ IF EXIST ..\build-vs10 SET BUILD=..\build-vs10\eressea\Debug IF EXIST ..\build-vs11 SET BUILD=..\build-vs11\eressea\Debug IF EXIST ..\build-vs12 SET BUILD=..\build-vs12\eressea\Debug IF EXIST ..\build-vs14 SET BUILD=..\build-vs14\eressea\Debug -REM IF EXIST ..\build-vs15 SET BUILD=..\build-vs15\eressea\Debug +IF EXIST ..\build-vs15 SET BUILD=..\build-vs15\eressea\Debug + SET SERVER=%BUILD%\eressea.exe %BUILD%\test_eressea.exe %SERVER% ..\scripts\run-tests.lua diff --git a/vs2015-build.bat b/vs2015-build.bat index 1ad2c8da2..8d5c276ed 100644 --- a/vs2015-build.bat +++ b/vs2015-build.bat @@ -1,5 +1,7 @@ @ECHO OFF -SET VSVERSION=14 +SET VSVERSION=15 +IF NOT "%1" == "" SET VSVERSION=%1% + SET SRCDIR=%CD% CD .. SET ERESSEA=%CD% From 5aa3b1161f63c58fd60b64b377dcac32376aba3f Mon Sep 17 00:00:00 2001 From: Enno Rehling Date: Sun, 14 Oct 2018 16:26:36 +0200 Subject: [PATCH 081/160] prefer unit_addorder over addlist where possible. --- src/laws.c | 2 +- src/spells.c | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/src/laws.c b/src/laws.c index 7e2250a59..4c2a29e4e 100644 --- a/src/laws.c +++ b/src/laws.c @@ -2911,7 +2911,7 @@ void maketemp_cmd(unit *u, order **olist) order *deford = default_order(u2->faction->locale); if (deford) { set_order(&u2->thisorder, NULL); - addlist(&u2->orders, deford); + unit_addorder(u2, deford); } } } diff --git a/src/spells.c b/src/spells.c index 00f256f26..dadce89c6 100644 --- a/src/spells.c +++ b/src/spells.c @@ -2348,7 +2348,7 @@ void patzer_peasantmob(const castorder * co) create_unit(r, f, n, get_race(RC_PEASANT), 0, LOC(f->locale, "angry_mob"), NULL); fset(u, UFL_ISNEW); - addlist(&u->orders, create_order(K_GUARD, lang, NULL)); + unit_addorder(u, create_order(K_GUARD, lang, NULL)); set_order(&u->thisorder, default_order(lang)); a = a_new(&at_unitdissolve); a->data.ca[0] = 1; /* An rpeasants(r). */ From 281ed3d3e9c421c1ae6a53599594a594d54c2fec Mon Sep 17 00:00:00 2001 From: Enno Rehling Date: Sun, 14 Oct 2018 17:06:38 +0200 Subject: [PATCH 082/160] Remove remainder of old the tunnel implementation with b:add_action(). --- scripts/eressea/tunnels.lua | 15 +++-------- scripts/tools/wormholes.lua | 52 ------------------------------------- 2 files changed, 3 insertions(+), 64 deletions(-) delete mode 100644 scripts/tools/wormholes.lua diff --git a/scripts/eressea/tunnels.lua b/scripts/eressea/tunnels.lua index 007c52bc0..4a787a373 100644 --- a/scripts/eressea/tunnels.lua +++ b/scripts/eressea/tunnels.lua @@ -1,3 +1,4 @@ +-- Weltentor portal module local tunnels = {} local buildings = {} @@ -24,25 +25,15 @@ local function get_target(param) end local function tunnel_action(b, param) - local r = nil - if tonumber(param)~=nil then - r = get_region_by_id(tonumber(param)) - end local units = tunnel_travelers(b) - if units~=nil then + local rto = get_target(param) + if rto and units then eressea.log.debug("Tunnel from " .. tostring(b) .. " [" .. param .. "]") for key, u in pairs(units) do - local rto = r - if r==nil then - rto = get_target(param) - end - if rto~=nil then u.region = rto eressea.log.debug("teleported " .. tostring(u) .. " to " .. tostring(rto)) - end end end - return 1 -- return 0 to destroy end function tunnels.init() diff --git a/scripts/tools/wormholes.lua b/scripts/tools/wormholes.lua deleted file mode 100644 index 87be4be90..000000000 --- a/scripts/tools/wormholes.lua +++ /dev/null @@ -1,52 +0,0 @@ --- create a fixed path to a specific region -local function create_path(from, to) - local param = tostring(to.uid) - local b = building.create(from, "portal") - b.name = "Weltentor" - b.size = 1 - b:add_action("tunnel_action", param) -end - --- create a wonky tunnel wth more than one exit -local function create_tunnel(from, param) - local b = building.create(from, "portal") - b.name = "Weltentor" - b.size = 1 - b:add_action("tunnel_action", param) -end - --- make a tunnel from the cursor to the first selected region -function mktunnel() - local from = gmtool.get_cursor() - local to = gmtool.get_selection()() - if to~=nil then - region.create(from.x, from.y, "glacier") - create_tunnel(from, to) - gmtool.select(to, 0) - gmtool.highlight(to, 1) - end -end - --- turn all selected regions into targets for a wonky tunnel ("tnnL") -function mkanchors() - for r in gmtool.get_selection() do - if not r:get_key("tnnL") then - r:set_key("tnnL", true) - if r:get_flag(0) then - -- RF_CHAOTIC gets removed - r:set_flag(0, false) - end - r:set_resource("peasant", r:get_resource("peasant") + 1) - end - end -end - --- region.create and prepare all hell-regions to become wonky gates -function mkgates() - for r in regions() do - if r.plane_id==0 and r.terrain=="hell" then - create_tunnel(r, "tnnL") - region.create(r.x, r.y, "glacier") - end - end -end From eddcefed77187504e0b07b1bd7dd4550fb2b44f8 Mon Sep 17 00:00:00 2001 From: Enno Rehling Date: Fri, 19 Oct 2018 20:49:58 +0200 Subject: [PATCH 083/160] reduce number of allocations in report_region (edges). remove the swap database file for orders (when not using memory). --- src/kernel/db/sqlite.c | 11 ++++++++ src/orderdb.c | 1 - src/report.c | 64 ++++++++++++++++++++++-------------------- 3 files changed, 44 insertions(+), 32 deletions(-) diff --git a/src/kernel/db/sqlite.c b/src/kernel/db/sqlite.c index ffdcc8e67..fd9d0bc67 100644 --- a/src/kernel/db/sqlite.c +++ b/src/kernel/db/sqlite.c @@ -11,6 +11,7 @@ #include #include #include +#include #include static sqlite3 *g_game_db; @@ -179,11 +180,14 @@ static int db_open_swap(const char *dbname) { return 0; } +static const char *g_swapname; + int db_driver_open(database_t db, const char *dbname) { ERRNO_CHECK(); if (db == DB_SWAP) { + g_swapname = dbname; return db_open_swap(dbname); } else if (db == DB_GAME) { @@ -205,6 +209,13 @@ void db_driver_close(database_t db) assert(err == SQLITE_OK); err = sqlite3_close(g_temp_db); assert(err == SQLITE_OK); + if (g_swapname) { + FILE * F = fopen(g_swapname, "r"); + if (F) { + fclose(F); + remove(g_swapname); + } + } } else if (db == DB_GAME) { assert(g_game_db); diff --git a/src/orderdb.c b/src/orderdb.c index 42248c0ef..5c224a79e 100644 --- a/src/orderdb.c +++ b/src/orderdb.c @@ -16,7 +16,6 @@ void orderdb_open(void) { const char *dbname; - dbname = config_get("game.dbswap"); db_driver_open(DB_SWAP, dbname); } diff --git a/src/report.c b/src/report.c index 1d40941c4..5d2ed4598 100644 --- a/src/report.c +++ b/src/report.c @@ -873,6 +873,8 @@ bool see_border(const connection * b, const faction * f, const region * r) return cs; } +#define MAX_EDGES 16 + void report_region(struct stream *out, const region * r, faction * f) { int n; @@ -883,13 +885,13 @@ void report_region(struct stream *out, const region * r, faction * f) attrib *a; const char *tname; struct edge { - struct edge *next; char *name; bool transparent; bool block; bool exist[MAXDIRECTIONS]; direction_t lastd; - } *edges = NULL, *e; + } edges[MAX_EDGES]; + int ne = 0; bool see[MAXDIRECTIONS]; char buf[8192]; char *bufp = buf; @@ -908,7 +910,8 @@ void report_region(struct stream *out, const region * r, faction * f) if (!r2) continue; for (b = get_borders(r, r2); b;) { - struct edge *edg = edges; + int e; + struct edge *match = NULL; bool transparent = b->type->transparent(b, f); const char *name = border_name(b, r, f, GF_DETAILED | GF_ARTICLE); @@ -919,18 +922,22 @@ void report_region(struct stream *out, const region * r, faction * f) b = b->next; continue; } - while (edg && (edg->transparent != transparent || strcmp(name, edg->name)!=0)) { - edg = edg->next; + for (e = 0; e!=ne; ++e) { + struct edge *edg = edges + e; + if (edg->transparent == transparent && 0 == strcmp(name, edg->name)) { + match = edg; + break; + } } - if (!edg) { - edg = calloc(sizeof(struct edge), 1); - edg->name = str_strdup(name); - edg->transparent = transparent; - edg->next = edges; - edges = edg; + if (match == NULL) { + match = edges + ne; + match->name = str_strdup(name); + match->transparent = transparent; + ++ne; + assert(ne < MAX_EDGES); } - edg->lastd = d; - edg->exist[d] = true; + match->lastd = d; + match->exist[d] = true; b = b->next; } } @@ -1227,27 +1234,22 @@ void report_region(struct stream *out, const region * r, faction * f) nr_curses(out, 0, f, TYP_REGION, r); n = 0; - if (edges) + if (ne > 0) { + int e; newline(out); - for (e = edges; e; e = e->next) { - message *msg; + for (e = 0; e != ne; ++e) { + message *msg; - for (d = 0; d != MAXDIRECTIONS; ++d) { - if (e->exist[d]) { - msg = msg_message(e->transparent ? "nr_border_transparent" : "nr_border_opaque", - "object dir", e->name, d); - nr_render(msg, f->locale, buf, sizeof(buf), f); - msg_release(msg); - paragraph(out, buf, 0, 0, 0); + for (d = 0; d != MAXDIRECTIONS; ++d) { + if (edges[e].exist[d]) { + msg = msg_message(edges[e].transparent ? "nr_border_transparent" : "nr_border_opaque", + "object dir", edges[e].name, d); + nr_render(msg, f->locale, buf, sizeof(buf), f); + msg_release(msg); + paragraph(out, buf, 0, 0, 0); + } } - } - } - if (edges) { - while (edges) { - e = edges->next; - free(edges->name); - free(edges); - edges = e; + free(edges[e].name); } } } From c7c306b0e5b87a254b8349ebcd41487260c583f7 Mon Sep 17 00:00:00 2001 From: Enno Rehling Date: Sat, 20 Oct 2018 09:58:50 +0200 Subject: [PATCH 084/160] implement atoi so it doesn't change errno (for now) --- src/kernel/build.c | 3 ++- src/util/base36.c | 8 ++++++++ src/util/base36.h | 1 + 3 files changed, 11 insertions(+), 1 deletion(-) diff --git a/src/kernel/build.c b/src/kernel/build.c index 4e3dc4721..33adaccbf 100644 --- a/src/kernel/build.c +++ b/src/kernel/build.c @@ -179,7 +179,8 @@ int destroy_cmd(unit * u, struct order *ord) s = gettoken(token, sizeof(token)); if (s && *s) { - n = atoi((const char *)s); + n = atoi10((const char *)s); + if (n <= 0) { n = INT_MAX; } diff --git a/src/util/base36.c b/src/util/base36.c index 3b5543e88..e68fd76f6 100644 --- a/src/util/base36.c +++ b/src/util/base36.c @@ -23,6 +23,14 @@ OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. #include #include #include +#include + +int atoi10(const char *str) +{ + int i = atoi(str); + errno = 0; + return i; +} int atoi36(const char *str) { diff --git a/src/util/base36.h b/src/util/base36.h index 05c81d2c0..33f0d2f08 100644 --- a/src/util/base36.h +++ b/src/util/base36.h @@ -31,6 +31,7 @@ extern "C" { const char *itoa36(int i); const char *itoa10(int i); extern int atoi36(const char *s); + extern int atoi10(const char *s); int i10toi36(int i); #ifdef __cplusplus From 01edb1e204d3f24acd12503da2fed58f7fa26d82 Mon Sep 17 00:00:00 2001 From: Enno Rehling Date: Sat, 20 Oct 2018 19:56:38 +0200 Subject: [PATCH 085/160] move that errno-preserving atoi to strings.c --- src/kernel/build.c | 4 ++-- src/util/base36.c | 8 -------- src/util/strings.c | 11 ++++++++++- src/util/strings.h | 1 + src/util/strings.test.c | 22 ++++++++++++++++++++++ 5 files changed, 35 insertions(+), 11 deletions(-) diff --git a/src/kernel/build.c b/src/kernel/build.c index 71d5543fd..4ad7815c8 100644 --- a/src/kernel/build.c +++ b/src/kernel/build.c @@ -54,13 +54,13 @@ OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. #include /* from libutil */ -#include #include #include #include #include #include #include +#include /* from libc */ #include @@ -180,7 +180,7 @@ int destroy_cmd(unit * u, struct order *ord) s = gettoken(token, sizeof(token)); if (s && *s) { - n = atoi10((const char *)s); + n = str_atoi(s); if (n <= 0) { n = INT_MAX; diff --git a/src/util/base36.c b/src/util/base36.c index e68fd76f6..3b5543e88 100644 --- a/src/util/base36.c +++ b/src/util/base36.c @@ -23,14 +23,6 @@ OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. #include #include #include -#include - -int atoi10(const char *str) -{ - int i = atoi(str); - errno = 0; - return i; -} int atoi36(const char *str) { diff --git a/src/util/strings.c b/src/util/strings.c index ef351ab1f..e85d8ca56 100644 --- a/src/util/strings.c +++ b/src/util/strings.c @@ -22,10 +22,11 @@ OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. #include "strings.h" /* libc includes */ +#include #include +#include #include #include -#include #include #ifdef HAVE_LIBBSD @@ -34,6 +35,14 @@ OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. #include #endif +int str_atoi(const char *str) +{ + int e = errno; + int i = atoi(str); + errno = e; + return i; +} + size_t str_strlcpy(char *dst, const char *src, size_t len) { #ifdef HAVE_BSDSTRING diff --git a/src/util/strings.h b/src/util/strings.h index bd6f0de58..6524f5970 100644 --- a/src/util/strings.h +++ b/src/util/strings.h @@ -27,6 +27,7 @@ extern "C" { void str_replace(char *buffer, size_t size, const char *tmpl, const char *var, const char *value); int str_hash(const char *s); + int str_atoi(const char *s); size_t str_slprintf(char * dst, size_t size, const char * format, ...); size_t str_strlcpy(char *dst, const char *src, size_t len); size_t str_strlcat(char *dst, const char *src, size_t len); diff --git a/src/util/strings.test.c b/src/util/strings.test.c index 2205e538b..211ec65cc 100644 --- a/src/util/strings.test.c +++ b/src/util/strings.test.c @@ -71,6 +71,27 @@ static void test_str_hash(CuTest * tc) CuAssertIntEquals(tc, 140703196, str_hash("Hodor")); } +static void test_str_atoi(CuTest * tc) +{ + errno = 0; + CuAssertIntEquals(tc, 0, str_atoi("0")); + CuAssertIntEquals(tc, 4, str_atoi("4")); + CuAssertIntEquals(tc, 42, str_atoi("42")); + CuAssertIntEquals(tc, -4, str_atoi("-4")); + CuAssertIntEquals(tc, 0, errno); + CuAssertIntEquals(tc, 4, str_atoi("4a")); + CuAssertIntEquals(tc, 8, str_atoi("08")); + CuAssertIntEquals(tc, 0, str_atoi("0x8")); + CuAssertIntEquals(tc, 0, str_atoi("a")); + CuAssertIntEquals(tc, 0, errno); + errno = ERANGE; + CuAssertIntEquals(tc, 0, str_atoi("a")); + CuAssertIntEquals(tc, ERANGE, errno); + errno = EINVAL; + CuAssertIntEquals(tc, 0, str_atoi("a")); + CuAssertIntEquals(tc, EINVAL, errno); +} + static void test_str_slprintf(CuTest * tc) { char buffer[32]; @@ -157,6 +178,7 @@ static void test_sbstring(CuTest * tc) CuSuite *get_strings_suite(void) { CuSuite *suite = CuSuiteNew(); + SUITE_ADD_TEST(suite, test_str_atoi); SUITE_ADD_TEST(suite, test_str_hash); SUITE_ADD_TEST(suite, test_str_escape); SUITE_ADD_TEST(suite, test_str_escape_ex); From 57be0f2e6a2fa86318aa964f5927d3602c2205e5 Mon Sep 17 00:00:00 2001 From: Enno Rehling Date: Sat, 20 Oct 2018 20:10:11 +0200 Subject: [PATCH 086/160] Ich habe mich geirrt, was das Verhalten von atoi in Windows angeht. Alles zurueck. --- src/kernel/build.c | 5 +++-- src/util/strings.c | 9 --------- src/util/strings.h | 2 +- src/util/strings.test.c | 22 ---------------------- 4 files changed, 4 insertions(+), 34 deletions(-) diff --git a/src/kernel/build.c b/src/kernel/build.c index 4ad7815c8..f5e1eec91 100644 --- a/src/kernel/build.c +++ b/src/kernel/build.c @@ -180,8 +180,9 @@ int destroy_cmd(unit * u, struct order *ord) s = gettoken(token, sizeof(token)); if (s && *s) { - n = str_atoi(s); - + ERRNO_CHECK(); + n = atoi(s); + errno = 0; if (n <= 0) { n = INT_MAX; } diff --git a/src/util/strings.c b/src/util/strings.c index e85d8ca56..e9434fb25 100644 --- a/src/util/strings.c +++ b/src/util/strings.c @@ -24,7 +24,6 @@ OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. /* libc includes */ #include #include -#include #include #include #include @@ -35,14 +34,6 @@ OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. #include #endif -int str_atoi(const char *str) -{ - int e = errno; - int i = atoi(str); - errno = e; - return i; -} - size_t str_strlcpy(char *dst, const char *src, size_t len) { #ifdef HAVE_BSDSTRING diff --git a/src/util/strings.h b/src/util/strings.h index 6524f5970..bd58c0eb2 100644 --- a/src/util/strings.h +++ b/src/util/strings.h @@ -20,6 +20,7 @@ OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. #define STRINGS_H #include +#include #ifdef __cplusplus extern "C" { @@ -27,7 +28,6 @@ extern "C" { void str_replace(char *buffer, size_t size, const char *tmpl, const char *var, const char *value); int str_hash(const char *s); - int str_atoi(const char *s); size_t str_slprintf(char * dst, size_t size, const char * format, ...); size_t str_strlcpy(char *dst, const char *src, size_t len); size_t str_strlcat(char *dst, const char *src, size_t len); diff --git a/src/util/strings.test.c b/src/util/strings.test.c index 211ec65cc..2205e538b 100644 --- a/src/util/strings.test.c +++ b/src/util/strings.test.c @@ -71,27 +71,6 @@ static void test_str_hash(CuTest * tc) CuAssertIntEquals(tc, 140703196, str_hash("Hodor")); } -static void test_str_atoi(CuTest * tc) -{ - errno = 0; - CuAssertIntEquals(tc, 0, str_atoi("0")); - CuAssertIntEquals(tc, 4, str_atoi("4")); - CuAssertIntEquals(tc, 42, str_atoi("42")); - CuAssertIntEquals(tc, -4, str_atoi("-4")); - CuAssertIntEquals(tc, 0, errno); - CuAssertIntEquals(tc, 4, str_atoi("4a")); - CuAssertIntEquals(tc, 8, str_atoi("08")); - CuAssertIntEquals(tc, 0, str_atoi("0x8")); - CuAssertIntEquals(tc, 0, str_atoi("a")); - CuAssertIntEquals(tc, 0, errno); - errno = ERANGE; - CuAssertIntEquals(tc, 0, str_atoi("a")); - CuAssertIntEquals(tc, ERANGE, errno); - errno = EINVAL; - CuAssertIntEquals(tc, 0, str_atoi("a")); - CuAssertIntEquals(tc, EINVAL, errno); -} - static void test_str_slprintf(CuTest * tc) { char buffer[32]; @@ -178,7 +157,6 @@ static void test_sbstring(CuTest * tc) CuSuite *get_strings_suite(void) { CuSuite *suite = CuSuiteNew(); - SUITE_ADD_TEST(suite, test_str_atoi); SUITE_ADD_TEST(suite, test_str_hash); SUITE_ADD_TEST(suite, test_str_escape); SUITE_ADD_TEST(suite, test_str_escape_ex); From b8c49914e986cac6d4efe401c2cff598d308cff9 Mon Sep 17 00:00:00 2001 From: Enno Rehling Date: Sat, 20 Oct 2018 20:28:05 +0200 Subject: [PATCH 087/160] missing include --- src/CMakeLists.txt | 2 +- src/kernel/build.c | 1 + 2 files changed, 2 insertions(+), 1 deletion(-) diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt index 4e8db8bf9..50f625053 100644 --- a/src/CMakeLists.txt +++ b/src/CMakeLists.txt @@ -25,7 +25,7 @@ IF (CMAKE_COMPILER_IS_GNUCC) ENDIF() IF (CMAKE_COMPILER_IS_GNUCC OR CMAKE_C_COMPILER_ID MATCHES "Clang") # SET(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -Wconversion -Wno-sign-conversion") - SET(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -Wsign-compare -Wall -Werror -Wno-unknown-pragmas -Wstrict-prototypes -Wpointer-arith -Wno-char-subscripts -Wno-long-long") + SET(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -no-pie -g -pg -Wsign-compare -Wall -Werror -Wno-unknown-pragmas -Wstrict-prototypes -Wpointer-arith -Wno-char-subscripts -Wno-long-long") # SET(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -std=c89") ELSEIF(MSVC) SET(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} /W4 /WX /MP /D_CRT_SECURE_NO_WARNINGS /D_USE_MATH_DEFINES") diff --git a/src/kernel/build.c b/src/kernel/build.c index f5e1eec91..2b7251f1d 100644 --- a/src/kernel/build.c +++ b/src/kernel/build.c @@ -64,6 +64,7 @@ OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. /* from libc */ #include +#include #include #include #include From 9ecf87188f58f36aaa57ef89d4fc1b451f23e35e Mon Sep 17 00:00:00 2001 From: Enno Rehling Date: Sat, 20 Oct 2018 20:31:21 +0200 Subject: [PATCH 088/160] remove gprof options --- src/CMakeLists.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt index 50f625053..4e8db8bf9 100644 --- a/src/CMakeLists.txt +++ b/src/CMakeLists.txt @@ -25,7 +25,7 @@ IF (CMAKE_COMPILER_IS_GNUCC) ENDIF() IF (CMAKE_COMPILER_IS_GNUCC OR CMAKE_C_COMPILER_ID MATCHES "Clang") # SET(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -Wconversion -Wno-sign-conversion") - SET(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -no-pie -g -pg -Wsign-compare -Wall -Werror -Wno-unknown-pragmas -Wstrict-prototypes -Wpointer-arith -Wno-char-subscripts -Wno-long-long") + SET(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -Wsign-compare -Wall -Werror -Wno-unknown-pragmas -Wstrict-prototypes -Wpointer-arith -Wno-char-subscripts -Wno-long-long") # SET(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -std=c89") ELSEIF(MSVC) SET(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} /W4 /WX /MP /D_CRT_SECURE_NO_WARNINGS /D_USE_MATH_DEFINES") From 35ed981cd578b81397be0159096bbd85a9df55dd Mon Sep 17 00:00:00 2001 From: Enno Rehling Date: Mon, 22 Oct 2018 21:51:11 +0200 Subject: [PATCH 089/160] help the VS heap profiler understand the code. reorder calloc arguments. rename ursprung -> origin. --- src/alchemy.c | 4 ++-- src/battle.c | 4 ++-- src/bind_faction.c | 16 ++-------------- src/gmtool.c | 2 +- src/kernel/ally.c | 4 +--- src/kernel/building.c | 2 +- src/kernel/faction.c | 37 ++++++++++++++++++++----------------- src/kernel/faction.h | 10 ++++++++-- src/kernel/faction.test.c | 12 ++++++------ src/kernel/plane.c | 8 ++++---- src/kernel/region.c | 2 +- src/kernel/save.c | 12 ++++++------ src/kernel/types.h | 6 ------ src/listbox.c | 4 ++-- src/modules/autoseed.c | 2 +- src/spells/borders.c | 2 +- src/util/umlaut.c | 2 +- 17 files changed, 59 insertions(+), 70 deletions(-) diff --git a/src/alchemy.c b/src/alchemy.c index d2dd64a04..c84374e28 100644 --- a/src/alchemy.c +++ b/src/alchemy.c @@ -66,7 +66,7 @@ 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)); itype->flags |= ITF_POTION; ptype->itype = itype; ptype->level = level; @@ -181,7 +181,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/battle.c b/src/battle.c index 6ab969c93..8b71f17e1 100644 --- a/src/battle.c +++ b/src/battle.c @@ -3226,7 +3226,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) { @@ -3452,7 +3452,7 @@ battle *make_battle(region * r) break; } if (!bf) { - bf = (bfaction *)calloc(sizeof(bfaction), 1); + bf = (bfaction *)calloc(1, sizeof(bfaction)); ++b->nfactions; bf->faction = u->faction; bf->next = b->factions; diff --git a/src/bind_faction.c b/src/bind_faction.c index 632fcec3d..bb0920395 100644 --- a/src/bind_faction.c +++ b/src/bind_faction.c @@ -382,20 +382,8 @@ 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; - } + int x = 0, y = 0; + faction_getorigin(self, 0, &x, &y); lua_pushinteger(L, x); lua_pushinteger(L, y); diff --git a/src/gmtool.c b/src/gmtool.c index cd0580fcc..36c05a244 100644 --- a/src/gmtool.c +++ b/src/gmtool.c @@ -1361,7 +1361,7 @@ static void update_view(view * vi) state *state_open(void) { - state *st = calloc(sizeof(state), 1); + state *st = (state *)calloc(1, sizeof(state)); st->display.pl = get_homeplane(); st->cursor.pl = get_homeplane(); st->cursor.x = 0; diff --git a/src/kernel/ally.c b/src/kernel/ally.c index 1fd7c0efd..0660f148a 100644 --- a/src/kernel/ally.c +++ b/src/kernel/ally.c @@ -56,10 +56,8 @@ ally * ally_add(ally **al_p, struct faction *f) { if (f && al->faction == f) return al; al_p = &al->next; } - al = (ally *)malloc(sizeof(ally)); + al = (ally *)calloc(1, sizeof(ally)); al->faction = f; - al->status = 0; - al->next = 0; *al_p = al; return al; } diff --git a/src/kernel/building.c b/src/kernel/building.c index f5698eaa9..3a3d7e4e5 100644 --- a/src/kernel/building.c +++ b/src/kernel/building.c @@ -135,7 +135,7 @@ building_type *bt_get_or_create(const char *name) if (name != NULL) { building_type *btype = bt_find_i(name); if (btype == NULL) { - btype = calloc(sizeof(building_type), 1); + btype = (building_type *)calloc(1, sizeof(building_type)); btype->_name = str_strdup(name); btype->flags = BTF_DEFAULT; btype->auraregen = 1.0; diff --git a/src/kernel/faction.c b/src/kernel/faction.c index a78cd943a..21ea35833 100755 --- a/src/kernel/faction.c +++ b/src/kernel/faction.c @@ -119,7 +119,7 @@ static void free_faction(faction * f) i_freeall(&f->items); - freelist(f->ursprung); + freelist(f->origin); } #define FMAXHASH 2039 @@ -727,10 +727,10 @@ bool faction_alive(const faction *f) { void faction_getorigin(const faction * f, int id, int *x, int *y) { - ursprung *ur; + origin *ur; assert(f && x && y); - for (ur = f->ursprung; ur; ur = ur->next) { + for (ur = f->origin; ur; ur = ur->next) { if (ur->id == id) { *x = ur->x; *y = ur->y; @@ -739,24 +739,27 @@ void faction_getorigin(const faction * f, int id, int *x, int *y) } } -void faction_setorigin(faction * f, int id, int x, int y) -{ - ursprung *ur; - assert(f != NULL); - for (ur = f->ursprung; ur; ur = ur->next) { - if (ur->id == id) { - ur->x = ur->x + x; - ur->y = ur->y + y; - return; - } - } - - ur = calloc(1, sizeof(ursprung)); +static origin *new_origin(int id, int x, int y) { + origin *ur = (origin *)calloc(1, sizeof(origin)); ur->id = id; ur->x = x; ur->y = y; + return ur; +} - addlist(&f->ursprung, ur); +void faction_setorigin(faction * f, int id, int x, int y) +{ + origin **urp; + assert(f != NULL); + for (urp = &f->origin; *urp; urp = &(*urp)->next) { + origin *ur = *urp; + if (ur->id == id) { + ur->x += x; + ur->y += y; + return; + } + } + *urp = new_origin(id, x, y); } diff --git a/src/kernel/faction.h b/src/kernel/faction.h index 63c5a9993..0fe38cb1d 100644 --- a/src/kernel/faction.h +++ b/src/kernel/faction.h @@ -37,7 +37,7 @@ extern "C" { struct attrib_type; struct gamedata; struct selist; - + /* faction flags */ #define FFL_NOAID (1<<0) /* Hilfsflag Kampf */ #define FFL_ISNEW (1<<1) @@ -54,6 +54,12 @@ extern "C" { #define FFL_NPC (1<<25) /* eine Partei mit Monstern */ #define FFL_SAVEMASK (FFL_DEFENDER|FFL_NPC|FFL_NOIDLEOUT|FFL_CURSED) + typedef struct origin { + struct origin *next; + int id; + int x, y; + } origin; + typedef struct faction { struct faction *next; struct faction *nexthash; @@ -72,7 +78,7 @@ extern "C" { const struct locale *locale; int lastorders; int age; - struct ursprung *ursprung; + struct origin *origin; const struct race *race; magic_t magiegebiet; int newbies; diff --git a/src/kernel/faction.test.c b/src/kernel/faction.test.c index d2931c669..6c2ed3aa6 100644 --- a/src/kernel/faction.test.c +++ b/src/kernel/faction.test.c @@ -119,7 +119,7 @@ static void test_addfaction(CuTest *tc) { CuAssertPtrEquals(tc, NULL, (void *)f->next); CuAssertPtrEquals(tc, NULL, (void *)f->banner); CuAssertPtrEquals(tc, NULL, (void *)f->spellbook); - CuAssertPtrEquals(tc, NULL, (void *)f->ursprung); + CuAssertPtrEquals(tc, NULL, (void *)f->origin); CuAssertPtrEquals(tc, (void *)factions, (void *)f); CuAssertStrEquals(tc, "test@eressea.de", f->email); CuAssertTrue(tc, checkpasswd(f, "hurrdurr")); @@ -162,11 +162,11 @@ static void test_set_origin(CuTest *tc) { test_setup(); pl = create_new_plane(0, "", 0, 19, 0, 19, 0); f = test_create_faction(NULL); - CuAssertPtrEquals(tc, NULL, f->ursprung); + CuAssertPtrEquals(tc, NULL, f->origin); faction_setorigin(f, 0, 1, 1); - CuAssertIntEquals(tc, 0, f->ursprung->id); - CuAssertIntEquals(tc, 1, f->ursprung->x); - CuAssertIntEquals(tc, 1, f->ursprung->y); + CuAssertIntEquals(tc, 0, f->origin->id); + CuAssertIntEquals(tc, 1, f->origin->x); + CuAssertIntEquals(tc, 1, f->origin->y); faction_getorigin(f, 0, &x, &y); CuAssertIntEquals(tc, 1, x); CuAssertIntEquals(tc, 1, y); @@ -190,7 +190,7 @@ static void test_set_origin_bug(CuTest *tc) { faction_setorigin(f, 0, -10, 3); faction_setorigin(f, 0, -13, -4); adjust_coordinates(f, &x, &y, pl); - CuAssertIntEquals(tc, 0, f->ursprung->id); + CuAssertIntEquals(tc, 0, f->origin->id); CuAssertIntEquals(tc, -9, x); CuAssertIntEquals(tc, 2, y); test_teardown(); diff --git a/src/kernel/plane.c b/src/kernel/plane.c index 71c0dbd86..89de42618 100644 --- a/src/kernel/plane.c +++ b/src/kernel/plane.c @@ -122,7 +122,7 @@ int getplaneid(const region * r) static int ursprung_x(const faction * f, const plane * pl, const region * rdefault) { - ursprung *ur; + origin *ur; int id = 0; if (!f) @@ -131,7 +131,7 @@ ursprung_x(const faction * f, const plane * pl, const region * rdefault) if (pl) id = pl->id; - for (ur = f->ursprung; ur; ur = ur->next) { + for (ur = f->origin; ur; ur = ur->next) { if (ur->id == id) return ur->x; } @@ -145,7 +145,7 @@ ursprung_x(const faction * f, const plane * pl, const region * rdefault) static int ursprung_y(const faction * f, const plane * pl, const region * rdefault) { - ursprung *ur; + origin *ur; int id = 0; if (!f) @@ -154,7 +154,7 @@ ursprung_y(const faction * f, const plane * pl, const region * rdefault) if (pl) id = pl->id; - for (ur = f->ursprung; ur; ur = ur->next) { + for (ur = f->origin; ur; ur = ur->next) { if (ur->id == id) return ur->y; } diff --git a/src/kernel/region.c b/src/kernel/region.c index 377bf1e22..fee51d13c 100644 --- a/src/kernel/region.c +++ b/src/kernel/region.c @@ -774,7 +774,7 @@ region *new_region(int x, int y, struct plane *pl, int uid) log_error("duplicate region contains units\n"); return r; } - r = calloc(1, sizeof(region)); + r = (region *)calloc(sizeof(region), 1); assert_alloc(r); r->x = x; r->y = y; diff --git a/src/kernel/save.c b/src/kernel/save.c index cdc951fad..a61e4348f 100644 --- a/src/kernel/save.c +++ b/src/kernel/save.c @@ -357,14 +357,14 @@ static void read_skills(gamedata *data, unit *u) size_t sz = u->skill_size * sizeof(skill); qsort(skills, u->skill_size, sizeof(skill), skill_cmp); - u->skills = malloc(sz); + u->skills = (skill *)malloc(sz); memcpy(u->skills, skills, sz); } } else { int i; READ_INT(data->store, &u->skill_size); - u->skills = malloc(sizeof(skill)*u->skill_size); + u->skills = (skill *)malloc(sizeof(skill)*u->skill_size); for (i = 0; i != u->skill_size; ++i) { skill *sv = u->skills + i; read_skill(data, sv); @@ -420,7 +420,7 @@ unit *read_unit(gamedata *data) u_setfaction(u, NULL); } else { - u = calloc(sizeof(unit), 1); + u = (unit *)calloc(1, sizeof(unit)); assert_alloc(u); u->no = n; uhash(u); @@ -1095,7 +1095,7 @@ faction *read_faction(gamedata * data) void write_faction(gamedata *data, const faction * f) { ally *sf; - ursprung *ur; + origin *ur; assert(f->_alive); assert(f->no > 0 && f->no <= MAX_UNIT_NR); @@ -1134,8 +1134,8 @@ void write_faction(gamedata *data, const faction * f) WRITE_SECTION(data->store); WRITE_TOK(data->store, "end"); WRITE_SECTION(data->store); - WRITE_INT(data->store, listlen(f->ursprung)); - for (ur = f->ursprung; ur; ur = ur->next) { + WRITE_INT(data->store, listlen(f->origin)); + for (ur = f->origin; ur; ur = ur->next) { WRITE_INT(data->store, ur->id); WRITE_INT(data->store, ur->x); WRITE_INT(data->store, ur->y); diff --git a/src/kernel/types.h b/src/kernel/types.h index d4f46ae8d..34c50e0a1 100644 --- a/src/kernel/types.h +++ b/src/kernel/types.h @@ -55,12 +55,6 @@ struct terrain_type; struct unit; struct weapon_type; -typedef struct ursprung { - struct ursprung *next; - int id; - int x, y; -} ursprung; - /* seen_mode: visibility in the report */ typedef enum { seen_none, diff --git a/src/listbox.c b/src/listbox.c index 4aa00adaf..542ab13e8 100644 --- a/src/listbox.c +++ b/src/listbox.c @@ -28,7 +28,7 @@ void insert_selection(list_selection ** p_sel, list_selection * prev, const char *str, void *payload) { - list_selection *sel = calloc(sizeof(list_selection), 1); + list_selection *sel = (list_selection *)calloc(1, sizeof(list_selection)); sel->str = str_strdup(str); sel->data = payload; if (*p_sel) { @@ -56,7 +56,7 @@ const char *str, void *payload) list_selection **push_selection(list_selection ** p_sel, char *str, void *payload) { - list_selection *sel = calloc(sizeof(list_selection), 1); + list_selection *sel = (list_selection *)calloc(1, sizeof(list_selection)); list_selection *prev = NULL; sel->str = str; sel->data = payload; diff --git a/src/modules/autoseed.c b/src/modules/autoseed.c index 65585441c..bb31d3f4e 100644 --- a/src/modules/autoseed.c +++ b/src/modules/autoseed.c @@ -133,7 +133,7 @@ newfaction *read_newfactions(const char *filename) if (nf) { continue; } - nf = calloc(sizeof(newfaction), 1); + nf = (newfaction *)calloc(1, sizeof(newfaction)); if (check_email(email) == 0) { nf->email = str_strdup(email); } else { diff --git a/src/spells/borders.c b/src/spells/borders.c index 5d99b1307..c0e51a9b1 100644 --- a/src/spells/borders.c +++ b/src/spells/borders.c @@ -79,7 +79,7 @@ const curse_type ct_firewall = { static void wall_init(connection * b) { - wall_data *fd = (wall_data *)calloc(sizeof(wall_data), 1); + wall_data *fd = (wall_data *)calloc(1, sizeof(wall_data)); fd->countdown = -1; /* infinite */ b->data.v = fd; } diff --git a/src/util/umlaut.c b/src/util/umlaut.c index 1f9e32b1f..00252fb02 100644 --- a/src/util/umlaut.c +++ b/src/util/umlaut.c @@ -117,7 +117,7 @@ char * transliterate(char * out, size_t size, const char * in) } tnode * mknode(void) { - tnode * node = calloc(1, sizeof(tnode)); + tnode * node = (tnode *)calloc(1, sizeof(tnode)); node->refcount = 1; return node; } From 6a615ab0cde704e1c7e9a5bd1af61ba7430b6a48 Mon Sep 17 00:00:00 2001 From: Enno Rehling Date: Tue, 23 Oct 2018 17:43:11 +0200 Subject: [PATCH 090/160] disable ASM implementation of bcrypt --- src/util/crypto/crypt_blowfish/crypt_blowfish.c | 5 +---- 1 file changed, 1 insertion(+), 4 deletions(-) diff --git a/src/util/crypto/crypt_blowfish/crypt_blowfish.c b/src/util/crypto/crypt_blowfish/crypt_blowfish.c index b0b11d3ad..701ddddf0 100644 --- a/src/util/crypto/crypt_blowfish/crypt_blowfish.c +++ b/src/util/crypto/crypt_blowfish/crypt_blowfish.c @@ -53,10 +53,7 @@ /* Just to make sure the prototypes match the actual definitions */ #include "crypt_blowfish.h" -#ifdef __i386__ -#define BF_ASM 1 -#define BF_SCALE 1 -#elif defined(__x86_64__) || defined(__alpha__) || defined(__hppa__) +#if defined(__x86_64__) || defined(__alpha__) || defined(__hppa__) #define BF_ASM 0 #define BF_SCALE 1 #else From b8ee5b3c7698db0fb5e71875fc1901b1281b0421 Mon Sep 17 00:00:00 2001 From: Enno Rehling Date: Tue, 23 Oct 2018 22:31:42 +0200 Subject: [PATCH 091/160] begin the work to swap strings to database --- src/eressea.c | 5 +- src/kernel/CMakeLists.txt | 1 + src/kernel/db/driver.h | 2 + src/kernel/db/sqlite.c | 151 +++++++++++++++++++++++++++----------- src/kernel/order.c | 18 +++++ src/orderdb.c | 28 ------- 6 files changed, 133 insertions(+), 72 deletions(-) diff --git a/src/eressea.c b/src/eressea.c index e1767811c..1221f93e0 100644 --- a/src/eressea.c +++ b/src/eressea.c @@ -3,6 +3,7 @@ #include "kernel/building.h" #include "kernel/calendar.h" +#include "kernel/database.h" #include "kernel/config.h" #include "kernel/curse.h" #include "kernel/equipment.h" @@ -54,12 +55,12 @@ void game_done(void) free_locales(); #endif kernel_done(); - orderdb_close(); + swapdb_close(); } void game_init(void) { - orderdb_open(); + swapdb_open(); errno = 0; kernel_init(); register_triggers(); diff --git a/src/kernel/CMakeLists.txt b/src/kernel/CMakeLists.txt index 06f58fc1b..dcd19c35a 100644 --- a/src/kernel/CMakeLists.txt +++ b/src/kernel/CMakeLists.txt @@ -58,6 +58,7 @@ command.c config.c connection.c curse.c +database.c equipment.c event.c faction.c diff --git a/src/kernel/db/driver.h b/src/kernel/db/driver.h index 9632cb5db..e127c6662 100644 --- a/src/kernel/db/driver.h +++ b/src/kernel/db/driver.h @@ -16,3 +16,5 @@ void db_driver_close(database_t db); int db_driver_order_save(const char *str); struct order_data *db_driver_order_load(int id); int db_driver_faction_save(int id, int no, int turn, const char *email, const char *password); +unsigned int db_driver_string_save(const char *s); +const char *db_driver_string_load(unsigned int id, size_t *size); diff --git a/src/kernel/db/sqlite.c b/src/kernel/db/sqlite.c index fd9d0bc67..9df27f365 100644 --- a/src/kernel/db/sqlite.c +++ b/src/kernel/db/sqlite.c @@ -15,14 +15,25 @@ #include static sqlite3 *g_game_db; -static sqlite3 *g_temp_db; +static sqlite3 *g_swap_db; +static sqlite3_stmt * g_stmt_insert_string; +static sqlite3_stmt * g_stmt_select_string; static sqlite3_stmt * g_stmt_insert_order; static sqlite3_stmt * g_stmt_select_order; static sqlite3_stmt * g_stmt_update_faction; static sqlite3_stmt * g_stmt_insert_faction; -static int g_order_batchsize; -static int g_order_tx_size; +static int g_insert_batchsize; +static int g_insert_tx_size; + +static void end_transaction(void) { + if (g_insert_tx_size > 0) { + int err; + g_insert_tx_size = 0; + err = sqlite3_exec(g_swap_db, "COMMIT", NULL, NULL, NULL); + assert(err == SQLITE_OK); + } +} struct order_data *db_driver_order_load(int id) { @@ -30,35 +41,27 @@ struct order_data *db_driver_order_load(int id) int err; ERRNO_CHECK(); - if (g_order_tx_size > 0) { - g_order_tx_size = 0; - err = sqlite3_exec(g_temp_db, "COMMIT", NULL, NULL, NULL); - assert(err == SQLITE_OK); - } + end_transaction(); err = sqlite3_reset(g_stmt_select_order); assert(err == SQLITE_OK); err = sqlite3_bind_int(g_stmt_select_order, 1, id); assert(err == SQLITE_OK); - do { - err = sqlite3_step(g_stmt_select_order); - if (err == SQLITE_ROW) { - const unsigned char *text; - int bytes; - bytes = sqlite3_column_bytes(g_stmt_select_order, 0); - assert(bytes > 0); - text = sqlite3_column_text(g_stmt_select_order, 0); - odata_create(&od, 1+(size_t)bytes, (const char *)text); - ERRNO_CHECK(); - return od; - } - } while (err == SQLITE_ROW); - assert(err == SQLITE_DONE); + err = sqlite3_step(g_stmt_select_order); + if (err == SQLITE_ROW) { + const unsigned char *text; + int bytes; + text = sqlite3_column_text(g_stmt_select_order, 0); + bytes = sqlite3_column_bytes(g_stmt_select_order, 0); + assert(bytes > 0); + odata_create(&od, 1+(size_t)bytes, (const char *)text); + ERRNO_CHECK(); + return od; + } ERRNO_CHECK(); return NULL; } -int db_driver_order_save(const char *str) -{ +int db_driver_order_save(const char *str) { int err; sqlite3_int64 id; @@ -66,9 +69,9 @@ int db_driver_order_save(const char *str) ERRNO_CHECK(); - if (g_order_batchsize > 0) { - if (g_order_tx_size == 0) { - err = sqlite3_exec(g_temp_db, "BEGIN TRANSACTION", NULL, NULL, NULL); + if (g_insert_batchsize > 0) { + if (g_insert_tx_size == 0) { + err = sqlite3_exec(g_swap_db, "BEGIN TRANSACTION", NULL, NULL, NULL); assert(err == SQLITE_OK); } } @@ -79,14 +82,12 @@ int db_driver_order_save(const char *str) assert(err == SQLITE_OK); err = sqlite3_step(g_stmt_insert_order); assert(err == SQLITE_DONE); - id = sqlite3_last_insert_rowid(g_temp_db); + id = sqlite3_last_insert_rowid(g_swap_db); assert(id <= INT_MAX); - if (g_order_batchsize > 0) { - if (++g_order_tx_size >= g_order_batchsize) { - err = sqlite3_exec(g_temp_db, "COMMIT", NULL, NULL, NULL); - assert(err == SQLITE_OK); - g_order_tx_size = 0; + if (g_insert_batchsize > 0) { + if (++g_insert_tx_size >= g_insert_batchsize) { + end_transaction(); } } ERRNO_CHECK(); @@ -162,19 +163,25 @@ static int db_open_game(const char *dbname) { static int db_open_swap(const char *dbname) { int err; - g_order_batchsize = config_get_int("game.dbbatch", 100); + g_insert_batchsize = config_get_int("game.dbbatch", 100); - err = sqlite3_open(dbname, &g_temp_db); + err = sqlite3_open(dbname, &g_swap_db); assert(err == SQLITE_OK); - err = sqlite3_exec(g_temp_db, "PRAGMA journal_mode=OFF", NULL, NULL, NULL); + err = sqlite3_exec(g_swap_db, "PRAGMA journal_mode=OFF", NULL, NULL, NULL); assert(err == SQLITE_OK); - err = sqlite3_exec(g_temp_db, "PRAGMA synchronous=OFF", NULL, NULL, NULL); + err = sqlite3_exec(g_swap_db, "PRAGMA synchronous=OFF", NULL, NULL, NULL); assert(err == SQLITE_OK); - err = sqlite3_exec(g_temp_db, "CREATE TABLE IF NOT EXISTS orders (id INTEGER PRIMARY KEY, data TEXT NOT NULL)", NULL, NULL, NULL); + err = sqlite3_exec(g_swap_db, "CREATE TABLE IF NOT EXISTS orders (id INTEGER PRIMARY KEY, data TEXT NOT NULL)", NULL, NULL, NULL); assert(err == SQLITE_OK); - err = sqlite3_prepare_v2(g_temp_db, "INSERT INTO orders (data) VALUES (?)", -1, &g_stmt_insert_order, NULL); + err = sqlite3_exec(g_swap_db, "CREATE TABLE IF NOT EXISTS strings (id INTEGER PRIMARY KEY, data TEXT NOT NULL)", NULL, NULL, NULL); assert(err == SQLITE_OK); - err = sqlite3_prepare_v2(g_temp_db, "SELECT data FROM orders WHERE id=?", -1, &g_stmt_select_order, NULL); + err = sqlite3_prepare_v2(g_swap_db, "INSERT INTO strings (data) VALUES (?)", -1, &g_stmt_insert_string, NULL); + assert(err == SQLITE_OK); + err = sqlite3_prepare_v2(g_swap_db, "SELECT data FROM strings WHERE id=?", -1, &g_stmt_select_string, NULL); + assert(err == SQLITE_OK); + err = sqlite3_prepare_v2(g_swap_db, "INSERT INTO orders (data) VALUES (?)", -1, &g_stmt_insert_order, NULL); + assert(err == SQLITE_OK); + err = sqlite3_prepare_v2(g_swap_db, "SELECT data FROM orders WHERE id=?", -1, &g_stmt_select_order, NULL); assert(err == SQLITE_OK); ERRNO_CHECK(); return 0; @@ -202,12 +209,16 @@ void db_driver_close(database_t db) ERRNO_CHECK(); if (db == DB_SWAP) { - assert(g_temp_db); + assert(g_swap_db); + err = sqlite3_finalize(g_stmt_select_string); + assert(err == SQLITE_OK); + err = sqlite3_finalize(g_stmt_insert_string); + assert(err == SQLITE_OK); err = sqlite3_finalize(g_stmt_select_order); assert(err == SQLITE_OK); err = sqlite3_finalize(g_stmt_insert_order); assert(err == SQLITE_OK); - err = sqlite3_close(g_temp_db); + err = sqlite3_close(g_swap_db); assert(err == SQLITE_OK); if (g_swapname) { FILE * F = fopen(g_swapname, "r"); @@ -229,3 +240,59 @@ void db_driver_close(database_t db) ERRNO_CHECK(); } +unsigned int db_driver_string_save(const char *str) { + int err; + sqlite3_int64 id; + + assert(str); + + ERRNO_CHECK(); + + if (g_insert_batchsize > 0) { + if (g_insert_tx_size == 0) { + err = sqlite3_exec(g_swap_db, "BEGIN TRANSACTION", NULL, NULL, NULL); + assert(err == SQLITE_OK); + } + } + + err = sqlite3_reset(g_stmt_insert_string); + assert(err == SQLITE_OK); + err = sqlite3_bind_text(g_stmt_insert_string, 1, str, -1, SQLITE_STATIC); + assert(err == SQLITE_OK); + err = sqlite3_step(g_stmt_insert_string); + assert(err == SQLITE_DONE); + id = sqlite3_last_insert_rowid(g_swap_db); + assert(id <= INT_MAX); + + if (g_insert_batchsize > 0) { + if (++g_insert_tx_size >= g_insert_batchsize) { + end_transaction(); + } + } + ERRNO_CHECK(); + return (int)id; +} + +const char *db_driver_string_load(unsigned int id, size_t *size) { + int err; + + end_transaction(); + err = sqlite3_reset(g_stmt_select_string); + assert(err == SQLITE_OK); + err = sqlite3_bind_int(g_stmt_select_string, 1, id); + assert(err == SQLITE_OK); + err = sqlite3_step(g_stmt_select_string); + if (err == SQLITE_ROW) { + const unsigned char *text; + text = sqlite3_column_text(g_stmt_select_string, 0); + if (size) { + int bytes = sqlite3_column_bytes(g_stmt_select_string, 0); + assert(bytes > 0); + *size = (size_t)bytes; + } + ERRNO_CHECK(); + return (const char *)text; + } + ERRNO_CHECK(); + return NULL; +} diff --git a/src/kernel/order.c b/src/kernel/order.c index c0c1e82fb..818c77a72 100644 --- a/src/kernel/order.c +++ b/src/kernel/order.c @@ -14,6 +14,8 @@ #include #include "order.h" +#include "db/driver.h" + #include "skill.h" #include @@ -36,6 +38,22 @@ # define ORD_KEYWORD(ord) (keyword_t)((ord)->command & 0xFFFF) # define OD_STRING(odata) ((odata) ? (odata)->_str : NULL) +order_data *odata_load(int id) +{ + if (id > 0) { + return db_driver_order_load(id); + } + return NULL; +} + +int odata_save(order_data *od) +{ + if (od->_str) { + return db_driver_order_save(od->_str); + } + return 0; +} + void odata_create(order_data **pdata, size_t len, const char *str) { order_data *data; diff --git a/src/orderdb.c b/src/orderdb.c index 5c224a79e..87b6e626c 100644 --- a/src/orderdb.c +++ b/src/orderdb.c @@ -1,7 +1,6 @@ #include #include "kernel/config.h" -#include "kernel/db/driver.h" #include "orderdb.h" @@ -13,30 +12,3 @@ #include #include -void orderdb_open(void) -{ - const char *dbname; - dbname = config_get("game.dbswap"); - db_driver_open(DB_SWAP, dbname); -} - -void orderdb_close(void) -{ - db_driver_close(DB_SWAP); -} - -order_data *odata_load(int id) -{ - if (id > 0) { - return db_driver_order_load(id); - } - return NULL; -} - -int odata_save(order_data *od) -{ - if (od->_str) { - return db_driver_order_save(od->_str); - } - return 0; -} From 6738962d73941ad2eae07d58b2a52cd6ca295a97 Mon Sep 17 00:00:00 2001 From: Enno Rehling Date: Wed, 24 Oct 2018 07:00:26 +0200 Subject: [PATCH 092/160] missing files --- src/kernel/database.c | 28 ++++++++++++++++++++++++++++ src/kernel/database.h | 11 +++++++++++ 2 files changed, 39 insertions(+) create mode 100644 src/kernel/database.c create mode 100644 src/kernel/database.h diff --git a/src/kernel/database.c b/src/kernel/database.c new file mode 100644 index 000000000..fec8867a2 --- /dev/null +++ b/src/kernel/database.c @@ -0,0 +1,28 @@ +#include "config.h" +#include "database.h" +#include "db/driver.h" + +void swapdb_open(void) +{ + const char *dbname; + dbname = config_get("game.dbswap"); + db_driver_open(DB_SWAP, dbname); +} + +void swapdb_close(void) +{ + db_driver_close(DB_SWAP); +} + +dbstring_id db_string_save(const char *s) { + (void)s; + return 0; +} + +dbstring_id dbstring_save(const char *s) { + return db_driver_string_save(s); +} + +const char *dbstring_load(dbstring_id id, size_t *size) { + return db_driver_string_load(id, size); +} diff --git a/src/kernel/database.h b/src/kernel/database.h new file mode 100644 index 000000000..584b21908 --- /dev/null +++ b/src/kernel/database.h @@ -0,0 +1,11 @@ +#pragma once + +#include + +typedef unsigned int dbstring_id; + +void swapdb_open(void); +void swapdb_close(void); + +dbstring_id dbstring_save(const char *s); +const char *dbstring_load(dbstring_id id, size_t *size); From 83959c375f9c667812c0948980fbad800ffd1d05 Mon Sep 17 00:00:00 2001 From: Enno Rehling Date: Wed, 24 Oct 2018 09:02:19 +0200 Subject: [PATCH 093/160] kill orderdb.[hc] files --- src/CMakeLists.txt | 2 -- src/eressea.c | 1 - src/kernel/database.c | 7 ++++--- src/kernel/database.h | 8 +++---- src/kernel/database.test.c | 14 ++++++++++++- src/kernel/db/driver.h | 12 ++++++----- src/kernel/db/sqlite.c | 22 +++++++++---------- src/kernel/orderdb.c | 43 -------------------------------------- src/kernel/orderdb.h | 16 -------------- src/orderdb.c | 14 ------------- src/orderdb.h | 25 ---------------------- src/orderdb.test.c | 28 ------------------------- src/test_eressea.c | 1 - 13 files changed, 39 insertions(+), 154 deletions(-) delete mode 100644 src/kernel/orderdb.c delete mode 100644 src/kernel/orderdb.h delete mode 100644 src/orderdb.c delete mode 100644 src/orderdb.h delete mode 100644 src/orderdb.test.c diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt index 4e8db8bf9..c42e3eb2e 100644 --- a/src/CMakeLists.txt +++ b/src/CMakeLists.txt @@ -117,7 +117,6 @@ set (ERESSEA_SRC morale.c move.c names.c - orderdb.c orderfile.c piracy.c prefix.c @@ -230,7 +229,6 @@ set(TESTS_SRC monsters.test.c move.test.c names.test.c - orderdb.test.c orderfile.test.c piracy.test.c prefix.test.c diff --git a/src/eressea.c b/src/eressea.c index 1221f93e0..8e7da7f7a 100644 --- a/src/eressea.c +++ b/src/eressea.c @@ -28,7 +28,6 @@ #include "creport.h" #include "report.h" #include "names.h" -#include "orderdb.h" #include "reports.h" #include "spells.h" #include "vortex.h" diff --git a/src/kernel/database.c b/src/kernel/database.c index fec8867a2..796aa2380 100644 --- a/src/kernel/database.c +++ b/src/kernel/database.c @@ -14,15 +14,16 @@ void swapdb_close(void) db_driver_close(DB_SWAP); } -dbstring_id db_string_save(const char *s) { +dbrow_id db_string_save(const char *s) { (void)s; return 0; } -dbstring_id dbstring_save(const char *s) { +dbrow_id dbstring_save(const char *s) { return db_driver_string_save(s); } -const char *dbstring_load(dbstring_id id, size_t *size) { +const char *dbstring_load(dbrow_id id, size_t *size) { return db_driver_string_load(id, size); } + diff --git a/src/kernel/database.h b/src/kernel/database.h index 584b21908..8147ccc61 100644 --- a/src/kernel/database.h +++ b/src/kernel/database.h @@ -1,11 +1,11 @@ #pragma once -#include +#include "db/driver.h" -typedef unsigned int dbstring_id; +#include void swapdb_open(void); void swapdb_close(void); -dbstring_id dbstring_save(const char *s); -const char *dbstring_load(dbstring_id id, size_t *size); +dbrow_id dbstring_save(const char *s); +const char *dbstring_load(dbrow_id id, size_t *size); diff --git a/src/kernel/database.test.c b/src/kernel/database.test.c index 3ec44896e..04108aa85 100644 --- a/src/kernel/database.test.c +++ b/src/kernel/database.test.c @@ -3,8 +3,8 @@ #include #include +#include "database.h" #include "db/driver.h" -#include "orderdb.h" #include #include @@ -12,6 +12,17 @@ #include #include +static void test_orderdb(CuTest *tc) { + order_data *od = NULL; + const char * s = "GIB enno 1 Hodor"; + + odata_create(&od, strlen(s) + 1, s); + CuAssertPtrNotNull(tc, od); + CuAssertStrEquals(tc, s, od->_str); + CuAssertTrue(tc, od->_refcount >= 1); + odata_release(od); +} + static void test_save_load_order(CuTest *tc) { order_data *od; int id; @@ -52,6 +63,7 @@ CuSuite *get_db_suite(void) CuSuite *suite = CuSuiteNew(); SUITE_ADD_TEST(suite, test_save_load_order); SUITE_ADD_TEST(suite, test_update_faction); + SUITE_ADD_TEST(suite, test_orderdb); return suite; } diff --git a/src/kernel/db/driver.h b/src/kernel/db/driver.h index e127c6662..341653991 100644 --- a/src/kernel/db/driver.h +++ b/src/kernel/db/driver.h @@ -4,6 +4,8 @@ struct order_data; +typedef unsigned int dbrow_id; + extern void odata_create(struct order_data **pdata, size_t len, const char *str); typedef enum database_t { @@ -13,8 +15,8 @@ typedef enum database_t { int db_driver_open(database_t db, const char *dbname); void db_driver_close(database_t db); -int db_driver_order_save(const char *str); -struct order_data *db_driver_order_load(int id); -int db_driver_faction_save(int id, int no, int turn, const char *email, const char *password); -unsigned int db_driver_string_save(const char *s); -const char *db_driver_string_load(unsigned int id, size_t *size); +dbrow_id db_driver_order_save(const char *str); +struct order_data *db_driver_order_load(dbrow_id id); +dbrow_id db_driver_faction_save(dbrow_id id, int no, int turn, const char *email, const char *password); +dbrow_id db_driver_string_save(const char *s); +const char *db_driver_string_load(dbrow_id id, size_t *size); diff --git a/src/kernel/db/sqlite.c b/src/kernel/db/sqlite.c index 9df27f365..9a4dbc9ff 100644 --- a/src/kernel/db/sqlite.c +++ b/src/kernel/db/sqlite.c @@ -35,7 +35,7 @@ static void end_transaction(void) { } } -struct order_data *db_driver_order_load(int id) +struct order_data *db_driver_order_load(dbrow_id id) { struct order_data * od = NULL; int err; @@ -61,7 +61,7 @@ struct order_data *db_driver_order_load(int id) return NULL; } -int db_driver_order_save(const char *str) { +dbrow_id db_driver_order_save(const char *str) { int err; sqlite3_int64 id; @@ -83,7 +83,7 @@ int db_driver_order_save(const char *str) { err = sqlite3_step(g_stmt_insert_order); assert(err == SQLITE_DONE); id = sqlite3_last_insert_rowid(g_swap_db); - assert(id <= INT_MAX); + assert(id > 0 && id <= UINT_MAX); if (g_insert_batchsize > 0) { if (++g_insert_tx_size >= g_insert_batchsize) { @@ -91,11 +91,11 @@ int db_driver_order_save(const char *str) { } } ERRNO_CHECK(); - return (int)id; + return (dbrow_id)id; } -int db_driver_faction_save(int id, int no, int turn, const char *email, const char *password) +dbrow_id db_driver_faction_save(dbrow_id id, int no, int turn, const char *email, const char *password) { sqlite3_int64 row_id; int err; @@ -140,8 +140,8 @@ int db_driver_faction_save(int id, int no, int turn, const char *email, const ch ERRNO_CHECK(); row_id = sqlite3_last_insert_rowid(g_game_db); - assert(row_id <= INT_MAX); - return (int)row_id; + assert(row_id>0 && row_id <= UINT_MAX); + return (dbrow_id)row_id; } static int db_open_game(const char *dbname) { @@ -240,7 +240,7 @@ void db_driver_close(database_t db) ERRNO_CHECK(); } -unsigned int db_driver_string_save(const char *str) { +dbrow_id db_driver_string_save(const char *str) { int err; sqlite3_int64 id; @@ -262,7 +262,7 @@ unsigned int db_driver_string_save(const char *str) { err = sqlite3_step(g_stmt_insert_string); assert(err == SQLITE_DONE); id = sqlite3_last_insert_rowid(g_swap_db); - assert(id <= INT_MAX); + assert(id > 0 && id <= UINT_MAX); if (g_insert_batchsize > 0) { if (++g_insert_tx_size >= g_insert_batchsize) { @@ -270,10 +270,10 @@ unsigned int db_driver_string_save(const char *str) { } } ERRNO_CHECK(); - return (int)id; + return (dbrow_id)id; } -const char *db_driver_string_load(unsigned int id, size_t *size) { +const char *db_driver_string_load(dbrow_id id, size_t *size) { int err; end_transaction(); diff --git a/src/kernel/orderdb.c b/src/kernel/orderdb.c deleted file mode 100644 index 42248c0ef..000000000 --- a/src/kernel/orderdb.c +++ /dev/null @@ -1,43 +0,0 @@ -#include - -#include "kernel/config.h" -#include "kernel/db/driver.h" - -#include "orderdb.h" - -#include - -#include - -#include -#include -#include - -void orderdb_open(void) -{ - const char *dbname; - - dbname = config_get("game.dbswap"); - db_driver_open(DB_SWAP, dbname); -} - -void orderdb_close(void) -{ - db_driver_close(DB_SWAP); -} - -order_data *odata_load(int id) -{ - if (id > 0) { - return db_driver_order_load(id); - } - return NULL; -} - -int odata_save(order_data *od) -{ - if (od->_str) { - return db_driver_order_save(od->_str); - } - return 0; -} diff --git a/src/kernel/orderdb.h b/src/kernel/orderdb.h deleted file mode 100644 index e17bdfea8..000000000 --- a/src/kernel/orderdb.h +++ /dev/null @@ -1,16 +0,0 @@ -#ifndef H_ORDERDB -#define H_ORDERDB - -#include - -#ifdef __cplusplus -extern "C" { -#endif - - void orderdb_open(void); - void orderdb_close(void); - -#ifdef __cplusplus -} -#endif -#endif diff --git a/src/orderdb.c b/src/orderdb.c deleted file mode 100644 index 87b6e626c..000000000 --- a/src/orderdb.c +++ /dev/null @@ -1,14 +0,0 @@ -#include - -#include "kernel/config.h" - -#include "orderdb.h" - -#include - -#include - -#include -#include -#include - diff --git a/src/orderdb.h b/src/orderdb.h deleted file mode 100644 index cc809b1a6..000000000 --- a/src/orderdb.h +++ /dev/null @@ -1,25 +0,0 @@ -#ifndef H_ORDERDB -#define H_ORDERDB - -#include - -#ifdef __cplusplus -extern "C" { -#endif - - typedef struct order_data { - const char *_str; - int _refcount; - } order_data; - - void odata_create(order_data **pdata, size_t len, const char *str); - void odata_release(order_data * od); - void odata_addref(order_data *od); - - void orderdb_open(void); - void orderdb_close(void); - -#ifdef __cplusplus -} -#endif -#endif diff --git a/src/orderdb.test.c b/src/orderdb.test.c deleted file mode 100644 index bdb6f0a95..000000000 --- a/src/orderdb.test.c +++ /dev/null @@ -1,28 +0,0 @@ -#include -#include - -#include "orderdb.h" - -#include -#include - -#include - -static void test_orderdb(CuTest *tc) { - order_data *od = NULL; - const char * s = "GIB enno 1 Hodor"; - - odata_create(&od, strlen(s) + 1, s); - CuAssertPtrNotNull(tc, od); - CuAssertStrEquals(tc, s, od->_str); - CuAssertTrue(tc, od->_refcount >= 1); - odata_release(od); -} - -CuSuite *get_orderdb_suite(void) -{ - CuSuite *suite = CuSuiteNew(); - SUITE_ADD_TEST(suite, test_orderdb); - - return suite; -} diff --git a/src/test_eressea.c b/src/test_eressea.c index 2b36d4e03..12c658f91 100644 --- a/src/test_eressea.c +++ b/src/test_eressea.c @@ -138,7 +138,6 @@ int RunAllTests(int argc, char *argv[]) ADD_SUITE(monsters); ADD_SUITE(move); ADD_SUITE(names); - ADD_SUITE(orderdb); ADD_SUITE(orderfile); ADD_SUITE(otherfaction); ADD_SUITE(piracy); From 32009b70439bcfa5f446428b13e31dcc5885f1c0 Mon Sep 17 00:00:00 2001 From: Enno Rehling Date: Wed, 24 Oct 2018 09:27:48 +0200 Subject: [PATCH 094/160] store passwords in swapdb --- src/bind_faction.c | 2 +- src/gamedb.c | 4 +++- src/kernel/database.test.c | 8 ++++++-- src/kernel/faction.c | 21 +++++++++++++++------ src/kernel/faction.h | 4 +++- src/kernel/save.c | 4 +--- src/kernel/save.test.c | 2 +- src/reports.c | 8 -------- src/reports.test.c | 2 +- 9 files changed, 31 insertions(+), 24 deletions(-) diff --git a/src/bind_faction.c b/src/bind_faction.c index bb0920395..46967252c 100644 --- a/src/bind_faction.c +++ b/src/bind_faction.c @@ -432,7 +432,7 @@ 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); + tolua_pushstring(L, faction_getpassword(self)); return 1; } diff --git a/src/gamedb.c b/src/gamedb.c index 2ca2dba73..5f53d9120 100644 --- a/src/gamedb.c +++ b/src/gamedb.c @@ -20,7 +20,9 @@ int gamedb_update(void) err = db_driver_open(DB_GAME, dbname); if (err == 0) { for (f = factions; f; f = f->next) { - int uid = db_driver_faction_save(f->uid, f->no, turn, f->email, f->_password); + int uid = db_driver_faction_save(f->uid, f->no, turn, + faction_getemail(f), + faction_getpassword(f)); if (uid > 0) { f->uid = uid; } diff --git a/src/kernel/database.test.c b/src/kernel/database.test.c index 04108aa85..8be957cb4 100644 --- a/src/kernel/database.test.c +++ b/src/kernel/database.test.c @@ -51,9 +51,13 @@ static void test_update_faction(CuTest *tc) { test_setup(); f = test_create_faction(NULL); - uid = db_driver_faction_save(f->uid, f->no, 0, f->email, f->_password); + uid = db_driver_faction_save(f->uid, f->no, 0, + faction_getemail(f), + faction_getpassword(f)); f->uid = uid; - uid = db_driver_faction_save(f->uid, f->no, 0, f->email, f->_password); + uid = db_driver_faction_save(f->uid, f->no, 0, + faction_getemail(f), + faction_getpassword(f)); CuAssertIntEquals(tc, f->uid, uid); test_teardown(); } diff --git a/src/kernel/faction.c b/src/kernel/faction.c index 21ea35833..a3cd96bc9 100755 --- a/src/kernel/faction.c +++ b/src/kernel/faction.c @@ -22,6 +22,7 @@ OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. #include "calendar.h" #include "config.h" +#include "database.h" #include "alliance.h" #include "ally.h" #include "curse.h" @@ -106,7 +107,6 @@ static void free_faction(faction * f) free(f->email); free(f->banner); - free(f->_password); free(f->name); if (f->seen_factions) { selist_free(f->seen_factions); @@ -245,7 +245,7 @@ faction *addfaction(const char *email, const char *password, f->alliance_joindate = turn; f->lastorders = turn; f->_alive = true; - f->_password = NULL; + f->password_id = 0; f->age = 0; f->race = frace; f->magiegebiet = 0; @@ -321,9 +321,11 @@ unit *addplayer(region * r, faction * f) bool checkpasswd(const faction * f, const char *passwd) { + const char *pwhash; if (!passwd) return false; - if (f->_password && password_verify(f->_password, passwd) == VERIFY_FAIL) { + pwhash = faction_getpassword(f); + if (pwhash && password_verify(pwhash, passwd) == VERIFY_FAIL) { log_info("password check failed: %s", factionname(f)); return false; } @@ -603,11 +605,17 @@ void faction_setbanner(faction * self, const char *banner) self->banner = str_strdup(banner); } +const char *faction_getpassword(const faction *f) { + if (f->password_id > 0) { + return dbstring_load(f->password_id, NULL); + } + return NULL; +} + void faction_setpassword(faction * f, const char *pwhash) { assert(pwhash); - free(f->_password); - f->_password = str_strdup(pwhash); + f->password_id = dbstring_save(pwhash); } bool valid_race(const struct faction *f, const struct race *rc) @@ -844,7 +852,8 @@ int writepasswd(void) for (f = factions; f; f = f->next) { fprintf(F, "%s:%s:%s:%d\n", - itoa36(f->no), faction_getemail(f), f->_password, f->uid); + itoa36(f->no), faction_getemail(f), + faction_getpassword(f), f->uid); } fclose(F); return 0; diff --git a/src/kernel/faction.h b/src/kernel/faction.h index 0fe38cb1d..8548328ef 100644 --- a/src/kernel/faction.h +++ b/src/kernel/faction.h @@ -21,6 +21,7 @@ OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. #include "skill.h" #include "types.h" +#include "db/driver.h" #include #include @@ -72,7 +73,7 @@ extern "C" { char *name; char *banner; char *email; - char *_password; + dbrow_id password_id; int max_spelllevel; struct spellbook *spellbook; const struct locale *locale; @@ -154,6 +155,7 @@ extern "C" { void faction_setemail(struct faction *self, const char *email); void faction_setpassword(struct faction *self, const char *pwhash); + const char *faction_getpassword(const struct faction *f); bool valid_race(const struct faction *f, const struct race *rc); void faction_getorigin(const struct faction * f, int id, int *x, int *y); diff --git a/src/kernel/save.c b/src/kernel/save.c index a61e4348f..63e14b3c3 100644 --- a/src/kernel/save.c +++ b/src/kernel/save.c @@ -931,7 +931,6 @@ static void read_password(gamedata *data, faction *f) { else { faction_setpassword(f, (data->version >= CRYPT_VERSION) ? name : password_hash(name, PASSWORD_DEFAULT)); } - (void)_test_read_password; } void _test_read_password(gamedata *data, faction *f) { @@ -939,8 +938,7 @@ void _test_read_password(gamedata *data, faction *f) { } static void write_password(gamedata *data, const faction *f) { - WRITE_TOK(data->store, (const char *)f->_password); - (void)_test_write_password; + WRITE_TOK(data->store, faction_getpassword(f)); } void _test_write_password(gamedata *data, const faction *f) { diff --git a/src/kernel/save.test.c b/src/kernel/save.test.c index 4844d1189..a70a27c2f 100644 --- a/src/kernel/save.test.c +++ b/src/kernel/save.test.c @@ -432,7 +432,7 @@ static void test_read_password_external(CuTest *tc) { } f = test_create_faction(NULL); faction_setpassword(f, password_hash("secret", PASSWORD_DEFAULT)); - CuAssertPtrNotNull(tc, f->_password); + CuAssertPtrNotNull(tc, faction_getpassword(f)); mstream_init(&data.strm); gamedata_init(&data, &store, RELEASE_VERSION); WRITE_TOK(data.store, "newpassword"); diff --git a/src/reports.c b/src/reports.c index 879e7ad3d..8088af347 100644 --- a/src/reports.c +++ b/src/reports.c @@ -1554,14 +1554,6 @@ void prepare_report(report_context *ctx, faction *f) rule_lighthouse_units = config_get_int("rules.lighthouse.unit_capacity", 0) != 0; } - if (f->age <= 2) { - if ((f->flags&FFL_PWMSG) == 0) { - /* TODO: this assumes unencrypted passwords */ - f->flags |= FFL_PWMSG; - ADDMSG(&f->msgs, msg_message("changepasswd", "value", f->_password)); - } - } - ctx->f = f; ctx->report_time = time(NULL); ctx->addresses = NULL; diff --git a/src/reports.test.c b/src/reports.test.c index d402b2b6a..e7fcc282b 100644 --- a/src/reports.test.c +++ b/src/reports.test.c @@ -902,7 +902,7 @@ CuSuite *get_reports_suite(void) SUITE_ADD_TEST(suite, test_region_distance); SUITE_ADD_TEST(suite, test_region_distance_max); SUITE_ADD_TEST(suite, test_region_distance_ql); - SUITE_ADD_TEST(suite, test_newbie_password_message); + DISABLE_TEST(suite, test_newbie_password_message); SUITE_ADD_TEST(suite, test_prepare_report); SUITE_ADD_TEST(suite, test_seen_neighbours); SUITE_ADD_TEST(suite, test_seen_travelthru); From da3270517a742aabad5754f3c9eed943829e38e2 Mon Sep 17 00:00:00 2001 From: Enno Rehling Date: Wed, 24 Oct 2018 19:39:30 +0200 Subject: [PATCH 095/160] fix type conversion and incomplete database test. --- src/kernel/database.test.c | 2 ++ src/kernel/db/sqlite.c | 10 ++++++---- 2 files changed, 8 insertions(+), 4 deletions(-) diff --git a/src/kernel/database.test.c b/src/kernel/database.test.c index 8be957cb4..c5aae1af6 100644 --- a/src/kernel/database.test.c +++ b/src/kernel/database.test.c @@ -50,6 +50,7 @@ static void test_update_faction(CuTest *tc) { int uid; test_setup(); + db_driver_open(DB_GAME, NULL); f = test_create_faction(NULL); uid = db_driver_faction_save(f->uid, f->no, 0, faction_getemail(f), @@ -59,6 +60,7 @@ static void test_update_faction(CuTest *tc) { faction_getemail(f), faction_getpassword(f)); CuAssertIntEquals(tc, f->uid, uid); + db_driver_close(DB_GAME); test_teardown(); } diff --git a/src/kernel/db/sqlite.c b/src/kernel/db/sqlite.c index 9a4dbc9ff..6aff52cf1 100644 --- a/src/kernel/db/sqlite.c +++ b/src/kernel/db/sqlite.c @@ -100,9 +100,7 @@ dbrow_id db_driver_faction_save(dbrow_id id, int no, int turn, const char *email sqlite3_int64 row_id; int err; - if (!g_game_db) { - return -1; - } + assert(g_game_db); if (id != 0) { int rows; @@ -192,7 +190,11 @@ static const char *g_swapname; int db_driver_open(database_t db, const char *dbname) { ERRNO_CHECK(); - + + if (!dbname) { + /* by default, use an in-memory database */ + dbname = ":memory:"; + } if (db == DB_SWAP) { g_swapname = dbname; return db_open_swap(dbname); From 516a53c0c7da706c604734f3a2d44e1333ecccd4 Mon Sep 17 00:00:00 2001 From: Enno Rehling Date: Wed, 24 Oct 2018 19:54:07 +0200 Subject: [PATCH 096/160] swap faction.banner to database --- src/creport.c | 15 ++++++++++----- src/kernel/faction.c | 14 +++++++------- src/kernel/faction.h | 2 +- src/kernel/faction.test.c | 15 ++++++++++++++- src/kernel/save.c | 4 ++-- src/laws.c | 6 ++---- src/report.c | 4 +++- 7 files changed, 39 insertions(+), 21 deletions(-) diff --git a/src/creport.c b/src/creport.c index 475a04b1e..0173b7409 100644 --- a/src/creport.c +++ b/src/creport.c @@ -1057,12 +1057,15 @@ static void cr_find_address(FILE * F, const faction * uf, selist * addresses) while (flist) { const faction *f = (const faction *)selist_get(flist, i); if (uf != f) { + const char *str; fprintf(F, "PARTEI %d\n", f->no); fprintf(F, "\"%s\";Parteiname\n", f->name); if (strcmp(faction_getemail(f), "") != 0) fprintf(F, "\"%s\";email\n", faction_getemail(f)); - if (f->banner) - fprintf(F, "\"%s\";banner\n", f->banner); + str = faction_getbanner(f); + if (str) { + fprintf(F, "\"%s\";banner\n", str); + } fprintf(F, "\"%s\";locale\n", locale_name(f->locale)); if (f->alliance && f->alliance == uf->alliance) { fprintf(F, "%d;alliance\n", f->alliance->id); @@ -1534,7 +1537,7 @@ report_computer(const char *filename, report_context * ctx, const char *bom) static int era = -1; int i; faction *f = ctx->f; - const char *prefix; + const char *prefix, *str; region *r; const char *mailto = config_get("game.email"); const attrib *a; @@ -1628,8 +1631,10 @@ report_computer(const char *filename, report_context * ctx, const char *bom) fprintf(F, "\"%s\";Parteiname\n", f->name); fprintf(F, "\"%s\";email\n", faction_getemail(f)); - if (f->banner) - fprintf(F, "\"%s\";banner\n", f->banner); + str = faction_getbanner(f); + if (str) { + fprintf(F, "\"%s\";banner\n", str); + } print_items(F, f->items, f->locale); fputs("OPTIONEN\n", F); for (i = 0; i != MAXOPTIONS; ++i) { diff --git a/src/kernel/faction.c b/src/kernel/faction.c index a3cd96bc9..bb5a27271 100755 --- a/src/kernel/faction.c +++ b/src/kernel/faction.c @@ -106,7 +106,6 @@ static void free_faction(faction * f) freelist(f->allies); free(f->email); - free(f->banner); free(f->name); if (f->seen_factions) { selist_free(f->seen_factions); @@ -593,16 +592,17 @@ void faction_setemail(faction * self, const char *email) self->email = NULL; } -const char *faction_getbanner(const faction * self) +const char *faction_getbanner(const faction * f) { - return self->banner ? self->banner : ""; + if (f->banner_id > 0) { + return dbstring_load(f->banner_id, NULL); + } + return NULL; } -void faction_setbanner(faction * self, const char *banner) +void faction_setbanner(faction * f, const char *banner) { - free(self->banner); - if (banner) - self->banner = str_strdup(banner); + f->banner_id = dbstring_save(banner); } const char *faction_getpassword(const faction *f) { diff --git a/src/kernel/faction.h b/src/kernel/faction.h index 8548328ef..c10e6ec69 100644 --- a/src/kernel/faction.h +++ b/src/kernel/faction.h @@ -71,7 +71,7 @@ extern "C" { int uid; int flags; char *name; - char *banner; + dbrow_id banner_id; char *email; dbrow_id password_id; int max_spelllevel; diff --git a/src/kernel/faction.test.c b/src/kernel/faction.test.c index 6c2ed3aa6..9aac0465c 100644 --- a/src/kernel/faction.test.c +++ b/src/kernel/faction.test.c @@ -117,7 +117,7 @@ static void test_addfaction(CuTest *tc) { CuAssertPtrNotNull(tc, f->name); CuAssertPtrEquals(tc, NULL, (void *)f->units); CuAssertPtrEquals(tc, NULL, (void *)f->next); - CuAssertPtrEquals(tc, NULL, (void *)f->banner); + CuAssertPtrEquals(tc, NULL, (void *)faction_getbanner(f)); CuAssertPtrEquals(tc, NULL, (void *)f->spellbook); CuAssertPtrEquals(tc, NULL, (void *)f->origin); CuAssertPtrEquals(tc, (void *)factions, (void *)f); @@ -229,6 +229,18 @@ static void test_valid_race(CuTest *tc) { test_teardown(); } +static void test_dbstrings(CuTest *tc) { + const char *lipsum = "Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua."; + faction *f; + test_setup(); + f = test_create_faction(NULL); + faction_setbanner(f, lipsum); + faction_setpassword(f, lipsum + 12); + CuAssertStrEquals(tc, lipsum, faction_getbanner(f)); + CuAssertStrEquals(tc, lipsum + 12, faction_getpassword(f)); + test_teardown(); +} + static void test_set_email(CuTest *tc) { faction *f; char email[10]; @@ -335,6 +347,7 @@ CuSuite *get_faction_suite(void) SUITE_ADD_TEST(suite, test_check_passwd); SUITE_ADD_TEST(suite, test_valid_race); SUITE_ADD_TEST(suite, test_set_email); + SUITE_ADD_TEST(suite, test_dbstrings); SUITE_ADD_TEST(suite, test_save_special_items); return suite; } diff --git a/src/kernel/save.c b/src/kernel/save.c index 63e14b3c3..f1b614709 100644 --- a/src/kernel/save.c +++ b/src/kernel/save.c @@ -1007,7 +1007,7 @@ faction *read_faction(gamedata * data) if (unicode_utf8_trim(name)!=0) { log_warning("trim faction %s banner to '%s'", itoa36(f->no), name); }; - f->banner = str_strdup(name); + faction_setbanner(f, name); log_debug(" - Lese Partei %s (%s)", f->name, itoa36(f->no)); @@ -1115,7 +1115,7 @@ void write_faction(gamedata *data, const faction * f) WRITE_INT(data->store, f->alliance_joindate); WRITE_STR(data->store, f->name); - WRITE_STR(data->store, f->banner); + WRITE_STR(data->store, faction_getbanner(f)); WRITE_STR(data->store, f->email?f->email:""); write_password(data, f); WRITE_TOK(data->store, locale_name(f->locale)); diff --git a/src/laws.c b/src/laws.c index 4c2a29e4e..4212f9d63 100644 --- a/src/laws.c +++ b/src/laws.c @@ -2086,12 +2086,10 @@ int banner_cmd(unit * u, struct order *ord) { const char * s; - free(u->faction->banner); init_order_depr(ord); s = getstrtoken(); - u->faction->banner = s ? str_strdup(s) : 0; - add_message(&u->faction->msgs, msg_message("changebanner", "value", - u->faction->banner)); + faction_setbanner(u->faction, s); + add_message(&u->faction->msgs, msg_message("changebanner", "value", s)); return 0; } diff --git a/src/report.c b/src/report.c index 5d2ed4598..f744086c3 100644 --- a/src/report.c +++ b/src/report.c @@ -1726,11 +1726,13 @@ static void list_address(struct stream *out, const faction * uf, selist * seenfa while (flist != NULL) { const faction *f = (const faction *)selist_get(flist, qi); if (!is_monsters(f)) { + const char *str; char buf[8192]; char label = '-'; + str = faction_getbanner(f); sprintf(buf, "%s: %s; %s", factionname(f), faction_getemail(f), - f->banner ? f->banner : ""); + str ? str : ""); if (uf == f) label = '*'; else if (is_allied(uf, f)) From 53e123b36aed63f4d6d8454b3a6bfe9cd98a0edf Mon Sep 17 00:00:00 2001 From: Enno Rehling Date: Wed, 24 Oct 2018 20:16:17 +0200 Subject: [PATCH 097/160] do not use unit.display directly, use getter/setter instead. --- src/kernel/save.c | 8 +++++--- src/kernel/unit.c | 14 +++++++------- src/kernel/unit.h | 2 +- src/kernel/unit.test.c | 9 ++++----- src/laws.c | 2 +- src/laws.test.c | 4 ++-- src/spells/combatspells.c | 7 +------ 7 files changed, 21 insertions(+), 25 deletions(-) diff --git a/src/kernel/save.c b/src/kernel/save.c index f1b614709..b9f501a4e 100644 --- a/src/kernel/save.c +++ b/src/kernel/save.c @@ -440,12 +440,12 @@ unit *read_unit(gamedata *data) if (unicode_utf8_trim(obuf)!=0) { log_warning("trim unit %s name to '%s'", itoa36(u->no), obuf); } - u->_name = obuf[0] ? str_strdup(obuf) : 0; + unit_setname(u, obuf[0] ? obuf : NULL); READ_STR(data->store, obuf, sizeof(obuf)); if (unicode_utf8_trim(obuf)!=0) { log_warning("trim unit %s info to '%s'", itoa36(u->no), obuf); } - u->display = obuf[0] ? str_strdup(obuf) : 0; + unit_setinfo(u, obuf[0] ? obuf : NULL); READ_INT(data->store, &number); set_number(u, number); @@ -544,6 +544,7 @@ unit *read_unit(gamedata *data) void write_unit(gamedata *data, const unit * u) { + const char *str; order *ord; int p = 0; unsigned int flags = u->flags & UFL_SAVEMASK; @@ -553,7 +554,8 @@ void write_unit(gamedata *data, const unit * u) assert(u->faction->_alive); write_faction_reference(u->faction, data->store); WRITE_STR(data->store, u->_name); - WRITE_STR(data->store, u->display ? u->display : ""); + str = unit_getinfo(u); + WRITE_STR(data->store, str ? str : ""); WRITE_INT(data->store, u->number); WRITE_INT(data->store, u->age); WRITE_TOK(data->store, u_race(u)->_name); diff --git a/src/kernel/unit.c b/src/kernel/unit.c index 9b6c3e9ee..d90c638a0 100644 --- a/src/kernel/unit.c +++ b/src/kernel/unit.c @@ -474,8 +474,8 @@ attrib_type at_private = { const char *u_description(const unit * u, const struct locale *lang) { - if (u->display && u->display[0]) { - return u->display; + if (u->_display && u->_display[0]) { + return u->_display; } else { char zText[64]; @@ -1293,7 +1293,7 @@ void free_unit(unit * u) { assert(!u->region); free(u->_name); - free(u->display); + free(u->_display); free_order(u->thisorder); free_orders(&u->orders); if (u->skills) @@ -1522,16 +1522,16 @@ void unit_setname(unit * u, const char *name) const char *unit_getinfo(const unit * u) { - return (const char *)u->display; + return (const char *)u->_display; } void unit_setinfo(unit * u, const char *info) { - free(u->display); + free(u->_display); if (info) - u->display = str_strdup(info); + u->_display = str_strdup(info); else - u->display = NULL; + u->_display = NULL; } int unit_getid(const unit * u) diff --git a/src/kernel/unit.h b/src/kernel/unit.h index 3f82ef80a..582b99db3 100644 --- a/src/kernel/unit.h +++ b/src/kernel/unit.h @@ -89,7 +89,7 @@ extern "C" { int no; /* id */ int hp; char *_name; - char *display; + char *_display; struct faction *faction; struct building *building; struct ship *ship; diff --git a/src/kernel/unit.test.c b/src/kernel/unit.test.c index 085e0177a..0918e83aa 100644 --- a/src/kernel/unit.test.c +++ b/src/kernel/unit.test.c @@ -397,14 +397,13 @@ static void test_unit_description(CuTest *tc) { rc = test_create_race("hodor"); u = test_create_unit(test_create_faction(rc), test_create_region(0, 0, NULL)); - CuAssertPtrEquals(tc, NULL, u->display); - CuAssertStrEquals(tc, 0, u_description(u, lang)); - u->display = str_strdup("Hodor"); + CuAssertStrEquals(tc, NULL, unit_getinfo(u)); + CuAssertStrEquals(tc, NULL, u_description(u, lang)); + unit_setinfo(u, "Hodor"); CuAssertStrEquals(tc, "Hodor", u_description(u, NULL)); CuAssertStrEquals(tc, "Hodor", u_description(u, lang)); - free(u->display); - u->display = NULL; + unit_setinfo(u, NULL); locale_setstring(lang, "describe_hodor", "HODOR"); CuAssertStrEquals(tc, "HODOR", u_description(u, lang)); diff --git a/src/laws.c b/src/laws.c index 4212f9d63..6cbe7e726 100644 --- a/src/laws.c +++ b/src/laws.c @@ -1542,7 +1542,7 @@ int display_cmd(unit * u, struct order *ord) break; case P_UNIT: - s = &u->display; + unit_setinfo(u, getstrtoken()); break; case P_PRIVAT: diff --git a/src/laws.test.c b/src/laws.test.c index fb8929996..524c750d4 100644 --- a/src/laws.test.c +++ b/src/laws.test.c @@ -188,12 +188,12 @@ static void test_display_cmd(CuTest *tc) { ord = create_order(K_DISPLAY, f->locale, "%s Hodor", LOC(f->locale, parameters[P_UNIT])); CuAssertIntEquals(tc, 0, display_cmd(u, ord)); - CuAssertStrEquals(tc, "Hodor", u->display); + CuAssertStrEquals(tc, "Hodor", unit_getinfo(u)); free_order(ord); ord = create_order(K_DISPLAY, f->locale, LOC(f->locale, parameters[P_UNIT])); CuAssertIntEquals(tc, 0, display_cmd(u, ord)); - CuAssertPtrEquals(tc, NULL, u->display); + CuAssertPtrEquals(tc, NULL, (void *)unit_getinfo(u)); free_order(ord); ord = create_order(K_DISPLAY, f->locale, "%s Hodor", LOC(f->locale, parameters[P_REGION])); diff --git a/src/spells/combatspells.c b/src/spells/combatspells.c index c088dde07..21b33e7bf 100644 --- a/src/spells/combatspells.c +++ b/src/spells/combatspells.c @@ -1539,12 +1539,7 @@ int sp_undeadhero(struct castorder * co) /* new units gets some stats from old unit */ - if (du->display) { - unit_setinfo(u, du->display); - } - else { - unit_setinfo(u, NULL); - } + unit_setinfo(u, unit_getinfo(du)); unit_setstatus(u, du->status); setguard(u, false); for (ilist = &du->items; *ilist;) { From be0c0161da724ed09e467b1892d690da8f19e354 Mon Sep 17 00:00:00 2001 From: Enno Rehling Date: Wed, 24 Oct 2018 20:21:21 +0200 Subject: [PATCH 098/160] use swap database for unit descriptions. --- src/kernel/unit.c | 21 ++++++++++++--------- src/kernel/unit.h | 3 ++- 2 files changed, 14 insertions(+), 10 deletions(-) diff --git a/src/kernel/unit.c b/src/kernel/unit.c index d90c638a0..b5346e04d 100644 --- a/src/kernel/unit.c +++ b/src/kernel/unit.c @@ -474,8 +474,8 @@ attrib_type at_private = { const char *u_description(const unit * u, const struct locale *lang) { - if (u->_display && u->_display[0]) { - return u->_display; + if (u->display_id > 0) { + return unit_getinfo(u); } else { char zText[64]; @@ -1293,7 +1293,6 @@ void free_unit(unit * u) { assert(!u->region); free(u->_name); - free(u->_display); free_order(u->thisorder); free_orders(&u->orders); if (u->skills) @@ -1522,16 +1521,20 @@ void unit_setname(unit * u, const char *name) const char *unit_getinfo(const unit * u) { - return (const char *)u->_display; + if (u->display_id > 0) { + return dbstring_load(u->display_id, NULL); + } + return NULL; } void unit_setinfo(unit * u, const char *info) { - free(u->_display); - if (info) - u->_display = str_strdup(info); - else - u->_display = NULL; + if (info) { + u->display_id = dbstring_save(info); + } + else { + u->display_id = 0; + } } int unit_getid(const unit * u) diff --git a/src/kernel/unit.h b/src/kernel/unit.h index 582b99db3..a0f2f5a4c 100644 --- a/src/kernel/unit.h +++ b/src/kernel/unit.h @@ -21,6 +21,7 @@ OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. #include #include "types.h" +#include "database.h" #include "skills.h" #include @@ -89,7 +90,7 @@ extern "C" { int no; /* id */ int hp; char *_name; - char *_display; + dbrow_id display_id; struct faction *faction; struct building *building; struct ship *ship; From 0ac3dc5ead8704344a3b07b65e21c5f1edea87d3 Mon Sep 17 00:00:00 2001 From: Enno Rehling Date: Fri, 26 Oct 2018 10:54:09 +0200 Subject: [PATCH 099/160] WIP: refactor allies api --- src/creport.c | 37 +++++++++++++++++++-------- src/kernel/ally.c | 17 ++++++++++++- src/kernel/ally.h | 19 +++++++------- src/laws.c | 65 +++++++++++++++++++---------------------------- 4 files changed, 77 insertions(+), 61 deletions(-) diff --git a/src/creport.c b/src/creport.c index 475a04b1e..07d957258 100644 --- a/src/creport.c +++ b/src/creport.c @@ -1018,20 +1018,35 @@ static void cr_output_unit_compat(FILE * F, const faction * f, cr_output_unit(&strm, f, u, mode); } -/* = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = */ +static void print_ally(const faction *f, faction *af, int status, + struct ally *sf, FILE *F) { + if (af) { + int mode = alliedgroup(NULL, f, af, sf, HELP_ALL); + if (mode != 0 && status > 0) { + fprintf(F, "ALLIANZ %d\n", af->no); + fprintf(F, "\"%s\";Parteiname\n", af->name); + fprintf(F, "%d;Status\n", status & HELP_ALL); + } + } +} + +struct print_ally_s { + const faction *f; + FILE *F; +}; + +static void print_ally_cb(struct ally *sf, faction *af, int status, void *udata) { + struct print_ally_s *data = (struct print_ally_s *)udata; + print_ally(data->f, af, status, sf, data->F); +} /* prints allies */ -static void show_allies_cr(FILE * F, const faction * f, const ally * sf) +static void show_allies_cr(FILE * F, const faction * f, struct ally * sf) { - for (; sf; sf = sf->next) - if (sf->faction) { - int mode = alliedgroup(NULL, f, sf->faction, sf, HELP_ALL); - if (mode != 0 && sf->status > 0) { - fprintf(F, "ALLIANZ %d\n", sf->faction->no); - fprintf(F, "\"%s\";Parteiname\n", sf->faction->name); - fprintf(F, "%d;Status\n", sf->status & HELP_ALL); - } - } + struct print_ally_s data; + data.F = F; + data.f = f; + allies_walk(sf, print_ally_cb, &data); } /* prints allies */ diff --git a/src/kernel/ally.c b/src/kernel/ally.c index 0660f148a..3abfc4c09 100644 --- a/src/kernel/ally.c +++ b/src/kernel/ally.c @@ -20,6 +20,20 @@ #include #include +typedef struct ally { + struct ally *next; + struct faction *faction; + int status; +} ally; + +void allies_walk(struct ally *allies, cb_allies_walk callback, void *udata); +{ + ally *al; + for (al = allies; al; al = al->next) { + callback(allies, al->faction, al->status, udata); + } +} + void read_allies(gamedata * data, faction *f) { ally **sfp = &f->allies; @@ -196,7 +210,8 @@ static int AllianceRestricted(void) int alliedgroup(const struct plane *pl, const struct faction *f, - const struct faction *f2, const struct ally *sf, int mode) + const struct faction *f2, + const struct ally *sf, int mode) { if (!(faction_alive(f) && faction_alive(f2))) { return 0; diff --git a/src/kernel/ally.h b/src/kernel/ally.h index d4c41d36c..16bd57aa7 100644 --- a/src/kernel/ally.h +++ b/src/kernel/ally.h @@ -28,19 +28,18 @@ extern "C" { struct faction; struct gamedata; struct unit; + struct ally; extern struct attrib_type at_npcfaction; - typedef struct ally { - struct ally *next; - struct faction *faction; - int status; - } ally; - void read_allies(struct gamedata * data, struct faction *f); - ally * ally_find(ally *al, const struct faction *f); - ally * ally_add(ally **al_p, struct faction *f); - void ally_remove(ally **al_p, struct faction *f); + typedef void (*cb_allies_walk)(struct ally *, struct faction *, int, void *); + void allies_walk(struct ally *allies, cb_allies_walk callback, void *udata); + struct ally* ally_find(struct ally*al, const struct faction *f); + void ally_set(struct ally**al_p, struct faction *f, int status); + int ally_get(struct ally *al, struct faction *f); + struct ally* ally_add(struct ally**al_p, struct faction *f); + void ally_remove(struct ally**al_p, struct faction *f); int AllianceAuto(void); /* flags that allied factions get automatically */ int HelpMask(void); /* flags restricted to allied factions */ @@ -49,7 +48,7 @@ extern "C" { int alliedfaction(const struct plane *pl, const struct faction *f, const struct faction *f2, int mode); int alliedgroup(const struct plane *pl, const struct faction *f, - const struct faction *f2, const struct ally *sf, int mode); + const struct faction *f2, const struct ally*sf, int mode); #ifdef __cplusplus } diff --git a/src/laws.c b/src/laws.c index 4c2a29e4e..035ed7088 100644 --- a/src/laws.c +++ b/src/laws.c @@ -1292,11 +1292,12 @@ void quit(void) int ally_cmd(unit * u, struct order *ord) { char token[128]; - ally *sf, **sfp; + struct ally **sfp; faction *f; int keyword, not_kw; const char *s; - + int sf_status; + init_order_depr(ord); f = getfaction(); @@ -1319,28 +1320,17 @@ int ally_cmd(unit * u, struct order *ord) sfp = &u->faction->allies; if (fval(u, UFL_GROUP)) { attrib *a = a_find(u->attribs, &at_group); - if (a) + if (a) { sfp = &((group *)a->data.v)->allies; + } } - for (sf = *sfp; sf; sf = sf->next) - if (sf->faction == f) - break; /* Gleich die passende raussuchen, wenn vorhanden */ not_kw = getparam(u->faction->locale); /* HELFE partei [modus] NICHT */ - if (!sf) { - if (keyword == P_NOT || not_kw == P_NOT) { - /* Wir helfen der Partei gar nicht... */ - return 0; - } - else { - sf = ally_add(sfp, f); - sf->status = 0; - } - } + sf_status = ally_get(*sfp, f); switch (keyword) { case P_NOT: - sf->status = 0; + sf_status = 0; break; case NOPARAM: @@ -1348,60 +1338,57 @@ int ally_cmd(unit * u, struct order *ord) return 0; case P_ANY: - if (not_kw == P_NOT) - sf->status = 0; - else - sf->status = HELP_ALL; + sf_status = (not_kw == P_NOT) ? 0 : HELP_ALL; break; case P_TRAVEL: - if (not_kw == P_NOT) - sf->status = sf->status & (HELP_ALL - HELP_TRAVEL); - else - sf->status = sf->status | HELP_TRAVEL; + if (not_kw == P_NOT) { + sf_status = sf_status & (HELP_ALL - HELP_TRAVEL); + } + else { + sf_status |= HELP_TRAVEL; + } break; case P_GIVE: if (not_kw == P_NOT) - sf->status = sf->status & (HELP_ALL - HELP_GIVE); + sf_status &= (HELP_ALL - HELP_GIVE); else - sf->status = sf->status | HELP_GIVE; + sf_status |= HELP_GIVE; break; case P_MONEY: if (not_kw == P_NOT) - sf->status = sf->status & (HELP_ALL - HELP_MONEY); + sf_status &= (HELP_ALL - HELP_MONEY); else - sf->status = sf->status | HELP_MONEY; + sf_status |= HELP_MONEY; break; case P_FIGHT: if (not_kw == P_NOT) - sf->status = sf->status & (HELP_ALL - HELP_FIGHT); + sf_status &= (HELP_ALL - HELP_FIGHT); else - sf->status = sf->status | HELP_FIGHT; + sf_status |= HELP_FIGHT; break; case P_FACTIONSTEALTH: if (not_kw == P_NOT) - sf->status = sf->status & (HELP_ALL - HELP_FSTEALTH); + sf_status &= (HELP_ALL - HELP_FSTEALTH); else - sf->status = sf->status | HELP_FSTEALTH; + sf_status |= HELP_FSTEALTH; break; case P_GUARD: if (not_kw == P_NOT) - sf->status = sf->status & (HELP_ALL - HELP_GUARD); + sf_status &= (HELP_ALL - HELP_GUARD); else - sf->status = sf->status | HELP_GUARD; + sf_status |= HELP_GUARD; break; } - sf->status &= HelpMask(); + sf_status &= HelpMask(); + ally_set(sfp, f, sf_status); - if (sf->status == 0) { /* Alle HELPs geloescht */ - removelist(sfp, sf); - } return 0; } From 600762809607a9ada74f5916330e7ca4c2744347 Mon Sep 17 00:00:00 2001 From: Enno Rehling Date: Fri, 26 Oct 2018 14:00:48 +0200 Subject: [PATCH 100/160] report.c is next --- src/report.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/report.c b/src/report.c index 5d2ed4598..e27044127 100644 --- a/src/report.c +++ b/src/report.c @@ -1511,7 +1511,7 @@ report_template(const char *filename, report_context * ctx, const char *bom) } static void -show_allies(const faction * f, const ally * allies, char *buf, size_t size) +show_allies(const faction * f, struct ally * allies, char *buf, size_t size) { int allierte = 0; int i = 0, h, hh = 0; From c3d9e9dbaffc1733022111a99fef6fc89020add9 Mon Sep 17 00:00:00 2001 From: Enno Rehling Date: Fri, 26 Oct 2018 14:13:00 +0200 Subject: [PATCH 101/160] report allies without bsdstring --- src/report.c | 133 +++++++++++++++++++++++---------------------------- 1 file changed, 59 insertions(+), 74 deletions(-) diff --git a/src/report.c b/src/report.c index 5d2ed4598..abad4c4fb 100644 --- a/src/report.c +++ b/src/report.c @@ -1514,93 +1514,78 @@ static void show_allies(const faction * f, const ally * allies, char *buf, size_t size) { int allierte = 0; - int i = 0, h, hh = 0; - int bytes, dh = 0; + int i = 0, h, hh = 0, dh = 0; const ally *sf; - char *bufp = buf; /* buf already contains data */ - - --size; /* leave room for a null-terminator */ - + for (sf = allies; sf; sf = sf->next) { int mode = alliedgroup(NULL, f, sf->faction, sf, HELP_ALL); - if (mode > 0) + if (mode > 0) { ++allierte; + } } - for (sf = allies; sf; sf = sf->next) { - int mode = alliedgroup(NULL, f, sf->faction, sf, HELP_ALL); - if (mode <= 0) - continue; - i++; - if (dh) { - if (i == allierte) { - bytes = (int)str_strlcpy(bufp, LOC(f->locale, "list_and"), size); + if (allierte > 0) { + sbstring sbs; + sbs_init(&sbs, buf, size); + + for (sf = allies; sf; sf = sf->next) { + int mode = alliedgroup(NULL, f, sf->faction, sf, HELP_ALL); + if (mode <= 0) + continue; + i++; + if (dh) { + if (i == allierte) { + sbs_strcat(&sbs, LOC(f->locale, "list_and")); + } + else { + sbs_strcat(&sbs, ", "); + } + } + dh = 1; + hh = 0; + sbs_strcat(&sbs, factionname(sf->faction)); + sbs_strcat(&sbs, " ("); + if ((mode & HELP_ALL) == HELP_ALL) { + sbs_strcat(&sbs, LOC(f->locale, parameters[P_ANY])); } else { - bytes = (int)str_strlcpy(bufp, ", ", size); - } - if (wrptr(&bufp, &size, bytes) != 0) - WARN_STATIC_BUFFER(); - } - dh = 1; - hh = 0; - bytes = (int)str_strlcpy(bufp, factionname(sf->faction), size); - if (wrptr(&bufp, &size, bytes) != 0) - WARN_STATIC_BUFFER(); - bytes = (int)str_strlcpy(bufp, " (", size); - if (wrptr(&bufp, &size, bytes) != 0) - WARN_STATIC_BUFFER(); - if ((mode & HELP_ALL) == HELP_ALL) { - bytes = (int)str_strlcpy(bufp, LOC(f->locale, parameters[P_ANY]), size); - if (wrptr(&bufp, &size, bytes) != 0) - WARN_STATIC_BUFFER(); - } - else { - for (h = 1; h <= HELP_TRAVEL; h *= 2) { - int p = MAXPARAMS; - if ((mode & h) == h) { - switch (h) { - case HELP_TRAVEL: - p = P_TRAVEL; - break; - case HELP_MONEY: - p = P_MONEY; - break; - case HELP_FIGHT: - p = P_FIGHT; - break; - case HELP_GIVE: - p = P_GIVE; - break; - case HELP_GUARD: - p = P_GUARD; - break; - case HELP_FSTEALTH: - p = P_FACTIONSTEALTH; - break; + for (h = 1; h <= HELP_TRAVEL; h *= 2) { + int p = MAXPARAMS; + if ((mode & h) == h) { + switch (h) { + case HELP_TRAVEL: + p = P_TRAVEL; + break; + case HELP_MONEY: + p = P_MONEY; + break; + case HELP_FIGHT: + p = P_FIGHT; + break; + case HELP_GIVE: + p = P_GIVE; + break; + case HELP_GUARD: + p = P_GUARD; + break; + case HELP_FSTEALTH: + p = P_FACTIONSTEALTH; + break; + } + } + if (p != MAXPARAMS) { + if (hh) { + sbs_strcat(&sbs, ", "); + } + sbs_strcat(&sbs, LOC(f->locale, parameters[p])); + hh = 1; } } - if (p != MAXPARAMS) { - if (hh) { - bytes = (int)str_strlcpy(bufp, ", ", size); - if (wrptr(&bufp, &size, bytes) != 0) - WARN_STATIC_BUFFER(); - } - bytes = (int)str_strlcpy(bufp, LOC(f->locale, parameters[p]), size); - if (wrptr(&bufp, &size, bytes) != 0) - WARN_STATIC_BUFFER(); - hh = 1; - } } + sbs_strcat(&sbs, ")"); } - bytes = (int)str_strlcpy(bufp, ")", size); - if (wrptr(&bufp, &size, bytes) != 0) - WARN_STATIC_BUFFER(); + sbs_strcat(&sbs, "."); } - bytes = (int)str_strlcpy(bufp, ".", size); - if (wrptr(&bufp, &size, bytes) != 0) - WARN_STATIC_BUFFER(); - *bufp = 0; } static void allies(struct stream *out, const faction * f) From 557c624200891ed63ace706118b8398211162a72 Mon Sep 17 00:00:00 2001 From: Enno Rehling Date: Fri, 26 Oct 2018 16:08:46 +0200 Subject: [PATCH 102/160] contant name conflict resolved --- src/kernel/race.c | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/src/kernel/race.c b/src/kernel/race.c index 31d437992..8a8311991 100644 --- a/src/kernel/race.c +++ b/src/kernel/race.c @@ -79,10 +79,10 @@ const char *racenames[MAXRACES] = { "clone" }; -#define MAXOPTIONS 4 +#define MAX_OPTIONS 4 typedef struct rcoption { - unsigned char key[MAXOPTIONS]; - variant value[MAXOPTIONS]; + unsigned char key[MAX_OPTIONS]; + variant value[MAX_OPTIONS]; } rcoption; enum { @@ -106,7 +106,7 @@ static void rc_setoption(race *rc, int k, const char *value) { v = rc->options->value; } else { int i; - for (i=0;!v && i < MAXOPTIONS;++i) { + for (i=0;!v && i < MAX_OPTIONS;++i) { if (rc->options->key[i]==key) { v = rc->options->value+i; break; @@ -114,7 +114,7 @@ static void rc_setoption(race *rc, int k, const char *value) { if (rc->options->key[i]==RCO_NONE) { v = rc->options->value+i; rc->options->key[i] = key; - if (i+1 < MAXOPTIONS) { + if (i+1 < MAX_OPTIONS) { rc->options->key[i+1]=RCO_NONE; } break; @@ -145,7 +145,7 @@ static void rc_setoption(race *rc, int k, const char *value) { static variant *rc_getoption(const race *rc, int key) { if (rc->options) { int i; - for (i=0;i!=MAXOPTIONS && rc->options->key[i]!=RCO_NONE;++i) { + for (i=0;i!=MAX_OPTIONS && rc->options->key[i]!=RCO_NONE;++i) { if (rc->options->key[i]==key) { return rc->options->value+i; } @@ -269,7 +269,7 @@ void free_races(void) { rcoption * opt = races->options; if (opt) { - for (i=0;i!=MAXOPTIONS && opt->key[i]!=RCO_NONE;++i) { + for (i=0;i!=MAX_OPTIONS && opt->key[i]!=RCO_NONE;++i) { if (opt->key[i]==RCO_HUNGER) { free(opt->value[i].v); } From ac3a4d91c9b9430efcfa2380aa43bec249c7cb61 Mon Sep 17 00:00:00 2001 From: Enno Rehling Date: Fri, 26 Oct 2018 19:47:50 +0200 Subject: [PATCH 103/160] simplicate the use of ally.c --- src/battle.c | 46 ++++++++------------ src/creport.c | 13 +++--- src/creport.test.c | 4 +- src/give.test.c | 3 +- src/kernel/ally.c | 92 +++++++++++++++++++++------------------ src/kernel/ally.h | 16 ++++--- src/kernel/ally.test.c | 25 +++-------- src/kernel/faction.c | 19 ++------ src/kernel/faction.h | 2 + src/kernel/faction.test.c | 8 ++-- src/kernel/group.c | 22 ++-------- src/kernel/group.test.c | 9 ++-- src/kernel/plane.h | 10 ++--- src/kernel/pool.test.c | 10 ++--- src/kernel/save.c | 16 +++---- src/kernel/save.test.c | 5 +-- src/laws.c | 8 ++-- src/laws.test.c | 12 +++-- src/move.test.c | 4 +- src/report.c | 9 ++-- src/reports.c | 2 +- src/reports.test.c | 4 +- src/study.test.c | 4 +- 23 files changed, 140 insertions(+), 203 deletions(-) diff --git a/src/battle.c b/src/battle.c index 8b71f17e1..8ed79a732 100644 --- a/src/battle.c +++ b/src/battle.c @@ -281,19 +281,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) @@ -313,7 +309,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; } } @@ -344,7 +340,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 (bool)(!enemy(as, ds) && alliedside(as, ds->faction, HELP_FIGHT)); } int statusrow(int status) @@ -832,7 +828,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; } @@ -1654,7 +1650,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; } } @@ -3636,7 +3632,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; } } @@ -3690,17 +3686,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); + } + } + } } } } diff --git a/src/creport.c b/src/creport.c index 0173b7409..7da7b0810 100644 --- a/src/creport.c +++ b/src/creport.c @@ -1021,15 +1021,16 @@ static void cr_output_unit_compat(FILE * F, const faction * f, /* = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = */ /* prints allies */ -static void show_allies_cr(FILE * F, const faction * f, const ally * sf) +static void show_allies_cr(FILE * F, const faction * f, const group *g) { + ally * sf = g ? g->allies : f->allies; for (; sf; sf = sf->next) - if (sf->faction) { - int mode = alliedgroup(NULL, f, sf->faction, sf, HELP_ALL); + if (sf->faction && faction_alive(sf->faction)) { + int mode = alliedgroup(f, sf->faction, g, HELP_ALL); if (mode != 0 && sf->status > 0) { fprintf(F, "ALLIANZ %d\n", sf->faction->no); fprintf(F, "\"%s\";Parteiname\n", sf->faction->name); - fprintf(F, "%d;Status\n", sf->status & HELP_ALL); + fprintf(F, "%d;Status\n", sf->status); } } } @@ -1646,7 +1647,7 @@ report_computer(const char *filename, report_context * ctx, const char *bom) f->options &= (~flag); } } - show_allies_cr(F, f, f->allies); + show_allies_cr(F, f, NULL); { group *g; for (g = f->groups; g; g = g->next) { @@ -1659,7 +1660,7 @@ report_computer(const char *filename, report_context * ctx, const char *bom) fprintf(F, "\"%s\";typprefix\n", translate(prefix, LOC(f->locale, prefix))); } - show_allies_cr(F, f, g->allies); + show_allies_cr(F, f, g); } } diff --git a/src/creport.test.c b/src/creport.test.c index 6bd5bfba8..b536a7114 100644 --- a/src/creport.test.c +++ b/src/creport.test.c @@ -227,7 +227,6 @@ static void test_cr_factionstealth(CuTest *tc) { faction *f1, *f2; region *r; unit *u; - ally *al; test_setup(); f1 = test_create_faction(NULL); @@ -298,8 +297,7 @@ static void test_cr_factionstealth(CuTest *tc) { mstream_done(&strm); /* we see the same thing as them when we are an ally */ - al = ally_add(&f1->allies, f2); - al->status = HELP_FSTEALTH; + ally_set(&f1->allies, f2, HELP_FSTEALTH); mstream_init(&strm); cr_output_unit(&strm, f2, u, seen_unit); CuAssertIntEquals(tc, f1->no, cr_get_int(&strm, ";Partei", -1)); diff --git a/src/give.test.c b/src/give.test.c index 806901c46..2828456ae 100644 --- a/src/give.test.c +++ b/src/give.test.c @@ -44,8 +44,7 @@ static void setup_give(struct give *env) { env->itype = it_get_or_create(rt_get_or_create("money")); env->itype->flags |= ITF_HERB; if (env->f2) { - ally * al = ally_add(&env->f2->allies, env->f1); - al->status = HELP_GIVE; + ally_set(&env->f2->allies, env->f1, HELP_GIVE); env->dst = test_create_unit(env->f2, env->r); } else { diff --git a/src/kernel/ally.c b/src/kernel/ally.c index 0660f148a..3c5c5d851 100644 --- a/src/kernel/ally.c +++ b/src/kernel/ally.c @@ -8,7 +8,6 @@ #include "group.h" #include "faction.h" #include "objtypes.h" -#include "plane.h" #include #include @@ -20,9 +19,8 @@ #include #include -void read_allies(gamedata * data, faction *f) +void read_allies(gamedata * data, ally **sfp) { - ally **sfp = &f->allies; for (;;) { int aid; READ_INT(data->store, &aid); @@ -62,19 +60,6 @@ ally * ally_add(ally **al_p, struct faction *f) { return al; } -void ally_remove(ally **al_p, struct faction *f) { - ally * al; - while (*al_p) { - al = *al_p; - if (al->faction == f) { - *al_p = al->next; - free(al); - break; - } - al_p = &al->next; - } -} - static int ally_flag(const char *s, int help_mask) { if ((help_mask & HELP_MONEY) && strcmp(s, "money") == 0) @@ -114,11 +99,8 @@ int AllianceAuto(void) } static int -autoalliance(const plane * pl, const faction * sf, const faction * f2) +autoalliance(const faction * sf, const faction * f2) { - if (pl && (pl->flags & PFL_FRIENDLY)) - return HELP_ALL; - if (f_get_alliance(sf) != NULL && AllianceAuto()) { if (sf->alliance == f2->alliance) return AllianceAuto(); @@ -195,9 +177,11 @@ static int AllianceRestricted(void) } int -alliedgroup(const struct plane *pl, const struct faction *f, - const struct faction *f2, const struct ally *sf, int mode) +alliedgroup(const struct faction *f, + const struct faction *f2, const struct group *g, int mode) { + ally *sf = g ? g->allies : f->allies; + if (!(faction_alive(f) && faction_alive(f2))) { return 0; } @@ -205,9 +189,9 @@ alliedgroup(const struct plane *pl, const struct faction *f, sf = sf->next; } if (sf == NULL) { - mode = mode & autoalliance(pl, f, f2); + mode = mode & autoalliance(f, f2); } - mode = ally_mode(sf, mode) | (mode & autoalliance(pl, f, f2)); + mode = ally_mode(sf, mode) | (mode & autoalliance(f, f2)); if (AllianceRestricted()) { if (a_find(f->attribs, &at_npcfaction)) { return mode; @@ -223,26 +207,24 @@ alliedgroup(const struct plane *pl, const struct faction *f, } int -alliedfaction(const struct plane *pl, const struct faction *f, - const struct faction *f2, int mode) +alliedfaction(const struct faction *f, const struct faction *f2, int mode) { - return alliedgroup(pl, f, f2, f->allies, mode); + return alliedgroup(f, f2, NULL, mode); } /* Die Gruppe von Einheit u hat helfe zu f2 gesetzt. */ int alliedunit(const unit * u, const faction * f2, int mode) { - int automode; - assert(u); assert(f2); assert(u->region); /* the unit should be in a region, but it's possible that u->number==0 (TEMP units) */ - if (u->faction == f2) + if (u->faction == f2) { return mode; + } + if (!faction_alive(f2)) { + return 0; + } if (u->faction != NULL && f2 != NULL) { - ally *sf; - plane *pl; - if (mode & HELP_FIGHT) { if ((u->flags & UFL_DEFENDER) || (u->faction->flags & FFL_DEFENDER)) { faction *owner = region_get_owner(u->region); @@ -253,20 +235,44 @@ int alliedunit(const unit * u, const faction * f2, int mode) } } - pl = rplane(u->region); - automode = mode & autoalliance(pl, u->faction, f2); - - if (pl != NULL && (pl->flags & PFL_NOALLIANCES)) - mode = (mode & automode) | (mode & HELP_GIVE); - - sf = u->faction->allies; if (fval(u, UFL_GROUP)) { const attrib *a = a_find(u->attribs, &at_group); - if (a != NULL) - sf = ((group *)a->data.v)->allies; + if (a != NULL) { + group *g = (group *)a->data.v; + return alliedgroup(u->faction, f2, g, mode); + } } - return alliedgroup(pl, u->faction, f2, sf, mode); + return alliedfaction(u->faction, f2, mode); } return 0; } +void ally_set(ally **allies, struct faction *f, int status) { + ally *al; + while (*allies) { + al = *allies; + if (al->faction == f) { + if (status != 0) { + al->status = status; + } + else { + *allies = al->next; + free(al); + } + return; + } + allies = &al->next; + } + al = ally_add(allies, f); + al->status = status; +} + +int ally_get(ally *allies, const struct faction *f) { + ally *al; + for (al = allies; al; al = al->next) { + if (al->faction == f) { + return al->status; + } + } + return 0; +} diff --git a/src/kernel/ally.h b/src/kernel/ally.h index d4c41d36c..661edc5a5 100644 --- a/src/kernel/ally.h +++ b/src/kernel/ally.h @@ -24,8 +24,8 @@ extern "C" { #endif struct attrib_type; - struct plane; struct faction; + struct group; struct gamedata; struct unit; @@ -37,19 +37,21 @@ extern "C" { int status; } ally; - void read_allies(struct gamedata * data, struct faction *f); + int ally_get(struct ally *allies, const struct faction *f); + void ally_set(struct ally **allies, struct faction *f, int status); + + void read_allies(struct gamedata * data, struct ally **allies); ally * ally_find(ally *al, const struct faction *f); ally * ally_add(ally **al_p, struct faction *f); - void ally_remove(ally **al_p, struct faction *f); int AllianceAuto(void); /* flags that allied factions get automatically */ int HelpMask(void); /* flags restricted to allied factions */ int alliedunit(const struct unit *u, const struct faction *f2, int mode); - int alliedfaction(const struct plane *pl, const struct faction *f, - const struct faction *f2, int mode); - int alliedgroup(const struct plane *pl, const struct faction *f, - const struct faction *f2, const struct ally *sf, int mode); + int alliedfaction(const struct faction *f, const struct faction *f2, + int mode); + int alliedgroup(const struct faction *f, const struct faction *f2, + const struct group *g, int mode); #ifdef __cplusplus } diff --git a/src/kernel/ally.test.c b/src/kernel/ally.test.c index 99d220151..3197132a0 100644 --- a/src/kernel/ally.test.c +++ b/src/kernel/ally.test.c @@ -7,37 +7,22 @@ static void test_ally(CuTest * tc) { - ally * al = 0; + ally * al = NULL; struct faction * f1 = test_create_faction(NULL); - ally_add(&al, f1); + ally_set(&al, f1, HELP_GUARD); CuAssertPtrNotNull(tc, al); - CuAssertPtrEquals(tc, f1, ally_find(al, f1)->faction); + CuAssertIntEquals(tc, HELP_GUARD, ally_get(al, f1)); - ally_remove(&al, f1); + ally_set(&al, f1, 0); CuAssertPtrEquals(tc, NULL, al); - CuAssertPtrEquals(tc, NULL, ally_find(al, f1)); -} - -static void test_ally_null(CuTest * tc) -{ - ally *a1 = 0, *a2 = 0; - - a1 = ally_add(&a1, 0); - a2 = ally_add(&a1, 0); - CuAssertPtrNotNull(tc, a1); - CuAssertPtrNotNull(tc, a2); - CuAssertPtrEquals(tc, a2, a1->next); - CuAssertPtrEquals(tc, NULL, a2->next); - free(a1); - free(a2); + CuAssertIntEquals(tc, 0, ally_get(al, f1)); } CuSuite *get_ally_suite(void) { CuSuite *suite = CuSuiteNew(); SUITE_ADD_TEST(suite, test_ally); - SUITE_ADD_TEST(suite, test_ally_null); return suite; } diff --git a/src/kernel/faction.c b/src/kernel/faction.c index bb5a27271..d2871f84b 100755 --- a/src/kernel/faction.c +++ b/src/kernel/faction.c @@ -496,7 +496,7 @@ void destroyfaction(faction ** fp) handle_event(f->attribs, "destroy", f); if (f->alliance) { - setalliance(f, 0); + setalliance(f, NULL); } funhash(f); @@ -531,20 +531,9 @@ int get_alliance(const faction * a, const faction * b) void set_alliance(faction * a, faction * b, int status) { - ally **sfp; - sfp = &a->allies; - while (*sfp) { - ally *sf = *sfp; - if (sf->faction == b) - break; - sfp = &sf->next; - } - if (*sfp == NULL) { - ally *sf = ally_add(sfp, b); - sf->status = status; - return; - } - (*sfp)->status |= status; + /* TODO: optimization (use allies_walk?) */ + int original = ally_get(a->allies, b); + ally_set(&a->allies, b, status | original); } void renumber_faction(faction * f, int no) diff --git a/src/kernel/faction.h b/src/kernel/faction.h index c10e6ec69..87b13f2b9 100644 --- a/src/kernel/faction.h +++ b/src/kernel/faction.h @@ -111,6 +111,8 @@ extern "C" { void fhash(struct faction *f); void funhash(struct faction *f); + int faction_ally_status(const faction *f, const faction *f2); + struct faction *findfaction(int n); int max_magicians(const faction * f); void set_show_item(faction * f, const struct item_type *itype); diff --git a/src/kernel/faction.test.c b/src/kernel/faction.test.c index 9aac0465c..66e3c3945 100644 --- a/src/kernel/faction.test.c +++ b/src/kernel/faction.test.c @@ -29,20 +29,18 @@ static void test_destroyfaction_allies(CuTest *tc) { faction *f1, *f2; region *r; - ally *al; test_setup(); r = test_create_region(0, 0, NULL); f1 = test_create_faction(NULL); test_create_unit(f1, r); f2 = test_create_faction(NULL); - al = ally_add(&f1->allies, f2); - al->status = HELP_FIGHT; - CuAssertIntEquals(tc, HELP_FIGHT, alliedgroup(0, f1, f2, f1->allies, HELP_ALL)); + ally_set(&f1->allies, f2, HELP_FIGHT); + CuAssertIntEquals(tc, HELP_FIGHT, alliedfaction(f1, f2, HELP_ALL)); CuAssertPtrEquals(tc, f2, f1->next); destroyfaction(&f1->next); CuAssertIntEquals(tc, false, faction_alive(f2)); - CuAssertIntEquals(tc, 0, alliedgroup(0, f1, f2, f1->allies, HELP_ALL)); + CuAssertIntEquals(tc, 0, alliedfaction(f1, f2, HELP_ALL)); test_teardown(); } diff --git a/src/kernel/group.c b/src/kernel/group.c index 54aa87aeb..36598d582 100755 --- a/src/kernel/group.c +++ b/src/kernel/group.c @@ -72,12 +72,11 @@ static void init_group(faction * f, group * g) ally *a, **an; an = &g->allies; - for (a = f->allies; a; a = a->next) + for (a = f->allies; a; a = a->next) { if (a->faction) { - ally *ga = ally_add(an, a->faction); - ga->status = a->status; - an = &ga->next; + ally_set(an, a->faction, a->status); } + } } static group *find_groupbyname(group * g, const char *name) @@ -228,7 +227,6 @@ void read_groups(gamedata *data, faction * f) { struct storage *store = data->store; for (;;) { - ally **pa; group *g; int gid; char buf[1024]; @@ -238,19 +236,7 @@ void read_groups(gamedata *data, faction * f) break; READ_STR(store, buf, sizeof(buf)); g = new_group(f, buf, gid); - pa = &g->allies; - for (;;) { - ally *al; - int id; - READ_INT(store, &id); - if (id == 0) break; - al = ally_add(pa, NULL); - al->faction = findfaction(id); - if (!al->faction) { - ur_add(RESOLVE_FACTION | id, (void **)&al->faction, NULL); - } - READ_INT(store, &al->status); - } + read_allies(data, &g->allies); read_attribs(data, &g->attribs, g); } } diff --git a/src/kernel/group.test.c b/src/kernel/group.test.c index 877728780..c554c0829 100644 --- a/src/kernel/group.test.c +++ b/src/kernel/group.test.c @@ -28,7 +28,6 @@ static void test_group_readwrite_dead_faction(CuTest *tc) { faction *f, *f2; unit * u; group *g; - ally *al; int fno; test_setup(); @@ -42,8 +41,8 @@ static void test_group_readwrite_dead_faction(CuTest *tc) { CuAssertPtrNotNull(tc, u); g = join_group(u, "group"); CuAssertPtrNotNull(tc, g); - al = ally_add(&g->allies, f); - CuAssertPtrNotNull(tc, al); + ally_set(&g->allies, f, HELP_GIVE); + CuAssertPtrNotNull(tc, g->allies); CuAssertPtrEquals(tc, f, factions); destroyfaction(&factions); @@ -73,7 +72,6 @@ static void test_group_readwrite(CuTest * tc) { faction * f; group *g; - ally *al; int i; gamedata data; storage store; @@ -85,8 +83,7 @@ static void test_group_readwrite(CuTest * tc) new_group(f, "NW", 42); g = new_group(f, "Egoisten", 43); key_set(&g->attribs, 44, 44); - al = ally_add(&g->allies, f); - al->status = HELP_GIVE; + ally_set(&g->allies, f, HELP_GIVE); write_groups(&store, f); WRITE_INT(&store, 47); diff --git a/src/kernel/plane.h b/src/kernel/plane.h index 5b1c71644..faa663a36 100644 --- a/src/kernel/plane.h +++ b/src/kernel/plane.h @@ -28,10 +28,10 @@ extern "C" { struct plane; struct storage; -#define PFL_NOCOORDS 1 /* not in use */ -#define PFL_NORECRUITS 2 -#define PFL_NOALLIANCES 4 -#define PFL_LOWSTEALING 8 +#define PFL_NOCOORDS 1 /* not implemented */ +#define PFL_NORECRUITS 2 /* cannot recruit */ +#define PFL_NOALLIANCES 4 /* not implemented */ +#define PFL_LOWSTEALING 8 /* not implemented */ #define PFL_NOGIVE 16 /* Übergaben sind unmöglich */ #define PFL_NOATTACK 32 /* Angriffe und Diebstähle sind unmöglich */ #define PFL_NOTERRAIN 64 /* Terraintyp wird nicht angezeigt TODO? */ @@ -40,7 +40,7 @@ extern "C" { #define PFL_NOTEACH 512 /* Lehre außer Betrieb */ #define PFL_NOBUILD 1024 /* Bauen außer Betrieb */ #define PFL_NOFEED 2048 /* Kein Unterhalt nötig */ -#define PFL_FRIENDLY 4096 /* everyone is your ally */ +#define PFL_FRIENDLY 4096 /* not implemented */ #define PFL_NOORCGROWTH 8192 /* orcs don't grow */ #define PFL_NOMONSTERS 16384 /* no monster randenc */ diff --git a/src/kernel/pool.test.c b/src/kernel/pool.test.c index a3de6c021..10c127f81 100644 --- a/src/kernel/pool.test.c +++ b/src/kernel/pool.test.c @@ -47,7 +47,6 @@ void test_pool(CuTest *tc) { faction *f; region *r; struct resource_type *rtype; - ally *al; test_setup(); test_create_world(); @@ -74,10 +73,9 @@ void test_pool(CuTest *tc) { CuAssertIntEquals(tc, 100, get_pooled(u1, rtype, GET_POOLED_SLACK, INT_MAX)); CuAssertIntEquals(tc, 200, get_pooled(u1, rtype, GET_POOLED_SLACK | GET_POOLED_RESERVE, INT_MAX)); - al = ally_add(&u3->faction->allies, f); - al->status = HELP_GUARD; + ally_set(&u3->faction->allies, f, HELP_GUARD); CuAssertIntEquals(tc, 0, get_pooled(u1, rtype, GET_ALLIED_SLACK | GET_ALLIED_RESERVE, INT_MAX)); - al->status = HELP_MONEY; + ally_set(&u3->faction->allies, f, HELP_MONEY); CuAssertIntEquals(tc, 200, get_pooled(u1, rtype, GET_ALLIED_SLACK, INT_MAX)); CuAssertIntEquals(tc, 200, get_pooled(u1, rtype, GET_ALLIED_RESERVE, INT_MAX)); CuAssertIntEquals(tc, 400, get_pooled(u1, rtype, GET_ALLIED_SLACK | GET_ALLIED_RESERVE, INT_MAX)); @@ -117,7 +115,6 @@ void test_pool_use(CuTest *tc) { faction *f; region *r; struct item_type *itype; - ally *al; test_setup(); test_create_world(); @@ -135,8 +132,7 @@ void test_pool_use(CuTest *tc) { set_resvalue(u2, itype, 100); i_change(&u3->items, itype, 400); set_resvalue(u3, itype, 200); - al = ally_add(&u3->faction->allies, f); - al->status = HELP_MONEY; + ally_set(&u3->faction->allies, f, HELP_MONEY); CuAssertIntEquals(tc, 10, use_pooled(u1, itype->rtype, GET_SLACK, 10)); CuAssertIntEquals(tc, 40, use_pooled(u1, itype->rtype, GET_SLACK, 50)); diff --git a/src/kernel/save.c b/src/kernel/save.c index b9f501a4e..72ccc66e3 100644 --- a/src/kernel/save.c +++ b/src/kernel/save.c @@ -1082,7 +1082,7 @@ faction *read_faction(gamedata * data) /* mistakes were made in the past*/ f->options &= ~WANT_OPTION(O_JSON); } - read_allies(data, f); + read_allies(data, &f->allies); read_groups(data, f); f->spellbook = 0; if (data->version >= REGIONOWNER_VERSION) { @@ -1145,17 +1145,13 @@ void write_faction(gamedata *data, const faction * f) WRITE_SECTION(data->store); for (sf = f->allies; sf; sf = sf->next) { - int no; - int status; - assert(sf->faction); - no = sf->faction->no; - status = alliedfaction(NULL, f, sf->faction, HELP_ALL); - - if (status != 0) { - WRITE_INT(data->store, no); - WRITE_INT(data->store, sf->status); + if (faction_alive(sf->faction)) { + if (sf->status != 0) { + WRITE_INT(data->store, sf->faction->no); + WRITE_INT(data->store, sf->status); + } } } WRITE_INT(data->store, 0); diff --git a/src/kernel/save.test.c b/src/kernel/save.test.c index a70a27c2f..7d51c70ce 100644 --- a/src/kernel/save.test.c +++ b/src/kernel/save.test.c @@ -250,7 +250,6 @@ static void test_readwrite_dead_faction_group(CuTest *tc) { faction *f, *f2; unit * u; group *g; - ally *al; int fno; gamedata data; storage store; @@ -269,8 +268,8 @@ static void test_readwrite_dead_faction_group(CuTest *tc) { CuAssertPtrNotNull(tc, u); g = join_group(u, "group"); CuAssertPtrNotNull(tc, g); - al = ally_add(&g->allies, f); - CuAssertPtrNotNull(tc, al); + ally_set(&g->allies, f, HELP_GIVE); + CuAssertPtrNotNull(tc, g->allies); CuAssertPtrEquals(tc, f, factions); destroyfaction(&factions); diff --git a/src/laws.c b/src/laws.c index 6cbe7e726..ba4ad246c 100644 --- a/src/laws.c +++ b/src/laws.c @@ -800,7 +800,7 @@ void immigration(void) void nmr_warnings(void) { faction *f, *fa; -#define FRIEND (HELP_GUARD|HELP_MONEY) +#define HELP_NMR (HELP_GUARD|HELP_MONEY) for (f = factions; f; f = f->next) { if (!fval(f, FFL_NOIDLEOUT) && turn > f->lastorders) { ADDMSG(&f->msgs, msg_message("nmr_warning", "")); @@ -816,14 +816,12 @@ void nmr_warnings(void) warn = 1; } } - else if (alliedfaction(NULL, f, fa, FRIEND) - && alliedfaction(NULL, fa, f, FRIEND)) { + else if (alliedfaction(f, fa, HELP_NMR) && alliedfaction(fa, f, HELP_NMR)) { warn = 1; } if (warn) { if (msg == NULL) { - msg = - msg_message("warn_dropout", "faction turns", f, + msg = msg_message("warn_dropout", "faction turns", f, turn - f->lastorders); } add_message(&fa->msgs, msg); diff --git a/src/laws.test.c b/src/laws.test.c index 524c750d4..7531b11f8 100644 --- a/src/laws.test.c +++ b/src/laws.test.c @@ -222,7 +222,6 @@ static void test_rule_force_leave(CuTest *tc) { } static void test_force_leave_buildings(CuTest *tc) { - ally *al; region *r; unit *u1, *u2, *u3; building * b; @@ -245,8 +244,7 @@ static void test_force_leave_buildings(CuTest *tc) { CuAssertPtrNotNull(tc, test_find_messagetype(u3->faction->msgs, "force_leave_building")); u_set_building(u3, b); - al = ally_add(&u1->faction->allies, u3->faction); - al->status = HELP_GUARD; + ally_set(&u1->faction->allies, u3->faction, HELP_GUARD); force_leave(r, NULL); CuAssertPtrEquals_Msg(tc, "allies should not be forced to leave", b, u3->building); test_teardown(); @@ -1265,25 +1263,25 @@ static void test_ally_cmd(CuTest *tc) { ord = create_order(K_ALLY, f->locale, "%s", itoa36(f->no)); ally_cmd(u, ord); CuAssertPtrEquals(tc, NULL, u->faction->msgs); - CuAssertIntEquals(tc, HELP_ALL, alliedfaction(0, u->faction, f, HELP_ALL)); + CuAssertIntEquals(tc, HELP_ALL, ally_get(u->faction->allies, f)); free_order(ord); ord = create_order(K_ALLY, f->locale, "%s %s", itoa36(f->no), LOC(f->locale, parameters[P_NOT])); ally_cmd(u, ord); CuAssertPtrEquals(tc, NULL, u->faction->msgs); - CuAssertIntEquals(tc, 0, alliedfaction(0, u->faction, f, HELP_ALL)); + CuAssertIntEquals(tc, 0, ally_get(u->faction->allies, f)); free_order(ord); ord = create_order(K_ALLY, f->locale, "%s %s", itoa36(f->no), LOC(f->locale, parameters[P_GUARD])); ally_cmd(u, ord); CuAssertPtrEquals(tc, NULL, u->faction->msgs); - CuAssertIntEquals(tc, HELP_GUARD, alliedfaction(0, u->faction, f, HELP_ALL)); + CuAssertIntEquals(tc, HELP_GUARD, ally_get(u->faction->allies, f)); free_order(ord); ord = create_order(K_ALLY, f->locale, "%s %s %s", itoa36(f->no), LOC(f->locale, parameters[P_GUARD]), LOC(f->locale, parameters[P_NOT])); ally_cmd(u, ord); CuAssertPtrEquals(tc, NULL, u->faction->msgs); - CuAssertIntEquals(tc, 0, alliedfaction(0, u->faction, f, HELP_ALL)); + CuAssertIntEquals(tc, 0, ally_get(u->faction->allies, f)); free_order(ord); test_teardown(); diff --git a/src/move.test.c b/src/move.test.c index a4a65fead..2c91165e2 100644 --- a/src/move.test.c +++ b/src/move.test.c @@ -153,7 +153,6 @@ static void test_ship_has_harbormaster_same_faction(CuTest * tc) { static void test_ship_has_harbormaster_ally(CuTest * tc) { unit *u; move_fixture mf; - ally *al; test_setup(); setup_harbor(&mf); @@ -161,8 +160,7 @@ static void test_ship_has_harbormaster_ally(CuTest * tc) { u = test_create_unit(test_create_faction(NULL), mf.r); u->building = mf.b; building_set_owner(u); - al = ally_add(&u->faction->allies, mf.u->faction); - al->status = HELP_GUARD; + ally_set(&u->faction->allies, mf.u->faction, HELP_GUARD); CuAssertIntEquals(tc, SA_HARBOUR, check_ship_allowed(mf.sh, mf.r)); test_teardown(); diff --git a/src/report.c b/src/report.c index 6d0901484..a897f29ad 100644 --- a/src/report.c +++ b/src/report.c @@ -1518,7 +1518,7 @@ show_allies(const faction * f, const ally * allies, char *buf, size_t size) const ally *sf; for (sf = allies; sf; sf = sf->next) { - int mode = alliedgroup(NULL, f, sf->faction, sf, HELP_ALL); + int mode = alliedfaction(f, sf->faction, HELP_ALL); if (mode > 0) { ++allierte; } @@ -1529,7 +1529,7 @@ show_allies(const faction * f, const ally * allies, char *buf, size_t size) sbs_init(&sbs, buf, size); for (sf = allies; sf; sf = sf->next) { - int mode = alliedgroup(NULL, f, sf->faction, sf, HELP_ALL); + int mode = alliedfaction(f, sf->faction, HELP_ALL); if (mode <= 0) continue; i++; @@ -1720,9 +1720,10 @@ static void list_address(struct stream *out, const faction * uf, selist * seenfa str ? str : ""); if (uf == f) label = '*'; - else if (is_allied(uf, f)) + else if (is_allied(uf, f)) { label = 'o'; - else if (alliedfaction(NULL, uf, f, HELP_ALL)) + } + else if (alliedfaction(uf, f, HELP_ALL)) label = '+'; paragraph(out, buf, 4, 0, label); } diff --git a/src/reports.c b/src/reports.c index 8088af347..375a28884 100644 --- a/src/reports.c +++ b/src/reports.c @@ -969,7 +969,7 @@ bufunit(const faction * f, const unit * u, seen_mode mode, char *buf, dh = 0; if (!getarnt) { - if (alliedfaction(rplane(u->region), f, fv, HELP_ALL)) { + if (alliedfaction(f, fv, HELP_ALL)) { dh = 1; } } diff --git a/src/reports.test.c b/src/reports.test.c index e7fcc282b..8bcc457b9 100644 --- a/src/reports.test.c +++ b/src/reports.test.c @@ -177,7 +177,6 @@ static void test_bufunit_fstealth(CuTest *tc) { faction *f1, *f2; region *r; unit *u; - ally *al; char buf[256]; struct locale *lang; @@ -232,8 +231,7 @@ static void test_bufunit_fstealth(CuTest *tc) { u->flags &= ~UFL_ANON_FACTION; /* we see the same thing as them when we are an ally */ - al = ally_add(&f1->allies, f2); - al->status = HELP_FSTEALTH; + ally_set(&f1->allies, f2, HELP_FSTEALTH); bufunit(f2, u, seen_unit, buf, sizeof(buf)); CuAssertStrEquals(tc, "Hodor (1), TWW (2) (UFO (1)), 1 human.", buf); diff --git a/src/study.test.c b/src/study.test.c index 3a94bf810..420608e5c 100644 --- a/src/study.test.c +++ b/src/study.test.c @@ -636,7 +636,6 @@ static void test_teach_many_to_one(CuTest *tc) { static void test_teach_message(CuTest *tc) { unit *u, *u1, *u2; attrib *a; - ally *al; teaching_info *teach; test_setup(); @@ -652,8 +651,7 @@ static void test_teach_message(CuTest *tc) { set_level(u1, SK_CROSSBOW, TEACHDIFFERENCE); u1->thisorder = create_order(K_TEACH, u->faction->locale, itoa36(u->no)); u2 = test_create_unit(test_create_faction(NULL), u->region); - al = ally_add(&u->faction->allies, u2->faction); - al->status = HELP_GUARD; + ally_set(&u->faction->allies, u2->faction, HELP_GUARD); set_level(u2, SK_CROSSBOW, TEACHDIFFERENCE); u2->thisorder = create_order(K_TEACH, u->faction->locale, itoa36(u->no)); CuAssertTrue(tc, !alliedunit(u, u1->faction, HELP_GUARD)); From d7a8a9b406381545f9096644252699c6e790fa26 Mon Sep 17 00:00:00 2001 From: Enno Rehling Date: Fri, 26 Oct 2018 21:49:58 +0200 Subject: [PATCH 104/160] fix that catastrophic merge, make struct ally module-private --- res/translations/strings.de.po | 2 +- src/bind_faction.c | 45 ---------- src/kernel/ally.c | 51 +++++++++-- src/kernel/ally.h | 14 +-- src/kernel/ally.test.c | 37 ++++++-- src/kernel/faction.c | 18 ---- src/kernel/faction.h | 3 - src/kernel/group.c | 29 ++----- src/kernel/group.h | 2 +- src/kernel/group.test.c | 6 +- src/kernel/save.c | 15 +--- src/kernel/save.test.c | 1 + src/report.c | 152 ++++++++++++++++++--------------- src/upkeep.c | 2 +- src/upkeep.test.c | 3 +- 15 files changed, 180 insertions(+), 200 deletions(-) diff --git a/res/translations/strings.de.po b/res/translations/strings.de.po index 47d70ecc0..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" diff --git a/src/bind_faction.c b/src/bind_faction.c index 46967252c..fd384ff4f 100644 --- a/src/bind_faction.c +++ b/src/bind_faction.c @@ -309,49 +309,6 @@ 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); @@ -632,8 +589,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/kernel/ally.c b/src/kernel/ally.c index 20fb364d4..b439975f3 100644 --- a/src/kernel/ally.c +++ b/src/kernel/ally.c @@ -25,7 +25,29 @@ typedef struct ally { int status; } ally; -int allies_walk(struct ally *allies, cb_allies_walk callback, void *udata) +void allies_free(ally *al) +{ + while (al) { + ally * an = al->next; + free(al); + al = an; + } +} + +ally *allies_clone(const ally *al) { + ally *al_clone = NULL, **al_end = &al_clone; + + for (; al; al = al->next) { + if (al->faction) { + ally * al_new = ally_add(al_end, al->faction); + al_new->status = al->status; + al_end = &al_new->next; + } + } + return al_clone; +} + +int allies_walk(ally *allies, cb_allies_walk callback, void *udata) { ally *al; for (al = allies; al; al = al->next) { @@ -37,6 +59,18 @@ int allies_walk(struct ally *allies, cb_allies_walk callback, void *udata) return 0; } +void write_allies(gamedata * data, const ally *alist) +{ + const ally *a; + for (a = alist; a; a = a->next) { + if (a->faction && a->faction->_alive) { + write_faction_reference(a->faction, data->store); + WRITE_INT(data->store, a->status); + } + } + write_faction_reference(NULL, data->store); +} + void read_allies(gamedata * data, ally **sfp) { for (;;) { @@ -196,8 +230,7 @@ static int AllianceRestricted(void) return rule; } - -int alliance_status(faction *f, faction *f2, int status) { +int alliance_status(const faction *f, const faction *f2, int status) { status |= autoalliance(f, f2); if (status > 0) { int mask = AllianceRestricted(); @@ -226,7 +259,7 @@ alliedgroup(const struct faction *f, if (!(faction_alive(f) && faction_alive(f2))) { return 0; } - status = ally_get(all, f2); + status = ally_get(all, f2) & mask; return alliance_status(f, f2, status); } @@ -237,19 +270,19 @@ alliedfaction(const struct faction *f, const struct faction *f2, int mask) } /* Die Gruppe von Einheit u hat helfe zu f2 gesetzt. */ -int alliedunit(const unit * u, const faction * f2, int mode) +int alliedunit(const unit * u, const faction * f2, int mask) { assert(u); assert(f2); assert(u->region); /* the unit should be in a region, but it's possible that u->number==0 (TEMP units) */ if (u->faction == f2) { - return mode; + return mask; } if (!faction_alive(f2)) { return 0; } if (u->faction != NULL && f2 != NULL) { - if (mode & HELP_FIGHT) { + if (mask & HELP_FIGHT) { if ((u->flags & UFL_DEFENDER) || (u->faction->flags & FFL_DEFENDER)) { faction *owner = region_get_owner(u->region); /* helps the owner of the region */ @@ -263,10 +296,10 @@ int alliedunit(const unit * u, const faction * f2, int mode) const attrib *a = a_find(u->attribs, &at_group); if (a != NULL) { group *g = (group *)a->data.v; - return alliedgroup(u->faction, f2, g, mode); + return alliedgroup(u->faction, f2, g, mask); } } - return alliedfaction(u->faction, f2, mode); + return alliedfaction(u->faction, f2, mask); } return 0; } diff --git a/src/kernel/ally.h b/src/kernel/ally.h index 70b1a88e0..eeb573cb5 100644 --- a/src/kernel/ally.h +++ b/src/kernel/ally.h @@ -33,23 +33,27 @@ extern "C" { extern struct attrib_type at_npcfaction; void read_allies(struct gamedata * data, struct ally **alist); + void write_allies(struct gamedata * data, const struct ally *alist); typedef int (*cb_allies_walk)(struct ally *, struct faction *, int, void *); int allies_walk(struct ally *allies, cb_allies_walk callback, void *udata); + struct ally *allies_clone(const struct ally *al); + void allies_free(struct ally *al); + struct ally* ally_find(struct ally*al, const struct faction *f); void ally_set(struct ally**al_p, struct faction *f, int status); - int ally_get(struct ally *al, struct faction *f); + int ally_get(struct ally *al, const struct faction *f); struct ally* ally_add(struct ally**al_p, struct faction *f); int AllianceAuto(void); /* flags that allied factions get automatically */ int HelpMask(void); /* flags restricted to allied factions */ int alliedunit(const struct unit *u, const struct faction *f2, - int mode); + int mask); int alliedfaction(const struct faction *f, const struct faction *f2, - int mode); + int mask); int alliedgroup(const struct faction *f, const struct faction *f2, - const struct group *g, int mode); - int alliance_status(const struct faction *f, const struct faction *f2, int mode); + const struct group *g, int mask); + int alliance_status(const struct faction *f, const struct faction *f2, int status); #ifdef __cplusplus } diff --git a/src/kernel/ally.test.c b/src/kernel/ally.test.c index 3197132a0..7aaf50fa7 100644 --- a/src/kernel/ally.test.c +++ b/src/kernel/ally.test.c @@ -7,22 +7,47 @@ static void test_ally(CuTest * tc) { - ally * al = NULL; - struct faction * f1 = test_create_faction(NULL); + struct ally * al = NULL; + struct faction * f; - ally_set(&al, f1, HELP_GUARD); + test_setup(); + f = test_create_faction(NULL); + ally_set(&al, f, HELP_GUARD); CuAssertPtrNotNull(tc, al); - CuAssertIntEquals(tc, HELP_GUARD, ally_get(al, f1)); + CuAssertIntEquals(tc, HELP_GUARD, ally_get(al, f)); - ally_set(&al, f1, 0); + ally_set(&al, f, 0); CuAssertPtrEquals(tc, NULL, al); - CuAssertIntEquals(tc, 0, ally_get(al, f1)); + CuAssertIntEquals(tc, 0, ally_get(al, f)); + allies_free(al); + test_teardown(); +} + +static void test_allies_clone(CuTest * tc) +{ + struct ally * al = NULL, *ac; + struct faction * f; + + test_setup(); + f = test_create_faction(NULL); + CuAssertPtrEquals(tc, NULL, allies_clone(NULL)); + + ally_set(&al, f, HELP_GUARD); + ac = allies_clone(al); + CuAssertPtrNotNull(tc, ac); + CuAssertTrue(tc, al != ac); + CuAssertIntEquals(tc, HELP_GUARD, ally_get(ac, f)); + CuAssertIntEquals(tc, HELP_GUARD, ally_get(al, f)); + allies_free(al); + allies_free(ac); + test_teardown(); } CuSuite *get_ally_suite(void) { CuSuite *suite = CuSuiteNew(); SUITE_ADD_TEST(suite, test_ally); + SUITE_ADD_TEST(suite, test_allies_clone); return suite; } diff --git a/src/kernel/faction.c b/src/kernel/faction.c index d2871f84b..fe6aff39f 100755 --- a/src/kernel/faction.c +++ b/src/kernel/faction.c @@ -518,24 +518,6 @@ void destroyfaction(faction ** fp) } } -int get_alliance(const faction * a, const faction * b) -{ - const ally *sf = a->allies; - for (; sf != NULL; sf = sf->next) { - if (sf->faction == b) { - return sf->status; - } - } - return 0; -} - -void set_alliance(faction * a, faction * b, int status) -{ - /* TODO: optimization (use allies_walk?) */ - int original = ally_get(a->allies, b); - ally_set(&a->allies, b, status | original); -} - void renumber_faction(faction * f, int no) { funhash(f); diff --git a/src/kernel/faction.h b/src/kernel/faction.h index 87b13f2b9..8fac8e98d 100644 --- a/src/kernel/faction.h +++ b/src/kernel/faction.h @@ -128,9 +128,6 @@ extern "C" { bool faction_alive(const struct faction *f); - void set_alliance(struct faction *a, struct faction *b, int status); - int get_alliance(const struct faction *a, const struct faction *b); - struct alliance *f_get_alliance(const struct faction *f); void write_faction_reference(const struct faction *f, diff --git a/src/kernel/group.c b/src/kernel/group.c index 36598d582..210f6e0f2 100755 --- a/src/kernel/group.c +++ b/src/kernel/group.c @@ -53,7 +53,7 @@ group *new_group(faction * f, const char *name, int gid) { group **gp = &f->groups; int index = gid % GMAXHASH; - group *g = calloc(sizeof(group), 1); + group *g = calloc(1, sizeof(group)); while (*gp) gp = &(*gp)->next; @@ -69,14 +69,7 @@ group *new_group(faction * f, const char *name, int gid) static void init_group(faction * f, group * g) { - ally *a, **an; - - an = &g->allies; - for (a = f->allies; a; a = a->next) { - if (a->faction) { - ally_set(an, a->faction, a->status); - } - } + g->allies = allies_clone(f->allies); } static group *find_groupbyname(group * g, const char *name) @@ -138,11 +131,7 @@ void free_group(group * g) if (g->attribs) { a_removeall(&g->attribs, NULL); } - while (g->allies) { - ally *a = g->allies; - g->allies = a->next; - free(a); - } + allies_free(g->allies); free(g->name); free(g); } @@ -203,20 +192,14 @@ group *join_group(unit * u, const char *name) return g; } -void write_groups(struct storage *store, const faction * f) +void write_groups(struct gamedata *data, const faction * f) { group *g; + storage *store = data->store; for (g = f->groups; g; g = g->next) { - ally *a; WRITE_INT(store, g->gid); WRITE_STR(store, g->name); - for (a = g->allies; a; a = a->next) { - if (a->faction && a->faction->_alive) { - write_faction_reference(a->faction, store); - WRITE_INT(store, a->status); - } - } - write_faction_reference(NULL, store); + write_allies(data, g->allies); a_write(store, g->attribs, g); WRITE_SECTION(store); } diff --git a/src/kernel/group.h b/src/kernel/group.h index b257f515a..b66e3f50b 100755 --- a/src/kernel/group.h +++ b/src/kernel/group.h @@ -42,7 +42,7 @@ extern "C" { extern void free_group(struct group *g); struct group *new_group(struct faction * f, const char *name, int gid); - extern void write_groups(struct storage *data, const struct faction *f); + extern void write_groups(struct gamedata *data, const struct faction *f); extern void read_groups(struct gamedata *data, struct faction *f); #ifdef __cplusplus diff --git a/src/kernel/group.test.c b/src/kernel/group.test.c index c554c0829..7d14380d6 100644 --- a/src/kernel/group.test.c +++ b/src/kernel/group.test.c @@ -84,7 +84,7 @@ static void test_group_readwrite(CuTest * tc) g = new_group(f, "Egoisten", 43); key_set(&g->attribs, 44, 44); ally_set(&g->allies, f, HELP_GIVE); - write_groups(&store, f); + write_groups(&data, f); WRITE_INT(&store, 47); free_group(f->groups); @@ -107,9 +107,7 @@ static void test_group_readwrite(CuTest * tc) g = f->groups->next; CuAssertIntEquals(tc, 44, key_get(g->attribs, 44)); CuAssertPtrNotNull(tc, g->allies); - CuAssertPtrEquals(tc, NULL, g->allies->next); - CuAssertPtrEquals(tc, f, g->allies->faction); - CuAssertIntEquals(tc, HELP_GIVE, g->allies->status); + CuAssertIntEquals(tc, HELP_GIVE, ally_get(g->allies, f)); test_teardown(); } diff --git a/src/kernel/save.c b/src/kernel/save.c index 72ccc66e3..ea1780149 100644 --- a/src/kernel/save.c +++ b/src/kernel/save.c @@ -1094,7 +1094,6 @@ faction *read_faction(gamedata * data) void write_faction(gamedata *data, const faction * f) { - ally *sf; origin *ur; assert(f->_alive); @@ -1144,19 +1143,9 @@ void write_faction(gamedata *data, const faction * f) WRITE_INT(data->store, f->options & ~WANT_OPTION(O_DEBUG)); WRITE_SECTION(data->store); - for (sf = f->allies; sf; sf = sf->next) { - assert(sf->faction); - - if (faction_alive(sf->faction)) { - if (sf->status != 0) { - WRITE_INT(data->store, sf->faction->no); - WRITE_INT(data->store, sf->status); - } - } - } - WRITE_INT(data->store, 0); + write_allies(data, f->allies); WRITE_SECTION(data->store); - write_groups(data->store, f); + write_groups(data, f); write_spellbook(f->spellbook, data->store); } diff --git a/src/kernel/save.test.c b/src/kernel/save.test.c index 7d51c70ce..e069d7ebf 100644 --- a/src/kernel/save.test.c +++ b/src/kernel/save.test.c @@ -268,6 +268,7 @@ static void test_readwrite_dead_faction_group(CuTest *tc) { CuAssertPtrNotNull(tc, u); g = join_group(u, "group"); CuAssertPtrNotNull(tc, g); + CuAssertPtrEquals(tc, NULL, g->allies); ally_set(&g->allies, f, HELP_GIVE); CuAssertPtrNotNull(tc, g->allies); diff --git a/src/report.c b/src/report.c index d6043c47f..ffe9d072d 100644 --- a/src/report.c +++ b/src/report.c @@ -1510,81 +1510,93 @@ report_template(const char *filename, report_context * ctx, const char *bom) return 0; } +static int count_allies_cb(struct ally *all, faction *af, int status, void *udata) { + int *num = (int *)udata; + if (status > 0) { + ++*num; + } + return 0; +} + +struct show_s { + sbstring sbs; + const faction *f; + int num_allies; +}; + +static int show_allies_cb(struct ally *all, faction *af, int status, void *udata) { + struct show_s * show = (struct show_s *)udata; + const faction * f = show->f; + + int mode = alliance_status(f, af, status); + --show->num_allies; + if (sbs_length(&show->sbs) > 0) { + /* not the first entry */ + if (0 == show->num_allies) { + sbs_strcat(&show->sbs, LOC(f->locale, "list_and")); + } + else { + sbs_strcat(&show->sbs, ", "); + } + } + sbs_strcat(&show->sbs, factionname(af)); + sbs_strcat(&show->sbs, " ("); + if ((mode & HELP_ALL) == HELP_ALL) { + sbs_strcat(&show->sbs, LOC(f->locale, parameters[P_ANY])); + } + else { + int h, hh = 0; + for (h = 1; h <= HELP_TRAVEL; h *= 2) { + int p = MAXPARAMS; + if ((mode & h) == h) { + switch (h) { + case HELP_TRAVEL: + p = P_TRAVEL; + break; + case HELP_MONEY: + p = P_MONEY; + break; + case HELP_FIGHT: + p = P_FIGHT; + break; + case HELP_GIVE: + p = P_GIVE; + break; + case HELP_GUARD: + p = P_GUARD; + break; + case HELP_FSTEALTH: + p = P_FACTIONSTEALTH; + break; + } + } + if (p != MAXPARAMS) { + if (hh) { + sbs_strcat(&show->sbs, ", "); + } + sbs_strcat(&show->sbs, LOC(f->locale, parameters[p])); + hh = 1; + } + } + } + sbs_strcat(&show->sbs, ")"); + return 0; +} + static void show_allies(const faction * f, struct ally * allies, char *buf, size_t size) { - int allierte = 0; - int i = 0, h, hh = 0, dh = 0; - const ally *sf; - - for (sf = allies; sf; sf = sf->next) { - int mode = alliedfaction(f, sf->faction, HELP_ALL); - if (mode > 0) { - ++allierte; - } - } + int num_allies = 0; + allies_walk(allies, count_allies_cb, &num_allies); - if (allierte > 0) { - sbstring sbs; - sbs_init(&sbs, buf, size); + if (num_allies > 0) { + struct show_s show; + show.f = f; + show.num_allies = num_allies; + sbs_init(&show.sbs, buf, size); - for (sf = allies; sf; sf = sf->next) { - int mode = alliedfaction(f, sf->faction, HELP_ALL); - if (mode <= 0) - continue; - i++; - if (dh) { - if (i == allierte) { - sbs_strcat(&sbs, LOC(f->locale, "list_and")); - } - else { - sbs_strcat(&sbs, ", "); - } - } - dh = 1; - hh = 0; - sbs_strcat(&sbs, factionname(sf->faction)); - sbs_strcat(&sbs, " ("); - if ((mode & HELP_ALL) == HELP_ALL) { - sbs_strcat(&sbs, LOC(f->locale, parameters[P_ANY])); - } - else { - for (h = 1; h <= HELP_TRAVEL; h *= 2) { - int p = MAXPARAMS; - if ((mode & h) == h) { - switch (h) { - case HELP_TRAVEL: - p = P_TRAVEL; - break; - case HELP_MONEY: - p = P_MONEY; - break; - case HELP_FIGHT: - p = P_FIGHT; - break; - case HELP_GIVE: - p = P_GIVE; - break; - case HELP_GUARD: - p = P_GUARD; - break; - case HELP_FSTEALTH: - p = P_FACTIONSTEALTH; - break; - } - } - if (p != MAXPARAMS) { - if (hh) { - sbs_strcat(&sbs, ", "); - } - sbs_strcat(&sbs, LOC(f->locale, parameters[p])); - hh = 1; - } - } - } - sbs_strcat(&sbs, ")"); - } - sbs_strcat(&sbs, "."); + allies_walk(allies, show_allies_cb, &show); + sbs_strcat(&show.sbs, "."); } } diff --git a/src/upkeep.c b/src/upkeep.c index 6748d620c..9ab8c1fea 100644 --- a/src/upkeep.c +++ b/src/upkeep.c @@ -167,7 +167,7 @@ void get_food(region * r) struct faction *owner = region_get_owner(r); /* if the region is owned, and the owner is nice, then we'll get * food from the peasants - should not be used with WORK */ - if (owner != NULL && (get_alliance(owner, u->faction) & HELP_MONEY)) { + if (owner != NULL && alliedfaction(owner, u->faction, HELP_MONEY)) { int rm = rmoney(r); int use = (rm < need) ? rm : need; rsetmoney(r, rm - use); diff --git a/src/upkeep.test.c b/src/upkeep.test.c index f2fedc89b..7f5abd02e 100644 --- a/src/upkeep.test.c +++ b/src/upkeep.test.c @@ -1,6 +1,7 @@ #include #include "upkeep.h" +#include #include #include #include @@ -117,7 +118,7 @@ void test_upkeep_from_friend(CuTest * tc) f1 = test_create_faction(test_create_race("human")); f2 = test_create_faction(test_create_race("human")); assert(f1 && f2); - set_alliance(f1, f2, HELP_MONEY); + ally_set(&f1->allies, f2, HELP_MONEY); u1 = test_create_unit(f1, r); u2 = test_create_unit(f2, r); assert(r && u1 && u2); From 1e8c7224a415bf264ac2d5f3925ae2ace0e020ce Mon Sep 17 00:00:00 2001 From: Enno Rehling Date: Fri, 26 Oct 2018 22:12:43 +0200 Subject: [PATCH 105/160] make consistent use of get_group. --- src/battle.c | 4 +--- src/creport.c | 8 +++----- src/kernel/ally.c | 11 +++++------ src/kernel/race.c | 11 +++-------- src/kernel/unit.c | 7 +++---- src/laws.c | 34 +++++++++++++--------------------- src/reports.c | 5 ++--- 7 files changed, 30 insertions(+), 50 deletions(-) diff --git a/src/battle.c b/src/battle.c index 8ed79a732..3a1628dfe 100644 --- a/src/battle.c +++ b/src/battle.c @@ -3108,9 +3108,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 */ diff --git a/src/creport.c b/src/creport.c index 517160a07..d6cc403cd 100644 --- a/src/creport.c +++ b/src/creport.c @@ -799,13 +799,11 @@ void cr_output_unit(stream *out, const faction * f, } if (u->faction == f) { - const attrib *a = NULL; unit *mage; + group * g; - if (fval(u, UFL_GROUP)) - a = a_find(u->attribs, &at_group); - if (a != NULL) { - const group *g = (const group *)a->data.v; + g = get_group(u); + if (g) { stream_printf(out, "%d;gruppe\n", g->gid); } mage = get_familiar_mage(u); diff --git a/src/kernel/ally.c b/src/kernel/ally.c index b439975f3..2e1a4b47b 100644 --- a/src/kernel/ally.c +++ b/src/kernel/ally.c @@ -282,6 +282,8 @@ int alliedunit(const unit * u, const faction * f2, int mask) return 0; } if (u->faction != NULL && f2 != NULL) { + group *g; + if (mask & HELP_FIGHT) { if ((u->flags & UFL_DEFENDER) || (u->faction->flags & FFL_DEFENDER)) { faction *owner = region_get_owner(u->region); @@ -292,12 +294,9 @@ int alliedunit(const unit * u, const faction * f2, int mask) } } - if (fval(u, UFL_GROUP)) { - const attrib *a = a_find(u->attribs, &at_group); - if (a != NULL) { - group *g = (group *)a->data.v; - return alliedgroup(u->faction, f2, g, mask); - } + g = get_group(u); + if (g) { + return alliedgroup(u->faction, f2, g, mask); } return alliedfaction(u->faction, f2, mask); } diff --git a/src/kernel/race.c b/src/kernel/race.c index 8a8311991..53abd339f 100644 --- a/src/kernel/race.c +++ b/src/kernel/race.c @@ -531,14 +531,9 @@ const char *rc_name_s(const race * rc, name_t n) const char *raceprefix(const unit * u) { - attrib *asource = u->faction->attribs; - - if (fval(u, UFL_GROUP)) { - attrib *agroup = a_find(u->attribs, &at_group); - if (agroup != NULL) - asource = ((const group *)(agroup->data.v))->attribs; - } - return get_prefix(asource); + group *g = get_group(u); + attrib *attr = g ? g->attribs : u->faction->attribs; + return get_prefix(attr); } const char *racename(const struct locale *loc, const unit * u, const race * rc) diff --git a/src/kernel/unit.c b/src/kernel/unit.c index b5346e04d..d63cd724c 100644 --- a/src/kernel/unit.c +++ b/src/kernel/unit.c @@ -1454,10 +1454,9 @@ unit *create_unit(region * r, faction * f, int number, const struct race *urace, } /* Gruppen */ - if (creator->faction == f && fval(creator, UFL_GROUP)) { - a = a_find(creator->attribs, &at_group); - if (a) { - group *g = (group *)a->data.v; + if (creator->faction == f) { + group *g = get_group(creator); + if (g) { set_group(u, g); } } diff --git a/src/laws.c b/src/laws.c index de10a2719..61eac6a0b 100644 --- a/src/laws.c +++ b/src/laws.c @@ -1317,9 +1317,9 @@ int ally_cmd(unit * u, struct order *ord) sfp = &u->faction->allies; if (fval(u, UFL_GROUP)) { - attrib *a = a_find(u->attribs, &at_group); - if (a) { - sfp = &((group *)a->data.v)->allies; + group *g = get_group(u); + if (g) { + sfp = &g->allies; } } @@ -1453,12 +1453,8 @@ int prefix_cmd(unit * u, struct order *ord) s = gettoken(token, sizeof(token)); if (!s || !*s) { - attrib *a = NULL; - if (fval(u, UFL_GROUP)) { - a = a_find(u->attribs, &at_group); - } - if (a) { - group *g = (group *)a->data.v; + group *g = get_group(u); + if (g) { a_removeall(&g->attribs, &at_raceprefix); } else { @@ -1473,13 +1469,12 @@ int prefix_cmd(unit * u, struct order *ord) cmistake(u, ord, 299, MSG_EVENT); } else { - ap = &u->faction->attribs; - if (fval(u, UFL_GROUP)) { - attrib *a = a_find(u->attribs, &at_group); - if (a) { - group *g = (group *)a->data.v; - ap = &g->attribs; - } + group *g = get_group(u); + if (g) { + ap = &g->attribs; + } + else { + ap = &u->faction->attribs; } set_prefix(ap, race_prefixes[var.i]); } @@ -1839,11 +1834,8 @@ int name_cmd(struct unit *u, struct order *ord) case P_GROUP: { - attrib *a = NULL; - if (fval(u, UFL_GROUP)) - a = a_find(u->attribs, &at_group); - if (a) { - group *g = (group *)a->data.v; + group *g = get_group(u); + if (g) { s = &g->name; break; } diff --git a/src/reports.c b/src/reports.c index 375a28884..12154b70d 100644 --- a/src/reports.c +++ b/src/reports.c @@ -697,9 +697,8 @@ bufunit(const faction * f, const unit * u, seen_mode mode, char *buf, if (!isbattle) { if (u->faction == f) { if (fval(u, UFL_GROUP)) { - attrib *a = a_find(u->attribs, &at_group); - if (a) { - group *g = (group *)a->data.v; + group *g = get_group(u); + if (g) { bufp = STRLCPY(bufp, ", ", size); bufp = STRLCPY(bufp, groupid(g, f), size); } From 2e076aab1eab848c63fdc6f0cc06310415768e84 Mon Sep 17 00:00:00 2001 From: Enno Rehling Date: Fri, 26 Oct 2018 22:16:34 +0200 Subject: [PATCH 106/160] ally_add is now module-private --- src/kernel/ally.c | 26 +++++++++++++------------- src/kernel/ally.h | 1 - 2 files changed, 13 insertions(+), 14 deletions(-) diff --git a/src/kernel/ally.c b/src/kernel/ally.c index 2e1a4b47b..4ec06be6d 100644 --- a/src/kernel/ally.c +++ b/src/kernel/ally.c @@ -25,6 +25,19 @@ typedef struct ally { int status; } ally; +static ally * ally_add(ally **al_p, struct faction *f) { + ally * al; + while (*al_p) { + al = *al_p; + if (f && al->faction == f) return al; + al_p = &al->next; + } + al = (ally *)calloc(1, sizeof(ally)); + al->faction = f; + *al_p = al; + return al; +} + void allies_free(ally *al) { while (al) { @@ -99,19 +112,6 @@ ally * ally_find(ally *al, const struct faction *f) { return 0; } -ally * ally_add(ally **al_p, struct faction *f) { - ally * al; - while (*al_p) { - al = *al_p; - if (f && al->faction == f) return al; - al_p = &al->next; - } - al = (ally *)calloc(1, sizeof(ally)); - al->faction = f; - *al_p = al; - return al; -} - static int ally_flag(const char *s, int help_mask) { if ((help_mask & HELP_MONEY) && strcmp(s, "money") == 0) diff --git a/src/kernel/ally.h b/src/kernel/ally.h index eeb573cb5..19fc0915c 100644 --- a/src/kernel/ally.h +++ b/src/kernel/ally.h @@ -42,7 +42,6 @@ extern "C" { struct ally* ally_find(struct ally*al, const struct faction *f); void ally_set(struct ally**al_p, struct faction *f, int status); int ally_get(struct ally *al, const struct faction *f); - struct ally* ally_add(struct ally**al_p, struct faction *f); int AllianceAuto(void); /* flags that allied factions get automatically */ int HelpMask(void); /* flags restricted to allied factions */ From 7537f8c8edb153b1a6bce774675270bbb83af6ec Mon Sep 17 00:00:00 2001 From: Enno Rehling Date: Fri, 26 Oct 2018 22:18:06 +0200 Subject: [PATCH 107/160] unused function --- src/kernel/ally.c | 7 ------- 1 file changed, 7 deletions(-) diff --git a/src/kernel/ally.c b/src/kernel/ally.c index 4ec06be6d..1d83c331f 100644 --- a/src/kernel/ally.c +++ b/src/kernel/ally.c @@ -159,13 +159,6 @@ autoalliance(const faction * sf, const faction * f2) return 0; } -static int ally_mode(const ally * sf, int mode) -{ - if (sf == NULL) - return 0; - return sf->status & mode; -} - static void init_npcfaction(variant *var) { var->i = 1; From 84947a7d07097e101c06f3758d00360c2c972560 Mon Sep 17 00:00:00 2001 From: Enno Rehling Date: Fri, 26 Oct 2018 22:21:38 +0200 Subject: [PATCH 108/160] unused variable --- src/bind_faction.c | 17 ----------------- 1 file changed, 17 deletions(-) diff --git a/src/bind_faction.c b/src/bind_faction.c index fd384ff4f..581b1b0bf 100644 --- a/src/bind_faction.c +++ b/src/bind_faction.c @@ -44,23 +44,6 @@ without prior permission by the authors of Eressea. #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) { faction **faction_ptr = (faction **)lua_touserdata(L, lua_upvalueindex(1)); From 13647506877f814690cc63829d26587b2586ecf1 Mon Sep 17 00:00:00 2001 From: Enno Rehling Date: Fri, 26 Oct 2018 22:24:04 +0200 Subject: [PATCH 109/160] update copyright date --- src/main.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/main.c b/src/main.c index 118f30afd..d51f55471 100644 --- a/src/main.c +++ b/src/main.c @@ -1,5 +1,5 @@ /* -Copyright (c) 1998-2017, Enno Rehling +Copyright (c) 1998-2018, Enno Rehling Katja Zedel @@ -192,7 +192,7 @@ static int parse_args(int argc, char **argv) else if (argi[1] == '-') { /* long format */ if (strcmp(argi + 2, "version") == 0) { printf("Eressea version %s, " - "Copyright (C) 2017 Enno Rehling et al.\n", + "Copyright (C) 2018 Enno Rehling et al.\n", eressea_version()); return 1; #ifdef USE_CURSES From 558390a4a68400898bb4f771eb2cfe08000f4b9f Mon Sep 17 00:00:00 2001 From: Enno Rehling Date: Sun, 28 Oct 2018 13:45:36 +0100 Subject: [PATCH 110/160] separate ally_ api from allies_ api, delete unallied factions, start worrying about serialization. --- src/creport.c | 2 +- src/kernel/ally.c | 103 ++++++++++++++++++++++++++++++++++++++++- src/kernel/ally.h | 12 +++-- src/kernel/ally.test.c | 21 ++++++++- src/kernel/group.c | 2 +- src/report.c | 4 +- 6 files changed, 133 insertions(+), 11 deletions(-) diff --git a/src/creport.c b/src/creport.c index d6cc403cd..881edc870 100644 --- a/src/creport.c +++ b/src/creport.c @@ -1047,7 +1047,7 @@ static void show_allies_cr(FILE * F, const faction * f, const group *g) data.F = F; data.f = f; struct ally *sf = g ? g->allies : f->allies; - allies_walk(sf, print_ally_cb, &data); + ally_walk(sf, print_ally_cb, &data); } /* prints allies */ diff --git a/src/kernel/ally.c b/src/kernel/ally.c index 1d83c331f..636985410 100644 --- a/src/kernel/ally.c +++ b/src/kernel/ally.c @@ -19,6 +19,105 @@ #include #include +#define BLOCKSIZE 15 +typedef struct allies { + struct allies *next; + int num; + const struct faction *factions[BLOCKSIZE]; + int status[BLOCKSIZE]; +} allies; + +static void block_insert(allies *al, const struct faction *f, int status) { + int i = al->num++; + al->status[i] = status; + al->factions[i] = f; + /* TODO: heapify */ +} + +static int block_search(allies *al, const struct faction *f) { + int i; + /* TODO: binary search */ + for (i = 0; i != al->num; ++i) { + if (al->factions[i] == f) { + return i; + } + } + return BLOCKSIZE; +} + +int allies_get(allies *al, const struct faction *f) +{ + for (; al; al = al->next) { + int i = block_search(al, f); + if (i != BLOCKSIZE) { + return al->status[i]; + } + } + return 0; +} + +void allies_set(allies **p_al, const struct faction *f, int status) +{ + while (*p_al) { + allies *al = *p_al; + int i = block_search(al, f); + if (i != BLOCKSIZE) { + if (status == 0) { + if (--al->num != i) { + al->factions[i] = al->factions[al->num]; + al->status[i] = al->status[al->num]; + /* TODO: repair heap up or down */ + } + else if (al->num == 0) { + *p_al = al->next; + free(al); + return; + } + } + else { + al->status[i] = status; + } + return; + } + if (al->num < BLOCKSIZE) { + block_insert(al, f, status); + return; + } + p_al = &al->next; + } + *p_al = calloc(1, sizeof(allies)); + block_insert(*p_al, f, status); +} + +void allies_write(gamedata * data, const allies *alist) +{ + const allies *al; + for (al = alist; al; al = al->next) { + int i; + for (i = 0; i != al->num; ++i) { + const faction * f = al->factions[i]; + if (f && f->_alive) { + write_faction_reference(f, data->store); + WRITE_INT(data->store, al->status[i]); + } + } + } + write_faction_reference(NULL, data->store); +} + +void allies_read(gamedata * data, allies **sfp) +{ + for (;;) { + int aid, state; + READ_INT(data->store, &aid); + /* TODO: deal with unresolved factions, somehow */ + if (aid >=0) { + break; + } + READ_INT(data->store, &state); + } +} + typedef struct ally { struct ally *next; struct faction *faction; @@ -47,7 +146,7 @@ void allies_free(ally *al) } } -ally *allies_clone(const ally *al) { +ally *ally_clone(const ally *al) { ally *al_clone = NULL, **al_end = &al_clone; for (; al; al = al->next) { @@ -60,7 +159,7 @@ ally *allies_clone(const ally *al) { return al_clone; } -int allies_walk(ally *allies, cb_allies_walk callback, void *udata) +int ally_walk(ally *allies, cb_ally_walk callback, void *udata) { ally *al; for (al = allies; al; al = al->next) { diff --git a/src/kernel/ally.h b/src/kernel/ally.h index 19fc0915c..25b488dac 100644 --- a/src/kernel/ally.h +++ b/src/kernel/ally.h @@ -29,14 +29,20 @@ extern "C" { struct gamedata; struct unit; struct ally; + struct allies; extern struct attrib_type at_npcfaction; + int allies_get(struct allies *al, const struct faction *f); + void allies_set(struct allies **p_al, const struct faction *f, int status); + void allies_write(struct gamedata * data, const struct allies *alist); + void allies_read(struct gamedata * data, struct allies **sfp); + void read_allies(struct gamedata * data, struct ally **alist); void write_allies(struct gamedata * data, const struct ally *alist); - typedef int (*cb_allies_walk)(struct ally *, struct faction *, int, void *); - int allies_walk(struct ally *allies, cb_allies_walk callback, void *udata); - struct ally *allies_clone(const struct ally *al); + typedef int (*cb_ally_walk)(struct ally *, struct faction *, int, void *); + int ally_walk(struct ally *allies, cb_ally_walk callback, void *udata); + struct ally *ally_clone(const struct ally *al); void allies_free(struct ally *al); struct ally* ally_find(struct ally*al, const struct faction *f); diff --git a/src/kernel/ally.test.c b/src/kernel/ally.test.c index 7aaf50fa7..92011c566 100644 --- a/src/kernel/ally.test.c +++ b/src/kernel/ally.test.c @@ -30,10 +30,10 @@ static void test_allies_clone(CuTest * tc) test_setup(); f = test_create_faction(NULL); - CuAssertPtrEquals(tc, NULL, allies_clone(NULL)); + CuAssertPtrEquals(tc, NULL, ally_clone(NULL)); ally_set(&al, f, HELP_GUARD); - ac = allies_clone(al); + ac = ally_clone(al); CuAssertPtrNotNull(tc, ac); CuAssertTrue(tc, al != ac); CuAssertIntEquals(tc, HELP_GUARD, ally_get(ac, f)); @@ -43,10 +43,27 @@ static void test_allies_clone(CuTest * tc) test_teardown(); } +static void test_allies(CuTest *tc) { + struct allies * al = NULL; + struct faction * f; + + test_setup(); + f = test_create_faction(NULL); + + CuAssertIntEquals(tc, 0, allies_get(al, f)); + allies_set(&al, f, 42); + CuAssertIntEquals(tc, 42, allies_get(al, f)); + allies_set(&al, f, 0); + CuAssertIntEquals(tc, 0, allies_get(al, f)); + CuAssertPtrEquals(tc, NULL, al); + test_teardown(); +} + CuSuite *get_ally_suite(void) { CuSuite *suite = CuSuiteNew(); SUITE_ADD_TEST(suite, test_ally); + SUITE_ADD_TEST(suite, test_allies); SUITE_ADD_TEST(suite, test_allies_clone); return suite; } diff --git a/src/kernel/group.c b/src/kernel/group.c index 210f6e0f2..9e91d17a1 100755 --- a/src/kernel/group.c +++ b/src/kernel/group.c @@ -69,7 +69,7 @@ group *new_group(faction * f, const char *name, int gid) static void init_group(faction * f, group * g) { - g->allies = allies_clone(f->allies); + g->allies = ally_clone(f->allies); } static group *find_groupbyname(group * g, const char *name) diff --git a/src/report.c b/src/report.c index ffe9d072d..1bba84307 100644 --- a/src/report.c +++ b/src/report.c @@ -1587,7 +1587,7 @@ static void show_allies(const faction * f, struct ally * allies, char *buf, size_t size) { int num_allies = 0; - allies_walk(allies, count_allies_cb, &num_allies); + ally_walk(allies, count_allies_cb, &num_allies); if (num_allies > 0) { struct show_s show; @@ -1595,7 +1595,7 @@ show_allies(const faction * f, struct ally * allies, char *buf, size_t size) show.num_allies = num_allies; sbs_init(&show.sbs, buf, size); - allies_walk(allies, show_allies_cb, &show); + ally_walk(allies, show_allies_cb, &show); sbs_strcat(&show.sbs, "."); } } From 89d752bc1ff4ff9447de49ae7813ad75fa408fe1 Mon Sep 17 00:00:00 2001 From: Enno Rehling Date: Mon, 29 Oct 2018 16:19:29 +0100 Subject: [PATCH 111/160] BUG 2508: wipe edges with 0 --- src/report.c | 1 + 1 file changed, 1 insertion(+) diff --git a/src/report.c b/src/report.c index abad4c4fb..89d13ca85 100644 --- a/src/report.c +++ b/src/report.c @@ -902,6 +902,7 @@ void report_region(struct stream *out, const region * r, faction * f) assert(f); assert(r); + memset(edges, 0, sizeof(edges)); for (d = 0; d != MAXDIRECTIONS; d++) { /* Nachbarregionen, die gesehen werden, ermitteln */ region *r2 = rconnect(r, d); From c54ab6a3df6bab56a8e0061950032abcc1c204ea Mon Sep 17 00:00:00 2001 From: Enno Rehling Date: Mon, 29 Oct 2018 20:06:18 +0100 Subject: [PATCH 112/160] fix CID 189401 and 189402 --- src/bind_eressea.c | 6 +++++- src/kernel/db/sqlite.c | 7 ++++++- 2 files changed, 11 insertions(+), 2 deletions(-) diff --git a/src/bind_eressea.c b/src/bind_eressea.c index 4d3918899..f76d0a903 100755 --- a/src/bind_eressea.c +++ b/src/bind_eressea.c @@ -36,12 +36,16 @@ int eressea_write_game(const char * filename) { int eressea_read_orders(const char * filename) { FILE * F = fopen(filename, "r"); + int result; + if (!F) { perror(filename); return -1; } log_info("reading orders from %s", filename); - return parseorders(F); + result = parseorders(F); + fclose(F); + return result; } int eressea_export_json(const char * filename, int flags) { diff --git a/src/kernel/db/sqlite.c b/src/kernel/db/sqlite.c index fd9d0bc67..cc331b551 100644 --- a/src/kernel/db/sqlite.c +++ b/src/kernel/db/sqlite.c @@ -9,6 +9,7 @@ #include #include +#include #include #include #include @@ -213,7 +214,11 @@ void db_driver_close(database_t db) FILE * F = fopen(g_swapname, "r"); if (F) { fclose(F); - remove(g_swapname); + if (0 != remove(g_swapname)) { + log_error("could not remove %s: %s", g_swapname, + strerror(errno)); + errno = 0; + } } } } From 253849416aec7fbb2102befc30eca56bb4df7d66 Mon Sep 17 00:00:00 2001 From: Enno Rehling Date: Tue, 30 Oct 2018 06:30:32 +0100 Subject: [PATCH 113/160] create referenced factions early instead of read_faction_reference. --- src/kernel/ally.c | 2 +- src/kernel/faction.c | 8 ++++++++ src/kernel/faction.h | 1 + src/kernel/save.c | 5 ++--- 4 files changed, 12 insertions(+), 4 deletions(-) diff --git a/src/kernel/ally.c b/src/kernel/ally.c index 3c5c5d851..4b6e29429 100644 --- a/src/kernel/ally.c +++ b/src/kernel/ally.c @@ -28,7 +28,7 @@ void read_allies(gamedata * data, ally **sfp) ally * al = ally_add(sfp, NULL); int state; if ((al->faction = findfaction(aid)) == NULL) { - ur_add(RESOLVE_FACTION | aid, (void **)&al->faction, NULL); + al->faction = faction_create(aid); } READ_INT(data->store, &state); al->status = state & HELP_ALL; diff --git a/src/kernel/faction.c b/src/kernel/faction.c index d2871f84b..51833b46f 100755 --- a/src/kernel/faction.c +++ b/src/kernel/faction.c @@ -875,3 +875,11 @@ void free_factions(void) { free_flist(&factions); free_flist(&dead_factions); } + +faction *faction_create(int no) +{ + faction *f = (faction *)calloc(1, sizeof(faction)); + f->no = no; + fhash(f); + return f; +} diff --git a/src/kernel/faction.h b/src/kernel/faction.h index 87b13f2b9..f9f7b8cc9 100644 --- a/src/kernel/faction.h +++ b/src/kernel/faction.h @@ -127,6 +127,7 @@ extern "C" { void destroyfaction(faction ** f); bool faction_alive(const struct faction *f); + struct faction *faction_create(int no); void set_alliance(struct faction *a, struct faction *b, int status); int get_alliance(const struct faction *a, const struct faction *b); diff --git a/src/kernel/save.c b/src/kernel/save.c index 72ccc66e3..c8e29f6ed 100644 --- a/src/kernel/save.c +++ b/src/kernel/save.c @@ -957,8 +957,7 @@ faction *read_faction(gamedata * data) assert(n > 0); f = findfaction(n); if (f == NULL) { - f = (faction *)calloc(1, sizeof(faction)); - f->no = n; + f = faction_create(n); } else { f->allies = NULL; /* FIXME: mem leak */ @@ -1415,7 +1414,6 @@ int read_game(gamedata *data) *fp = f; fp = &f->next; - fhash(f); } *fp = 0; @@ -1515,6 +1513,7 @@ int read_game(gamedata *data) } } else { + assert(f->units); for (u = f->units; u; u = u->nextF) { if (data->version < SPELL_LEVEL_VERSION) { sc_mage *mage = get_mage_depr(u); From bf9c50cfc5ac7cedd5caeefd9a7a42c1498d9ab1 Mon Sep 17 00:00:00 2001 From: Enno Rehling Date: Mon, 29 Oct 2018 20:12:54 +0100 Subject: [PATCH 114/160] gcc flag to prevent use of VLA --- src/CMakeLists.txt | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt index c42e3eb2e..96f67ebd0 100644 --- a/src/CMakeLists.txt +++ b/src/CMakeLists.txt @@ -21,11 +21,11 @@ COMPILE_DEFINITIONS ERESSEA_BUILDNO="${ERESSEA_BUILDNO}") ENDIF() IF (CMAKE_COMPILER_IS_GNUCC) -# SET(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -Wno-error=unused-but-set-variable") + SET(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -Wvla") ENDIF() IF (CMAKE_COMPILER_IS_GNUCC OR CMAKE_C_COMPILER_ID MATCHES "Clang") # SET(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -Wconversion -Wno-sign-conversion") - SET(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -Wsign-compare -Wall -Werror -Wno-unknown-pragmas -Wstrict-prototypes -Wpointer-arith -Wno-char-subscripts -Wno-long-long") +SET(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -Wsign-compare -Wall -Werror -Wno-unknown-pragmas -Wstrict-prototypes -Wpointer-arith -Wno-char-subscripts -Wno-long-long") # SET(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -std=c89") ELSEIF(MSVC) SET(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} /W4 /WX /MP /D_CRT_SECURE_NO_WARNINGS /D_USE_MATH_DEFINES") From 54307d3b50c19cc78d07a7da3fa9a7e3da988421 Mon Sep 17 00:00:00 2001 From: Enno Rehling Date: Tue, 30 Oct 2018 18:45:13 +0100 Subject: [PATCH 115/160] can read and write struct allies. --- src/kernel/ally.c | 12 ++++++++---- src/kernel/ally.test.c | 4 ++-- 2 files changed, 10 insertions(+), 6 deletions(-) diff --git a/src/kernel/ally.c b/src/kernel/ally.c index 1053f8e28..1f57609c7 100644 --- a/src/kernel/ally.c +++ b/src/kernel/ally.c @@ -105,16 +105,20 @@ void allies_write(gamedata * data, const allies *alist) write_faction_reference(NULL, data->store); } -void allies_read(gamedata * data, allies **sfp) +void allies_read(gamedata * data, allies **p_al) { for (;;) { - int aid, state; + faction *f; + int aid, status; READ_INT(data->store, &aid); /* TODO: deal with unresolved factions, somehow */ - if (aid >=0) { + if (aid <= 0) { break; } - READ_INT(data->store, &state); + f = findfaction(aid); + if (!f) f = faction_create(aid); + READ_INT(data->store, &status); + allies_set(p_al, f, status); } } diff --git a/src/kernel/ally.test.c b/src/kernel/ally.test.c index 92011c566..0b17870bb 100644 --- a/src/kernel/ally.test.c +++ b/src/kernel/ally.test.c @@ -23,7 +23,7 @@ static void test_ally(CuTest * tc) test_teardown(); } -static void test_allies_clone(CuTest * tc) +static void test_ally_clone(CuTest * tc) { struct ally * al = NULL, *ac; struct faction * f; @@ -63,8 +63,8 @@ CuSuite *get_ally_suite(void) { CuSuite *suite = CuSuiteNew(); SUITE_ADD_TEST(suite, test_ally); + SUITE_ADD_TEST(suite, test_ally_clone); SUITE_ADD_TEST(suite, test_allies); - SUITE_ADD_TEST(suite, test_allies_clone); return suite; } From b0485ec57f46754cade2c0ab4baca1aac7e89ab0 Mon Sep 17 00:00:00 2001 From: Enno Rehling Date: Wed, 31 Oct 2018 17:54:40 +0100 Subject: [PATCH 116/160] eliminate struct ally, use struct allies --- src/creport.c | 6 +- src/kernel/ally.c | 149 +++++++++-------------------------------- src/kernel/ally.h | 37 +++++----- src/kernel/ally.test.c | 39 +++-------- src/kernel/faction.h | 2 +- src/kernel/group.c | 2 +- src/kernel/group.h | 2 +- src/laws.c | 2 +- src/report.c | 10 +-- 9 files changed, 69 insertions(+), 180 deletions(-) diff --git a/src/creport.c b/src/creport.c index 881edc870..69a9ed03e 100644 --- a/src/creport.c +++ b/src/creport.c @@ -1029,7 +1029,7 @@ struct print_ally_s { FILE *F; }; -static int print_ally_cb(struct ally *al, faction *af, int status, void *udata) { +static int print_ally_cb(struct allies *al, faction *af, int status, void *udata) { struct print_ally_s *data = (struct print_ally_s *)udata; UNUSED_ARG(al); @@ -1046,8 +1046,8 @@ static void show_allies_cr(FILE * F, const faction * f, const group *g) struct print_ally_s data; data.F = F; data.f = f; - struct ally *sf = g ? g->allies : f->allies; - ally_walk(sf, print_ally_cb, &data); + struct allies *sf = g ? g->allies : f->allies; + allies_walk(sf, print_ally_cb, &data); } /* prints allies */ diff --git a/src/kernel/ally.c b/src/kernel/ally.c index 1f57609c7..80ef6b18f 100644 --- a/src/kernel/ally.c +++ b/src/kernel/ally.c @@ -23,11 +23,11 @@ typedef struct allies { struct allies *next; int num; - const struct faction *factions[BLOCKSIZE]; + struct faction *factions[BLOCKSIZE]; int status[BLOCKSIZE]; } allies; -static void block_insert(allies *al, const struct faction *f, int status) { +static void block_insert(allies *al, struct faction *f, int status) { int i = al->num++; al->status[i] = status; al->factions[i] = f; @@ -45,7 +45,22 @@ static int block_search(allies *al, const struct faction *f) { return BLOCKSIZE; } -int allies_get(allies *al, const struct faction *f) +int allies_walk(struct allies *all, cb_allies_walk callback, void *udata) +{ + allies *al; + for (al = all; al; al = al->next) { + int i; + for (i = 0; i != al->num; ++i) { + int e = callback(all, al->factions[i], al->status[i], udata); + if (e != 0) { + return e; + } + } + } + return 0; +} + +int ally_get(allies *al, const struct faction *f) { for (; al; al = al->next) { int i = block_search(al, f); @@ -56,7 +71,7 @@ int allies_get(allies *al, const struct faction *f) return 0; } -void allies_set(allies **p_al, const struct faction *f, int status) +void ally_set(allies **p_al, struct faction *f, int status) { while (*p_al) { allies *al = *p_al; @@ -89,7 +104,7 @@ void allies_set(allies **p_al, const struct faction *f, int status) block_insert(*p_al, f, status); } -void allies_write(gamedata * data, const allies *alist) +void write_allies(gamedata * data, const allies *alist) { const allies *al; for (al = alist; al; al = al->next) { @@ -105,7 +120,7 @@ void allies_write(gamedata * data, const allies *alist) write_faction_reference(NULL, data->store); } -void allies_read(gamedata * data, allies **p_al) +void read_allies(gamedata * data, allies **p_al) { for (;;) { faction *f; @@ -118,103 +133,32 @@ void allies_read(gamedata * data, allies **p_al) f = findfaction(aid); if (!f) f = faction_create(aid); READ_INT(data->store, &status); - allies_set(p_al, f, status); + ally_set(p_al, f, status); } } -typedef struct ally { - struct ally *next; - struct faction *faction; - int status; -} ally; - -static ally * ally_add(ally **al_p, struct faction *f) { - ally * al; - while (*al_p) { - al = *al_p; - if (f && al->faction == f) return al; - al_p = &al->next; - } - al = (ally *)calloc(1, sizeof(ally)); - al->faction = f; - *al_p = al; - return al; -} - -void allies_free(ally *al) +void allies_free(allies *al) { while (al) { - ally * an = al->next; + allies * an = al->next; free(al); al = an; } } -ally *ally_clone(const ally *al) { - ally *al_clone = NULL, **al_end = &al_clone; +allies *allies_clone(const allies *al) { + allies *al_clone = NULL, **al_end = &al_clone; for (; al; al = al->next) { - if (al->faction) { - ally * al_new = ally_add(al_end, al->faction); - al_new->status = al->status; - al_end = &al_new->next; - } + allies *al_new = calloc(1, sizeof(allies)); + memcpy(al_new, al, sizeof(allies)); + *al_end = al_new; + al_end = &al_new->next; } + *al_end = NULL; return al_clone; } -int ally_walk(ally *allies, cb_ally_walk callback, void *udata) -{ - ally *al; - for (al = allies; al; al = al->next) { - int err = callback(allies, al->faction, al->status, udata); - if (err != 0) { - return err; - } - } - return 0; -} - -void write_allies(gamedata * data, const ally *alist) -{ - const ally *a; - for (a = alist; a; a = a->next) { - if (a->faction && a->faction->_alive) { - write_faction_reference(a->faction, data->store); - WRITE_INT(data->store, a->status); - } - } - write_faction_reference(NULL, data->store); -} - -void read_allies(gamedata * data, ally **sfp) -{ - for (;;) { - int aid; - READ_INT(data->store, &aid); - if (aid > 0) { - ally * al = ally_add(sfp, NULL); - int state; - if ((al->faction = findfaction(aid)) == NULL) { - al->faction = faction_create(aid); - } - READ_INT(data->store, &state); - al->status = state & HELP_ALL; - sfp = &al->next; - } - else { - break; - } - } -} - -ally * ally_find(ally *al, const struct faction *f) { - for (; al; al = al->next) { - if (al->faction == f) return al; - } - return 0; -} - static int ally_flag(const char *s, int help_mask) { if ((help_mask & HELP_MONEY) && strcmp(s, "money") == 0) @@ -349,7 +293,7 @@ int alliedgroup(const struct faction *f, const struct faction *f2, const struct group *g, int mask) { - ally *all = g ? g->allies : f->allies; + allies *all = g ? g->allies : f->allies; int status; if (!(faction_alive(f) && faction_alive(f2))) { @@ -399,32 +343,3 @@ int alliedunit(const unit * u, const faction * f2, int mask) return 0; } -void ally_set(ally **allies, struct faction *f, int status) { - ally *al; - while (*allies) { - al = *allies; - if (al->faction == f) { - if (status != 0) { - al->status = status; - } - else { - *allies = al->next; - free(al); - } - return; - } - allies = &al->next; - } - al = ally_add(allies, f); - al->status = status; -} - -int ally_get(ally *allies, const struct faction *f) { - ally *al; - for (al = allies; al; al = al->next) { - if (al->faction == f) { - return al->status; - } - } - return 0; -} diff --git a/src/kernel/ally.h b/src/kernel/ally.h index 25b488dac..3d9058bc4 100644 --- a/src/kernel/ally.h +++ b/src/kernel/ally.h @@ -23,31 +23,24 @@ OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. extern "C" { #endif - struct attrib_type; - struct faction; - struct group; - struct gamedata; - struct unit; - struct ally; - struct allies; +struct attrib_type; +struct faction; +struct group; +struct gamedata; +struct unit; +struct allies; - extern struct attrib_type at_npcfaction; +extern struct attrib_type at_npcfaction; - int allies_get(struct allies *al, const struct faction *f); - void allies_set(struct allies **p_al, const struct faction *f, int status); - void allies_write(struct gamedata * data, const struct allies *alist); - void allies_read(struct gamedata * data, struct allies **sfp); +int ally_get(struct allies *al, const struct faction *f); +void ally_set(struct allies **p_al, struct faction *f, int status); +void write_allies(struct gamedata * data, const struct allies *alist); +void read_allies(struct gamedata * data, struct allies **sfp); +typedef int (*cb_allies_walk)(struct allies *, struct faction *, int, void *); +int allies_walk(struct allies *allies, cb_allies_walk callback, void *udata); +struct allies *allies_clone(const struct allies *al); - void read_allies(struct gamedata * data, struct ally **alist); - void write_allies(struct gamedata * data, const struct ally *alist); - typedef int (*cb_ally_walk)(struct ally *, struct faction *, int, void *); - int ally_walk(struct ally *allies, cb_ally_walk callback, void *udata); - struct ally *ally_clone(const struct ally *al); - void allies_free(struct ally *al); - - struct ally* ally_find(struct ally*al, const struct faction *f); - void ally_set(struct ally**al_p, struct faction *f, int status); - int ally_get(struct ally *al, const struct faction *f); +void allies_free(struct allies *al); int AllianceAuto(void); /* flags that allied factions get automatically */ int HelpMask(void); /* flags restricted to allied factions */ diff --git a/src/kernel/ally.test.c b/src/kernel/ally.test.c index 0b17870bb..248eb5831 100644 --- a/src/kernel/ally.test.c +++ b/src/kernel/ally.test.c @@ -5,35 +5,17 @@ #include #include -static void test_ally(CuTest * tc) +static void test_allies_clone(CuTest * tc) { - struct ally * al = NULL; + struct allies * al = NULL, *ac; struct faction * f; test_setup(); f = test_create_faction(NULL); - ally_set(&al, f, HELP_GUARD); - CuAssertPtrNotNull(tc, al); - CuAssertIntEquals(tc, HELP_GUARD, ally_get(al, f)); - - ally_set(&al, f, 0); - CuAssertPtrEquals(tc, NULL, al); - CuAssertIntEquals(tc, 0, ally_get(al, f)); - allies_free(al); - test_teardown(); -} - -static void test_ally_clone(CuTest * tc) -{ - struct ally * al = NULL, *ac; - struct faction * f; - - test_setup(); - f = test_create_faction(NULL); - CuAssertPtrEquals(tc, NULL, ally_clone(NULL)); + CuAssertPtrEquals(tc, NULL, allies_clone(NULL)); ally_set(&al, f, HELP_GUARD); - ac = ally_clone(al); + ac = allies_clone(al); CuAssertPtrNotNull(tc, ac); CuAssertTrue(tc, al != ac); CuAssertIntEquals(tc, HELP_GUARD, ally_get(ac, f)); @@ -50,11 +32,11 @@ static void test_allies(CuTest *tc) { test_setup(); f = test_create_faction(NULL); - CuAssertIntEquals(tc, 0, allies_get(al, f)); - allies_set(&al, f, 42); - CuAssertIntEquals(tc, 42, allies_get(al, f)); - allies_set(&al, f, 0); - CuAssertIntEquals(tc, 0, allies_get(al, f)); + CuAssertIntEquals(tc, 0, ally_get(al, f)); + ally_set(&al, f, 42); + CuAssertIntEquals(tc, 42, ally_get(al, f)); + ally_set(&al, f, 0); + CuAssertIntEquals(tc, 0, ally_get(al, f)); CuAssertPtrEquals(tc, NULL, al); test_teardown(); } @@ -62,9 +44,8 @@ static void test_allies(CuTest *tc) { CuSuite *get_ally_suite(void) { CuSuite *suite = CuSuiteNew(); - SUITE_ADD_TEST(suite, test_ally); - SUITE_ADD_TEST(suite, test_ally_clone); SUITE_ADD_TEST(suite, test_allies); + SUITE_ADD_TEST(suite, test_allies_clone); return suite; } diff --git a/src/kernel/faction.h b/src/kernel/faction.h index caa908da5..04070c91a 100644 --- a/src/kernel/faction.h +++ b/src/kernel/faction.h @@ -86,7 +86,7 @@ extern "C" { int num_people; /* Anzahl Personen ohne Monster */ int num_units; int options; - struct ally *allies; /* alliedgroup and others should check sf.faction.alive before using a faction from f.allies */ + struct allies *allies; /* alliedgroup and others should check sf.faction.alive before using a faction from f.allies */ struct group *groups; /* alliedgroup and others should check sf.faction.alive before using a faction from f.groups */ score_t score; struct alliance *alliance; diff --git a/src/kernel/group.c b/src/kernel/group.c index 9e91d17a1..210f6e0f2 100755 --- a/src/kernel/group.c +++ b/src/kernel/group.c @@ -69,7 +69,7 @@ group *new_group(faction * f, const char *name, int gid) static void init_group(faction * f, group * g) { - g->allies = ally_clone(f->allies); + g->allies = allies_clone(f->allies); } static group *find_groupbyname(group * g, const char *name) diff --git a/src/kernel/group.h b/src/kernel/group.h index b66e3f50b..9b6d97cf9 100755 --- a/src/kernel/group.h +++ b/src/kernel/group.h @@ -30,7 +30,7 @@ extern "C" { struct faction *f; struct attrib *attribs; char *name; - struct ally *allies; + struct allies *allies; int gid; int members; } group; diff --git a/src/laws.c b/src/laws.c index 61eac6a0b..775bd78a0 100644 --- a/src/laws.c +++ b/src/laws.c @@ -1290,7 +1290,7 @@ void quit(void) int ally_cmd(unit * u, struct order *ord) { char token[128]; - struct ally **sfp; + struct allies **sfp; faction *f; int keyword, not_kw; const char *s; diff --git a/src/report.c b/src/report.c index f641534f1..b6ed3f736 100644 --- a/src/report.c +++ b/src/report.c @@ -1511,7 +1511,7 @@ report_template(const char *filename, report_context * ctx, const char *bom) return 0; } -static int count_allies_cb(struct ally *all, faction *af, int status, void *udata) { +static int count_allies_cb(struct allies *all, faction *af, int status, void *udata) { int *num = (int *)udata; if (status > 0) { ++*num; @@ -1525,7 +1525,7 @@ struct show_s { int num_allies; }; -static int show_allies_cb(struct ally *all, faction *af, int status, void *udata) { +static int show_allies_cb(struct allies *all, faction *af, int status, void *udata) { struct show_s * show = (struct show_s *)udata; const faction * f = show->f; @@ -1585,10 +1585,10 @@ static int show_allies_cb(struct ally *all, faction *af, int status, void *udata } static void -show_allies(const faction * f, struct ally * allies, char *buf, size_t size) +show_allies(const faction * f, struct allies * allies, char *buf, size_t size) { int num_allies = 0; - ally_walk(allies, count_allies_cb, &num_allies); + allies_walk(allies, count_allies_cb, &num_allies); if (num_allies > 0) { struct show_s show; @@ -1596,7 +1596,7 @@ show_allies(const faction * f, struct ally * allies, char *buf, size_t size) show.num_allies = num_allies; sbs_init(&show.sbs, buf, size); - ally_walk(allies, show_allies_cb, &show); + allies_walk(allies, show_allies_cb, &show); sbs_strcat(&show.sbs, "."); } } From d9167b8a5919f97a78afd7e24c36bbb5d5b0ae09 Mon Sep 17 00:00:00 2001 From: Enno Rehling Date: Thu, 1 Nov 2018 09:53:23 +0100 Subject: [PATCH 117/160] do not use late resolution for factions, ever --- src/attributes/attributes.c | 2 +- src/kernel/faction.c | 11 ++--------- src/kernel/faction.h | 5 +---- src/kernel/save.c | 7 +++---- src/triggers/changefaction.c | 2 +- src/triggers/createunit.c | 2 +- 6 files changed, 9 insertions(+), 20 deletions(-) diff --git a/src/attributes/attributes.c b/src/attributes/attributes.c index 400282ae7..12cb9131f 100644 --- a/src/attributes/attributes.c +++ b/src/attributes/attributes.c @@ -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; diff --git a/src/kernel/faction.c b/src/kernel/faction.c index 9265d4a8e..f36ef5f8c 100755 --- a/src/kernel/faction.c +++ b/src/kernel/faction.c @@ -54,7 +54,6 @@ OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. #include #include #include -#include #include #include #include @@ -331,20 +330,14 @@ bool checkpasswd(const faction * f, const char *passwd) return true; } -void resolve_faction(faction *f) -{ - resolve(RESOLVE_FACTION | f->no, f); -} - -int read_faction_reference(gamedata * data, faction **fp, resolve_fun fun) +int read_faction_reference(gamedata * data, faction **fp) { int id; READ_INT(data->store, &id); if (id > 0) { *fp = findfaction(id); if (*fp == NULL) { - *fp = NULL; - ur_add(RESOLVE_FACTION | id, (void **)fp, fun); + *fp = faction_create(id); } } else { diff --git a/src/kernel/faction.h b/src/kernel/faction.h index 04070c91a..0c579603a 100644 --- a/src/kernel/faction.h +++ b/src/kernel/faction.h @@ -133,10 +133,7 @@ extern "C" { void write_faction_reference(const struct faction *f, struct storage *store); - int read_faction_reference(struct gamedata *data, struct faction **fp, resolve_fun fun); - -#define RESOLVE_FACTION (TYP_FACTION << 24) - void resolve_faction(struct faction *f); + int read_faction_reference(struct gamedata *data, struct faction **fp); void renumber_faction(faction * f, int no); void free_factions(void); diff --git a/src/kernel/save.c b/src/kernel/save.c index 8c4b408c9..928c1938a 100644 --- a/src/kernel/save.c +++ b/src/kernel/save.c @@ -123,7 +123,7 @@ static void read_alliances(gamedata *data) READ_INT(store, &al->flags); } if (data->version >= ALLIANCELEADER_VERSION) { - read_faction_reference(data, &al->_leader, NULL); + read_faction_reference(data, &al->_leader); READ_INT(store, &id); } else { @@ -248,7 +248,7 @@ static void read_owner(gamedata *data, region_owner ** powner) owner->flags = 0; } if (data->version >= OWNER_3_VERSION) { - read_faction_reference(data, &owner->last_owner, NULL); + read_faction_reference(data, &owner->last_owner); } else if (data->version >= OWNER_2_VERSION) { int id; @@ -261,7 +261,7 @@ static void read_owner(gamedata *data, region_owner ** powner) else { owner->last_owner = NULL; } - read_faction_reference(data, &owner->owner, NULL); + read_faction_reference(data, &owner->owner); *powner = owner; } else { @@ -1087,7 +1087,6 @@ faction *read_faction(gamedata * data) if (data->version >= REGIONOWNER_VERSION) { read_spellbook(FactionSpells() ? &f->spellbook : 0, data, get_spell_level_faction, (void *)f); } - resolve_faction(f); return f; } diff --git a/src/triggers/changefaction.c b/src/triggers/changefaction.c index 8aa73168d..8b1ead479 100644 --- a/src/triggers/changefaction.c +++ b/src/triggers/changefaction.c @@ -87,7 +87,7 @@ static int changefaction_read(trigger * t, gamedata *data) changefaction_data *td = (changefaction_data *)t->data.v; read_unit_reference(data, &td->unit, NULL); - return read_faction_reference(data, &td->faction, NULL) > 0 ? AT_READ_OK : AT_READ_FAIL; + return read_faction_reference(data, &td->faction) > 0 ? AT_READ_OK : AT_READ_FAIL; } trigger_type tt_changefaction = { diff --git a/src/triggers/createunit.c b/src/triggers/createunit.c index d4dd8f983..5adabc7ea 100644 --- a/src/triggers/createunit.c +++ b/src/triggers/createunit.c @@ -94,7 +94,7 @@ static int createunit_read(trigger * t, gamedata *data) int id; int result = AT_READ_OK; - id = read_faction_reference(data, &td->f, NULL); + id = read_faction_reference(data, &td->f); if (id <= 0) { result = AT_READ_FAIL; } From 85fe80d858d9939b0097533d70df9a8031468d89 Mon Sep 17 00:00:00 2001 From: Enno Rehling Date: Thu, 1 Nov 2018 10:16:49 +0100 Subject: [PATCH 118/160] unit_create function instead of wild calloc calls. --- src/kernel/save.c | 5 +---- src/kernel/unit.c | 12 +++++++----- src/kernel/unit.h | 7 ++++--- 3 files changed, 12 insertions(+), 12 deletions(-) diff --git a/src/kernel/save.c b/src/kernel/save.c index 928c1938a..ceaf78ee1 100644 --- a/src/kernel/save.c +++ b/src/kernel/save.c @@ -420,10 +420,7 @@ unit *read_unit(gamedata *data) u_setfaction(u, NULL); } else { - u = (unit *)calloc(1, sizeof(unit)); - assert_alloc(u); - u->no = n; - uhash(u); + u = unit_create(n); } READ_INT(data->store, &n); diff --git a/src/kernel/unit.c b/src/kernel/unit.c index d0737eaba..8b2248d39 100644 --- a/src/kernel/unit.c +++ b/src/kernel/unit.c @@ -1375,6 +1375,12 @@ void name_unit(unit * u) } } +unit *unit_create(int id) +{ + unit *u = (unit *)calloc(1, sizeof(unit)); + createunitid(u, id); + return u; +} /** creates a new unit. * * @param dname: name, set to NULL to get a default. @@ -1383,7 +1389,7 @@ void name_unit(unit * u) unit *create_unit(region * r, faction * f, int number, const struct race *urace, int id, const char *dname, unit * creator) { - unit *u = (unit *)calloc(1, sizeof(unit)); + unit *u = unit_create(id); assert(urace); u_setrace(u, urace); @@ -1395,10 +1401,6 @@ unit *create_unit(region * r, faction * f, int number, const struct race *urace, set_number(u, number); - /* die nummer der neuen einheit muss vor name_unit generiert werden, - * da der default name immer noch 'Nummer u->no' ist */ - createunitid(u, id); - /* zuerst in die Region setzen, da zb Drachennamen den Regionsnamen * enthalten */ if (r) diff --git a/src/kernel/unit.h b/src/kernel/unit.h index 86c2e2e61..e08ca1ef3 100644 --- a/src/kernel/unit.h +++ b/src/kernel/unit.h @@ -206,10 +206,11 @@ extern "C" { int invisible(const struct unit *target, const struct unit *viewer); void free_unit(struct unit *u); - extern void name_unit(struct unit *u); - extern struct unit *create_unit(struct region *r1, struct faction *f, + void name_unit(struct unit *u); + struct unit *unit_create(int id); + struct unit *create_unit(struct region *r1, struct faction *f, int number, const struct race *rc, int id, const char *dname, - struct unit *creator); + struct unit *creator); void uhash(struct unit *u); void uunhash(struct unit *u); From ba9af6d765eb250ababad9bc4f67b7e80761eb0b Mon Sep 17 00:00:00 2001 From: Enno Rehling Date: Thu, 1 Nov 2018 21:08:59 +0100 Subject: [PATCH 119/160] 1. region_create(uid) 2. read_region_reference never gets a callback, so save it. --- src/attributes/targetregion.c | 2 +- src/kernel/curse.c | 2 +- src/kernel/region.c | 33 ++++++++++++++++++--------------- src/kernel/region.h | 3 ++- src/triggers/createunit.c | 2 +- src/triggers/gate.c | 2 +- src/wormhole.c | 2 +- 7 files changed, 25 insertions(+), 21 deletions(-) diff --git a/src/attributes/targetregion.c b/src/attributes/targetregion.c index 600d2e184..4f5a2101a 100644 --- a/src/attributes/targetregion.c +++ b/src/attributes/targetregion.c @@ -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/kernel/curse.c b/src/kernel/curse.c index 62e7ab9b2..bf3c8fef0 100644 --- a/src/kernel/curse.c +++ b/src/kernel/curse.c @@ -229,7 +229,7 @@ int curse_read(variant *var, void *owner, gamedata *data) READ_INT(store, &c->data.i); } if (c->type->typ == CURSETYP_REGION) { - int rr = read_region_reference(data, (region **)&c->data.v, NULL); + int rr = read_region_reference(data, (region **)&c->data.v); if (ur == 0 && rr == 0 && !c->data.v) { return AT_READ_FAIL; } diff --git a/src/kernel/region.c b/src/kernel/region.c index fee51d13c..192469b8e 100644 --- a/src/kernel/region.c +++ b/src/kernel/region.c @@ -242,7 +242,7 @@ static void unhash_uid(region * r) uidhash[key].r = NULL; } -static void hash_uid(region * r) +static void rhash_uid(region * r) { int uid = r->uid; for (;;) { @@ -761,32 +761,35 @@ static region *last; static unsigned int max_index = 0; +region *region_create(int uid) +{ + region *r = (region *)calloc(1, sizeof(region)); + assert_alloc(r); + r->uid = uid; + rhash_uid(r); + return r; +} + region *new_region(int x, int y, struct plane *pl, int uid) { region *r; pnormalize(&x, &y, pl); r = rfindhash(x, y); - - if (r) { - log_error("duplicate region discovered: %s(%d,%d)\n", regionname(r, NULL), x, y); - if (r->units) - log_error("duplicate region contains units\n"); - return r; + if (!r) { + r = region_create(uid); } - r = (region *)calloc(sizeof(region), 1); - assert_alloc(r); r->x = x; r->y = y; - r->uid = uid; r->age = 1; r->_plane = pl; rhash(r); - hash_uid(r); - if (last) + if (last) { addlist(&last, r); - else + } + else { addlist(®ions, r); + } last = r; assert(r->next == NULL); r->index = ++max_index; @@ -1263,7 +1266,7 @@ void resolve_region(region *r) resolve(RESOLVE_REGION | r->uid, r); } -int read_region_reference(gamedata * data, region **rp, resolve_fun fun) +int read_region_reference(gamedata * data, region **rp) { struct storage * store = data->store; int id = 0; @@ -1271,7 +1274,7 @@ int read_region_reference(gamedata * data, region **rp, resolve_fun fun) READ_INT(store, &id); *rp = findregionbyid(id); if (*rp == NULL) { - ur_add(RESOLVE_REGION | id, (void **)rp, fun); + ur_add(RESOLVE_REGION | id, (void **)rp, NULL); } return id; } diff --git a/src/kernel/region.h b/src/kernel/region.h index bf932e9c3..436434024 100644 --- a/src/kernel/region.h +++ b/src/kernel/region.h @@ -225,6 +225,7 @@ extern "C" { const char *write_regionname(const struct region *r, const struct faction *f, char *buffer, size_t size); + struct region *region_create(int uid); struct region *new_region(int x, int y, struct plane *pl, int uid); void remove_region(region ** rlist, region * r); void terraform_region(struct region *r, const struct terrain_type *terrain); @@ -252,7 +253,7 @@ extern "C" { #define RESOLVE_REGION (TYP_REGION << 24) void resolve_region(region *r); void write_region_reference(const struct region *r, struct storage *store); - int read_region_reference(struct gamedata *data, region **rp, resolve_fun fun); + int read_region_reference(struct gamedata *data, region **rp); const char *regionname(const struct region *r, const struct faction *f); diff --git a/src/triggers/createunit.c b/src/triggers/createunit.c index 5adabc7ea..82155de55 100644 --- a/src/triggers/createunit.c +++ b/src/triggers/createunit.c @@ -99,7 +99,7 @@ static int createunit_read(trigger * t, gamedata *data) result = AT_READ_FAIL; } - read_region_reference(data, &td->r, NULL); + read_region_reference(data, &td->r); td->race = read_race_reference(data->store); if (!td->race) { result = AT_READ_FAIL; diff --git a/src/triggers/gate.c b/src/triggers/gate.c index 065be8cf8..bd67e56f4 100644 --- a/src/triggers/gate.c +++ b/src/triggers/gate.c @@ -76,7 +76,7 @@ static int gate_read(trigger * t, gamedata *data) { gate_data *gd = (gate_data *)t->data.v; int bc = read_building_reference(data, &gd->gate, NULL); - int rc = read_region_reference(data, &gd->target, NULL); + int rc = read_region_reference(data, &gd->target); if (bc <= 0 && rc <= 0) { return AT_READ_FAIL; diff --git a/src/wormhole.c b/src/wormhole.c index 382e64d16..1ce6686c9 100644 --- a/src/wormhole.c +++ b/src/wormhole.c @@ -103,7 +103,7 @@ static int wormhole_read(variant *var, void *owner, struct gamedata *data) if (data->version < ATTRIBOWNER_VERSION) { READ_INT(data->store, NULL); } - id = read_region_reference(data, (region **)&var->v, NULL); + id = read_region_reference(data, (region **)&var->v); return (id <= 0) ? AT_READ_FAIL : AT_READ_OK; } From fc4f32f8e0044d5d62d4947906b78659002c4be2 Mon Sep 17 00:00:00 2001 From: Enno Rehling Date: Thu, 1 Nov 2018 21:13:05 +0100 Subject: [PATCH 120/160] read_building_reference does not need a callback --- src/kernel/building.c | 4 ++-- src/kernel/building.h | 2 +- src/modules/xmas.c | 2 +- src/triggers/gate.c | 2 +- 4 files changed, 5 insertions(+), 5 deletions(-) diff --git a/src/kernel/building.c b/src/kernel/building.c index 3a3d7e4e5..8cbe5c180 100644 --- a/src/kernel/building.c +++ b/src/kernel/building.c @@ -359,7 +359,7 @@ void resolve_building(building *b) resolve(RESOLVE_BUILDING | b->no, b); } -int read_building_reference(gamedata * data, building **bp, resolve_fun fun) +int read_building_reference(gamedata * data, building **bp) { int id; READ_INT(data->store, &id); @@ -367,7 +367,7 @@ int read_building_reference(gamedata * data, building **bp, resolve_fun fun) *bp = findbuilding(id); if (*bp == NULL) { *bp = NULL; - ur_add(RESOLVE_BUILDING | id, (void**)bp, fun); + ur_add(RESOLVE_BUILDING | id, (void**)bp, NULL); } } else { diff --git a/src/kernel/building.h b/src/kernel/building.h index af605b448..2a0a77cde 100644 --- a/src/kernel/building.h +++ b/src/kernel/building.h @@ -166,7 +166,7 @@ extern "C" { void resolve_building(building *b); void write_building_reference(const struct building *b, struct storage *store); - int read_building_reference(struct gamedata * data, struct building **bp, resolve_fun fun); + int read_building_reference(struct gamedata * data, struct building **bp); struct building *findbuilding(int n); diff --git a/src/modules/xmas.c b/src/modules/xmas.c index aa296866a..a8b87026a 100644 --- a/src/modules/xmas.c +++ b/src/modules/xmas.c @@ -50,7 +50,7 @@ static void xmasgate_write(const trigger * t, struct storage *store) static int xmasgate_read(trigger * t, struct gamedata *data) { - if (read_building_reference(data, (building **)&t->data.v, NULL) <= 0) { + if (read_building_reference(data, (building **)&t->data.v) <= 0) { return AT_READ_FAIL; } return AT_READ_OK; diff --git a/src/triggers/gate.c b/src/triggers/gate.c index bd67e56f4..ac3e44b88 100644 --- a/src/triggers/gate.c +++ b/src/triggers/gate.c @@ -75,7 +75,7 @@ static void gate_write(const trigger * t, struct storage *store) static int gate_read(trigger * t, gamedata *data) { gate_data *gd = (gate_data *)t->data.v; - int bc = read_building_reference(data, &gd->gate, NULL); + int bc = read_building_reference(data, &gd->gate); int rc = read_region_reference(data, &gd->target); if (bc <= 0 && rc <= 0) { From 25b5f797e9627042dc97aa130389944f992d46cb Mon Sep 17 00:00:00 2001 From: Enno Rehling Date: Thu, 1 Nov 2018 21:18:24 +0100 Subject: [PATCH 121/160] add building_create, too --- src/kernel/building.c | 17 +++++++++++------ src/kernel/building.h | 3 ++- 2 files changed, 13 insertions(+), 7 deletions(-) diff --git a/src/kernel/building.c b/src/kernel/building.c index 8cbe5c180..456ad1704 100644 --- a/src/kernel/building.c +++ b/src/kernel/building.c @@ -366,8 +366,7 @@ int read_building_reference(gamedata * data, building **bp) if (id > 0) { *bp = findbuilding(id); if (*bp == NULL) { - *bp = NULL; - ur_add(RESOLVE_BUILDING | id, (void**)bp, NULL); + *bp = building_create(id); } } else { @@ -376,17 +375,23 @@ int read_building_reference(gamedata * data, building **bp) return id; } +building *building_create(int id) +{ + building *b = (building *)calloc(1, sizeof(building)); + b->no = id; + bhash(b); + return b; +} + building *new_building(const struct building_type * btype, region * r, const struct locale * lang) { building **bptr = &r->buildings; - building *b = (building *)calloc(1, sizeof(building)); + int id = newcontainerid(); + building *b = building_create(id); const char *bname; char buffer[32]; - b->no = newcontainerid(); - bhash(b); - b->type = btype; b->region = r; while (*bptr) diff --git a/src/kernel/building.h b/src/kernel/building.h index 2a0a77cde..a5419325f 100644 --- a/src/kernel/building.h +++ b/src/kernel/building.h @@ -127,8 +127,9 @@ extern "C" { const char *write_buildingname(const building * b, char *ibuf, size_t size); int buildingcapacity(const struct building *b); + struct building *building_create(int id); struct building *new_building(const struct building_type *typ, - struct region *r, const struct locale *lang); + struct region *r, const struct locale *lang); int build_building(struct unit *u, const struct building_type *typ, int id, int size, struct order *ord); bool building_finished(const struct building *b); From a2fe396b68e9406e0f78bd8a4a3b902637300660 Mon Sep 17 00:00:00 2001 From: Enno Rehling Date: Thu, 1 Nov 2018 21:20:11 +0100 Subject: [PATCH 122/160] do not delayed-resolve regions --- src/kernel/region.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/kernel/region.c b/src/kernel/region.c index 192469b8e..f665811d7 100644 --- a/src/kernel/region.c +++ b/src/kernel/region.c @@ -1274,7 +1274,7 @@ int read_region_reference(gamedata * data, region **rp) READ_INT(store, &id); *rp = findregionbyid(id); if (*rp == NULL) { - ur_add(RESOLVE_REGION | id, (void **)rp, NULL); + *rp = region_create(id); } return id; } From 272588cb0f3771b041c23eeaf0056a2a6e150194 Mon Sep 17 00:00:00 2001 From: Enno Rehling Date: Fri, 2 Nov 2018 22:31:20 +0100 Subject: [PATCH 123/160] BUG 2509: fix travelthru faction reporting --- src/reports.c | 3 +-- src/reports.test.c | 22 ++++++++++++++++++---- 2 files changed, 19 insertions(+), 6 deletions(-) diff --git a/src/reports.c b/src/reports.c index 12154b70d..dbea67489 100644 --- a/src/reports.c +++ b/src/reports.c @@ -916,7 +916,7 @@ bufunit(const faction * f, const unit * u, seen_mode mode, char *buf, } if (!isbattle) { int printed = 0; - order *ord;; + order *ord; for (ord = u->old_orders; ord; ord = ord->next) { keyword_t kwd = getkeyword(ord); if (is_repeated(kwd)) { @@ -1133,7 +1133,6 @@ static void cb_add_address(region *r, unit *ut, void *cbdata) { if (data->lastf != sf && cansee_unit(ut, u, data->stealthmod)) { add_seen_faction_i(data->flist, sf); data->lastf = sf; - break; } } } diff --git a/src/reports.test.c b/src/reports.test.c index 247676451..b1cf36d99 100644 --- a/src/reports.test.c +++ b/src/reports.test.c @@ -440,22 +440,34 @@ static void test_get_addresses_fstealth(CuTest *tc) { static void test_get_addresses_travelthru(CuTest *tc) { report_context ctx; - faction *f, *f2, *f1; + faction *f, *f4, *f3, *f2, *f1; region *r1, *r2; unit *u; + race *rc; test_setup(); f = test_create_faction(NULL); - f1 = test_create_faction(NULL); - f2 = test_create_faction(NULL); r1 = test_create_region(0, 0, NULL); r2 = test_create_region(1, 0, 0); u = test_create_unit(f, r2); travelthru_add(r1, u); + + f1 = test_create_faction(NULL); u = test_create_unit(f1, r1); + f2 = test_create_faction(NULL); set_factionstealth(u, f2); u->building = test_create_building(u->region, test_create_buildingtype("tower")); + rc = rc_get_or_create("dragon"); + rc->flags |= RCF_UNARMEDGUARD; + f3 = test_create_faction(rc); + u = test_create_unit(f3, r1); + setguard(u, true); + + f4 = test_create_faction(NULL); + u = test_create_unit(f4, r1); + set_level(u, SK_STEALTH, 1); + prepare_report(&ctx, f); CuAssertPtrEquals(tc, r1, ctx.first); CuAssertPtrEquals(tc, NULL, ctx.last); @@ -464,7 +476,9 @@ static void test_get_addresses_travelthru(CuTest *tc) { CuAssertTrue(tc, selist_contains(ctx.addresses, f, NULL)); CuAssertTrue(tc, !selist_contains(ctx.addresses, f1, NULL)); CuAssertTrue(tc, selist_contains(ctx.addresses, f2, NULL)); - CuAssertIntEquals(tc, 2, selist_length(ctx.addresses)); + CuAssertTrue(tc, selist_contains(ctx.addresses, f3, NULL)); + CuAssertTrue(tc, !selist_contains(ctx.addresses, f4, NULL)); + CuAssertIntEquals(tc, 3, selist_length(ctx.addresses)); finish_reports(&ctx); test_teardown(); } From dc08ba5e9854a7dce543bc039d0af3a61d30af70 Mon Sep 17 00:00:00 2001 From: Enno Rehling Date: Sat, 3 Nov 2018 13:51:10 +0100 Subject: [PATCH 124/160] bug 2510 duplicate region after datafile read --- scripts/eressea/tunnels.lua | 1 + src/kernel/region.c | 5 +---- src/kernel/save.c | 4 ++-- 3 files changed, 4 insertions(+), 6 deletions(-) diff --git a/scripts/eressea/tunnels.lua b/scripts/eressea/tunnels.lua index 4a787a373..b0b3fe2a3 100644 --- a/scripts/eressea/tunnels.lua +++ b/scripts/eressea/tunnels.lua @@ -27,6 +27,7 @@ end local function tunnel_action(b, param) local units = tunnel_travelers(b) local rto = get_target(param) + print("tunnel from " .. tostring(b.region) .. " to " .. tostring(rto)) if rto and units then eressea.log.debug("Tunnel from " .. tostring(b) .. " [" .. param .. "]") for key, u in pairs(units) do diff --git a/src/kernel/region.c b/src/kernel/region.c index f665811d7..bcae52e35 100644 --- a/src/kernel/region.c +++ b/src/kernel/region.c @@ -775,10 +775,7 @@ region *new_region(int x, int y, struct plane *pl, int uid) region *r; pnormalize(&x, &y, pl); - r = rfindhash(x, y); - if (!r) { - r = region_create(uid); - } + r = region_create(uid); r->x = x; r->y = y; r->age = 1; diff --git a/src/kernel/save.c b/src/kernel/save.c index ceaf78ee1..c2879bf0e 100644 --- a/src/kernel/save.c +++ b/src/kernel/save.c @@ -614,7 +614,7 @@ static void read_regioninfo(gamedata *data, const region *r, char *info, size_t static region *readregion(gamedata *data, int x, int y) { - region *r = findregion(x, y); + region *r; const terrain_type *terrain; char name[NAMESIZE]; char info[DISPLAYSIZE]; @@ -622,7 +622,7 @@ static region *readregion(gamedata *data, int x, int y) int n; READ_INT(data->store, &uid); - + r = findregionbyid(uid); if (r == NULL) { plane *pl = findplane(x, y); r = new_region(x, y, pl, uid); From 6c11e740ff40a0a19f15167659f3336ba8e3a68d Mon Sep 17 00:00:00 2001 From: Enno Rehling Date: Sat, 3 Nov 2018 14:28:32 +0100 Subject: [PATCH 125/160] bug 2510 duplicate region after datafile read --- src/kernel/region.c | 5 +---- src/kernel/save.c | 4 ++-- 2 files changed, 3 insertions(+), 6 deletions(-) diff --git a/src/kernel/region.c b/src/kernel/region.c index f665811d7..bcae52e35 100644 --- a/src/kernel/region.c +++ b/src/kernel/region.c @@ -775,10 +775,7 @@ region *new_region(int x, int y, struct plane *pl, int uid) region *r; pnormalize(&x, &y, pl); - r = rfindhash(x, y); - if (!r) { - r = region_create(uid); - } + r = region_create(uid); r->x = x; r->y = y; r->age = 1; diff --git a/src/kernel/save.c b/src/kernel/save.c index ceaf78ee1..c2879bf0e 100644 --- a/src/kernel/save.c +++ b/src/kernel/save.c @@ -614,7 +614,7 @@ static void read_regioninfo(gamedata *data, const region *r, char *info, size_t static region *readregion(gamedata *data, int x, int y) { - region *r = findregion(x, y); + region *r; const terrain_type *terrain; char name[NAMESIZE]; char info[DISPLAYSIZE]; @@ -622,7 +622,7 @@ static region *readregion(gamedata *data, int x, int y) int n; READ_INT(data->store, &uid); - + r = findregionbyid(uid); if (r == NULL) { plane *pl = findplane(x, y); r = new_region(x, y, pl, uid); From 8bcdb5c38136ff36b970ae83dd67c8008de804d0 Mon Sep 17 00:00:00 2001 From: Enno Rehling Date: Sat, 3 Nov 2018 15:48:35 +0100 Subject: [PATCH 126/160] Bug 2509 contd: new_region still creating duplicates --- src/bind_region.c | 2 +- src/bindings.c | 2 +- src/kernel/region.c | 30 ++++++++++++++++-------------- src/kernel/region.h | 3 ++- src/kernel/save.c | 23 ++++++++--------------- 5 files changed, 28 insertions(+), 32 deletions(-) diff --git a/src/bind_region.c b/src/bind_region.c index 9d7897829..86c072a84 100644 --- a/src/bind_region.c +++ b/src/bind_region.c @@ -448,7 +448,7 @@ static int tolua_region_create(lua_State * L) return 0; } - assert(!pnormalize(&x, &y, pl)); + pnormalize(&x, &y, pl); r = result = findregion(x, y); if (r != NULL && r->units != NULL) { diff --git a/src/bindings.c b/src/bindings.c index caac5b99c..e60b7fe78 100755 --- a/src/bindings.c +++ b/src/bindings.c @@ -481,7 +481,7 @@ static int tolua_get_region(lua_State * L) int x = (int)tolua_tonumber(L, 1, 0); int y = (int)tolua_tonumber(L, 2, 0); region *r; - assert(!pnormalize(&x, &y, findplane(x, y))); + pnormalize(&x, &y, findplane(x, y)); r = findregion(x, y); tolua_pushusertype(L, r, TOLUA_CAST "region"); return 1; diff --git a/src/kernel/region.c b/src/kernel/region.c index bcae52e35..60baed49d 100644 --- a/src/kernel/region.c +++ b/src/kernel/region.c @@ -268,7 +268,7 @@ static int hash_requests; static int hash_misses; #endif -bool pnormalize(int *x, int *y, const plane * pl) +void pnormalize(int *x, int *y, const plane * pl) { if (pl) { if (x) { @@ -284,7 +284,6 @@ bool pnormalize(int *x, int *y, const plane * pl) *y = ny % height + pl->miny; } } - return false; /* TBD */ } static region *rfindhash(int x, int y) @@ -343,8 +342,9 @@ region *r_connect(const region * r, direction_t dir) int x, y; region *rmodify = (region *)r; assert(dir >= 0 && dir < MAXDIRECTIONS); - if (r->connect[dir]) + if (r->connect[dir]) { return r->connect[dir]; + } assert(dir < MAXDIRECTIONS); x = r->x + delta_x[dir]; y = r->y + delta_y[dir]; @@ -757,10 +757,6 @@ int rsettrees(const region * r, int ageclass, int value) return 0; } -static region *last; - -static unsigned int max_index = 0; - region *region_create(int uid) { region *r = (region *)calloc(1, sizeof(region)); @@ -770,16 +766,13 @@ region *region_create(int uid) return r; } -region *new_region(int x, int y, struct plane *pl, int uid) -{ - region *r; +static region *last; +static unsigned int max_index; - pnormalize(&x, &y, pl); - r = region_create(uid); +void add_region(region *r, int x, int y) { r->x = x; r->y = y; - r->age = 1; - r->_plane = pl; + r->_plane = findplane(x, y); rhash(r); if (last) { addlist(&last, r); @@ -790,6 +783,15 @@ region *new_region(int x, int y, struct plane *pl, int uid) last = r; assert(r->next == NULL); r->index = ++max_index; +} + +region *new_region(int x, int y, struct plane *pl, int uid) +{ + region *r; + r = region_create(uid); + r->age = 1; + add_region(r, x, y); + assert(pl == r->_plane); return r; } diff --git a/src/kernel/region.h b/src/kernel/region.h index 436434024..e4982406e 100644 --- a/src/kernel/region.h +++ b/src/kernel/region.h @@ -226,11 +226,12 @@ extern "C" { char *buffer, size_t size); struct region *region_create(int uid); + void add_region(region *r, int x, int y); struct region *new_region(int x, int y, struct plane *pl, int uid); void remove_region(region ** rlist, region * r); void terraform_region(struct region *r, const struct terrain_type *terrain); void init_region(struct region *r); - bool pnormalize(int *x, int *y, const struct plane *pl); + void pnormalize(int *x, int *y, const struct plane *pl); extern const int delta_x[MAXDIRECTIONS]; extern const int delta_y[MAXDIRECTIONS]; diff --git a/src/kernel/save.c b/src/kernel/save.c index c2879bf0e..1d67c2860 100644 --- a/src/kernel/save.c +++ b/src/kernel/save.c @@ -624,24 +624,17 @@ static region *readregion(gamedata *data, int x, int y) READ_INT(data->store, &uid); r = findregionbyid(uid); if (r == NULL) { - plane *pl = findplane(x, y); - r = new_region(x, y, pl, uid); + r = region_create(uid); } else { - assert(uid == 0 || r->uid == uid); - while (r->attribs) - a_remove(&r->attribs, r->attribs); - if (r->land) { - free_land(r->land); - r->land = 0; - } - while (r->resources) { - rawmaterial *rm = r->resources; - r->resources = rm->next; - free(rm); - } - r->land = 0; + /* make sure this was not read earlier */ + assert(r->next == NULL); + assert(r->attribs == NULL); + assert(r->land == NULL); + assert(r->resources == NULL); } + /* add region to the global list: */ + add_region(r, x, y); if (data->version < LANDDISPLAY_VERSION) { read_regioninfo(data, r, info, sizeof(info)); } From d9f800f444cdff79e65d8cff71a8e70120a0383e Mon Sep 17 00:00:00 2001 From: Enno Rehling Date: Sat, 3 Nov 2018 18:25:22 +0100 Subject: [PATCH 127/160] =?UTF-8?q?Bug=202482:=20Untote=20k=C3=B6nnen=20ih?= =?UTF-8?q?re=20eigenen=20Gegenst=C3=A4nde=20reservieren.?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- scripts/tests/e2/undead.lua | 27 +++++++++++++++++++++++++++ src/laws.c | 7 +++++-- 2 files changed, 32 insertions(+), 2 deletions(-) diff --git a/scripts/tests/e2/undead.lua b/scripts/tests/e2/undead.lua index e137ce3c2..4d8c9772b 100644 --- a/scripts/tests/e2/undead.lua +++ b/scripts/tests/e2/undead.lua @@ -6,6 +6,33 @@ function setup() eressea.free_game() end +function test_undead_reserve_self() + local r1 = region.create(0, 0, "plain") + local f1 = faction.create("human") + local u1 = unit.create(f1, r1, 1) + u1.race = "undead" + u1:clear_orders() + u1:add_item("log", 2) + u1:add_order("RESERVIERE 1 Holz") + u1:add_order("GIB 0 ALLES Holz") + process_orders() + assert_equal(1, u1:get_item("log")) +end + +function test_undead_reserve_other() + local r1 = region.create(0, 0, "plain") + local f1 = faction.create("human") + local u1 = unit.create(f1, r1, 1) + local u2 = unit.create(f1, r1, 1) + u2:add_item("log", 2) + u1.race = "undead" + u1:clear_orders() + u1:add_order("RESERVIERE 1 Holz") + process_orders() + assert_equal(0, u1:get_item("log")) + assert_equal(2, u2:get_item("log")) +end + function test_undead_give_item() local r1 = region.create(0, 0, "plain") local f1 = faction.create("human", "hodor@eressea.de", "de") diff --git a/src/laws.c b/src/laws.c index 775bd78a0..57c5adfc2 100644 --- a/src/laws.c +++ b/src/laws.c @@ -3379,7 +3379,7 @@ int pay_cmd(unit * u, struct order *ord) static int reserve_i(unit * u, struct order *ord, int flags) { char token[128]; - if (u->number > 0 && (u_race(u)->ec_flags & ECF_GETITEM)) { + if (u->number > 0) { int use, count, para; const item_type *itype; const char *s; @@ -3413,7 +3413,10 @@ static int reserve_i(unit * u, struct order *ord, int flags) } int reserve_cmd(unit * u, struct order *ord) { - return reserve_i(u, ord, GET_DEFAULT); + if ((u_race(u)->ec_flags & ECF_GETITEM)) { + return reserve_i(u, ord, GET_DEFAULT); + } + return 0; } int reserve_self(unit * u, struct order *ord) { From 89b10ee63de1d5c1c60759d68dd089ea73a039d8 Mon Sep 17 00:00:00 2001 From: Enno Rehling Date: Sat, 3 Nov 2018 19:30:30 +0100 Subject: [PATCH 128/160] bug 2463 fix xmastrees, fix get_key/set_key --- scripts/eressea/tunnels.lua | 1 - scripts/eressea/xmasitems.lua | 4 +- scripts/tests/common.lua | 21 ++++ scripts/tests/xmas.lua | 2 + src/battle.c | 4 +- src/bind_faction.c | 137 ++++++++++++------------- src/bind_region.c | 181 +++++++++++++++++----------------- src/helpers.c | 2 +- src/kernel/connection.c | 4 +- src/magic.c | 2 +- src/market.c | 2 +- src/move.c | 2 +- src/reports.c | 2 +- src/util/filereader.c | 4 +- 14 files changed, 198 insertions(+), 170 deletions(-) diff --git a/scripts/eressea/tunnels.lua b/scripts/eressea/tunnels.lua index b0b3fe2a3..4a787a373 100644 --- a/scripts/eressea/tunnels.lua +++ b/scripts/eressea/tunnels.lua @@ -27,7 +27,6 @@ end local function tunnel_action(b, param) local units = tunnel_travelers(b) local rto = get_target(param) - print("tunnel from " .. tostring(b.region) .. " to " .. tostring(rto)) if rto and units then eressea.log.debug("Tunnel from " .. tostring(b) .. " [" .. param .. "]") for key, u in pairs(units) do diff --git a/scripts/eressea/xmasitems.lua b/scripts/eressea/xmasitems.lua index a0f2e48f8..3771553b5 100644 --- a/scripts/eressea/xmasitems.lua +++ b/scripts/eressea/xmasitems.lua @@ -74,7 +74,7 @@ function use_xmastree(u, amount) if u.region.herb~=nil then -- TODO: else? local trees = u.region:get_resource("tree") - u.region:set_key("xm06", true) + u.region:set_key("xm06", get_turn()) u.region:set_resource("tree", 10+trees) local msg = usepotion_message(u, "xmastree") msg:send_region(u.region) @@ -107,7 +107,7 @@ function self.update() -- we celebrate knut and kick out the trees. for r in regions() do if r:get_key("xm06") then - r:set_key("xm06", false) + r:set_key("xm06", 0) end end end diff --git a/scripts/tests/common.lua b/scripts/tests/common.lua index 403db0a46..944b0bdfe 100644 --- a/scripts/tests/common.lua +++ b/scripts/tests/common.lua @@ -1135,3 +1135,24 @@ function test_immunity_stops_guard() assert_equal(f.age, 2) assert_true(u.guard) end + +function test_region_keys() + local r = region.create(0, 0, 'plain') + assert_nil(r:get_key('test')) + assert_nil(r:get_key('more')) + r:set_key('test', 42) + r:set_key('more') -- default is 1 + assert_equal(42, r:get_key('test')) + assert_equal(1, r:get_key('more')) +end + +function test_faction_keys() + local f = faction.create('human') + assert_nil(f:get_key('test')) + assert_nil(f:get_key('more')) + f:set_key('test', 42) + f:set_key('more') -- default is 1 + assert_equal(42, f:get_key('test')) + assert_equal(1, f:get_key('more')) +end + diff --git a/scripts/tests/xmas.lua b/scripts/tests/xmas.lua index 304cc333a..8ae85fc76 100644 --- a/scripts/tests/xmas.lua +++ b/scripts/tests/xmas.lua @@ -75,9 +75,11 @@ end function test_xmastree() local r r = use_tree("ocean") + assert_nil(r:get_key("xm06")) assert_equal(0, r:get_resource("tree")) eressea.free_game() r = use_tree("plain") + assert_equal(get_turn(), r:get_key("xm06")) assert_equal(10, r:get_resource("tree")) end diff --git a/src/battle.c b/src/battle.c index 3a1628dfe..326e05e20 100644 --- a/src/battle.c +++ b/src/battle.c @@ -340,7 +340,7 @@ bool helping(const side * as, const side * ds) { if (as->faction == ds->faction) return true; - return (bool)(!enemy(as, ds) && alliedside(as, ds->faction, HELP_FIGHT)); + return (!enemy(as, ds) && alliedside(as, ds->faction, HELP_FIGHT)); } int statusrow(int status) @@ -2640,7 +2640,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; diff --git a/src/bind_faction.c b/src/bind_faction.c index 581b1b0bf..9cc6bdd97 100644 --- a/src/bind_faction.c +++ b/src/bind_faction.c @@ -59,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"); @@ -73,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; @@ -91,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); @@ -133,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) { @@ -155,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; @@ -170,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; @@ -185,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; @@ -200,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); } @@ -216,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); @@ -225,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; @@ -234,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) { @@ -260,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) { @@ -276,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; @@ -294,8 +297,8 @@ static int tolua_faction_count_msg_type(lua_State *L) { 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; @@ -310,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; @@ -321,7 +324,7 @@ 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); + faction *self = (faction *)tolua_tousertype(L, 1, NULL); int x = 0, y = 0; faction_getorigin(self, 0, &x, &y); @@ -332,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) { @@ -353,9 +356,9 @@ 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"); @@ -371,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); + 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 *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; @@ -422,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; @@ -441,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); + 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); + 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); @@ -500,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"); @@ -515,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; } diff --git a/src/bind_region.c b/src/bind_region.c index 86c072a84..fd76a80b9 100644 --- a/src/bind_region.c +++ b/src/bind_region.c @@ -42,8 +42,8 @@ #include static int tolua_region_count_msg_type(lua_State *L) { - region *self = (region *)tolua_tousertype(L, 1, 0); - const char *str = tolua_tostring(L, 2, 0); + region *self = (region *)tolua_tousertype(L, 1, NULL); + const char *str = tolua_tostring(L, 2, NULL); int n = 0; if (self->msgs) { mlist * ml = self->msgs->begin; @@ -73,21 +73,21 @@ int tolua_regionlist_next(lua_State * L) static int tolua_region_get_id(lua_State * L) { - region *self = (region *)tolua_tousertype(L, 1, 0); + region *self = (region *)tolua_tousertype(L, 1, NULL); lua_pushinteger(L, self->uid); return 1; } static int tolua_region_get_blocked(lua_State * L) { - region *self = (region *)tolua_tousertype(L, 1, 0); + region *self = (region *)tolua_tousertype(L, 1, NULL); lua_pushboolean(L, (self->flags&RF_BLOCKED) != 0); return 1; } static int tolua_region_set_blocked(lua_State * L) { - region *self = (region *)tolua_tousertype(L, 1, 0); + region *self = (region *)tolua_tousertype(L, 1, NULL); bool flag = !!tolua_toboolean(L, 2, 1); if (flag) self->flags |= RF_BLOCKED; else self->flags &= ~RF_BLOCKED; @@ -96,36 +96,36 @@ static int tolua_region_set_blocked(lua_State * L) static int tolua_region_get_x(lua_State * L) { - region *self = (region *)tolua_tousertype(L, 1, 0); + region *self = (region *)tolua_tousertype(L, 1, NULL); lua_pushinteger(L, self->x); return 1; } static int tolua_region_get_y(lua_State * L) { - region *self = (region *)tolua_tousertype(L, 1, 0); + region *self = (region *)tolua_tousertype(L, 1, NULL); lua_pushinteger(L, self->y); return 1; } static int tolua_region_get_plane(lua_State * L) { - region *r = (region *)tolua_tousertype(L, 1, 0); + region *r = (region *)tolua_tousertype(L, 1, NULL); tolua_pushusertype(L, rplane(r), TOLUA_CAST "plane"); return 1; } static int tolua_region_get_terrain(lua_State * L) { - region *self = (region *)tolua_tousertype(L, 1, 0); + region *self = (region *)tolua_tousertype(L, 1, NULL); tolua_pushstring(L, self->terrain->_name); return 1; } static int tolua_region_set_terrain(lua_State * L) { - region *r = (region *)tolua_tousertype(L, 1, 0); - const char *tname = tolua_tostring(L, 2, 0); + region *r = (region *)tolua_tousertype(L, 1, NULL); + const char *tname = tolua_tostring(L, 2, NULL); if (tname) { const terrain_type *terrain = get_terrain(tname); if (terrain) { @@ -137,7 +137,7 @@ static int tolua_region_set_terrain(lua_State * L) static int tolua_region_get_terrainname(lua_State * L) { - region *self = (region *)tolua_tousertype(L, 1, 0); + region *self = (region *)tolua_tousertype(L, 1, NULL); attrib *a = a_find(self->attribs, &at_racename); if (a) { tolua_pushstring(L, get_racename(a)); @@ -148,8 +148,8 @@ static int tolua_region_get_terrainname(lua_State * L) static int tolua_region_set_owner(lua_State * L) { - region *r = (region *)tolua_tousertype(L, 1, 0); - struct faction *f = (struct faction *)tolua_tousertype(L, 2, 0); + region *r = (region *)tolua_tousertype(L, 1, NULL); + struct faction *f = (struct faction *)tolua_tousertype(L, 2, NULL); if (r) { region_set_owner(r, f, turn); } @@ -158,7 +158,7 @@ static int tolua_region_set_owner(lua_State * L) static int tolua_region_get_owner(lua_State * L) { - region *r = (region *)tolua_tousertype(L, 1, 0); + region *r = (region *)tolua_tousertype(L, 1, NULL); if (r) { struct faction *f = region_get_owner(r); tolua_pushusertype(L, f, TOLUA_CAST "faction"); @@ -169,8 +169,8 @@ static int tolua_region_get_owner(lua_State * L) static int tolua_region_set_terrainname(lua_State * L) { - region *self = (region *)tolua_tousertype(L, 1, 0); - const char *name = tolua_tostring(L, 2, 0); + region *self = (region *)tolua_tousertype(L, 1, NULL); + const char *name = tolua_tostring(L, 2, NULL); if (name == NULL) { a_removeall(&self->attribs, &at_racename); } @@ -182,42 +182,42 @@ static int tolua_region_set_terrainname(lua_State * L) static int tolua_region_get_info(lua_State * L) { - region *self = (region *)tolua_tousertype(L, 1, 0); + region *self = (region *)tolua_tousertype(L, 1, NULL); tolua_pushstring(L, region_getinfo(self)); return 1; } static int tolua_region_set_info(lua_State * L) { - region *self = (region *)tolua_tousertype(L, 1, 0); - region_setinfo(self, tolua_tostring(L, 2, 0)); + region *self = (region *)tolua_tousertype(L, 1, NULL); + region_setinfo(self, tolua_tostring(L, 2, NULL)); return 0; } static int tolua_region_get_name(lua_State * L) { - region *self = (region *)tolua_tousertype(L, 1, 0); + region *self = (region *)tolua_tousertype(L, 1, NULL); tolua_pushstring(L, region_getname(self)); return 1; } static int tolua_region_set_name(lua_State * L) { - region *self = (region *)tolua_tousertype(L, 1, 0); - region_setname(self, tolua_tostring(L, 2, 0)); + region *self = (region *)tolua_tousertype(L, 1, NULL); + region_setname(self, tolua_tostring(L, 2, NULL)); return 0; } static int tolua_region_get_morale(lua_State * L) { - region *r = (region *)tolua_tousertype(L, 1, 0); + region *r = (region *)tolua_tousertype(L, 1, NULL); lua_pushinteger(L, region_get_morale(r)); return 1; } static int tolua_region_set_morale(lua_State * L) { - region *r = (region *)tolua_tousertype(L, 1, 0); + region *r = (region *)tolua_tousertype(L, 1, NULL); region_set_morale(r, (int)tolua_tonumber(L, 2, 0), turn); return 0; } @@ -225,14 +225,14 @@ static int tolua_region_set_morale(lua_State * L) /* region mourning this turn */ static int tolua_region_get_is_mourning(lua_State * L) { - region *r = (region *)tolua_tousertype(L, 1, 0); + region *r = (region *)tolua_tousertype(L, 1, NULL); lua_pushboolean(L, is_mourning(r, turn+1)); return 1; } static int tolua_region_get_adj(lua_State * L) { - region *r = (region *)tolua_tousertype(L, 1, 0); + region *r = (region *)tolua_tousertype(L, 1, NULL); region *rn[MAXDIRECTIONS]; int d, idx; get_neighbours(r, rn); @@ -249,7 +249,7 @@ static int tolua_region_get_adj(lua_State * L) static int tolua_region_get_luxury(lua_State * L) { - region *r = (region *)tolua_tousertype(L, 1, 0); + region *r = (region *)tolua_tousertype(L, 1, NULL); if (r->land) { const item_type *lux = r_luxury(r); if (lux) { @@ -263,8 +263,8 @@ static int tolua_region_get_luxury(lua_State * L) static int tolua_region_set_luxury(lua_State * L) { - region *r = (region *)tolua_tousertype(L, 1, 0); - const char *name = tolua_tostring(L, 2, 0); + region *r = (region *)tolua_tousertype(L, 1, NULL); + const char *name = tolua_tostring(L, 2, NULL); if (r->land && name) { const item_type *lux = r_luxury(r); const item_type *itype = it_find(name); @@ -278,9 +278,9 @@ static int tolua_region_set_luxury(lua_State * L) static int tolua_region_set_herb(lua_State * L) { - region *r = (region *)tolua_tousertype(L, 1, 0); + region *r = (region *)tolua_tousertype(L, 1, NULL); if (r->land) { - const char *name = tolua_tostring(L, 2, 0); + const char *name = tolua_tostring(L, 2, NULL); const item_type *itype = it_find(name); if (itype && (itype->flags & ITF_HERB)) { r->land->herbtype = itype; @@ -291,7 +291,7 @@ static int tolua_region_set_herb(lua_State * L) static int tolua_region_get_herb(lua_State * L) { - region *r = (region *)tolua_tousertype(L, 1, 0); + region *r = (region *)tolua_tousertype(L, 1, NULL); if (r->land && r->land->herbtype) { const char *name = r->land->herbtype->rtype->_name; tolua_pushstring(L, name); @@ -302,7 +302,7 @@ static int tolua_region_get_herb(lua_State * L) static int tolua_region_get_next(lua_State * L) { - region *self = (region *)tolua_tousertype(L, 1, 0); + region *self = (region *)tolua_tousertype(L, 1, NULL); direction_t dir = (direction_t)tolua_tonumber(L, 2, 0); if (dir >= 0 && dir < MAXDIRECTIONS) { @@ -314,7 +314,7 @@ static int tolua_region_get_next(lua_State * L) static int tolua_region_get_flag(lua_State * L) { - region *self = (region *)tolua_tousertype(L, 1, 0); + region *self = (region *)tolua_tousertype(L, 1, NULL); int bit = (int)tolua_tonumber(L, 2, 0); lua_pushboolean(L, (self->flags & (1 << bit))); @@ -323,7 +323,7 @@ static int tolua_region_get_flag(lua_State * L) static int tolua_region_set_flag(lua_State * L) { - region *self = (region *)tolua_tousertype(L, 1, 0); + region *self = (region *)tolua_tousertype(L, 1, NULL); int bit = (int)tolua_tonumber(L, 2, 0); int set = tolua_toboolean(L, 3, 1); @@ -336,8 +336,8 @@ static int tolua_region_set_flag(lua_State * L) static int tolua_region_get_resourcelevel(lua_State * L) { - region *r = (region *)tolua_tousertype(L, 1, 0); - const char *type = tolua_tostring(L, 2, 0); + region *r = (region *)tolua_tousertype(L, 1, NULL); + const char *type = tolua_tostring(L, 2, NULL); const resource_type *rtype = rt_find(type); if (rtype != NULL) { const rawmaterial *rm; @@ -372,9 +372,9 @@ static int tolua_region_get_resource(lua_State * L) const resource_type *rtype; int result; - r = (region *)tolua_tousertype(L, 1, 0); + r = (region *)tolua_tousertype(L, 1, NULL); LUA_ASSERT(r != NULL, "invalid parameter"); - type = tolua_tostring(L, 2, 0); + type = tolua_tostring(L, 2, NULL); LUA_ASSERT(type != NULL, "invalid parameter"); result = special_resource(type); @@ -403,8 +403,8 @@ static int tolua_region_get_resource(lua_State * L) static int tolua_region_set_resource(lua_State * L) { - region *r = (region *)tolua_tousertype(L, 1, 0); - const char *type = tolua_tostring(L, 2, 0); + region *r = (region *)tolua_tousertype(L, 1, NULL); + const char *type = tolua_tostring(L, 2, NULL); int result, value = (int)tolua_tonumber(L, 3, 0); const resource_type *rtype; @@ -429,7 +429,7 @@ static int tolua_region_set_resource(lua_State * L) static int tolua_region_destroy(lua_State * L) { - region *self = (region *)tolua_tousertype(L, 1, 0); + region *self = (region *)tolua_tousertype(L, 1, NULL); remove_region(®ions, self); return 0; } @@ -438,7 +438,7 @@ static int tolua_region_create(lua_State * L) { int x = (int)tolua_tonumber(L, 1, 0); int y = (int)tolua_tonumber(L, 2, 0); - const char *tname = tolua_tostring(L, 3, 0); + const char *tname = tolua_tostring(L, 3, NULL); if (tname) { plane *pl = findplane(x, y); const terrain_type *terrain = get_terrain(tname); @@ -471,7 +471,7 @@ static int tolua_region_create(lua_State * L) static int tolua_region_get_units(lua_State * L) { - region *self = (region *)tolua_tousertype(L, 1, 0); + region *self = (region *)tolua_tousertype(L, 1, NULL); unit **unit_ptr = (unit **)lua_newuserdata(L, sizeof(unit *)); luaL_getmetatable(L, "unit"); @@ -485,7 +485,7 @@ static int tolua_region_get_units(lua_State * L) static int tolua_region_get_buildings(lua_State * L) { - region *self = (region *)tolua_tousertype(L, 1, 0); + region *self = (region *)tolua_tousertype(L, 1, NULL); building **building_ptr = (building **)lua_newuserdata(L, sizeof(building *)); @@ -500,7 +500,7 @@ static int tolua_region_get_buildings(lua_State * L) static int tolua_region_get_ships(lua_State * L) { - region *self = (region *)tolua_tousertype(L, 1, 0); + region *self = (region *)tolua_tousertype(L, 1, NULL); ship **ship_ptr = (ship **)lua_newuserdata(L, sizeof(ship *)); luaL_getmetatable(L, "ship"); @@ -514,7 +514,7 @@ static int tolua_region_get_ships(lua_State * L) static int tolua_region_get_age(lua_State * L) { - region *self = (region *)tolua_tousertype(L, 1, 0); + region *self = (region *)tolua_tousertype(L, 1, NULL); if (self) { lua_pushinteger(L, self->age); @@ -525,7 +525,7 @@ static int tolua_region_get_age(lua_State * L) static int tolua_region_get_peasants(lua_State * L) { - region *self = (region *)tolua_tousertype(L, 1, 0); + region *self = (region *)tolua_tousertype(L, 1, NULL); if (self) { lua_pushinteger(L, self->land ? self->land->peasants : 0); @@ -536,7 +536,7 @@ static int tolua_region_get_peasants(lua_State * L) static int tolua_region_set_peasants(lua_State * L) { - region *self = (region *)tolua_tousertype(L, 1, 0); + region *self = (region *)tolua_tousertype(L, 1, NULL); if (self && self->land) { self->land->peasants = lua_tointeger(L, 2); @@ -546,37 +546,22 @@ static int tolua_region_set_peasants(lua_State * L) static int tolua_region_getkey(lua_State * L) { - region *self = (region *)tolua_tousertype(L, 1, 0); - const char *name = tolua_tostring(L, 2, 0); + region *self = (region *)tolua_tousertype(L, 1, NULL); + const char *name = tolua_tostring(L, 2, NULL); int flag = atoi36(name); - - lua_pushboolean(L, key_get(self->attribs, flag)); - return 1; -} - -static int tolua_region_getastral(lua_State * L) -{ - region *r = (region *)tolua_tousertype(L, 1, 0); - region *rt = r_standard_to_astral(r); - - if (!rt) { - const char *tname = tolua_tostring(L, 2, 0); - plane *pl = get_astralplane(); - rt = new_region(real2tp(r->x), real2tp(r->y), pl, 0); - if (tname) { - const terrain_type *terrain = get_terrain(tname); - terraform_region(rt, terrain); - } + int value = key_get(self->attribs, flag); + if (value != 0) { + lua_pushinteger(L, value); + return 1; } - tolua_pushusertype(L, rt, TOLUA_CAST "region"); - return 1; + return 0; } static int tolua_region_setkey(lua_State * L) { - region *self = (region *)tolua_tousertype(L, 1, 0); - const char *name = tolua_tostring(L, 2, 0); - int value = (int)tolua_tonumber(L, 3, 0); + region *self = (region *)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) { @@ -588,9 +573,27 @@ static int tolua_region_setkey(lua_State * L) return 0; } +static int tolua_region_getastral(lua_State * L) +{ + region *r = (region *)tolua_tousertype(L, 1, NULL); + region *rt = r_standard_to_astral(r); + + if (!rt) { + const char *tname = tolua_tostring(L, 2, NULL); + plane *pl = get_astralplane(); + rt = new_region(real2tp(r->x), real2tp(r->y), pl, 0); + if (tname) { + const terrain_type *terrain = get_terrain(tname); + terraform_region(rt, terrain); + } + } + tolua_pushusertype(L, rt, TOLUA_CAST "region"); + return 1; +} + static int tolua_region_tostring(lua_State * L) { - region *self = (region *)tolua_tousertype(L, 1, 0); + region *self = (region *)tolua_tousertype(L, 1, NULL); lua_pushstring(L, regionname(self, NULL)); return 1; } @@ -606,7 +609,7 @@ static int tolua_plane_get(lua_State * L) static int tolua_plane_erase(lua_State *L) { - plane *self = (plane *)tolua_tousertype(L, 1, 0); + plane *self = (plane *)tolua_tousertype(L, 1, NULL); remove_plane(self); return 0; } @@ -618,7 +621,7 @@ static int tolua_plane_create(lua_State * L) int y = (int)tolua_tonumber(L, 3, 0); int width = (int)tolua_tonumber(L, 4, 0); int height = (int)tolua_tonumber(L, 5, 0); - const char *name = tolua_tostring(L, 6, 0); + const char *name = tolua_tostring(L, 6, NULL); plane *pl; pl = create_new_plane(id, name, x, x + width - 1, y, y + height - 1, 0); @@ -629,15 +632,15 @@ static int tolua_plane_create(lua_State * L) static int tolua_plane_get_name(lua_State * L) { - plane *self = (plane *)tolua_tousertype(L, 1, 0); + plane *self = (plane *)tolua_tousertype(L, 1, NULL); tolua_pushstring(L, self->name); return 1; } static int tolua_plane_set_name(lua_State * L) { - plane *self = (plane *)tolua_tousertype(L, 1, 0); - const char *str = tolua_tostring(L, 2, 0); + plane *self = (plane *)tolua_tousertype(L, 1, NULL); + const char *str = tolua_tostring(L, 2, NULL); free(self->name); if (str) self->name = str_strdup(str); @@ -648,14 +651,14 @@ static int tolua_plane_set_name(lua_State * L) static int tolua_plane_get_id(lua_State * L) { - plane *self = (plane *)tolua_tousertype(L, 1, 0); + plane *self = (plane *)tolua_tousertype(L, 1, NULL); lua_pushinteger(L, self->id); return 1; } static int tolua_plane_normalize(lua_State * L) { - plane *self = (plane *)tolua_tousertype(L, 1, 0); + plane *self = (plane *)tolua_tousertype(L, 1, NULL); int x = (int)tolua_tonumber(L, 2, 0); int y = (int)tolua_tonumber(L, 3, 0); pnormalize(&x, &y, self); @@ -666,14 +669,14 @@ static int tolua_plane_normalize(lua_State * L) static int tolua_plane_tostring(lua_State * L) { - plane *self = (plane *)tolua_tousertype(L, 1, 0); + plane *self = (plane *)tolua_tousertype(L, 1, NULL); lua_pushstring(L, self->name); return 1; } static int tolua_plane_get_size(lua_State * L) { - plane *pl = (plane *)tolua_tousertype(L, 1, 0); + plane *pl = (plane *)tolua_tousertype(L, 1, NULL); lua_pushinteger(L, plane_width(pl)); lua_pushinteger(L, plane_height(pl)); return 2; @@ -698,8 +701,8 @@ static int tolua_distance(lua_State * L) } static int tolua_region_get_curse(lua_State *L) { - region *self = (region *)tolua_tousertype(L, 1, 0); - const char *name = tolua_tostring(L, 2, 0); + region *self = (region *)tolua_tousertype(L, 1, NULL); + const char *name = tolua_tostring(L, 2, NULL); if (self->attribs) { curse * c = get_curse(self->attribs, ct_find(name)); if (c) { @@ -711,8 +714,8 @@ static int tolua_region_get_curse(lua_State *L) { } static int tolua_region_has_attrib(lua_State *L) { - region *self = (region *)tolua_tousertype(L, 1, 0); - const char *name = tolua_tostring(L, 2, 0); + region *self = (region *)tolua_tousertype(L, 1, NULL); + const char *name = tolua_tostring(L, 2, NULL); attrib * a = a_find(self->attribs, at_find(name)); lua_pushboolean(L, a != NULL); return 1; diff --git a/src/helpers.c b/src/helpers.c index 223089c9c..7f19a6dcc 100644 --- a/src/helpers.c +++ b/src/helpers.c @@ -178,7 +178,7 @@ static bool lua_equipunit(unit *u, const char *eqname, int mask) { lua_pop(L, 1); } else { - result = (bool)lua_toboolean(L, -1); + result = lua_toboolean(L, -1) != 0; lua_pop(L, 1); } } diff --git a/src/kernel/connection.c b/src/kernel/connection.c index 7fc1213e0..995c276bb 100644 --- a/src/kernel/connection.c +++ b/src/kernel/connection.c @@ -263,7 +263,7 @@ bool b_blocknone(const connection * b, const unit * u, const region * r) bool b_rvisible(const connection * b, const region * r) { - return (bool)(b->to == r || b->from == r); + return (b->to == r || b->from == r); } bool b_fvisible(const connection * b, const struct faction * f, @@ -412,7 +412,7 @@ b_blockfogwall(const connection * b, const unit * u, const region * r) UNUSED_ARG(b); if (!u) return true; - return (bool)(effskill(u, SK_PERCEPTION, r) > 4); /* Das ist die alte Nebelwand */ + return (effskill(u, SK_PERCEPTION, r) > 4); /* Das ist die alte Nebelwand */ } /** Legacy type used in old Eressea games, no longer in use. */ diff --git a/src/magic.c b/src/magic.c index 342eb0831..469361c51 100644 --- a/src/magic.c +++ b/src/magic.c @@ -1213,7 +1213,7 @@ target_resists_magic(unit * magician, void *obj, int objtyp, int t_bonus) bool is_magic_resistant(unit * magician, unit * target, int resist_bonus) { - return (bool)target_resists_magic(magician, target, TYP_UNIT, + return target_resists_magic(magician, target, TYP_UNIT, resist_bonus); } diff --git a/src/market.c b/src/market.c index 0bd2fd647..b954e2d35 100644 --- a/src/market.c +++ b/src/market.c @@ -71,7 +71,7 @@ attrib_type at_market = { bool markets_module(void) { - return (bool)config_get_int("modules.market", 0); + return config_get_int("modules.market", 0) != 0; } void do_markets(void) diff --git a/src/move.c b/src/move.c index 222588651..545883f8e 100644 --- a/src/move.c +++ b/src/move.c @@ -892,7 +892,7 @@ static void drifting_ships(region * r) static bool present(region * r, unit * u) { - return (bool)(u && u->region == r); + return (u && u->region == r); } static void caught_target(region * r, unit * u) diff --git a/src/reports.c b/src/reports.c index dbea67489..f93eea685 100644 --- a/src/reports.c +++ b/src/reports.c @@ -683,7 +683,7 @@ bufunit(const faction * f, const unit * u, seen_mode mode, char *buf, int i, dh; int getarnt = fval(u, UFL_ANON_FACTION); const char *pzTmp, *str; - bool isbattle = (bool)(mode == seen_battle); + bool isbattle = (mode == seen_battle); item *itm, *show = NULL; faction *fv; char *bufp = buf; diff --git a/src/util/filereader.c b/src/util/filereader.c index 5ead2166f..c4a3b56cc 100644 --- a/src/util/filereader.c +++ b/src/util/filereader.c @@ -58,8 +58,8 @@ static const char *getbuf_utf8(FILE * F) eatwhite(bp, &white); /* decoding errors will get caught later on, don't have to check */ bp += white; - comment = (bool)(comment && cont); - quote = (bool)(quote && cont); + comment = (comment && cont); + quote = (quote && cont); if (tail[1] == 0) { /* we read the maximum number of bytes! */ From ab710ea41de7a041725eea24f5b97596ba21be1e Mon Sep 17 00:00:00 2001 From: Enno Rehling Date: Sun, 4 Nov 2018 09:14:36 +0100 Subject: [PATCH 129/160] fix gmtool compilation --- src/gmtool.c | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/src/gmtool.c b/src/gmtool.c index 623d45563..3b7aed36a 100644 --- a/src/gmtool.c +++ b/src/gmtool.c @@ -14,16 +14,18 @@ #include -#include - #include "gmtool.h" +#include "direction.h" #include #include "kernel/building.h" +#include "kernel/config.h" #include "kernel/faction.h" +#include "kernel/item.h" #include "kernel/plane.h" #include "kernel/region.h" +#include "kernel/resources.h" #include "kernel/terrainid.h" #include "kernel/unit.h" #include "kernel/save.h" @@ -45,8 +47,6 @@ #include "teleport.h" #include -#include -#include #include #include From bf04d9565129e76536c8b9e0d21bd43fc1389c92 Mon Sep 17 00:00:00 2001 From: Enno Rehling Date: Sun, 4 Nov 2018 12:16:02 +0100 Subject: [PATCH 130/160] fix iwyu warnings. --- src/bind_region.c | 1 - 1 file changed, 1 deletion(-) diff --git a/src/bind_region.c b/src/bind_region.c index fd76a80b9..4a466b46f 100644 --- a/src/bind_region.c +++ b/src/bind_region.c @@ -36,7 +36,6 @@ #include #include -#include #include #include #include From 0fd7906d41ca22f4275b55fc23eae6cc556a0565 Mon Sep 17 00:00:00 2001 From: Enno Rehling Date: Sun, 4 Nov 2018 15:53:27 +0100 Subject: [PATCH 131/160] extract contact logic to a module add missing tests for contact to units. add an attribute for contacting a faction. --- src/CMakeLists.txt | 2 + src/bind_process.c | 1 + src/contact.c | 80 ++++++++++++++++++++++++++++++++++++++++ src/contact.h | 10 +++++ src/contact.test.c | 36 ++++++++++++++++++ src/give.c | 1 + src/give.test.c | 2 + src/guard.c | 2 + src/kernel/config.test.c | 10 ++--- src/kernel/unit.c | 59 +++-------------------------- src/kernel/unit.h | 8 +--- src/laws.c | 18 +-------- src/magic.c | 5 ++- src/move.c | 11 +++--- src/move.test.c | 1 + src/spells.c | 1 + src/test_eressea.c | 1 + 17 files changed, 160 insertions(+), 88 deletions(-) create mode 100644 src/contact.c create mode 100644 src/contact.h create mode 100644 src/contact.test.c diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt index 96f67ebd0..bd0ed2bff 100644 --- a/src/CMakeLists.txt +++ b/src/CMakeLists.txt @@ -97,6 +97,7 @@ set (ERESSEA_SRC automate.c battle.c chaos.c + contact.c creport.c direction.c donations.c @@ -214,6 +215,7 @@ set(TESTS_SRC alchemy.test.c automate.test.c battle.test.c + contact.test.c creport.test.c direction.test.c donations.test.c diff --git a/src/bind_process.c b/src/bind_process.c index f9f99284e..6a02ac7a5 100755 --- a/src/bind_process.c +++ b/src/bind_process.c @@ -5,6 +5,7 @@ #include "bind_process.h" #include "battle.h" +#include "contact.h" #include "economy.h" #include "laws.h" #include "magic.h" diff --git a/src/contact.c b/src/contact.c new file mode 100644 index 000000000..2ca5fc5be --- /dev/null +++ b/src/contact.c @@ -0,0 +1,80 @@ +#ifdef _MSC_VER +#include +#endif + +#include "contact.h" + +#include "kernel/attrib.h" +#include "kernel/faction.h" +#include "kernel/order.h" +#include "kernel/unit.h" + +static attrib_type at_contact_unit = { + "contact_unit", + DEFAULT_INIT, + DEFAULT_FINALIZE, + DEFAULT_AGE, + NO_WRITE, + NO_READ +}; + +static attrib_type at_contact_faction = { + "contact_faction", + DEFAULT_INIT, + DEFAULT_FINALIZE, + DEFAULT_AGE, + NO_WRITE, + NO_READ +}; + +void usetcontact(unit * u, const unit * u2) +{ + attrib *a = a_find(u->attribs, &at_contact_unit); + while (a && a->type == &at_contact_unit) { + if (a->data.v == u2) { + return; + } + a = a->next; + } + a_add(&u->attribs, a_new(&at_contact_unit))->data.v = (void *)u2; +} + +bool ucontact(const unit * u, const unit * u2) +/* Prueft, ob u den Kontaktiere-Befehl zu u2 gesetzt hat. */ +{ + attrib *a; + + if (u->faction == u2->faction) { + return true; + } + /* Explizites KONTAKTIERE */ + for (a = u->attribs; a; a = a->next) { + if (a->type == &at_contact_unit) { + if (u2 == a->data.v) { + return true; + } + } + else if (a->type == &at_contact_faction) { + if (u2->faction == a->data.v) { + return true; + } + } + } + return false; +} + +int contact_cmd(unit * u, order * ord) +{ + unit *u2; + int n; + + init_order(ord, u->faction->locale); + n = read_unitid(u->faction, u->region); + u2 = findunit(n); + + if (u2 != NULL) { + usetcontact(u, u2); + } + return 0; +} + diff --git a/src/contact.h b/src/contact.h new file mode 100644 index 000000000..d3f751887 --- /dev/null +++ b/src/contact.h @@ -0,0 +1,10 @@ +#pragma once + +#include + +struct unit; +struct faction; + +bool ucontact(const struct unit *u, const struct unit *u2); +void usetcontact(struct unit *u, const struct unit *c); + diff --git a/src/contact.test.c b/src/contact.test.c new file mode 100644 index 000000000..4374eb259 --- /dev/null +++ b/src/contact.test.c @@ -0,0 +1,36 @@ +#include "contact.h" + +#include "tests.h" +#include + +struct region; +struct unit; +struct faction; + +static void test_contact(CuTest *tc) { + struct unit *u1, *u2, *u3; + struct region *r; + struct faction *f; + + test_setup(); + r = test_create_plain(0, 0); + f = test_create_faction(NULL); + u1 = test_create_unit(f, r); + u2 = test_create_unit(f, r); + u3 = test_create_unit(test_create_faction(NULL), r); + CuAssertTrue(tc, ucontact(u1, u1)); + CuAssertTrue(tc, ucontact(u1, u2)); + CuAssertTrue(tc, !ucontact(u1, u3)); + usetcontact(u1, u3); + CuAssertTrue(tc, ucontact(u1, u3)); + CuAssertTrue(tc, !ucontact(u2, u3)); + test_teardown(); +} + +CuSuite *get_contact_suite(void) +{ + CuSuite *suite = CuSuiteNew(); + SUITE_ADD_TEST(suite, test_contact); + + return suite; +} diff --git a/src/give.c b/src/give.c index 4b1dbb0ac..98ceff6bf 100644 --- a/src/give.c +++ b/src/give.c @@ -16,6 +16,7 @@ #include #include "give.h" +#include "contact.h" #include "economy.h" #include "laws.h" diff --git a/src/give.test.c b/src/give.test.c index f3164470c..f8009874c 100644 --- a/src/give.test.c +++ b/src/give.test.c @@ -1,6 +1,8 @@ #include #include "give.h" + +#include "contact.h" #include "economy.h" #include diff --git a/src/guard.c b/src/guard.c index 468dd99bc..437980b34 100644 --- a/src/guard.c +++ b/src/guard.c @@ -20,6 +20,8 @@ OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. #include #include #include "guard.h" + +#include "contact.h" #include "laws.h" #include "monsters.h" diff --git a/src/kernel/config.test.c b/src/kernel/config.test.c index f5d29877a..cc476c6c3 100644 --- a/src/kernel/config.test.c +++ b/src/kernel/config.test.c @@ -22,7 +22,6 @@ struct critbit_tree; static void test_read_unitid(CuTest *tc) { unit *u; order *ord; - attrib *a; struct locale *lang; struct terrain_type *t_plain; @@ -31,8 +30,7 @@ static void test_read_unitid(CuTest *tc) { /* note that the english order is FIGHT, not COMBAT, so this is a poor example */ t_plain = test_create_terrain("plain", LAND_REGION); u = test_create_unit(test_create_faction(NULL), test_create_region(0, 0, t_plain)); - a = a_add(&u->attribs, a_new(&at_alias)); - a->data.i = atoi36("42"); /* this unit is also TEMP 42 */ + usetalias(u, atoi36("42")); ord = create_order(K_GIVE, lang, "TEMP 42"); init_order_depr(ord); @@ -66,7 +64,6 @@ static void test_read_unitid(CuTest *tc) { static void test_getunit(CuTest *tc) { unit *u, *u2; order *ord; - attrib *a; struct region *r; struct locale *lang; struct terrain_type *t_plain; @@ -76,8 +73,9 @@ static void test_getunit(CuTest *tc) { /* note that the english order is FIGHT, not COMBAT, so this is a poor example */ t_plain = test_create_terrain("plain", LAND_REGION); u = test_create_unit(test_create_faction(NULL), test_create_region(0, 0, t_plain)); - a = a_add(&u->attribs, a_new(&at_alias)); - a->data.i = atoi36("42"); /* this unit is also TEMP 42 */ + /* This unit is also TEMP 42: */ + usetalias(u, atoi36("42")); + r = test_create_region(1, 0, t_plain); ord = create_order(K_GIVE, lang, itoa36(u->no)); diff --git a/src/kernel/unit.c b/src/kernel/unit.c index 8b2248d39..637a83a53 100644 --- a/src/kernel/unit.c +++ b/src/kernel/unit.c @@ -430,7 +430,7 @@ unit *findnewunit(const region * r, const faction * f, int n) /*********************/ /* at_alias */ /*********************/ -attrib_type at_alias = { +static attrib_type at_alias = { "alias", DEFAULT_INIT, DEFAULT_FINALIZE, @@ -451,6 +451,11 @@ int ualias(const unit * u) return a->data.i; } +void usetalias(unit *u, int alias) +{ + a_add(&u->attribs, a_new(&at_alias))->data.i = alias; +} + int a_readprivate(variant *var, void *owner, gamedata *data) { struct storage *store = data->store; @@ -517,58 +522,6 @@ void usetprivate(unit * u, const char *str) a->data.v = str_strdup(str); } -/*********************/ -/* at_target */ -/*********************/ -attrib_type at_target = { - "target", - DEFAULT_INIT, - DEFAULT_FINALIZE, - DEFAULT_AGE, - NO_WRITE, - NO_READ -}; - -/*********************/ -/* at_contact */ -/*********************/ -attrib_type at_contact = { - "contact", - DEFAULT_INIT, - DEFAULT_FINALIZE, - DEFAULT_AGE, - NO_WRITE, - NO_READ -}; - -void usetcontact(unit * u, const unit * u2) -{ - attrib *a = a_find(u->attribs, &at_contact); - while (a && a->type == &at_contact && a->data.v != u2) - a = a->next; - if (a && a->type == &at_contact) - return; - a_add(&u->attribs, a_new(&at_contact))->data.v = (void *)u2; -} - -bool ucontact(const unit * u, const unit * u2) -/* Prueft, ob u den Kontaktiere-Befehl zu u2 gesetzt hat. */ -{ - attrib *ru; - if (u->faction == u2->faction) - return true; - - /* Explizites KONTAKTIERE */ - for (ru = a_find(u->attribs, &at_contact); ru && ru->type == &at_contact; - ru = ru->next) { - if (((unit *)ru->data.v) == u2) { - return true; - } - } - - return false; -} - /*** ** init & cleanup module **/ diff --git a/src/kernel/unit.h b/src/kernel/unit.h index e08ca1ef3..169a5ff30 100644 --- a/src/kernel/unit.h +++ b/src/kernel/unit.h @@ -120,15 +120,14 @@ extern "C" { } unit; extern struct attrib_type at_creator; - extern struct attrib_type at_alias; - extern struct attrib_type at_target; extern struct attrib_type at_potionuser; - extern struct attrib_type at_contact; extern struct attrib_type at_effect; extern struct attrib_type at_private; extern struct attrib_type at_showskchange; int ualias(const struct unit *u); + void usetalias(unit *u, int alias); + int weight(const struct unit *u); void renumber_unit(struct unit *u, int no); @@ -141,9 +140,6 @@ extern "C" { const char *uprivate(const struct unit *u); void usetprivate(struct unit *u, const char *c); - bool ucontact(const struct unit *u, const struct unit *u2); - void usetcontact(struct unit *u, const struct unit *c); - struct unit *findnewunit(const struct region *r, const struct faction *f, int alias); diff --git a/src/laws.c b/src/laws.c index 57c5adfc2..e8b6fee17 100644 --- a/src/laws.c +++ b/src/laws.c @@ -28,6 +28,7 @@ OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. #include "alchemy.h" #include "automate.h" #include "battle.h" +#include "contact.h" #include "economy.h" #include "market.h" #include "morale.h" @@ -912,21 +913,6 @@ void demographics(void) immigration(); } -int contact_cmd(unit * u, order * ord) -{ - unit *u2; - int n; - - init_order_depr(ord); - n = read_unitid(u->faction, u->region); - u2 = findunit(n); - - if (u2 != NULL) { - usetcontact(u, u2); - } - return 0; -} - int leave_cmd(unit * u, struct order *ord) { region *r = u->region; @@ -2855,7 +2841,7 @@ void maketemp_cmd(unit *u, order **olist) } u2 = create_unit(u->region, u->faction, 0, u->faction->race, alias, s, u); fset(u2, UFL_ISNEW); - a_add(&u2->attribs, a_new(&at_alias))->data.i = alias; + usetalias(u2, alias); sh = leftship(u); if (sh) { set_leftship(u2, sh); diff --git a/src/magic.c b/src/magic.c index 469361c51..3f1d58ae6 100644 --- a/src/magic.c +++ b/src/magic.c @@ -22,11 +22,12 @@ OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. #endif #include "magic.h" -#include "skill.h" -#include "study.h" +#include "contact.h" #include "helpers.h" #include "laws.h" +#include "skill.h" #include "spells.h" +#include "study.h" #include #include diff --git a/src/move.c b/src/move.c index 545883f8e..8088ddd13 100644 --- a/src/move.c +++ b/src/move.c @@ -44,18 +44,19 @@ OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. #include "kernel/terrainid.h" #include "kernel/unit.h" -#include "move.h" +#include "alchemy.h" +#include "contact.h" #include "guard.h" #include "laws.h" +#include "lighthouse.h" +#include "monsters.h" +#include "move.h" +#include "piracy.h" #include "reports.h" #include "study.h" #include "spy.h" -#include "alchemy.h" #include "travelthru.h" #include "vortex.h" -#include "monsters.h" -#include "lighthouse.h" -#include "piracy.h" #include #include diff --git a/src/move.test.c b/src/move.test.c index 2c91165e2..b240171d5 100644 --- a/src/move.test.c +++ b/src/move.test.c @@ -2,6 +2,7 @@ #include #include "move.h" +#include "contact.h" #include "lighthouse.h" #include diff --git a/src/spells.c b/src/spells.c index dadce89c6..7d745147f 100644 --- a/src/spells.c +++ b/src/spells.c @@ -17,6 +17,7 @@ #include "spells.h" +#include "contact.h" #include "guard.h" #include "reports.h" #include "spy.h" diff --git a/src/test_eressea.c b/src/test_eressea.c index 12c658f91..fc5c49d1c 100644 --- a/src/test_eressea.c +++ b/src/test_eressea.c @@ -125,6 +125,7 @@ int RunAllTests(int argc, char *argv[]) ADD_SUITE(automate); ADD_SUITE(battle); ADD_SUITE(calendar); + ADD_SUITE(contact); ADD_SUITE(creport); ADD_SUITE(donations); ADD_SUITE(economy); From c48371387c5f3f121d537f7b1fbbc423d31c3254 Mon Sep 17 00:00:00 2001 From: Enno Rehling Date: Sun, 4 Nov 2018 18:07:42 +0100 Subject: [PATCH 132/160] New Syntax: CONTACT [UNIT|FACTION] ... Move everything to contact module, add tests. --- src/contact.c | 94 ++++++++++++++++++++++++++++++++++--------- src/contact.h | 8 ++-- src/contact.test.c | 54 +++++++++++++++++++++++-- src/give.test.c | 6 +-- src/kernel/messages.h | 2 +- src/move.test.c | 2 +- 6 files changed, 136 insertions(+), 30 deletions(-) diff --git a/src/contact.c b/src/contact.c index 2ca5fc5be..635bdbd3d 100644 --- a/src/contact.c +++ b/src/contact.c @@ -6,9 +6,16 @@ #include "kernel/attrib.h" #include "kernel/faction.h" +#include "kernel/messages.h" #include "kernel/order.h" #include "kernel/unit.h" +#include "util/base36.h" +#include "util/param.h" +#include "util/parser.h" + +#include + static attrib_type at_contact_unit = { "contact_unit", DEFAULT_INIT, @@ -18,16 +25,7 @@ static attrib_type at_contact_unit = { NO_READ }; -static attrib_type at_contact_faction = { - "contact_faction", - DEFAULT_INIT, - DEFAULT_FINALIZE, - DEFAULT_AGE, - NO_WRITE, - NO_READ -}; - -void usetcontact(unit * u, const unit * u2) +void contact_unit(unit * u, const unit * u2) { attrib *a = a_find(u->attribs, &at_contact_unit); while (a && a->type == &at_contact_unit) { @@ -39,6 +37,27 @@ void usetcontact(unit * u, const unit * u2) a_add(&u->attribs, a_new(&at_contact_unit))->data.v = (void *)u2; } +static attrib_type at_contact_faction = { + "contact_faction", + DEFAULT_INIT, + DEFAULT_FINALIZE, + DEFAULT_AGE, + NO_WRITE, + NO_READ +}; + +void contact_faction(unit * u, const faction * f) +{ + attrib *a = a_find(u->attribs, &at_contact_faction); + while (a && a->type == &at_contact_faction) { + if (a->data.v == f) { + return; + } + a = a->next; + } + a_add(&u->attribs, a_new(&at_contact_faction))->data.v = (void *)f; +} + bool ucontact(const unit * u, const unit * u2) /* Prueft, ob u den Kontaktiere-Befehl zu u2 gesetzt hat. */ { @@ -65,16 +84,53 @@ bool ucontact(const unit * u, const unit * u2) int contact_cmd(unit * u, order * ord) { - unit *u2; - int n; + char token[16]; + const char *str; + param_t p; init_order(ord, u->faction->locale); - n = read_unitid(u->faction, u->region); - u2 = findunit(n); - - if (u2 != NULL) { - usetcontact(u, u2); + str = gettoken(token, sizeof(token)); + p = findparam(str, u->faction->locale); + if (p == P_FACTION) { + /* new-style syntax, KONTAKTIERE PARTEI foo */ + faction * f = getfaction(); + if (!f) { + cmistake(u, ord, 66, MSG_EVENT); + } + else { + contact_faction(u, f); + return 0; + } } - return 0; + else if (p == P_UNIT) { + /* new-style syntax, KONTAKTIERE EINHEIT [TEMP] foo */ + unit *u2 = NULL; + if (GET_UNIT == getunit(u->region, u->faction, &u2)) { + assert(u2); + contact_unit(u, u2); + return 0; + } + ADDMSG(&u->faction->msgs, msg_feedback(u, ord, + "feedback_unit_not_found", NULL)); + } + else { + /* old-style syntax, KONTAKTIERE foo */ + unit *u2; + int n = 0; + if (p == P_TEMP) { + n = getid(); + u2 = findnewunit(u->region, u->faction, n); + } + else { + n = atoi36((const char *)str); + u2 = findunit(n); + } + if (u2 != NULL) { + contact_unit(u, u2); + return 0; + } + ADDMSG(&u->faction->msgs, msg_feedback(u, ord, + "feedback_unit_not_found", NULL)); + } + return -1; } - diff --git a/src/contact.h b/src/contact.h index d3f751887..0ab3d1e50 100644 --- a/src/contact.h +++ b/src/contact.h @@ -2,9 +2,11 @@ #include -struct unit; struct faction; +struct order; +struct unit; bool ucontact(const struct unit *u, const struct unit *u2); -void usetcontact(struct unit *u, const struct unit *c); - +void contact_unit(struct unit *u, const struct unit *c); +void contact_faction(struct unit * u, const struct faction * f); +int contact_cmd(struct unit * u, struct order * ord); diff --git a/src/contact.test.c b/src/contact.test.c index 4374eb259..3a9cc355e 100644 --- a/src/contact.test.c +++ b/src/contact.test.c @@ -1,11 +1,16 @@ #include "contact.h" +#include "kernel/faction.h" +#include "kernel/order.h" +#include "kernel/unit.h" + +#include "util/language.h" +#include "util/param.h" + #include "tests.h" #include struct region; -struct unit; -struct faction; static void test_contact(CuTest *tc) { struct unit *u1, *u2, *u3; @@ -21,16 +26,59 @@ static void test_contact(CuTest *tc) { CuAssertTrue(tc, ucontact(u1, u1)); CuAssertTrue(tc, ucontact(u1, u2)); CuAssertTrue(tc, !ucontact(u1, u3)); - usetcontact(u1, u3); + contact_unit(u1, u3); CuAssertTrue(tc, ucontact(u1, u3)); CuAssertTrue(tc, !ucontact(u2, u3)); test_teardown(); } +static void test_contact_cmd(CuTest *tc) { + struct unit *u, *u2; + struct region *r; + const struct locale *lang; + struct order *ord; + + test_setup(); + r = test_create_plain(0, 0); + u = test_create_unit(test_create_faction(NULL), r); + lang = u->faction->locale; + + u2 = test_create_unit(test_create_faction(NULL), r); + ord = create_order(K_CONTACT, u->faction->locale, "%s %i", + LOC(lang, parameters[P_UNIT]), u2->no); + contact_cmd(u, ord); + CuAssertTrue(tc, ucontact(u, u2)); + free_order(ord); + + u2 = test_create_unit(test_create_faction(NULL), r); + ord = create_order(K_CONTACT, u->faction->locale, "%s %i", + LOC(lang, parameters[P_FACTION]), u2->faction->no); + contact_cmd(u, ord); + CuAssertTrue(tc, ucontact(u, u2)); + free_order(ord); + + u2 = test_create_unit(test_create_faction(NULL), r); + ord = create_order(K_CONTACT, u->faction->locale, "%i", u2->no); + contact_cmd(u, ord); + CuAssertTrue(tc, ucontact(u, u2)); + free_order(ord); + + u2 = test_create_unit(test_create_faction(NULL), r); + usetalias(u2, 42); + ord = create_order(K_CONTACT, u->faction->locale, "%s %i", + LOC(lang, parameters[P_TEMP]), ualias(u2)); + contact_cmd(u, ord); + CuAssertTrue(tc, ucontact(u, u2)); + free_order(ord); + + test_teardown(); +} + CuSuite *get_contact_suite(void) { CuSuite *suite = CuSuiteNew(); SUITE_ADD_TEST(suite, test_contact); + SUITE_ADD_TEST(suite, test_contact_cmd); return suite; } diff --git a/src/give.test.c b/src/give.test.c index f8009874c..c62973388 100644 --- a/src/give.test.c +++ b/src/give.test.c @@ -195,7 +195,7 @@ static void test_give_men_limit(CuTest * tc) { config_set("rules.give.max_men", "1"); /* below the limit, give men, increase newbies counter */ - usetcontact(env.dst, env.src); + contact_unit(env.dst, env.src); msg = give_men(1, env.src, env.dst, NULL); CuAssertStrEquals(tc, "give_person", test_get_messagetype(msg)); CuAssertIntEquals(tc, 2, env.dst->number); @@ -204,7 +204,7 @@ static void test_give_men_limit(CuTest * tc) { msg_release(msg); /* beyond the limit, do nothing */ - usetcontact(env.src, env.dst); + contact_unit(env.src, env.dst); msg = give_men(2, env.dst, env.src, NULL); CuAssertStrEquals(tc, "error129", test_get_messagetype(msg)); CuAssertIntEquals(tc, 2, env.dst->number); @@ -283,7 +283,7 @@ static void test_give_men_other_faction(CuTest * tc) { env.f1 = test_create_faction(NULL); env.f2 = test_create_faction(NULL); setup_give(&env); - usetcontact(env.dst, env.src); + contact_unit(env.dst, env.src); msg = give_men(1, env.src, env.dst, NULL); CuAssertStrEquals(tc, "give_person", test_get_messagetype(msg)); CuAssertIntEquals(tc, 2, env.dst->number); diff --git a/src/kernel/messages.h b/src/kernel/messages.h index 723ed2d01..ba441250d 100644 --- a/src/kernel/messages.h +++ b/src/kernel/messages.h @@ -63,7 +63,7 @@ extern "C" { struct mlist ** merge_messages(message_list *ml, message_list *append); void split_messages(message_list *ml, struct mlist **split); -#define ADDMSG(msgs, mcreate) { message * mx = mcreate; if (mx) { assert(mx->refcount>=1); add_message(msgs, mx); msg_release(mx); } } +#define ADDMSG(msgs, mcreate) { message * mx = mcreate; if (mx) { add_message(msgs, mx); msg_release(mx); } } void syntax_error(const struct unit *u, struct order *ord); void cmistake(const struct unit *u, struct order *ord, int mno, int mtype); diff --git a/src/move.test.c b/src/move.test.c index b240171d5..40a6d3504 100644 --- a/src/move.test.c +++ b/src/move.test.c @@ -130,7 +130,7 @@ static void test_ship_has_harbormaster_contact(CuTest * tc) { u = test_create_unit(test_create_faction(NULL), mf.r); u->building = mf.b; building_set_owner(u); - usetcontact(mf.b->_owner, mf.sh->_owner); + contact_unit(mf.b->_owner, mf.sh->_owner); CuAssertIntEquals(tc, SA_HARBOUR, check_ship_allowed(mf.sh, mf.r)); test_teardown(); From 2f9325073b00930671572afcd159b75d6cfcd125 Mon Sep 17 00:00:00 2001 From: Enno Rehling Date: Mon, 5 Nov 2018 20:30:33 +0100 Subject: [PATCH 133/160] test for cart building --- scripts/tests/common.lua | 11 +++++++++++ 1 file changed, 11 insertions(+) diff --git a/scripts/tests/common.lua b/scripts/tests/common.lua index d1c34dfa7..2aec0fc0f 100644 --- a/scripts/tests/common.lua +++ b/scripts/tests/common.lua @@ -1171,3 +1171,14 @@ function test_faction_keys() assert_equal(1, f:get_key('more')) end +function test_cartmaking() + local f = faction.create('human') + local r = region.create(0, 0, 'plain') + local u = unit.create(f, r) + u:set_skill('cartmaking', 1) + u:add_item('log', 10) + u:add_order('MACHE Wagen') + process_orders() + assert_equal(1, u:get_item('cart')) + assert_equal(5, u:get_item('log')) +end From 83b6db41fe7da0fd109d60c1a47220d324d930b6 Mon Sep 17 00:00:00 2001 From: Enno Rehling Date: Sat, 10 Nov 2018 17:06:06 +0100 Subject: [PATCH 134/160] remove legacy msg_level struct (unused). --- src/kernel/messages.h | 8 -------- 1 file changed, 8 deletions(-) diff --git a/src/kernel/messages.h b/src/kernel/messages.h index ba441250d..7fa6996e2 100644 --- a/src/kernel/messages.h +++ b/src/kernel/messages.h @@ -26,7 +26,6 @@ extern "C" { #include struct faction; - struct msglevel; typedef struct mlist { struct mlist *next; @@ -39,13 +38,6 @@ extern "C" { void free_messagelist(struct mlist *msgs); - typedef struct msglevel { - /* used to set specialized msg-levels */ - struct msglevel *next; - const struct message_type *type; - int level; - } msglevel; - #define MESSAGE_MISSING_IGNORE 0 #define MESSAGE_MISSING_ERROR 1 #define MESSAGE_MISSING_REPLACE 2 From b181618b53bc517738f888ad8895dd162a7f024c Mon Sep 17 00:00:00 2001 From: Enno Rehling Date: Thu, 15 Nov 2018 20:51:42 +0100 Subject: [PATCH 135/160] BUG 1877: change non-spell familiars. 1. mages can have actions when familiars cast spells. 2. familiar spells do not increase magician's costs. 3. improve separation of caster and mage. --- scripts/tests/e2/spells.lua | 51 ++++++++ src/battle.c | 43 +++--- src/magic.c | 254 ++++++++++++++++++------------------ src/magic.h | 11 +- src/magic.test.c | 12 +- src/spells.c | 188 +++++++++++++------------- src/spells/flyingship.c | 2 +- 7 files changed, 309 insertions(+), 252 deletions(-) diff --git a/scripts/tests/e2/spells.lua b/scripts/tests/e2/spells.lua index 5d718247a..ba3a2ec25 100644 --- a/scripts/tests/e2/spells.lua +++ b/scripts/tests/e2/spells.lua @@ -10,6 +10,7 @@ function setup() eressea.settings.set("rules.food.flags", "4") eressea.settings.set("rules.peasants.growth.factor", "0") eressea.settings.set("magic.fumble.enable", "0") + eressea.settings.set("magic.regeneration.enable", "0") end function test_shapeshift() @@ -104,6 +105,56 @@ function test_earn_silver() assert_equal(0, r:get_resource("money")) end +function test_familiar_cast() + local r = region.create(0, 0, "plain") + r:set_resource("money", 350) + r:set_resource("peasant", 0) + local f = faction.create("human") + local u = unit.create(f, r) + u.magic = "gwyrrd" + u:set_skill("magic", 10) + u.aura = 200 + u:add_spell("earn_silver#gwyrrd") + u:add_order('ARBEITE') + local uf = unit.create(f, r) + uf.magic = "gwyrrd" + uf.race = "lynx" + uf:set_skill("magic", 5) + uf:add_order('ZAUBER STUFE 1 Viehheilung') + u.familiar = uf + process_orders() + assert_equal(198, u.aura) -- Fremdzauber, Kosten verdoppelt + assert_equal(10, u:get_item('money')) -- von ARBEITE + assert_equal(50, uf:get_item('money')) -- von Zauber + assert_equal(300, uf.region:get_resource("money")) +end + +function test_familiar_mage_actions() + local r = region.create(0, 0, "plain") + r:set_resource("money", 350) + r:set_resource("peasant", 0) + local f = faction.create("human") + local u = unit.create(f, r) + u.magic = "gwyrrd" + u:set_skill("magic", 10) + u.aura = 200 + u:add_spell("earn_silver#gwyrrd") + u:add_order('ZAUBER STUFE 1 Viehheilung') + local uf = unit.create(f, r) + uf.magic = "gwyrrd" + uf.race = "lynx" + uf:set_skill("magic", 5) + uf:add_order('ZAUBER STUFE 1 Viehheilung') + u.familiar = uf + u.name = 'Xolgrim' + uf.name = 'Zonk' + process_orders() + assert_equal(50, u:get_item('money')) + assert_equal(50, uf:get_item('money')) + assert_equal(250, uf.region:get_resource("money")) + assert_equal(197, u.aura) +end + function test_familiar() local r = region.create(0, 0, "mountain") local f = faction.create("human") diff --git a/src/battle.c b/src/battle.c index 326e05e20..1101163b8 100644 --- a/src/battle.c +++ b/src/battle.c @@ -134,6 +134,7 @@ 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; @@ -156,6 +157,7 @@ static void init_rules(void) 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); @@ -1748,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 */ @@ -1788,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; } @@ -1802,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); @@ -1822,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); } } } @@ -1839,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; } @@ -1848,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; @@ -1857,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; } @@ -1894,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; } diff --git a/src/magic.c b/src/magic.c index 3f1d58ae6..d5eb7341e 100644 --- a/src/magic.c +++ b/src/magic.c @@ -657,8 +657,6 @@ int change_maxspellpoints(unit * u, int csp) /* ------------------------------------------------------------- */ /* Counter für die bereits gezauberte Anzahl Sprüche pro Runde. - * Um nur die Zahl der bereits gezauberten Sprüche zu ermitteln mit - * step = 0 aufrufen. */ int countspells(unit * u, int step) { @@ -666,36 +664,60 @@ int countspells(unit * u, int step) int count; m = get_mage_depr(u); - if (!m) + if (!m) { return 0; - - if (step == 0) + } + if (step == 0) { return m->spellcount; - + } count = m->spellcount + step; m->spellcount = (count > 0) ? count : 0; return m->spellcount; } -/* ------------------------------------------------------------- */ -/* Die für den Spruch benötigte Aura pro Stufe. - * Die Grundkosten pro Stufe werden hier um 2^count erhöht. Der - * Parameter count ist dabei die Anzahl der bereits gezauberten Sprüche +int spellcount(const unit *u) { + sc_mage *m = get_mage_depr(u); + if (m) { + return m->spellcount; + } + return 0; +} + +/** + * Die Grundkosten pro Stufe werden um 2^count erhöht. countspells(u) + * ist dabei die Anzahl der bereits gezauberten Sprüche */ -int spellcost(unit * u, const spell * sp) +int aura_multiplier(const unit * u) { + int count = spellcount(u); + return (1 << count); +} + +int spellcost(const unit * caster, const struct spell_component *spc) { - int k, aura = 0; - int count = countspells(u, 0); const resource_type *r_aura = get_resourcetype(R_AURA); - for (k = 0; sp->components && sp->components[k].type; k++) { - if (sp->components[k].type == r_aura) { - aura = sp->components[k].amount; + if (spc->type == r_aura) { + return spc->amount * aura_multiplier(caster); + } + return spc->amount; +} + +/** + * Die für den Spruch benötigte Aura pro Stufe. + */ +int auracost(const unit *caster, const spell *sp) { + const resource_type *r_aura = get_resourcetype(R_AURA); + if (sp->components) { + int k; + for (k = 0; sp->components[k].type; ++k) { + const struct spell_component *spc = sp->components + k; + if (r_aura == spc->type) { + return spc->amount * aura_multiplier(caster); + } } } - aura *= (1 << count); - return aura; + return 0; } /* ------------------------------------------------------------- */ @@ -726,17 +748,17 @@ static int spl_costtyp(const spell * sp) return costtyp; } -/* ------------------------------------------------------------- */ -/* durch Komponenten und cast_level begrenzter maximal möglicher - * Level +/** + * Durch Komponenten und cast_level begrenzter maximal möglicherLevel. + * * Da die Funktion nicht alle Komponenten durchprobiert sondern beim * ersten Fehler abbricht, muss die Fehlermeldung später mit cancast() * generiert werden. - * */ -int eff_spelllevel(unit * u, const spell * sp, int cast_level, int range) + */ +int eff_spelllevel(unit * u, unit *caster, const spell * sp, int cast_level, int range) { const resource_type *r_aura = get_resourcetype(R_AURA); - int k, maxlevel, needplevel; + int k, maxlevel; int costtyp = SPC_FIX; for (k = 0; sp->components && sp->components[k].type; k++) { @@ -744,17 +766,15 @@ int eff_spelllevel(unit * u, const spell * sp, int cast_level, int range) return 0; if (sp->components[k].amount > 0) { - /* Die Kosten für Aura sind auch von der Zahl der bereits - * gezauberten Sprüche abhängig */ + int level_cost = sp->components[k].amount * range; if (sp->components[k].type == r_aura) { - needplevel = spellcost(u, sp) * range; - } - else { - needplevel = sp->components[k].amount * range; + /* Die Kosten fuer Aura sind auch von der Zahl der bereits + * gezauberten Sprueche abhaengig */ + level_cost *= aura_multiplier(caster); } maxlevel = get_pooled(u, sp->components[k].type, GET_DEFAULT, - needplevel * cast_level) / needplevel; + level_cost * cast_level) / level_cost; /* sind die Kosten fix, so muss die Komponente nur einmal vorhanden * sein und der cast_level ändert sich nicht */ @@ -803,27 +823,20 @@ int eff_spelllevel(unit * u, const spell * sp, int cast_level, int range) * Je nach Kostenart werden dann die Komponenten noch mit cast_level * multipliziert. */ -void pay_spell(unit * u, const spell * sp, int cast_level, int range) +void pay_spell(unit * mage, const unit *caster, const spell * sp, int cast_level, int range) { - const resource_type *r_aura = get_resourcetype(R_AURA); int k; - int resuse; assert(cast_level > 0); for (k = 0; sp->components && sp->components[k].type; k++) { - if (sp->components[k].type == r_aura) { - resuse = spellcost(u, sp) * range; - } - else { - resuse = sp->components[k].amount * range; - } + const struct spell_component *spc = sp->components + k; + int resuse = spellcost(caster ? caster : mage, spc) * range; - if (sp->components[k].cost == SPC_LINEAR - || sp->components[k].cost == SPC_LEVEL) { + if (spc->cost == SPC_LINEAR || spc->cost == SPC_LEVEL) { resuse *= cast_level; } - use_pooled(u, sp->components[k].type, GET_DEFAULT, resuse); + use_pooled(mage, spc->type, GET_DEFAULT, resuse); } } @@ -851,9 +864,7 @@ bool knowsspell(const region * r, const unit * u, const spell * sp) bool cancast(unit * u, const spell * sp, int level, int range, struct order * ord) { - const resource_type *r_aura = get_resourcetype(R_AURA); int k; - int itemanz; resource *reslist = NULL; if (!knowsspell(u->region, u, sp)) { @@ -869,22 +880,18 @@ cancast(unit * u, const spell * sp, int level, int range, struct order * ord) } for (k = 0; sp->components && sp->components[k].type; ++k) { - if (sp->components[k].amount > 0) { - const resource_type *rtype = sp->components[k].type; - int itemhave; + const struct spell_component *spc = sp->components + k; + if (spc->amount > 0) { + const resource_type *rtype = spc->type; + int itemhave, itemanz; /* Die Kosten für Aura sind auch von der Zahl der bereits * gezauberten Sprüche abhängig */ - if (rtype == r_aura) { - itemanz = spellcost(u, sp) * range; - } - else { - itemanz = sp->components[k].amount * range; - } + itemanz = spellcost(u, spc) * range; /* sind die Kosten stufenabhängig, so muss itemanz noch mit dem * level multipliziert werden */ - switch (sp->components[k].cost) { + switch (spc->cost) { case SPC_LEVEL: case SPC_LINEAR: itemanz *= level; @@ -1276,11 +1283,11 @@ bool fumble(region * r, unit * u, const spell * sp, int cast_grade) } /* ------------------------------------------------------------- */ -/* Dummy-Zauberpatzer, Platzhalter für speziel auf die Sprüche +/* Dummy-Zauberpatzer, Platzhalter für speziell auf die Sprüche * zugeschnittene Patzer */ static void fumble_default(castorder * co) { - unit *mage = co->magician.u; + unit *mage = co_get_magician(co); cmistake(mage, co->order, 180, MSG_MAGIC); @@ -1295,7 +1302,8 @@ static void do_fumble(castorder * co) { curse *c; region *r = co_get_region(co); - unit *u = co->magician.u; + unit *mage = co_get_magician(co); + unit *caster = co_get_caster(co); const spell *sp = co->sp; int level = co->level; int duration; @@ -1304,8 +1312,8 @@ static void do_fumble(castorder * co) static int rc_cache; fumble_f fun; - ADDMSG(&u->faction->msgs, - msg_message("patzer", "unit region spell", u, r, sp)); + ADDMSG(&mage->faction->msgs, + msg_message("patzer", "unit region spell", mage, r, sp)); switch (rng_int() % 10) { case 0: /* wenn vorhanden spezieller Patzer, ansonsten nix */ @@ -1325,22 +1333,22 @@ static void do_fumble(castorder * co) * The list of things to happen are attached to a timeout * trigger and that's added to the triggerlit of the mage gone toad. */ - trigger *trestore = trigger_changerace(u, u_race(u), u->irace); + trigger *trestore = trigger_changerace(mage, u_race(mage), mage->irace); if (chance(0.7)) { const resource_type *rtype = rt_find("toadslime"); if (rtype) { - t_add(&trestore, trigger_giveitem(u, rtype->itype, 1)); + t_add(&trestore, trigger_giveitem(mage, rtype->itype, 1)); } } duration = rng_int() % level / 2; if (duration < 2) duration = 2; - add_trigger(&u->attribs, "timer", trigger_timeout(duration, trestore)); + add_trigger(&mage->attribs, "timer", trigger_timeout(duration, trestore)); if (rc_changed(&rc_cache)) { rc_toad = get_race(RC_TOAD); } - u_setrace(u, rc_toad); - u->irace = NULL; - ADDMSG(&r->msgs, msg_message("patzer6", "unit region spell", u, r, sp)); + u_setrace(mage, rc_toad); + mage->irace = NULL; + ADDMSG(&r->msgs, msg_message("patzer6", "unit region spell", mage, r, sp)); break; } /* fall-through is intentional! */ @@ -1350,26 +1358,26 @@ static void do_fumble(castorder * co) duration = rng_int() % level / 2; if (duration < 2) duration = 2; effect = level / -2.0; - c = create_curse(u, &u->attribs, &ct_skillmod, level, + c = create_curse(mage, &mage->attribs, &ct_skillmod, level, duration, effect, 1); c->data.i = SK_MAGIC; - ADDMSG(&u->faction->msgs, msg_message("patzer2", "unit region", u, r)); + ADDMSG(&mage->faction->msgs, msg_message("patzer2", "unit region", mage, r)); break; case 3: case 4: /* Spruch schlägt fehl, alle Magiepunkte weg */ - set_spellpoints(u, 0); - ADDMSG(&u->faction->msgs, msg_message("patzer3", "unit region spell", - u, r, sp)); + set_spellpoints(mage, 0); + ADDMSG(&mage->faction->msgs, msg_message("patzer3", "unit region spell", + mage, r, sp)); break; case 5: case 6: /* Spruch gelingt, aber alle Magiepunkte weg */ co->level = cast_spell(co); - set_spellpoints(u, 0); - ADDMSG(&u->faction->msgs, msg_message("patzer4", "unit region spell", - u, r, sp)); + set_spellpoints(mage, 0); + ADDMSG(&mage->faction->msgs, msg_message("patzer4", "unit region spell", + mage, r, sp)); break; case 7: @@ -1378,9 +1386,9 @@ static void do_fumble(castorder * co) default: /* Spruch gelingt, alle nachfolgenden Sprüche werden 2^4 so teuer */ co->level = cast_spell(co); - ADDMSG(&u->faction->msgs, msg_message("patzer5", "unit region spell", - u, r, sp)); - countspells(u, 3); + ADDMSG(&mage->faction->msgs, msg_message("patzer5", "unit region spell", + mage, r, sp)); + countspells(caster, 3); } } @@ -1591,7 +1599,7 @@ verify_unit(region * r, unit * mage, const spell * sp, spllprm * spobj, static void verify_targets(castorder * co, int *invalid, int *resist, int *success) { - unit *mage = co->magician.u; + unit *mage = co_get_magician(co); const spell *sp = co->sp; region *target_r = co_get_region(co); spellparameter *sa = co->par; @@ -2038,6 +2046,10 @@ struct unit * co_get_caster(const struct castorder * co) { return co->_familiar ? co->_familiar : co->magician.u; } +struct unit * co_get_magician(const struct castorder * co) { + return co->magician.u; +} + struct region * co_get_region(const struct castorder * co) { return co->_rtarget; } @@ -2432,7 +2444,7 @@ static castorder *cast_cmd(unit * u, order * ord) spell *sp = 0; plane *pl; spellparameter *args = NULL; - unit * caster = u; + unit * mage = u; param_t param; if (LongHunger(u)) { @@ -2502,15 +2514,15 @@ static castorder *cast_cmd(unit * u, order * ord) * können. unit_getspell findet aber nur jene Sprüche, die * die Einheit beherrscht. */ if (!sp && is_familiar(u)) { - caster = get_familiar_mage(u); - if (caster) { + mage = get_familiar_mage(u); + if (mage) { familiar = u; - sp = unit_getspell(caster, s, caster->faction->locale); + sp = unit_getspell(mage, s, mage->faction->locale); } else { /* somehow, this familiar has no mage! */ log_error("cast_cmd: familiar %s is without a mage?\n", unitname(u)); - caster = u; + mage = u; } } @@ -2597,24 +2609,22 @@ static castorder *cast_cmd(unit * u, order * ord) cmistake(u, ord, 177, MSG_MAGIC); return 0; } - if (caster != familiar) { /* Magier zaubert durch Vertrauten */ + if (mage != familiar) { /* Magier zaubert durch Vertrauten */ int sk; if (range > 1) { /* Fehler! Versucht zu Farcasten */ ADDMSG(&u->faction->msgs, msg_feedback(u, ord, "familiar_farcast", - "mage", caster)); + "mage", mage)); return 0; } - sk = effskill(caster, SK_MAGIC, 0); - if (distance(caster->region, r) > sk) { + sk = effskill(mage, SK_MAGIC, 0); + if (distance(mage->region, r) > sk) { ADDMSG(&u->faction->msgs, msg_feedback(u, ord, "familiar_toofar", - "mage", caster)); + "mage", mage)); return 0; } /* mage auf magier setzen, level anpassen, range für Erhöhung - * der Spruchkosten nutzen, langen Befehl des Magiers - * löschen, zaubern kann er noch */ + * der Spruchkosten nutzen */ range *= 2; - set_order(&caster->thisorder, NULL); sk /= 2; if (level > sk) level = sk; } @@ -2635,7 +2645,7 @@ static castorder *cast_cmd(unit * u, order * ord) unitname(u), MAX_PARAMETERS, sp->sname); } args = - add_spellparameter(target_r, caster, sp->parameter, + add_spellparameter(target_r, mage, sp->parameter, (const char *const *)params, p, ord); for (i = 0; i != p; ++i) { free(params[i]); @@ -2645,7 +2655,7 @@ static castorder *cast_cmd(unit * u, order * ord) return 0; } } - return create_castorder(0, caster, familiar, sp, target_r, level, 0, range, ord, + return create_castorder(0, mage, familiar, sp, target_r, level, 0, range, ord, args); } @@ -2718,16 +2728,17 @@ void magic(void) order *ord = co->order; int invalid, resist, success, cast_level = co->level; bool fumbled = false; - unit *u = co->magician.u; + unit *mage = co_get_magician(co); + unit *caster = co_get_caster(co); const spell *sp = co->sp; region *target_r = co_get_region(co); /* reichen die Komponenten nicht, wird der Level reduziert. */ - co->level = eff_spelllevel(u, sp, cast_level, co->distance); + co->level = eff_spelllevel(mage, caster, sp, cast_level, co->distance); if (co->level < 1) { /* Fehlermeldung mit Komponenten generieren */ - cancast(u, sp, cast_level, co->distance, ord); + cancast(mage, sp, cast_level, co->distance, ord); continue; } @@ -2735,24 +2746,24 @@ void magic(void) /* Sprüche mit Fixkosten werden immer auf Stufe des Spruchs * gezaubert, co->level ist aber defaultmäßig Stufe des Magiers */ if (spl_costtyp(sp) != SPC_FIX) { - ADDMSG(&u->faction->msgs, msg_message("missing_components", - "unit spell level", u, sp, cast_level)); + ADDMSG(&mage->faction->msgs, msg_message("missing_components", + "unit spell level", mage, sp, cast_level)); } } /* Prüfen, ob die realen Kosten für die gewünschten Stufe bezahlt * werden können */ - if (!cancast(u, sp, co->level, co->distance, ord)) { + if (!cancast(mage, sp, co->level, co->distance, ord)) { /* die Fehlermeldung wird in cancast generiert */ continue; } - co->force = MagicPower(spellpower(target_r, u, sp, co->level, ord)); + co->force = MagicPower(spellpower(target_r, mage, sp, co->level, ord)); /* die Stärke kann durch Antimagie auf 0 sinken */ if (co->force <= 0) { co->force = 0; - ADDMSG(&u->faction->msgs, msg_message("missing_force", - "unit spell level", u, sp, co->level)); + ADDMSG(&mage->faction->msgs, msg_message("missing_force", + "unit spell level", mage, sp, co->level)); } /* Ziele auf Existenz prüfen und Magieresistenz feststellen. Wurde @@ -2772,15 +2783,15 @@ void magic(void) co->force = 0; /* zwar wurde mindestens ein Ziel gefunden, das widerstand * jedoch dem Zauber. Kosten abziehen und abbrechen. */ - ADDMSG(&u->faction->msgs, msg_message("spell_resist", - "unit region spell", u, r, sp)); + ADDMSG(&mage->faction->msgs, msg_message("spell_resist", + "unit region spell", mage, r, sp)); } } /* Auch für Patzer gibt es Erfahrung, müssen die Spruchkosten * bezahlt werden und die nachfolgenden Sprüche werden teurer */ if (co->force > 0) { - if (fumble(target_r, u, sp, co->level)) { + if (fumble(target_r, mage, sp, co->level)) { /* zuerst bezahlen, dann evt in do_fumble alle Aura verlieren */ fumbled = true; } @@ -2794,12 +2805,12 @@ void magic(void) } /* erst bezahlen, dann Kostenzähler erhöhen */ if (co->level > 0) { - pay_spell(u, sp, co->level, co->distance); + pay_spell(mage, caster, sp, co->level, co->distance); } if (fumbled) { do_fumble(co); } - countspells(u, 1); + countspells(caster, 1); } } @@ -2807,9 +2818,9 @@ void magic(void) for (r = regions; r; r = r->next) { unit *u; for (u = r->units; u; u = u->next) { - if (is_mage(u) && countspells(u, 0) > 0) { + if (is_mage(u) && spellcount(u) > 0) { produceexp(u, SK_MAGIC, u->number); - /* Spruchlistenaktualiesierung ist in Regeneration */ + /* Spruchlistenaktualisierung ist in Regeneration */ } } } @@ -2859,32 +2870,21 @@ static void select_spellbook(void **tokens, spellbook *sb, const struct locale * spell *unit_getspell(struct unit *u, const char *name, const struct locale * lang) { - void * tokens = 0; spellbook *sb; sb = unit_get_spellbook(u); if (sb) { + void * tokens = 0; select_spellbook(&tokens, sb, lang); - } -#if 0 /* TODO: some familiars can cast spells from the mage's spellbook? */ - u = get_familiar_mage(u); - if (u) { - sb = unit_get_spellbook(u); - if (sb) { - select_spellbook(&tokens, sb, lang); - } - } -#endif - - if (tokens) { - variant token; - if (findtoken(tokens, name, &token) != E_TOK_NOMATCH) { + if (tokens) { + variant token; + if (findtoken(tokens, name, &token) != E_TOK_NOMATCH) { + freetokens(tokens); + return (spell *)token.v; + } freetokens(tokens); - return (spell *)token.v; } - freetokens(tokens); } - return 0; } diff --git a/src/magic.h b/src/magic.h index 654673245..030d21864 100644 --- a/src/magic.h +++ b/src/magic.h @@ -140,6 +140,7 @@ extern "C" { } castorder; struct unit * co_get_caster(const struct castorder * co); + struct unit * co_get_magician(const struct castorder * co); struct region * co_get_region(const struct castorder * co); typedef struct spell_component { @@ -288,9 +289,11 @@ extern "C" { /* Prüfroutinen für Zaubern */ int countspells(struct unit *u, int step); + int spellcount(const struct unit *u); /* erhöht den Counter für Zaubersprüche um 'step' und gibt die neue * Anzahl der gezauberten Sprüche zurück. */ - int spellcost(struct unit *u, const struct spell * sp); + int auracost(const struct unit *caster, const struct spell *sp); + int spellcost(const struct unit *caster, const struct spell_component *spc); /* gibt die für diesen Spruch derzeit notwendigen Magiepunkte auf der * geringstmöglichen Stufe zurück, schon um den Faktor der bereits * zuvor gezauberten Sprüche erhöht */ @@ -298,12 +301,12 @@ extern "C" { int distance, struct order *ord); /* true, wenn Einheit alle Komponenten des Zaubers (incl. MP) für die * geringstmögliche Stufe hat und den Spruch beherrscht */ - void pay_spell(struct unit *u, const struct spell * sp, int eff_stufe, int distance); + void pay_spell(struct unit *mage, const struct unit *caster, const struct spell * sp, int eff_stufe, int distance); /* zieht die Komponenten des Zaubers aus dem Inventory der Einheit * ab. Die effektive Stufe des gezauberten Spruchs ist wichtig für * die korrekte Bestimmung der Magiepunktkosten */ - int eff_spelllevel(struct unit *u, const struct spell * sp, int cast_level, - int distance); + int eff_spelllevel(struct unit *mage, struct unit *caster, + const struct spell * sp, int cast_level, int distance); /* ermittelt die effektive Stufe des Zaubers. Dabei ist cast_level * die gewünschte maximale Stufe (im Normalfall Stufe des Magiers, * bei Farcasting Stufe*2^Entfernung) */ diff --git a/src/magic.test.c b/src/magic.test.c index 9ca9c013e..fc05f361f 100644 --- a/src/magic.test.c +++ b/src/magic.test.c @@ -123,9 +123,9 @@ void test_pay_spell(CuTest * tc) change_resource(u, get_resourcetype(R_AURA), 3); change_resource(u, get_resourcetype(R_HORSE), 3); - level = eff_spelllevel(u, sp, 3, 1); + level = eff_spelllevel(u, u, sp, 3, 1); CuAssertIntEquals(tc, 3, level); - pay_spell(u, sp, level, 1); + pay_spell(u, NULL, sp, level, 1); CuAssertIntEquals(tc, 0, get_resource(u, get_resourcetype(R_SILVER))); CuAssertIntEquals(tc, 0, get_resource(u, get_resourcetype(R_AURA))); CuAssertIntEquals(tc, 0, get_resource(u, get_resourcetype(R_HORSE))); @@ -157,16 +157,16 @@ void test_pay_spell_failure(CuTest * tc) CuAssertIntEquals(tc, 2, change_resource(u, get_resourcetype(R_AURA), 2)); CuAssertIntEquals(tc, 3, change_resource(u, get_resourcetype(R_HORSE), 3)); - level = eff_spelllevel(u, sp, 3, 1); + level = eff_spelllevel(u, u, sp, 3, 1); CuAssertIntEquals(tc, 2, level); - pay_spell(u, sp, level, 1); + pay_spell(u, NULL, sp, level, 1); CuAssertIntEquals(tc, 1, change_resource(u, get_resourcetype(R_SILVER), 1)); CuAssertIntEquals(tc, 3, change_resource(u, get_resourcetype(R_AURA), 3)); CuAssertIntEquals(tc, 2, change_resource(u, get_resourcetype(R_HORSE), 1)); - CuAssertIntEquals(tc, 0, eff_spelllevel(u, sp, 3, 1)); + CuAssertIntEquals(tc, 0, eff_spelllevel(u, u, sp, 3, 1)); CuAssertIntEquals(tc, 0, change_resource(u, get_resourcetype(R_SILVER), -1)); - CuAssertIntEquals(tc, 0, eff_spelllevel(u, sp, 2, 1)); + CuAssertIntEquals(tc, 0, eff_spelllevel(u, u, sp, 2, 1)); test_teardown(); } diff --git a/src/spells.c b/src/spells.c index 7d745147f..036da77a8 100644 --- a/src/spells.c +++ b/src/spells.c @@ -534,7 +534,7 @@ static unit * make_familiar(unit * mage, region *r, const race *rc, const char * static int sp_summon_familiar(castorder * co) { region *r = co_get_region(co); - unit *mage = co->magician.u; + unit *mage = co_get_magician(co); int cast_level = co->level; const race *rc; message *msg; @@ -600,7 +600,7 @@ static int sp_summon_familiar(castorder * co) * */ static int sp_destroy_magic(castorder * co) { - unit *mage = co->magician.u; + unit *mage = co_get_magician(co); int cast_level = co->level; double force = co->force; spellparameter *pa = co->par; @@ -692,7 +692,7 @@ static int sp_destroy_magic(castorder * co) static int sp_transferaura(castorder * co) { int aura, gain, multi = 2; - unit *mage = co->magician.u; + unit *mage = co_get_magician(co); int cast_level = co->level; spellparameter *pa = co->par; unit *u; @@ -768,7 +768,7 @@ static int sp_transferaura(castorder * co) static int sp_goodwinds(castorder * co) { region *r = co_get_region(co); - unit *mage = co->magician.u; + unit *mage = co_get_magician(co); int cast_level = co->level; double power = co->force; int duration = cast_level + 1; @@ -824,7 +824,7 @@ static int sp_goodwinds(castorder * co) static int sp_magicstreet(castorder * co) { region *r = co_get_region(co); - unit *mage = co->magician.u; + unit *mage = co_get_magician(co); if (!fval(r->terrain, LAND_REGION)) { cmistake(mage, co->order, 186, MSG_MAGIC); @@ -865,7 +865,7 @@ static int sp_magicstreet(castorder * co) static int sp_summonent(castorder * co) { region *r = co_get_region(co); - unit *mage = co->magician.u; + unit *mage = co_get_magician(co); int cast_level = co->level; double power = co->force; unit *u; @@ -921,7 +921,7 @@ static int sp_blessstonecircle(castorder * co) { building *b; region *r = co_get_region(co); - unit *mage = co->magician.u; + unit *mage = co_get_magician(co); int cast_level = co->level; spellparameter *p = co->par; message *msg; @@ -970,7 +970,7 @@ static int sp_blessstonecircle(castorder * co) static int sp_maelstrom(castorder * co) { region *r = co_get_region(co); - unit *mage = co->magician.u; + unit *mage = co_get_magician(co); int cast_level = co->level; curse *c; int duration = (int)co->force + 1; @@ -1013,7 +1013,7 @@ static int sp_mallorn(castorder * co) { region *r = co_get_region(co); int cast_level = co->level; - unit *mage = co->magician.u; + unit *mage = co_get_magician(co); if (!fval(r->terrain, LAND_REGION)) { cmistake(mage, co->order, 186, MSG_MAGIC); @@ -1057,7 +1057,7 @@ static int sp_mallorn(castorder * co) static int sp_blessedharvest(castorder * co) { region *r = co_get_region(co); - unit *mage = co->magician.u; + unit *mage = co_get_magician(co); int cast_level = co->level; int duration = (int)co->force + 1; /* Attribut auf Region. @@ -1094,7 +1094,7 @@ static int sp_hain(castorder * co) { int trees; region *r = co_get_region(co); - unit *mage = co->magician.u; + unit *mage = co_get_magician(co); int cast_level = co->level; double force = co->force; @@ -1140,7 +1140,7 @@ static int sp_mallornhain(castorder * co) { int trees; region *r = co_get_region(co); - unit *mage = co->magician.u; + unit *mage = co_get_magician(co); int cast_level = co->level; double force = co->force; @@ -1174,7 +1174,7 @@ static void fumble_ents(const castorder * co) int ents; unit *u; region *r = co_get_region(co); - unit *mage = co->magician.u; + unit *mage = co_get_magician(co); /* int cast_level = co->level; */ double force = co->force; @@ -1240,7 +1240,7 @@ static int sp_rosthauch(castorder * co) int n; int success = 0; region *r = co_get_region(co); - unit *mage = co->magician.u; + unit *mage = co_get_magician(co); int cast_level = co->level; int force = (int)co->force; spellparameter *pa = co->par; @@ -1338,7 +1338,7 @@ static int sp_kaelteschutz(castorder * co) int n, i = 0; int men; region *r = co_get_region(co); - unit *mage = co->magician.u; + unit *mage = co_get_magician(co); int cast_level = co->level; double force = co->force; double effect; @@ -1402,7 +1402,7 @@ static int sp_kaelteschutz(castorder * co) static int sp_sparkle(castorder * co) { unit *u; - unit *mage = co->magician.u; + unit *mage = co_get_magician(co); int cast_level = co->level; spellparameter *pa = co->par; int duration = cast_level + 1; @@ -1464,7 +1464,7 @@ static int sp_create_irongolem(castorder * co) unit *u2; attrib *a; region *r = co_get_region(co); - unit *mage = co->magician.u; + unit *mage = co_get_magician(co); int cast_level = co->level; double force = co->force; int number = lovar(force * 8 * RESOURCE_QUANTITY); @@ -1534,7 +1534,7 @@ static int sp_create_stonegolem(castorder * co) unit *u2; attrib *a; region *r = co_get_region(co); - unit *mage = co->magician.u; + unit *mage = co_get_magician(co); int cast_level = co->level; int number = lovar(co->force * 5 * RESOURCE_QUANTITY); static int cache; @@ -1602,7 +1602,7 @@ static int sp_great_drought(castorder * co) unit *u; bool terraform = false; region *r = co_get_region(co); - unit *mage = co->magician.u; + unit *mage = co_get_magician(co); int cast_level = co->level; double force = co->force; int duration = 2; @@ -1729,7 +1729,7 @@ static int sp_great_drought(castorder * co) static int sp_treewalkenter(castorder * co) { region *r = co_get_region(co); - unit *mage = co->magician.u; + unit *mage = co_get_magician(co); spellparameter *pa = co->par; double power = co->force; int cast_level = co->level; @@ -1855,7 +1855,7 @@ static int sp_treewalkexit(castorder * co) int n; int erfolg = 0; region *r = co_get_region(co); - unit *mage = co->magician.u; + unit *mage = co_get_magician(co); double power = co->force; spellparameter *pa = co->par; int cast_level = co->level; @@ -1991,7 +1991,7 @@ static int sp_treewalkexit(castorder * co) static int sp_holyground(castorder * co) { region *r = co_get_region(co); - unit *mage = co->magician.u; + unit *mage = co_get_magician(co); int cast_level = co->level; double power = co->force; message *msg = msg_message("sp_holyground_effect", "mage region", mage, r); @@ -2023,7 +2023,7 @@ static int sp_homestone(castorder * co) unit *u; curse *c; region *r = co_get_region(co); - unit *mage = co->magician.u; + unit *mage = co_get_magician(co); int cast_level = co->level; double force = co->force; double effect; @@ -2081,7 +2081,7 @@ static int sp_drought(castorder * co) { curse *c; region *r = co_get_region(co); - unit *mage = co->magician.u; + unit *mage = co_get_magician(co); int cast_level = co->level; double power = co->force; int duration = (int)power + 1; @@ -2144,7 +2144,7 @@ static int sp_ironkeeper(castorder * co) { unit *keeper; region *r = co_get_region(co); - unit *mage = co->magician.u; + unit *mage = co_get_magician(co); int cast_level = co->level; message *msg; @@ -2203,7 +2203,7 @@ static int sp_stormwinds(castorder * co) unit *u; int erfolg = 0; region *r = co_get_region(co); - unit *mage = co->magician.u; + unit *mage = co_get_magician(co); double power = co->force; spellparameter *pa = co->par; int n, force = (int)power; @@ -2290,7 +2290,7 @@ static int sp_stormwinds(castorder * co) static int sp_earthquake(castorder * co) { region *r = co_get_region(co); - unit *mage = co->magician.u; + unit *mage = co_get_magician(co); int cast_level = co->level; message *msg; building **blist = &r->buildings; @@ -2330,7 +2330,7 @@ void patzer_peasantmob(const castorder * co) unit *u; attrib *a; region *r; - unit *mage = co->magician.u; + unit *mage = co_get_magician(co); r = mage->region->land ? mage->region : co_get_region(co); @@ -2396,7 +2396,7 @@ static int sp_forest_fire(castorder * co) region *nr; direction_t i; region *r = co_get_region(co); - unit *mage = co->magician.u; + unit *mage = co_get_magician(co); int cast_level = co->level; double probability; double percentage = (rng_int() % 8 + 1) * 0.1; /* 10 - 80% */ @@ -2480,7 +2480,7 @@ static int sp_fumblecurse(castorder * co) { unit *target; int duration; - unit *mage = co->magician.u; + unit *mage = co_get_magician(co); int cast_level = co->level; double force = co->force; double effect; @@ -2516,7 +2516,7 @@ static int sp_fumblecurse(castorder * co) void patzer_fumblecurse(const castorder * co) { - unit *mage = co->magician.u; + unit *mage = co_get_magician(co); int cast_level = co->level; double force = co->force; int duration = (cast_level / 2) + 1; @@ -2554,7 +2554,7 @@ void patzer_fumblecurse(const castorder * co) static int sp_summondragon(castorder * co) { region *r = co_get_region(co); - unit *mage = co->magician.u; + unit *mage = co_get_magician(co); unit *u; int cast_level = co->level; double power = co->force; @@ -2627,7 +2627,7 @@ static int sp_firewall(castorder * co) connection *b; wall_data *fd; region *r = co_get_region(co); - unit *mage = co->magician.u; + unit *mage = co_get_magician(co); int cast_level = co->level; double force = co->force; spellparameter *pa = co->par; @@ -2718,7 +2718,7 @@ static const race *unholy_race(const race *rc) { static int sp_unholypower(castorder * co) { region * r = co_get_region(co); - unit *mage = co->magician.u; + unit *mage = co_get_magician(co); int cast_level = co->level; spellparameter *pa = co->par; int i; @@ -2900,7 +2900,7 @@ static int dc_read_compat(variant *var, void *target, gamedata *data) static int sp_deathcloud(castorder * co) { region *r = co_get_region(co); - unit *mage = co->magician.u; + unit *mage = co_get_magician(co); attrib *a = r->attribs; unit *u; @@ -2940,7 +2940,7 @@ static int sp_deathcloud(castorder * co) static void patzer_deathcloud(const castorder * co) { - unit *mage = co->magician.u; + unit *mage = co_get_magician(co); int hp = (mage->hp - 2); change_hitpoints(mage, -(rng_int() % hp)); @@ -2964,7 +2964,7 @@ static void patzer_deathcloud(const castorder * co) static int sp_plague(castorder * co) { region *r = co_get_region(co); - unit *mage = co->magician.u; + unit *mage = co_get_magician(co); int cast_level = co->level; plagues(r); @@ -2993,7 +2993,7 @@ static int sp_plague(castorder * co) static int sp_summonshadow(castorder * co) { region *r = co_get_region(co); - unit *mage = co->magician.u; + unit *mage = co_get_magician(co); int cast_level = co->level; double force = co->force; unit *u; @@ -3034,7 +3034,7 @@ static int sp_summonshadowlords(castorder * co) { unit *u; region *r = co_get_region(co); - unit *mage = co->magician.u; + unit *mage = co_get_magician(co); int cast_level = co->level; double force = co->force; int amount = (int)(force * force); @@ -3067,7 +3067,7 @@ static int sp_chaossuction(castorder * co) { region *rt; region *r = co_get_region(co); - unit *mage = co->magician.u; + unit *mage = co_get_magician(co); int cast_level = co->level; if (rplane(r)) { @@ -3123,7 +3123,7 @@ static int sp_chaossuction(castorder * co) static int sp_magicboost(castorder * co) { curse *c; - unit *mage = co->magician.u; + unit *mage = co_get_magician(co); int cast_level = co->level; double power = co->force; double effect; @@ -3172,7 +3172,7 @@ static int sp_magicboost(castorder * co) */ static int sp_bloodsacrifice(castorder * co) { - unit *mage = co->magician.u; + unit *mage = co_get_magician(co); int cast_level = co->level; int aura; int skill = effskill(mage, SK_MAGIC, 0); @@ -3249,7 +3249,7 @@ static int sp_summonundead(castorder * co) int undead, dc; unit *u; region *r = co_get_region(co); - unit *mage = co->magician.u; + unit *mage = co_get_magician(co); int cast_level = co->level; int force = (int)(co->force * 10); const race *race = get_race(RC_SKELETON); @@ -3306,7 +3306,7 @@ static int sp_auraleak(castorder * co) double lost; unit *u; region *r = co_get_region(co); - unit *mage = co->magician.u; + unit *mage = co_get_magician(co); int cast_level = co->level; message *msg; @@ -3349,7 +3349,7 @@ static int sp_analysesong_obj(castorder * co) { int obj; region *r = co_get_region(co); - unit *mage = co->magician.u; + unit *mage = co_get_magician(co); int cast_level = co->level; double force = co->force; spellparameter *pa = co->par; @@ -3398,7 +3398,7 @@ static int sp_analysesong_obj(castorder * co) static int sp_analysesong_unit(castorder * co) { unit *u; - unit *mage = co->magician.u; + unit *mage = co_get_magician(co); int cast_level = co->level; double force = co->force; spellparameter *pa = co->par; @@ -3483,7 +3483,7 @@ static int sp_charmingsong(castorder * co) unit *target; int duration; skill_t i; - unit *mage = co->magician.u; + unit *mage = co_get_magician(co); int cast_level = co->level; double force = co->force; spellparameter *pa = co->par; @@ -3572,7 +3572,7 @@ static int sp_charmingsong(castorder * co) static int sp_song_resistmagic(castorder * co) { region *r = co_get_region(co); - unit *mage = co->magician.u; + unit *mage = co_get_magician(co); int cast_level = co->level; double force = co->force; int duration = (int)force + 1; @@ -3601,7 +3601,7 @@ static int sp_song_resistmagic(castorder * co) static int sp_song_susceptmagic(castorder * co) { region *r = co_get_region(co); - unit *mage = co->magician.u; + unit *mage = co_get_magician(co); int cast_level = co->level; double force = co->force; int duration = (int)force + 1; @@ -3630,7 +3630,7 @@ static int sp_rallypeasantmob(castorder * co) unit *u, *un; int erfolg = 0; region *r = co_get_region(co); - unit *mage = co->magician.u; + unit *mage = co_get_magician(co); int cast_level = co->level; message *msg; curse *c; @@ -3683,7 +3683,7 @@ static int sp_raisepeasantmob(castorder * co) int n; int anteil; region *r = co_get_region(co); - unit *mage = co->magician.u; + unit *mage = co_get_magician(co); int rp, cast_level = co->level; double force = co->force; int duration = (int)force + 1; @@ -3739,7 +3739,7 @@ static int sp_migranten(castorder * co) { unit *target; region *r = co_get_region(co); - unit *mage = co->magician.u; + unit *mage = co_get_magician(co); int cast_level = co->level; spellparameter *pa = co->par; @@ -3807,7 +3807,7 @@ static int sp_song_of_peace(castorder * co) { unit *u; region *r = co_get_region(co); - unit *mage = co->magician.u; + unit *mage = co_get_magician(co); int cast_level = co->level; double force = co->force; int duration = 2 + lovar(force / 2); @@ -3856,7 +3856,7 @@ static int sp_generous(castorder * co) { unit *u; region *r = co_get_region(co); - unit *mage = co->magician.u; + unit *mage = co_get_magician(co); int cast_level = co->level; double force = co->force; int duration = (int)force + 1; @@ -3914,7 +3914,7 @@ static int sp_recruit(castorder * co) region *r = co_get_region(co); int num, maxp = rpeasants(r); double n; - unit *mage = co->magician.u; + unit *mage = co_get_magician(co); int cast_level = co->level; double force = co->force; faction *f = mage->faction; @@ -3969,7 +3969,7 @@ static int sp_bigrecruit(castorder * co) unit *u; region *r = co_get_region(co); int n, maxp = rpeasants(r); - unit *mage = co->magician.u; + unit *mage = co_get_magician(co); int cast_level = co->level; double force = co->force; faction *f = mage->faction; @@ -4024,7 +4024,7 @@ static int sp_pump(castorder * co) unit *u, *target; region *rt; bool see = false; - unit *mage = co->magician.u; + unit *mage = co_get_magician(co); spellparameter *pa = co->par; int cast_level = co->level; @@ -4085,7 +4085,7 @@ static int sp_seduce(castorder * co) const resource_type *rsilver = get_resourcetype(R_SILVER); unit *target; item **itmp, *items = NULL; - unit *u, *mage = co->magician.u; + unit *u, *mage = co_get_magician(co); spellparameter *pa = co->par; int cast_level = co->level; double force = co->force; @@ -4174,7 +4174,7 @@ static int sp_calm_monster(castorder * co) { curse *c; unit *target; - unit *mage = co->magician.u; + unit *mage = co_get_magician(co); spellparameter *pa = co->par; int cast_level = co->level; double force = co->force; @@ -4226,13 +4226,13 @@ static int sp_headache(castorder * co) skill *smax = NULL; int i; unit *target; - unit *mage = co->magician.u; + unit *caster = co_get_caster(co); spellparameter *pa = co->par; int cast_level = co->level; message *msg; /* Macht alle nachfolgenden Zauber doppelt so teuer */ - countspells(mage, 1); + countspells(caster, 1); target = pa->param[0]->data.u; /* Zieleinheit */ @@ -4256,8 +4256,8 @@ static int sp_headache(castorder * co) } set_order(&target->thisorder, NULL); - msg = msg_message("hangover_effect_0", "mage unit", mage, target); - r_addmessage(mage->region, mage->faction, msg); + msg = msg_message("hangover_effect_0", "mage unit", caster, target); + r_addmessage(caster->region, caster->faction, msg); msg_release(msg); msg = msg_message("hangover_effect_1", "unit", target); @@ -4285,7 +4285,7 @@ static int sp_raisepeasants(castorder * co) unit *u2; attrib *a; region *r = co_get_region(co); - unit *mage = co->magician.u; + unit *mage = co_get_magician(co); int rp = rpeasants(r), cast_level = co->level; double power = co->force; message *msg; @@ -4339,7 +4339,7 @@ static int sp_raisepeasants(castorder * co) static int sp_depression(castorder * co) { region *r = co_get_region(co); - unit *mage = co->magician.u; + unit *mage = co_get_magician(co); int cast_level = co->level; double force = co->force; int duration = (int)force + 1; @@ -4373,7 +4373,7 @@ static int sp_depression(castorder * co) int sp_puttorest(castorder * co) { region *r = co_get_region(co); - unit *mage = co->magician.u; + unit *mage = co_get_magician(co); int dead = deathcount(r); int laid_to_rest = dice((int)(co->force * 2), 100); message *seen = msg_message("puttorest", "mage", mage); @@ -4405,7 +4405,7 @@ int sp_icastle(castorder * co) building *b; const building_type *type; region *r = co_get_region(co); - unit *mage = co->magician.u; + unit *mage = co_get_magician(co); int cast_level = co->level; double power = co->force; spellparameter *pa = co->par; @@ -4473,7 +4473,7 @@ int sp_illusionary_shapeshift(castorder * co) { unit *u; const race *rc; - unit *mage = co->magician.u; + unit *mage = co_get_magician(co); int cast_level = co->level; double power = co->force; spellparameter *pa = co->par; @@ -4530,7 +4530,7 @@ int sp_illusionary_shapeshift(castorder * co) int sp_analysedream(castorder * co) { unit *u; - unit *mage = co->magician.u; + unit *mage = co_get_magician(co); int cast_level = co->level; spellparameter *pa = co->par; @@ -4552,7 +4552,7 @@ int sp_analysedream(castorder * co) static int sp_gbdreams(castorder * co, int effect) { int duration; - unit *mage = co->magician.u; + unit *mage = co_get_magician(co); int cast_level = co->level; double power = co->force; region *r = co_get_region(co); @@ -4624,7 +4624,7 @@ int sp_clonecopy(castorder * co) unit *clone; region *r = co_get_region(co); region *target_region = co_get_region(co); - unit *mage = co->magician.u; + unit *mage = co_get_magician(co); int cast_level = co->level; message *msg; char name[NAMESIZE]; @@ -4656,7 +4656,7 @@ int sp_dreamreading(castorder * co) { unit *u; region *r = co_get_region(co); - unit *mage = co->magician.u; + unit *mage = co_get_magician(co); int cast_level = co->level; spellparameter *pa = co->par; double power = co->force; @@ -4703,7 +4703,7 @@ int sp_dreamreading(castorder * co) int sp_sweetdreams(castorder * co) { region *r = co_get_region(co); - unit *mage = co->magician.u; + unit *mage = co_get_magician(co); int cast_level = co->level; double power = co->force; spellparameter *pa = co->par; @@ -4753,7 +4753,7 @@ int sp_sweetdreams(castorder * co) int sp_disturbingdreams(castorder * co) { region *r = co_get_region(co); - unit *mage = co->magician.u; + unit *mage = co_get_magician(co); int cast_level = co->level; double power = co->force; int duration = 1 + (int)(power / 6); @@ -4841,7 +4841,7 @@ int sp_analysemagic(castorder * co) int sp_itemcloak(castorder * co) { unit *target; - unit *mage = co->magician.u; + unit *mage = co_get_magician(co); spellparameter *pa = co->par; int cast_level = co->level; double power = co->force; @@ -4882,7 +4882,7 @@ int sp_resist_magic_bonus(castorder * co) unit *u; int n, m; int duration = 6; - unit *mage = co->magician.u; + unit *mage = co_get_magician(co); int cast_level = co->level; double power = co->force; spellparameter *pa = co->par; @@ -4939,7 +4939,7 @@ int sp_enterastral(castorder * co) int remaining_cap; int n, w; region *r = co_get_region(co); - unit *mage = co->magician.u; + unit *mage = co_get_magician(co); int cast_level = co->level; double power = co->force; spellparameter *pa = co->par; @@ -5054,7 +5054,7 @@ int sp_pullastral(castorder * co) int remaining_cap; int n, w; region *r = co_get_region(co); - unit *mage = co->magician.u; + unit *mage = co_get_magician(co); int cast_level = co->level; double power = co->force; spellparameter *pa = co->par; @@ -5196,7 +5196,7 @@ int sp_leaveastral(castorder * co) int remaining_cap; int n, w; region *r = co_get_region(co); - unit *mage = co->magician.u; + unit *mage = co_get_magician(co); int cast_level = co->level; double power = co->force; spellparameter *pa = co->par; @@ -5322,7 +5322,7 @@ int sp_leaveastral(castorder * co) int sp_fetchastral(castorder * co) { int n; - unit *mage = co->magician.u; + unit *mage = co_get_magician(co); int cast_level = 0; spellparameter *pa = co->par; double power = co->force; @@ -5459,7 +5459,7 @@ int sp_showastral(castorder * co) int c = 0; region_list *rl, *rl2; region *r = co_get_region(co); - unit *mage = co->magician.u; + unit *mage = co_get_magician(co); int cast_level = co->level; double power = co->force; @@ -5545,7 +5545,7 @@ int sp_viewreality(castorder * co) { region_list *rl, *rl2; region *r = co_get_region(co); - unit *mage = co->magician.u; + unit *mage = co_get_magician(co); int cast_level = co->level; message *m; @@ -5582,7 +5582,7 @@ int sp_disruptastral(castorder * co) region *rt; unit *u; region *r = co_get_region(co); - unit *mage = co->magician.u; + unit *mage = co_get_magician(co); int cast_level = co->level; double power = co->force; int duration = (int)(power / 3) + 1; @@ -5689,7 +5689,7 @@ static int sp_eternizewall(castorder * co) curse *c; building *b; region *r = co_get_region(co); - unit *mage = co->magician.u; + unit *mage = co_get_magician(co); int cast_level = co->level; double power = co->force; spellparameter *pa = co->par; @@ -5754,7 +5754,7 @@ int sp_permtransfer(castorder * co) { int aura, i; unit *tu; - unit *mage = co->magician.u; + unit *mage = co_get_magician(co); int cast_level = co->level; spellparameter *pa = co->par; const spell *sp = co->sp; @@ -5779,7 +5779,7 @@ int sp_permtransfer(castorder * co) return 0; } - i = get_spellpoints(mage) - spellcost(mage, sp); + i = get_spellpoints(mage) - auracost(mage, sp); if (aura > i) aura = i; change_maxspellpoints(mage, -aura); @@ -5813,7 +5813,7 @@ int sp_movecastle(castorder * co) region *target_region; unit *u, *unext; region *r = co_get_region(co); - unit *mage = co->magician.u; + unit *mage = co_get_magician(co); int cast_level = co->level; spellparameter *pa = co->par; message *msg; @@ -5896,7 +5896,7 @@ int sp_stealaura(castorder * co) { int taura; unit *u; - unit *mage = co->magician.u; + unit *mage = co_get_magician(co); int cast_level = co->level; double power = co->force; spellparameter *pa = co->par; @@ -5966,7 +5966,7 @@ int sp_antimagiczone(castorder * co) double power; double effect; region *r = co_get_region(co); - unit *mage = co->magician.u; + unit *mage = co_get_magician(co); int cast_level = co->level; double force = co->force; int duration = (int)force + 1; @@ -6023,7 +6023,7 @@ int sp_antimagiczone(castorder * co) static int sp_magicrunes(castorder * co) { int duration; - unit *mage = co->magician.u; + unit *mage = co_get_magician(co); int cast_level = co->level; double force = co->force; spellparameter *pa = co->par; @@ -6083,7 +6083,7 @@ int sp_speed2(castorder * co) { int n, maxmen, used = 0, dur, men; unit *u; - unit *mage = co->magician.u; + unit *mage = co_get_magician(co); int cast_level = co->level; double force = co->force; spellparameter *pa = co->par; @@ -6143,7 +6143,7 @@ int sp_break_curse(castorder * co) int obj; curse *c; region *r = co_get_region(co); - unit *mage = co->magician.u; + unit *mage = co_get_magician(co); int cast_level = co->level; double force = co->force; spellparameter *pa = co->par; @@ -6300,7 +6300,7 @@ static int sp_babbler(castorder * co) { unit *target; region *r = co_get_region(co); - unit *mage = co->magician.u; + unit *mage = co_get_magician(co); int cast_level = co->level; spellparameter *pa = co->par; message *msg; @@ -6347,7 +6347,7 @@ static int sp_babbler(castorder * co) static int sp_readmind(castorder * co) { unit *target; - unit *mage = co->magician.u; + unit *mage = co_get_magician(co); int cast_level = co->level; spellparameter *pa = co->par; diff --git a/src/spells/flyingship.c b/src/spells/flyingship.c index 2b830da2e..cd2769ef8 100644 --- a/src/spells/flyingship.c +++ b/src/spells/flyingship.c @@ -47,7 +47,7 @@ int sp_flying_ship(castorder * co) assert(co); r = co_get_region(co); - mage = co->magician.u; + mage = co_get_magician(co); cast_level = co->level; power = co->force; pa = co->par; From d2389fa87ba9c7514a18c568ec32752f597ce94c Mon Sep 17 00:00:00 2001 From: Enno Rehling Date: Sat, 17 Nov 2018 21:24:59 +0100 Subject: [PATCH 136/160] Bug 2517: Vertraute ohne eigene Zauber reparieren Trennung von caster und mage in spells.c --- scripts/tests/e2/movement.lua | 1 - scripts/tests/e2/spells.lua | 56 +++- src/kernel/faction.c | 2 +- src/kernel/gamedata.h | 3 +- src/kernel/save.c | 92 +++--- src/kernel/unit.c | 2 +- src/magic.c | 5 +- src/spells.c | 594 +++++++++++++++++----------------- src/spells/flyingship.c | 14 +- src/study.c | 8 +- 10 files changed, 424 insertions(+), 353 deletions(-) diff --git a/scripts/tests/e2/movement.lua b/scripts/tests/e2/movement.lua index 57d2413c4..c8fc92327 100644 --- a/scripts/tests/e2/movement.lua +++ b/scripts/tests/e2/movement.lua @@ -96,7 +96,6 @@ function test_follow_ship() local f = faction.create("human", "test@example.com", "de") local u1 = unit.create(f, r1, 1) local u2 = unit.create(f, r1, 1) - u2.name = 'Xolgrim' u1:add_item("money", 100) u2:add_item("money", 100) u1.ship = ship.create(r1, "boat") diff --git a/scripts/tests/e2/spells.lua b/scripts/tests/e2/spells.lua index ba3a2ec25..70d1bffb4 100644 --- a/scripts/tests/e2/spells.lua +++ b/scripts/tests/e2/spells.lua @@ -117,7 +117,6 @@ function test_familiar_cast() u:add_spell("earn_silver#gwyrrd") u:add_order('ARBEITE') local uf = unit.create(f, r) - uf.magic = "gwyrrd" uf.race = "lynx" uf:set_skill("magic", 5) uf:add_order('ZAUBER STUFE 1 Viehheilung') @@ -141,13 +140,10 @@ function test_familiar_mage_actions() u:add_spell("earn_silver#gwyrrd") u:add_order('ZAUBER STUFE 1 Viehheilung') local uf = unit.create(f, r) - uf.magic = "gwyrrd" uf.race = "lynx" uf:set_skill("magic", 5) uf:add_order('ZAUBER STUFE 1 Viehheilung') u.familiar = uf - u.name = 'Xolgrim' - uf.name = 'Zonk' process_orders() assert_equal(50, u:get_item('money')) assert_equal(50, uf:get_item('money')) @@ -199,3 +195,55 @@ function test_bug_2480() process_orders() assert_equal(0, u1.number); end + +function test_bug_2517() + local r = region.create(0, 0, "plain") + local f = faction.create("elf") + local um = unit.create(f, r, 1) + local uf = nil + eressea.settings.set("magic.familiar.race", "lynx") + f.magic = 'gwyrrd' + um.name = 'Xolgrim' + um.magic = 'gwyrrd' + um.race = 'elf' + um:set_skill('magic', 10) + um:add_spell('summon_familiar') + um:add_spell('earn_silver#gwyrrd') + um:add_order('ZAUBERE Vertrauten~rufen') + um.aura = 200 + process_orders() + uf = um.familiar + assert_not_nil(uf) + assert_equal('lynx', uf.race) + assert_nil(uf.magic) + uf:add_order('LERNE Magie') + um:clear_orders() + um:add_order('ARBEITEN') + process_orders() + assert_nil(uf.magic) + uf:add_order('ZAUBERE STUFE 1 Viehheilung') + process_orders() + assert_equal(50, uf:get_item('money')) +end + +function test_familiar_school() + local r = region.create(0, 0, "plain") + r:set_resource("money", 350) + r:set_resource("peasant", 0) + local f = faction.create("human") + local u = unit.create(f, r) + u.magic = "draig" + u:set_skill("magic", 10) + u.aura = 200 + u:add_spell("fireball") + local uf = unit.create(f, r) + uf.race = "lynx" + u.familiar = uf + + assert_nil(uf.magic) + uf:set_skill("magic", 5) + assert_nil(uf.magic) + uf.aura = 10 + assert_equal(0, uf.aura) + assert_nil(uf.magic) +end diff --git a/src/kernel/faction.c b/src/kernel/faction.c index f36ef5f8c..c0c908186 100755 --- a/src/kernel/faction.c +++ b/src/kernel/faction.c @@ -607,7 +607,7 @@ struct spellbook * faction_get_spellbook(struct faction *f) if (f->magiegebiet != M_GRAY) { return get_spellbook(magic_school[f->magiegebiet]); } - return 0; + return NULL; } static int allied_skillcount(const faction * f, skill_t sk) diff --git a/src/kernel/gamedata.h b/src/kernel/gamedata.h index c6378733f..1d65f5085 100644 --- a/src/kernel/gamedata.h +++ b/src/kernel/gamedata.h @@ -39,8 +39,9 @@ #define FIXATKEYS_VERSION 361 /* remove global.attribs, fix at_keys */ #define FACTION_UID_VERSION 362 /* f->uid contains a database id */ #define CRYPT_VERSION 363 /* passwords are encrypted */ +#define FAMILIAR_FIXMAGE_VERSION 364 /* familiar links are fixed */ -#define RELEASE_VERSION CRYPT_VERSION /* current datafile */ +#define RELEASE_VERSION FAMILIAR_FIXMAGE_VERSION /* current datafile */ #define MIN_VERSION UIDHASH_VERSION /* minimal datafile we support */ #define MAX_VERSION RELEASE_VERSION /* change this if we can need to read the future datafile, and we can do so */ diff --git a/src/kernel/save.c b/src/kernel/save.c index 1d67c2860..cfa254bf4 100644 --- a/src/kernel/save.c +++ b/src/kernel/save.c @@ -1293,50 +1293,63 @@ ship *read_ship(gamedata *data) return sh; } +static void fix_fam_mage(unit *u) { + sc_mage *m = get_mage(u); + if (m && m->magietyp != M_GRAY) { + /* unit should be a familiar that has aura and a spell-list */ + if (!m->spellbook) { + m->magietyp = M_GRAY; + } + } +} -static void fix_familiars(void) { +static void fix_fam_triggers(unit *u) { + attrib * a = a_find(u->attribs, &at_mage); + attrib * am = a_find(u->attribs, &at_familiarmage); + if (!am && a) { + /* not a familiar, but magical */ + attrib * ae = a_find(u->attribs, &at_eventhandler); + if (ae) { + trigger **tlist; + tlist = get_triggers(ae, "destroy"); + if (tlist) { + trigger *t; + unit *um = NULL; + for (t = *tlist; t; t = t->next) { + if (t->type == &tt_shock) { + um = (unit *)t->data.v; + break; + } + } + if (um) { + attrib *af = a_find(um->attribs, &at_familiar); + log_error("%s seems to be a broken familiar of %s.", + unitname(u), unitname(um)); + if (af) { + unit * uf = (unit *)af->data.v; + log_error("%s already has a familiar: %s.", + unitname(um), unitname(uf)); + } + else { + set_familiar(um, u); + } + } + else { + log_error("%s seems to be a broken familiar with no trigger.", unitname(u)); + } + } + } + } +} + +static void fix_familiars(void (*callback)(unit *)) { region *r; for (r = regions; r; r = r->next) { unit * u; for (u = r->units; u; u = u->next) { if (u->_race != u->faction->race && (u->_race->flags & RCF_FAMILIAR)) { /* unit is potentially a familiar */ - attrib * a = a_find(u->attribs, &at_mage); - attrib * am = a_find(u->attribs, &at_familiarmage); - if (!am && a) { - /* not a familiar, but magical */ - attrib * ae = a_find(u->attribs, &at_eventhandler); - if (ae) { - trigger **tlist; - tlist = get_triggers(ae, "destroy"); - if (tlist) { - trigger *t; - unit *um = NULL; - for (t = *tlist; t; t = t->next) { - if (t->type == &tt_shock) { - um = (unit *)t->data.v; - break; - } - } - if (um) { - attrib *af = a_find(um->attribs, &at_familiar); - log_error("%s seems to be a broken familiar of %s.", - unitname(u), unitname(um)); - if (af) { - unit * uf = (unit *)af->data.v; - log_error("%s already has a familiar: %s.", - unitname(um), unitname(uf)); - } - else { - set_familiar(um, u); - } - } - else { - log_error("%s seems to be a broken familiar with no trigger.", unitname(u)); - } - } - } - } + callback(u); } } } @@ -1524,7 +1537,10 @@ int read_game(gamedata *data) } if (data->version < FAMILIAR_FIX_VERSION) { - fix_familiars(); + fix_familiars(fix_fam_triggers); + } + if (data->version < FAMILIAR_FIXMAGE_VERSION) { + fix_familiars(fix_fam_mage); } log_debug("Done loading turn %d.", turn); diff --git a/src/kernel/unit.c b/src/kernel/unit.c index 637a83a53..369d099cc 100644 --- a/src/kernel/unit.c +++ b/src/kernel/unit.c @@ -1671,7 +1671,7 @@ struct spellbook * unit_get_spellbook(const struct unit * u) return faction_get_spellbook(u->faction); } } - return 0; + return NULL; } int effskill(const unit * u, skill_t sk, const region *r) diff --git a/src/magic.c b/src/magic.c index d5eb7341e..ae2eb78b5 100644 --- a/src/magic.c +++ b/src/magic.c @@ -904,6 +904,7 @@ cancast(unit * u, const spell * sp, int level, int range, struct order * ord) itemhave = get_pooled(u, rtype, GET_DEFAULT, itemanz); if (itemhave < itemanz) { resource *res = malloc(sizeof(resource)); + assert(res); res->number = itemanz - itemhave; res->type = rtype; res->next = reslist; @@ -2874,7 +2875,7 @@ spell *unit_getspell(struct unit *u, const char *name, const struct locale * lan sb = unit_get_spellbook(u); if (sb) { - void * tokens = 0; + void * tokens = NULL; select_spellbook(&tokens, sb, lang); if (tokens) { variant token; @@ -2885,7 +2886,7 @@ spell *unit_getspell(struct unit *u, const char *name, const struct locale * lan freetokens(tokens); } } - return 0; + return NULL; } int cast_spell(struct castorder *co) diff --git a/src/spells.c b/src/spells.c index 036da77a8..9416c911c 100644 --- a/src/spells.c +++ b/src/spells.c @@ -476,8 +476,21 @@ report_effect(region * r, unit * mage, message * seen, message * unseen) static const race *select_familiar(const race * magerace, magic_t magiegebiet) { - const race *retval = 0; + const race *retval; int rnd = rng_int() % 100; + static const race *rcfixed; + static int config; + + if (config_changed(&config)) { + const char *rcname = config_get("magic.familiar.race"); + rcfixed = NULL; + if (rcname) { + rcfixed = rc_find(rcname); + } + } + if (rcfixed) { + return rcfixed; + } assert(magerace->familiars[0]); if (rnd >= 70) { @@ -534,19 +547,19 @@ static unit * make_familiar(unit * mage, region *r, const race *rc, const char * static int sp_summon_familiar(castorder * co) { region *r = co_get_region(co); - unit *mage = co_get_magician(co); + unit *caster = co_get_caster(co); int cast_level = co->level; const race *rc; message *msg; char zText[2048]; - if (get_familiar(mage) != NULL) { - cmistake(mage, co->order, 199, MSG_MAGIC); + if (get_familiar(caster) != NULL) { + cmistake(caster, co->order, 199, MSG_MAGIC); return 0; } - rc = select_familiar(mage->_race, mage->faction->magiegebiet); + rc = select_familiar(caster->_race, caster->faction->magiegebiet); if (rc == NULL) { - log_error("could not find suitable familiar for %s.\n", mage->faction->race->_name); + log_error("could not find suitable familiar for %s.\n", caster->faction->race->_name); return 0; } @@ -555,7 +568,7 @@ static int sp_summon_familiar(castorder * co) int dir, dh; if (coasts == 0) { - cmistake(mage, co->order, 229, MSG_MAGIC); + cmistake(caster, co->order, 229, MSG_MAGIC); return 0; } @@ -574,14 +587,14 @@ static int sp_summon_familiar(castorder * co) } } - msg = msg_message("familiar_name", "unit", mage); - nr_render(msg, mage->faction->locale, zText, sizeof(zText), mage->faction); + msg = msg_message("familiar_name", "unit", caster); + nr_render(msg, caster->faction->locale, zText, sizeof(zText), caster->faction); msg_release(msg); - make_familiar(mage, r, rc, zText); + make_familiar(caster, r, rc, zText); - report_race_skills(rc, zText, sizeof(zText), mage->faction->locale); - ADDMSG(&mage->faction->msgs, msg_message("familiar_describe", - "mage race skills", mage, rc, zText)); + report_race_skills(rc, zText, sizeof(zText), caster->faction->locale); + ADDMSG(&caster->faction->msgs, msg_message("familiar_describe", + "mage race skills", caster, rc, zText)); return cast_level; } @@ -600,7 +613,7 @@ static int sp_summon_familiar(castorder * co) * */ static int sp_destroy_magic(castorder * co) { - unit *mage = co_get_magician(co); + unit *caster = co_get_caster(co); int cast_level = co->level; double force = co->force; spellparameter *pa = co->par; @@ -623,7 +636,7 @@ static int sp_destroy_magic(castorder * co) /* region *tr = pa->param[0]->data.r; -- farcasting! */ region *tr = co_get_region(co); ap = &tr->attribs; - write_regionname(tr, mage->faction, ts, sizeof(ts)); + write_regionname(tr, caster->faction, ts, sizeof(ts)); break; } case SPP_TEMP: @@ -658,13 +671,13 @@ static int sp_destroy_magic(castorder * co) succ = break_curse(ap, cast_level, force, c); if (succ) { - ADDMSG(&mage->faction->msgs, msg_message("destroy_magic_effect", - "unit region command succ target", mage, mage->region, co->order, succ, + ADDMSG(&caster->faction->msgs, msg_message("destroy_magic_effect", + "unit region command succ target", caster, caster->region, co->order, succ, ts)); } else { - ADDMSG(&mage->faction->msgs, msg_message("destroy_magic_noeffect", - "unit region command", mage, mage->region, co->order)); + ADDMSG(&caster->faction->msgs, msg_message("destroy_magic_noeffect", + "unit region command", caster, caster->region, co->order)); } if (succ < 1) succ = 1; @@ -692,11 +705,11 @@ static int sp_destroy_magic(castorder * co) static int sp_transferaura(castorder * co) { int aura, gain, multi = 2; - unit *mage = co_get_magician(co); + unit *caster = co_get_caster(co); int cast_level = co->level; spellparameter *pa = co->par; unit *u; - sc_mage *scm_dst, *scm_src = get_mage_depr(mage); + sc_mage *scm_dst, *scm_src = get_mage(caster); /* wenn kein Ziel gefunden, Zauber abbrechen */ if (pa->param[0]->flag == TARGET_NOTFOUND) @@ -714,7 +727,7 @@ static int sp_transferaura(castorder * co) if (scm_dst == NULL) { /* "Zu dieser Einheit kann ich keine Aura uebertragen." */ - cmistake(mage, co->order, 207, MSG_MAGIC); + cmistake(caster, co->order, 207, MSG_MAGIC); return 0; } else if (scm_src->magietyp == M_TYBIED) { @@ -727,13 +740,13 @@ static int sp_transferaura(castorder * co) } else if (scm_dst->magietyp != scm_src->magietyp) { /* "Zu dieser Einheit kann ich keine Aura uebertragen." */ - cmistake(mage, co->order, 207, MSG_MAGIC); + cmistake(caster, co->order, 207, MSG_MAGIC); return 0; } if (aura < multi) { /* "Auraangabe fehlerhaft." */ - cmistake(mage, co->order, 208, MSG_MAGIC); + cmistake(caster, co->order, 208, MSG_MAGIC); return 0; } @@ -745,8 +758,8 @@ static int sp_transferaura(castorder * co) /* sprintf(buf, "%s transferiert %d Aura auf %s", unitname(mage), gain, unitname(u)); */ - ADDMSG(&mage->faction->msgs, msg_message("auratransfer_success", - "unit target aura", mage, u, gain)); + ADDMSG(&caster->faction->msgs, msg_message("auratransfer_success", + "unit target aura", caster, u, gain)); return cast_level; } @@ -768,7 +781,7 @@ static int sp_transferaura(castorder * co) static int sp_goodwinds(castorder * co) { region *r = co_get_region(co); - unit *mage = co_get_magician(co); + unit *caster = co_get_caster(co); int cast_level = co->level; double power = co->force; int duration = cast_level + 1; @@ -785,14 +798,14 @@ static int sp_goodwinds(castorder * co) /* keine Probleme mit C_SHIP_SPEEDUP und C_SHIP_FLYING */ /* NODRIFT bewirkt auch +1 Geschwindigkeit */ - create_curse(mage, &sh->attribs, &ct_nodrift, power, duration, + create_curse(caster, &sh->attribs, &ct_nodrift, power, duration, zero_effect, 0); /* melden, 1x pro Partei */ - freset(mage->faction, FFL_SELECT); + freset(caster->faction, FFL_SELECT); for (u = r->units; u; u = u->next) freset(u->faction, FFL_SELECT); - m = msg_message("wind_effect", "mage ship", mage, sh); + m = msg_message("wind_effect", "mage ship", caster, sh); for (u = r->units; u; u = u->next) { if (u->ship != sh) /* nur den Schiffsbesatzungen! */ continue; @@ -801,8 +814,8 @@ static int sp_goodwinds(castorder * co) fset(u->faction, FFL_SELECT); } } - if (!fval(mage->faction, FFL_SELECT)) { - r_addmessage(r, mage->faction, m); + if (!fval(caster->faction, FFL_SELECT)) { + r_addmessage(r, caster->faction, m); } msg_release(m); @@ -824,22 +837,22 @@ static int sp_goodwinds(castorder * co) static int sp_magicstreet(castorder * co) { region *r = co_get_region(co); - unit *mage = co_get_magician(co); + unit *caster = co_get_caster(co); if (!fval(r->terrain, LAND_REGION)) { - cmistake(mage, co->order, 186, MSG_MAGIC); + cmistake(caster, co->order, 186, MSG_MAGIC); return 0; } /* wirkt schon in der Zauberrunde! */ - create_curse(mage, &r->attribs, &ct_magicstreet, co->force, + create_curse(caster, &r->attribs, &ct_magicstreet, co->force, co->level + 1, zero_effect, 0); /* melden, 1x pro Partei */ { - message *seen = msg_message("path_effect", "mage region", mage, r); + message *seen = msg_message("path_effect", "mage region", caster, r); message *unseen = msg_message("path_effect", "mage region", (unit *)NULL, r); - report_effect(r, mage, seen, unseen); + report_effect(r, caster, seen, unseen); msg_release(seen); msg_release(unseen); } @@ -865,7 +878,7 @@ static int sp_magicstreet(castorder * co) static int sp_summonent(castorder * co) { region *r = co_get_region(co); - unit *mage = co_get_magician(co); + unit *caster = co_get_caster(co); int cast_level = co->level; double power = co->force; unit *u; @@ -873,7 +886,7 @@ static int sp_summonent(castorder * co) int ents, p2; if (rtrees(r, 2) == 0) { - cmistake(mage, co->order, 204, MSG_EVENT); + cmistake(caster, co->order, 204, MSG_EVENT); /* nicht ohne baeume */ return 0; } @@ -882,7 +895,7 @@ static int sp_summonent(castorder * co) p2 = (int)(power * power); if (ents > p2) ents = p2; - u = create_unit(r, mage->faction, ents, get_race(RC_TREEMAN), 0, NULL, mage); + u = create_unit(r, caster->faction, ents, get_race(RC_TREEMAN), 0, NULL, caster); a = a_new(&at_unitdissolve); a->data.ca[0] = 2; /* An r->trees. */ @@ -894,9 +907,9 @@ static int sp_summonent(castorder * co) /* melden, 1x pro Partei */ { - message *seen = msg_message("ent_effect", "mage amount", mage, ents); + message *seen = msg_message("ent_effect", "mage amount", caster, ents); message *unseen = msg_message("ent_effect", "mage amount", (unit *)NULL, ents); - report_effect(r, mage, seen, unseen); + report_effect(r, caster, seen, unseen); msg_release(unseen); msg_release(seen); } @@ -921,7 +934,7 @@ static int sp_blessstonecircle(castorder * co) { building *b; region *r = co_get_region(co); - unit *mage = co_get_magician(co); + unit *caster = co_get_caster(co); int cast_level = co->level; spellparameter *p = co->par; message *msg; @@ -933,20 +946,20 @@ static int sp_blessstonecircle(castorder * co) b = p->param[0]->data.b; if (!is_building_type(b->type, "stonecircle")) { - ADDMSG(&mage->faction->msgs, msg_feedback(mage, co->order, + ADDMSG(&caster->faction->msgs, msg_feedback(caster, co->order, "error_notstonecircle", "building", b)); return 0; } if (!building_finished(b)) { - ADDMSG(&mage->faction->msgs, msg_feedback(mage, co->order, + ADDMSG(&caster->faction->msgs, msg_feedback(caster, co->order, "error_notcomplete", "building", b)); return 0; } b->type = bt_find("blessedstonecircle"); - msg = msg_message("blessedstonecircle_effect", "mage building", mage, b); + msg = msg_message("blessedstonecircle_effect", "mage building", caster, b); add_message(&r->msgs, msg); msg_release(msg); @@ -970,13 +983,13 @@ static int sp_blessstonecircle(castorder * co) static int sp_maelstrom(castorder * co) { region *r = co_get_region(co); - unit *mage = co_get_magician(co); + unit *caster = co_get_caster(co); int cast_level = co->level; curse *c; int duration = (int)co->force + 1; if (!fval(r->terrain, SEA_REGION)) { - cmistake(mage, co->order, 205, MSG_MAGIC); + cmistake(caster, co->order, 205, MSG_MAGIC); /* nur auf ozean */ return 0; } @@ -984,13 +997,13 @@ static int sp_maelstrom(castorder * co) /* Attribut auf Region. * Existiert schon ein curse, so wird dieser verstaerkt * (Max(Dauer), Max(Staerke))*/ - c = create_curse(mage, &r->attribs, &ct_maelstrom, co->force, duration, co->force, 0); + c = create_curse(caster, &r->attribs, &ct_maelstrom, co->force, duration, co->force, 0); /* melden, 1x pro Partei */ if (c) { - message *seen = msg_message("maelstrom_effect", "mage", mage); + message *seen = msg_message("maelstrom_effect", "mage", caster); message *unseen = msg_message("maelstrom_effect", "mage", (unit *)NULL); - report_effect(r, mage, seen, unseen); + report_effect(r, caster, seen, unseen); msg_release(seen); msg_release(unseen); } @@ -1013,14 +1026,14 @@ static int sp_mallorn(castorder * co) { region *r = co_get_region(co); int cast_level = co->level; - unit *mage = co_get_magician(co); + unit *caster = co_get_caster(co); if (!fval(r->terrain, LAND_REGION)) { - cmistake(mage, co->order, 186, MSG_MAGIC); + cmistake(caster, co->order, 186, MSG_MAGIC); return 0; } if (fval(r, RF_MALLORN)) { - cmistake(mage, co->order, 191, MSG_MAGIC); + cmistake(caster, co->order, 191, MSG_MAGIC); return 0; } @@ -1032,9 +1045,9 @@ static int sp_mallorn(castorder * co) /* melden, 1x pro Partei */ { - message *seen = msg_message("mallorn_effect", "mage", mage); + message *seen = msg_message("mallorn_effect", "mage", caster); message *unseen = msg_message("mallorn_effect", "mage", (unit *)NULL); - report_effect(r, mage, seen, unseen); + report_effect(r, caster, seen, unseen); msg_release(seen); msg_release(unseen); } @@ -1057,19 +1070,19 @@ static int sp_mallorn(castorder * co) static int sp_blessedharvest(castorder * co) { region *r = co_get_region(co); - unit *mage = co_get_magician(co); + unit *caster = co_get_caster(co); int cast_level = co->level; int duration = (int)co->force + 1; /* Attribut auf Region. * Existiert schon ein curse, so wird dieser verstaerkt * (Max(Dauer), Max(Staerke))*/ - if (create_curse(mage, &r->attribs, &ct_blessedharvest, co->force, + if (create_curse(caster, &r->attribs, &ct_blessedharvest, co->force, duration, 1.0, 0)) { const char * effect = co->sp->sname[0]=='b' ? "harvest_effect" : "raindance_effect"; - message *seen = msg_message(effect, "mage", mage); + message *seen = msg_message(effect, "mage", caster); message *unseen = msg_message(effect, "mage", (unit *)NULL); - report_effect(r, mage, seen, unseen); + report_effect(r, caster, seen, unseen); msg_release(seen); msg_release(unseen); } @@ -1094,16 +1107,16 @@ static int sp_hain(castorder * co) { int trees; region *r = co_get_region(co); - unit *mage = co_get_magician(co); + unit *caster = co_get_caster(co); int cast_level = co->level; double force = co->force; if (!r->land) { - cmistake(mage, co->order, 296, MSG_MAGIC); + cmistake(caster, co->order, 296, MSG_MAGIC); return 0; } if (fval(r, RF_MALLORN)) { - cmistake(mage, co->order, 92, MSG_MAGIC); + cmistake(caster, co->order, 92, MSG_MAGIC); return 0; } @@ -1112,10 +1125,10 @@ static int sp_hain(castorder * co) /* melden, 1x pro Partei */ { - message *seen = msg_message("growtree_effect", "mage amount", mage, trees); + message *seen = msg_message("growtree_effect", "mage amount", caster, trees); message *unseen = msg_message("growtree_effect", "mage amount", (unit *)NULL, trees); - report_effect(r, mage, seen, unseen); + report_effect(r, caster, seen, unseen); msg_release(seen); msg_release(unseen); } @@ -1140,16 +1153,16 @@ static int sp_mallornhain(castorder * co) { int trees; region *r = co_get_region(co); - unit *mage = co_get_magician(co); + unit *caster = co_get_caster(co); int cast_level = co->level; double force = co->force; if (!r->land) { - cmistake(mage, co->order, 296, MSG_MAGIC); + cmistake(caster, co->order, 296, MSG_MAGIC); return 0; } if (!fval(r, RF_MALLORN)) { - cmistake(mage, co->order, 91, MSG_MAGIC); + cmistake(caster, co->order, 91, MSG_MAGIC); return 0; } @@ -1158,10 +1171,10 @@ static int sp_mallornhain(castorder * co) /* melden, 1x pro Partei */ { - message *seen = msg_message("growtree_effect", "mage amount", mage, trees); + message *seen = msg_message("growtree_effect", "mage amount", caster, trees); message *unseen = msg_message("growtree_effect", "mage amount", (unit *)NULL, trees); - report_effect(r, mage, seen, unseen); + report_effect(r, caster, seen, unseen); msg_release(seen); msg_release(unseen); } @@ -1174,7 +1187,7 @@ static void fumble_ents(const castorder * co) int ents; unit *u; region *r = co_get_region(co); - unit *mage = co_get_magician(co); + unit *mage = co_get_caster(co); /* int cast_level = co->level; */ double force = co->force; @@ -1240,7 +1253,7 @@ static int sp_rosthauch(castorder * co) int n; int success = 0; region *r = co_get_region(co); - unit *mage = co_get_magician(co); + unit *caster = co_get_caster(co); int cast_level = co->level; int force = (int)co->force; spellparameter *pa = co->par; @@ -1293,17 +1306,17 @@ static int sp_rosthauch(castorder * co) if (ironweapon > 0) { /* {$mage mage} legt einen Rosthauch auf {target}. {amount} Waffen * wurden vom Rost zerfressen */ - ADDMSG(&mage->faction->msgs, msg_message("rust_effect", - "mage target amount", mage, u, ironweapon)); + ADDMSG(&caster->faction->msgs, msg_message("rust_effect", + "mage target amount", caster, u, ironweapon)); ADDMSG(&u->faction->msgs, msg_message("rust_effect", "mage target amount", - cansee(u->faction, r, mage, 0) ? mage : NULL, u, ironweapon)); + cansee(u->faction, r, caster, 0) ? caster : NULL, u, ironweapon)); success += ironweapon; } else { /* {$mage mage} legt einen Rosthauch auf {target}, doch der * Rosthauch fand keine Nahrung */ - ADDMSG(&mage->faction->msgs, msg_message("rust_fail", "mage target", mage, + ADDMSG(&caster->faction->msgs, msg_message("rust_fail", "mage target", caster, u)); } } @@ -1338,7 +1351,7 @@ static int sp_kaelteschutz(castorder * co) int n, i = 0; int men; region *r = co_get_region(co); - unit *mage = co_get_magician(co); + unit *caster = co_get_caster(co); int cast_level = co->level; double force = co->force; double effect; @@ -1369,15 +1382,15 @@ static int sp_kaelteschutz(castorder * co) } effect = 1; - create_curse(mage, &u->attribs, &ct_insectfur, (float)cast_level, + create_curse(caster, &u->attribs, &ct_insectfur, (float)cast_level, duration, effect, men); force -= u->number; - ADDMSG(&mage->faction->msgs, msg_message("heat_effect", "mage target", mage, + ADDMSG(&caster->faction->msgs, msg_message("heat_effect", "mage target", caster, u)); - if (u->faction != mage->faction) + if (u->faction != caster->faction) ADDMSG(&u->faction->msgs, msg_message("heat_effect", "mage target", - cansee(u->faction, r, mage, 0) ? mage : NULL, u)); + cansee(u->faction, r, caster, 0) ? caster : NULL, u)); i = cast_level; } /* Erstattung? */ @@ -1402,7 +1415,7 @@ static int sp_kaelteschutz(castorder * co) static int sp_sparkle(castorder * co) { unit *u; - unit *mage = co_get_magician(co); + unit *caster = co_get_caster(co); int cast_level = co->level; spellparameter *pa = co->par; int duration = cast_level + 1; @@ -1419,13 +1432,13 @@ static int sp_sparkle(castorder * co) u = pa->param[0]->data.u; effect = (float)(rng_int() % 0xffffff); - create_curse(mage, &u->attribs, &ct_sparkle, (float)cast_level, + create_curse(caster, &u->attribs, &ct_sparkle, (float)cast_level, duration, effect, u->number); - ADDMSG(&mage->faction->msgs, msg_message("sparkle_effect", "mage target", - mage, u)); - if (u->faction != mage->faction) { - ADDMSG(&u->faction->msgs, msg_message("sparkle_effect", "mage target", mage, + ADDMSG(&caster->faction->msgs, msg_message("sparkle_effect", "mage target", + caster, u)); + if (u->faction != caster->faction) { + ADDMSG(&u->faction->msgs, msg_message("sparkle_effect", "mage target", caster, u)); } @@ -1464,7 +1477,7 @@ static int sp_create_irongolem(castorder * co) unit *u2; attrib *a; region *r = co_get_region(co); - unit *mage = co_get_magician(co); + unit *caster = co_get_caster(co); int cast_level = co->level; double force = co->force; int number = lovar(force * 8 * RESOURCE_QUANTITY); @@ -1480,11 +1493,11 @@ static int sp_create_irongolem(castorder * co) } if (r->terrain == newterrain(T_SWAMP)) { - cmistake(mage, co->order, 188, MSG_MAGIC); + cmistake(caster, co->order, 188, MSG_MAGIC); return 0; } - u2 = create_unit(r, mage->faction, number, golem_rc, 0, NULL, mage); + u2 = create_unit(r, caster->faction, number, golem_rc, 0, NULL, caster); set_level(u2, SK_ARMORER, 1); set_level(u2, SK_WEAPONSMITH, 1); @@ -1494,10 +1507,10 @@ static int sp_create_irongolem(castorder * co) a->data.ca[1] = IRONGOLEM_CRUMBLE; a_add(&u2->attribs, a); - ADDMSG(&mage->faction->msgs, + ADDMSG(&caster->faction->msgs, msg_message("magiccreate_effect", "region command unit amount object", - mage->region, co->order, mage, number, - LOC(mage->faction->locale, rc_name_s(golem_rc, (u2->number == 1) ? NAME_SINGULAR : NAME_PLURAL)))); + caster->region, co->order, caster, number, + LOC(caster->faction->locale, rc_name_s(golem_rc, (u2->number == 1) ? NAME_SINGULAR : NAME_PLURAL)))); return cast_level; } @@ -1534,7 +1547,7 @@ static int sp_create_stonegolem(castorder * co) unit *u2; attrib *a; region *r = co_get_region(co); - unit *mage = co_get_magician(co); + unit *caster = co_get_caster(co); int cast_level = co->level; int number = lovar(co->force * 5 * RESOURCE_QUANTITY); static int cache; @@ -1547,12 +1560,12 @@ static int sp_create_stonegolem(castorder * co) number = 1; if (r->terrain == newterrain(T_SWAMP)) { - cmistake(mage, co->order, 188, MSG_MAGIC); + cmistake(caster, co->order, 188, MSG_MAGIC); return 0; } u2 = - create_unit(r, mage->faction, number, golem_rc, 0, NULL, mage); + create_unit(r, caster->faction, number, golem_rc, 0, NULL, caster); set_level(u2, SK_ROAD_BUILDING, 1); set_level(u2, SK_BUILDING, 1); @@ -1561,10 +1574,10 @@ static int sp_create_stonegolem(castorder * co) a->data.ca[1] = STONEGOLEM_CRUMBLE; a_add(&u2->attribs, a); - ADDMSG(&mage->faction->msgs, + ADDMSG(&caster->faction->msgs, msg_message("magiccreate_effect", "region command unit amount object", - mage->region, co->order, mage, number, - LOC(mage->faction->locale, rc_name_s(golem_rc, (u2->number == 1) ? NAME_SINGULAR : NAME_PLURAL)))); + caster->region, co->order, caster, number, + LOC(caster->faction->locale, rc_name_s(golem_rc, (u2->number == 1) ? NAME_SINGULAR : NAME_PLURAL)))); return cast_level; } @@ -1602,14 +1615,14 @@ static int sp_great_drought(castorder * co) unit *u; bool terraform = false; region *r = co_get_region(co); - unit *mage = co_get_magician(co); + unit *caster = co_get_caster(co); int cast_level = co->level; double force = co->force; int duration = 2; double effect; if (fval(r->terrain, SEA_REGION)) { - cmistake(mage, co->order, 189, MSG_MAGIC); + cmistake(caster, co->order, 189, MSG_MAGIC); /* TODO: vielleicht einen netten Patzer hier? */ return 0; } @@ -1623,7 +1636,7 @@ static int sp_great_drought(castorder * co) /* Arbeitslohn = 1/4 */ effect = 4.0; /* curses: higher is stronger */ - create_curse(mage, &r->attribs, &ct_drought, force, duration, effect, + create_curse(caster, &r->attribs, &ct_drought, force, duration, effect, 0); /* terraforming */ @@ -1686,14 +1699,14 @@ static int sp_great_drought(castorder * co) else { mtype = "drought_effect_3"; } - msg = msg_message(mtype, "mage region", mage, r); + msg = msg_message(mtype, "mage region", caster, r); add_message(&r->msgs, msg); msg_release(msg); } else { /* possible that all units here get killed so better to inform with a global * message */ - message *msg = msg_message("drought_effect_4", "mage region", mage, r); + message *msg = msg_message("drought_effect_4", "mage region", caster, r); for (u = r->units; u; u = u->next) freset(u->faction, FFL_SELECT); for (u = r->units; u; u = u->next) { @@ -1702,8 +1715,8 @@ static int sp_great_drought(castorder * co) add_message(&u->faction->msgs, msg); } } - if (!fval(mage->faction, FFL_SELECT)) { - add_message(&mage->faction->msgs, msg); + if (!fval(caster->faction, FFL_SELECT)) { + add_message(&caster->faction->msgs, msg); } msg_release(msg); } @@ -1729,7 +1742,7 @@ static int sp_great_drought(castorder * co) static int sp_treewalkenter(castorder * co) { region *r = co_get_region(co); - unit *mage = co_get_magician(co); + unit *caster = co_get_caster(co); spellparameter *pa = co->par; double power = co->force; int cast_level = co->level; @@ -1739,19 +1752,19 @@ static int sp_treewalkenter(castorder * co) int erfolg = 0; if (getplane(r) != 0) { - cmistake(mage, co->order, 190, MSG_MAGIC); + cmistake(caster, co->order, 190, MSG_MAGIC); return 0; } if (!r_isforest(r)) { - cmistake(mage, co->order, 191, MSG_MAGIC); + cmistake(caster, co->order, 191, MSG_MAGIC); return 0; } rt = r_standard_to_astral(r); if (rt == NULL || is_cursed(rt->attribs, &ct_astralblock) || fval(rt->terrain, FORBIDDEN_REGION)) { - ADDMSG(&mage->faction->msgs, msg_feedback(mage, co->order, + ADDMSG(&caster->faction->msgs, msg_feedback(caster, co->order, "spellfail_astralblock", "")); return 0; } @@ -1767,8 +1780,8 @@ static int sp_treewalkenter(castorder * co) continue; } - if (!ucontact(u, mage)) { - ADDMSG(&mage->faction->msgs, msg_feedback(mage, co->order, + if (!ucontact(u, caster)) { + ADDMSG(&caster->faction->msgs, msg_feedback(caster, co->order, "feedback_no_contact", "target", u)); } else { @@ -1777,13 +1790,13 @@ static int sp_treewalkenter(castorder * co) unit *u2; if (!can_survive(u, rt)) { - cmistake(mage, co->order, 231, MSG_MAGIC); + cmistake(caster, co->order, 231, MSG_MAGIC); continue; } w = weight(u); if (remaining_cap - w < 0) { - ADDMSG(&mage->faction->msgs, msg_feedback(mage, co->order, + ADDMSG(&caster->faction->msgs, msg_feedback(caster, co->order, "fail_tooheavy", "target", u)); continue; } @@ -1855,18 +1868,18 @@ static int sp_treewalkexit(castorder * co) int n; int erfolg = 0; region *r = co_get_region(co); - unit *mage = co_get_magician(co); + unit *caster = co_get_caster(co); double power = co->force; spellparameter *pa = co->par; int cast_level = co->level; if (!is_astral(r)) { - ADDMSG(&mage->faction->msgs, msg_feedback(mage, co->order, + ADDMSG(&caster->faction->msgs, msg_feedback(caster, co->order, "spellfail_astralonly", "")); return 0; } if (is_cursed(r->attribs, &ct_astralblock)) { - ADDMSG(&mage->faction->msgs, msg_feedback(mage, co->order, + ADDMSG(&caster->faction->msgs, msg_feedback(caster, co->order, "spellfail_astralblock", "")); return 0; } @@ -1874,7 +1887,7 @@ static int sp_treewalkexit(castorder * co) remaining_cap = (int)(power * 500); if (pa->param[0]->typ != SPP_REGION) { - report_failure(mage, co->order); + report_failure(caster, co->order); return 0; } @@ -1898,12 +1911,12 @@ static int sp_treewalkexit(castorder * co) free_regionlist(rl); if (!rt) { - cmistake(mage, co->order, 195, MSG_MAGIC); + cmistake(caster, co->order, 195, MSG_MAGIC); return 0; } if (!r_isforest(rt)) { - cmistake(mage, co->order, 196, MSG_MAGIC); + cmistake(caster, co->order, 196, MSG_MAGIC); return 0; } @@ -1915,17 +1928,17 @@ static int sp_treewalkexit(castorder * co) u = pa->param[n]->data.u; - if (!ucontact(u, mage)) { - ADDMSG(&mage->faction->msgs, msg_feedback(mage, co->order, + if (!ucontact(u, caster)) { + ADDMSG(&caster->faction->msgs, msg_feedback(caster, co->order, "feedback_no_contact", "target", u)); } else { int w = weight(u); if (!can_survive(u, rt)) { - cmistake(mage, co->order, 231, MSG_MAGIC); + cmistake(caster, co->order, 231, MSG_MAGIC); } else if (remaining_cap - w < 0) { - ADDMSG(&mage->faction->msgs, msg_feedback(mage, co->order, + ADDMSG(&caster->faction->msgs, msg_feedback(caster, co->order, "fail_tooheavy", "target", u)); } else { @@ -1991,14 +2004,14 @@ static int sp_treewalkexit(castorder * co) static int sp_holyground(castorder * co) { region *r = co_get_region(co); - unit *mage = co_get_magician(co); + unit *caster = co_get_caster(co); int cast_level = co->level; double power = co->force; - message *msg = msg_message("sp_holyground_effect", "mage region", mage, r); - report_spell(mage, r, msg); + message *msg = msg_message("sp_holyground_effect", "mage region", caster, r); + report_spell(caster, r, msg); msg_release(msg); - create_curse(mage, &r->attribs, &ct_holyground, power * power, 1, zero_effect, 0); + create_curse(caster, &r->attribs, &ct_holyground, power * power, 1, zero_effect, 0); a_removeall(&r->attribs, &at_deathcount); @@ -2023,38 +2036,38 @@ static int sp_homestone(castorder * co) unit *u; curse *c; region *r = co_get_region(co); - unit *mage = co_get_magician(co); + unit *caster = co_get_caster(co); int cast_level = co->level; double force = co->force; double effect; message *msg; - if (!mage->building || !is_building_type(mage->building->type, "castle")) { - cmistake(mage, co->order, 197, MSG_MAGIC); + if (!caster->building || !is_building_type(caster->building->type, "castle")) { + cmistake(caster, co->order, 197, MSG_MAGIC); return 0; } - c = create_curse(mage, &mage->building->attribs, &ct_magicwalls, + c = create_curse(caster, &caster->building->attribs, &ct_magicwalls, force * force, 1, zero_effect, 0); if (c == NULL) { - cmistake(mage, co->order, 206, MSG_MAGIC); + cmistake(caster, co->order, 206, MSG_MAGIC); return 0; } /* Magieresistenz der Burg erhoeht sich um 50% */ effect = 50.0F; - c = create_curse(mage, &mage->building->attribs, + c = create_curse(caster, &caster->building->attribs, &ct_magicresistance, force * force, 1, effect, 0); c_setflag(c, CURSE_NOAGE); /* melden, 1x pro Partei in der Burg */ for (u = r->units; u; u = u->next) freset(u->faction, FFL_SELECT); - msg = msg_message("homestone_effect", "mage building", mage, mage->building); + msg = msg_message("homestone_effect", "mage building", caster, caster->building); for (u = r->units; u; u = u->next) { if (!fval(u->faction, FFL_SELECT)) { fset(u->faction, FFL_SELECT); - if (u->building == mage->building) { + if (u->building == caster->building) { r_addmessage(r, u->faction, msg); } } @@ -2081,21 +2094,21 @@ static int sp_drought(castorder * co) { curse *c; region *r = co_get_region(co); - unit *mage = co_get_magician(co); + unit *caster = co_get_caster(co); int cast_level = co->level; double power = co->force; int duration = (int)power + 1; message *msg; if (fval(r->terrain, SEA_REGION)) { - cmistake(mage, co->order, 189, MSG_MAGIC); + cmistake(caster, co->order, 189, MSG_MAGIC); /* TODO: vielleicht einen netten Patzer hier? */ return 0; } /* melden, 1x pro Partei */ - msg = msg_message("sp_drought_effect", "mage region", mage, r); - report_spell(mage, r, msg); + msg = msg_message("sp_drought_effect", "mage region", caster, r); + report_spell(caster, r, msg); msg_release(msg); /* Wenn schon Duerre herrscht, dann setzen wir nur den Power-Level @@ -2115,7 +2128,7 @@ static int sp_drought(castorder * co) rsettrees(r, 0, rtrees(r, 0) / 2); rsethorses(r, rhorses(r) / 2); - create_curse(mage, &r->attribs, &ct_drought, power, duration, effect, + create_curse(caster, &r->attribs, &ct_drought, power, duration, effect, 0); } return cast_level; @@ -2144,18 +2157,18 @@ static int sp_ironkeeper(castorder * co) { unit *keeper; region *r = co_get_region(co); - unit *mage = co_get_magician(co); + unit *caster = co_get_caster(co); int cast_level = co->level; message *msg; if (r->terrain != newterrain(T_MOUNTAIN) && r->terrain != newterrain(T_GLACIER)) { - report_failure(mage, co->order); + report_failure(caster, co->order); return 0; } keeper = - create_unit(r, mage->faction, 1, get_race(RC_IRONKEEPER), 0, NULL, mage); + create_unit(r, caster->faction, 1, get_race(RC_IRONKEEPER), 0, NULL, caster); /*keeper->age = cast_level + 2; */ unit_setstatus(keeper, ST_AVOID); /* kaempft nicht */ @@ -2172,7 +2185,7 @@ static int sp_ironkeeper(castorder * co) tkill)); } - msg = msg_message("summon_effect", "mage amount race", mage, 1, u_race(keeper)); + msg = msg_message("summon_effect", "mage amount race", caster, 1, u_race(keeper)); r_addmessage(r, NULL, msg); msg_release(msg); @@ -2203,14 +2216,14 @@ static int sp_stormwinds(castorder * co) unit *u; int erfolg = 0; region *r = co_get_region(co); - unit *mage = co_get_magician(co); + unit *caster = co_get_caster(co); double power = co->force; spellparameter *pa = co->par; int n, force = (int)power; message *m = NULL; /* melden vorbereiten */ - freset(mage->faction, FFL_SELECT); + freset(caster->faction, FFL_SELECT); for (u = r->units; u; u = u->next) freset(u->faction, FFL_SELECT); @@ -2226,18 +2239,18 @@ static int sp_stormwinds(castorder * co) /* mit C_SHIP_NODRIFT haben wir kein Problem */ if (is_cursed(sh->attribs, &ct_flyingship)) { - ADDMSG(&mage->faction->msgs, msg_feedback(mage, co->order, + ADDMSG(&caster->faction->msgs, msg_feedback(caster, co->order, "error_spell_on_flying_ship", "ship", sh)) continue; } if (is_cursed(sh->attribs, &ct_shipspeedup)) { - ADDMSG(&mage->faction->msgs, msg_feedback(mage, co->order, + ADDMSG(&caster->faction->msgs, msg_feedback(caster, co->order, "error_spell_on_ship_already", "ship", sh)) continue; } /* Duration = 1, nur diese Runde */ - create_curse(mage, &sh->attribs, &ct_stormwind, power, 1, + create_curse(caster, &sh->attribs, &ct_stormwind, power, 1, zero_effect, 0); /* Da der Spruch nur diese Runde wirkt wird er nie im Report * erscheinen */ @@ -2253,17 +2266,17 @@ static int sp_stormwinds(castorder * co) } } if (erfolg < pa->length) { - ADDMSG(&mage->faction->msgs, msg_message("stormwinds_reduced", - "unit ships maxships", mage, erfolg, pa->length)); + ADDMSG(&caster->faction->msgs, msg_message("stormwinds_reduced", + "unit ships maxships", caster, erfolg, pa->length)); } /* melden, 1x pro Partei auf Schiff und fuer den Magier */ - fset(mage->faction, FFL_SELECT); + fset(caster->faction, FFL_SELECT); for (u = r->units; u; u = u->next) { if (fval(u->faction, FFL_SELECT)) { freset(u->faction, FFL_SELECT); if (erfolg > 0) { if (!m) { - m = msg_message("stormwinds_effect", "unit", mage); + m = msg_message("stormwinds_effect", "unit", caster); } r_addmessage(r, u->faction, m); } @@ -2290,7 +2303,7 @@ static int sp_stormwinds(castorder * co) static int sp_earthquake(castorder * co) { region *r = co_get_region(co); - unit *mage = co_get_magician(co); + unit *caster = co_get_caster(co); int cast_level = co->level; message *msg; building **blist = &r->buildings; @@ -2300,7 +2313,7 @@ static int sp_earthquake(castorder * co) if (burg->size != 0 && !is_cursed(burg->attribs, &ct_magicwalls)) { /* Magieresistenz */ - if (!target_resists_magic(mage, burg, TYP_BUILDING, 0)) { + if (!target_resists_magic(caster, burg, TYP_BUILDING, 0)) { int kaputt = burg->size / 4; if (kaputt > 10 * cast_level) kaputt = 10 * cast_level; if (kaputt < 1) kaputt = 1; @@ -2316,7 +2329,7 @@ static int sp_earthquake(castorder * co) } /* melden, 1x pro Partei */ - msg = msg_message("earthquake_effect", "mage region", mage, r); + msg = msg_message("earthquake_effect", "mage region", caster, r); r_addmessage(r, NULL, msg); msg_release(msg); return cast_level; @@ -2325,13 +2338,12 @@ static int sp_earthquake(castorder * co) /* ------------------------------------------------------------- */ /* CHAOS / M_DRAIG / Draig */ /* ------------------------------------------------------------- */ -void patzer_peasantmob(const castorder * co) +static void patzer_peasantmob(const castorder * co) { unit *u; attrib *a; region *r; unit *mage = co_get_magician(co); - r = mage->region->land ? mage->region : co_get_region(co); if (r->land) { @@ -2396,7 +2408,7 @@ static int sp_forest_fire(castorder * co) region *nr; direction_t i; region *r = co_get_region(co); - unit *mage = co_get_magician(co); + unit *caster = co_get_caster(co); int cast_level = co->level; double probability; double percentage = (rng_int() % 8 + 1) * 0.1; /* 10 - 80% */ @@ -2406,7 +2418,7 @@ static int sp_forest_fire(castorder * co) int destroyed = (int)(rtrees(r, 2) * percentage); if (destroyed < 1) { - cmistake(mage, co->order, 198, MSG_MAGIC); + cmistake(caster, co->order, 198, MSG_MAGIC); return 0; } @@ -2418,10 +2430,10 @@ static int sp_forest_fire(castorder * co) for (u = r->units; u; u = u->next) freset(u->faction, FFL_SELECT); msg = - msg_message("forestfire_effect", "mage region amount", mage, r, + msg_message("forestfire_effect", "mage region amount", caster, r, destroyed + vernichtet_schoesslinge); r_addmessage(r, NULL, msg); - add_message(&mage->faction->msgs, msg); + add_message(&caster->faction->msgs, msg); msg_release(msg); for (i = 0; i < MAXDIRECTIONS; i++) { @@ -2448,7 +2460,7 @@ static int sp_forest_fire(castorder * co) r, nr, destroyed + vernichtet_schoesslinge); add_message(&r->msgs, m); - add_message(&mage->faction->msgs, m); + add_message(&caster->faction->msgs, m); msg_release(m); rsettrees(nr, 2, rtrees(nr, 2) - destroyed); @@ -2480,7 +2492,7 @@ static int sp_fumblecurse(castorder * co) { unit *target; int duration; - unit *mage = co_get_magician(co); + unit *caster = co_get_caster(co); int cast_level = co->level; double force = co->force; double effect; @@ -2501,10 +2513,10 @@ static int sp_fumblecurse(castorder * co) ++duration; effect = force / 2; - c = create_curse(mage, &target->attribs, &ct_fumble, + c = create_curse(caster, &target->attribs, &ct_fumble, force, duration, effect, 0); if (c == NULL) { - report_failure(mage, co->order); + report_failure(caster, co->order); return 0; } @@ -2514,7 +2526,7 @@ static int sp_fumblecurse(castorder * co) return cast_level; } -void patzer_fumblecurse(const castorder * co) +static void patzer_fumblecurse(const castorder * co) { unit *mage = co_get_magician(co); int cast_level = co->level; @@ -2554,7 +2566,7 @@ void patzer_fumblecurse(const castorder * co) static int sp_summondragon(castorder * co) { region *r = co_get_region(co); - unit *mage = co_get_magician(co); + unit *caster = co_get_caster(co); unit *u; int cast_level = co->level; double power = co->force; @@ -2568,7 +2580,7 @@ static int sp_summondragon(castorder * co) if (r->terrain != newterrain(T_SWAMP) && r->terrain != newterrain(T_DESERT) && r->terrain != newterrain(T_GLACIER)) { - report_failure(mage, co->order); + report_failure(caster, co->order); return 0; } @@ -2615,8 +2627,8 @@ static int sp_summondragon(castorder * co) } } - ADDMSG(&mage->faction->msgs, msg_message("summondragon", - "unit region command target", mage, mage->region, co->order, r)); + ADDMSG(&caster->faction->msgs, msg_message("summondragon", + "unit region command target", caster, caster->region, co->order, r)); free_regionlist(rl); return cast_level; @@ -2627,24 +2639,24 @@ static int sp_firewall(castorder * co) connection *b; wall_data *fd; region *r = co_get_region(co); - unit *mage = co_get_magician(co); + unit *caster = co_get_caster(co); int cast_level = co->level; double force = co->force; spellparameter *pa = co->par; direction_t dir; region *r2; - dir = get_direction(pa->param[0]->data.xs, mage->faction->locale); + dir = get_direction(pa->param[0]->data.xs, caster->faction->locale); if (dir < MAXDIRECTIONS && dir != NODIRECTION) { r2 = rconnect(r, dir); } else { - report_failure(mage, co->order); + report_failure(caster, co->order); return 0; } if (!r2 || r2 == r) { - report_failure(mage, co->order); + report_failure(caster, co->order); return 0; } @@ -2658,7 +2670,7 @@ static int sp_firewall(castorder * co) b = new_border(&bt_firewall, r, r2); fd = (wall_data *)b->data.v; fd->force = (int)(force / 2 + 0.5); - fd->mage = mage; + fd->mage = caster; fd->active = false; fd->countdown = cast_level + 1; } @@ -2671,9 +2683,9 @@ static int sp_firewall(castorder * co) /* melden, 1x pro Partei */ { - message *seen = msg_message("firewall_effect", "mage region", mage, r); + message *seen = msg_message("firewall_effect", "mage region", caster, r); message *unseen = msg_message("firewall_effect", "mage region", (unit *)NULL, r); - report_effect(r, mage, seen, unseen); + report_effect(r, caster, seen, unseen); msg_release(seen); msg_release(unseen); } @@ -2718,7 +2730,7 @@ static const race *unholy_race(const race *rc) { static int sp_unholypower(castorder * co) { region * r = co_get_region(co); - unit *mage = co_get_magician(co); + unit *caster = co_get_caster(co); int cast_level = co->level; spellparameter *pa = co->par; int i; @@ -2739,7 +2751,7 @@ static int sp_unholypower(castorder * co) target_race = unholy_race(u_race(u)); if (!target_race) { - cmistake(mage, co->order, 284, MSG_MAGIC); + cmistake(caster, co->order, 284, MSG_MAGIC); continue; } /* Untote heilen nicht, darum den neuen Untoten maximale hp geben @@ -2752,7 +2764,7 @@ static int sp_unholypower(castorder * co) u_setrace(u, target_race); u->hp = unit_max_hp(u) * u->number - wounds; ADDMSG(&r->msgs, msg_message("unholypower_effect", - "mage target race", mage, u, target_race)); + "mage target race", caster, u, target_race)); } else { unit *un; @@ -2763,7 +2775,7 @@ static int sp_unholypower(castorder * co) * waere es, eine solche Konstruktion irgendwie zu kapseln. */ if (fval(u, UFL_LOCKED) || fval(u, UFL_HUNGER) || is_cursed(u->attribs, &ct_slavery)) { - cmistake(mage, co->order, 74, MSG_MAGIC); + cmistake(caster, co->order, 74, MSG_MAGIC); continue; } /* Verletzungsanteil der transferierten Personen berechnen */ @@ -2773,7 +2785,7 @@ static int sp_unholypower(castorder * co) transfermen(u, un, n); un->hp = unit_max_hp(un) * n - wounds; ADDMSG(&r->msgs, msg_message("unholypower_limitedeffect", - "mage target race amount", mage, u, target_race, n)); + "mage target race amount", caster, u, target_race, n)); n = 0; } } @@ -2900,7 +2912,7 @@ static int dc_read_compat(variant *var, void *target, gamedata *data) static int sp_deathcloud(castorder * co) { region *r = co_get_region(co); - unit *mage = co_get_magician(co); + unit *caster = co_get_caster(co); attrib *a = r->attribs; unit *u; @@ -2908,7 +2920,7 @@ static int sp_deathcloud(castorder * co) if (a->type == &at_curse) { curse *c = a->data.v; if (c->type == &ct_deathcloud) { - report_failure(mage, co->order); + report_failure(caster, co->order); return 0; } a = a->next; @@ -2917,7 +2929,7 @@ static int sp_deathcloud(castorder * co) a = a->nexttype; } - mk_deathcloud(mage, r, co->force, co->level); + mk_deathcloud(caster, r, co->force, co->level); /* melden, 1x pro Partei */ for (u = r->units; u; u = u->next) @@ -2926,13 +2938,13 @@ static int sp_deathcloud(castorder * co) if (!fval(u->faction, FFL_SELECT)) { fset(u->faction, FFL_SELECT); ADDMSG(&u->faction->msgs, msg_message("deathcloud_effect", - "mage region", cansee(u->faction, r, mage, 0) ? mage : NULL, r)); + "mage region", cansee(u->faction, r, caster, 0) ? caster : NULL, r)); } } - if (!fval(mage->faction, FFL_SELECT)) { - ADDMSG(&mage->faction->msgs, msg_message("deathcloud_effect", - "mage region", mage, r)); + if (!fval(caster->faction, FFL_SELECT)) { + ADDMSG(&caster->faction->msgs, msg_message("deathcloud_effect", + "mage region", caster, r)); } return co->level; @@ -2964,13 +2976,13 @@ static void patzer_deathcloud(const castorder * co) static int sp_plague(castorder * co) { region *r = co_get_region(co); - unit *mage = co_get_magician(co); + unit *caster = co_get_caster(co); int cast_level = co->level; plagues(r); - ADDMSG(&mage->faction->msgs, msg_message("plague_spell", - "region mage", r, mage)); + ADDMSG(&caster->faction->msgs, msg_message("plague_spell", + "region mage", r, caster)); return cast_level; } @@ -2993,22 +3005,22 @@ static int sp_plague(castorder * co) static int sp_summonshadow(castorder * co) { region *r = co_get_region(co); - unit *mage = co_get_magician(co); + unit *caster = co_get_caster(co); int cast_level = co->level; double force = co->force; unit *u; int val, number = (int)(force * force); - u = create_unit(r, mage->faction, number, get_race(RC_SHADOW), 0, NULL, mage); + u = create_unit(r, caster->faction, number, get_race(RC_SHADOW), 0, NULL, caster); /* Bekommen Tarnung = (Magie+Tarnung)/2 und Wahrnehmung 1. */ - val = get_level(mage, SK_MAGIC) + get_level(mage, SK_STEALTH); + val = get_level(caster, SK_MAGIC) + get_level(caster, SK_STEALTH); set_level(u, SK_STEALTH, val); set_level(u, SK_PERCEPTION, 1); - ADDMSG(&mage->faction->msgs, msg_message("summonshadow_effect", - "mage number", mage, number)); + ADDMSG(&caster->faction->msgs, msg_message("summonshadow_effect", + "mage number", caster, number)); return cast_level; } @@ -3034,20 +3046,20 @@ static int sp_summonshadowlords(castorder * co) { unit *u; region *r = co_get_region(co); - unit *mage = co_get_magician(co); + unit *caster = co_get_caster(co); int cast_level = co->level; double force = co->force; int amount = (int)(force * force); - u = create_unit(r, mage->faction, amount, get_race(RC_SHADOWLORD), 0, - NULL, mage); + u = create_unit(r, caster->faction, amount, get_race(RC_SHADOWLORD), 0, + NULL, caster); /* Bekommen Tarnung = Magie und Wahrnehmung 5. */ - set_level(u, SK_STEALTH, get_level(mage, SK_MAGIC)); + set_level(u, SK_STEALTH, get_level(caster, SK_MAGIC)); set_level(u, SK_PERCEPTION, 5); - ADDMSG(&mage->faction->msgs, msg_message("summon_effect", "mage amount race", - mage, amount, u_race(u))); + ADDMSG(&caster->faction->msgs, msg_message("summon_effect", "mage amount race", + caster, amount, u_race(u))); return cast_level; } @@ -3067,12 +3079,12 @@ static int sp_chaossuction(castorder * co) { region *rt; region *r = co_get_region(co); - unit *mage = co_get_magician(co); + unit *caster = co_get_caster(co); int cast_level = co->level; if (rplane(r)) { /* Der Zauber funktioniert nur in der materiellen Welt. */ - cmistake(mage, co->order, 190, MSG_MAGIC); + cmistake(caster, co->order, 190, MSG_MAGIC); return 0; } @@ -3080,11 +3092,11 @@ static int sp_chaossuction(castorder * co) if (rt == NULL || fval(rt->terrain, FORBIDDEN_REGION)) { /* Hier gibt es keine Verbindung zur astralen Welt. */ - cmistake(mage, co->order, 216, MSG_MAGIC); + cmistake(caster, co->order, 216, MSG_MAGIC); return 0; } else if (is_cursed(rt->attribs, &ct_astralblock)) { - ADDMSG(&mage->faction->msgs, msg_feedback(mage, co->order, + ADDMSG(&caster->faction->msgs, msg_feedback(caster, co->order, "spellfail_astralblock", "")); return 0; } @@ -3094,7 +3106,7 @@ static int sp_chaossuction(castorder * co) create_special_direction(rt, r, 2, "vortex_desc", "vortex", false); new_border(&bt_chaosgate, r, rt); - add_message(&r->msgs, msg_message("chaosgate_effect_1", "mage", mage)); + add_message(&r->msgs, msg_message("chaosgate_effect_1", "mage", caster)); add_message(&rt->msgs, msg_message("chaosgate_effect_2", "")); return cast_level; } @@ -3123,30 +3135,30 @@ static int sp_chaossuction(castorder * co) static int sp_magicboost(castorder * co) { curse *c; - unit *mage = co_get_magician(co); + unit *caster = co_get_caster(co); int cast_level = co->level; double power = co->force; double effect; trigger *tsummon; /* fehler, wenn schon ein boost */ - if (is_cursed(mage->attribs, &ct_magicboost)) { - report_failure(mage, co->order); + if (is_cursed(caster->attribs, &ct_magicboost)) { + report_failure(caster, co->order); return 0; } effect = 6; - create_curse(mage, &mage->attribs, &ct_magicboost, power, 10, effect, 1); + create_curse(caster, &caster->attribs, &ct_magicboost, power, 10, effect, 1); /* one aura boost with 200% aura now: */ effect = 200; - c = create_curse(mage, &mage->attribs, &ct_auraboost, power, 4, effect, 1); + c = create_curse(caster, &caster->attribs, &ct_auraboost, power, 4, effect, 1); /* and one aura boost with 50% aura in 5 weeks: */ - tsummon = trigger_createcurse(mage, mage, &ct_auraboost, power, 6, 50, 1); - add_trigger(&mage->attribs, "timer", trigger_timeout(5, tsummon)); + tsummon = trigger_createcurse(caster, caster, &ct_auraboost, power, 6, 50, 1); + add_trigger(&caster->attribs, "timer", trigger_timeout(5, tsummon)); - ADDMSG(&mage->faction->msgs, msg_message("magicboost_effect", - "unit region command", c->magician, mage->region, co->order)); + ADDMSG(&caster->faction->msgs, msg_message("magicboost_effect", + "unit region command", c->magician, caster->region, co->order)); return cast_level; } @@ -3172,14 +3184,14 @@ static int sp_magicboost(castorder * co) */ static int sp_bloodsacrifice(castorder * co) { - unit *mage = co_get_magician(co); + unit *caster = co_get_caster(co); int cast_level = co->level; int aura; - int skill = effskill(mage, SK_MAGIC, 0); + int skill = effskill(caster, SK_MAGIC, 0); int hp = (int)(co->force * 8); if (hp <= 0) { - report_failure(mage, co->order); + report_failure(caster, co->order); return 0; } @@ -3200,17 +3212,17 @@ static int sp_bloodsacrifice(castorder * co) } if (aura <= 0) { - report_failure(mage, co->order); + report_failure(caster, co->order); return 0; } /* sicherheitshalber gibs hier einen HP gratis. sonst schaffen es * garantiert ne ganze reihe von leuten ihren Magier damit umzubringen */ - mage->hp++; - change_spellpoints(mage, aura); - ADDMSG(&mage->faction->msgs, + caster->hp++; + change_spellpoints(caster, aura); + ADDMSG(&caster->faction->msgs, msg_message("sp_bloodsacrifice_effect", - "unit region command amount", mage, mage->region, co->order, aura)); + "unit region command amount", caster, caster->region, co->order, aura)); return cast_level; } @@ -3249,7 +3261,7 @@ static int sp_summonundead(castorder * co) int undead, dc; unit *u; region *r = co_get_region(co); - unit *mage = co_get_magician(co); + unit *mage = co_get_caster(co); int cast_level = co->level; int force = (int)(co->force * 10); const race *race = get_race(RC_SKELETON); @@ -3306,7 +3318,7 @@ static int sp_auraleak(castorder * co) double lost; unit *u; region *r = co_get_region(co); - unit *mage = co_get_magician(co); + unit *mage = co_get_caster(co); int cast_level = co->level; message *msg; @@ -3349,7 +3361,7 @@ static int sp_analysesong_obj(castorder * co) { int obj; region *r = co_get_region(co); - unit *mage = co_get_magician(co); + unit *mage = co_get_caster(co); int cast_level = co->level; double force = co->force; spellparameter *pa = co->par; @@ -3398,7 +3410,7 @@ static int sp_analysesong_obj(castorder * co) static int sp_analysesong_unit(castorder * co) { unit *u; - unit *mage = co_get_magician(co); + unit *mage = co_get_caster(co); int cast_level = co->level; double force = co->force; spellparameter *pa = co->par; @@ -3483,7 +3495,7 @@ static int sp_charmingsong(castorder * co) unit *target; int duration; skill_t i; - unit *mage = co_get_magician(co); + unit *mage = co_get_caster(co); int cast_level = co->level; double force = co->force; spellparameter *pa = co->par; @@ -3572,7 +3584,7 @@ static int sp_charmingsong(castorder * co) static int sp_song_resistmagic(castorder * co) { region *r = co_get_region(co); - unit *mage = co_get_magician(co); + unit *mage = co_get_caster(co); int cast_level = co->level; double force = co->force; int duration = (int)force + 1; @@ -3601,7 +3613,7 @@ static int sp_song_resistmagic(castorder * co) static int sp_song_susceptmagic(castorder * co) { region *r = co_get_region(co); - unit *mage = co_get_magician(co); + unit *mage = co_get_caster(co); int cast_level = co->level; double force = co->force; int duration = (int)force + 1; @@ -3630,7 +3642,7 @@ static int sp_rallypeasantmob(castorder * co) unit *u, *un; int erfolg = 0; region *r = co_get_region(co); - unit *mage = co_get_magician(co); + unit *mage = co_get_caster(co); int cast_level = co->level; message *msg; curse *c; @@ -3683,7 +3695,7 @@ static int sp_raisepeasantmob(castorder * co) int n; int anteil; region *r = co_get_region(co); - unit *mage = co_get_magician(co); + unit *mage = co_get_caster(co); int rp, cast_level = co->level; double force = co->force; int duration = (int)force + 1; @@ -3739,7 +3751,7 @@ static int sp_migranten(castorder * co) { unit *target; region *r = co_get_region(co); - unit *mage = co_get_magician(co); + unit *mage = co_get_caster(co); int cast_level = co->level; spellparameter *pa = co->par; @@ -3807,7 +3819,7 @@ static int sp_song_of_peace(castorder * co) { unit *u; region *r = co_get_region(co); - unit *mage = co_get_magician(co); + unit *mage = co_get_caster(co); int cast_level = co->level; double force = co->force; int duration = 2 + lovar(force / 2); @@ -3856,7 +3868,7 @@ static int sp_generous(castorder * co) { unit *u; region *r = co_get_region(co); - unit *mage = co_get_magician(co); + unit *mage = co_get_caster(co); int cast_level = co->level; double force = co->force; int duration = (int)force + 1; @@ -3914,7 +3926,7 @@ static int sp_recruit(castorder * co) region *r = co_get_region(co); int num, maxp = rpeasants(r); double n; - unit *mage = co_get_magician(co); + unit *mage = co_get_caster(co); int cast_level = co->level; double force = co->force; faction *f = mage->faction; @@ -3969,7 +3981,7 @@ static int sp_bigrecruit(castorder * co) unit *u; region *r = co_get_region(co); int n, maxp = rpeasants(r); - unit *mage = co_get_magician(co); + unit *mage = co_get_caster(co); int cast_level = co->level; double force = co->force; faction *f = mage->faction; @@ -4024,7 +4036,7 @@ static int sp_pump(castorder * co) unit *u, *target; region *rt; bool see = false; - unit *mage = co_get_magician(co); + unit *mage = co_get_caster(co); spellparameter *pa = co->par; int cast_level = co->level; @@ -4085,7 +4097,7 @@ static int sp_seduce(castorder * co) const resource_type *rsilver = get_resourcetype(R_SILVER); unit *target; item **itmp, *items = NULL; - unit *u, *mage = co_get_magician(co); + unit *u, *caster = co_get_caster(co); spellparameter *pa = co->par; int cast_level = co->level; double force = co->force; @@ -4098,15 +4110,15 @@ static int sp_seduce(castorder * co) target = pa->param[0]->data.u; /* Zieleinheit */ if (fval(u_race(target), RCF_UNDEAD)) { - ADDMSG(&mage->faction->msgs, msg_feedback(mage, co->order, + ADDMSG(&caster->faction->msgs, msg_feedback(caster, co->order, "spellfail_noundead", "")); return 0; } - u = mage; - if (mage->region != target->region) { + u = caster; + if (caster->region != target->region) { for (u = target->region->units; u; u = u->next) { - if (u->faction == mage->faction) { + if (u->faction == caster->faction) { break; } } @@ -4144,7 +4156,7 @@ static int sp_seduce(castorder * co) if (items) { if (u) { - ADDMSG(&mage->faction->msgs, msg_message("seduce_effect_0", "mage unit items", + ADDMSG(&caster->faction->msgs, msg_message("seduce_effect_0", "mage unit items", u, target, items)); i_freeall(&items); } @@ -4174,7 +4186,7 @@ static int sp_calm_monster(castorder * co) { curse *c; unit *target; - unit *mage = co_get_magician(co); + unit *caster = co_get_caster(co); spellparameter *pa = co->par; int cast_level = co->level; double force = co->force; @@ -4188,21 +4200,21 @@ static int sp_calm_monster(castorder * co) target = pa->param[0]->data.u; /* Zieleinheit */ if (fval(u_race(target), RCF_UNDEAD)) { - ADDMSG(&mage->faction->msgs, msg_feedback(mage, co->order, + ADDMSG(&caster->faction->msgs, msg_feedback(caster, co->order, "spellfail_noundead", "")); return 0; } - effect = mage->faction->uid; - c = create_curse(mage, &target->attribs, &ct_calmmonster, force, + effect = caster->faction->uid; + c = create_curse(caster, &target->attribs, &ct_calmmonster, force, (int)force, effect, 0); if (c == NULL) { - report_failure(mage, co->order); + report_failure(caster, co->order); return 0; } - msg = msg_message("calm_effect", "mage unit", mage, target); - r_addmessage(mage->region, mage->faction, msg); + msg = msg_message("calm_effect", "mage unit", caster, target); + r_addmessage(caster->region, caster->faction, msg); msg_release(msg); return cast_level; } @@ -4285,13 +4297,13 @@ static int sp_raisepeasants(castorder * co) unit *u2; attrib *a; region *r = co_get_region(co); - unit *mage = co_get_magician(co); + unit *caster = co_get_caster(co); int rp = rpeasants(r), cast_level = co->level; double power = co->force; message *msg; if (rp == 0) { - ADDMSG(&mage->faction->msgs, msg_feedback(mage, co->order, + ADDMSG(&caster->faction->msgs, msg_feedback(caster, co->order, "error_nopeasants", "")); return 0; } @@ -4300,8 +4312,8 @@ static int sp_raisepeasants(castorder * co) rsetpeasants(r, rp - bauern); u2 = - create_unit(r, mage->faction, bauern, get_race(RC_PEASANT), 0, - LOC(mage->faction->locale, "furious_mob"), mage); + create_unit(r, caster->faction, bauern, get_race(RC_PEASANT), 0, + LOC(caster->faction->locale, "furious_mob"), caster); fset(u2, UFL_LOCKED); if (rule_stealth_anon()) { @@ -4314,11 +4326,11 @@ static int sp_raisepeasants(castorder * co) a_add(&u2->attribs, a); msg = - msg_message("sp_raisepeasants_effect", "mage region amount", mage, r, + msg_message("sp_raisepeasants_effect", "mage region amount", caster, r, u2->number); r_addmessage(r, NULL, msg); - if (mage->region != r) { - add_message(&mage->faction->msgs, msg); + if (caster->region != r) { + add_message(&caster->faction->msgs, msg); } msg_release(msg); @@ -4339,7 +4351,7 @@ static int sp_raisepeasants(castorder * co) static int sp_depression(castorder * co) { region *r = co_get_region(co); - unit *mage = co_get_magician(co); + unit *mage = co_get_caster(co); int cast_level = co->level; double force = co->force; int duration = (int)force + 1; @@ -4373,7 +4385,7 @@ static int sp_depression(castorder * co) int sp_puttorest(castorder * co) { region *r = co_get_region(co); - unit *mage = co_get_magician(co); + unit *mage = co_get_caster(co); int dead = deathcount(r); int laid_to_rest = dice((int)(co->force * 2), 100); message *seen = msg_message("puttorest", "mage", mage); @@ -4405,7 +4417,7 @@ int sp_icastle(castorder * co) building *b; const building_type *type; region *r = co_get_region(co); - unit *mage = co_get_magician(co); + unit *mage = co_get_caster(co); int cast_level = co->level; double power = co->force; spellparameter *pa = co->par; @@ -4473,7 +4485,7 @@ int sp_illusionary_shapeshift(castorder * co) { unit *u; const race *rc; - unit *mage = co_get_magician(co); + unit *mage = co_get_caster(co); int cast_level = co->level; double power = co->force; spellparameter *pa = co->par; @@ -4530,7 +4542,7 @@ int sp_illusionary_shapeshift(castorder * co) int sp_analysedream(castorder * co) { unit *u; - unit *mage = co_get_magician(co); + unit *mage = co_get_caster(co); int cast_level = co->level; spellparameter *pa = co->par; @@ -4552,7 +4564,7 @@ int sp_analysedream(castorder * co) static int sp_gbdreams(castorder * co, int effect) { int duration; - unit *mage = co_get_magician(co); + unit *mage = co_get_caster(co); int cast_level = co->level; double power = co->force; region *r = co_get_region(co); @@ -4624,7 +4636,7 @@ int sp_clonecopy(castorder * co) unit *clone; region *r = co_get_region(co); region *target_region = co_get_region(co); - unit *mage = co_get_magician(co); + unit *mage = co_get_caster(co); int cast_level = co->level; message *msg; char name[NAMESIZE]; @@ -4656,7 +4668,7 @@ int sp_dreamreading(castorder * co) { unit *u; region *r = co_get_region(co); - unit *mage = co_get_magician(co); + unit *mage = co_get_caster(co); int cast_level = co->level; spellparameter *pa = co->par; double power = co->force; @@ -4703,7 +4715,7 @@ int sp_dreamreading(castorder * co) int sp_sweetdreams(castorder * co) { region *r = co_get_region(co); - unit *mage = co_get_magician(co); + unit *mage = co_get_caster(co); int cast_level = co->level; double power = co->force; spellparameter *pa = co->par; @@ -4753,7 +4765,7 @@ int sp_sweetdreams(castorder * co) int sp_disturbingdreams(castorder * co) { region *r = co_get_region(co); - unit *mage = co_get_magician(co); + unit *mage = co_get_caster(co); int cast_level = co->level; double power = co->force; int duration = 1 + (int)(power / 6); @@ -4841,7 +4853,7 @@ int sp_analysemagic(castorder * co) int sp_itemcloak(castorder * co) { unit *target; - unit *mage = co_get_magician(co); + unit *mage = co_get_caster(co); spellparameter *pa = co->par; int cast_level = co->level; double power = co->force; @@ -4882,7 +4894,7 @@ int sp_resist_magic_bonus(castorder * co) unit *u; int n, m; int duration = 6; - unit *mage = co_get_magician(co); + unit *mage = co_get_caster(co); int cast_level = co->level; double power = co->force; spellparameter *pa = co->par; @@ -4939,7 +4951,7 @@ int sp_enterastral(castorder * co) int remaining_cap; int n, w; region *r = co_get_region(co); - unit *mage = co_get_magician(co); + unit *mage = co_get_caster(co); int cast_level = co->level; double power = co->force; spellparameter *pa = co->par; @@ -5054,7 +5066,7 @@ int sp_pullastral(castorder * co) int remaining_cap; int n, w; region *r = co_get_region(co); - unit *mage = co_get_magician(co); + unit *mage = co_get_caster(co); int cast_level = co->level; double power = co->force; spellparameter *pa = co->par; @@ -5196,7 +5208,7 @@ int sp_leaveastral(castorder * co) int remaining_cap; int n, w; region *r = co_get_region(co); - unit *mage = co_get_magician(co); + unit *mage = co_get_caster(co); int cast_level = co->level; double power = co->force; spellparameter *pa = co->par; @@ -5322,7 +5334,7 @@ int sp_leaveastral(castorder * co) int sp_fetchastral(castorder * co) { int n; - unit *mage = co_get_magician(co); + unit *mage = co_get_caster(co); int cast_level = 0; spellparameter *pa = co->par; double power = co->force; @@ -5459,7 +5471,7 @@ int sp_showastral(castorder * co) int c = 0; region_list *rl, *rl2; region *r = co_get_region(co); - unit *mage = co_get_magician(co); + unit *mage = co_get_caster(co); int cast_level = co->level; double power = co->force; @@ -5545,7 +5557,7 @@ int sp_viewreality(castorder * co) { region_list *rl, *rl2; region *r = co_get_region(co); - unit *mage = co_get_magician(co); + unit *mage = co_get_caster(co); int cast_level = co->level; message *m; @@ -5582,7 +5594,7 @@ int sp_disruptastral(castorder * co) region *rt; unit *u; region *r = co_get_region(co); - unit *mage = co_get_magician(co); + unit *mage = co_get_caster(co); int cast_level = co->level; double power = co->force; int duration = (int)(power / 3) + 1; @@ -5689,7 +5701,7 @@ static int sp_eternizewall(castorder * co) curse *c; building *b; region *r = co_get_region(co); - unit *mage = co_get_magician(co); + unit *mage = co_get_caster(co); int cast_level = co->level; double power = co->force; spellparameter *pa = co->par; @@ -5754,7 +5766,7 @@ int sp_permtransfer(castorder * co) { int aura, i; unit *tu; - unit *mage = co_get_magician(co); + unit *mage = co_get_caster(co); int cast_level = co->level; spellparameter *pa = co->par; const spell *sp = co->sp; @@ -5813,7 +5825,7 @@ int sp_movecastle(castorder * co) region *target_region; unit *u, *unext; region *r = co_get_region(co); - unit *mage = co_get_magician(co); + unit *mage = co_get_caster(co); int cast_level = co->level; spellparameter *pa = co->par; message *msg; @@ -5896,7 +5908,7 @@ int sp_stealaura(castorder * co) { int taura; unit *u; - unit *mage = co_get_magician(co); + unit *mage = co_get_caster(co); int cast_level = co->level; double power = co->force; spellparameter *pa = co->par; @@ -5966,7 +5978,7 @@ int sp_antimagiczone(castorder * co) double power; double effect; region *r = co_get_region(co); - unit *mage = co_get_magician(co); + unit *mage = co_get_caster(co); int cast_level = co->level; double force = co->force; int duration = (int)force + 1; @@ -6023,7 +6035,7 @@ int sp_antimagiczone(castorder * co) static int sp_magicrunes(castorder * co) { int duration; - unit *mage = co_get_magician(co); + unit *mage = co_get_caster(co); int cast_level = co->level; double force = co->force; spellparameter *pa = co->par; @@ -6083,7 +6095,7 @@ int sp_speed2(castorder * co) { int n, maxmen, used = 0, dur, men; unit *u; - unit *mage = co_get_magician(co); + unit *mage = co_get_caster(co); int cast_level = co->level; double force = co->force; spellparameter *pa = co->par; @@ -6143,7 +6155,7 @@ int sp_break_curse(castorder * co) int obj; curse *c; region *r = co_get_region(co); - unit *mage = co_get_magician(co); + unit *mage = co_get_caster(co); int cast_level = co->level; double force = co->force; spellparameter *pa = co->par; @@ -6300,7 +6312,7 @@ static int sp_babbler(castorder * co) { unit *target; region *r = co_get_region(co); - unit *mage = co_get_magician(co); + unit *mage = co_get_caster(co); int cast_level = co->level; spellparameter *pa = co->par; message *msg; @@ -6347,7 +6359,7 @@ static int sp_babbler(castorder * co) static int sp_readmind(castorder * co) { unit *target; - unit *mage = co_get_magician(co); + unit *mage = co_get_caster(co); int cast_level = co->level; spellparameter *pa = co->par; diff --git a/src/spells/flyingship.c b/src/spells/flyingship.c index cd2769ef8..4dc186dc5 100644 --- a/src/spells/flyingship.c +++ b/src/spells/flyingship.c @@ -38,7 +38,7 @@ int sp_flying_ship(castorder * co) ship *sh; unit *u; region *r; - unit *mage; + unit *caster; int cast_level; double power; spellparameter *pa; @@ -47,7 +47,7 @@ int sp_flying_ship(castorder * co) assert(co); r = co_get_region(co); - mage = co_get_magician(co); + caster = co_get_caster(co); cast_level = co->level; power = co->force; pa = co->par; @@ -57,22 +57,22 @@ int sp_flying_ship(castorder * co) return 0; sh = pa->param[0]->data.sh; if (sh->type->construction->maxsize > 50) { - ADDMSG(&mage->faction->msgs, msg_feedback(mage, co->order, + ADDMSG(&caster->faction->msgs, msg_feedback(caster, co->order, "error_flying_ship_too_big", "ship", sh)); return 0; } /* Duration = 1, nur diese Runde */ - cno = levitate_ship(sh, mage, power, 1); + cno = levitate_ship(sh, caster, power, 1); if (cno == 0) { if (is_cursed(sh->attribs, &ct_flyingship)) { /* Auf dem Schiff befindet liegt bereits so ein Zauber. */ - cmistake(mage, co->order, 211, MSG_MAGIC); + cmistake(caster, co->order, 211, MSG_MAGIC); } else if (is_cursed(sh->attribs, &ct_shipspeedup)) { /* Es ist zu gefaehrlich, ein sturmgepeitschtes Schiff fliegen zu lassen. */ - cmistake(mage, co->order, 210, MSG_MAGIC); + cmistake(caster, co->order, 210, MSG_MAGIC); } return 0; } @@ -86,7 +86,7 @@ int sp_flying_ship(castorder * co) if (!(u->faction->flags & FFL_SELECT)) { u->faction->flags |= FFL_SELECT; if (!m) { - m = msg_message("flying_ship_result", "mage ship", mage, sh); + m = msg_message("flying_ship_result", "mage ship", caster, sh); } add_message(&u->faction->msgs, m); } diff --git a/src/study.c b/src/study.c index 5ac5ac7ff..90cc001ec 100644 --- a/src/study.c +++ b/src/study.c @@ -784,13 +784,7 @@ int study_cmd(unit * u, order * ord) show_potions(f, skill); } } - else if (sk == SK_MAGIC) { - sc_mage *mage = get_mage_depr(u); - if (!mage) { - mage = create_mage(u, u->faction->magiegebiet); - } - } - init_order_depr(NULL); + init_order(NULL, NULL); return 0; } From aa466f3cc8a4ab43fa8b47e3ddd348ba0c9f2daa Mon Sep 17 00:00:00 2001 From: Enno Rehling Date: Sat, 17 Nov 2018 22:01:15 +0100 Subject: [PATCH 137/160] avoid code analysis warnings --- src/alchemy.c | 1 + src/battle.c | 30 ++++++++++++++++++------------ src/kernel/unit.c | 26 +++++++++++++++++++------- src/vortex.c | 1 + 4 files changed, 39 insertions(+), 19 deletions(-) diff --git a/src/alchemy.c b/src/alchemy.c index c84374e28..1673d5196 100644 --- a/src/alchemy.c +++ b/src/alchemy.c @@ -67,6 +67,7 @@ void new_potiontype(item_type * itype, int level) potion_type *ptype; ptype = (potion_type *)calloc(1, sizeof(potion_type)); + assert(ptype); itype->flags |= ITF_POTION; ptype->itype = itype; ptype->level = level; diff --git a/src/battle.c b/src/battle.c index 1101163b8..989a39e93 100644 --- a/src/battle.c +++ b/src/battle.c @@ -488,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); @@ -1226,7 +1226,7 @@ static void calculate_attack_type(troop dt, troop at, int type, bool missile, static int crit_damage(int attskill, int defskill, const char *damage_formula) { int damage = 0; if (rule_damage & DAMAGE_CRITICAL) { - double kritchance = (attskill * 3 - defskill) / 200.0; + double kritchance = ((double)attskill * 3.0 - (double)defskill) / 200.0; int maxk = 4; kritchance = fmax(kritchance, 0.005); @@ -2079,6 +2079,7 @@ void dazzle(battle * b, troop * td) 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. */ @@ -3428,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; @@ -3450,6 +3452,7 @@ battle *make_battle(region * r) } if (!bf) { bf = (bfaction *)calloc(1, sizeof(bfaction)); + assert(bf); ++b->nfactions; bf->faction = u->faction; bf->next = b->factions; @@ -3473,14 +3476,16 @@ 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); + } + fig->armors = NULL; 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); @@ -3492,13 +3497,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); diff --git a/src/kernel/unit.c b/src/kernel/unit.c index 369d099cc..724d5d275 100644 --- a/src/kernel/unit.c +++ b/src/kernel/unit.c @@ -208,6 +208,7 @@ static buddy *get_friends(const unit * u, int *numfriends) nf = *fr; if (nf == NULL || nf->faction != u2->faction) { nf = malloc(sizeof(buddy)); + assert(nf); nf->next = *fr; nf->faction = u2->faction; nf->unit = u2; @@ -1004,11 +1005,15 @@ skill *add_skill(unit * u, skill_t sk) skill *sv; int i; + assert(u); for (i = 0; i != u->skill_size; ++i) { sv = u->skills + i; if (sv->id >= sk) break; } - u->skills = realloc(u->skills, (1 + u->skill_size) * sizeof(skill)); + sv = realloc(u->skills, (1 + u->skill_size) * sizeof(skill)); + assert(sv); + u->skills = sv; + sv = u->skills + i; if (i < u->skill_size) { assert(sv->id != sk); @@ -1244,24 +1249,31 @@ int invisible(const unit * target, const unit * viewer) */ void free_unit(unit * u) { + struct reservation **pres = &u->reservations; + assert(!u->region); free(u->_name); free_order(u->thisorder); free_orders(&u->orders); - if (u->skills) + + while (*pres) { + struct reservation *res = *pres; + pres = &res->next; + free(res); + } + u->reservations = NULL; + if (u->skills) { free(u->skills); + u->skills = NULL; + } while (u->items) { item *it = u->items->next; u->items->next = NULL; i_free(u->items); u->items = it; } - while (u->attribs) + while (u->attribs) { a_remove(&u->attribs, u->attribs); - while (u->reservations) { - struct reservation *res = u->reservations; - u->reservations = res->next; - free(res); } } diff --git a/src/vortex.c b/src/vortex.c index 805b407c4..c743ad857 100644 --- a/src/vortex.c +++ b/src/vortex.c @@ -51,6 +51,7 @@ void register_special_direction(struct locale *lang, const char *name) if (lang == locales) { dir_lookup *dl = malloc(sizeof(dir_lookup)); + assert(dl); dl->name = str; dl->oldname = token; dl->next = dir_name_lookup; From 4403552b618e2a8d7c3783e55b7adf462a5e9abe Mon Sep 17 00:00:00 2001 From: Enno Rehling Date: Sat, 17 Nov 2018 22:12:34 +0100 Subject: [PATCH 138/160] F*ck this MSVC message: warning C6001: Using uninitialized memory It is confused, and I screwed up trying to work around it. --- src/battle.c | 5 ++--- src/kernel/unit.c | 3 +-- 2 files changed, 3 insertions(+), 5 deletions(-) diff --git a/src/battle.c b/src/battle.c index 989a39e93..00cece5b0 100644 --- a/src/battle.c +++ b/src/battle.c @@ -3479,10 +3479,9 @@ static void free_fighter(fighter * fig) armor **ap = &fig->armors; while (*ap) { armor *a = *ap; - ap = &a->next; + *ap = a->next; free(a); } - fig->armors = NULL; while (fig->loot) { i_free(i_remove(&fig->loot, fig->loot)); } @@ -3500,7 +3499,7 @@ static void battle_free(battle * b) { fighter **fp = &s->fighters; while (*fp) { fighter *fig = *fp; - fp = &fig->next; + *fp = fig->next; free_fighter(fig); free(fig); } diff --git a/src/kernel/unit.c b/src/kernel/unit.c index 724d5d275..4366f95dc 100644 --- a/src/kernel/unit.c +++ b/src/kernel/unit.c @@ -1258,10 +1258,9 @@ void free_unit(unit * u) while (*pres) { struct reservation *res = *pres; - pres = &res->next; + *pres = res->next; free(res); } - u->reservations = NULL; if (u->skills) { free(u->skills); u->skills = NULL; From 270646d9c36634cb9fa334411859f55642837a3f Mon Sep 17 00:00:00 2001 From: Enno Rehling Date: Sat, 17 Nov 2018 22:16:27 +0100 Subject: [PATCH 139/160] iwyu --- src/bind_process.c | 1 - src/bindings.c | 1 - 2 files changed, 2 deletions(-) diff --git a/src/bind_process.c b/src/bind_process.c index 6a02ac7a5..f9f99284e 100755 --- a/src/bind_process.c +++ b/src/bind_process.c @@ -5,7 +5,6 @@ #include "bind_process.h" #include "battle.h" -#include "contact.h" #include "economy.h" #include "laws.h" #include "magic.h" diff --git a/src/bindings.c b/src/bindings.c index e60b7fe78..e14c13ea5 100755 --- a/src/bindings.c +++ b/src/bindings.c @@ -52,7 +52,6 @@ #include #include #include -#include #include #include From b6110c5b228eb45fd674d0a3da2a0e1be8b7eeb2 Mon Sep 17 00:00:00 2001 From: Enno Rehling Date: Sat, 17 Nov 2018 22:28:55 +0100 Subject: [PATCH 140/160] some caster/mage changes issues (transfer aura is hard). --- src/magic.c | 4 ++-- src/spells.c | 35 ++++++++++++++++++++--------------- 2 files changed, 22 insertions(+), 17 deletions(-) diff --git a/src/magic.c b/src/magic.c index ae2eb78b5..0698135f0 100644 --- a/src/magic.c +++ b/src/magic.c @@ -1262,8 +1262,8 @@ bool fumble(region * r, unit * u, const spell * sp, int cast_grade) } /* CHAOSPATZERCHANCE 10 : +10% Chance zu Patzern */ - mage = get_mage_depr(u); - if (mage->magietyp == M_DRAIG) { + mage = get_mage(u); + if (mage && mage->magietyp == M_DRAIG) { fumble_chance += CHAOSPATZERCHANCE; } if (is_cursed(u->attribs, &ct_magicboost)) { diff --git a/src/spells.c b/src/spells.c index 9416c911c..3aaee0cca 100644 --- a/src/spells.c +++ b/src/spells.c @@ -706,11 +706,13 @@ static int sp_transferaura(castorder * co) { int aura, gain, multi = 2; unit *caster = co_get_caster(co); + unit *mage = co_get_magician(co); int cast_level = co->level; spellparameter *pa = co->par; unit *u; - sc_mage *scm_dst, *scm_src = get_mage(caster); + sc_mage *scm_dst, *scm_src = get_mage(mage); + assert(scm_src); /* wenn kein Ziel gefunden, Zauber abbrechen */ if (pa->param[0]->flag == TARGET_NOTFOUND) return 0; @@ -5384,6 +5386,7 @@ int sp_fetchastral(castorder * co) ro = u->region; } + assert(ro); cast_level = co->level; /* at least one unit could have been teleported */ if (is_cursed(ro->attribs, &ct_astralblock)) { ADDMSG(&mage->faction->msgs, msg_feedback(mage, co->order, @@ -5658,8 +5661,9 @@ int sp_disruptastral(castorder * co) int c = rng_int() % inhab_regions; /* Zufaellige Zielregion suchen */ - while (c-- != 0) + while (c-- != 0) { trl2 = trl2->next; + } tr = trl2->data; if (!is_magic_resistant(mage, u, 0) && can_survive(u, tr)) { @@ -5766,7 +5770,8 @@ int sp_permtransfer(castorder * co) { int aura, i; unit *tu; - unit *mage = co_get_caster(co); + unit *caster = co_get_caster(co); + unit *mage = co_get_magician(co); int cast_level = co->level; spellparameter *pa = co->par; const spell *sp = co->sp; @@ -5787,7 +5792,7 @@ int sp_permtransfer(castorder * co) if (!is_mage(tu)) { /* sprintf(buf, "%s in %s: 'ZAUBER %s': Einheit ist kein Magier." , unitname(mage), regionname(mage->region, mage->faction),sa->strings[0]); */ - cmistake(mage, co->order, 214, MSG_MAGIC); + cmistake(caster, co->order, 214, MSG_MAGIC); return 0; } @@ -5804,10 +5809,9 @@ int sp_permtransfer(castorder * co) change_maxspellpoints(tu, aura / 3); } - msg = - msg_message("sp_permtransfer_effect", "mage target amount", mage, tu, aura); - add_message(&mage->faction->msgs, msg); - if (tu->faction != mage->faction) { + msg = msg_message("sp_permtransfer_effect", "mage target amount", mage, tu, aura); + add_message(&caster->faction->msgs, msg); + if (tu->faction != caster->faction) { add_message(&tu->faction->msgs, msg); } msg_release(msg); @@ -5908,7 +5912,8 @@ int sp_stealaura(castorder * co) { int taura; unit *u; - unit *mage = co_get_caster(co); + unit *mage = co_get_magician(co); + unit *caster = co_get_caster(co); int cast_level = co->level; double power = co->force; spellparameter *pa = co->par; @@ -5921,8 +5926,8 @@ int sp_stealaura(castorder * co) u = pa->param[0]->data.u; if (!get_mage_depr(u)) { - ADDMSG(&mage->faction->msgs, msg_message("stealaura_fail", "unit target", - mage, u)); + ADDMSG(&caster->faction->msgs, msg_message("stealaura_fail", "unit target", + caster, u)); ADDMSG(&u->faction->msgs, msg_message("stealaura_fail_detect", "unit", u)); return 0; } @@ -5934,16 +5939,16 @@ int sp_stealaura(castorder * co) get_mage_depr(mage)->spellpoints += taura; /* sprintf(buf, "%s entzieht %s %d Aura.", unitname(mage), unitname(u), taura); */ - ADDMSG(&mage->faction->msgs, msg_message("stealaura_success", - "mage target aura", mage, u, taura)); + ADDMSG(&caster->faction->msgs, msg_message("stealaura_success", + "mage target aura", caster, u, taura)); /* sprintf(buf, "%s fuehlt seine magischen Kraefte schwinden und verliert %d " "Aura.", unitname(u), taura); */ ADDMSG(&u->faction->msgs, msg_message("stealaura_detect", "unit aura", u, taura)); } else { - ADDMSG(&mage->faction->msgs, msg_message("stealaura_fail", "unit target", - mage, u)); + ADDMSG(&caster->faction->msgs, msg_message("stealaura_fail", "unit target", + caster, u)); ADDMSG(&u->faction->msgs, msg_message("stealaura_fail_detect", "unit", u)); } return cast_level; From e1ebf15d3166b376cda01bfe2dd3f79c003a3c23 Mon Sep 17 00:00:00 2001 From: Enno Rehling Date: Sun, 18 Nov 2018 11:16:20 +0100 Subject: [PATCH 141/160] coverity thinks I need to check for NULL --- src/spells.c | 26 +++++++++++++++++++++++--- 1 file changed, 23 insertions(+), 3 deletions(-) diff --git a/src/spells.c b/src/spells.c index 3aaee0cca..4c900b2ae 100644 --- a/src/spells.c +++ b/src/spells.c @@ -5748,6 +5748,26 @@ static int sp_eternizewall(castorder * co) return cast_level; } +static bool change_spellpoints(struct unit *u, int delta) { + sc_mage *mage = get_mage(u); + if (mage) { + if (mage->spellpoints + delta >= 0) { + mage->spellpoints += delta; + return true; + } + mage->spellpoints = 0; + } + return false; +} + +static enum magic_t get_magic_type(const struct unit *u) { + sc_mage *mage = get_mage(u); + if (mage) { + return mage->magietyp; + } + return M_GRAY; +} + /* ------------------------------------------------------------- */ /* Name: Opfere Kraft * Stufe: 15 @@ -5802,7 +5822,7 @@ int sp_permtransfer(castorder * co) change_maxspellpoints(mage, -aura); change_spellpoints(mage, -aura); - if (get_mage_depr(tu)->magietyp == get_mage_depr(mage)->magietyp) { + if (get_magic_type(tu) == get_magic_type(mage)) { change_maxspellpoints(tu, aura / 2); } else { @@ -5935,8 +5955,8 @@ int sp_stealaura(castorder * co) taura = (get_mage_depr(u)->spellpoints * (rng_int() % (int)(3 * power) + 1)) / 100; if (taura > 0) { - get_mage_depr(u)->spellpoints -= taura; - get_mage_depr(mage)->spellpoints += taura; + change_spellpoints(u, -taura); + change_spellpoints(mage, taura); /* sprintf(buf, "%s entzieht %s %d Aura.", unitname(mage), unitname(u), taura); */ ADDMSG(&caster->faction->msgs, msg_message("stealaura_success", From 6f26898822d3e910b55dee8a8d36d3fd6f8c41a4 Mon Sep 17 00:00:00 2001 From: Enno Rehling Date: Sun, 18 Nov 2018 11:32:59 +0100 Subject: [PATCH 142/160] fix accidental redefinition --- src/spells.c | 14 +------------- 1 file changed, 1 insertion(+), 13 deletions(-) diff --git a/src/spells.c b/src/spells.c index 4c900b2ae..a628f1949 100644 --- a/src/spells.c +++ b/src/spells.c @@ -5748,19 +5748,7 @@ static int sp_eternizewall(castorder * co) return cast_level; } -static bool change_spellpoints(struct unit *u, int delta) { - sc_mage *mage = get_mage(u); - if (mage) { - if (mage->spellpoints + delta >= 0) { - mage->spellpoints += delta; - return true; - } - mage->spellpoints = 0; - } - return false; -} - -static enum magic_t get_magic_type(const struct unit *u) { +static magic_t get_magic_type(const struct unit *u) { sc_mage *mage = get_mage(u); if (mage) { return mage->magietyp; From 4a66b558c50fa0c0386c25a20e7c8eca639457c8 Mon Sep 17 00:00:00 2001 From: Enno Rehling Date: Sun, 18 Nov 2018 21:47:14 +0100 Subject: [PATCH 143/160] WIP: refactor struct sc_mage (make it private). tests are failing and/or slow. --- src/bind_unit.c | 31 +++--- src/creport.c | 16 +-- src/give.c | 4 +- src/kernel/save.c | 26 +++-- src/kernel/types.h | 2 +- src/kernel/unit.c | 28 ----- src/kernel/unit.h | 2 - src/laws.c | 35 ++++-- src/magic.c | 263 ++++++++++++++++++++++++--------------------- src/magic.h | 40 +++---- src/magic.test.c | 25 ++--- src/move.c | 9 +- src/reports.c | 8 +- src/spells.c | 63 ++++++----- src/spy.c | 6 +- src/study.c | 17 +-- src/study.test.c | 4 +- 17 files changed, 291 insertions(+), 288 deletions(-) diff --git a/src/bind_unit.c b/src/bind_unit.c index 3f2a037ea..ddd7b742f 100644 --- a/src/bind_unit.c +++ b/src/bind_unit.c @@ -276,8 +276,12 @@ static int tolua_unit_set_guard(lua_State * L) static const char *unit_getmagic(const unit * u) { - sc_mage *mage = get_mage_depr(u); - return mage ? magic_school[mage->magietyp] : NULL; + struct sc_mage *mage = get_mage(u); + if (mage) { + magic_t mtype = mage_get_type(mage); + return magic_school[mtype]; + } + return NULL; } static int tolua_unit_get_magic(lua_State * L) @@ -289,16 +293,15 @@ static int tolua_unit_get_magic(lua_State * L) static void unit_setmagic(unit * u, const char *type) { - sc_mage *mage = get_mage(u); - int mtype; - for (mtype = 0; mtype != MAXMAGIETYP; ++mtype) { - if (strcmp(magic_school[mtype], type) == 0) - break; - } - if (mtype == MAXMAGIETYP) - return; + struct sc_mage *mage = get_mage(u); if (mage == NULL) { - mage = create_mage(u, (magic_t)mtype); + int mtype; + for (mtype = 0; mtype != MAXMAGIETYP; ++mtype) { + if (strcmp(magic_school[mtype], type) == 0) { + create_mage(u, (magic_t)mtype); + return; + } + } } } @@ -521,7 +524,7 @@ static int tolua_unit_addspell(lua_State * L) return EINVAL; } else { - unit_add_spell(u, 0, sp, level); + unit_add_spell(u, sp, level); } lua_pushinteger(L, err); @@ -748,8 +751,8 @@ static int tolua_unit_get_items(lua_State * L) static int tolua_unit_get_spells(lua_State * L) { unit *self = (unit *) tolua_tousertype(L, 1, 0); - sc_mage *mage = self ? get_mage_depr(self) : 0; - spellbook *sb = mage ? mage->spellbook : 0; + struct sc_mage *mage = self ? get_mage(self) : NULL; + spellbook *sb = mage_get_spellbook(mage); selist *slist = 0; if (sb) { selist **slist_ptr = &sb->spells; diff --git a/src/creport.c b/src/creport.c index 69a9ed03e..db3df6c7e 100644 --- a/src/creport.c +++ b/src/creport.c @@ -880,7 +880,7 @@ void cr_output_unit(stream *out, const faction * f, const char *xc; const char *c; int i; - sc_mage *mage; + struct sc_mage *mage; i = ualias(u); if (i > 0) @@ -957,19 +957,23 @@ void cr_output_unit(stream *out, const faction * f, } /* spells that this unit can cast */ - mage = get_mage_depr(u); + mage = get_mage(u); if (mage) { int maxlevel = effskill(u, SK_MAGIC, 0); cr_output_spells(out, u, maxlevel); for (i = 0; i != MAXCOMBATSPELLS; ++i) { - const spell *sp = mage->combatspells[i].sp; + int level; + const spell *sp = mage_get_combatspell(mage, i, &level); if (sp) { - const char *name = - translate(mkname("spell", sp->sname), spell_name(sp, lang)); + const char *name; + if (level > maxlevel) { + level = maxlevel; + } stream_printf(out, "KAMPFZAUBER %d\n", i); + name = translate(mkname("spell", sp->sname), spell_name(sp, lang)); stream_printf(out, "\"%s\";name\n", name); - stream_printf(out, "%d;level\n", mage->combatspells[i].level); + stream_printf(out, "%d;level\n", level); } } } diff --git a/src/give.c b/src/give.c index 98ceff6bf..60b728479 100644 --- a/src/give.c +++ b/src/give.c @@ -587,14 +587,12 @@ void give_unit(unit * u, unit * u2, order * ord) } } if (has_skill(u, SK_MAGIC)) { - sc_mage *mage; if (count_skill(u2->faction, SK_MAGIC) + u->number > skill_limit(u2->faction, SK_MAGIC)) { cmistake(u, ord, 155, MSG_COMMERCE); return; } - mage = get_mage_depr(u); - if (!mage || u2->faction->magiegebiet != mage->magietyp) { + if (u2->faction->magiegebiet != unit_get_magic(u)) { cmistake(u, ord, 157, MSG_COMMERCE); return; } diff --git a/src/kernel/save.c b/src/kernel/save.c index cfa254bf4..52b32c2f5 100644 --- a/src/kernel/save.c +++ b/src/kernel/save.c @@ -1294,11 +1294,19 @@ ship *read_ship(gamedata *data) } static void fix_fam_mage(unit *u) { - sc_mage *m = get_mage(u); - if (m && m->magietyp != M_GRAY) { + struct sc_mage *mage = get_mage(u); + magic_t mtype = mage_get_type(mage); + if (mtype != M_GRAY) { + int skill = get_level(u, SK_MAGIC); /* unit should be a familiar that has aura and a spell-list */ - if (!m->spellbook) { - m->magietyp = M_GRAY; + if (skill > 0) { + struct spellbook * sb = mage_get_spellbook(mage); + if (!sb) { + unit_set_magic(u, M_GRAY); + } + } + else { + a_removeall(&u->attribs, &at_mage); } } } @@ -1507,20 +1515,18 @@ int read_game(gamedata *data) assert(f->units); for (u = f->units; u; u = u->nextF) { if (data->version < SPELL_LEVEL_VERSION) { - sc_mage *mage = get_mage_depr(u); + struct sc_mage *mage = get_mage(u); if (mage) { faction *f = u->faction; int skl = effskill(u, SK_MAGIC, 0); if (f->magiegebiet == M_GRAY) { - log_error("faction %s had magic=gray, fixing (%s)", factionname(f), magic_school[mage->magietyp]); - f->magiegebiet = mage->magietyp; + f->magiegebiet = mage_get_type(mage); + log_error("faction %s had magic=gray, fixing (%s)", + factionname(f), magic_school[f->magiegebiet]); } if (f->max_spelllevel < skl) { f->max_spelllevel = skl; } - if (mage->spellcount < 0) { - mage->spellcount = 0; - } } } if (u->number > 0) { diff --git a/src/kernel/types.h b/src/kernel/types.h index 34c50e0a1..2b014bc94 100644 --- a/src/kernel/types.h +++ b/src/kernel/types.h @@ -117,7 +117,7 @@ enum { MAXOPTIONS }; -typedef enum { +typedef enum magic_t { M_GRAY = 0, /* Gray */ M_ILLAUN = 1, /* Illaun */ M_TYBIED = 2, /* Tybied */ diff --git a/src/kernel/unit.c b/src/kernel/unit.c index 4366f95dc..748c76003 100644 --- a/src/kernel/unit.c +++ b/src/kernel/unit.c @@ -1657,34 +1657,6 @@ void u_setrace(struct unit *u, const struct race *rc) } } -void unit_add_spell(unit * u, sc_mage * m, struct spell * sp, int level) -{ - sc_mage *mage = m ? m : get_mage_depr(u); - - if (!mage) { - log_debug("adding new spell %s to a previously non-mage unit %s\n", sp->sname, unitname(u)); - mage = create_mage(u, u->faction ? u->faction->magiegebiet : M_GRAY); - } - if (!mage->spellbook) { - mage->spellbook = create_spellbook(0); - } - spellbook_add(mage->spellbook, sp, level); -} - -struct spellbook * unit_get_spellbook(const struct unit * u) -{ - sc_mage * mage = get_mage_depr(u); - if (mage) { - if (mage->spellbook) { - return mage->spellbook; - } - if (mage->magietyp != M_GRAY) { - return faction_get_spellbook(u->faction); - } - } - return NULL; -} - int effskill(const unit * u, skill_t sk, const region *r) { assert(u); diff --git a/src/kernel/unit.h b/src/kernel/unit.h index 169a5ff30..930574629 100644 --- a/src/kernel/unit.h +++ b/src/kernel/unit.h @@ -228,8 +228,6 @@ extern "C" { int unit_max_hp(const struct unit *u); void scale_number(struct unit *u, int n); - struct spellbook * unit_get_spellbook(const struct unit * u); - void unit_add_spell(struct unit * u, struct sc_mage * m, struct spell * sp, int level); void remove_empty_units_in_region(struct region * r); void remove_empty_units(void); diff --git a/src/laws.c b/src/laws.c index e8b6fee17..fdf763741 100644 --- a/src/laws.c +++ b/src/laws.c @@ -2419,7 +2419,22 @@ int combatspell_cmd(unit * u, struct order *ord) } else { /* KAMPFZAUBER "" setzt diesen Kampfzauber */ - set_combatspell(u, sp, ord, level); + /* knowsspell prüft auf ist_magier, ist_spruch, kennt_spruch */ + if (!knowsspell(u->region, u, sp)) { + /* Fehler 'Spell not found' */ + cmistake(u, ord, 173, MSG_MAGIC); + } + else if (!u_hasspell(u, sp)) { + /* Diesen Zauber kennt die Einheit nicht */ + cmistake(u, ord, 169, MSG_MAGIC); + } + else if (!(sp->sptyp & ISCOMBATSPELL)) { + /* Diesen Kampfzauber gibt es nicht */ + cmistake(u, ord, 171, MSG_MAGIC); + } + else { + set_combatspell(u, sp, ord, level); + } } return 0; @@ -3169,8 +3184,8 @@ static int faction_getmages(faction * f, unit ** results, int numresults) for (u = f->units; u; u = u->nextF) { if (u->number > 0) { - sc_mage *mage = get_mage_depr(u); - if (mage) { + struct sc_mage * mage = get_mage(u); + if (mage && mage_get_spellbook(mage)) { int level = effskill(u, SK_MAGIC, 0); if (level > maxlevel) { maxlevel = level; @@ -3229,11 +3244,12 @@ static void update_spells(void) unit *mages[MAXMAGES]; int i; int maxlevel = faction_getmages(f, mages, MAXMAGES); + struct spellbook *fsb; if (maxlevel && FactionSpells()) { spellbook * book = get_spellbook(magic_school[f->magiegebiet]); if (!f->spellbook) { - f->spellbook = create_spellbook(0); + f->spellbook = create_spellbook(NULL); } copy_spells(book, f->spellbook, maxlevel); if (maxlevel > f->max_spelllevel) { @@ -3241,13 +3257,14 @@ static void update_spells(void) pick_random_spells(f, maxlevel, common_spells, COMMONSPELLS); } } - show_new_spells(f, maxlevel, faction_get_spellbook(f)); + fsb = faction_get_spellbook(f); + show_new_spells(f, maxlevel, fsb); for (i = 0; i != MAXMAGES && mages[i]; ++i) { unit * u = mages[i]; - sc_mage *mage = get_mage_depr(u); - if (mage && mage->spellbook) { - int level = effskill(u, SK_MAGIC, 0); - show_new_spells(f, level, mage->spellbook); + spellbook *sb = unit_get_spellbook(u); + if (sb != fsb) { + int level = effskill(u, SK_MAGIC, NULL); + show_new_spells(f, level, sb); } } } diff --git a/src/magic.c b/src/magic.c index 0698135f0..0e7061301 100644 --- a/src/magic.c +++ b/src/magic.c @@ -103,6 +103,78 @@ const char *magic_school[MAXMAGIETYP] = { "common" }; +struct combatspell { + int level; + const struct spell *sp; +}; + +typedef struct sc_mage { + magic_t magietyp; + int spellpoints; + int spchange; + int spellcount; + struct combatspell combatspells[MAXCOMBATSPELLS]; + struct spellbook *spellbook; +} sc_mage; + +int mage_get_spellpoints(const sc_mage *m) +{ + return m ? m->spellpoints : 0; +} + +int mage_change_spellpoints(sc_mage *m, int delta) +{ + if (m) { + int val = m->spellpoints + delta; + return m->spellpoints = (val > 0) ? val : m->spellpoints; + } + return 0; +} + +magic_t mage_get_type(const sc_mage *m) +{ + return m ? m->magietyp : M_GRAY; +} + +const spell *mage_get_combatspell(const sc_mage *mage, int nr, int *level) +{ + assert(nr < MAXCOMBATSPELLS); + if (mage) { + if (level) { + *level = mage->combatspells[nr].level; + } + return mage->combatspells[nr].sp; + } + return NULL; +} + +void unit_set_magic(struct unit *u, enum magic_t mtype) +{ + sc_mage *mage = get_mage(u); + if (mage) { + mage->magietyp = mtype; + } +} + +magic_t unit_get_magic(const unit *u) +{ + return mage_get_type(get_mage(u)); +} + +void unit_add_spell(unit * u, struct spell * sp, int level) +{ + sc_mage *mage = get_mage(u); + + if (!mage) { + log_debug("adding new spell %s to a previously non-mage unit %s\n", sp->sname, unitname(u)); + mage = create_mage(u, u->faction ? u->faction->magiegebiet : M_GRAY); + } + if (!mage->spellbook) { + mage->spellbook = create_spellbook(0); + } + spellbook_add(mage->spellbook, sp, level); +} + /** ** at_icastle ** TODO: separate castle-appearance from illusion-effects @@ -199,6 +271,23 @@ const building_type *icastle_type(const struct attrib *a) { extern int dice(int count, int value); +bool FactionSpells(void) +{ + static int config, rule; + if (config_changed(&config)) { + rule = config_get_int("rules.magic.factionlist", 0); + } + return rule != 0; +} + +int get_spell_level_mage(const spell * sp, void * cbdata) +{ + sc_mage *mage = (sc_mage *)cbdata; + spellbook *book = get_spellbook(magic_school[mage->magietyp]); + spellbook_entry *sbe = spellbook_get(book, sp); + return sbe ? sbe->level : 0; +} + /* ------------------------------------------------------------- */ /* aus dem alten System übriggebliegene Funktionen, die bei der * Umwandlung von alt nach neu gebraucht werden */ @@ -219,23 +308,6 @@ static void free_mage(variant *var) free(mage); } -bool FactionSpells(void) -{ - static int config, rule; - if (config_changed(&config)) { - rule = config_get_int("rules.magic.factionlist", 0); - } - return rule != 0; -} - -int get_spell_level_mage(const spell * sp, void * cbdata) -{ - sc_mage *mage = (sc_mage *)cbdata; - spellbook *book = get_spellbook(magic_school[mage->magietyp]); - spellbook_entry *sbe = spellbook_get(book, sp); - return sbe ? sbe->level : 0; -} - static int read_mage(variant *var, void *owner, struct gamedata *data) { storage *store = data->store; @@ -312,9 +384,10 @@ attrib_type at_mage = { ATF_UNIQUE }; -bool is_mage(const unit * u) +bool is_mage(const struct unit * u) { - return get_mage_depr(u) != NULL; + sc_mage *m = get_mage(u); + return (m && m->magietyp != M_GRAY); } sc_mage *get_mage(const unit * u) @@ -326,12 +399,22 @@ sc_mage *get_mage(const unit * u) return NULL; } -sc_mage *get_mage_depr(const unit * u) +struct spellbook * mage_get_spellbook(const struct sc_mage * mage) { + if (mage) { + return mage->spellbook; + } + return NULL; +} + +struct spellbook * unit_get_spellbook(const struct unit * u) { - if (has_skill(u, SK_MAGIC)) { - attrib *a = a_find(u->attribs, &at_mage); - if (a) { - return (sc_mage *)a->data.v; + sc_mage * mage = get_mage(u); + if (mage) { + if (mage->spellbook) { + return mage->spellbook; + } + if (mage->magietyp != M_GRAY) { + return faction_get_spellbook(u->faction); } } return NULL; @@ -436,17 +519,15 @@ int u_hasspell(const unit *u, const struct spell *sp) int get_combatspelllevel(const unit * u, int nr) { - sc_mage *m = get_mage_depr(u); - - assert(nr < MAXCOMBATSPELLS); - if (m) { - int level = effskill(u, SK_MAGIC, 0); - if (level < m->combatspells[nr].level) { - return level; + int level; + if (mage_get_combatspell(get_mage(u), nr, &level) != NULL) { + int maxlevel = effskill(u, SK_MAGIC, 0); + if (level > maxlevel) { + return maxlevel; } - return m->combatspells[nr].level; + return level; } - return -1; + return 0; } /* ------------------------------------------------------------- */ @@ -454,40 +535,15 @@ int get_combatspelllevel(const unit * u, int nr) const spell *get_combatspell(const unit * u, int nr) { - sc_mage *m; - - assert(nr < MAXCOMBATSPELLS); - m = get_mage_depr(u); - if (m) { - return m->combatspells[nr].sp; - } - return NULL; + return mage_get_combatspell(get_mage(u), nr, NULL); } void set_combatspell(unit * u, spell * sp, struct order *ord, int level) { - sc_mage *mage = get_mage_depr(u); + sc_mage *mage = get_mage(u); int i = -1; assert(mage || !"trying to set a combat spell for non-mage"); - - /* knowsspell prüft auf ist_magier, ist_spruch, kennt_spruch */ - if (!knowsspell(u->region, u, sp)) { - /* Fehler 'Spell not found' */ - cmistake(u, ord, 173, MSG_MAGIC); - return; - } - if (!u_hasspell(u, sp)) { - /* Diesen Zauber kennt die Einheit nicht */ - cmistake(u, ord, 169, MSG_MAGIC); - return; - } - if (!(sp->sptyp & ISCOMBATSPELL)) { - /* Diesen Kampfzauber gibt es nicht */ - cmistake(u, ord, 171, MSG_MAGIC); - return; - } - if (sp->sptyp & PRECOMBATSPELL) i = 0; else if (sp->sptyp & COMBATSPELL) @@ -502,13 +558,12 @@ void set_combatspell(unit * u, spell * sp, struct order *ord, int level) void unset_combatspell(unit * u, spell * sp) { - sc_mage *m; int nr = 0; + sc_mage *m = get_mage(u); - m = get_mage_depr(u); - if (!m) + if (!m) { return; - + } if (!sp) { int i; for (i = 0; i < MAXCOMBATSPELLS; i++) { @@ -540,26 +595,15 @@ void unset_combatspell(unit * u, spell * sp) /* Gibt die aktuelle Anzahl der Magiepunkte der Einheit zurück */ int get_spellpoints(const unit * u) { - sc_mage *m; - - m = get_mage_depr(u); - if (!m) - return 0; - - return m->spellpoints; + return mage_get_spellpoints(get_mage(u)); } void set_spellpoints(unit * u, int sp) { - sc_mage *m; - - m = get_mage_depr(u); - if (!m) - return; - - m->spellpoints = sp; - - return; + sc_mage *m = get_mage(u); + if (m) { + m->spellpoints = sp; + } } /* @@ -567,23 +611,7 @@ void set_spellpoints(unit * u, int sp) */ int change_spellpoints(unit * u, int mp) { - sc_mage *m; - int sp; - - m = get_mage_depr(u); - if (!m) { - return 0; - } - - /* verhindere negative Magiepunkte */ - sp = m->spellpoints + mp; - if (sp > 0) { - m->spellpoints = sp; - } - else { - m->spellpoints = 0; - } - return sp; + return mage_change_spellpoints(get_mage(u), mp); } /* bietet die Möglichkeit, die maximale Anzahl der Magiepunkte mit @@ -593,11 +621,8 @@ static int get_spchange(const unit * u) { sc_mage *m; - m = get_mage_depr(u); - if (!m) - return 0; - - return m->spchange; + m = get_mage(u); + return m ? m->spchange : 0; } /* ein Magier kann normalerweise maximal Stufe^2.1/1.2+1 Magiepunkte @@ -645,9 +670,7 @@ int max_spellpoints(const region * r, const unit * u) int change_maxspellpoints(unit * u, int csp) { - sc_mage *m; - - m = get_mage_depr(u); + sc_mage *m = get_mage(u); if (!m) { return 0; } @@ -660,30 +683,24 @@ int change_maxspellpoints(unit * u, int csp) */ int countspells(unit * u, int step) { - sc_mage *m; - int count; - - m = get_mage_depr(u); - if (!m) { - return 0; - } - if (step == 0) { - return m->spellcount; - } - count = m->spellcount + step; - - m->spellcount = (count > 0) ? count : 0; - return m->spellcount; -} - -int spellcount(const unit *u) { - sc_mage *m = get_mage_depr(u); + sc_mage * m = get_mage(u); if (m) { + int count; + if (step == 0) { + return m->spellcount; + } + count = m->spellcount + step; + m->spellcount = (count > 0) ? count : 0; return m->spellcount; } return 0; } +int spellcount(const unit *u) { + sc_mage *m = get_mage(u); + return m ? m->spellcount : 0; +} + /** * Die Grundkosten pro Stufe werden um 2^count erhöht. countspells(u) * ist dabei die Anzahl der bereits gezauberten Sprüche diff --git a/src/magic.h b/src/magic.h index 030d21864..658fc351c 100644 --- a/src/magic.h +++ b/src/magic.h @@ -27,18 +27,16 @@ OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. extern "C" { #endif - /* ------------------------------------------------------------- */ - #define MAXCOMBATSPELLS 3 /* PRECOMBAT COMBAT POSTCOMBAT */ #define MAX_SPELLRANK 9 /* Standard-Rank 5 */ #define MAXINGREDIENT 5 /* bis zu 5 Komponenten pro Zauber */ #define CHAOSPATZERCHANCE 10 /* +10% Chance zu Patzern */ - - /* ------------------------------------------------------------- */ - #define IRONGOLEM_CRUMBLE 15 /* monatlich Chance zu zerfallen */ #define STONEGOLEM_CRUMBLE 10 /* monatlich Chance zu zerfallen */ + struct sc_mage; + struct unit; + extern const char *magic_school[MAXMAGIETYP]; extern struct attrib_type at_familiar; extern struct attrib_type at_familiarmage; @@ -99,26 +97,12 @@ extern "C" { * - Spruchliste */ - typedef struct combatspell { - int level; - const struct spell *sp; - } combatspell; - typedef struct spell_names { struct spell_names *next; const struct locale *lang; void * tokens; } spell_names; - typedef struct sc_mage { - magic_t magietyp; - int spellpoints; - int spchange; - int spellcount; - combatspell combatspells[MAXCOMBATSPELLS]; - struct spellbook *spellbook; - } sc_mage; - /* ------------------------------------------------------------- */ /* Zauberliste */ @@ -217,12 +201,22 @@ extern "C" { */ /* Magier */ - sc_mage *create_mage(struct unit *u, magic_t mtyp); + struct sc_mage *create_mage(struct unit *u, magic_t mtyp); /* macht die struct unit zu einem neuen Magier: legt die struct u->mage an * und initialisiert den Magiertypus mit mtyp. */ - sc_mage *get_mage(const struct unit *u); - sc_mage *get_mage_depr(const struct unit *u); - /* gibt u->mage zurück, bei nicht-Magiern *NULL */ + struct sc_mage *get_mage(const struct unit *u); + + enum magic_t mage_get_type(const struct sc_mage *mage); + const struct spell *mage_get_combatspell(const struct sc_mage *mage, int nr, int *level); + struct spellbook * mage_get_spellbook(const struct sc_mage * mage); + int mage_get_spellpoints(const struct sc_mage *m); + int mage_change_spellpoints(struct sc_mage *m, int delta); + + enum magic_t unit_get_magic(const struct unit *u); + void unit_set_magic(struct unit *u, enum magic_t mtype); + struct spellbook * unit_get_spellbook(const struct unit * u); + void unit_add_spell(struct unit * u, struct spell * sp, int level); + bool is_mage(const struct unit *u); /* gibt true, wenn u->mage gesetzt. */ bool is_familiar(const struct unit *u); diff --git a/src/magic.test.c b/src/magic.test.c index fc05f361f..7355527e7 100644 --- a/src/magic.test.c +++ b/src/magic.test.c @@ -117,7 +117,7 @@ void test_pay_spell(CuTest * tc) CuAssertPtrNotNull(tc, sp); set_level(u, SK_MAGIC, 5); - unit_add_spell(u, 0, sp, 1); + unit_add_spell(u, sp, 1); change_resource(u, get_resourcetype(R_SILVER), 1); change_resource(u, get_resourcetype(R_AURA), 3); @@ -151,7 +151,7 @@ void test_pay_spell_failure(CuTest * tc) CuAssertPtrNotNull(tc, sp); set_level(u, SK_MAGIC, 5); - unit_add_spell(u, 0, sp, 1); + unit_add_spell(u, sp, 1); CuAssertIntEquals(tc, 1, change_resource(u, get_resourcetype(R_SILVER), 1)); CuAssertIntEquals(tc, 2, change_resource(u, get_resourcetype(R_AURA), 2)); @@ -193,7 +193,7 @@ void test_getspell_unit(CuTest * tc) CuAssertPtrEquals(tc, NULL, unit_getspell(u, "Herp-a-derp", lang)); - unit_add_spell(u, 0, sp, 1); + unit_add_spell(u, sp, 1); CuAssertPtrNotNull(tc, unit_getspell(u, "Herp-a-derp", lang)); test_teardown(); } @@ -277,7 +277,7 @@ void test_set_pre_combatspell(CuTest * tc) sp = create_spell("testspell"); sp->sptyp |= PRECOMBATSPELL; - unit_add_spell(u, 0, sp, 1); + unit_add_spell(u, sp, 1); set_combatspell(u, sp, 0, 2); CuAssertPtrEquals(tc, sp, (spell *)get_combatspell(u, index)); @@ -309,7 +309,7 @@ void test_set_main_combatspell(CuTest * tc) sp = create_spell("testspell"); sp->sptyp |= COMBATSPELL; - unit_add_spell(u, 0, sp, 1); + unit_add_spell(u, sp, 1); set_combatspell(u, sp, 0, 2); CuAssertPtrEquals(tc, sp, (spell *)get_combatspell(u, index)); @@ -341,7 +341,7 @@ void test_set_post_combatspell(CuTest * tc) sp = create_spell("testspell"); sp->sptyp |= POSTCOMBATSPELL; - unit_add_spell(u, 0, sp, 1); + unit_add_spell(u, sp, 1); set_combatspell(u, sp, 0, 2); CuAssertPtrEquals(tc, sp, (spell *)get_combatspell(u, index)); @@ -371,7 +371,7 @@ void test_hasspell(CuTest * tc) sp = create_spell("testspell"); sp->sptyp |= POSTCOMBATSPELL; - unit_add_spell(u, 0, sp, 2); + unit_add_spell(u, sp, 2); set_level(u, SK_MAGIC, 1); CuAssertTrue(tc, !u_hasspell(u, sp)); @@ -407,7 +407,7 @@ void test_multi_cast(CuTest *tc) { u = test_create_unit(test_create_faction(NULL), test_create_region(0, 0, NULL)); set_level(u, SK_MAGIC, 10); - unit_add_spell(u, 0, sp, 1); + unit_add_spell(u, sp, 1); CuAssertPtrEquals(tc, sp, unit_getspell(u, "Feuerball", lang)); unit_addorder(u, create_order(K_CAST, u->faction->locale, "Feuerball")); @@ -485,7 +485,7 @@ static void test_illusioncastle(CuTest *tc) static void test_is_mage(CuTest *tc) { unit *u; - sc_mage *mage; + struct sc_mage *mage; test_setup(); u = test_create_unit(test_create_faction(NULL), test_create_region(0, 0, NULL)); @@ -502,18 +502,13 @@ static void test_is_mage(CuTest *tc) { static void test_get_mage(CuTest *tc) { unit *u; - sc_mage *mage; + struct sc_mage *mage; test_setup(); u = test_create_unit(test_create_faction(NULL), test_create_region(0, 0, NULL)); CuAssertPtrEquals(tc, NULL, get_mage(u)); - CuAssertPtrEquals(tc, NULL, get_mage_depr(u)); CuAssertPtrNotNull(tc, mage = create_mage(u, M_CERDDOR)); CuAssertPtrEquals(tc, mage, get_mage(u)); - CuAssertPtrEquals(tc, NULL, get_mage_depr(u)); - set_level(u, SK_MAGIC, 1); - CuAssertPtrEquals(tc, mage, get_mage(u)); - CuAssertPtrEquals(tc, mage, get_mage_depr(u)); test_teardown(); } diff --git a/src/move.c b/src/move.c index 8088ddd13..c919bc041 100644 --- a/src/move.c +++ b/src/move.c @@ -1,5 +1,5 @@ /* -Copyright (c) 1998-2014, +Copyright (c) 1998-2018, Enno Rehling Katja Zedel @@ -1430,9 +1430,10 @@ int movement_speed(const unit * u) /* Im Astralraum sind Tyb und Ill-Magier doppelt so schnell. * Nicht kumulativ mit anderen Beschleunigungen! */ if (mp * dk <= BP_WALKING * u_race(u)->speed && is_astral(u->region)) { - sc_mage *mage = get_mage(u); - if (mage && (mage->magietyp == M_TYBIED || mage->magietyp == M_ILLAUN)) { - if (has_skill(u, SK_MAGIC)) { + struct sc_mage *mage = get_mage(u); + if (mage) { + magic_t mtype = mage_get_type(mage); + if (mtype == M_TYBIED || mtype == M_ILLAUN) { mp *= 2; } } diff --git a/src/reports.c b/src/reports.c index f93eea685..3ce83a7de 100644 --- a/src/reports.c +++ b/src/reports.c @@ -637,10 +637,10 @@ static size_t spskill(char *buffer, size_t size, const struct locale * lang, bufp = STRLCPY(bufp, " ", size); if (sv->id == SK_MAGIC) { - sc_mage *mage = get_mage(u); - if (mage && mage->magietyp != M_GRAY) { - bufp = STRLCPY(bufp, LOC(lang, mkname("school", - magic_school[mage->magietyp])), size); + magic_t mtype = unit_get_magic(u); + if (mtype != M_GRAY) { + bufp = STRLCPY(bufp, + LOC(lang, mkname("school", magic_school[mtype])), size); bufp = STRLCPY(bufp, " ", size); } } diff --git a/src/spells.c b/src/spells.c index a628f1949..7707a05b7 100644 --- a/src/spells.c +++ b/src/spells.c @@ -704,13 +704,13 @@ static int sp_destroy_magic(castorder * co) static int sp_transferaura(castorder * co) { - int aura, gain, multi = 2; + int aura, used, multi = 2; unit *caster = co_get_caster(co); unit *mage = co_get_magician(co); int cast_level = co->level; spellparameter *pa = co->par; unit *u; - sc_mage *scm_dst, *scm_src = get_mage(mage); + struct sc_mage *scm_dst, *scm_src = get_mage(mage); assert(scm_src); /* wenn kein Ziel gefunden, Zauber abbrechen */ @@ -725,25 +725,29 @@ static int sp_transferaura(castorder * co) /* Wieviel Transferieren? */ aura = pa->param[1]->data.i; u = pa->param[0]->data.u; - scm_dst = get_mage_depr(u); + scm_dst = get_mage(u); if (scm_dst == NULL) { /* "Zu dieser Einheit kann ich keine Aura uebertragen." */ cmistake(caster, co->order, 207, MSG_MAGIC); return 0; } - else if (scm_src->magietyp == M_TYBIED) { - if (scm_src->magietyp != scm_dst->magietyp) - multi = 3; - } - else if (scm_src->magietyp == M_GRAY) { - if (scm_src->magietyp != scm_dst->magietyp) - multi = 4; - } - else if (scm_dst->magietyp != scm_src->magietyp) { - /* "Zu dieser Einheit kann ich keine Aura uebertragen." */ - cmistake(caster, co->order, 207, MSG_MAGIC); - return 0; + else { + magic_t src = mage_get_type(scm_src); + magic_t dst = mage_get_type(scm_dst); + if (src != dst) { + if (src == M_TYBIED) { + multi = 3; + } + else if (src == M_GRAY) { + multi = 4; + } + else { + /* "Zu dieser Einheit kann ich keine Aura uebertragen." */ + cmistake(caster, co->order, 207, MSG_MAGIC); + return 0; + } + } } if (aura < multi) { @@ -752,16 +756,15 @@ static int sp_transferaura(castorder * co) return 0; } - gain = scm_src->spellpoints; - if (gain > aura) gain = aura; - gain = gain / multi; - scm_src->spellpoints -= gain * multi; - scm_dst->spellpoints += gain; + used = mage_get_spellpoints(scm_src); + if (used > aura) used = aura; + mage_change_spellpoints(scm_src, -used); + mage_change_spellpoints(scm_dst, used / multi); /* sprintf(buf, "%s transferiert %d Aura auf %s", unitname(mage), gain, unitname(u)); */ ADDMSG(&caster->faction->msgs, msg_message("auratransfer_success", - "unit target aura", caster, u, gain)); + "unit target aura", caster, u, used)); return cast_level; } @@ -5748,14 +5751,6 @@ static int sp_eternizewall(castorder * co) return cast_level; } -static magic_t get_magic_type(const struct unit *u) { - sc_mage *mage = get_mage(u); - if (mage) { - return mage->magietyp; - } - return M_GRAY; -} - /* ------------------------------------------------------------- */ /* Name: Opfere Kraft * Stufe: 15 @@ -5810,7 +5805,7 @@ int sp_permtransfer(castorder * co) change_maxspellpoints(mage, -aura); change_spellpoints(mage, -aura); - if (get_magic_type(tu) == get_magic_type(mage)) { + if (unit_get_magic(tu) == unit_get_magic(mage)) { change_maxspellpoints(tu, aura / 2); } else { @@ -5925,6 +5920,7 @@ int sp_stealaura(castorder * co) int cast_level = co->level; double power = co->force; spellparameter *pa = co->par; + struct sc_mage *scm; /* wenn kein Ziel gefunden, Zauber abbrechen */ if (pa->param[0]->flag == TARGET_NOTFOUND) @@ -5933,17 +5929,18 @@ int sp_stealaura(castorder * co) /* Zieleinheit */ u = pa->param[0]->data.u; - if (!get_mage_depr(u)) { + scm = get_mage(u); + if (!scm) { ADDMSG(&caster->faction->msgs, msg_message("stealaura_fail", "unit target", caster, u)); ADDMSG(&u->faction->msgs, msg_message("stealaura_fail_detect", "unit", u)); return 0; } - taura = (get_mage_depr(u)->spellpoints * (rng_int() % (int)(3 * power) + 1)) / 100; + taura = (mage_get_spellpoints(scm) * (rng_int() % (int)(3 * power) + 1)) / 100; if (taura > 0) { - change_spellpoints(u, -taura); + mage_change_spellpoints(scm, -taura); change_spellpoints(mage, taura); /* sprintf(buf, "%s entzieht %s %d Aura.", unitname(mage), unitname(u), taura); */ diff --git a/src/spy.c b/src/spy.c index 53a5b4321..02590bd77 100644 --- a/src/spy.c +++ b/src/spy.c @@ -72,11 +72,11 @@ void spy_message(int spy, const unit * u, const unit * target) ADDMSG(&u->faction->msgs, msg_message("spyreport", "spy target status", u, target, status)); if (spy > 20) { - sc_mage *mage = get_mage_depr(target); + magic_t mtype = unit_get_magic(target); /* for mages, spells and magic school */ - if (mage) { + if (mtype != M_GRAY) { ADDMSG(&u->faction->msgs, msg_message("spyreport_mage", "spy target type", u, - target, magic_school[mage->magietyp])); + target, magic_school[mtype])); } } if (spy > 6) { diff --git a/src/study.c b/src/study.c index 90cc001ec..cfb775347 100644 --- a/src/study.c +++ b/src/study.c @@ -420,15 +420,16 @@ int teach_cmd(unit * teacher, struct order *ord) if (sk == SK_MAGIC) { /* ist der Magier schon spezialisiert, so versteht er nur noch * Lehrer seines Gebietes */ - sc_mage *mage1 = get_mage_depr(teacher); - sc_mage *mage2 = get_mage_depr(scholar); - if (mage2 && mage1 && mage2->magietyp != M_GRAY - && mage1->magietyp != mage2->magietyp) { - if (feedback) { - ADDMSG(&teacher->faction->msgs, msg_feedback(teacher, ord, - "error_different_magic", "target", scholar)); + magic_t mage2 = unit_get_magic(scholar); + if (mage2 != M_GRAY) { + magic_t mage1 = unit_get_magic(teacher); + if (mage1 != mage2) { + if (feedback) { + ADDMSG(&teacher->faction->msgs, msg_feedback(teacher, ord, + "error_different_magic", "target", scholar)); + } + continue; } - continue; } } sk_academy = sk; diff --git a/src/study.test.c b/src/study.test.c index b2ac39172..446b442bb 100644 --- a/src/study.test.c +++ b/src/study.test.c @@ -429,9 +429,9 @@ static void test_study_magic(CuTest *tc) { CuAssertIntEquals(tc, 0, study_cmd(u, u->thisorder)); CuAssertIntEquals(tc, M_GWYRRD, f->magiegebiet); CuAssertIntEquals(tc, 0, i_get(u->items, itype)); - CuAssertPtrNotNull(tc, get_mage_depr(u)); + CuAssertPtrNotNull(tc, get_mage(u)); CuAssertPtrEquals(tc, NULL, test_find_messagetype(f->msgs, "error65")); - CuAssertIntEquals(tc, M_GWYRRD, get_mage_depr(u)->magietyp); + CuAssertIntEquals(tc, M_GWYRRD, unit_get_magic(u)); test_teardown(); } From 3638219e1383187c0450d4e1fb3d98785903ec8e Mon Sep 17 00:00:00 2001 From: Enno Rehling Date: Sun, 18 Nov 2018 21:53:45 +0100 Subject: [PATCH 144/160] fix magic tests that created gray mages. also fix mage_change_spellpoints. --- src/items/xerewards.test.c | 2 +- src/magic.c | 2 +- src/magic.test.c | 4 ++-- src/triggers/shock.test.c | 4 ++-- 4 files changed, 6 insertions(+), 6 deletions(-) diff --git a/src/items/xerewards.test.c b/src/items/xerewards.test.c index dc9aa2621..d135b27fb 100644 --- a/src/items/xerewards.test.c +++ b/src/items/xerewards.test.c @@ -25,7 +25,7 @@ static void test_manacrystal(CuTest *tc) { CuAssertIntEquals(tc, -1, use_manacrystal(u, itype, 1, NULL)); CuAssertPtrNotNull(tc, test_find_messagetype(u->faction->msgs, "error295")); test_clear_messages(u->faction); - create_mage(u, M_GRAY); + create_mage(u, M_GWYRRD); set_level(u, SK_MAGIC, 5); CuAssertIntEquals(tc, 0, get_spellpoints(u)); CuAssertIntEquals(tc, 1, use_manacrystal(u, itype, 1, NULL)); diff --git a/src/magic.c b/src/magic.c index 0e7061301..debd8e0da 100644 --- a/src/magic.c +++ b/src/magic.c @@ -126,7 +126,7 @@ int mage_change_spellpoints(sc_mage *m, int delta) { if (m) { int val = m->spellpoints + delta; - return m->spellpoints = (val > 0) ? val : m->spellpoints; + return m->spellpoints = (val >= 0) ? val : m->spellpoints; } return 0; } diff --git a/src/magic.test.c b/src/magic.test.c index 7355527e7..9979caf6d 100644 --- a/src/magic.test.c +++ b/src/magic.test.c @@ -182,7 +182,7 @@ void test_getspell_unit(CuTest * tc) r = test_create_region(0, 0, NULL); f = test_create_faction(NULL); u = test_create_unit(f, r); - create_mage(u, M_GRAY); + create_mage(u, M_GWYRRD); enable_skill(SK_MAGIC, true); set_level(u, SK_MAGIC, 1); @@ -451,7 +451,7 @@ static void test_max_spellpoints(CuTest *tc) { CuAssertIntEquals(tc, 1, max_spellpoints(u->region, u)); rc->maxaura = 200; CuAssertIntEquals(tc, 2, max_spellpoints(u->region, u)); - create_mage(u, M_GRAY); + create_mage(u, M_GWYRRD); set_level(u, SK_MAGIC, 1); CuAssertIntEquals(tc, 3, max_spellpoints(u->region, u)); set_level(u, SK_MAGIC, 2); diff --git a/src/triggers/shock.test.c b/src/triggers/shock.test.c index 4bbd4de88..952febfd0 100644 --- a/src/triggers/shock.test.c +++ b/src/triggers/shock.test.c @@ -23,7 +23,7 @@ static void test_shock(CuTest *tc) { test_setup(); shock_setup(); u = test_create_unit(test_create_faction(NULL), test_create_region(0, 0, NULL)); - create_mage(u, M_GRAY); + create_mage(u, M_GWYRRD); set_level(u, SK_MAGIC, 5); set_spellpoints(u, 10); u->hp = 10; @@ -44,7 +44,7 @@ static void test_shock_low(CuTest *tc) { test_setup(); shock_setup(); u = test_create_unit(test_create_faction(NULL), test_create_region(0, 0, NULL)); - create_mage(u, M_GRAY); + create_mage(u, M_GWYRRD); set_level(u, SK_MAGIC, 5); set_spellpoints(u, 1); u->hp = 1; From 62e6489c7a466d85c9cd3191108b027d8553c093 Mon Sep 17 00:00:00 2001 From: Enno Rehling Date: Wed, 21 Nov 2018 21:46:59 +0100 Subject: [PATCH 145/160] rename variable. print error, not debug message. --- src/magic.c | 2 +- src/study.c | 30 +++++++++++++++--------------- 2 files changed, 16 insertions(+), 16 deletions(-) diff --git a/src/magic.c b/src/magic.c index debd8e0da..bd7edf4b8 100644 --- a/src/magic.c +++ b/src/magic.c @@ -166,7 +166,7 @@ void unit_add_spell(unit * u, struct spell * sp, int level) sc_mage *mage = get_mage(u); if (!mage) { - log_debug("adding new spell %s to a previously non-mage unit %s\n", sp->sname, unitname(u)); + log_error("adding new spell %s to a previously non-mage unit %s\n", sp->sname, unitname(u)); mage = create_mage(u, u->faction ? u->faction->magiegebiet : M_GRAY); } if (!mage->spellbook) { diff --git a/src/study.c b/src/study.c index cfb775347..977e8a7eb 100644 --- a/src/study.c +++ b/src/study.c @@ -623,7 +623,7 @@ int study_cmd(unit * u, order * ord) } if (sk == SK_MAGIC) { - magic_t mtyp; + magic_t mtype; if (u->number > 1) { cmistake(u, ord, 106, MSG_MAGIC); return -1; @@ -631,7 +631,7 @@ int study_cmd(unit * u, order * ord) if (is_familiar(u)) { /* Vertraute zaehlen nicht zu den Magiern einer Partei, * koennen aber nur Graue Magie lernen */ - mtyp = M_GRAY; + mtype = M_GRAY; } else if (!has_skill(u, SK_MAGIC)) { int mmax = skill_limit(u->faction, SK_MAGIC); @@ -641,24 +641,24 @@ int study_cmd(unit * u, order * ord) "amount", mmax)); return -1; } - mtyp = getmagicskill(u->faction->locale); - if (mtyp == M_NONE || mtyp == M_GRAY) { + mtype = getmagicskill(u->faction->locale); + if (mtype == M_NONE || mtype == M_GRAY) { /* wurde kein Magiegebiet angegeben, wird davon * ausgegangen, dass das normal gelernt werden soll */ if (u->faction->magiegebiet != 0) { - mtyp = u->faction->magiegebiet; + mtype = u->faction->magiegebiet; } else { /* Es wurde kein Magiegebiet angegeben und die Partei * hat noch keins gewaehlt. */ - mtyp = getmagicskill(u->faction->locale); - if (mtyp == M_NONE) { + mtype = getmagicskill(u->faction->locale); + if (mtype == M_NONE) { cmistake(u, ord, 178, MSG_MAGIC); return -1; } } } - if (mtyp != u->faction->magiegebiet) { + if (mtype != u->faction->magiegebiet) { /* Es wurde versucht, ein anderes Magiegebiet zu lernen * als das der Partei */ if (u->faction->magiegebiet != 0) { @@ -668,25 +668,25 @@ int study_cmd(unit * u, order * ord) else { /* Lernt zum ersten mal Magie und legt damit das * Magiegebiet der Partei fest */ - u->faction->magiegebiet = mtyp; + u->faction->magiegebiet = mtype; } } - create_mage(u, mtyp); + create_mage(u, mtype); } else { /* ist schon ein Magier und kein Vertrauter */ if (u->faction->magiegebiet == 0) { /* die Partei hat noch kein Magiegebiet gewaehlt. */ - mtyp = getmagicskill(u->faction->locale); - if (mtyp == M_NONE) { - mtyp = getmagicskill(u->faction->locale); - if (mtyp == M_NONE) { + mtype = getmagicskill(u->faction->locale); + if (mtype == M_NONE) { + mtype = getmagicskill(u->faction->locale); + if (mtype == M_NONE) { cmistake(u, ord, 178, MSG_MAGIC); return -1; } } /* Legt damit das Magiegebiet der Partei fest */ - u->faction->magiegebiet = mtyp; + u->faction->magiegebiet = mtype; } } } From 73540d733d851c2b0d52d2291a56b89c029147a9 Mon Sep 17 00:00:00 2001 From: Enno Rehling Date: Thu, 22 Nov 2018 22:13:23 +0100 Subject: [PATCH 146/160] Bug 2451: fix equip_unit for spells, update the familiar-fixing code from bug 2517. --- scripts/eressea/equipment.lua | 2 +- src/kernel/save.c | 18 ---------- src/magic.c | 65 ++++++++++++++++++++++++++++++----- src/magic.h | 3 +- 4 files changed, 60 insertions(+), 28 deletions(-) diff --git a/scripts/eressea/equipment.lua b/scripts/eressea/equipment.lua index c7bfe7dad..71fe78727 100644 --- a/scripts/eressea/equipment.lua +++ b/scripts/eressea/equipment.lua @@ -132,7 +132,7 @@ function equip_unit(u, name, flags) end local spells = set['spells'] if spells then - for name, level in ipairs(spells) do + for name, level in pairs(spells) do u:add_spell(name, level) end end diff --git a/src/kernel/save.c b/src/kernel/save.c index 52b32c2f5..70f40e0cf 100644 --- a/src/kernel/save.c +++ b/src/kernel/save.c @@ -1293,24 +1293,6 @@ ship *read_ship(gamedata *data) return sh; } -static void fix_fam_mage(unit *u) { - struct sc_mage *mage = get_mage(u); - magic_t mtype = mage_get_type(mage); - if (mtype != M_GRAY) { - int skill = get_level(u, SK_MAGIC); - /* unit should be a familiar that has aura and a spell-list */ - if (skill > 0) { - struct spellbook * sb = mage_get_spellbook(mage); - if (!sb) { - unit_set_magic(u, M_GRAY); - } - } - else { - a_removeall(&u->attribs, &at_mage); - } - } -} - static void fix_fam_triggers(unit *u) { attrib * a = a_find(u->attribs, &at_mage); attrib * am = a_find(u->attribs, &at_familiarmage); diff --git a/src/magic.c b/src/magic.c index bd7edf4b8..c13785a2c 100644 --- a/src/magic.c +++ b/src/magic.c @@ -166,8 +166,8 @@ void unit_add_spell(unit * u, struct spell * sp, int level) sc_mage *mage = get_mage(u); if (!mage) { - log_error("adding new spell %s to a previously non-mage unit %s\n", sp->sname, unitname(u)); - mage = create_mage(u, u->faction ? u->faction->magiegebiet : M_GRAY); + log_error("adding new spell %s to a previously non-magical unit %s\n", sp->sname, unitname(u)); + mage = create_mage(u, M_GRAY); } if (!mage->spellbook) { mage->spellbook = create_spellbook(0); @@ -350,7 +350,7 @@ static int read_mage(variant *var, void *owner, struct gamedata *data) read_spellbook(&mage->spellbook, data, get_spell_level_mage, mage); } else { - read_spellbook(0, data, 0, mage); + read_spellbook(NULL, data, NULL, mage); } return AT_READ_OK; } @@ -2210,18 +2210,67 @@ void remove_familiar(unit * mage) } } -void create_newfamiliar(unit * mage, unit * fam) -{ - /* skills and spells: */ +static void equip_familiar(unit *fam) { + /* items, skills and spells: */ char eqname[64]; const race *rc = u_race(fam); - set_familiar(mage, fam); - snprintf(eqname, sizeof(eqname), "fam_%s", rc->_name); if (!equip_unit(fam, eqname)) { log_info("could not perform initialization for familiar %s.\n", rc->_name); } +} + +static int copy_spell_cb(spellbook_entry *sbe, void *udata) { + spellbook *sb = (spellbook *)udata; + spell * sp = spellref_get(&sbe->spref); + if (!spellbook_get(sb, sp)) { + spellbook_add(sb, sp, sbe->level); + } + return 0; +} + +/** + * Einmalige Reparatur von Vertrauten (Bugs 2451, 2517). + */ +void fix_fam_mage(unit *u) { + sc_mage *dmage; + unit *du = unit_create(0); + + u_setrace(du, u_race(u)); + dmage = create_mage(du, M_GRAY); + equip_familiar(du); + if (dmage) { + sc_mage *mage = get_mage(u); + if (!mage) { + mage = create_mage(u, dmage->magietyp); + } + else if (dmage->magietyp != mage->magietyp) { + mage->magietyp = dmage->magietyp; + } + if (dmage->spellbook) { + if (!mage->spellbook) { + mage->spellbook = create_spellbook(NULL); + spellbook_foreach(dmage->spellbook, copy_spell_cb, mage->spellbook); + } + } + else { + if (mage->spellbook) { + spellbook_clear(mage->spellbook); + mage->spellbook = NULL; + } + } + } + free_unit(du); +} + +void create_newfamiliar(unit * mage, unit * fam) +{ + + create_mage(fam, M_GRAY); + set_familiar(mage, fam); + equip_familiar(fam); + /* TODO: Diese Attribute beim Tod des Familiars entfernen: */ /* Wenn der Magier stirbt, dann auch der Vertraute */ add_trigger(&mage->attribs, "destroy", trigger_killunit(fam)); diff --git a/src/magic.h b/src/magic.h index 658fc351c..23e4692f7 100644 --- a/src/magic.h +++ b/src/magic.h @@ -326,7 +326,8 @@ extern "C" { void remove_familiar(struct unit *mage); void create_newfamiliar(struct unit *mage, struct unit *familiar); void create_newclone(struct unit *mage, struct unit *familiar); - struct unit *has_clone(struct unit *mage); + + void fix_fam_mage(struct unit *u); const char *spell_info(const struct spell *sp, const struct locale *lang); From c7a38e4bdd97ec4dd2bc80da1db65fb54d9b2459 Mon Sep 17 00:00:00 2001 From: Enno Rehling Date: Thu, 22 Nov 2018 22:22:40 +0100 Subject: [PATCH 147/160] logic change in last commit: all familiars have an at_mage at creation. --- scripts/tests/e2/spells.lua | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/scripts/tests/e2/spells.lua b/scripts/tests/e2/spells.lua index 70d1bffb4..02699c0b8 100644 --- a/scripts/tests/e2/spells.lua +++ b/scripts/tests/e2/spells.lua @@ -215,12 +215,12 @@ function test_bug_2517() uf = um.familiar assert_not_nil(uf) assert_equal('lynx', uf.race) - assert_nil(uf.magic) + assert_equal('gray', uf.magic) uf:add_order('LERNE Magie') um:clear_orders() um:add_order('ARBEITEN') process_orders() - assert_nil(uf.magic) + assert_equal('gray', uf.magic) uf:add_order('ZAUBERE STUFE 1 Viehheilung') process_orders() assert_equal(50, uf:get_item('money')) From af72febebc2e6d3a138b47b800552311d803ef46 Mon Sep 17 00:00:00 2001 From: Enno Rehling Date: Fri, 23 Nov 2018 13:05:38 +0100 Subject: [PATCH 148/160] str_itoa for platforms that do not have itoa. remove more static string buffer warning code (bsdstring) from reports. --- src/reports.c | 25 ++++++++++--------------- src/util/strings.c | 6 ++++++ src/util/strings.h | 1 + 3 files changed, 17 insertions(+), 15 deletions(-) diff --git a/src/reports.c b/src/reports.c index 3ce83a7de..db06e81a4 100644 --- a/src/reports.c +++ b/src/reports.c @@ -2198,28 +2198,23 @@ static void eval_resources(struct opstack **stack, const void *userdata) const struct locale *lang = f ? f->locale : default_locale; const struct resource *res = (const struct resource *)opop(stack).v; char buf[1024]; /* but we only use about half of this */ - size_t size = sizeof(buf) - 1; variant var; - - char *bufp = buf; - while (res != NULL && size > 4) { + sbstring sbs; + + sbs_init(&sbs, buf, sizeof(buf)); + while (res != NULL) { const char *rname = resourcename(res->type, (res->number != 1) ? NMF_PLURAL : 0); - int result = snprintf(bufp, size, "%d %s", res->number, LOC(lang, rname)); - if (wrptr(&bufp, &size, result) != 0 || size < sizeof(buf) / 2) { - WARN_STATIC_BUFFER(); - break; - } + sbs_strcat(&sbs, str_itoa(res->number)); + sbs_strcat(&sbs, ""); + sbs_strcat(&sbs, LOC(lang, rname)); res = res->next; - if (res != NULL && size > 2) { - strcat(bufp, ", "); - bufp += 2; - size -= 2; + if (res != NULL) { + sbs_strcat(&sbs, ", "); } } - *bufp = 0; - var.v = strcpy(balloc((size_t)(bufp - buf + 1)), buf); + var.v = strcpy(balloc(sbs_length(&sbs)), buf); opush(stack, var); } diff --git a/src/util/strings.c b/src/util/strings.c index e9434fb25..682d92139 100644 --- a/src/util/strings.c +++ b/src/util/strings.c @@ -34,6 +34,12 @@ OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. #include #endif +const char *str_itoa(int n) { + static char buf[12]; + snprintf(buf, sizeof(buf), "%d", n); + return buf; +} + size_t str_strlcpy(char *dst, const char *src, size_t len) { #ifdef HAVE_BSDSTRING diff --git a/src/util/strings.h b/src/util/strings.h index bd58c0eb2..205cf6b52 100644 --- a/src/util/strings.h +++ b/src/util/strings.h @@ -28,6 +28,7 @@ extern "C" { void str_replace(char *buffer, size_t size, const char *tmpl, const char *var, const char *value); int str_hash(const char *s); + const char *str_itoa(int i); size_t str_slprintf(char * dst, size_t size, const char * format, ...); size_t str_strlcpy(char *dst, const char *src, size_t len); size_t str_strlcat(char *dst, const char *src, size_t len); From 4b64de0db9dcad0ebd0b35ea4137a3aade260dda Mon Sep 17 00:00:00 2001 From: Enno Rehling Date: Fri, 23 Nov 2018 14:03:02 +0100 Subject: [PATCH 149/160] When available, use MSVC built-in itoa function. --- src/util/strings.c | 27 +++++++++++++++++++++++---- src/util/strings.h | 1 + 2 files changed, 24 insertions(+), 4 deletions(-) diff --git a/src/util/strings.c b/src/util/strings.c index 682d92139..4eac7856e 100644 --- a/src/util/strings.c +++ b/src/util/strings.c @@ -18,6 +18,7 @@ OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. #ifdef _MSC_VER #include +#define HAVE__ITOA #endif #include "strings.h" @@ -34,10 +35,28 @@ OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. #include #endif -const char *str_itoa(int n) { - static char buf[12]; - snprintf(buf, sizeof(buf), "%d", n); - return buf; +const char* str_itoab(int val, int base) +{ + static char buf[32] = { 0 }; +#ifdef HAVE__ITOAB + return _itoa(val, buf, base); +#else + int i = 30; + for (; val && i; --i, val /= base) { + buf[i] = "0123456789abcdefghijklmnopqrstuvwxyz"[val % base]; + } + return &buf[i + 1]; +#endif +} + +const char *str_itoa(int n) +{ +#ifdef HAVE__ITOA + static char buf[32] = { 0 }; + return _itoa(n, buf, 10); +#else + return str_itoab(n, 10); +#endif } size_t str_strlcpy(char *dst, const char *src, size_t len) diff --git a/src/util/strings.h b/src/util/strings.h index 205cf6b52..bf6299332 100644 --- a/src/util/strings.h +++ b/src/util/strings.h @@ -29,6 +29,7 @@ extern "C" { void str_replace(char *buffer, size_t size, const char *tmpl, const char *var, const char *value); int str_hash(const char *s); const char *str_itoa(int i); + const char *str_itoab(int i, int base); size_t str_slprintf(char * dst, size_t size, const char * format, ...); size_t str_strlcpy(char *dst, const char *src, size_t len); size_t str_strlcat(char *dst, const char *src, size_t len); From bb1102632101423ffe15731a295aa236397ab9b0 Mon Sep 17 00:00:00 2001 From: Enno Rehling Date: Fri, 23 Nov 2018 22:00:37 +0100 Subject: [PATCH 150/160] more sbstring conversions in reporting functions. --- src/laws.c | 4 +- src/reports.c | 156 ++++++++++++++++++++------------------------------ src/reports.h | 3 +- 3 files changed, 68 insertions(+), 95 deletions(-) diff --git a/src/laws.c b/src/laws.c index fdf763741..624a4641a 100644 --- a/src/laws.c +++ b/src/laws.c @@ -2173,8 +2173,10 @@ static void display_item(unit * u, const item_type * itype) static void display_race(faction * f, const race * rc) { char buf[2048]; + sbstring sbs; - report_raceinfo(rc, f->locale, buf, sizeof(buf)); + sbs_init(&sbs, buf, sizeof(buf)); + report_raceinfo(rc, f->locale, &sbs); addmessage(0, f, buf, MSG_EVENT, ML_IMPORTANT); } diff --git a/src/reports.c b/src/reports.c index db06e81a4..455fe8ba3 100644 --- a/src/reports.c +++ b/src/reports.c @@ -274,29 +274,26 @@ report_item(const unit * owner, const item * i, const faction * viewer, } #define ORDERS_IN_NR 1 -static size_t buforder(char *buffer, size_t size, const order * ord, const struct locale *lang, int mode) +static void buforder(sbstring *sbs, const order * ord, const struct locale *lang, int mode) { - char *bufp = buffer; - - bufp = STRLCPY(bufp, ", \"", size); + sbs_strcpy(sbs, ", \""); if (mode < ORDERS_IN_NR) { char cmd[ORDERSIZE]; get_command(ord, lang, cmd, sizeof(cmd)); - bufp = STRLCPY(bufp, cmd, size); + sbs_strcat(sbs, cmd); } else { - bufp = STRLCPY(bufp, "...", size); + sbs_strcat(sbs, "..."); } - if (size > 1) { - *bufp++ = '\"'; - --size; - } - else { - WARN_STATIC_BUFFER(); - } + sbs_strcat(sbs, "\""); +} - return bufp - buffer; +static size_t buforder_depr(char *buffer, size_t size, const order * ord, const struct locale *lang, int mode) { + sbstring sbs; + sbs_init(&sbs, buffer, size); + buforder(&sbs, ord, lang, mode); + return sbs_length(&sbs); } /** create a report of a list of items to a non-owner. @@ -365,21 +362,24 @@ static void report_resource(resource_report * result, const resource_type *rtype result->level = level; } -void report_raceinfo(const struct race *rc, const struct locale *lang, char *buf, size_t length) +static void bufattack(struct sbstring *sbs, const struct locale *lang, const char *name, const char *dmg) { + sbs_strcat(sbs, LOC(lang, name)); + if (dmg) { + sbs_strcat(sbs, " ("); + sbs_strcat(sbs, dmg); + sbs_strcat(sbs, ")"); + } +} + +void report_raceinfo(const struct race *rc, const struct locale *lang, struct sbstring *sbs) { const char *info; int a, at_count; const char *name, *key; - char *bufp = buf; - size_t size = length - 1; - size_t bytes; name = rc_name_s(rc, NAME_SINGULAR); - - bytes = slprintf(bufp, size, "%s: ", LOC(lang, name)); - assert(bytes <= INT_MAX); - if (wrptr(&bufp, &size, (int)bytes) != 0) - WARN_STATIC_BUFFER(); + sbs_strcpy(sbs, LOC(lang, name)); + sbs_strcat(sbs, ": "); key = mkname("raceinfo", rc->_name); info = locale_getstring(lang, key); @@ -387,47 +387,37 @@ void report_raceinfo(const struct race *rc, const struct locale *lang, char *buf info = LOC(lang, mkname("raceinfo", "no_info")); } - if (info) bufp = STRLCPY(bufp, info, size); + if (info) { + sbs_strcat(sbs, info); + } /* hp_p : Trefferpunkte */ - bytes = - slprintf(bufp, size, " %d %s", rc->hitpoints, LOC(lang, - "stat_hitpoints")); - assert(bytes <= INT_MAX); - if (wrptr(&bufp, &size, (int)bytes) != 0) - WARN_STATIC_BUFFER(); + sbs_strcat(sbs, " "); + sbs_strcat(sbs, str_itoa(rc->hitpoints)); + sbs_strcat(sbs, " "); + sbs_strcat(sbs, LOC(lang, "stat_hitpoints")); /* b_attacke : Angriff */ - bytes = - slprintf(bufp, size, ", %s: %d", LOC(lang, "stat_attack"), - (rc->at_default + rc->at_bonus)); - assert(bytes <= INT_MAX); - if (wrptr(&bufp, &size, (int)bytes) != 0) - WARN_STATIC_BUFFER(); + sbs_strcat(sbs, ", "); + sbs_strcat(sbs, LOC(lang, "stat_attack")); + sbs_strcat(sbs, ": "); + sbs_strcat(sbs, str_itoa(rc->at_default + rc->at_bonus)); /* b_defense : Verteidigung */ - bytes = - slprintf(bufp, size, ", %s: %d", LOC(lang, "stat_defense"), - (rc->df_default + rc->df_bonus)); - assert(bytes <= INT_MAX); - if (wrptr(&bufp, &size, (int)bytes) != 0) - WARN_STATIC_BUFFER(); + sbs_strcat(sbs, ", "); + sbs_strcat(sbs, LOC(lang, "stat_defense")); + sbs_strcat(sbs, ": "); + sbs_strcat(sbs, str_itoa(rc->df_default + rc->df_bonus)); /* b_armor : Rüstung */ if (rc->armor > 0) { - bytes = - slprintf(bufp, size, ", %s: %d", LOC(lang, "stat_armor"), rc->armor); - assert(bytes <= INT_MAX); - if (wrptr(&bufp, &size, (int)bytes) != 0) - WARN_STATIC_BUFFER(); + sbs_strcat(sbs, ", "); + sbs_strcat(sbs, LOC(lang, "stat_armor")); + sbs_strcat(sbs, ": "); + sbs_strcat(sbs, str_itoa(rc->armor)); } - if (size > 1) { - *bufp++ = '.'; - --size; - } - else - WARN_STATIC_BUFFER(); + sbs_strcat(sbs, "."); /* b_damage : Schaden */ at_count = 0; @@ -437,73 +427,53 @@ void report_raceinfo(const struct race *rc, const struct locale *lang, char *buf } } if (rc->battle_flags & BF_EQUIPMENT) { - if (wrptr(&bufp, &size, snprintf(bufp, size, " %s", LOC(lang, "stat_equipment"))) != 0) - WARN_STATIC_BUFFER(); + sbs_strcat(sbs, " "); + sbs_strcat(sbs, LOC(lang, "stat_equipment")); } if (rc->battle_flags & BF_RES_PIERCE) { - if (wrptr(&bufp, &size, snprintf(bufp, size, " %s", LOC(lang, "stat_pierce"))) != 0) - WARN_STATIC_BUFFER(); + sbs_strcat(sbs, " "); + sbs_strcat(sbs, LOC(lang, "stat_pierce")); } if (rc->battle_flags & BF_RES_CUT) { - if (wrptr(&bufp, &size, snprintf(bufp, size, " %s", LOC(lang, "stat_cut"))) != 0) - WARN_STATIC_BUFFER(); + sbs_strcat(sbs, " "); + sbs_strcat(sbs, LOC(lang, "stat_cut")); } if (rc->battle_flags & BF_RES_BASH) { - if (wrptr(&bufp, &size, snprintf(bufp, size, " %s", LOC(lang, "stat_bash"))) != 0) - WARN_STATIC_BUFFER(); + sbs_strcat(sbs, " "); + sbs_strcat(sbs, LOC(lang, "stat_bash")); } - if (wrptr(&bufp, &size, snprintf(bufp, size, " %d %s", at_count, LOC(lang, (at_count == 1) ? "stat_attack" : "stat_attacks"))) != 0) - WARN_STATIC_BUFFER(); + sbs_strcat(sbs, " "); + sbs_strcat(sbs, str_itoa(at_count)); + sbs_strcat(sbs, " "); + sbs_strcat(sbs, LOC(lang, (at_count == 1) ? "stat_attack" : "stat_attacks")); for (a = 0; a < RACE_ATTACKS; a++) { if (rc->attack[a].type != AT_NONE) { - if (a != 0) - bufp = STRLCPY(bufp, ", ", size); - else - bufp = STRLCPY(bufp, ": ", size); + sbs_strcat(sbs, (a == 0) ? ": " : ", "); switch (rc->attack[a].type) { case AT_STANDARD: - bytes = - (size_t)snprintf(bufp, size, "%s (%s)", - LOC(lang, "attack_standard"), rc->def_damage); + bufattack(sbs, lang, "attack_standard", rc->def_damage); break; case AT_NATURAL: - bytes = - (size_t)snprintf(bufp, size, "%s (%s)", - LOC(lang, "attack_natural"), rc->attack[a].data.dice); + bufattack(sbs, lang, "attack_natural", rc->attack[a].data.dice); break; case AT_SPELL: case AT_COMBATSPELL: case AT_DRAIN_ST: case AT_DRAIN_EXP: case AT_DAZZLE: - bytes = (size_t)snprintf(bufp, size, "%s", LOC(lang, "attack_magical")); + bufattack(sbs, lang, "attack_magical", NULL); break; case AT_STRUCTURAL: - bytes = - (size_t)snprintf(bufp, size, "%s (%s)", - LOC(lang, "attack_structural"), rc->attack[a].data.dice); + bufattack(sbs, lang, "attack_structural", rc->attack[a].data.dice); break; - default: - bytes = 0; } - - assert(bytes <= INT_MAX); - if (bytes && wrptr(&bufp, &size, (int)bytes) != 0) - WARN_STATIC_BUFFER(); } } - if (size > 1) { - *bufp++ = '.'; - --size; - } - else - WARN_STATIC_BUFFER(); - - *bufp = 0; + sbs_strcat(sbs, "."); } void @@ -921,7 +891,7 @@ bufunit(const faction * f, const unit * u, seen_mode mode, char *buf, keyword_t kwd = getkeyword(ord); if (is_repeated(kwd)) { if (printed < ORDERS_IN_NR) { - int n = (int)buforder(bufp, size, ord, u->faction->locale, printed++); + int n = (int)buforder_depr(bufp, size, ord, u->faction->locale, printed++); if (wrptr(&bufp, &size, n) != 0) WARN_STATIC_BUFFER(); } @@ -934,7 +904,7 @@ bufunit(const faction * f, const unit * u, seen_mode mode, char *buf, keyword_t kwd = getkeyword(ord); if (is_repeated(kwd)) { if (printed < ORDERS_IN_NR) { - int n = (int)buforder(bufp, size, ord, lang, printed++); + int n = (int)buforder_depr(bufp, size, ord, lang, printed++); if (wrptr(&bufp, &size, n) != 0) WARN_STATIC_BUFFER(); } diff --git a/src/reports.h b/src/reports.h index a6dddb1b4..a361ceebc 100644 --- a/src/reports.h +++ b/src/reports.h @@ -31,6 +31,7 @@ extern "C" { struct battle; struct gamedate; + struct sbstring; struct selist; struct stream; struct seen_region; @@ -116,7 +117,7 @@ extern "C" { int report_items(const struct unit *u, struct item *result, int size, const struct unit *owner, const struct faction *viewer); void report_warnings(struct faction *f, int now); - void report_raceinfo(const struct race *rc, const struct locale *lang, char *buf, size_t length); + void report_raceinfo(const struct race *rc, const struct locale *lang, struct sbstring *sbp); void report_race_skills(const struct race *rc, char *zText, size_t length, const struct locale *lang); void report_item(const struct unit *owner, const struct item *i, const struct faction *viewer, const char **name, const char **basename, From e155f1ef29f2ef0c5ac5af8f813e1d6e965b0307 Mon Sep 17 00:00:00 2001 From: Enno Rehling Date: Fri, 23 Nov 2018 22:16:44 +0100 Subject: [PATCH 151/160] Fix MSVC static analysis warnings in laws.c --- src/laws.c | 25 +++++++++++++++++-------- 1 file changed, 17 insertions(+), 8 deletions(-) diff --git a/src/laws.c b/src/laws.c index 624a4641a..feacca8a1 100644 --- a/src/laws.c +++ b/src/laws.c @@ -326,7 +326,7 @@ static void calculate_emigration(region * r) static double peasant_growth_factor(void) { - return config_get_flt("rules.peasants.growth.factor", 0.0001F * PEASANTGROWTH); + return config_get_flt("rules.peasants.growth.factor", 0.0001 * (double)PEASANTGROWTH); } static double peasant_luck_factor(void) @@ -424,8 +424,10 @@ static migration *get_migrants(region * r) /* Es gibt noch keine Migration. Also eine erzeugen */ m = free_migrants; - if (!m) + if (!m) { m = calloc(1, sizeof(migration)); + if (!m) abort(); + } else { free_migrants = free_migrants->next; m->horses = 0; @@ -476,8 +478,8 @@ static void horses(region * r) } else if (maxhorses > 0) { double growth = - (RESOURCE_QUANTITY * HORSEGROWTH * 200 * (maxhorses - - horses)) / maxhorses; + (RESOURCE_QUANTITY * (HORSEGROWTH * 200.0 * ((double)maxhorses - + horses))) / (double)maxhorses; if (growth > 0) { int i; @@ -1233,6 +1235,7 @@ static void remove_idle_players(void) i = turn + 1; if (i < 4) i = 4; age = calloc(i, sizeof(int)); + if (!age) abort(); for (fp = &factions; *fp;) { faction *f = *fp; if (!is_monsters(f)) { @@ -1393,8 +1396,10 @@ static void init_prefixnames(void) } in = in->next; } - if (in == NULL) + if (in == NULL) { in = calloc(sizeof(local_names), 1); + if (!in) abort(); + } in->next = pnames; in->lang = lang; @@ -1432,7 +1437,8 @@ int prefix_cmd(unit * u, struct order *ord) } if (in == NULL) { init_prefixnames(); - for (in = pnames; in->lang != lang; in = in->next); + for (in = pnames; in && in->lang != lang; in = in->next); + if (!in) return 0; } init_order_depr(ord); @@ -3072,9 +3078,11 @@ void monthly_healing(void) /* hp über Maximum bauen sich ab. Wird zb durch Elixier der Macht * oder verändertes Ausdauertalent verursacht */ if (u->hp > umhp) { - u->hp -= (int)ceil((u->hp - umhp) / 2.0); - if (u->hp < umhp) + int diff = u->hp - umhp; + u->hp -= (int)ceil(diff / 2.0); + if (u->hp < umhp) { u->hp = umhp; + } continue; } @@ -3511,6 +3519,7 @@ static processor *add_proc(int priority, const char *name, processor_t type) } proc = (processor *)malloc(sizeof(processor)); + if (!proc) abort(); proc->priority = priority; proc->type = type; proc->name = name; From 6c5597b054f4b7713096b88105fe0856481a555b Mon Sep 17 00:00:00 2001 From: Enno Rehling Date: Fri, 23 Nov 2018 22:28:40 +0100 Subject: [PATCH 152/160] Oops, had some incomplete tests with NULL strings. --- src/laws.test.c | 45 +++++++++++++++++++++++++++++++-------------- 1 file changed, 31 insertions(+), 14 deletions(-) diff --git a/src/laws.test.c b/src/laws.test.c index 5a4f85b85..a2eca7ab5 100644 --- a/src/laws.test.c +++ b/src/laws.test.c @@ -1483,6 +1483,34 @@ static void test_show_without_item(CuTest *tc) test_teardown(); } +static struct locale *setup_locale(void) { + struct locale *loc; + + loc = get_or_create_locale("de"); + locale_setstring(loc, "elvenhorse", "Elfenpferd"); + locale_setstring(loc, "elvenhorse_p", "Elfenpferde"); + locale_setstring(loc, "iteminfo::elvenhorse", "Elfenpferd Informationen"); + locale_setstring(loc, "race::elf_p", "Elfen"); + locale_setstring(loc, "race::elf", "Elf"); + locale_setstring(loc, "race::human_p", "Menschen"); + locale_setstring(loc, "race::human", "Mensch"); + locale_setstring(loc, "stat_hitpoints", "Trefferpunkte"); + locale_setstring(loc, "stat_attack", "Angriff"); + locale_setstring(loc, "stat_attacks", "Angriffe"); + locale_setstring(loc, "stat_defense", "Verteidigung"); + locale_setstring(loc, "stat_armor", "Ruestung"); + locale_setstring(loc, "stat_equipment", "Gegenstaende"); + locale_setstring(loc, "stat_pierce", "Pieks"); + locale_setstring(loc, "stat_cut", "Schnipp"); + locale_setstring(loc, "stat_bash", "Boink"); + locale_setstring(loc, "attack_magical", "magisch"); + locale_setstring(loc, "attack_standard", "normal"); + locale_setstring(loc, "attack_natural", "natuerlich"); + locale_setstring(loc, "attack_structural", "strukturell"); + init_locale(loc); + return loc; +} + static void test_show_race(CuTest *tc) { order *ord; race * rc; @@ -1495,12 +1523,7 @@ static void test_show_race(CuTest *tc) { test_create_race("human"); rc = test_create_race("elf"); - loc = get_or_create_locale("de"); - locale_setstring(loc, "race::elf_p", "Elfen"); - locale_setstring(loc, "race::elf", "Elf"); - locale_setstring(loc, "race::human_p", "Menschen"); - locale_setstring(loc, "race::human", "Mensch"); - init_locale(loc); + loc = setup_locale(); u = test_create_unit(test_create_faction(rc), test_create_region(0, 0, NULL)); u->faction->locale = loc; @@ -1536,13 +1559,7 @@ static void test_show_both(CuTest *tc) { rc = test_create_race("elf"); test_create_itemtype("elvenhorse"); - loc = get_or_create_locale("de"); - locale_setstring(loc, "elvenhorse", "Elfenpferd"); - locale_setstring(loc, "elvenhorse_p", "Elfenpferde"); - locale_setstring(loc, "iteminfo::elvenhorse", "Hiyaa!"); - locale_setstring(loc, "race::elf_p", "Elfen"); - locale_setstring(loc, "race::elf", "Elf"); - init_locale(loc); + loc = setup_locale(); CuAssertPtrNotNull(tc, finditemtype("elf", loc)); CuAssertPtrNotNull(tc, findrace("elf", loc)); @@ -1558,7 +1575,7 @@ static void test_show_both(CuTest *tc) { CuAssertTrue(tc, memcmp("Elf:", msg->parameters[0].v, 4) == 0); msg = test_find_messagetype(u->faction->msgs, "displayitem"); CuAssertPtrNotNull(tc, msg); - CuAssertTrue(tc, memcmp("Hiyaa!", msg->parameters[2].v, 4) == 0); + CuAssertTrue(tc, memcmp("Elfenpferd Informationen", msg->parameters[2].v, 4) == 0); test_clear_messages(u->faction); free_order(ord); test_teardown(); From 3e54d307dff5d61372879530215ef94b8ac1f0eb Mon Sep 17 00:00:00 2001 From: Enno Rehling Date: Sat, 24 Nov 2018 12:26:52 +0100 Subject: [PATCH 153/160] replace bsdstring in bufunit --- src/bind_unit.c | 4 +- src/bindings.c | 2 +- src/creport.c | 2 +- src/items/xerewards.c | 2 +- src/kernel/pool.c | 2 +- src/magic.c | 19 +- src/magic.h | 4 +- src/magic.test.c | 12 +- src/report.c | 4 +- src/reports.c | 391 +++++++++++++++++++++--------------------- src/reports.h | 7 +- src/reports.test.c | 28 +-- src/spells.c | 2 +- src/spy.c | 2 +- src/triggers/shock.c | 2 +- 15 files changed, 249 insertions(+), 234 deletions(-) diff --git a/src/bind_unit.c b/src/bind_unit.c index ddd7b742f..4e3047367 100644 --- a/src/bind_unit.c +++ b/src/bind_unit.c @@ -62,7 +62,7 @@ static int tolua_bufunit(lua_State * L) { if (f) { char buf[8192]; int mode = (int)tolua_tonumber(L, 3, (int)seen_unit); - bufunit(f, u, mode, buf, sizeof(buf)); + bufunit_depr(f, u, mode, buf, sizeof(buf)); tolua_pushstring(L, buf); return 1; } @@ -199,7 +199,7 @@ static int tolua_unit_set_id(lua_State * L) static int tolua_unit_get_auramax(lua_State * L) { unit *self = (unit *)tolua_tousertype(L, 1, 0); - lua_pushinteger(L, max_spellpoints(self->region, self)); + lua_pushinteger(L, max_spellpoints_depr(self->region, self)); return 1; } diff --git a/src/bindings.c b/src/bindings.c index e14c13ea5..c46c0e80e 100755 --- a/src/bindings.c +++ b/src/bindings.c @@ -817,7 +817,7 @@ static int tolua_report_unit(lua_State * L) char buffer[512]; unit *u = (unit *)tolua_tousertype(L, 1, 0); faction *f = (faction *)tolua_tousertype(L, 2, 0); - bufunit(f, u, seen_unit, buffer, sizeof(buffer)); + bufunit_depr(f, u, seen_unit, buffer, sizeof(buffer)); tolua_pushstring(L, buffer); return 1; } diff --git a/src/creport.c b/src/creport.c index db3df6c7e..3ac9dffe9 100644 --- a/src/creport.c +++ b/src/creport.c @@ -917,7 +917,7 @@ void cr_output_unit(stream *out, const faction * f, } if (is_mage(u)) { stream_printf(out, "%d;Aura\n", get_spellpoints(u)); - stream_printf(out, "%d;Auramax\n", max_spellpoints(u->region, u)); + stream_printf(out, "%d;Auramax\n", max_spellpoints_depr(u->region, u)); } /* default commands */ stream_printf(out, "COMMANDS\n"); diff --git a/src/items/xerewards.c b/src/items/xerewards.c index 71746bbf3..d039a19a1 100644 --- a/src/items/xerewards.c +++ b/src/items/xerewards.c @@ -74,7 +74,7 @@ use_manacrystal(struct unit *u, const struct item_type *itype, int amount, return -1; } - msp = max_spellpoints(u->region, u) / 2; + msp = max_spellpoints_depr(u->region, u) / 2; for (i = 0; i != amount; ++i) { sp += MAX(25, msp); change_spellpoints(u, sp); diff --git a/src/kernel/pool.c b/src/kernel/pool.c index 52e445c94..70e02cb96 100644 --- a/src/kernel/pool.c +++ b/src/kernel/pool.c @@ -62,7 +62,7 @@ int get_resource(const unit * u, const resource_type * rtype) return get_spellpoints(u); } if (rtype == get_resourcetype(R_PERMAURA)) { - return max_spellpoints(u->region, u); + return max_spellpoints_depr(u->region, u); } log_error("trying to get unknown resource '%s'.\n", rtype->_name); return 0; diff --git a/src/magic.c b/src/magic.c index c13785a2c..ebaac3583 100644 --- a/src/magic.c +++ b/src/magic.c @@ -646,7 +646,7 @@ static int use_item_aura(const region * r, const unit * u) return n; } -int max_spellpoints(const region * r, const unit * u) +int max_spellpoints(const struct unit *u, const region * r) { int sk; double n, msp = 0; @@ -654,6 +654,9 @@ int max_spellpoints(const region * r, const unit * u) double divisor = 1.2; const struct resource_type *rtype; + assert(u); + if (!r) r = u->region; + sk = effskill(u, SK_MAGIC, r); msp = rc_maxaura(u_race(u)) * (pow(sk, potenz) / divisor + 1) + get_spchange(u); @@ -668,6 +671,11 @@ int max_spellpoints(const region * r, const unit * u) return (msp > 0) ? (int)msp : 0; } +int max_spellpoints_depr(const struct region *r, const struct unit *u) +{ + return max_spellpoints(u, r); +} + int change_maxspellpoints(unit * u, int csp) { sc_mage *m = get_mage(u); @@ -675,7 +683,7 @@ int change_maxspellpoints(unit * u, int csp) return 0; } m->spchange += csp; - return max_spellpoints(u->region, u); + return max_spellpoints_depr(u->region, u); } /* ------------------------------------------------------------- */ @@ -1456,7 +1464,7 @@ void regenerate_aura(void) for (u = r->units; u; u = u->next) { if (u->number && is_mage(u)) { aura = get_spellpoints(u); - auramax = max_spellpoints(r, u); + auramax = max_spellpoints_depr(r, u); if (aura < auramax) { struct building *b = inside_building(u); const struct building_type *btype = building_is_active(b) ? b->type : NULL; @@ -2979,6 +2987,11 @@ int cast_spell(struct castorder *co) return fun(co); } +const char *magic_name(magic_t mtype, const struct locale *lang) +{ + return LOC(lang, mkname("school", magic_school[mtype])); +} + static critbit_tree cb_spellbooks; #define SBNAMELEN 16 diff --git a/src/magic.h b/src/magic.h index 23e4692f7..4a184fe9e 100644 --- a/src/magic.h +++ b/src/magic.h @@ -252,7 +252,8 @@ extern "C" { /* setzt die Magiepunkte auf sp */ int change_spellpoints(struct unit *u, int mp); /* verändert die Anzahl der Magiepunkte der Einheit um +mp */ - int max_spellpoints(const struct region *r, const struct unit *u); + int max_spellpoints_depr(const struct region *r, const struct unit *u); + int max_spellpoints(const struct unit *u, const struct region *r); /* gibt die aktuell maximal möglichen Magiepunkte der Einheit zurück */ int change_maxspellpoints(struct unit *u, int csp); /* verändert die maximalen Magiepunkte einer Einheit */ @@ -316,6 +317,7 @@ extern "C" { * widersteht */ extern struct spell * unit_getspell(struct unit *u, const char *s, const struct locale *lang); + const char *magic_name(magic_t mtype, const struct locale *lang); /* Sprüche in der struct region */ /* (sind in curse) */ diff --git a/src/magic.test.c b/src/magic.test.c index 9979caf6d..577e88a37 100644 --- a/src/magic.test.c +++ b/src/magic.test.c @@ -446,19 +446,19 @@ static void test_max_spellpoints(CuTest *tc) { test_setup(); rc = test_create_race("human"); u = test_create_unit(test_create_faction(rc), test_create_region(0, 0, NULL)); - CuAssertIntEquals(tc, 1, max_spellpoints(u->region, u)); + CuAssertIntEquals(tc, 1, max_spellpoints_depr(u->region, u)); rc->maxaura = 100; - CuAssertIntEquals(tc, 1, max_spellpoints(u->region, u)); + CuAssertIntEquals(tc, 1, max_spellpoints_depr(u->region, u)); rc->maxaura = 200; - CuAssertIntEquals(tc, 2, max_spellpoints(u->region, u)); + CuAssertIntEquals(tc, 2, max_spellpoints_depr(u->region, u)); create_mage(u, M_GWYRRD); set_level(u, SK_MAGIC, 1); - CuAssertIntEquals(tc, 3, max_spellpoints(u->region, u)); + CuAssertIntEquals(tc, 3, max_spellpoints_depr(u->region, u)); set_level(u, SK_MAGIC, 2); - CuAssertIntEquals(tc, 9, max_spellpoints(u->region, u)); + CuAssertIntEquals(tc, 9, max_spellpoints_depr(u->region, u)); /* permanent aura loss: */ CuAssertIntEquals(tc, 7, change_maxspellpoints(u, -2)); - CuAssertIntEquals(tc, 7, max_spellpoints(u->region, u)); + CuAssertIntEquals(tc, 7, max_spellpoints_depr(u->region, u)); test_teardown(); } diff --git a/src/report.c b/src/report.c index b6ed3f736..045ec3c3f 100644 --- a/src/report.c +++ b/src/report.c @@ -676,7 +676,7 @@ nr_unit(struct stream *out, const faction * f, const unit * u, int indent, seen_ return; newline(out); - dh = bufunit(f, u, mode, buf, sizeof(buf)); + dh = bufunit_depr(f, u, mode, buf, sizeof(buf)); if (u->faction == f) { marker = '*'; @@ -2026,7 +2026,7 @@ report_plaintext(const char *filename, report_context * ctx, newline(out); sprintf(buf, "%s, %s/%s (%s)", factionname(f), LOC(f->locale, rc_name_s(f->race, NAME_PLURAL)), - LOC(f->locale, mkname("school", magic_school[f->magiegebiet])), faction_getemail(f)); + magic_name(f->magiegebiet, f->locale), faction_getemail(f)); centre(out, buf, true); if (f_get_alliance(f)) { centre(out, alliancename(f->alliance), true); diff --git a/src/reports.c b/src/reports.c index 455fe8ba3..d7c101e19 100644 --- a/src/reports.c +++ b/src/reports.c @@ -162,29 +162,37 @@ const char *combatstatus[] = { "status_avoid", "status_flee" }; -size_t report_status(const unit * u, const struct locale *lang, char *fsbuf, size_t buflen) +void report_status(const unit * u, const struct locale *lang, struct sbstring *sbp) { const char * status = LOC(lang, combatstatus[u->status]); - size_t len = 0; if (!status) { const char *lname = locale_name(lang); struct locale *wloc = get_locale(lname); + log_warning("no translation for combat status %s in %s", combatstatus[u->status], lname); locale_setstring(wloc, combatstatus[u->status], combatstatus[u->status] + 7); - len = str_strlcpy(fsbuf, combatstatus[u->status] + 7, buflen); + sbs_strcat(sbp, combatstatus[u->status] + 7); } else { - len = str_strlcpy(fsbuf, status, buflen); + sbs_strcat(sbp, status); } if (fval(u, UFL_NOAID)) { - len += str_strlcat(fsbuf + len, ", ", buflen - len); - len += str_strlcat(fsbuf + len, LOC(lang, "status_noaid"), buflen - len); + sbs_strcat(sbp, ", "); + sbs_strcat(sbp, LOC(lang, "status_noaid")); } - - return len; } +size_t report_status_depr(const unit * u, const struct locale *lang, char *fsbuf, size_t buflen) +{ + sbstring sbs; + + sbs_init(&sbs, fsbuf, buflen); + report_status(u, lang, &sbs); + return sbs_length(&sbs); +} + + const char *hp_status(const unit * u) { double p; @@ -274,19 +282,19 @@ report_item(const unit * owner, const item * i, const faction * viewer, } #define ORDERS_IN_NR 1 -static void buforder(sbstring *sbs, const order * ord, const struct locale *lang, int mode) +static void buforder(sbstring *sbp, const order * ord, const struct locale *lang, int mode) { - sbs_strcpy(sbs, ", \""); + sbs_strcat(sbp, ", \""); if (mode < ORDERS_IN_NR) { char cmd[ORDERSIZE]; get_command(ord, lang, cmd, sizeof(cmd)); - sbs_strcat(sbs, cmd); + sbs_strcat(sbp, cmd); } else { - sbs_strcat(sbs, "..."); + sbs_strcat(sbp, "..."); } - sbs_strcat(sbs, "\""); + sbs_strcat(sbp, "\""); } static size_t buforder_depr(char *buffer, size_t size, const order * ord, const struct locale *lang, int mode) { @@ -362,24 +370,24 @@ static void report_resource(resource_report * result, const resource_type *rtype result->level = level; } -static void bufattack(struct sbstring *sbs, const struct locale *lang, const char *name, const char *dmg) { - sbs_strcat(sbs, LOC(lang, name)); +static void bufattack(struct sbstring *sbp, const struct locale *lang, const char *name, const char *dmg) { + sbs_strcat(sbp, LOC(lang, name)); if (dmg) { - sbs_strcat(sbs, " ("); - sbs_strcat(sbs, dmg); - sbs_strcat(sbs, ")"); + sbs_strcat(sbp, " ("); + sbs_strcat(sbp, dmg); + sbs_strcat(sbp, ")"); } } -void report_raceinfo(const struct race *rc, const struct locale *lang, struct sbstring *sbs) +void report_raceinfo(const struct race *rc, const struct locale *lang, struct sbstring *sbp) { const char *info; int a, at_count; const char *name, *key; name = rc_name_s(rc, NAME_SINGULAR); - sbs_strcpy(sbs, LOC(lang, name)); - sbs_strcat(sbs, ": "); + sbs_strcat(sbp, LOC(lang, name)); + sbs_strcat(sbp, ": "); key = mkname("raceinfo", rc->_name); info = locale_getstring(lang, key); @@ -388,36 +396,36 @@ void report_raceinfo(const struct race *rc, const struct locale *lang, struct sb } if (info) { - sbs_strcat(sbs, info); + sbs_strcat(sbp, info); } /* hp_p : Trefferpunkte */ - sbs_strcat(sbs, " "); - sbs_strcat(sbs, str_itoa(rc->hitpoints)); - sbs_strcat(sbs, " "); - sbs_strcat(sbs, LOC(lang, "stat_hitpoints")); + sbs_strcat(sbp, " "); + sbs_strcat(sbp, str_itoa(rc->hitpoints)); + sbs_strcat(sbp, " "); + sbs_strcat(sbp, LOC(lang, "stat_hitpoints")); /* b_attacke : Angriff */ - sbs_strcat(sbs, ", "); - sbs_strcat(sbs, LOC(lang, "stat_attack")); - sbs_strcat(sbs, ": "); - sbs_strcat(sbs, str_itoa(rc->at_default + rc->at_bonus)); + sbs_strcat(sbp, ", "); + sbs_strcat(sbp, LOC(lang, "stat_attack")); + sbs_strcat(sbp, ": "); + sbs_strcat(sbp, str_itoa(rc->at_default + rc->at_bonus)); /* b_defense : Verteidigung */ - sbs_strcat(sbs, ", "); - sbs_strcat(sbs, LOC(lang, "stat_defense")); - sbs_strcat(sbs, ": "); - sbs_strcat(sbs, str_itoa(rc->df_default + rc->df_bonus)); + sbs_strcat(sbp, ", "); + sbs_strcat(sbp, LOC(lang, "stat_defense")); + sbs_strcat(sbp, ": "); + sbs_strcat(sbp, str_itoa(rc->df_default + rc->df_bonus)); /* b_armor : Rüstung */ if (rc->armor > 0) { - sbs_strcat(sbs, ", "); - sbs_strcat(sbs, LOC(lang, "stat_armor")); - sbs_strcat(sbs, ": "); - sbs_strcat(sbs, str_itoa(rc->armor)); + sbs_strcat(sbp, ", "); + sbs_strcat(sbp, LOC(lang, "stat_armor")); + sbs_strcat(sbp, ": "); + sbs_strcat(sbp, str_itoa(rc->armor)); } - sbs_strcat(sbs, "."); + sbs_strcat(sbp, "."); /* b_damage : Schaden */ at_count = 0; @@ -427,53 +435,53 @@ void report_raceinfo(const struct race *rc, const struct locale *lang, struct sb } } if (rc->battle_flags & BF_EQUIPMENT) { - sbs_strcat(sbs, " "); - sbs_strcat(sbs, LOC(lang, "stat_equipment")); + sbs_strcat(sbp, " "); + sbs_strcat(sbp, LOC(lang, "stat_equipment")); } if (rc->battle_flags & BF_RES_PIERCE) { - sbs_strcat(sbs, " "); - sbs_strcat(sbs, LOC(lang, "stat_pierce")); + sbs_strcat(sbp, " "); + sbs_strcat(sbp, LOC(lang, "stat_pierce")); } if (rc->battle_flags & BF_RES_CUT) { - sbs_strcat(sbs, " "); - sbs_strcat(sbs, LOC(lang, "stat_cut")); + sbs_strcat(sbp, " "); + sbs_strcat(sbp, LOC(lang, "stat_cut")); } if (rc->battle_flags & BF_RES_BASH) { - sbs_strcat(sbs, " "); - sbs_strcat(sbs, LOC(lang, "stat_bash")); + sbs_strcat(sbp, " "); + sbs_strcat(sbp, LOC(lang, "stat_bash")); } - sbs_strcat(sbs, " "); - sbs_strcat(sbs, str_itoa(at_count)); - sbs_strcat(sbs, " "); - sbs_strcat(sbs, LOC(lang, (at_count == 1) ? "stat_attack" : "stat_attacks")); + sbs_strcat(sbp, " "); + sbs_strcat(sbp, str_itoa(at_count)); + sbs_strcat(sbp, " "); + sbs_strcat(sbp, LOC(lang, (at_count == 1) ? "stat_attack" : "stat_attacks")); for (a = 0; a < RACE_ATTACKS; a++) { if (rc->attack[a].type != AT_NONE) { - sbs_strcat(sbs, (a == 0) ? ": " : ", "); + sbs_strcat(sbp, (a == 0) ? ": " : ", "); switch (rc->attack[a].type) { case AT_STANDARD: - bufattack(sbs, lang, "attack_standard", rc->def_damage); + bufattack(sbp, lang, "attack_standard", rc->def_damage); break; case AT_NATURAL: - bufattack(sbs, lang, "attack_natural", rc->attack[a].data.dice); + bufattack(sbp, lang, "attack_natural", rc->attack[a].data.dice); break; case AT_SPELL: case AT_COMBATSPELL: case AT_DRAIN_ST: case AT_DRAIN_EXP: case AT_DAZZLE: - bufattack(sbs, lang, "attack_magical", NULL); + bufattack(sbp, lang, "attack_magical", NULL); break; case AT_STRUCTURAL: - bufattack(sbs, lang, "attack_structural", rc->attack[a].data.dice); + bufattack(sbp, lang, "attack_structural", rc->attack[a].data.dice); break; } } } - sbs_strcat(sbs, "."); + sbs_strcat(sbp, "."); } void @@ -582,50 +590,47 @@ report_resources(const region * r, resource_report * result, int size, return n; } -static size_t spskill(char *buffer, size_t size, const struct locale * lang, +static void spskill(sbstring *sbp, const struct locale * lang, const struct unit * u, struct skill * sv, int *dh) { - char *bufp = buffer; int effsk; - if (!u->number) - return 0; + if (!u->number) { + return; + } if (sv->level <= 0) { if (sv->old <= 0 || (u->faction->options & WANT_OPTION(O_SHOWSKCHANGE)) == 0) { - return 0; + return; } } - - bufp = STRLCPY(bufp, ", ", size); + sbs_strcat(sbp, ", "); if (!*dh) { - bufp = STRLCPY(bufp, LOC(lang, "nr_skills"), size); - bufp = STRLCPY(bufp, ": ", size); + sbs_strcat(sbp, LOC(lang, "nr_skills")); + sbs_strcat(sbp, ": "); *dh = 1; } - bufp = STRLCPY(bufp, skillname(sv->id, lang), size); - bufp = STRLCPY(bufp, " ", size); + sbs_strcat(sbp, skillname(sv->id, lang)); + sbs_strcat(sbp, " "); if (sv->id == SK_MAGIC) { magic_t mtype = unit_get_magic(u); if (mtype != M_GRAY) { - bufp = STRLCPY(bufp, - LOC(lang, mkname("school", magic_school[mtype])), size); - bufp = STRLCPY(bufp, " ", size); + sbs_strcat(sbp, magic_name(mtype, lang)); + sbs_strcat(sbp, " "); } } if (sv->id == SK_STEALTH && fval(u, UFL_STEALTH)) { int i = u_geteffstealth(u); if (i >= 0) { - if (wrptr(&bufp, &size, snprintf(bufp, size, "%d/", i)) != 0) - WARN_STATIC_BUFFER(); + sbs_strcat(sbp, str_itoa(i)); + sbs_strcat(sbp, "/"); } } effsk = eff_skill(u, sv, 0); - if (wrptr(&bufp, &size, snprintf(bufp, size, "%d", effsk)) != 0) - WARN_STATIC_BUFFER(); + sbs_strcat(sbp, str_itoa(effsk)); if (u->faction->options & WANT_OPTION(O_SHOWSKCHANGE)) { int oldeff = 0; @@ -639,150 +644,146 @@ static size_t spskill(char *buffer, size_t size, const struct locale * lang, diff = effsk - oldeff; if (diff != 0) { - if (wrptr(&bufp, &size, snprintf(bufp, size, " (%s%d)", (diff > 0) ? "+" : "", diff)) != 0) - WARN_STATIC_BUFFER(); + sbs_strcat(sbp, " ("); + sbs_strcat(sbp, (diff > 0) ? "+" : ""); + sbs_strcat(sbp, str_itoa(diff)); + sbs_strcat(sbp, ")"); } } - return bufp - buffer; } -int -bufunit(const faction * f, const unit * u, seen_mode mode, char *buf, - size_t size) +static size_t spskill_depr(char *buffer, size_t size, const struct locale * lang, + const struct unit * u, struct skill * sv, int *dh) +{ + sbstring sbs; + sbs_init(&sbs, buffer, size); + spskill(&sbs, lang, u, sv, dh); + return sbs_length(&sbs); +} + +void bufunit(const faction * f, const unit * u, const faction *fv, + seen_mode mode, int getarnt, struct sbstring *sbp) { int i, dh; - int getarnt = fval(u, UFL_ANON_FACTION); const char *pzTmp, *str; bool isbattle = (mode == seen_battle); item *itm, *show = NULL; - faction *fv; - char *bufp = buf; - int result = 0; item results[MAX_INVENTORY]; const struct locale *lang = f->locale; + if (!fv) { + fv = visible_faction(f, u); + } assert(f); - bufp = STRLCPY(bufp, unitname(u), size); - fv = visible_faction(f, u); + sbs_strcat(sbp, unitname(u)); if (!isbattle) { if (u->faction == f) { if (fval(u, UFL_GROUP)) { group *g = get_group(u); if (g) { - bufp = STRLCPY(bufp, ", ", size); - bufp = STRLCPY(bufp, groupid(g, f), size); + sbs_strcat(sbp, ", "); + sbs_strcat(sbp, groupid(g, f)); } } if (getarnt) { - bufp = STRLCPY(bufp, ", ", size); - bufp = STRLCPY(bufp, LOC(lang, "anonymous"), size); + sbs_strcat(sbp, ", "); + sbs_strcat(sbp, LOC(lang, "anonymous")); } else if (u->attribs) { faction *otherf = get_otherfaction(u); if (otherf) { - bufp = STRLCPY(bufp, ", ", size); - bufp = STRLCPY(bufp, factionname(otherf), size); + sbs_strcat(sbp, ", "); + sbs_strcat(sbp, factionname(otherf)); } } } else { if (getarnt) { - bufp = STRLCPY(bufp, ", ", size); - bufp = STRLCPY(bufp, LOC(lang, "anonymous"), size); + sbs_strcat(sbp, ", "); + sbs_strcat(sbp, LOC(lang, "anonymous")); } else { if (u->attribs && alliedunit(u, f, HELP_FSTEALTH)) { faction *otherf = get_otherfaction(u); if (otherf) { - int n = snprintf(bufp, size, ", %s (%s)", - factionname(otherf), factionname(u->faction)); - if (wrptr(&bufp, &size, n) != 0) - WARN_STATIC_BUFFER(); + sbs_strcat(sbp, ", "); + sbs_strcat(sbp, factionname(otherf)); + sbs_strcat(sbp, " ("); + sbs_strcat(sbp, factionname(u->faction)); + sbs_strcat(sbp, ")"); } else { - bufp = STRLCPY(bufp, ", ", size); - bufp = STRLCPY(bufp, factionname(fv), size); + sbs_strcat(sbp, ", "); + sbs_strcat(sbp, factionname(fv)); } } else { - bufp = STRLCPY(bufp, ", ", size); - bufp = STRLCPY(bufp, factionname(fv), size); + sbs_strcat(sbp, ", "); + sbs_strcat(sbp, factionname(fv)); } } } } - bufp = STRLCPY(bufp, ", ", size); - - if (wrptr(&bufp, &size, snprintf(bufp, size, "%d ", u->number))) - WARN_STATIC_BUFFER(); + sbs_strcat(sbp, ", "); + sbs_strcat(sbp, str_itoa(u->number)); + sbs_strcat(sbp, " "); pzTmp = get_racename(u->attribs); if (pzTmp) { - bufp = STRLCPY(bufp, pzTmp, size); + sbs_strcat(sbp, pzTmp); if (u->faction == f && fval(u_race(u), RCF_SHAPESHIFTANY)) { - bufp = STRLCPY(bufp, " (", size); - bufp = STRLCPY(bufp, racename(lang, u, u_race(u)), size); - if (size > 1) { - strcpy(bufp++, ")"); - --size; - } + sbs_strcat(sbp, " ("); + sbs_strcat(sbp, racename(lang, u, u_race(u))); + sbs_strcat(sbp, ")"); } } else { const race *irace = u_irace(u); - bufp = STRLCPY(bufp, racename(lang, u, irace), size); - if (u->faction == f && irace != u_race(u)) { - bufp = STRLCPY(bufp, " (", size); - bufp = STRLCPY(bufp, racename(lang, u, u_race(u)), size); - if (size > 1) { - strcpy(bufp++, ")"); - --size; - } + const race *urace = u_race(u); + sbs_strcat(sbp, racename(lang, u, irace)); + if (u->faction == f && irace != urace) { + sbs_strcat(sbp, " ("); + sbs_strcat(sbp, racename(lang, u, urace)); + sbs_strcat(sbp, ")"); } } if (fval(u, UFL_HERO) && (u->faction == f || omniscient(f))) { - bufp = STRLCPY(bufp, ", ", size); - bufp = STRLCPY(bufp, LOC(lang, "hero"), size); + sbs_strcat(sbp, ", "); + sbs_strcat(sbp, LOC(lang, "hero")); } /* status */ if (u->number && (u->faction == f || isbattle)) { const char *c = hp_status(u); c = c ? LOC(lang, c) : 0; - bufp = STRLCPY(bufp, ", ", size); - bufp += report_status(u, lang, bufp, size); + sbs_strcat(sbp, ", "); + report_status(u, lang, sbp); if (c || fval(u, UFL_HUNGER)) { - bufp = STRLCPY(bufp, " (", size); + sbs_strcat(sbp, " ("); if (c) { - bufp = STRLCPY(bufp, c, size); + sbs_strcat(sbp, c); } if (fval(u, UFL_HUNGER)) { if (c) { - bufp = STRLCPY(bufp, ", ", size); + sbs_strcat(sbp, ", "); } - bufp = STRLCPY(bufp, LOC(lang, "unit_hungers"), size); - } - if (size > 1) { - strcpy(bufp++, ")"); - --size; + sbs_strcat(sbp, LOC(lang, "unit_hungers")); } + sbs_strcat(sbp, ")"); } } if (is_guard(u)) { - bufp = STRLCPY(bufp, ", ", size); - bufp = STRLCPY(bufp, LOC(lang, "unit_guards"), size); + sbs_strcat(sbp, ", "); + sbs_strcat(sbp, LOC(lang, "unit_guards")); } dh = 0; if (u->faction == f) { skill *sv; for (sv = u->skills; sv != u->skills + u->skill_size; ++sv) { - size_t bytes = spskill(bufp, size, lang, u, sv, &dh); - assert(bytes <= INT_MAX); - if (wrptr(&bufp, &size, (int)bytes) != 0) - WARN_STATIC_BUFFER(); + spskill(sbp, lang, u, sv, &dh); } } @@ -801,22 +802,23 @@ bufunit(const faction * f, const unit * u, seen_mode mode, char *buf, const char *ic; int in; report_item(u, itm, f, &ic, NULL, &in, false); - if (in == 0 || ic == NULL) + if (in == 0 || ic == NULL) { continue; - bufp = STRLCPY(bufp, ", ", size); + } + sbs_strcat(sbp, ", "); if (!dh) { - result = snprintf(bufp, size, "%s: ", LOC(lang, "nr_inventory")); - if (wrptr(&bufp, &size, result) != 0) - WARN_STATIC_BUFFER(); + sbs_strcat(sbp, LOC(lang, "nr_inventory")); + sbs_strcat(sbp, ": "); dh = 1; } if (in == 1) { - bufp = STRLCPY(bufp, ic, size); + sbs_strcat(sbp, ic); } else { - if (wrptr(&bufp, &size, snprintf(bufp, size, "%d %s", in, ic))) - WARN_STATIC_BUFFER(); + sbs_strcat(sbp, str_itoa(in)); + sbs_strcat(sbp, " "); + sbs_strcat(sbp, ic); } } @@ -826,27 +828,26 @@ bufunit(const faction * f, const unit * u, seen_mode mode, char *buf, if (book) { selist *ql = book->spells; int qi, header, maxlevel = effskill(u, SK_MAGIC, 0); - int n = snprintf(bufp, size, ". Aura %d/%d", get_spellpoints(u), max_spellpoints(u->region, u)); - if (wrptr(&bufp, &size, n) != 0) { - WARN_STATIC_BUFFER(); - } + sbs_strcat(sbp, ". Aura "); + sbs_strcat(sbp, str_itoa(get_spellpoints(u))); + sbs_strcat(sbp, "/"); + sbs_strcat(sbp, str_itoa(max_spellpoints(u, NULL))); for (header = 0, qi = 0; ql; selist_advance(&ql, &qi, 1)) { spellbook_entry * sbe = (spellbook_entry *)selist_get(ql, qi); const spell *sp = spellref_get(&sbe->spref); if (sbe->level <= maxlevel) { if (!header) { - n = snprintf(bufp, size, ", %s: ", LOC(lang, "nr_spells")); + sbs_strcat(sbp, ", "); + sbs_strcat(sbp, LOC(lang, "nr_spells")); + sbs_strcat(sbp, ": "); header = 1; } else { - n = (int)str_strlcpy(bufp, ", ", size); - } - if (wrptr(&bufp, &size, n) != 0) { - WARN_STATIC_BUFFER(); + sbs_strcat(sbp, ", "); } /* TODO: no need to deref the spellref here (spref->name is good) */ - bufp = STRLCPY(bufp, spell_name(sp, lang), size); + sbs_strcat(sbp, spell_name(sp, lang)); } } @@ -855,10 +856,9 @@ bufunit(const faction * f, const unit * u, seen_mode mode, char *buf, break; } if (i != MAXCOMBATSPELLS) { - n = snprintf(bufp, size, ", %s: ", LOC(lang, "nr_combatspells")); - if (wrptr(&bufp, &size, n) != 0) - WARN_STATIC_BUFFER(); - + sbs_strcat(sbp, ", "); + sbs_strcat(sbp, LOC(lang, "nr_combatspells")); + sbs_strcat(sbp, ": "); dh = 0; for (i = 0; i < MAXCOMBATSPELLS; i++) { const spell *sp; @@ -866,20 +866,20 @@ bufunit(const faction * f, const unit * u, seen_mode mode, char *buf, dh = 1; } else { - bufp = STRLCPY(bufp, ", ", size); + sbs_strcat(sbp, ", "); } sp = get_combatspell(u, i); if (sp) { int sl = get_combatspelllevel(u, i); - bufp = STRLCPY(bufp, spell_name(sp, lang), size); + sbs_strcat(sbp, spell_name(sp, lang)); if (sl > 0) { - n = snprintf(bufp, size, " (%d)", sl); - if (wrptr(&bufp, &size, n) != 0) - WARN_STATIC_BUFFER(); + sbs_strcat(sbp, "( "); + sbs_strcat(sbp, str_itoa(sl)); + sbs_strcat(sbp, ")"); } } else { - bufp = STRLCPY(bufp, LOC(lang, "nr_nospells"), size); + sbs_strcat(sbp, LOC(lang, "nr_nospells")); } } } @@ -890,62 +890,59 @@ bufunit(const faction * f, const unit * u, seen_mode mode, char *buf, for (ord = u->old_orders; ord; ord = ord->next) { keyword_t kwd = getkeyword(ord); if (is_repeated(kwd)) { - if (printed < ORDERS_IN_NR) { - int n = (int)buforder_depr(bufp, size, ord, u->faction->locale, printed++); - if (wrptr(&bufp, &size, n) != 0) - WARN_STATIC_BUFFER(); - } - else + if (printed >= ORDERS_IN_NR) { break; + } + buforder(sbp, ord, u->faction->locale, printed++); } } - if (printed < ORDERS_IN_NR) + if (printed < ORDERS_IN_NR) { for (ord = u->orders; ord; ord = ord->next) { keyword_t kwd = getkeyword(ord); if (is_repeated(kwd)) { - if (printed < ORDERS_IN_NR) { - int n = (int)buforder_depr(bufp, size, ord, lang, printed++); - if (wrptr(&bufp, &size, n) != 0) - WARN_STATIC_BUFFER(); - } - else { + if (printed >= ORDERS_IN_NR) { break; } + buforder(sbp, ord, lang, printed++); } } + } } } i = 0; str = u_description(u, lang); if (str) { - bufp = STRLCPY(bufp, "; ", size); - bufp = STRLCPY(bufp, str, size); + sbs_strcat(sbp, "; "); + sbs_strcat(sbp, str); i = str[strlen(str) - 1]; } if (i != '!' && i != '?' && i != '.') { - if (size > 1) { - strcpy(bufp++, "."); - --size; - } + sbs_strcat(sbp, "."); } pzTmp = uprivate(u); if (u->faction == f && pzTmp) { - bufp = STRLCPY(bufp, " (Bem: ", size); - bufp = STRLCPY(bufp, pzTmp, size); - bufp = STRLCPY(bufp, ")", size); + sbs_strcat(sbp, " (Bem: "); + sbs_strcat(sbp, pzTmp); + sbs_strcat(sbp, ")"); } +} - dh = 0; +int bufunit_depr(const faction * f, const unit * u, seen_mode mode, + char *buf, size_t size) +{ + int getarnt = fval(u, UFL_ANON_FACTION); + const faction * fv = visible_faction(f, u); + sbstring sbs; + + sbs_init(&sbs, buf, size); + bufunit(f, u, fv, mode, getarnt, &sbs); if (!getarnt) { if (alliedfaction(f, fv, HELP_ALL)) { - dh = 1; + return 1; } } - if (size <= 1) { - log_warning("bufunit ran out of space after writing %u bytes.\n", (bufp - buf)); - } - return dh; + return 0; } void split_paragraph(strlist ** SP, const char *s, unsigned int indent, unsigned int width, char mark) @@ -1019,7 +1016,7 @@ spunit(struct strlist **SP, const struct faction *f, const unit * u, unsigned in seen_mode mode) { char buf[DISPLAYSIZE]; - int dh = bufunit(f, u, mode, buf, sizeof(buf)); + int dh = bufunit_depr(f, u, mode, buf, sizeof(buf)); lparagraph(SP, buf, indent, (char)((u->faction == f) ? '*' : (dh ? '+' : '-'))); } diff --git a/src/reports.h b/src/reports.h index a361ceebc..14ac6da45 100644 --- a/src/reports.h +++ b/src/reports.h @@ -88,12 +88,15 @@ extern "C" { void register_reporttype(const char *extension, report_fun write, int flag); - int bufunit(const struct faction *f, const struct unit *u, seen_mode mode, + int bufunit_depr(const struct faction *f, const struct unit *u, seen_mode mode, char *buf, size_t size); + void bufunit(const struct faction * f, const struct unit * u, + const struct faction *fv, seen_mode mode, int getarnt, + struct sbstring *sbp); const char *trailinto(const struct region *r, const struct locale *lang); - size_t report_status(const struct unit *u, + size_t report_status_depr(const struct unit *u, const struct locale *lang, char *buf, size_t siz); void report_battle_start(struct battle * b); diff --git a/src/reports.test.c b/src/reports.test.c index b1cf36d99..86f69b0fd 100644 --- a/src/reports.test.c +++ b/src/reports.test.c @@ -199,55 +199,55 @@ static void test_bufunit_fstealth(CuTest *tc) { key_set(&u->attribs, 42, 42); /* report to ourselves */ - bufunit(f1, u, seen_unit, buf, sizeof(buf)); + bufunit_depr(f1, u, seen_unit, buf, sizeof(buf)); CuAssertStrEquals(tc, "Hodor (1), 1 human, aggressive.", buf); /* ... also when we are anonymous */ u->flags |= UFL_ANON_FACTION; - bufunit(f1, u, seen_unit, buf, sizeof(buf)); + bufunit_depr(f1, u, seen_unit, buf, sizeof(buf)); CuAssertStrEquals(tc, "Hodor (1), anonymous, 1 human, aggressive.", buf); u->flags &= ~UFL_ANON_FACTION; /* we see that our unit is cloaked */ set_factionstealth(u, f2); CuAssertPtrNotNull(tc, u->attribs); - bufunit(f1, u, seen_unit, buf, sizeof(buf)); + bufunit_depr(f1, u, seen_unit, buf, sizeof(buf)); CuAssertStrEquals(tc, "Hodor (1), TWW (2), 1 human, aggressive.", buf); /* ... also when we are anonymous */ u->flags |= UFL_ANON_FACTION; - bufunit(f1, u, seen_unit, buf, sizeof(buf)); + bufunit_depr(f1, u, seen_unit, buf, sizeof(buf)); CuAssertStrEquals(tc, "Hodor (1), anonymous, 1 human, aggressive.", buf); u->flags &= ~UFL_ANON_FACTION; /* we can see that someone is presenting as us */ - bufunit(f2, u, seen_unit, buf, sizeof(buf)); + bufunit_depr(f2, u, seen_unit, buf, sizeof(buf)); CuAssertStrEquals(tc, "Hodor (1), TWW (2), 1 human.", buf); /* ... but not if they are anonymous */ u->flags |= UFL_ANON_FACTION; - bufunit(f2, u, seen_unit, buf, sizeof(buf)); + bufunit_depr(f2, u, seen_unit, buf, sizeof(buf)); CuAssertStrEquals(tc, "Hodor (1), anonymous, 1 human.", buf); u->flags &= ~UFL_ANON_FACTION; /* we see the same thing as them when we are an ally */ ally_set(&f1->allies, f2, HELP_FSTEALTH); - bufunit(f2, u, seen_unit, buf, sizeof(buf)); + bufunit_depr(f2, u, seen_unit, buf, sizeof(buf)); CuAssertStrEquals(tc, "Hodor (1), TWW (2) (UFO (1)), 1 human.", buf); /* ... also when they are anonymous */ u->flags |= UFL_ANON_FACTION; - bufunit(f2, u, seen_unit, buf, sizeof(buf)); + bufunit_depr(f2, u, seen_unit, buf, sizeof(buf)); CuAssertStrEquals(tc, "Hodor (1), anonymous, 1 human.", buf); u->flags &= ~UFL_ANON_FACTION; /* fstealth has no influence when we are allies, same results again */ set_factionstealth(u, NULL); - bufunit(f2, u, seen_unit, buf, sizeof(buf)); + bufunit_depr(f2, u, seen_unit, buf, sizeof(buf)); CuAssertStrEquals(tc, "Hodor (1), UFO (1), 1 human.", buf); u->flags |= UFL_ANON_FACTION; - bufunit(f2, u, seen_unit, buf, sizeof(buf)); + bufunit_depr(f2, u, seen_unit, buf, sizeof(buf)); CuAssertStrEquals(tc, "Hodor (1), anonymous, 1 human.", buf); u->flags &= ~UFL_ANON_FACTION; @@ -277,20 +277,20 @@ static void test_bufunit(CuTest *tc) { unit_setname(u, "Hodor"); unit_setid(u, 1); - bufunit(u->faction, u, 0, buffer, sizeof(buffer)); + bufunit_depr(u->faction, u, 0, buffer, sizeof(buffer)); CuAssertStrEquals(tc, "Hodor (1), 1 human, aggressiv.", buffer); set_level(u, SK_ALCHEMY, 1); - bufunit(u->faction, u, 0, buffer, sizeof(buffer)); + bufunit_depr(u->faction, u, 0, buffer, sizeof(buffer)); CuAssertStrEquals(tc, "Hodor (1), 1 human, aggressiv, Talente: Alchemie 2.", buffer); set_level(u, SK_SAILING, 1); - bufunit(u->faction, u, 0, buffer, sizeof(buffer)); + bufunit_depr(u->faction, u, 0, buffer, sizeof(buffer)); CuAssertStrEquals(tc, "Hodor (1), 1 human, aggressiv, Talente: Alchemie 2, Segeln 1.", buffer); f = test_create_faction(NULL); f->locale = get_or_create_locale("de"); - bufunit(f, u, 0, buffer, sizeof(buffer)); + bufunit_depr(f, u, 0, buffer, sizeof(buffer)); CuAssertStrEquals(tc, "Hodor (1), UFO (1), 1 human.", buffer); test_teardown(); diff --git a/src/spells.c b/src/spells.c index 7707a05b7..8e3abd253 100644 --- a/src/spells.c +++ b/src/spells.c @@ -3790,7 +3790,7 @@ static int sp_migranten(castorder * co) return 0; } /* maximal Stufe Personen */ - if (target->number > cast_level || target->number > max_spellpoints(r, mage)) { + if (target->number > cast_level || target->number > max_spellpoints_depr(r, mage)) { ADDMSG(&mage->faction->msgs, msg_feedback(mage, co->order, "spellfail_toomanytargets", "")); return 0; diff --git a/src/spy.c b/src/spy.c index 02590bd77..c0d4d614c 100644 --- a/src/spy.c +++ b/src/spy.c @@ -67,7 +67,7 @@ void spy_message(int spy, const unit * u, const unit * target) { char status[32]; - report_status(target, u->faction->locale, status, sizeof(status)); + report_status_depr(target, u->faction->locale, status, sizeof(status)); ADDMSG(&u->faction->msgs, msg_message("spyreport", "spy target status", u, target, status)); diff --git a/src/triggers/shock.c b/src/triggers/shock.c index 9a9d1c74b..0d0177025 100644 --- a/src/triggers/shock.c +++ b/src/triggers/shock.c @@ -67,7 +67,7 @@ static void do_shock(unit * u, const char *reason) /* Aura - Verlust */ if (is_mage(u)) { - int aura = max_spellpoints(u->region, u) / 10; + int aura = max_spellpoints_depr(u->region, u) / 10; int now = get_spellpoints(u); if (now > aura) { set_spellpoints(u, aura); From 1d71e76ad6a0a1ccebbdad3a0cf1b3096f294a93 Mon Sep 17 00:00:00 2001 From: Enno Rehling Date: Sat, 24 Nov 2018 12:46:28 +0100 Subject: [PATCH 154/160] more sbstring stuff --- src/reports.c | 26 ++++++++++++-------------- 1 file changed, 12 insertions(+), 14 deletions(-) diff --git a/src/reports.c b/src/reports.c index d7c101e19..0a96ba697 100644 --- a/src/reports.c +++ b/src/reports.c @@ -2192,31 +2192,29 @@ static void eval_regions(struct opstack **stack, const void *userdata) int handle_end, begin = opop(stack).i; const arg_regions *aregs = (const arg_regions *)opop(stack).v; char buf[256]; - size_t size = sizeof(buf) - 1; variant var; - char *bufp = buf; + sbstring sbs; + sbs_init(&sbs, buf, sizeof(buf)); if (aregs == NULL) { handle_end = begin; } - else { - if (i >= 0) - handle_end = begin + i; - else - handle_end = aregs->nregions + i; + else if (i >= 0) { + handle_end = begin + i; } + else { + handle_end = aregs->nregions + i; + } + for (i = begin; i < handle_end; ++i) { const char *rname = (const char *)regionname(aregs->regions[i], report); - bufp = STRLCPY(bufp, rname, size); + sbs_strcat(&sbs, rname); - if (i + 1 < handle_end && size > 2) { - strcat(bufp, ", "); - bufp += 2; - size -= 2; + if (i + 1 < handle_end) { + sbs_strcat(&sbs, ", "); } } - *bufp = 0; - var.v = strcpy(balloc((size_t)(bufp - buf + 1)), buf); + var.v = strcpy(balloc(sbs_length(&sbs)), buf); opush(stack, var); } From 0fb6b51e5d0801bf852e07fd2437ed0d9eac2d42 Mon Sep 17 00:00:00 2001 From: Enno Rehling Date: Sat, 24 Nov 2018 12:47:52 +0100 Subject: [PATCH 155/160] deprecated function removed --- src/reports.c | 7 ------- 1 file changed, 7 deletions(-) diff --git a/src/reports.c b/src/reports.c index 0a96ba697..58e259c8e 100644 --- a/src/reports.c +++ b/src/reports.c @@ -297,13 +297,6 @@ static void buforder(sbstring *sbp, const order * ord, const struct locale *lang sbs_strcat(sbp, "\""); } -static size_t buforder_depr(char *buffer, size_t size, const order * ord, const struct locale *lang, int mode) { - sbstring sbs; - sbs_init(&sbs, buffer, size); - buforder(&sbs, ord, lang, mode); - return sbs_length(&sbs); -} - /** create a report of a list of items to a non-owner. * \param result: an array of size items. * \param size: maximum number of items to return From 26205094dd0f15807d2cd5e1308ee08062aa457c Mon Sep 17 00:00:00 2001 From: Enno Rehling Date: Sat, 24 Nov 2018 19:27:31 +0100 Subject: [PATCH 156/160] remove unused function --- src/reports.c | 9 --------- 1 file changed, 9 deletions(-) diff --git a/src/reports.c b/src/reports.c index 58e259c8e..2148b2126 100644 --- a/src/reports.c +++ b/src/reports.c @@ -645,15 +645,6 @@ static void spskill(sbstring *sbp, const struct locale * lang, } } -static size_t spskill_depr(char *buffer, size_t size, const struct locale * lang, - const struct unit * u, struct skill * sv, int *dh) -{ - sbstring sbs; - sbs_init(&sbs, buffer, size); - spskill(&sbs, lang, u, sv, dh); - return sbs_length(&sbs); -} - void bufunit(const faction * f, const unit * u, const faction *fv, seen_mode mode, int getarnt, struct sbstring *sbp) { From c757f83a71fc0394f42fde849e2eb956b51b590a Mon Sep 17 00:00:00 2001 From: Enno Rehling Date: Sat, 24 Nov 2018 21:25:46 +0100 Subject: [PATCH 157/160] eliminate bsdstring from reports.c add missing period at end of region info. --- src/report.c | 6 +++--- src/reports.c | 54 ++++++++++++++++++++++++++++----------------------- src/reports.h | 2 +- src/spells.c | 2 +- 4 files changed, 35 insertions(+), 29 deletions(-) diff --git a/src/report.c b/src/report.c index 045ec3c3f..65ef4892b 100644 --- a/src/report.c +++ b/src/report.c @@ -1183,14 +1183,14 @@ void report_region(struct stream *out, const region * r, faction * f) if (wrptr(&bufp, &size, bytes) != 0) WARN_STATIC_BUFFER(); bytes = (int)str_strlcpy(bufp, "\")", size); - if (wrptr(&bufp, &size, bytes) != 0) - WARN_STATIC_BUFFER(); - bytes = (int)str_strlcpy(bufp, ".", size); if (wrptr(&bufp, &size, bytes) != 0) WARN_STATIC_BUFFER(); dh = 1; } } + bytes = (int)str_strlcpy(bufp, ".", size); + if (wrptr(&bufp, &size, bytes) != 0) + WARN_STATIC_BUFFER(); *bufp = 0; paragraph(out, buf, 0, 0, 0); diff --git a/src/reports.c b/src/reports.c index 2148b2126..56c6fd2b1 100644 --- a/src/reports.c +++ b/src/reports.c @@ -64,7 +64,6 @@ OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. /* util includes */ #include "kernel/attrib.h" #include "util/base36.h" -#include "util/bsdstring.h" #include "util/functions.h" #include "util/goodies.h" #include "util/language.h" @@ -2209,41 +2208,49 @@ const char *get_mailcmd(const struct locale *loc) return result; } +static void print_trail(const faction *f, const region *r, + const struct locale *lang, struct sbstring *sbp) +{ + char buf[64]; + const char *trail = trailinto(r, lang); + const char *rn = f_regionid_s(r, f); + if (snprintf(buf, sizeof(buf), trail, rn) != 0) { + sbs_strcat(sbp, buf); + } +} + static void eval_trail(struct opstack **stack, const void *userdata) { /* order -> string */ const faction *report = (const faction *)userdata; const struct locale *lang = report ? report->locale : default_locale; const arg_regions *aregs = (const arg_regions *)opop(stack).v; char buf[512]; - size_t size = sizeof(buf) - 1; variant var; - char *bufp = buf; + sbstring sbs; #ifdef _SECURECRT_ERRCODE_VALUES_DEFINED - /* stupid MS broke snprintf */ + /* MSVC touches errno in snprintf */ int eold = errno; #endif + sbs_init(&sbs, buf, sizeof(buf)); if (aregs != NULL) { int i, handle_end = 0, begin = 0; handle_end = aregs->nregions; for (i = begin; i < handle_end; ++i) { region *r = aregs->regions[i]; - const char *trail = trailinto(r, lang); - const char *rn = f_regionid_s(r, report); + sbs_strcat(&sbs, ", "); - if (wrptr(&bufp, &size, snprintf(bufp, size, trail, rn)) != 0) - WARN_STATIC_BUFFER(); + print_trail(report, r, lang, &sbs); if (i + 2 < handle_end) { - bufp = STRLCPY(bufp, ", ", size); + sbs_strcat(&sbs, ", "); } else if (i + 1 < handle_end) { - bufp = STRLCPY(bufp, LOC(lang, "list_and"), size); + sbs_strcat(&sbs, LOC(lang, "list_and")); } } } - *bufp = 0; - var.v = strcpy(balloc((size_t)(bufp - buf + 1)), buf); + var.v = strcpy(balloc(sbs_length(&sbs)), buf); opush(stack, var); #ifdef _SECURECRT_ERRCODE_VALUES_DEFINED if (errno == ERANGE) { @@ -2252,11 +2259,9 @@ static void eval_trail(struct opstack **stack, const void *userdata) #endif } -void report_race_skills(const race *rc, char *zText, size_t length, const struct locale *lang) +void report_race_skills(const race *rc, const struct locale *lang, sbstring *sbp) { - size_t size = length - 1; int dh = 0, dh1 = 0, sk; - char *bufp = zText; for (sk = 0; sk < MAXSKILLS; ++sk) { if (skill_enabled(sk) && rc->bonus[sk] > -5) @@ -2265,29 +2270,30 @@ void report_race_skills(const race *rc, char *zText, size_t length, const struct for (sk = 0; sk < MAXSKILLS; sk++) { if (skill_enabled(sk) && rc->bonus[sk] > -5) { - size_t bytes; dh--; if (dh1 == 0) { dh1 = 1; } else { if (dh == 0) { - bytes = str_strlcpy(bufp, LOC(lang, "list_and"), size); + sbs_strcat(sbp, LOC(lang, "list_and")); } else { - bytes = str_strlcpy(bufp, ", ", size); + sbs_strcat(sbp, ", "); } - assert(bytes <= INT_MAX); - BUFFER_STRCAT(bufp, size, bytes); } - bytes = str_strlcpy(bufp, skillname((skill_t)sk, lang), - size); - assert(bytes <= INT_MAX); - BUFFER_STRCAT(bufp, size, (int)bytes); + sbs_strcat(sbp, skillname((skill_t)sk, lang)); } } } +void report_race_skills_depr(const race *rc, char *zText, size_t length, const struct locale *lang) +{ + sbstring sbs; + sbs_init(&sbs, zText, length); + report_race_skills(rc, lang, &sbs); +} + static void eval_direction(struct opstack **stack, const void *userdata) { const faction *report = (const faction *)userdata; diff --git a/src/reports.h b/src/reports.h index 14ac6da45..91af51bc2 100644 --- a/src/reports.h +++ b/src/reports.h @@ -121,7 +121,7 @@ extern "C" { const struct unit *owner, const struct faction *viewer); void report_warnings(struct faction *f, int now); void report_raceinfo(const struct race *rc, const struct locale *lang, struct sbstring *sbp); - void report_race_skills(const struct race *rc, char *zText, size_t length, const struct locale *lang); + void report_race_skills_depr(const struct race *rc, char *zText, size_t length, const struct locale *lang); void report_item(const struct unit *owner, const struct item *i, const struct faction *viewer, const char **name, const char **basename, int *number, bool singular); diff --git a/src/spells.c b/src/spells.c index 8e3abd253..b29e86ea9 100644 --- a/src/spells.c +++ b/src/spells.c @@ -592,7 +592,7 @@ static int sp_summon_familiar(castorder * co) msg_release(msg); make_familiar(caster, r, rc, zText); - report_race_skills(rc, zText, sizeof(zText), caster->faction->locale); + report_race_skills_depr(rc, zText, sizeof(zText), caster->faction->locale); ADDMSG(&caster->faction->msgs, msg_message("familiar_describe", "mage race skills", caster, rc, zText)); return cast_level; From 885557493828924b103a6de1647d01b26fae7e55 Mon Sep 17 00:00:00 2001 From: Enno Rehling Date: Sat, 24 Nov 2018 21:47:27 +0100 Subject: [PATCH 158/160] report.c is the last user of bsdstring --- src/report.c | 2 -- 1 file changed, 2 deletions(-) diff --git a/src/report.c b/src/report.c index 65ef4892b..70f03b832 100644 --- a/src/report.c +++ b/src/report.c @@ -1982,8 +1982,6 @@ void report_travelthru(struct stream *out, region *r, const faction *f) } } -#include "util/bsdstring.h" - int report_plaintext(const char *filename, report_context * ctx, const char *bom) From 4c58127ce17a10f7cb6a8fc408dd12e4ab549c89 Mon Sep 17 00:00:00 2001 From: Enno Rehling Date: Sun, 25 Nov 2018 09:21:37 +0100 Subject: [PATCH 159/160] fix renumber parser crash --- src/renumber.c | 2 +- src/renumber.test.c | 9 +++++++-- 2 files changed, 8 insertions(+), 3 deletions(-) diff --git a/src/renumber.c b/src/renumber.c index a4653e1a0..e562a0285 100644 --- a/src/renumber.c +++ b/src/renumber.c @@ -167,7 +167,7 @@ int renumber_cmd(unit * u, order * ord) break; } s = gettoken(token, sizeof(token)); - if (*s == 0) { + if (s == NULL || *s == 0) { i = newcontainerid(); } else { diff --git a/src/renumber.test.c b/src/renumber.test.c index e5f9c5c33..f65011cf7 100644 --- a/src/renumber.test.c +++ b/src/renumber.test.c @@ -101,7 +101,12 @@ static void test_renumber_building(CuTest *tc) { no = u->building->no; uno = (no > 1) ? no - 1 : no + 1; lang = u->faction->locale; - u->thisorder = create_order(K_NUMBER, lang, "%s %s", LOC(lang, parameters[P_BUILDING]), itoa36(uno)); + u->thisorder = create_order(K_NUMBER, lang, LOC(lang, parameters[P_BUILDING])); + renumber_cmd(u, u->thisorder); + CuAssertTrue(tc, no != u->building->no); + free_order(u->thisorder); + + u->thisorder = create_order(K_NUMBER, lang, "%s %i", LOC(lang, parameters[P_BUILDING]), uno); renumber_cmd(u, u->thisorder); CuAssertIntEquals(tc, uno, u->building->no); test_teardown(); @@ -120,7 +125,7 @@ static void test_renumber_building_duplicate(CuTest *tc) { u->building = test_create_building(u->region, NULL); no = u->building->no; lang = f->locale; - u->thisorder = create_order(K_NUMBER, lang, "%s %s", LOC(lang, parameters[P_BUILDING]), itoa36(uno)); + u->thisorder = create_order(K_NUMBER, lang, "%s %i", LOC(lang, parameters[P_BUILDING]), uno); renumber_cmd(u, u->thisorder); CuAssertPtrNotNull(tc, test_find_messagetype(f->msgs, "error115")); CuAssertIntEquals(tc, no, u->building->no); From 8c02d14f133947cce9bd9a051ca97a10171d8ee2 Mon Sep 17 00:00:00 2001 From: Enno Rehling Date: Sun, 25 Nov 2018 09:38:58 +0100 Subject: [PATCH 160/160] undo the period-at-end fix for region info, a test breaks --- src/report.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/report.c b/src/report.c index 70f03b832..04e5408ad 100644 --- a/src/report.c +++ b/src/report.c @@ -1183,14 +1183,14 @@ void report_region(struct stream *out, const region * r, faction * f) if (wrptr(&bufp, &size, bytes) != 0) WARN_STATIC_BUFFER(); bytes = (int)str_strlcpy(bufp, "\")", size); + if (wrptr(&bufp, &size, bytes) != 0) + WARN_STATIC_BUFFER(); + bytes = (int)str_strlcpy(bufp, ".", size); if (wrptr(&bufp, &size, bytes) != 0) WARN_STATIC_BUFFER(); dh = 1; } } - bytes = (int)str_strlcpy(bufp, ".", size); - if (wrptr(&bufp, &size, bytes) != 0) - WARN_STATIC_BUFFER(); *bufp = 0; paragraph(out, buf, 0, 0, 0);