make item_use function crash if new and old rules do not agree

add a 'test' function to E3 that exercises all those items
This commit is contained in:
Enno Rehling 2017-02-28 10:48:27 +01:00
parent 9871d6f23f
commit 5a01eae522
7 changed files with 112 additions and 3 deletions

View file

@ -4,6 +4,7 @@ require 'tests.e3.spells'
require 'tests.e3.rules' require 'tests.e3.rules'
require 'tests.e3.parser' require 'tests.e3.parser'
require 'tests.e3.morale' require 'tests.e3.morale'
require 'tests.e3.items'
require 'tests.orders' require 'tests.orders'
require 'tests.common' require 'tests.common'
require 'tests.items' require 'tests.items'

View file

@ -0,0 +1,35 @@
require "lunit"
module("tests.e3.items", package.seeall, lunit.testcase )
function setup()
eressea.game.reset()
eressea.settings.set("rules.food.flags", "4") -- food is free
eressea.settings.set("NewbieImmunity", "0")
end
function test_goblins()
local r = region.create(0, 0, "plain")
assert(r)
local f1 = faction.create("goblin@eressea.de", "goblin", "de")
local f2 = faction.create("dwarf@eressea.de", "dwarf", "de")
local f3 = faction.create("elf@eressea.de", "elf", "de")
local u1 = unit.create(f1, r, 1)
local u2 = unit.create(f2, r, 1)
local u3 = unit.create(f3, r, 1)
local restricted = {
"towershield", "rep_crossbow", "plate", "lance",
"mllornlance", "greatbow", "greataxe", "axe", "scale",
"plate", "rustyhalberd", "halberd", "greatsword"
}
for k, v in ipairs(restricted) do
u1:add_item(v, 1)
u2:add_item(v, 1)
u2:add_item(v, 1)
end
u1:add_order("ATTACKIERE " .. itoa36(u2.id))
u1:add_order("ATTACKIERE " .. itoa36(u3.id))
process_orders()
end

View file

@ -576,10 +576,12 @@ static weapon *select_weapon(const troop t, bool attacking,
static bool i_canuse(const unit * u, const item_type * itype) static bool i_canuse(const unit * u, const item_type * itype)
{ {
bool result = true;
if (itype->canuse) { if (itype->canuse) {
return itype->canuse(u, itype); result = itype->canuse(u, itype);
} }
return true; assert(result==rc_can_use(u_race(u), itype));
return result;
} }
static int static int

View file

@ -121,6 +121,8 @@ extern "C" {
unsigned int flags; unsigned int flags;
int weight; int weight;
int capacity; int capacity;
int mask_allow;
int mask_deny;
struct construction *construction; struct construction *construction;
char *_appearance[2]; /* wie es f<>r andere aussieht */ char *_appearance[2]; /* wie es f<>r andere aussieht */
/* --- functions --- */ /* --- functions --- */

View file

@ -54,6 +54,7 @@ OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
/* libc includes */ /* libc includes */
#include <assert.h> #include <assert.h>
#include <ctype.h> #include <ctype.h>
#include <limits.h>
#include <math.h> #include <math.h>
#include <stdio.h> #include <stdio.h>
#include <string.h> #include <string.h>
@ -94,6 +95,7 @@ enum {
RCO_TRADEHERB RCO_TRADEHERB
}; };
static void rc_setoption(race *rc, int k, const char *value) { static void rc_setoption(race *rc, int k, const char *value) {
unsigned char key = (unsigned char)k; unsigned char key = (unsigned char)k;
int i; int i;
@ -323,6 +325,17 @@ bool rc_changed(int *cache) {
return false; return false;
} }
bool rc_can_use(const struct race *rc, const struct item_type *itype)
{
if (itype->mask_allow) {
return (rc->mask_item==0 || (itype->mask_allow & rc->mask_item) != 0);
}
if (itype->mask_deny) {
return (itype->mask_deny & rc->mask_item) == 0;
}
return true;
}
race *rc_create(const char *zName) race *rc_create(const char *zName)
{ {
race *rc; race *rc;

View file

@ -48,6 +48,7 @@ extern "C" {
struct spellref; struct spellref;
struct locale; struct locale;
struct rcoption; struct rcoption;
struct item_type;
extern int num_races; extern int num_races;
@ -140,6 +141,7 @@ extern "C" {
int flags; int flags;
int battle_flags; int battle_flags;
int ec_flags; int ec_flags;
int mask_item;
struct att attack[RACE_ATTACKS]; struct att attack[RACE_ATTACKS];
signed char bonus[MAXSKILLS]; signed char bonus[MAXSKILLS];
@ -174,6 +176,8 @@ extern "C" {
const race *rc_find(const char *); const race *rc_find(const char *);
void free_races(void); void free_races(void);
bool rc_can_use(const struct race *rc, const struct item_type *itype);
typedef enum name_t { NAME_SINGULAR, NAME_PLURAL, NAME_DEFINITIVE, NAME_CATEGORY } name_t; typedef enum name_t { NAME_SINGULAR, NAME_PLURAL, NAME_DEFINITIVE, NAME_CATEGORY } name_t;
const char * rc_name_s(const race *rc, name_t n); const char * rc_name_s(const race *rc, name_t n);
const char * rc_name(const race *rc, name_t n, char *name, size_t size); const char * rc_name(const race *rc, name_t n, char *name, size_t size);

View file

@ -1,10 +1,13 @@
#include <platform.h> #include <platform.h>
#include <kernel/config.h> #include <kernel/config.h>
#include "race.h" #include "race.h"
#include <CuTest.h> #include "item.h"
#include <tests.h> #include <tests.h>
#include <CuTest.h>
#include <stdlib.h> #include <stdlib.h>
#include <limits.h>
#include <assert.h> #include <assert.h>
static void test_rc_name(CuTest *tc) { static void test_rc_name(CuTest *tc) {
@ -100,6 +103,54 @@ static void test_rc_set_param(CuTest *tc) {
test_cleanup(); test_cleanup();
} }
static void test_rc_can_use(CuTest *tc) {
race *rc;
item_type *itype;
test_setup();
rc = test_create_race("goblin");
itype = test_create_itemtype("plate");
CuAssertTrue(tc, rc_can_use(rc, itype));
/* default case. all items and races in E2 */
itype->mask_deny = 0;
rc->mask_item = 0;
CuAssertTrue(tc, rc_can_use(rc, itype));
/* some race is forbidden from using this item. */
itype->mask_deny = 1;
/* we are not that race. */
rc->mask_item = 2;
CuAssertTrue(tc, rc_can_use(rc, itype));
/* we are that race */
rc->mask_item = 1;
CuAssertTrue(tc, ! rc_can_use(rc, itype));
/* we are not a special race at all */
rc->mask_item = 0;
CuAssertTrue(tc, rc_can_use(rc, itype));
/* only one race is allowed to use this item */
itype->mask_deny = 0;
itype->mask_allow = 1;
/* we are not that race */
rc->mask_item = 2;
CuAssertTrue(tc, ! rc_can_use(rc, itype));
/* we are that race */
rc->mask_item = 1;
CuAssertTrue(tc, rc_can_use(rc, itype));
/* we are not special */
rc->mask_item = 0;
CuAssertTrue(tc, rc_can_use(rc, itype));
test_cleanup();
}
CuSuite *get_race_suite(void) CuSuite *get_race_suite(void)
{ {
CuSuite *suite = CuSuiteNew(); CuSuite *suite = CuSuiteNew();
@ -109,6 +160,7 @@ CuSuite *get_race_suite(void)
SUITE_ADD_TEST(suite, test_rc_defaults); SUITE_ADD_TEST(suite, test_rc_defaults);
SUITE_ADD_TEST(suite, test_rc_find); SUITE_ADD_TEST(suite, test_rc_find);
SUITE_ADD_TEST(suite, test_rc_set_param); SUITE_ADD_TEST(suite, test_rc_set_param);
SUITE_ADD_TEST(suite, test_rc_can_use);
return suite; return suite;
} }