Bug 2605: testing horses and carts

fixing indentation in battle.c
This commit is contained in:
Enno Rehling 2019-09-12 22:23:50 +02:00
parent cc77ce6f20
commit ddc8c27489
7 changed files with 2838 additions and 2835 deletions

View file

@ -1134,19 +1134,6 @@ function test_route_pause()
assert_equal(r1, u.region) assert_equal(r1, u.region)
end end
function test_bug_2393_cart()
local r1 = region.create(0, 0, "plain")
local r2 = region.create(1, 0, "plain")
local f = faction.create("human", "cart@example.com")
local u = unit.create(f, r1, 2)
u:add_order("NACH O")
u:add_item('stone', 2)
u:add_item('horse', 2)
u:add_item('cart', 1)
process_orders()
assert_equal(r1, u.region)
end
function test_immunity_stops_guard() function test_immunity_stops_guard()
eressea.settings.set("NewbieImmunity", 2) eressea.settings.set("NewbieImmunity", 2)
local f = faction.create('human') local f = faction.create('human')

View file

@ -1,6 +1,6 @@
require "lunit" require "lunit"
module("tests.e2.capacity", package.seeall, lunit.testcase) module("tests.e2.carts", package.seeall, lunit.testcase)
function setup() function setup()
eressea.free_game() eressea.free_game()
@ -116,3 +116,72 @@ function test_rider_leads_horses()
assert_equal(r1, u2.region) assert_equal(r1, u2.region)
assert_equal(r1, u3.region) assert_equal(r1, u3.region)
end end
function test_carts()
local r0 = region.create(0, 0, "plain")
local r1 = region.create(1, 0, "plain")
local r2 = region.create(2, 0, "plain")
local r3 = region.create(3, 0, "plain")
local f = faction.create("human")
-- 1. two walkers, each with two horses and a cart:
local u1 = unit.create(f, r0, 2)
u1:add_item("horse", 2)
u1:add_item("cart", 1)
u1:add_order("NACH O O O")
-- 2. two riders, each with two horses and a cart:
local u2 = unit.create(f, r0, 2)
u2:set_skill("riding", 1)
u2:add_item("horse", 4)
u2:add_item("cart", 2)
u2:add_order("NACH O O O")
-- 2. two riders, each with five horses, and max carts:
local u3 = unit.create(f, r0, 2)
u3:set_skill("riding", 1)
u3:add_item("horse", 10)
u3:add_item("cart", 5)
u3:add_order("NACH O O O")
process_orders()
assert_equal(r1, u1.region)
assert_equal(r2, u2.region)
assert_equal(r1, u3.region)
end
function test_walking_carts()
local r0 = region.create(0, 0, "plain")
local r1 = region.create(1, 0, "plain")
local r2 = region.create(2, 0, "plain")
local r3 = region.create(3, 0, "plain")
local f = faction.create("human")
-- 1. ten riders walk with 50 horses and 25 carts, carry 3554 GE:
local u1 = unit.create(f, r0, 10)
u1:set_skill("riding", 1)
u1:add_item("horse", 50)
u1:add_item("cart", 25)
u1:add_item("money", 355400)
u1:add_order("NACH O O O")
process_orders()
assert_equal(r1, u1.region)
end
function test_trolls_pull_carts()
local r0 = region.create(0, 0, "plain")
local r1 = region.create(1, 0, "plain")
local r2 = region.create(2, 0, "plain")
local r3 = region.create(3, 0, "plain")
local f = faction.create("troll")
-- 1. 20 trolls can pull 5 loaded carts:
local u1 = unit.create(f, r0, 20)
u1:add_item("cart", 5)
-- trolls carry 10.8 GE, carts carry 100 GE:
u1:add_item("money", 100 * (5 * 100 + 2 * 108))
u1:add_order("NACH O O O")
process_orders()
assert_equal(r1, u1.region)
u1:add_item("money", 1) -- just one wafer thin mint
process_orders()
assert_equal(r1, u1.region)
end

View file

@ -1,4 +1,4 @@
require 'tests.e2.horses' require 'tests.e2.carts'
require 'tests.e2.quit' require 'tests.e2.quit'
require 'tests.e2.movement' require 'tests.e2.movement'
require 'tests.e2.astral' require 'tests.e2.astral'

View file

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

View file

@ -1177,9 +1177,9 @@ static void calculate_defense_type(troop at, troop dt, int type, bool missile,
*defskill = weapon_effskill(dt, at, weapon, false, false); *defskill = weapon_effskill(dt, at, weapon, false, false);
if (weapon != NULL) if (weapon != NULL)
*dwtype = weapon->type; *dwtype = weapon->type;
} }
static void calculate_attack_type(troop at, troop dt, int type, bool missile, static void calculate_attack_type(troop at, troop dt, int type, bool missile,
const weapon_type **awtype, int *attskill, bool *magic) { const weapon_type **awtype, int *attskill, bool *magic) {
const weapon *weapon; const weapon *weapon;
@ -1202,9 +1202,9 @@ static void calculate_defense_type(troop at, troop dt, int type, bool missile,
default: default:
break; break;
} }
} }
static int crit_damage(int attskill, int defskill, const char *damage_formula) { static int crit_damage(int attskill, int defskill, const char *damage_formula) {
int damage = 0; int damage = 0;
if (rule_damage & DAMAGE_CRITICAL) { if (rule_damage & DAMAGE_CRITICAL) {
double kritchance = ((double)attskill * 3.0 - (double)defskill) / 200.0; double kritchance = ((double)attskill * 3.0 - (double)defskill) / 200.0;
@ -1218,9 +1218,9 @@ static void calculate_defense_type(troop at, troop dt, int type, bool missile,
} }
} }
return damage; return damage;
} }
static int apply_race_resistance(int reduced_damage, fighter *df, static int apply_race_resistance(int reduced_damage, fighter *df,
const weapon_type *awtype, bool magic) { const weapon_type *awtype, bool magic) {
unit *du = df->unit; unit *du = df->unit;
@ -1240,9 +1240,9 @@ static void calculate_defense_type(troop at, troop dt, int type, bool missile,
reduced_damage /= 2; reduced_damage /= 2;
} }
return reduced_damage; return reduced_damage;
} }
static int apply_magicshield(int reduced_damage, fighter *df, static int apply_magicshield(int reduced_damage, fighter *df,
const weapon_type *awtype, battle *b, bool magic) { const weapon_type *awtype, battle *b, bool magic) {
side *ds = df->side; side *ds = df->side;
selist *ql; selist *ql;
@ -1273,11 +1273,11 @@ static void calculate_defense_type(troop at, troop dt, int type, bool missile,
} }
return reduced_damage; return reduced_damage;
} }
bool bool
terminate(troop dt, troop at, int type, const char *damage_formula, bool missile) terminate(troop dt, troop at, int type, const char *damage_formula, bool missile)
{ {
fighter *df = dt.fighter; fighter *df = dt.fighter;
fighter *af = at.fighter; fighter *af = at.fighter;
unit *au = af->unit; unit *au = af->unit;
@ -1361,11 +1361,11 @@ static void calculate_defense_type(troop at, troop dt, int type, bool missile,
kill_troop(dt); kill_troop(dt);
return true; return true;
} }
static int static int
count_side(const side * s, const side * vs, int minrow, int maxrow, int select) count_side(const side * s, const side * vs, int minrow, int maxrow, int select)
{ {
fighter *fig; fighter *fig;
int people = 0; int people = 0;
int unitrow[NUMROWS]; int unitrow[NUMROWS];
@ -1393,14 +1393,14 @@ static void calculate_defense_type(troop at, troop dt, int type, bool missile,
} }
} }
return people; return people;
} }
/* return the number of live allies warning: this function only considers /* return the number of live allies warning: this function only considers
* troops that are still alive, not those that are still fighting although * troops that are still alive, not those that are still fighting although
* dead. */ * dead. */
int int
count_allies(const side * as, int minrow, int maxrow, int select, int allytype) count_allies(const side * as, int minrow, int maxrow, int select, int allytype)
{ {
battle *b = as->battle; battle *b = as->battle;
side *ds; side *ds;
int count = 0; int count = 0;
@ -1414,12 +1414,12 @@ static void calculate_defense_type(troop at, troop dt, int type, bool missile,
} }
} }
return count; return count;
} }
static int static int
count_enemies_i(battle * b, const fighter * af, int minrow, int maxrow, count_enemies_i(battle * b, const fighter * af, int minrow, int maxrow,
int select) int select)
{ {
side *es, *as = af->side; side *es, *as = af->side;
int i = 0; int i = 0;
@ -1435,12 +1435,12 @@ static void calculate_defense_type(troop at, troop dt, int type, bool missile,
} }
} }
return i; return i;
} }
int int
count_enemies(battle * b, const fighter * af, int minrow, int maxrow, count_enemies(battle * b, const fighter * af, int minrow, int maxrow,
int select) int select)
{ {
int sr = statusrow(af->status); int sr = statusrow(af->status);
side *as = af->side; side *as = af->side;
@ -1469,10 +1469,10 @@ static void calculate_defense_type(troop at, troop dt, int type, bool missile,
return i; return i;
} }
return 0; return 0;
} }
troop select_enemy(fighter * af, int minrow, int maxrow, int select) troop select_enemy(fighter * af, int minrow, int maxrow, int select)
{ {
side *as = af->side; side *as = af->side;
battle *b = as->battle; battle *b = as->battle;
int si, selected; int si, selected;
@ -1552,10 +1552,10 @@ static void calculate_defense_type(troop at, troop dt, int type, bool missile,
assert(!selected); assert(!selected);
return no_troop; return no_troop;
#endif #endif
} }
static int get_tactics(const side * as, const side * ds) static int get_tactics(const side * as, const side * ds)
{ {
battle *b = as->battle; battle *b = as->battle;
side *stac; side *stac;
int result = 0; int result = 0;
@ -1574,9 +1574,9 @@ static void calculate_defense_type(troop at, troop dt, int type, bool missile,
} }
} }
return result - defense; return result - defense;
} }
double tactics_chance(const unit *u, int skilldiff) { double tactics_chance(const unit *u, int skilldiff) {
double tacch = 0.1 * skilldiff; double tacch = 0.1 * skilldiff;
if (fval(u->region->terrain, SEA_REGION)) { if (fval(u->region->terrain, SEA_REGION)) {
const ship *sh = u->ship; const ship *sh = u->ship;
@ -1585,10 +1585,10 @@ static void calculate_defense_type(troop at, troop dt, int type, bool missile,
} }
} }
return tacch; return tacch;
} }
static troop select_opponent(battle * b, troop at, int mindist, int maxdist) static troop select_opponent(battle * b, troop at, int mindist, int maxdist)
{ {
fighter *af = at.fighter; fighter *af = at.fighter;
troop dt; troop dt;
@ -1620,10 +1620,10 @@ static void calculate_defense_type(troop at, troop dt, int type, bool missile,
} }
return dt; return dt;
} }
selist *select_fighters(battle * b, const side * vs, int mask, select_fun cb, void *cbdata) selist *select_fighters(battle * b, const side * vs, int mask, select_fun cb, void *cbdata)
{ {
side *s; side *s;
selist *fightervp = 0; selist *fightervp = 0;
@ -1652,42 +1652,42 @@ static void calculate_defense_type(troop at, troop dt, int type, bool missile,
} }
return fightervp; return fightervp;
} }
struct selector { struct selector {
int minrow; int minrow;
int maxrow; int maxrow;
}; };
static bool select_row(const side *vs, const fighter *fig, void *cbdata) static bool select_row(const side *vs, const fighter *fig, void *cbdata)
{ {
struct selector *sel = (struct selector *)cbdata; struct selector *sel = (struct selector *)cbdata;
int row = get_unitrow(fig, vs); int row = get_unitrow(fig, vs);
return (row >= sel->minrow && row <= sel->maxrow); return (row >= sel->minrow && row <= sel->maxrow);
} }
selist *fighters(battle * b, const side * vs, int minrow, int maxrow, int mask) selist *fighters(battle * b, const side * vs, int minrow, int maxrow, int mask)
{ {
struct selector sel; struct selector sel;
sel.maxrow = maxrow; sel.maxrow = maxrow;
sel.minrow = minrow; sel.minrow = minrow;
return select_fighters(b, vs, mask, select_row, &sel); return select_fighters(b, vs, mask, select_row, &sel);
} }
static void report_failed_spell(struct battle * b, struct unit * mage, const struct spell *sp) static void report_failed_spell(struct battle * b, struct unit * mage, const struct spell *sp)
{ {
message *m = msg_message("spell_failed", "unit spell", mage, sp); message *m = msg_message("spell_failed", "unit spell", mage, sp);
message_all(b, m); message_all(b, m);
msg_release(m); msg_release(m);
} }
static castorder * create_castorder_combat(castorder *co, fighter *fig, const spell * sp, int level, double force) { static castorder * create_castorder_combat(castorder *co, fighter *fig, const spell * sp, int level, double force) {
co = create_castorder(co, fig->unit, 0, sp, fig->unit->region, level, force, 0, 0, 0); co = create_castorder(co, fig->unit, 0, sp, fig->unit->region, level, force, 0, 0, 0);
co->magician.fig = fig; co->magician.fig = fig;
return co; return co;
} }
static void summon_igjarjuk(battle *b, spellrank spellranks[]) { static void summon_igjarjuk(battle *b, spellrank spellranks[]) {
side *s; side *s;
castorder *co; castorder *co;
@ -1723,10 +1723,10 @@ static void calculate_defense_type(troop at, troop dt, int type, bool missile,
} }
} }
} }
} }
void do_combatmagic(battle * b, combatmagic_t was) void do_combatmagic(battle * b, combatmagic_t was)
{ {
side *s; side *s;
castorder *co; castorder *co;
region *r = b->region; region *r = b->region;
@ -1817,10 +1817,10 @@ static void calculate_defense_type(troop at, troop dt, int type, bool missile,
for (rank = 0; rank < MAX_SPELLRANK; rank++) { for (rank = 0; rank < MAX_SPELLRANK; rank++) {
free_castorders(spellranks[rank].begin); free_castorders(spellranks[rank].begin);
} }
} }
static int cast_combatspell(troop at, const spell * sp, int level, double force) static int cast_combatspell(troop at, const spell * sp, int level, double force)
{ {
castorder co; castorder co;
create_castorder_combat(&co, at.fighter, sp, level, force); create_castorder_combat(&co, at.fighter, sp, level, force);
@ -1830,10 +1830,10 @@ static void calculate_defense_type(troop at, troop dt, int type, bool missile,
pay_spell(at.fighter->unit, NULL, sp, level, 1); pay_spell(at.fighter->unit, NULL, sp, level, 1);
} }
return level; return level;
} }
static void do_combatspell(troop at) static void do_combatspell(troop at)
{ {
const spell *sp; const spell *sp;
fighter *fi = at.fighter; fighter *fi = at.fighter;
unit *mage = fi->unit; unit *mage = fi->unit;
@ -1896,15 +1896,15 @@ static void calculate_defense_type(troop at, troop dt, int type, bool missile,
} }
level = cast_combatspell(at, sp, level, power); level = cast_combatspell(at, sp, level, power);
} }
/* Sonderattacken: Monster patzern nicht und zahlen auch keine /* Sonderattacken: Monster patzern nicht und zahlen auch keine
* Spruchkosten. Da die Spruchstaerke direkt durch den Level bestimmt * Spruchkosten. Da die Spruchstaerke direkt durch den Level bestimmt
* wird, wirkt auch keine Antimagie (wird sonst in spellpower * wird, wirkt auch keine Antimagie (wird sonst in spellpower
* gemacht) */ * gemacht) */
static void do_extra_spell(troop at, const att * a) static void do_extra_spell(troop at, const att * a)
{ {
const spell *sp = spellref_get(a->data.sp); const spell *sp = spellref_get(a->data.sp);
if (!sp) { if (!sp) {
@ -1914,10 +1914,10 @@ static void calculate_defense_type(troop at, troop dt, int type, bool missile,
assert(a->level > 0); assert(a->level > 0);
cast_combatspell(at, sp, a->level, a->level); cast_combatspell(at, sp, a->level, a->level);
} }
} }
int skilldiff(troop at, troop dt, int dist) int skilldiff(troop at, troop dt, int dist)
{ {
fighter *af = at.fighter, *df = dt.fighter; fighter *af = at.fighter, *df = dt.fighter;
unit *au = af->unit, *du = df->unit; unit *au = af->unit, *du = df->unit;
int is_protected = 0, skdiff = 0; int is_protected = 0, skdiff = 0;
@ -1990,24 +1990,24 @@ static void calculate_defense_type(troop at, troop dt, int type, bool missile,
skdiff -= weapon_effskill(dt, at, dwp, false, dist > 1); skdiff -= weapon_effskill(dt, at, dwp, false, dist > 1);
} }
return skdiff; return skdiff;
} }
static int setreload(troop at) static int setreload(troop at)
{ {
fighter *af = at.fighter; fighter *af = at.fighter;
const weapon_type *wtype = af->person[at.index].missile->type; const weapon_type *wtype = af->person[at.index].missile->type;
if (wtype->reload == 0) if (wtype->reload == 0)
return 0; return 0;
return af->person[at.index].reload = wtype->reload; return af->person[at.index].reload = wtype->reload;
} }
int getreload(troop at) int getreload(troop at)
{ {
return at.fighter->person[at.index].reload; return at.fighter->person[at.index].reload;
} }
int hits(troop at, troop dt, weapon * awp) int hits(troop at, troop dt, weapon * awp)
{ {
fighter *af = at.fighter, *df = dt.fighter; fighter *af = at.fighter, *df = dt.fighter;
const armor_type *armor, *shield = 0; const armor_type *armor, *shield = 0;
int skdiff = 0; int skdiff = 0;
@ -2048,10 +2048,10 @@ static void calculate_defense_type(troop at, troop dt, int type, bool missile,
return 1; return 1;
} }
return 0; return 0;
} }
void dazzle(battle * b, troop * td) void dazzle(battle * b, troop * td)
{ {
UNUSED_ARG(b); UNUSED_ARG(b);
/* Nicht kumulativ ! */ /* Nicht kumulativ ! */
if (td->fighter->person[td->index].flags & (FL_COURAGE | FL_DAZZLED)) { if (td->fighter->person[td->index].flags & (FL_COURAGE | FL_DAZZLED)) {
@ -2060,10 +2060,10 @@ static void calculate_defense_type(troop at, troop dt, int type, bool missile,
td->fighter->person[td->index].flags |= FL_DAZZLED; td->fighter->person[td->index].flags |= FL_DAZZLED;
td->fighter->person[td->index].defense--; td->fighter->person[td->index].defense--;
} }
void damage_building(battle * b, building * bldg, int damage_abs) void damage_building(battle * b, building * bldg, int damage_abs)
{ {
assert(bldg); assert(bldg);
bldg->size -= damage_abs; bldg->size -= damage_abs;
if (bldg->size < 1) bldg->size = 1; if (bldg->size < 1) bldg->size = 1;
@ -2090,15 +2090,15 @@ static void calculate_defense_type(troop at, troop dt, int type, bool missile,
} }
} }
} }
} }
static int attacks_per_round(troop t) static int attacks_per_round(troop t)
{ {
return t.fighter->person[t.index].speed; return t.fighter->person[t.index].speed;
} }
static void make_heroes(battle * b) static void make_heroes(battle * b)
{ {
side *s; side *s;
for (s = b->sides; s != b->sides + b->nsides; ++s) { for (s = b->sides; s != b->sides + b->nsides; ++s) {
fighter *fig; fighter *fig;
@ -2115,10 +2115,10 @@ static void calculate_defense_type(troop at, troop dt, int type, bool missile,
} }
} }
} }
} }
static void attack(battle * b, troop ta, const att * a, int numattack) static void attack(battle * b, troop ta, const att * a, int numattack)
{ {
fighter *af = ta.fighter; fighter *af = ta.fighter;
troop td; troop td;
unit *au = af->unit; unit *au = af->unit;
@ -2271,10 +2271,10 @@ static void calculate_defense_type(troop at, troop dt, int type, bool missile,
damage_building(b, td.fighter->unit->building, dice_rand(a->data.dice)); damage_building(b, td.fighter->unit->building, dice_rand(a->data.dice));
} }
} }
} }
void do_attack(fighter * af) void do_attack(fighter * af)
{ {
troop ta; troop ta;
unit *au = af->unit; unit *au = af->unit;
side *side = af->side; side *side = af->side;
@ -2325,10 +2325,10 @@ static void calculate_defense_type(troop at, troop dt, int type, bool missile,
msg_release(m); msg_release(m);
af->catmsg = -1; af->catmsg = -1;
} }
} }
static void add_tactics(tactics * ta, fighter * fig, int value) static void add_tactics(tactics * ta, fighter * fig, int value)
{ {
if (value == 0 || value < ta->value) if (value == 0 || value < ta->value)
return; return;
if (value > ta->value) { if (value > ta->value) {
@ -2338,10 +2338,10 @@ static void calculate_defense_type(troop at, troop dt, int type, bool missile,
selist_push(&ta->fighters, fig); selist_push(&ta->fighters, fig);
selist_push(&fig->side->battle->leaders, fig); selist_push(&fig->side->battle->leaders, fig);
ta->value = value; ta->value = value;
} }
static int horse_fleeing_bonus(const unit * u) static int horse_fleeing_bonus(const unit * u)
{ {
const item_type *it_horse, *it_elvenhorse, *it_charger; const item_type *it_horse, *it_elvenhorse, *it_charger;
int n1 = 0, n2 = 0, n3 = 0; int n1 = 0, n2 = 0, n3 = 0;
item *itm; item *itm;
@ -2369,10 +2369,10 @@ static void calculate_defense_type(troop at, troop dt, int type, bool missile,
if (n1 + n2 + n3 >= u->number) if (n1 + n2 + n3 >= u->number)
return 10; return 10;
return 0; return 0;
} }
static int fleechance(unit * u) static int fleechance(unit * u)
{ {
int p = flee_chance_base; /* Fluchtwahrscheinlichkeit in % */ int p = flee_chance_base; /* Fluchtwahrscheinlichkeit in % */
/* Einheit u versucht, dem Getuemmel zu entkommen */ /* Einheit u versucht, dem Getuemmel zu entkommen */
@ -2386,14 +2386,14 @@ static void calculate_defense_type(troop at, troop dt, int type, bool missile,
} }
} }
return p; return p;
} }
/** add a new army to the conflict. /** add a new army to the conflict.
* beware: armies need to be added _at the beginning_ of the list because * beware: armies need to be added _at the beginning_ of the list because
* otherwise join_allies() will get into trouble */ * otherwise join_allies() will get into trouble */
side *make_side(battle * b, const faction * f, const group * g, side *make_side(battle * b, const faction * f, const group * g,
unsigned int flags, const faction * stealthfaction) unsigned int flags, const faction * stealthfaction)
{ {
side *s1 = b->sides + b->nsides; side *s1 = b->sides + b->nsides;
bfaction *bf; bfaction *bf;
@ -2432,10 +2432,10 @@ static void calculate_defense_type(troop at, troop dt, int type, bool missile,
} }
assert(bf); assert(bf);
return s1; return s1;
} }
troop select_ally(fighter * af, int minrow, int maxrow, int allytype) troop select_ally(fighter * af, int minrow, int maxrow, int allytype)
{ {
side *as = af->side; side *as = af->side;
battle *b = as->battle; battle *b = as->battle;
side *ds; side *ds;
@ -2467,11 +2467,11 @@ static void calculate_defense_type(troop at, troop dt, int type, bool missile,
} }
assert(!"we should never have gotten here"); assert(!"we should never have gotten here");
return no_troop; return no_troop;
} }
static int loot_quota(const unit * src, const unit * dst, static int loot_quota(const unit * src, const unit * dst,
const item_type * type, int n) const item_type * type, int n)
{ {
UNUSED_ARG(type); UNUSED_ARG(type);
if (dst && src && src->faction != dst->faction) { if (dst && src && src->faction != dst->faction) {
double divisor = config_get_flt("rules.items.loot_divisor", 1); double divisor = config_get_flt("rules.items.loot_divisor", 1);
@ -2488,10 +2488,10 @@ static void calculate_defense_type(troop at, troop dt, int type, bool missile,
} }
} }
return n; return n;
} }
static void loot_items(fighter * corpse) static void loot_items(fighter * corpse)
{ {
unit *u = corpse->unit; unit *u = corpse->unit;
item *itm = u->items; item *itm = u->items;
battle *b = corpse->side->battle; battle *b = corpse->side->battle;
@ -2565,24 +2565,24 @@ static void calculate_defense_type(troop at, troop dt, int type, bool missile,
} }
itm = itm->next; itm = itm->next;
} }
} }
bool seematrix(const faction * f, const side * s) bool seematrix(const faction * f, const side * s)
{ {
if (f == s->faction) if (f == s->faction)
return true; return true;
if (s->flags & SIDE_STEALTH) if (s->flags & SIDE_STEALTH)
return false; return false;
return true; return true;
} }
static double PopulationDamage(void) static double PopulationDamage(void)
{ {
return rule_population_damage / 100.0; return rule_population_damage / 100.0;
} }
static void battle_effects(battle * b, int dead_players) static void battle_effects(battle * b, int dead_players)
{ {
region *r = b->region; region *r = b->region;
int rp = rpeasants(r); int rp = rpeasants(r);
@ -2596,10 +2596,10 @@ static void calculate_defense_type(troop at, troop dt, int type, bool missile,
rsetpeasants(r, rp - dead_peasants); rsetpeasants(r, rp - dead_peasants);
} }
} }
} }
static void reorder_fleeing(region * r) static void reorder_fleeing(region * r)
{ {
unit **usrc = &r->units; unit **usrc = &r->units;
unit **udst = &r->units; unit **udst = &r->units;
unit *ufirst = NULL; unit *ufirst = NULL;
@ -2622,10 +2622,10 @@ static void calculate_defense_type(troop at, troop dt, int type, bool missile,
} }
} }
*udst = NULL; *udst = NULL;
} }
static void aftermath(battle * b) static void aftermath(battle * b)
{ {
region *r = b->region; region *r = b->region;
side *s; side *s;
int dead_players = 0; int dead_players = 0;
@ -2860,10 +2860,10 @@ static void calculate_defense_type(troop at, troop dt, int type, bool missile,
} }
reorder_fleeing(r); reorder_fleeing(r);
} }
static void battle_punit(unit * u, battle * b) static void battle_punit(unit * u, battle * b)
{ {
bfaction *bf; bfaction *bf;
for (bf = b->factions; bf; bf = bf->next) { for (bf = b->factions; bf; bf = bf->next) {
@ -2877,10 +2877,10 @@ static void calculate_defense_type(troop at, troop dt, int type, bool missile,
if (S) if (S)
freestrlist(S); freestrlist(S);
} }
} }
static void print_fighters(battle * b, const side * s) static void print_fighters(battle * b, const side * s)
{ {
fighter *df; fighter *df;
int row; int row;
@ -2902,20 +2902,20 @@ static void calculate_defense_type(troop at, troop dt, int type, bool missile,
if (m != NULL) if (m != NULL)
msg_release(m); msg_release(m);
} }
} }
bool is_attacker(const fighter * fig) bool is_attacker(const fighter * fig)
{ {
return fval(fig, FIG_ATTACKER) != 0; return fval(fig, FIG_ATTACKER) != 0;
} }
static void set_attacker(fighter * fig) static void set_attacker(fighter * fig)
{ {
fset(fig, FIG_ATTACKER); fset(fig, FIG_ATTACKER);
} }
static void print_stats(battle * b) static void print_stats(battle * b)
{ {
side *s2; side *s2;
side *s; side *s;
for (s = b->sides; s != b->sides + b->nsides; ++s) { for (s = b->sides; s != b->sides + b->nsides; ++s) {
@ -3036,18 +3036,18 @@ static void calculate_defense_type(troop at, troop dt, int type, bool missile,
} }
} }
} }
} }
static int weapon_weight(const weapon * w, bool missile) static int weapon_weight(const weapon * w, bool missile)
{ {
if (missile == !!(fval(w->type, WTF_MISSILE))) { if (missile == !!(fval(w->type, WTF_MISSILE))) {
return w->attackskill + w->defenseskill; return w->attackskill + w->defenseskill;
} }
return 0; return 0;
} }
side * get_side(battle * b, const struct unit * u) side * get_side(battle * b, const struct unit * u)
{ {
side * s; side * s;
for (s = b->sides; s != b->sides + b->nsides; ++s) { for (s = b->sides; s != b->sides + b->nsides; ++s) {
if (s->faction == u->faction) { if (s->faction == u->faction) {
@ -3060,10 +3060,10 @@ static void calculate_defense_type(troop at, troop dt, int type, bool missile,
} }
} }
return 0; return 0;
} }
side * find_side(battle * b, const faction * f, const group * g, unsigned int flags, const faction * stealthfaction) side * find_side(battle * b, const faction * f, const group * g, unsigned int flags, const faction * stealthfaction)
{ {
side * s; side * s;
for (s = b->sides; s != b->sides + b->nsides; ++s) { for (s = b->sides; s != b->sides + b->nsides; ++s) {
if (s->faction == f && s->group == g) { if (s->faction == f && s->group == g) {
@ -3078,10 +3078,10 @@ static void calculate_defense_type(troop at, troop dt, int type, bool missile,
} }
} }
return 0; return 0;
} }
fighter *make_fighter(battle * b, unit * u, side * s1, bool attack) fighter *make_fighter(battle * b, unit * u, side * s1, bool attack)
{ {
#define WMAX 20 #define WMAX 20
weapon weapons[WMAX]; weapon weapons[WMAX];
region *r = b->region; region *r = b->region;
@ -3370,10 +3370,10 @@ static void calculate_defense_type(troop at, troop dt, int type, bool missile,
add_tactics(&fig->side->leader, fig, tactics); add_tactics(&fig->side->leader, fig, tactics);
++b->nfighters; ++b->nfighters;
return fig; return fig;
} }
int join_battle(battle * b, unit * u, bool attack, fighter ** cp) int join_battle(battle * b, unit * u, bool attack, fighter ** cp)
{ {
side *s; side *s;
fighter *fc = NULL; fighter *fc = NULL;
@ -3397,10 +3397,10 @@ static void calculate_defense_type(troop at, troop dt, int type, bool missile,
} }
*cp = fc; *cp = fc;
return false; return false;
} }
battle *make_battle(region * r) battle *make_battle(region * r)
{ {
unit *u; unit *u;
bfaction *bf; bfaction *bf;
building * bld; building * bld;
@ -3439,15 +3439,15 @@ static void calculate_defense_type(troop at, troop dt, int type, bool missile,
freset(f, FFL_MARK); freset(f, FFL_MARK);
} }
return b; return b;
} }
static void free_side(side * si) static void free_side(side * si)
{ {
selist_free(si->leader.fighters); selist_free(si->leader.fighters);
} }
static void free_fighter(fighter * fig) static void free_fighter(fighter * fig)
{ {
armor **ap = &fig->armors; armor **ap = &fig->armors;
while (*ap) { while (*ap) {
armor *a = *ap; armor *a = *ap;
@ -3460,9 +3460,9 @@ static void calculate_defense_type(troop at, troop dt, int type, bool missile,
free(fig->person); free(fig->person);
free(fig->weapons); free(fig->weapons);
} }
static void battle_free(battle * b) { static void battle_free(battle * b) {
side *s; side *s;
assert(b); assert(b);
@ -3479,10 +3479,10 @@ static void calculate_defense_type(troop at, troop dt, int type, bool missile,
free_side(s); free_side(s);
} }
free(b); free(b);
} }
void free_battle(battle * b) void free_battle(battle * b)
{ {
while (b->factions) { while (b->factions) {
bfaction *bf = b->factions; bfaction *bf = b->factions;
b->factions = bf->next; b->factions = bf->next;
@ -3494,15 +3494,15 @@ static void calculate_defense_type(troop at, troop dt, int type, bool missile,
selist_free(b->meffects); selist_free(b->meffects);
battle_free(b); battle_free(b);
} }
static int *get_alive(side * s) static int *get_alive(side * s)
{ {
return s->size; return s->size;
} }
static int battle_report(battle * b) static int battle_report(battle * b)
{ {
side *s, *s2; side *s, *s2;
bool cont = false; bool cont = false;
bfaction *bf; bfaction *bf;
@ -3577,10 +3577,10 @@ static void calculate_defense_type(troop at, troop dt, int type, bool missile,
fbattlerecord(b, fac, buf); fbattlerecord(b, fac, buf);
} }
return cont; return cont;
} }
static void join_allies(battle * b) static void join_allies(battle * b)
{ {
region *r = b->region; region *r = b->region;
unit *u; unit *u;
side *s, *s_end = b->sides + b->nsides; side *s, *s_end = b->sides + b->nsides;
@ -3673,10 +3673,10 @@ static void calculate_defense_type(troop at, troop dt, int type, bool missile,
} }
} }
} }
} }
static void flee(const troop dt) static void flee(const troop dt)
{ {
fighter *fig = dt.fighter; fighter *fig = dt.fighter;
unit *u = fig->unit; unit *u = fig->unit;
int fchance = fleechance(u); int fchance = fleechance(u);
@ -3694,9 +3694,9 @@ static void calculate_defense_type(troop at, troop dt, int type, bool missile,
setguard(u, false); setguard(u, false);
kill_troop(dt); kill_troop(dt);
} }
} }
static bool is_calmed(const unit *u, const faction *f) { static bool is_calmed(const unit *u, const faction *f) {
attrib *a = a_find(u->attribs, &at_curse); attrib *a = a_find(u->attribs, &at_curse);
while (a && a->type == &at_curse) { while (a && a->type == &at_curse) {
@ -3709,10 +3709,10 @@ static void calculate_defense_type(troop at, troop dt, int type, bool missile,
a = a->next; a = a->next;
} }
return false; return false;
} }
static bool start_battle(region * r, battle ** bp) static bool start_battle(region * r, battle ** bp)
{ {
battle *b = NULL; battle *b = NULL;
unit *u; unit *u;
bool fighting = false; bool fighting = false;
@ -3861,14 +3861,14 @@ static void calculate_defense_type(troop at, troop dt, int type, bool missile,
} }
*bp = b; *bp = b;
return fighting; return fighting;
} }
/** execute one round of attacks /** execute one round of attacks
* fig->fighting is used to determine who attacks, not fig->alive, since * fig->fighting is used to determine who attacks, not fig->alive, since
* the latter may be influenced by attacks that already took place. * the latter may be influenced by attacks that already took place.
*/ */
static void battle_attacks(battle * b) static void battle_attacks(battle * b)
{ {
side *s; side *s;
for (s = b->sides; s != b->sides + b->nsides; ++s) { for (s = b->sides; s != b->sides + b->nsides; ++s) {
@ -3887,14 +3887,14 @@ static void calculate_defense_type(troop at, troop dt, int type, bool missile,
} }
} }
} }
} }
/** updates the number of attacking troops in each fighter struct. /** updates the number of attacking troops in each fighter struct.
* this has to be calculated _before_ the actual attacks take * this has to be calculated _before_ the actual attacks take
* place because otherwise dead troops would not strike in the * place because otherwise dead troops would not strike in the
* round they die. */ * round they die. */
static void battle_update(battle * b) static void battle_update(battle * b)
{ {
side *s; side *s;
for (s = b->sides; s != b->sides + b->nsides; ++s) { for (s = b->sides; s != b->sides + b->nsides; ++s) {
fighter *fig; fighter *fig;
@ -3902,13 +3902,13 @@ static void calculate_defense_type(troop at, troop dt, int type, bool missile,
fig->fighting = fig->alive - fig->removed; fig->fighting = fig->alive - fig->removed;
} }
} }
} }
/** attempt to flee from battle before the next round begins /** attempt to flee from battle before the next round begins
* there's a double attempt before the first round, but only * there's a double attempt before the first round, but only
* one attempt before round zero, the potential tactics round. */ * one attempt before round zero, the potential tactics round. */
static void battle_flee(battle * b) static void battle_flee(battle * b)
{ {
int attempt, flee_ops = 1; int attempt, flee_ops = 1;
if (b->turn == 1) if (b->turn == 1)
@ -3966,9 +3966,9 @@ static void calculate_defense_type(troop at, troop dt, int type, bool missile,
} }
} }
} }
} }
static bool is_enemy(battle *b, unit *u1, unit *u2) { static bool is_enemy(battle *b, unit *u1, unit *u2) {
if (u1->faction != u2->faction) { if (u1->faction != u2->faction) {
if (b) { if (b) {
side *es, *s1 = 0, *s2 = 0; side *es, *s1 = 0, *s2 = 0;
@ -3985,9 +3985,9 @@ static void calculate_defense_type(troop at, troop dt, int type, bool missile,
} }
} }
return false; return false;
} }
void force_leave(region *r, battle *b) { void force_leave(region *r, battle *b) {
unit *u; unit *u;
for (u = r->units; u; u = u->next) { for (u = r->units; u; u = u->next) {
@ -4012,10 +4012,10 @@ static void calculate_defense_type(troop at, troop dt, int type, bool missile,
leave(u, false); leave(u, false);
} }
} }
} }
static void do_battle(region * r) { static void do_battle(region * r) {
battle *b = NULL; battle *b = NULL;
bool fighting; bool fighting;
ship *sh; ship *sh;
@ -4076,12 +4076,12 @@ static void calculate_defense_type(troop at, troop dt, int type, bool missile,
* Hilfsstrukturen * wieder loeschen: */ * Hilfsstrukturen * wieder loeschen: */
free_battle(b); free_battle(b);
} }
void do_battles(void) { void do_battles(void) {
region *r; region *r;
init_rules(); init_rules();
for (r = regions; r; r = r->next) { for (r = regions; r; r = r->next) {
do_battle(r); do_battle(r);
} }
} }

View file

@ -272,7 +272,7 @@ static int tolua_faction_debug_messages(lua_State * L)
} }
lua_newtable(L); lua_newtable(L);
for (ml = self->msgs->begin; ml; ml = ml->next, ++i) { for (ml = self->msgs->begin; ml; ml = ml->next, ++i) {
char buf[80]; char buf[120];
nr_render(ml->msg, default_locale, buf, sizeof(buf), NULL); nr_render(ml->msg, default_locale, buf, sizeof(buf), NULL);
puts(buf); puts(buf);
} }

View file

@ -258,6 +258,14 @@ get_transporters(const item * itm, int *p_animals, int *p_acap, int *p_vehicles,
*p_acap = acap; *p_acap = acap;
} }
static int walking_horse_limit(const unit *u, int skill) {
return (1 + skill * 4) * u->number;
}
static int riding_horse_limit(const unit *u, int skill) {
return skill * 2 * u->number;
}
static int ridingcapacity(const unit * u) static int ridingcapacity(const unit * u)
{ {
int vehicles = 0, vcap = 0; int vehicles = 0, vcap = 0;
@ -270,7 +278,7 @@ static int ridingcapacity(const unit * u)
** tragen nichts (siehe walkingcapacity). Ein Wagen zaehlt nur, wenn er ** tragen nichts (siehe walkingcapacity). Ein Wagen zaehlt nur, wenn er
** von zwei Pferden gezogen wird */ ** von zwei Pferden gezogen wird */
horses = effskill(u, SK_RIDING, NULL) * u->number * 2; horses = riding_horse_limit(u, effskill(u, SK_RIDING, NULL));
if (animals > horses) animals = horses; if (animals > horses) animals = horses;
if (fval(u_race(u), RCF_HORSE)) if (fval(u_race(u), RCF_HORSE))
@ -297,7 +305,7 @@ int walkingcapacity(const struct unit *u)
/* Das Gewicht, welches die Pferde tragen, plus das Gewicht, welches /* Das Gewicht, welches die Pferde tragen, plus das Gewicht, welches
* die Leute tragen */ * die Leute tragen */
horses = effskill(u, SK_RIDING, NULL) * u->number * 4; horses = walking_horse_limit(u, effskill(u, SK_RIDING, NULL));
pferde_fuer_wagen = (animals < horses) ? animals : horses; pferde_fuer_wagen = (animals < horses) ? animals : horses;
if (fval(u_race(u), RCF_HORSE)) { if (fval(u_race(u), RCF_HORSE)) {
animals += u->number; animals += u->number;
@ -366,7 +374,6 @@ static int canwalk(unit * u)
int maxwagen, maxpferde; int maxwagen, maxpferde;
int vehicles = 0, vcap = 0; int vehicles = 0, vcap = 0;
int animals = 0, acap = 0; int animals = 0, acap = 0;
int effsk;
/* workaround: monsters are too stupid to drop items, therefore they have /* workaround: monsters are too stupid to drop items, therefore they have
* infinite carrying capacity */ * infinite carrying capacity */
@ -375,13 +382,12 @@ static int canwalk(unit * u)
get_transporters(u->items, &animals, &acap, &vehicles, &vcap); get_transporters(u->items, &animals, &acap, &vehicles, &vcap);
effsk = effskill(u, SK_RIDING, NULL); maxpferde = walking_horse_limit(u, effskill(u, SK_RIDING, NULL));
maxwagen = effsk * u->number * 2; maxwagen = maxpferde / 2;
if (u_race(u) == get_race(RC_TROLL)) { if (u_race(u) == get_race(RC_TROLL)) {
int trolls = u->number / 4; int trolls = u->number / 4;
if (maxwagen > trolls) maxwagen = trolls; if (maxwagen < trolls) maxwagen = trolls;
} }
maxpferde = effsk * u->number * 4 + u->number;
if (animals > maxpferde) if (animals > maxpferde)
return E_CANWALK_TOOMANYHORSES; return E_CANWALK_TOOMANYHORSES;
@ -440,7 +446,7 @@ bool canswim(unit * u)
static int walk_mode(const unit * u) static int walk_mode(const unit * u)
{ {
int horses = 0, maxhorses, unicorns = 0, maxunicorns; int horses = 0, maxhorses, unicorns = 0, maxunicorns;
int skill = effskill(u, SK_RIDING, NULL); int skill;
item *itm; item *itm;
const item_type *it_horse, *it_elvenhorse, *it_charger; const item_type *it_horse, *it_elvenhorse, *it_charger;
const resource_type *rtype; const resource_type *rtype;
@ -458,8 +464,9 @@ static int walk_mode(const unit * u)
} }
} }
skill = effskill(u, SK_RIDING, NULL);
maxunicorns = (skill / 5) * u->number; maxunicorns = (skill / 5) * u->number;
maxhorses = skill * u->number * 2; maxhorses = riding_horse_limit(u, skill);
if (!(u_race(u)->flags & RCF_HORSE) if (!(u_race(u)->flags & RCF_HORSE)
&& ((horses == 0 && unicorns == 0) && ((horses == 0 && unicorns == 0)