Bug 2569: Rostregen macht zu viele Waffen kaputt.

This commit is contained in:
Enno Rehling 2019-03-31 21:03:31 +02:00
parent 8f5eff063e
commit 17484e220f
4 changed files with 2840 additions and 2838 deletions

View File

@ -1160,12 +1160,14 @@ static void destroy_items(troop dt) {
if (rng_int() % 4 < 1) { if (rng_int() % 4 < 1) {
i_change(pitm, itype, -1); i_change(pitm, itype, -1);
} }
}
if (*pitm == itm) { if (*pitm == itm) {
pitm = &itm->next; pitm = &itm->next;
} }
} }
else {
pitm = &itm->next;
}
}
} }
static void calculate_defense_type(troop at, troop dt, int type, bool missile, static void calculate_defense_type(troop at, troop dt, int type, bool missile,
@ -3194,6 +3196,8 @@ fighter *make_fighter(battle * b, unit * u, side * s1, bool attack)
if (u_race(u)->battle_flags & BF_EQUIPMENT) { if (u_race(u)->battle_flags & BF_EQUIPMENT) {
int owp[WMAX]; int owp[WMAX];
int dwp[WMAX]; int dwp[WMAX];
int wcount[WMAX];
int wused[WMAX];
int oi = 0, di = 0, w = 0; int oi = 0, di = 0, w = 0;
for (itm = u->items; itm && w != WMAX; itm = itm->next) { for (itm = u->items; itm && w != WMAX; itm = itm->next) {
const weapon_type *wtype = resource2weapon(itm->type->rtype); const weapon_type *wtype = resource2weapon(itm->type->rtype);
@ -3203,8 +3207,8 @@ fighter *make_fighter(battle * b, unit * u, side * s1, bool attack)
weapons[w].defenseskill = weapon_skill(wtype, u, false); weapons[w].defenseskill = weapon_skill(wtype, u, false);
if (weapons[w].attackskill >= 0 || weapons[w].defenseskill >= 0) { if (weapons[w].attackskill >= 0 || weapons[w].defenseskill >= 0) {
weapons[w].type = wtype; weapons[w].type = wtype;
weapons[w].used = 0; wused[w] = 0;
weapons[w].count = itm->number; wcount[w] = itm->number;
++w; ++w;
} }
assert(w != WMAX); assert(w != WMAX);
@ -3242,7 +3246,7 @@ fighter *make_fighter(battle * b, unit * u, side * s1, bool attack)
for (i = 0; i != fig->alive; ++i) { for (i = 0; i != fig->alive; ++i) {
int wpless = weapon_skill(NULL, u, true); int wpless = weapon_skill(NULL, u, true);
while (oi != w while (oi != w
&& (fig->weapons[owp[oi]].used == fig->weapons[owp[oi]].count && (wused[owp[oi]] == wcount[owp[oi]]
|| fval(fig->weapons[owp[oi]].type, WTF_MISSILE))) { || fval(fig->weapons[owp[oi]].type, WTF_MISSILE))) {
++oi; ++oi;
} }
@ -3252,12 +3256,11 @@ fighter *make_fighter(battle * b, unit * u, side * s1, bool attack)
continue; /* we fight better with bare hands */ continue; /* we fight better with bare hands */
} }
fig->person[i].melee = &fig->weapons[owp[oi]]; fig->person[i].melee = &fig->weapons[owp[oi]];
++fig->weapons[owp[oi]].used; ++wused[owp[oi]];
} }
/* hand out missile weapons (from back to front, in case of mixed troops). */ /* hand out missile weapons (from back to front, in case of mixed troops). */
for (di = 0, i = fig->alive; i-- != 0;) { for (di = 0, i = fig->alive; i-- != 0;) {
while (di != w while (di != w && (wused[dwp[di]] == wcount[dwp[di]]
&& (fig->weapons[dwp[di]].used == fig->weapons[dwp[di]].count
|| !fval(fig->weapons[dwp[di]].type, WTF_MISSILE))) { || !fval(fig->weapons[dwp[di]].type, WTF_MISSILE))) {
++di; ++di;
} }
@ -3265,7 +3268,7 @@ fighter *make_fighter(battle * b, unit * u, side * s1, bool attack)
break; /* no more weapons available */ break; /* no more weapons available */
if (weapon_weight(fig->weapons + dwp[di], true) > 0) { if (weapon_weight(fig->weapons + dwp[di], true) > 0) {
fig->person[i].missile = &fig->weapons[dwp[di]]; fig->person[i].missile = &fig->weapons[dwp[di]];
++fig->weapons[dwp[di]].used; ++wused[dwp[di]];
} }
} }
} }

View File

@ -121,7 +121,6 @@ extern "C" {
} battle; } battle;
typedef struct weapon { typedef struct weapon {
int count, used;
const struct weapon_type *type; const struct weapon_type *type;
int attackskill; int attackskill;
int defenseskill; int defenseskill;

View File

@ -96,6 +96,7 @@ static void test_make_fighter(CuTest * tc)
static void test_select_weapon_restricted(CuTest *tc) { static void test_select_weapon_restricted(CuTest *tc) {
item_type *itype; item_type *itype;
weapon_type * wtype;
unit *au; unit *au;
fighter *af; fighter *af;
battle *b; battle *b;
@ -104,7 +105,7 @@ static void test_select_weapon_restricted(CuTest *tc) {
test_setup(); test_setup();
au = test_create_unit(test_create_faction(NULL), test_create_plain(0, 0)); au = test_create_unit(test_create_faction(NULL), test_create_plain(0, 0));
itype = test_create_itemtype("halberd"); itype = test_create_itemtype("halberd");
new_weapontype(itype, 0, frac_zero, NULL, 0, 0, 0, SK_MELEE); wtype = new_weapontype(itype, 0, frac_zero, NULL, 0, 0, 0, SK_MELEE);
i_change(&au->items, itype, 1); i_change(&au->items, itype, 1);
rc = test_create_race("smurf"); rc = test_create_race("smurf");
CuAssertIntEquals(tc, 0, rc->mask_item & au->_race->mask_item); CuAssertIntEquals(tc, 0, rc->mask_item & au->_race->mask_item);
@ -112,15 +113,15 @@ static void test_select_weapon_restricted(CuTest *tc) {
b = make_battle(au->region); b = make_battle(au->region);
af = make_fighter(b, au, make_side(b, au->faction, 0, 0, 0), false); af = make_fighter(b, au, make_side(b, au->faction, 0, 0, 0), false);
CuAssertPtrNotNull(tc, af->weapons); CuAssertPtrNotNull(tc, af->weapons);
CuAssertIntEquals(tc, 1, af->weapons[0].count); CuAssertPtrEquals(tc, wtype, (void *)af->weapons[0].type);
CuAssertIntEquals(tc, 0, af->weapons[1].count); CuAssertPtrEquals(tc, NULL, (void *)af->weapons[1].type);
free_battle(b); free_battle(b);
itype->mask_deny = rc_mask(au->_race); itype->mask_deny = rc_mask(au->_race);
b = make_battle(au->region); b = make_battle(au->region);
af = make_fighter(b, au, make_side(b, au->faction, 0, 0, 0), false); af = make_fighter(b, au, make_side(b, au->faction, 0, 0, 0), false);
CuAssertPtrNotNull(tc, af->weapons); CuAssertPtrNotNull(tc, af->weapons);
CuAssertIntEquals(tc, 0, af->weapons[0].count); CuAssertPtrEquals(tc, NULL, (void *)af->weapons[0].type);
free_battle(b); free_battle(b);
itype->mask_deny = 0; itype->mask_deny = 0;
@ -128,9 +129,8 @@ static void test_select_weapon_restricted(CuTest *tc) {
b = make_battle(au->region); b = make_battle(au->region);
af = make_fighter(b, au, make_side(b, au->faction, 0, 0, 0), false); af = make_fighter(b, au, make_side(b, au->faction, 0, 0, 0), false);
CuAssertPtrNotNull(tc, af->weapons); CuAssertPtrNotNull(tc, af->weapons);
CuAssertIntEquals(tc, 1, af->weapons[0].count); CuAssertPtrEquals(tc, wtype, (void *)af->weapons[0].type);
CuAssertPtrEquals(tc, itype->rtype->wtype, (void *)af->weapons[0].type); CuAssertPtrEquals(tc, NULL, (void *)af->weapons[1].type);
CuAssertIntEquals(tc, 0, af->weapons[1].count);
free_battle(b); free_battle(b);
itype->mask_deny = 0; itype->mask_deny = 0;
@ -138,7 +138,7 @@ static void test_select_weapon_restricted(CuTest *tc) {
b = make_battle(au->region); b = make_battle(au->region);
af = make_fighter(b, au, make_side(b, au->faction, 0, 0, 0), false); af = make_fighter(b, au, make_side(b, au->faction, 0, 0, 0), false);
CuAssertPtrNotNull(tc, af->weapons); CuAssertPtrNotNull(tc, af->weapons);
CuAssertIntEquals(tc, 0, af->weapons[0].count); CuAssertPtrEquals(tc, NULL, (void *)af->weapons[0].type);
free_battle(b); free_battle(b);
itype->mask_deny = 0; itype->mask_deny = 0;
@ -146,8 +146,8 @@ static void test_select_weapon_restricted(CuTest *tc) {
b = make_battle(au->region); b = make_battle(au->region);
af = make_fighter(b, au, make_side(b, au->faction, 0, 0, 0), false); af = make_fighter(b, au, make_side(b, au->faction, 0, 0, 0), false);
CuAssertPtrNotNull(tc, af->weapons); CuAssertPtrNotNull(tc, af->weapons);
CuAssertIntEquals(tc, 1, af->weapons[0].count); CuAssertPtrEquals(tc, wtype, (void *)af->weapons[0].type);
CuAssertIntEquals(tc, 0, af->weapons[1].count); CuAssertPtrEquals(tc, NULL, (void *)af->weapons[1].type);
free_battle(b); free_battle(b);
test_teardown(); test_teardown();

View File

@ -298,35 +298,35 @@ int sp_combatrosthauch(struct castorder * co)
for (w = 0; df->weapons[w].type != NULL; ++w) { for (w = 0; df->weapons[w].type != NULL; ++w) {
weapon *wp = df->weapons; weapon *wp = df->weapons;
int n = force; if (df->unit->items && force > 0) {
if (n > wp->used) n = wp->used; item ** itp = i_find(&df->unit->items, wp->type->itype);
if (n) { if (*itp) {
item *it = *itp;
requirement *mat = wp->type->itype->construction->materials; requirement *mat = wp->type->itype->construction->materials;
bool iron = false; int n = force;
if (it->number < n) n = it->number;
while (mat && mat->number > 0) { while (mat && mat->number > 0) {
if (mat->rtype == get_resourcetype(R_IRON)) { if (mat->rtype == get_resourcetype(R_IRON)) {
iron = true;
break;
}
mat++;
}
if (iron) {
int p; int p;
force -= n; force -= n;
wp->used -= n;
k += n; k += n;
i_change(&df->unit->items, wp->type->itype, -n); i_change(itp, wp->type->itype, -n);
for (p = 0; n && p != df->unit->number; ++p) {
if (df->person[p].melee == wp) {
df->person[p].melee = NULL;
--n;
}
}
for (p = 0; n && p != df->unit->number; ++p) { for (p = 0; n && p != df->unit->number; ++p) {
if (df->person[p].missile == wp) { if (df->person[p].missile == wp) {
df->person[p].missile = NULL; df->person[p].missile = NULL;
--n; --n;
} }
} }
for (p = 0; n && p != df->unit->number; ++p) { break;
if (df->person[p].melee == wp) {
df->person[p].melee = NULL;
--n;
} }
mat++;
} }
} }
} }