forked from github/server
commit
f9b2c40792
9 changed files with 2884 additions and 2842 deletions
|
@ -31,7 +31,15 @@ function test_undead_reserve_other()
|
|||
u1.name = 'Xolgrim'
|
||||
process_orders()
|
||||
|
||||
if 0 ~= u1:get_item("log") then
|
||||
-- try to catch that intermittent bug:
|
||||
print(u1:show())
|
||||
end
|
||||
assert_equal(0, u1:get_item("log"))
|
||||
if 2 ~= u2:get_item("log") then
|
||||
-- try to catch that intermittent bug:
|
||||
print(u2:show())
|
||||
end
|
||||
assert_equal(2, u2:get_item("log"))
|
||||
end
|
||||
|
||||
|
|
21
src/battle.c
21
src/battle.c
|
@ -1160,12 +1160,14 @@ static void destroy_items(troop dt) {
|
|||
if (rng_int() % 4 < 1) {
|
||||
i_change(pitm, itype, -1);
|
||||
}
|
||||
}
|
||||
if (*pitm == itm) {
|
||||
pitm = &itm->next;
|
||||
}
|
||||
}
|
||||
|
||||
else {
|
||||
pitm = &itm->next;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
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) {
|
||||
int owp[WMAX];
|
||||
int dwp[WMAX];
|
||||
int wcount[WMAX];
|
||||
int wused[WMAX];
|
||||
int oi = 0, di = 0, w = 0;
|
||||
for (itm = u->items; itm && w != WMAX; itm = itm->next) {
|
||||
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);
|
||||
if (weapons[w].attackskill >= 0 || weapons[w].defenseskill >= 0) {
|
||||
weapons[w].type = wtype;
|
||||
weapons[w].used = 0;
|
||||
weapons[w].count = itm->number;
|
||||
wused[w] = 0;
|
||||
wcount[w] = itm->number;
|
||||
++w;
|
||||
}
|
||||
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) {
|
||||
int wpless = weapon_skill(NULL, u, true);
|
||||
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))) {
|
||||
++oi;
|
||||
}
|
||||
|
@ -3252,12 +3256,11 @@ fighter *make_fighter(battle * b, unit * u, side * s1, bool attack)
|
|||
continue; /* we fight better with bare hands */
|
||||
}
|
||||
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). */
|
||||
for (di = 0, i = fig->alive; i-- != 0;) {
|
||||
while (di != w
|
||||
&& (fig->weapons[dwp[di]].used == fig->weapons[dwp[di]].count
|
||||
while (di != w && (wused[dwp[di]] == wcount[dwp[di]]
|
||||
|| !fval(fig->weapons[dwp[di]].type, WTF_MISSILE))) {
|
||||
++di;
|
||||
}
|
||||
|
@ -3265,7 +3268,7 @@ fighter *make_fighter(battle * b, unit * u, side * s1, bool attack)
|
|||
break; /* no more weapons available */
|
||||
if (weapon_weight(fig->weapons + dwp[di], true) > 0) {
|
||||
fig->person[i].missile = &fig->weapons[dwp[di]];
|
||||
++fig->weapons[dwp[di]].used;
|
||||
++wused[dwp[di]];
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -121,7 +121,6 @@ extern "C" {
|
|||
} battle;
|
||||
|
||||
typedef struct weapon {
|
||||
int count, used;
|
||||
const struct weapon_type *type;
|
||||
int attackskill;
|
||||
int defenseskill;
|
||||
|
|
|
@ -96,6 +96,7 @@ static void test_make_fighter(CuTest * tc)
|
|||
|
||||
static void test_select_weapon_restricted(CuTest *tc) {
|
||||
item_type *itype;
|
||||
weapon_type * wtype;
|
||||
unit *au;
|
||||
fighter *af;
|
||||
battle *b;
|
||||
|
@ -104,7 +105,7 @@ static void test_select_weapon_restricted(CuTest *tc) {
|
|||
test_setup();
|
||||
au = test_create_unit(test_create_faction(NULL), test_create_plain(0, 0));
|
||||
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);
|
||||
rc = test_create_race("smurf");
|
||||
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);
|
||||
af = make_fighter(b, au, make_side(b, au->faction, 0, 0, 0), false);
|
||||
CuAssertPtrNotNull(tc, af->weapons);
|
||||
CuAssertIntEquals(tc, 1, af->weapons[0].count);
|
||||
CuAssertIntEquals(tc, 0, af->weapons[1].count);
|
||||
CuAssertPtrEquals(tc, wtype, (void *)af->weapons[0].type);
|
||||
CuAssertPtrEquals(tc, NULL, (void *)af->weapons[1].type);
|
||||
free_battle(b);
|
||||
|
||||
itype->mask_deny = rc_mask(au->_race);
|
||||
b = make_battle(au->region);
|
||||
af = make_fighter(b, au, make_side(b, au->faction, 0, 0, 0), false);
|
||||
CuAssertPtrNotNull(tc, af->weapons);
|
||||
CuAssertIntEquals(tc, 0, af->weapons[0].count);
|
||||
CuAssertPtrEquals(tc, NULL, (void *)af->weapons[0].type);
|
||||
free_battle(b);
|
||||
|
||||
itype->mask_deny = 0;
|
||||
|
@ -128,9 +129,8 @@ static void test_select_weapon_restricted(CuTest *tc) {
|
|||
b = make_battle(au->region);
|
||||
af = make_fighter(b, au, make_side(b, au->faction, 0, 0, 0), false);
|
||||
CuAssertPtrNotNull(tc, af->weapons);
|
||||
CuAssertIntEquals(tc, 1, af->weapons[0].count);
|
||||
CuAssertPtrEquals(tc, itype->rtype->wtype, (void *)af->weapons[0].type);
|
||||
CuAssertIntEquals(tc, 0, af->weapons[1].count);
|
||||
CuAssertPtrEquals(tc, wtype, (void *)af->weapons[0].type);
|
||||
CuAssertPtrEquals(tc, NULL, (void *)af->weapons[1].type);
|
||||
free_battle(b);
|
||||
|
||||
itype->mask_deny = 0;
|
||||
|
@ -138,7 +138,7 @@ static void test_select_weapon_restricted(CuTest *tc) {
|
|||
b = make_battle(au->region);
|
||||
af = make_fighter(b, au, make_side(b, au->faction, 0, 0, 0), false);
|
||||
CuAssertPtrNotNull(tc, af->weapons);
|
||||
CuAssertIntEquals(tc, 0, af->weapons[0].count);
|
||||
CuAssertPtrEquals(tc, NULL, (void *)af->weapons[0].type);
|
||||
free_battle(b);
|
||||
|
||||
itype->mask_deny = 0;
|
||||
|
@ -146,8 +146,8 @@ static void test_select_weapon_restricted(CuTest *tc) {
|
|||
b = make_battle(au->region);
|
||||
af = make_fighter(b, au, make_side(b, au->faction, 0, 0, 0), false);
|
||||
CuAssertPtrNotNull(tc, af->weapons);
|
||||
CuAssertIntEquals(tc, 1, af->weapons[0].count);
|
||||
CuAssertIntEquals(tc, 0, af->weapons[1].count);
|
||||
CuAssertPtrEquals(tc, wtype, (void *)af->weapons[0].type);
|
||||
CuAssertPtrEquals(tc, NULL, (void *)af->weapons[1].type);
|
||||
free_battle(b);
|
||||
|
||||
test_teardown();
|
||||
|
|
|
@ -383,7 +383,8 @@ static int tolua_faction_set_password(lua_State * L)
|
|||
{
|
||||
faction *self = (faction *)tolua_tousertype(L, 1, NULL);
|
||||
const char * passw = tolua_tostring(L, 2, NULL);
|
||||
faction_setpassword(self, password_hash(passw, PASSWORD_DEFAULT));
|
||||
faction_setpassword(self,
|
||||
passw ? password_hash(passw, PASSWORD_DEFAULT) : NULL);
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
|
|
@ -564,9 +564,13 @@ const char *faction_getpassword(const faction *f) {
|
|||
|
||||
void faction_setpassword(faction * f, const char *pwhash)
|
||||
{
|
||||
assert(pwhash);
|
||||
if (pwhash) {
|
||||
f->password_id = dbstring_save(pwhash);
|
||||
}
|
||||
else {
|
||||
f->password_id = 0;
|
||||
}
|
||||
}
|
||||
|
||||
bool valid_race(const struct faction *f, const struct race *rc)
|
||||
{
|
||||
|
|
|
@ -41,8 +41,9 @@
|
|||
#define CRYPT_VERSION 363 /* passwords are encrypted */
|
||||
#define FAMILIAR_FIXMAGE_VERSION 364 /* familiar links are fixed */
|
||||
#define FAMILIAR_FIXSPELLBOOK_VERSION 365 /* familiar spells are fixed */
|
||||
#define FIX_STARTLEVEL_VERSION 366 /* fixing resource startlevels */
|
||||
|
||||
#define RELEASE_VERSION FAMILIAR_FIXSPELLBOOK_VERSION /* current datafile */
|
||||
#define RELEASE_VERSION FIX_STARTLEVEL_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 */
|
||||
|
||||
|
|
|
@ -613,6 +613,27 @@ static void read_regioninfo(gamedata *data, const region *r, char *info, size_t
|
|||
}
|
||||
}
|
||||
|
||||
static void fix_baselevel(region *r) {
|
||||
struct terrain_production *p;
|
||||
for (p = r->terrain->production; p->type; ++p) {
|
||||
char *end;
|
||||
long start = (int)strtol(p->startlevel, &end, 10);
|
||||
if (*end == '\0') {
|
||||
rawmaterial *res;
|
||||
for (res = r->resources; res; res = res->next) {
|
||||
if (p->type == res->rtype) {
|
||||
if (start != res->startlevel) {
|
||||
log_debug("setting resource start level for %s in %s to %d",
|
||||
res->rtype->_name, regionname(r, NULL), start);
|
||||
res->startlevel = start;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
static region *readregion(gamedata *data, int x, int y)
|
||||
{
|
||||
region *r;
|
||||
|
@ -781,6 +802,11 @@ static region *readregion(gamedata *data, int x, int y)
|
|||
}
|
||||
}
|
||||
read_attribs(data, &r->attribs, r);
|
||||
|
||||
if (r->resources && data->version < FIX_STARTLEVEL_VERSION) {
|
||||
/* we had some badly made rawmaterials before this */
|
||||
fix_baselevel(r);
|
||||
}
|
||||
return r;
|
||||
}
|
||||
|
||||
|
|
|
@ -298,35 +298,35 @@ int sp_combatrosthauch(struct castorder * co)
|
|||
|
||||
for (w = 0; df->weapons[w].type != NULL; ++w) {
|
||||
weapon *wp = df->weapons;
|
||||
int n = force;
|
||||
if (n > wp->used) n = wp->used;
|
||||
if (n) {
|
||||
if (df->unit->items && force > 0) {
|
||||
item ** itp = i_find(&df->unit->items, wp->type->itype);
|
||||
if (*itp) {
|
||||
item *it = *itp;
|
||||
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) {
|
||||
if (mat->rtype == get_resourcetype(R_IRON)) {
|
||||
iron = true;
|
||||
break;
|
||||
}
|
||||
mat++;
|
||||
}
|
||||
if (iron) {
|
||||
int p;
|
||||
force -= n;
|
||||
wp->used -= 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) {
|
||||
if (df->person[p].missile == wp) {
|
||||
df->person[p].missile = NULL;
|
||||
--n;
|
||||
}
|
||||
}
|
||||
for (p = 0; n && p != df->unit->number; ++p) {
|
||||
if (df->person[p].melee == wp) {
|
||||
df->person[p].melee = NULL;
|
||||
--n;
|
||||
break;
|
||||
}
|
||||
mat++;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
Loading…
Reference in a new issue