diff --git a/src/battle.c b/src/battle.c index 5a4cd2779..fb5f6e035 100644 --- a/src/battle.c +++ b/src/battle.c @@ -226,7 +226,7 @@ int armedmen(const unit * u, bool siege_weapons) const weapon_type *wtype = resource2weapon(itm->type->rtype); if (wtype == NULL || (!siege_weapons && (wtype->flags & WTF_SIEGE))) continue; - if (effskill(u, wtype->skill) >= 1) + if (effskill(u, wtype->skill) >= wtype->minskill) n += itm->number; /* if (effskill(u, wtype->skill) >= wtype->minskill) n += itm->number; */ if (n > u->number) diff --git a/src/kernel/item.c b/src/kernel/item.c index 72ca65885..12adf9e01 100644 --- a/src/kernel/item.c +++ b/src/kernel/item.c @@ -186,7 +186,7 @@ resource_type *rt_get_or_create(const char *name) { return rtype; } -void it_register(item_type * itype) +static void it_register(item_type * itype) { char buffer[64]; const char * name = itype->rtype->_name; @@ -270,6 +270,7 @@ weapon_type *new_weapontype(item_type * itype, { weapon_type *wtype; + assert(minskill > 0); assert(resource2weapon(itype->rtype) == NULL); wtype = calloc(sizeof(weapon_type), 1); diff --git a/src/kernel/item.h b/src/kernel/item.h index ade5cd17a..bbb2653ad 100644 --- a/src/kernel/item.h +++ b/src/kernel/item.h @@ -229,8 +229,6 @@ extern "C" { item_type *it_find(const char *name); void it_set_appearance(item_type *itype, const char *appearance); - void it_register(item_type * it); - void wt_register(weapon_type * wt); extern const item_type *resource2item(const resource_type * rtype); extern const resource_type *item2resource(const item_type * i); diff --git a/src/kernel/race.h b/src/kernel/race.h index d5214e8c9..3cf24f84a 100644 --- a/src/kernel/race.h +++ b/src/kernel/race.h @@ -119,7 +119,7 @@ extern "C" { typedef struct race { struct param *parameters; - const char *_name; /* neu: name[4]völker */ + const char *_name; float magres; float maxaura; /* Faktor auf Maximale Aura */ float regaura; /* Faktor auf Regeneration */ diff --git a/src/kernel/xmlreader.c b/src/kernel/xmlreader.c index d93ec6309..361504b5f 100644 --- a/src/kernel/xmlreader.c +++ b/src/kernel/xmlreader.c @@ -631,7 +631,7 @@ static weapon_type *xml_readweapon(xmlXPathContextPtr xpath, item_type * itype) xmlChar *propValue; int k; skill_t sk; - int minskill = xml_ivalue(node, "minskill", 0); + int minskill = xml_ivalue(node, "minskill", 1); int offmod = xml_ivalue(node, "offmod", 0); int defmod = xml_ivalue(node, "defmod", 0); int reload = xml_ivalue(node, "reload", 0); diff --git a/src/laws.test.c b/src/laws.test.c index 861e1cbe8..6e17c232f 100644 --- a/src/laws.test.c +++ b/src/laws.test.c @@ -22,67 +22,67 @@ static void test_new_building_can_be_renamed(CuTest * tc) { - region *r; - building *b; - building_type *btype; + region *r; + building *b; + building_type *btype; - test_cleanup(); - test_create_world(); + test_cleanup(); + test_create_world(); - btype = bt_get_or_create("castle"); - r = findregion(-1, 0); + btype = bt_get_or_create("castle"); + r = findregion(-1, 0); - b = new_building(btype, r, default_locale); - CuAssertTrue(tc, !renamed_building(b)); + b = new_building(btype, r, default_locale); + CuAssertTrue(tc, !renamed_building(b)); } static void test_rename_building(CuTest * tc) { - region *r; - building *b; - unit *u; - faction *f; - building_type *btype; + region *r; + building *b; + unit *u; + faction *f; + building_type *btype; - test_cleanup(); - test_create_world(); + test_cleanup(); + test_create_world(); - btype = bt_get_or_create("castle"); + btype = bt_get_or_create("castle"); - r = findregion(-1, 0); - b = new_building(btype, r, default_locale); - f = test_create_faction(rc_find("human")); - u = test_create_unit(f, r); - u_set_building(u, b); + r = findregion(-1, 0); + b = new_building(btype, r, default_locale); + f = test_create_faction(NULL); + u = test_create_unit(f, r); + u_set_building(u, b); - rename_building(u, NULL, b, "Villa Nagel"); - CuAssertStrEquals(tc, "Villa Nagel", b->name); + rename_building(u, NULL, b, "Villa Nagel"); + CuAssertStrEquals(tc, "Villa Nagel", b->name); } static void test_rename_building_twice(CuTest * tc) { - region *r; - building *b; - unit *u; - faction *f; - building_type *btype; + region *r; + building *b; + unit *u; + faction *f; + building_type *btype; - test_cleanup(); - test_create_world(); + test_cleanup(); + test_create_world(); - btype = bt_get_or_create("castle"); + btype = bt_get_or_create("castle"); - r = findregion(-1, 0); - b = new_building(btype, r, default_locale); - f = test_create_faction(rc_find("human")); - u = test_create_unit(f, r); - u_set_building(u, b); + r = findregion(-1, 0); + b = new_building(btype, r, default_locale); + f = test_create_faction(NULL); + u = test_create_unit(f, r); + u_set_building(u, b); - rename_building(u, NULL, b, "Villa Nagel"); - CuAssertStrEquals(tc, "Villa Nagel", b->name); + rename_building(u, NULL, b, "Villa Nagel"); + CuAssertStrEquals(tc, "Villa Nagel", b->name); - rename_building(u, NULL, b, "Villa Kunterbunt"); - CuAssertStrEquals(tc, "Villa Kunterbunt", b->name); + rename_building(u, NULL, b, "Villa Kunterbunt"); + CuAssertStrEquals(tc, "Villa Kunterbunt", b->name); } static void test_fishing_feeds_2_people(CuTest * tc) @@ -92,18 +92,18 @@ static void test_fishing_feeds_2_people(CuTest * tc) faction *f; unit *u; ship *sh; - + test_cleanup(); test_create_world(); r = findregion(-1, 0); CuAssertStrEquals(tc, "ocean", r->terrain->_name); /* test_create_world needs coverage */ - f = test_create_faction(rc_find("human")); + f = test_create_faction(NULL); u = test_create_unit(f, r); sh = new_ship(st_find("boat"), r, 0); u_set_ship(u, sh); rtype = get_resourcetype(R_SILVER); i_change(&u->items, rtype->itype, 42); - + scale_number(u, 1); sh->flags |= SF_FISHING; get_food(r); @@ -122,7 +122,7 @@ static void test_fishing_feeds_2_people(CuTest * tc) static int not_so_hungry(const unit * u) { - return 6 * u->number; + return 6 * u->number; } static void test_fishing_does_not_give_goblins_money(CuTest * tc) @@ -132,14 +132,14 @@ static void test_fishing_does_not_give_goblins_money(CuTest * tc) faction *f; unit *u; ship *sh; - + test_cleanup(); test_create_world(); rtype = get_resourcetype(R_SILVER); - + r = findregion(-1, 0); CuAssertStrEquals(tc, "ocean", r->terrain->_name); /* test_create_world needs coverage */ - f = test_create_faction(rc_find("human")); + f = test_create_faction(NULL); u = test_create_unit(f, r); sh = new_ship(st_find("boat"), r, 0); u_set_ship(u, sh); @@ -159,23 +159,23 @@ static void test_fishing_gets_reset(CuTest * tc) faction *f; unit *u; ship *sh; - + test_cleanup(); test_create_world(); rtype = get_resourcetype(R_SILVER); r = findregion(-1, 0); CuAssertStrEquals(tc, "ocean", r->terrain->_name); /* test_create_world needs coverage */ - f = test_create_faction(rc_find("human")); + f = test_create_faction(NULL); u = test_create_unit(f, r); sh = new_ship(st_find("boat"), r, 0); u_set_ship(u, sh); i_change(&u->items, rtype->itype, 42); - + scale_number(u, 1); sh->flags |= SF_FISHING; get_food(r); CuAssertIntEquals(tc, 42, i_get(u->items, rtype->itype)); - + scale_number(u, 1); get_food(r); CuAssertIntEquals(tc, 32, i_get(u->items, rtype->itype)); @@ -183,33 +183,33 @@ static void test_fishing_gets_reset(CuTest * tc) static void test_unit_limit(CuTest * tc) { - set_param(&global.parameters, "rules.limit.faction", "250"); - CuAssertIntEquals(tc, 250, rule_faction_limit()); + set_param(&global.parameters, "rules.limit.faction", "250"); + CuAssertIntEquals(tc, 250, rule_faction_limit()); - set_param(&global.parameters, "rules.limit.faction", "200"); - CuAssertIntEquals(tc, 200, rule_faction_limit()); + set_param(&global.parameters, "rules.limit.faction", "200"); + CuAssertIntEquals(tc, 200, rule_faction_limit()); - set_param(&global.parameters, "rules.limit.alliance", "250"); - CuAssertIntEquals(tc, 250, rule_alliance_limit()); + set_param(&global.parameters, "rules.limit.alliance", "250"); + CuAssertIntEquals(tc, 250, rule_alliance_limit()); } extern int checkunitnumber(const faction * f, int add); static void test_cannot_create_unit_above_limit(CuTest * tc) { - faction *f; + faction *f; - test_cleanup(); - test_create_world(); - f = test_create_faction(rc_find("human")); - set_param(&global.parameters, "rules.limit.faction", "4"); + test_cleanup(); + test_create_world(); + f = test_create_faction(NULL); + set_param(&global.parameters, "rules.limit.faction", "4"); - CuAssertIntEquals(tc, 0, checkunitnumber(f, 4)); - CuAssertIntEquals(tc, 2, checkunitnumber(f, 5)); + CuAssertIntEquals(tc, 0, checkunitnumber(f, 4)); + CuAssertIntEquals(tc, 2, checkunitnumber(f, 5)); - set_param(&global.parameters, "rules.limit.alliance", "3"); - CuAssertIntEquals(tc, 0, checkunitnumber(f, 3)); - CuAssertIntEquals(tc, 1, checkunitnumber(f, 4)); + set_param(&global.parameters, "rules.limit.alliance", "3"); + CuAssertIntEquals(tc, 0, checkunitnumber(f, 3)); + CuAssertIntEquals(tc, 1, checkunitnumber(f, 4)); } static void test_reserve_cmd(CuTest *tc) { @@ -225,7 +225,7 @@ static void test_reserve_cmd(CuTest *tc) { rtype = get_resourcetype(R_SILVER); assert(rtype && rtype->itype); - f = test_create_faction(rc_find("human")); + f = test_create_faction(NULL); r = findregion(0, 0); assert(r && f); u1 = test_create_unit(f, r); @@ -251,7 +251,7 @@ static void test_new_units(CuTest *tc) { const struct locale *loc; test_cleanup(); test_create_world(); - f = test_create_faction(rc_find("human")); + f = test_create_faction(NULL); r = findregion(0, 0); assert(r && f); u = test_create_unit(f, r); @@ -266,6 +266,102 @@ static void test_new_units(CuTest *tc) { test_cleanup(); } +typedef struct guard_fixture { + unit * u; +} guard_fixture; + +void setup_guard(guard_fixture *fix, bool armed) { + region *r; + faction *f; + unit * u; + + test_cleanup(); + test_create_world(); + + f = test_create_faction(NULL); + r = findregion(0, 0); + assert(r && f); + u = test_create_unit(f, r); + fset(u, UFL_GUARD); + u->status = ST_FIGHT; + + if (armed) { + item_type *itype; + weapon_type *wtype; + itype = it_get_or_create(rt_get_or_create("sword")); + wtype = new_weapontype(itype, 0, 0.0, NULL, 0, 0, 0, SK_MELEE, 2); + i_change(&u->items, itype, 1); + set_level(u, SK_MELEE, 2); + } + fix->u = u; +} + +static void test_update_guards(CuTest *tc) { + guard_fixture fix; + + setup_guard(&fix, true); + + update_guards(); + CuAssertTrue(tc, fval(fix.u, UFL_GUARD)); + freset(fix.u, UFL_GUARD); + update_guards(); + CuAssertTrue(tc, !fval(fix.u, UFL_GUARD)); + test_cleanup(); +} + +static void test_newbie_cannot_guard(CuTest *tc) { + guard_fixture fix; + + setup_guard(&fix, true); + set_param(&global.parameters, "NewbieImmunity", "4"); + CuAssertTrue(tc, IsImmune(fix.u->faction)); + update_guards(); + CuAssertTrue(tc, !fval(fix.u, UFL_GUARD)); + test_cleanup(); +} + +static void test_unarmed_cannot_guard(CuTest *tc) { + guard_fixture fix; + + setup_guard(&fix, false); + update_guards(); + CuAssertTrue(tc, !fval(fix.u, UFL_GUARD)); + test_cleanup(); +} + +static void test_unarmed_races_can_guard(CuTest *tc) { + guard_fixture fix; + race * rc; + + setup_guard(&fix, false); + rc = rc_get_or_create(fix.u->race_->_name); + rc->flags |= RCF_UNARMEDGUARD; + update_guards(); + CuAssertTrue(tc, fval(fix.u, UFL_GUARD)); + test_cleanup(); +} + +static void test_low_skill_cannot_guard(CuTest *tc) { + guard_fixture fix; + + setup_guard(&fix, true); + set_level(fix.u, SK_MELEE, 1); + fix.u->status = ST_FLEE; + update_guards(); + CuAssertTrue(tc, !fval(fix.u, UFL_GUARD)); + test_cleanup(); +} + +static void test_fleeing_cannot_guard(CuTest *tc) { + guard_fixture fix; + + setup_guard(&fix, true); + fix.u->status = ST_FLEE; + update_guards(); + CuAssertTrue(tc, !fval(fix.u, UFL_GUARD)); + test_cleanup(); +} + static void test_reserve_self(CuTest *tc) { unit *u1, *u2; faction *f; @@ -279,7 +375,7 @@ static void test_reserve_self(CuTest *tc) { rtype = get_resourcetype(R_SILVER); assert(rtype && rtype->itype); - f = test_create_faction(rc_find("human")); + f = test_create_faction(NULL); r = findregion(0, 0); assert(r && f); u1 = test_create_unit(f, r); @@ -299,17 +395,23 @@ static void test_reserve_self(CuTest *tc) { CuSuite *get_laws_suite(void) { - CuSuite *suite = CuSuiteNew(); - SUITE_ADD_TEST(suite, test_new_building_can_be_renamed); - SUITE_ADD_TEST(suite, test_rename_building); - SUITE_ADD_TEST(suite, test_rename_building_twice); - SUITE_ADD_TEST(suite, test_fishing_feeds_2_people); - SUITE_ADD_TEST(suite, test_fishing_does_not_give_goblins_money); - SUITE_ADD_TEST(suite, test_fishing_gets_reset); - SUITE_ADD_TEST(suite, test_unit_limit); - SUITE_ADD_TEST(suite, test_reserve_self); - SUITE_ADD_TEST(suite, test_reserve_cmd); - SUITE_ADD_TEST(suite, test_new_units); - SUITE_ADD_TEST(suite, test_cannot_create_unit_above_limit); - return suite; + CuSuite *suite = CuSuiteNew(); + SUITE_ADD_TEST(suite, test_new_building_can_be_renamed); + SUITE_ADD_TEST(suite, test_rename_building); + SUITE_ADD_TEST(suite, test_rename_building_twice); + SUITE_ADD_TEST(suite, test_fishing_feeds_2_people); + SUITE_ADD_TEST(suite, test_fishing_does_not_give_goblins_money); + SUITE_ADD_TEST(suite, test_fishing_gets_reset); + SUITE_ADD_TEST(suite, test_unit_limit); + SUITE_ADD_TEST(suite, test_update_guards); + SUITE_ADD_TEST(suite, test_newbie_cannot_guard); + SUITE_ADD_TEST(suite, test_unarmed_cannot_guard); + SUITE_ADD_TEST(suite, test_unarmed_races_can_guard); + SUITE_ADD_TEST(suite, test_fleeing_cannot_guard); + SUITE_ADD_TEST(suite, test_low_skill_cannot_guard); + SUITE_ADD_TEST(suite, test_reserve_self); + SUITE_ADD_TEST(suite, test_reserve_cmd); + SUITE_ADD_TEST(suite, test_new_units); + SUITE_ADD_TEST(suite, test_cannot_create_unit_above_limit); + return suite; }