Merge branch 'develop' of github.com:ennorehling/eressea into develop

This commit is contained in:
Enno Rehling 2018-11-07 08:36:47 +01:00
commit 4da6512f88
48 changed files with 971 additions and 377 deletions

2
clibs

@ -1 +1 @@
Subproject commit ed5c4fee3afbc3d8be79d64857f30702aed522f8
Subproject commit d80ba4b609c2aebf5bf38da60367dc0f0e2d50b9

View file

@ -55,7 +55,8 @@ cd $TESTROOT
cat >| eressea.ini <<HEREDOC
[lua]
dbname = preview.db
dbname = eressea.db
dbswap = :memory:
install = $SOURCE
paths = $SOURCE/lunit:$SOURCE/git/scripts
rules = e$game
@ -70,7 +71,6 @@ cd $TESTROOT
[ -d data ] || mkdir data
assert_dir data
assert_files $LIVE/orders.$turn $LIVE/data/$turn.dat
cp $LIVE/eressea.db preview.db
ln -f $LIVE/orders.$turn
ln -f $LIVE/data/$turn.dat data/
rm -rf reports

View file

@ -74,7 +74,7 @@ function use_xmastree(u, amount)
if u.region.herb~=nil then
-- TODO: else?
local trees = u.region:get_resource("tree")
u.region:set_key("xm06", true)
u.region:set_key("xm06", get_turn())
u.region:set_resource("tree", 10+trees)
local msg = usepotion_message(u, "xmastree")
msg:send_region(u.region)
@ -107,7 +107,7 @@ function self.update()
-- we celebrate knut and kick out the trees.
for r in regions() do
if r:get_key("xm06") then
r:set_key("xm06", false)
r:set_key("xm06", 0)
end
end
end

View file

@ -1058,6 +1058,21 @@ function test_give_silver()
assert_equal(10, u:get_item("money"))
end
function test_build_castle_one_stage()
local r = region.create(0, 0, 'plain')
local f = faction.create('human')
local u = unit.create(f, r, 2)
u:add_item('stone', 4)
u:set_skill('building', 1)
u:add_order('MACHE BURG')
process_orders()
assert_equal(2, u.building.size)
assert_equal(2, u:get_item('stone'))
end
function test_build_castle()
local r = region.create(0, 0, "plain")
local f = create_faction('human')
@ -1135,3 +1150,35 @@ function test_immunity_stops_guard()
assert_equal(f.age, 2)
assert_true(u.guard)
end
function test_region_keys()
local r = region.create(0, 0, 'plain')
assert_nil(r:get_key('test'))
assert_nil(r:get_key('more'))
r:set_key('test', 42)
r:set_key('more') -- default is 1
assert_equal(42, r:get_key('test'))
assert_equal(1, r:get_key('more'))
end
function test_faction_keys()
local f = faction.create('human')
assert_nil(f:get_key('test'))
assert_nil(f:get_key('more'))
f:set_key('test', 42)
f:set_key('more') -- default is 1
assert_equal(42, f:get_key('test'))
assert_equal(1, f:get_key('more'))
end
function test_cartmaking()
local f = faction.create('human')
local r = region.create(0, 0, 'plain')
local u = unit.create(f, r)
u:set_skill('cartmaking', 1)
u:add_item('log', 10)
u:add_order('MACHE Wagen')
process_orders()
assert_equal(1, u:get_item('cart'))
assert_equal(5, u:get_item('log'))
end

View file

@ -29,6 +29,21 @@ function test_castle_names()
assert_equal("citadel", b:get_typename(6250))
end
function test_build_castle_one_stage()
local r = region.create(0, 0, 'plain')
local f = faction.create('human')
local u = unit.create(f, r, 2)
u:add_item('stone', 4)
u:set_skill('building', 1)
u:add_order('MACHE BURG')
process_orders()
assert_equal(2, u.building.size)
assert_equal(2, u:get_item('stone'))
end
function test_build_castle_stages()
local r = region.create(0,0, "plain")
local f = faction.create("human")

View file

@ -6,6 +6,33 @@ function setup()
eressea.free_game()
end
function test_undead_reserve_self()
local r1 = region.create(0, 0, "plain")
local f1 = faction.create("human")
local u1 = unit.create(f1, r1, 1)
u1.race = "undead"
u1:clear_orders()
u1:add_item("log", 2)
u1:add_order("RESERVIERE 1 Holz")
u1:add_order("GIB 0 ALLES Holz")
process_orders()
assert_equal(1, u1:get_item("log"))
end
function test_undead_reserve_other()
local r1 = region.create(0, 0, "plain")
local f1 = faction.create("human")
local u1 = unit.create(f1, r1, 1)
local u2 = unit.create(f1, r1, 1)
u2:add_item("log", 2)
u1.race = "undead"
u1:clear_orders()
u1:add_order("RESERVIERE 1 Holz")
process_orders()
assert_equal(0, u1:get_item("log"))
assert_equal(2, u2:get_item("log"))
end
function test_undead_give_item()
local r1 = region.create(0, 0, "plain")
local f1 = faction.create("human", "hodor@eressea.de", "de")

View file

@ -75,9 +75,11 @@ end
function test_xmastree()
local r
r = use_tree("ocean")
assert_nil(r:get_key("xm06"))
assert_equal(0, r:get_resource("tree"))
eressea.free_game()
r = use_tree("plain")
assert_equal(get_turn(), r:get_key("xm06"))
assert_equal(10, r:get_resource("tree"))
end

View file

@ -97,6 +97,7 @@ set (ERESSEA_SRC
automate.c
battle.c
chaos.c
contact.c
creport.c
direction.c
donations.c
@ -214,6 +215,7 @@ set(TESTS_SRC
alchemy.test.c
automate.test.c
battle.test.c
contact.test.c
creport.test.c
direction.test.c
donations.test.c

View file

@ -28,29 +28,38 @@ static int cmp_scholars(const void *lhs, const void *rhs)
return (int)a->sk - (int)b->sk;
}
int autostudy_init(scholar scholars[], int max_scholars, region *r)
int autostudy_init(scholar scholars[], int max_scholars, unit **units)
{
unit *u;
unit *unext = NULL, *u = *units;
faction *f = u->faction;
int nscholars = 0;
for (u = r->units; u; u = u->next) {
while (u) {
keyword_t kwd = init_order(u->thisorder, u->faction->locale);
if (kwd == K_AUTOSTUDY) {
if (long_order_allowed(u)) {
scholar * st = scholars + nscholars;
skill_t sk = getskill(u->faction->locale);
if (check_student(u, u->thisorder, sk)) {
st->sk = sk;
st->level = effskill_study(u, st->sk);
st->learn = 0;
st->u = u;
if (++nscholars == max_scholars) {
log_fatal("you must increase MAXSCHOLARS");
if (f == u->faction) {
scholar * st = scholars + nscholars;
skill_t sk = getskill(u->faction->locale);
if (check_student(u, u->thisorder, sk)) {
st->sk = sk;
st->level = effskill_study(u, st->sk);
st->learn = 0;
st->u = u;
if (++nscholars == max_scholars) {
log_fatal("you must increase MAXSCHOLARS");
}
}
}
else if (!unext) {
unext = u;
}
}
}
u = u->next;
}
*units = unext;
scholars[nscholars].u = NULL;
if (nscholars > 0) {
qsort(scholars, nscholars, sizeof(scholar), cmp_scholars);
}
@ -85,11 +94,15 @@ void autostudy_run(scholar scholars[], int nscholars)
}
/* now si splits the teachers and students 1:10 */
/* first student must be 2 levels below first teacher: */
for (; si != se && scholars[ti].level - TEACHDIFFERENCE > scholars[si].level && scholars[si].sk == sk; ++si) {
for (; si != se && scholars[si].sk == sk; ++si) {
if (scholars[si].level + TEACHDIFFERENCE <= scholars[ti].level) {
break;
}
tt += scholars[si].u->number;
}
if (si == se) {
/* there are no students, so standard learning only */
/* now si is the first unit we can teach, if we can teach any */
if (si == se || scholars[si].sk != sk) {
/* there are no students, so standard learning for everyone */
for (t = ti; t != se; ++t) {
learning(scholars + t, scholars[t].u->number);
}
@ -100,7 +113,7 @@ void autostudy_run(scholar scholars[], int nscholars)
/* invariant: unit si has n students that can still be taught */
int n = scholars[si].u->number;
for (t = ti, s = si; t != si && s != se; ) {
if (i > n) {
if (i >= n) {
/* t has more than enough teaching capacity for s */
i -= n;
teaching(scholars + s, n);
@ -140,20 +153,37 @@ void autostudy_run(scholar scholars[], int nscholars)
i = scholars[t].u->number * STUDENTS_PER_TEACHER;
}
}
if (i > 0) {
int remain = (STUDENTS_PER_TEACHER * scholars[t].u->number - i + STUDENTS_PER_TEACHER - 1) / STUDENTS_PER_TEACHER;
/* teacher has remaining time */
learning(scholars + t, remain);
}
++t;
for (; t < si; ++t) {
learning(scholars + t, scholars[t].u->number);
}
}
ti = se;
}
}
#define MAXSCHOLARS 128
#define MAXSCHOLARS 512
void do_autostudy(region *r)
{
static int max_scholars;
unit *units = r->units;
scholar scholars[MAXSCHOLARS];
int i, nscholars = autostudy_init(scholars, MAXSCHOLARS, r);
autostudy_run(scholars, nscholars);
for (i = 0; i != nscholars; ++i) {
int days = STUDYDAYS * scholars[i].learn;
learn_skill(scholars[i].u, scholars[i].sk, days);
while (units) {
int i, nscholars = autostudy_init(scholars, MAXSCHOLARS, &units);
if (nscholars > max_scholars) {
stats_count("automate.max_scholars", nscholars - max_scholars);
max_scholars = nscholars;
}
autostudy_run(scholars, nscholars);
for (i = 0; i != nscholars; ++i) {
int days = STUDYDAYS * scholars[i].learn;
learn_skill(scholars[i].u, scholars[i].sk, days);
}
}
}

View file

@ -37,7 +37,7 @@ typedef struct scholar {
void do_autostudy(struct region *r);
int autostudy_init(scholar scholars[], int max_scholars, struct region *r);
int autostudy_init(scholar scholars[], int max_scholars, struct unit **units);
void autostudy_run(scholar scholars[], int nscholars);
#endif

View file

@ -17,7 +17,7 @@
static void test_autostudy_init(CuTest *tc) {
scholar scholars[4];
unit *u1, *u2, *u3, *u4;
unit *u1, *u2, *u3, *u4, *u5, *ulist;
faction *f;
region *r;
@ -35,10 +35,13 @@ static void test_autostudy_init(CuTest *tc) {
set_level(u2, SK_ENTERTAINMENT, 2);
u3 = test_create_unit(f, r);
u3->thisorder = create_order(K_AUTOSTUDY, f->locale, skillnames[SK_PERCEPTION]);
u4 = test_create_unit(test_create_faction(NULL), r);
u4 = test_create_unit(f, r);
u4->thisorder = create_order(K_AUTOSTUDY, f->locale, "Dudelidu");
u5 = test_create_unit(test_create_faction(NULL), r);
u5->thisorder = create_order(K_AUTOSTUDY, f->locale, skillnames[SK_PERCEPTION]);
scholars[3].u = NULL;
CuAssertIntEquals(tc, 3, autostudy_init(scholars, 4, r));
ulist = r->units;
CuAssertIntEquals(tc, 3, autostudy_init(scholars, 4, &ulist));
CuAssertPtrNotNull(tc, test_find_messagetype(u4->faction->msgs, "error77"));
CuAssertPtrEquals(tc, u2, scholars[0].u);
CuAssertIntEquals(tc, 2, scholars[0].level);
@ -53,12 +56,20 @@ static void test_autostudy_init(CuTest *tc) {
CuAssertIntEquals(tc, 0, scholars[2].learn);
CuAssertIntEquals(tc, SK_PERCEPTION, scholars[2].sk);
CuAssertPtrEquals(tc, NULL, scholars[3].u);
CuAssertPtrEquals(tc, u5, ulist);
CuAssertIntEquals(tc, 1, autostudy_init(scholars, 4, &ulist));
CuAssertPtrEquals(tc, u5, scholars[0].u);
CuAssertIntEquals(tc, 0, scholars[0].level);
CuAssertIntEquals(tc, 0, scholars[0].learn);
CuAssertIntEquals(tc, SK_PERCEPTION, scholars[0].sk);
CuAssertPtrEquals(tc, NULL, scholars[1].u);
CuAssertPtrEquals(tc, NULL, ulist);
test_teardown();
}
static void test_autostudy_run(CuTest *tc) {
scholar scholars[4];
unit *u1, *u2, *u3;
unit *u1, *u2, *u3, *ulist;
faction *f;
region *r;
@ -76,9 +87,11 @@ static void test_autostudy_run(CuTest *tc) {
u3->thisorder = create_order(K_AUTOSTUDY, f->locale, skillnames[SK_PERCEPTION]);
set_number(u3, 15);
scholars[3].u = NULL;
CuAssertIntEquals(tc, 3, autostudy_init(scholars, 4, r));
ulist = r->units;
CuAssertIntEquals(tc, 3, autostudy_init(scholars, 4, &ulist));
CuAssertPtrEquals(tc, NULL, ulist);
autostudy_run(scholars, 3);
CuAssertIntEquals(tc, 0, scholars[0].learn);
CuAssertIntEquals(tc, 1, scholars[0].learn);
CuAssertIntEquals(tc, 20, scholars[1].learn);
CuAssertIntEquals(tc, 15, scholars[2].learn);
test_teardown();
@ -86,7 +99,7 @@ static void test_autostudy_run(CuTest *tc) {
static void test_autostudy_run_noteachers(CuTest *tc) {
scholar scholars[4];
unit *u1, *u2, *u3;
unit *u1, *u2, *u3, *ulist;
faction *f;
region *r;
@ -104,7 +117,9 @@ static void test_autostudy_run_noteachers(CuTest *tc) {
u3->thisorder = create_order(K_AUTOSTUDY, f->locale, skillnames[SK_PERCEPTION]);
set_number(u3, 15);
scholars[3].u = NULL;
CuAssertIntEquals(tc, 3, autostudy_init(scholars, 4, r));
ulist = r->units;
CuAssertIntEquals(tc, 3, autostudy_init(scholars, 4, &ulist));
CuAssertPtrEquals(tc, NULL, ulist);
autostudy_run(scholars, 3);
CuAssertIntEquals(tc, 2, scholars[0].learn);
CuAssertIntEquals(tc, 10, scholars[1].learn);
@ -112,11 +127,46 @@ static void test_autostudy_run_noteachers(CuTest *tc) {
test_teardown();
}
/**
* Reproduce Bug 2514
*/
static void test_autostudy_run_skilldiff(CuTest *tc) {
scholar scholars[4];
unit *u1, *u2, *u3, *ulist;
faction *f;
region *r;
test_setup();
r = test_create_plain(0, 0);
f = test_create_faction(NULL);
u1 = test_create_unit(f, r);
u1->thisorder = create_order(K_AUTOSTUDY, f->locale, skillnames[SK_PERCEPTION]);
set_number(u1, 1);
set_level(u1, SK_PERCEPTION, 2);
u2 = test_create_unit(f, r);
u2->thisorder = create_order(K_AUTOSTUDY, f->locale, skillnames[SK_PERCEPTION]);
set_number(u2, 10);
set_level(u2, SK_PERCEPTION, 1);
u3 = test_create_unit(f, r);
u3->thisorder = create_order(K_AUTOSTUDY, f->locale, skillnames[SK_PERCEPTION]);
set_number(u3, 10);
scholars[3].u = NULL;
ulist = r->units;
CuAssertIntEquals(tc, 3, autostudy_init(scholars, 4, &ulist));
CuAssertPtrEquals(tc, NULL, ulist);
autostudy_run(scholars, 3);
CuAssertIntEquals(tc, 0, scholars[0].learn);
CuAssertIntEquals(tc, 20, scholars[2].learn);
CuAssertIntEquals(tc, 10, scholars[1].learn);
test_teardown();
}
CuSuite *get_automate_suite(void)
{
CuSuite *suite = CuSuiteNew();
SUITE_ADD_TEST(suite, test_autostudy_init);
SUITE_ADD_TEST(suite, test_autostudy_run);
SUITE_ADD_TEST(suite, test_autostudy_run_noteachers);
SUITE_ADD_TEST(suite, test_autostudy_run_skilldiff);
return suite;
}

View file

@ -340,7 +340,7 @@ bool helping(const side * as, const side * ds)
{
if (as->faction == ds->faction)
return true;
return (bool)(!enemy(as, ds) && alliedside(as, ds->faction, HELP_FIGHT));
return (!enemy(as, ds) && alliedside(as, ds->faction, HELP_FIGHT));
}
int statusrow(int status)
@ -2640,7 +2640,7 @@ static void aftermath(battle * b)
side *s;
int dead_players = 0;
bfaction *bf;
bool ships_damaged = (bool)(b->turn + (b->has_tactics_turn ? 1 : 0) > 2); /* only used for ship damage! */
bool ships_damaged = (b->turn + (b->has_tactics_turn ? 1 : 0) > 2); /* only used for ship damage! */
for (s = b->sides; s != b->sides + b->nsides; ++s) {
fighter *df;

View file

@ -59,7 +59,7 @@ int tolua_factionlist_next(lua_State * L)
static int tolua_faction_get_units(lua_State * L)
{
faction *self = (faction *)tolua_tousertype(L, 1, 0);
faction *self = (faction *)tolua_tousertype(L, 1, NULL);
unit **unit_ptr = (unit **)lua_newuserdata(L, sizeof(unit *));
luaL_getmetatable(L, TOLUA_CAST "unit");
@ -73,8 +73,8 @@ static int tolua_faction_get_units(lua_State * L)
int tolua_faction_add_item(lua_State * L)
{
faction *self = (faction *)tolua_tousertype(L, 1, 0);
const char *iname = tolua_tostring(L, 2, 0);
faction *self = (faction *)tolua_tousertype(L, 1, NULL);
const char *iname = tolua_tostring(L, 2, NULL);
int number = (int)tolua_tonumber(L, 3, 0);
int result = -1;
@ -91,35 +91,35 @@ int tolua_faction_add_item(lua_State * L)
static int tolua_faction_get_maxheroes(lua_State * L)
{
faction *self = (faction *)tolua_tousertype(L, 1, 0);
faction *self = (faction *)tolua_tousertype(L, 1, NULL);
lua_pushinteger(L, maxheroes(self));
return 1;
}
static int tolua_faction_get_heroes(lua_State * L)
{
faction *self = (faction *)tolua_tousertype(L, 1, 0);
faction *self = (faction *)tolua_tousertype(L, 1, NULL);
lua_pushinteger(L, countheroes(self));
return 1;
}
static int tolua_faction_get_score(lua_State * L)
{
faction *self = (faction *)tolua_tousertype(L, 1, 0);
faction *self = (faction *)tolua_tousertype(L, 1, NULL);
lua_pushnumber(L, (lua_Number)self->score);
return 1;
}
static int tolua_faction_get_id(lua_State * L)
{
faction *self = (faction *)tolua_tousertype(L, 1, 0);
faction *self = (faction *)tolua_tousertype(L, 1, NULL);
lua_pushinteger(L, self->no);
return 1;
}
static int tolua_faction_set_id(lua_State * L)
{
faction *self = (faction *)tolua_tousertype(L, 1, 0);
faction *self = (faction *)tolua_tousertype(L, 1, NULL);
int id = (int)tolua_tonumber(L, 2, 0);
if (findfaction(id) == NULL) {
renumber_faction(self, id);
@ -133,15 +133,15 @@ static int tolua_faction_set_id(lua_State * L)
static int tolua_faction_get_magic(lua_State * L)
{
faction *self = (faction *)tolua_tousertype(L, 1, 0);
faction *self = (faction *)tolua_tousertype(L, 1, NULL);
lua_pushstring(L, magic_school[self->magiegebiet]);
return 1;
}
static int tolua_faction_set_magic(lua_State * L)
{
faction *self = (faction *)tolua_tousertype(L, 1, 0);
const char *type = tolua_tostring(L, 2, 0);
faction *self = (faction *)tolua_tousertype(L, 1, NULL);
const char *type = tolua_tostring(L, 2, NULL);
int mtype;
for (mtype = 0; mtype != MAXMAGIETYP; ++mtype) {
@ -155,14 +155,14 @@ static int tolua_faction_set_magic(lua_State * L)
static int tolua_faction_get_age(lua_State * L)
{
faction *self = (faction *)tolua_tousertype(L, 1, 0);
faction *self = (faction *)tolua_tousertype(L, 1, NULL);
lua_pushinteger(L, self->age);
return 1;
}
static int tolua_faction_set_age(lua_State * L)
{
faction *self = (faction *)tolua_tousertype(L, 1, 0);
faction *self = (faction *)tolua_tousertype(L, 1, NULL);
int age = (int)tolua_tonumber(L, 2, 0);
self->age = age;
return 0;
@ -170,14 +170,14 @@ static int tolua_faction_set_age(lua_State * L)
static int tolua_faction_get_flags(lua_State * L)
{
faction *self = (faction *)tolua_tousertype(L, 1, 0);
faction *self = (faction *)tolua_tousertype(L, 1, NULL);
lua_pushinteger(L, self->flags);
return 1;
}
static int tolua_faction_set_flags(lua_State * L)
{
faction *self = (faction *)tolua_tousertype(L, 1, 0);
faction *self = (faction *)tolua_tousertype(L, 1, NULL);
int flags = (int)tolua_tonumber(L, 2, self->flags);
self->flags = flags;
return 1;
@ -185,14 +185,14 @@ static int tolua_faction_set_flags(lua_State * L)
static int tolua_faction_get_options(lua_State * L)
{
faction *self = (faction *)tolua_tousertype(L, 1, 0);
faction *self = (faction *)tolua_tousertype(L, 1, NULL);
lua_pushinteger(L, self->options);
return 1;
}
static int tolua_faction_set_options(lua_State * L)
{
faction *self = (faction *)tolua_tousertype(L, 1, 0);
faction *self = (faction *)tolua_tousertype(L, 1, NULL);
int options = (int)tolua_tonumber(L, 2, self->options);
self->options = options;
return 1;
@ -200,14 +200,14 @@ static int tolua_faction_set_options(lua_State * L)
static int tolua_faction_get_lastturn(lua_State * L)
{
faction *self = (faction *)tolua_tousertype(L, 1, 0);
faction *self = (faction *)tolua_tousertype(L, 1, NULL);
lua_pushinteger(L, self->lastorders);
return 1;
}
static int tolua_faction_set_lastturn(lua_State * L)
{
faction *self = (faction *)tolua_tousertype(L, 1, 0);
faction *self = (faction *)tolua_tousertype(L, 1, NULL);
if (self) {
self->lastorders = (int)tolua_tonumber(L, 2, self->lastorders);
}
@ -216,7 +216,7 @@ static int tolua_faction_set_lastturn(lua_State * L)
static int tolua_faction_renumber(lua_State * L)
{
faction *self = (faction *)tolua_tousertype(L, 1, 0);
faction *self = (faction *)tolua_tousertype(L, 1, NULL);
int no = (int)tolua_tonumber(L, 2, 0);
renumber_faction(self, no);
@ -225,8 +225,8 @@ static int tolua_faction_renumber(lua_State * L)
static int tolua_faction_addnotice(lua_State * L)
{
faction *self = (faction *)tolua_tousertype(L, 1, 0);
const char *str = tolua_tostring(L, 2, 0);
faction *self = (faction *)tolua_tousertype(L, 1, NULL);
const char *str = tolua_tostring(L, 2, NULL);
addmessage(NULL, self, str, MSG_MESSAGE, ML_IMPORTANT);
return 0;
@ -234,19 +234,22 @@ static int tolua_faction_addnotice(lua_State * L)
static int tolua_faction_getkey(lua_State * L)
{
faction *self = (faction *)tolua_tousertype(L, 1, 0);
const char *name = tolua_tostring(L, 2, 0);
faction *self = (faction *)tolua_tousertype(L, 1, NULL);
const char *name = tolua_tostring(L, 2, NULL);
int flag = atoi36(name);
lua_pushinteger(L, key_get(self->attribs, flag));
return 1;
int value = key_get(self->attribs, flag);
if (value != 0) {
lua_pushinteger(L, value);
return 1;
}
return 0;
}
static int tolua_faction_setkey(lua_State * L)
{
faction *self = (faction *)tolua_tousertype(L, 1, 0);
const char *name = tolua_tostring(L, 2, 0);
int value = (int)tolua_tonumber(L, 3, 0);
faction *self = (faction *)tolua_tousertype(L, 1, NULL);
const char *name = tolua_tostring(L, 2, NULL);
int value = (int)tolua_tonumber(L, 3, 1);
int flag = atoi36(name);
if (value) {
@ -260,7 +263,7 @@ static int tolua_faction_setkey(lua_State * L)
static int tolua_faction_get_messages(lua_State * L)
{
faction *self = (faction *)tolua_tousertype(L, 1, 0);
faction *self = (faction *)tolua_tousertype(L, 1, NULL);
int i = 1;
mlist *ml;
if (!self->msgs) {
@ -276,8 +279,8 @@ static int tolua_faction_get_messages(lua_State * L)
}
static int tolua_faction_count_msg_type(lua_State *L) {
faction *self = (faction *)tolua_tousertype(L, 1, 0);
const char *str = tolua_tostring(L, 2, 0);
faction *self = (faction *)tolua_tousertype(L, 1, NULL);
const char *str = tolua_tostring(L, 2, NULL);
int n = 0;
if (self->msgs) {
mlist * ml = self->msgs->begin;
@ -294,8 +297,8 @@ static int tolua_faction_count_msg_type(lua_State *L) {
static int tolua_faction_normalize(lua_State * L)
{
faction *f = (faction *)tolua_tousertype(L, 1, 0);
region *r = (region *)tolua_tousertype(L, 2, 0);
faction *f = (faction *)tolua_tousertype(L, 1, NULL);
region *r = (region *)tolua_tousertype(L, 2, NULL);
if (r) {
plane *pl = rplane(r);
int nx = r->x, ny = r->y;
@ -310,8 +313,8 @@ static int tolua_faction_normalize(lua_State * L)
static int tolua_faction_set_origin(lua_State * L)
{
faction *f = (faction *)tolua_tousertype(L, 1, 0);
region *r = (region *)tolua_tousertype(L, 2, 0);
faction *f = (faction *)tolua_tousertype(L, 1, NULL);
region *r = (region *)tolua_tousertype(L, 2, NULL);
plane *pl = rplane(r);
int id = pl ? pl->id : 0;
@ -321,7 +324,7 @@ static int tolua_faction_set_origin(lua_State * L)
static int tolua_faction_get_origin(lua_State * L)
{
faction *self = (faction *)tolua_tousertype(L, 1, 0);
faction *self = (faction *)tolua_tousertype(L, 1, NULL);
int x = 0, y = 0;
faction_getorigin(self, 0, &x, &y);
@ -332,7 +335,7 @@ static int tolua_faction_get_origin(lua_State * L)
static int tolua_faction_destroy(lua_State * L)
{
faction **fp, *f = (faction *)tolua_tousertype(L, 1, 0);
faction **fp, *f = (faction *)tolua_tousertype(L, 1, NULL);
/* TODO: this loop is slow af, but what can we do? */
for (fp = &factions; *fp; fp = &(*fp)->next) {
if (*fp == f) {
@ -353,9 +356,9 @@ static int tolua_faction_get(lua_State * L)
static int tolua_faction_create(lua_State * L)
{
const char *racename = tolua_tostring(L, 1, 0);
const char *email = tolua_tostring(L, 2, 0);
const char *lang = tolua_tostring(L, 3, 0);
const char *racename = tolua_tostring(L, 1, NULL);
const char *email = tolua_tostring(L, 2, NULL);
const char *lang = tolua_tostring(L, 3, NULL);
struct locale *loc = lang ? get_locale(lang) : default_locale;
faction *f = NULL;
const struct race *frace = rc_find(racename ? racename : "human");
@ -371,44 +374,44 @@ static int tolua_faction_create(lua_State * L)
static int tolua_faction_get_password(lua_State * L)
{
faction *self = (faction *)tolua_tousertype(L, 1, 0);
faction *self = (faction *)tolua_tousertype(L, 1, NULL);
tolua_pushstring(L, faction_getpassword(self));
return 1;
}
static int tolua_faction_set_password(lua_State * L)
{
faction *self = (faction *)tolua_tousertype(L, 1, 0);
const char * passw = tolua_tostring(L, 2, 0);
faction *self = (faction *)tolua_tousertype(L, 1, NULL);
const char * passw = tolua_tostring(L, 2, NULL);
faction_setpassword(self, password_hash(passw, PASSWORD_DEFAULT));
return 0;
}
static int tolua_faction_get_email(lua_State * L)
{
faction *self = (faction *)tolua_tousertype(L, 1, 0);
faction *self = (faction *)tolua_tousertype(L, 1, NULL);
tolua_pushstring(L, faction_getemail(self));
return 1;
}
static int tolua_faction_set_email(lua_State * L)
{
faction *self = (faction *)tolua_tousertype(L, 1, 0);
faction_setemail(self, tolua_tostring(L, 2, 0));
faction *self = (faction *)tolua_tousertype(L, 1, NULL);
faction_setemail(self, tolua_tostring(L, 2, NULL));
return 0;
}
static int tolua_faction_get_locale(lua_State * L)
{
faction *self = (faction *)tolua_tousertype(L, 1, 0);
faction *self = (faction *)tolua_tousertype(L, 1, NULL);
tolua_pushstring(L, locale_name(self->locale));
return 1;
}
static int tolua_faction_set_locale(lua_State * L)
{
faction *self = (faction *)tolua_tousertype(L, 1, 0);
const char *name = tolua_tostring(L, 2, 0);
faction *self = (faction *)tolua_tousertype(L, 1, NULL);
const char *name = tolua_tostring(L, 2, NULL);
const struct locale *loc = get_locale(name);
if (loc) {
self->locale = loc;
@ -422,15 +425,15 @@ static int tolua_faction_set_locale(lua_State * L)
static int tolua_faction_get_race(lua_State * L)
{
faction *self = (faction *)tolua_tousertype(L, 1, 0);
faction *self = (faction *)tolua_tousertype(L, 1, NULL);
tolua_pushstring(L, self->race->_name);
return 1;
}
static int tolua_faction_set_race(lua_State * L)
{
faction *self = (faction *)tolua_tousertype(L, 1, 0);
const char *name = tolua_tostring(L, 2, 0);
faction *self = (faction *)tolua_tousertype(L, 1, NULL);
const char *name = tolua_tostring(L, 2, NULL);
const race *rc = rc_find(name);
if (rc != NULL) {
self->race = rc;
@ -441,57 +444,57 @@ static int tolua_faction_set_race(lua_State * L)
static int tolua_faction_get_name(lua_State * L)
{
faction *self = (faction *)tolua_tousertype(L, 1, 0);
faction *self = (faction *)tolua_tousertype(L, 1, NULL);
tolua_pushstring(L, faction_getname(self));
return 1;
}
static int tolua_faction_set_name(lua_State * L)
{
faction *self = (faction *)tolua_tousertype(L, 1, 0);
faction_setname(self, tolua_tostring(L, 2, 0));
faction *self = (faction *)tolua_tousertype(L, 1, NULL);
faction_setname(self, tolua_tostring(L, 2, NULL));
return 0;
}
static int tolua_faction_get_uid(lua_State * L)
{
faction *f = (faction *)tolua_tousertype(L, 1, 0);
faction *f = (faction *)tolua_tousertype(L, 1, NULL);
lua_pushinteger(L, f->uid);
return 1;
}
static int tolua_faction_set_uid(lua_State * L)
{
faction *f = (faction *)tolua_tousertype(L, 1, 0);
faction *f = (faction *)tolua_tousertype(L, 1, NULL);
f->uid = (int)tolua_tonumber(L, 2, 0);
return 0;
}
static int tolua_faction_get_info(lua_State * L)
{
faction *self = (faction *)tolua_tousertype(L, 1, 0);
faction *self = (faction *)tolua_tousertype(L, 1, NULL);
tolua_pushstring(L, faction_getbanner(self));
return 1;
}
static int tolua_faction_set_info(lua_State * L)
{
faction *self = (faction *)tolua_tousertype(L, 1, 0);
faction_setbanner(self, tolua_tostring(L, 2, 0));
faction *self = (faction *)tolua_tousertype(L, 1, NULL);
faction_setbanner(self, tolua_tostring(L, 2, NULL));
return 0;
}
static int tolua_faction_get_alliance(lua_State * L)
{
faction *self = (faction *)tolua_tousertype(L, 1, 0);
faction *self = (faction *)tolua_tousertype(L, 1, NULL);
tolua_pushusertype(L, f_get_alliance(self), TOLUA_CAST "alliance");
return 1;
}
static int tolua_faction_set_alliance(lua_State * L)
{
struct faction *self = (struct faction *)tolua_tousertype(L, 1, 0);
struct alliance *alli = (struct alliance *) tolua_tousertype(L, 2, 0);
struct faction *self = (struct faction *)tolua_tousertype(L, 1, NULL);
struct alliance *alli = (struct alliance *) tolua_tousertype(L, 2, NULL);
setalliance(self, alli);
@ -500,7 +503,7 @@ static int tolua_faction_set_alliance(lua_State * L)
static int tolua_faction_get_items(lua_State * L)
{
faction *self = (faction *)tolua_tousertype(L, 1, 0);
faction *self = (faction *)tolua_tousertype(L, 1, NULL);
item **item_ptr = (item **)lua_newuserdata(L, sizeof(item *));
luaL_getmetatable(L, TOLUA_CAST "item");
@ -515,7 +518,7 @@ static int tolua_faction_get_items(lua_State * L)
static int tolua_faction_tostring(lua_State * L)
{
faction *self = (faction *)tolua_tousertype(L, 1, 0);
faction *self = (faction *)tolua_tousertype(L, 1, NULL);
lua_pushstring(L, factionname(self));
return 1;
}

View file

@ -5,6 +5,7 @@
#include "bind_process.h"
#include "battle.h"
#include "contact.h"
#include "economy.h"
#include "laws.h"
#include "magic.h"

View file

@ -36,14 +36,13 @@
#include <lauxlib.h>
#include <tolua.h>
#include <assert.h>
#include <string.h>
#include <stdbool.h>
#include <stdlib.h>
static int tolua_region_count_msg_type(lua_State *L) {
region *self = (region *)tolua_tousertype(L, 1, 0);
const char *str = tolua_tostring(L, 2, 0);
region *self = (region *)tolua_tousertype(L, 1, NULL);
const char *str = tolua_tostring(L, 2, NULL);
int n = 0;
if (self->msgs) {
mlist * ml = self->msgs->begin;
@ -73,21 +72,21 @@ int tolua_regionlist_next(lua_State * L)
static int tolua_region_get_id(lua_State * L)
{
region *self = (region *)tolua_tousertype(L, 1, 0);
region *self = (region *)tolua_tousertype(L, 1, NULL);
lua_pushinteger(L, self->uid);
return 1;
}
static int tolua_region_get_blocked(lua_State * L)
{
region *self = (region *)tolua_tousertype(L, 1, 0);
region *self = (region *)tolua_tousertype(L, 1, NULL);
lua_pushboolean(L, (self->flags&RF_BLOCKED) != 0);
return 1;
}
static int tolua_region_set_blocked(lua_State * L)
{
region *self = (region *)tolua_tousertype(L, 1, 0);
region *self = (region *)tolua_tousertype(L, 1, NULL);
bool flag = !!tolua_toboolean(L, 2, 1);
if (flag) self->flags |= RF_BLOCKED;
else self->flags &= ~RF_BLOCKED;
@ -96,36 +95,36 @@ static int tolua_region_set_blocked(lua_State * L)
static int tolua_region_get_x(lua_State * L)
{
region *self = (region *)tolua_tousertype(L, 1, 0);
region *self = (region *)tolua_tousertype(L, 1, NULL);
lua_pushinteger(L, self->x);
return 1;
}
static int tolua_region_get_y(lua_State * L)
{
region *self = (region *)tolua_tousertype(L, 1, 0);
region *self = (region *)tolua_tousertype(L, 1, NULL);
lua_pushinteger(L, self->y);
return 1;
}
static int tolua_region_get_plane(lua_State * L)
{
region *r = (region *)tolua_tousertype(L, 1, 0);
region *r = (region *)tolua_tousertype(L, 1, NULL);
tolua_pushusertype(L, rplane(r), TOLUA_CAST "plane");
return 1;
}
static int tolua_region_get_terrain(lua_State * L)
{
region *self = (region *)tolua_tousertype(L, 1, 0);
region *self = (region *)tolua_tousertype(L, 1, NULL);
tolua_pushstring(L, self->terrain->_name);
return 1;
}
static int tolua_region_set_terrain(lua_State * L)
{
region *r = (region *)tolua_tousertype(L, 1, 0);
const char *tname = tolua_tostring(L, 2, 0);
region *r = (region *)tolua_tousertype(L, 1, NULL);
const char *tname = tolua_tostring(L, 2, NULL);
if (tname) {
const terrain_type *terrain = get_terrain(tname);
if (terrain) {
@ -137,7 +136,7 @@ static int tolua_region_set_terrain(lua_State * L)
static int tolua_region_get_terrainname(lua_State * L)
{
region *self = (region *)tolua_tousertype(L, 1, 0);
region *self = (region *)tolua_tousertype(L, 1, NULL);
attrib *a = a_find(self->attribs, &at_racename);
if (a) {
tolua_pushstring(L, get_racename(a));
@ -148,8 +147,8 @@ static int tolua_region_get_terrainname(lua_State * L)
static int tolua_region_set_owner(lua_State * L)
{
region *r = (region *)tolua_tousertype(L, 1, 0);
struct faction *f = (struct faction *)tolua_tousertype(L, 2, 0);
region *r = (region *)tolua_tousertype(L, 1, NULL);
struct faction *f = (struct faction *)tolua_tousertype(L, 2, NULL);
if (r) {
region_set_owner(r, f, turn);
}
@ -158,7 +157,7 @@ static int tolua_region_set_owner(lua_State * L)
static int tolua_region_get_owner(lua_State * L)
{
region *r = (region *)tolua_tousertype(L, 1, 0);
region *r = (region *)tolua_tousertype(L, 1, NULL);
if (r) {
struct faction *f = region_get_owner(r);
tolua_pushusertype(L, f, TOLUA_CAST "faction");
@ -169,8 +168,8 @@ static int tolua_region_get_owner(lua_State * L)
static int tolua_region_set_terrainname(lua_State * L)
{
region *self = (region *)tolua_tousertype(L, 1, 0);
const char *name = tolua_tostring(L, 2, 0);
region *self = (region *)tolua_tousertype(L, 1, NULL);
const char *name = tolua_tostring(L, 2, NULL);
if (name == NULL) {
a_removeall(&self->attribs, &at_racename);
}
@ -182,42 +181,42 @@ static int tolua_region_set_terrainname(lua_State * L)
static int tolua_region_get_info(lua_State * L)
{
region *self = (region *)tolua_tousertype(L, 1, 0);
region *self = (region *)tolua_tousertype(L, 1, NULL);
tolua_pushstring(L, region_getinfo(self));
return 1;
}
static int tolua_region_set_info(lua_State * L)
{
region *self = (region *)tolua_tousertype(L, 1, 0);
region_setinfo(self, tolua_tostring(L, 2, 0));
region *self = (region *)tolua_tousertype(L, 1, NULL);
region_setinfo(self, tolua_tostring(L, 2, NULL));
return 0;
}
static int tolua_region_get_name(lua_State * L)
{
region *self = (region *)tolua_tousertype(L, 1, 0);
region *self = (region *)tolua_tousertype(L, 1, NULL);
tolua_pushstring(L, region_getname(self));
return 1;
}
static int tolua_region_set_name(lua_State * L)
{
region *self = (region *)tolua_tousertype(L, 1, 0);
region_setname(self, tolua_tostring(L, 2, 0));
region *self = (region *)tolua_tousertype(L, 1, NULL);
region_setname(self, tolua_tostring(L, 2, NULL));
return 0;
}
static int tolua_region_get_morale(lua_State * L)
{
region *r = (region *)tolua_tousertype(L, 1, 0);
region *r = (region *)tolua_tousertype(L, 1, NULL);
lua_pushinteger(L, region_get_morale(r));
return 1;
}
static int tolua_region_set_morale(lua_State * L)
{
region *r = (region *)tolua_tousertype(L, 1, 0);
region *r = (region *)tolua_tousertype(L, 1, NULL);
region_set_morale(r, (int)tolua_tonumber(L, 2, 0), turn);
return 0;
}
@ -225,14 +224,14 @@ static int tolua_region_set_morale(lua_State * L)
/* region mourning this turn */
static int tolua_region_get_is_mourning(lua_State * L)
{
region *r = (region *)tolua_tousertype(L, 1, 0);
region *r = (region *)tolua_tousertype(L, 1, NULL);
lua_pushboolean(L, is_mourning(r, turn+1));
return 1;
}
static int tolua_region_get_adj(lua_State * L)
{
region *r = (region *)tolua_tousertype(L, 1, 0);
region *r = (region *)tolua_tousertype(L, 1, NULL);
region *rn[MAXDIRECTIONS];
int d, idx;
get_neighbours(r, rn);
@ -249,7 +248,7 @@ static int tolua_region_get_adj(lua_State * L)
static int tolua_region_get_luxury(lua_State * L)
{
region *r = (region *)tolua_tousertype(L, 1, 0);
region *r = (region *)tolua_tousertype(L, 1, NULL);
if (r->land) {
const item_type *lux = r_luxury(r);
if (lux) {
@ -263,8 +262,8 @@ static int tolua_region_get_luxury(lua_State * L)
static int tolua_region_set_luxury(lua_State * L)
{
region *r = (region *)tolua_tousertype(L, 1, 0);
const char *name = tolua_tostring(L, 2, 0);
region *r = (region *)tolua_tousertype(L, 1, NULL);
const char *name = tolua_tostring(L, 2, NULL);
if (r->land && name) {
const item_type *lux = r_luxury(r);
const item_type *itype = it_find(name);
@ -278,9 +277,9 @@ static int tolua_region_set_luxury(lua_State * L)
static int tolua_region_set_herb(lua_State * L)
{
region *r = (region *)tolua_tousertype(L, 1, 0);
region *r = (region *)tolua_tousertype(L, 1, NULL);
if (r->land) {
const char *name = tolua_tostring(L, 2, 0);
const char *name = tolua_tostring(L, 2, NULL);
const item_type *itype = it_find(name);
if (itype && (itype->flags & ITF_HERB)) {
r->land->herbtype = itype;
@ -291,7 +290,7 @@ static int tolua_region_set_herb(lua_State * L)
static int tolua_region_get_herb(lua_State * L)
{
region *r = (region *)tolua_tousertype(L, 1, 0);
region *r = (region *)tolua_tousertype(L, 1, NULL);
if (r->land && r->land->herbtype) {
const char *name = r->land->herbtype->rtype->_name;
tolua_pushstring(L, name);
@ -302,7 +301,7 @@ static int tolua_region_get_herb(lua_State * L)
static int tolua_region_get_next(lua_State * L)
{
region *self = (region *)tolua_tousertype(L, 1, 0);
region *self = (region *)tolua_tousertype(L, 1, NULL);
direction_t dir = (direction_t)tolua_tonumber(L, 2, 0);
if (dir >= 0 && dir < MAXDIRECTIONS) {
@ -314,7 +313,7 @@ static int tolua_region_get_next(lua_State * L)
static int tolua_region_get_flag(lua_State * L)
{
region *self = (region *)tolua_tousertype(L, 1, 0);
region *self = (region *)tolua_tousertype(L, 1, NULL);
int bit = (int)tolua_tonumber(L, 2, 0);
lua_pushboolean(L, (self->flags & (1 << bit)));
@ -323,7 +322,7 @@ static int tolua_region_get_flag(lua_State * L)
static int tolua_region_set_flag(lua_State * L)
{
region *self = (region *)tolua_tousertype(L, 1, 0);
region *self = (region *)tolua_tousertype(L, 1, NULL);
int bit = (int)tolua_tonumber(L, 2, 0);
int set = tolua_toboolean(L, 3, 1);
@ -336,8 +335,8 @@ static int tolua_region_set_flag(lua_State * L)
static int tolua_region_get_resourcelevel(lua_State * L)
{
region *r = (region *)tolua_tousertype(L, 1, 0);
const char *type = tolua_tostring(L, 2, 0);
region *r = (region *)tolua_tousertype(L, 1, NULL);
const char *type = tolua_tostring(L, 2, NULL);
const resource_type *rtype = rt_find(type);
if (rtype != NULL) {
const rawmaterial *rm;
@ -372,9 +371,9 @@ static int tolua_region_get_resource(lua_State * L)
const resource_type *rtype;
int result;
r = (region *)tolua_tousertype(L, 1, 0);
r = (region *)tolua_tousertype(L, 1, NULL);
LUA_ASSERT(r != NULL, "invalid parameter");
type = tolua_tostring(L, 2, 0);
type = tolua_tostring(L, 2, NULL);
LUA_ASSERT(type != NULL, "invalid parameter");
result = special_resource(type);
@ -403,8 +402,8 @@ static int tolua_region_get_resource(lua_State * L)
static int tolua_region_set_resource(lua_State * L)
{
region *r = (region *)tolua_tousertype(L, 1, 0);
const char *type = tolua_tostring(L, 2, 0);
region *r = (region *)tolua_tousertype(L, 1, NULL);
const char *type = tolua_tostring(L, 2, NULL);
int result, value = (int)tolua_tonumber(L, 3, 0);
const resource_type *rtype;
@ -429,7 +428,7 @@ static int tolua_region_set_resource(lua_State * L)
static int tolua_region_destroy(lua_State * L)
{
region *self = (region *)tolua_tousertype(L, 1, 0);
region *self = (region *)tolua_tousertype(L, 1, NULL);
remove_region(&regions, self);
return 0;
}
@ -438,7 +437,7 @@ static int tolua_region_create(lua_State * L)
{
int x = (int)tolua_tonumber(L, 1, 0);
int y = (int)tolua_tonumber(L, 2, 0);
const char *tname = tolua_tostring(L, 3, 0);
const char *tname = tolua_tostring(L, 3, NULL);
if (tname) {
plane *pl = findplane(x, y);
const terrain_type *terrain = get_terrain(tname);
@ -448,7 +447,7 @@ static int tolua_region_create(lua_State * L)
return 0;
}
assert(!pnormalize(&x, &y, pl));
pnormalize(&x, &y, pl);
r = result = findregion(x, y);
if (r != NULL && r->units != NULL) {
@ -471,7 +470,7 @@ static int tolua_region_create(lua_State * L)
static int tolua_region_get_units(lua_State * L)
{
region *self = (region *)tolua_tousertype(L, 1, 0);
region *self = (region *)tolua_tousertype(L, 1, NULL);
unit **unit_ptr = (unit **)lua_newuserdata(L, sizeof(unit *));
luaL_getmetatable(L, "unit");
@ -485,7 +484,7 @@ static int tolua_region_get_units(lua_State * L)
static int tolua_region_get_buildings(lua_State * L)
{
region *self = (region *)tolua_tousertype(L, 1, 0);
region *self = (region *)tolua_tousertype(L, 1, NULL);
building **building_ptr =
(building **)lua_newuserdata(L, sizeof(building *));
@ -500,7 +499,7 @@ static int tolua_region_get_buildings(lua_State * L)
static int tolua_region_get_ships(lua_State * L)
{
region *self = (region *)tolua_tousertype(L, 1, 0);
region *self = (region *)tolua_tousertype(L, 1, NULL);
ship **ship_ptr = (ship **)lua_newuserdata(L, sizeof(ship *));
luaL_getmetatable(L, "ship");
@ -514,7 +513,7 @@ static int tolua_region_get_ships(lua_State * L)
static int tolua_region_get_age(lua_State * L)
{
region *self = (region *)tolua_tousertype(L, 1, 0);
region *self = (region *)tolua_tousertype(L, 1, NULL);
if (self) {
lua_pushinteger(L, self->age);
@ -525,7 +524,7 @@ static int tolua_region_get_age(lua_State * L)
static int tolua_region_get_peasants(lua_State * L)
{
region *self = (region *)tolua_tousertype(L, 1, 0);
region *self = (region *)tolua_tousertype(L, 1, NULL);
if (self) {
lua_pushinteger(L, self->land ? self->land->peasants : 0);
@ -536,7 +535,7 @@ static int tolua_region_get_peasants(lua_State * L)
static int tolua_region_set_peasants(lua_State * L)
{
region *self = (region *)tolua_tousertype(L, 1, 0);
region *self = (region *)tolua_tousertype(L, 1, NULL);
if (self && self->land) {
self->land->peasants = lua_tointeger(L, 2);
@ -546,37 +545,22 @@ static int tolua_region_set_peasants(lua_State * L)
static int tolua_region_getkey(lua_State * L)
{
region *self = (region *)tolua_tousertype(L, 1, 0);
const char *name = tolua_tostring(L, 2, 0);
region *self = (region *)tolua_tousertype(L, 1, NULL);
const char *name = tolua_tostring(L, 2, NULL);
int flag = atoi36(name);
lua_pushboolean(L, key_get(self->attribs, flag));
return 1;
}
static int tolua_region_getastral(lua_State * L)
{
region *r = (region *)tolua_tousertype(L, 1, 0);
region *rt = r_standard_to_astral(r);
if (!rt) {
const char *tname = tolua_tostring(L, 2, 0);
plane *pl = get_astralplane();
rt = new_region(real2tp(r->x), real2tp(r->y), pl, 0);
if (tname) {
const terrain_type *terrain = get_terrain(tname);
terraform_region(rt, terrain);
}
int value = key_get(self->attribs, flag);
if (value != 0) {
lua_pushinteger(L, value);
return 1;
}
tolua_pushusertype(L, rt, TOLUA_CAST "region");
return 1;
return 0;
}
static int tolua_region_setkey(lua_State * L)
{
region *self = (region *)tolua_tousertype(L, 1, 0);
const char *name = tolua_tostring(L, 2, 0);
int value = (int)tolua_tonumber(L, 3, 0);
region *self = (region *)tolua_tousertype(L, 1, NULL);
const char *name = tolua_tostring(L, 2, NULL);
int value = (int)tolua_tonumber(L, 3, 1);
int flag = atoi36(name);
if (value) {
@ -588,9 +572,27 @@ static int tolua_region_setkey(lua_State * L)
return 0;
}
static int tolua_region_getastral(lua_State * L)
{
region *r = (region *)tolua_tousertype(L, 1, NULL);
region *rt = r_standard_to_astral(r);
if (!rt) {
const char *tname = tolua_tostring(L, 2, NULL);
plane *pl = get_astralplane();
rt = new_region(real2tp(r->x), real2tp(r->y), pl, 0);
if (tname) {
const terrain_type *terrain = get_terrain(tname);
terraform_region(rt, terrain);
}
}
tolua_pushusertype(L, rt, TOLUA_CAST "region");
return 1;
}
static int tolua_region_tostring(lua_State * L)
{
region *self = (region *)tolua_tousertype(L, 1, 0);
region *self = (region *)tolua_tousertype(L, 1, NULL);
lua_pushstring(L, regionname(self, NULL));
return 1;
}
@ -606,7 +608,7 @@ static int tolua_plane_get(lua_State * L)
static int tolua_plane_erase(lua_State *L)
{
plane *self = (plane *)tolua_tousertype(L, 1, 0);
plane *self = (plane *)tolua_tousertype(L, 1, NULL);
remove_plane(self);
return 0;
}
@ -618,7 +620,7 @@ static int tolua_plane_create(lua_State * L)
int y = (int)tolua_tonumber(L, 3, 0);
int width = (int)tolua_tonumber(L, 4, 0);
int height = (int)tolua_tonumber(L, 5, 0);
const char *name = tolua_tostring(L, 6, 0);
const char *name = tolua_tostring(L, 6, NULL);
plane *pl;
pl = create_new_plane(id, name, x, x + width - 1, y, y + height - 1, 0);
@ -629,15 +631,15 @@ static int tolua_plane_create(lua_State * L)
static int tolua_plane_get_name(lua_State * L)
{
plane *self = (plane *)tolua_tousertype(L, 1, 0);
plane *self = (plane *)tolua_tousertype(L, 1, NULL);
tolua_pushstring(L, self->name);
return 1;
}
static int tolua_plane_set_name(lua_State * L)
{
plane *self = (plane *)tolua_tousertype(L, 1, 0);
const char *str = tolua_tostring(L, 2, 0);
plane *self = (plane *)tolua_tousertype(L, 1, NULL);
const char *str = tolua_tostring(L, 2, NULL);
free(self->name);
if (str)
self->name = str_strdup(str);
@ -648,14 +650,14 @@ static int tolua_plane_set_name(lua_State * L)
static int tolua_plane_get_id(lua_State * L)
{
plane *self = (plane *)tolua_tousertype(L, 1, 0);
plane *self = (plane *)tolua_tousertype(L, 1, NULL);
lua_pushinteger(L, self->id);
return 1;
}
static int tolua_plane_normalize(lua_State * L)
{
plane *self = (plane *)tolua_tousertype(L, 1, 0);
plane *self = (plane *)tolua_tousertype(L, 1, NULL);
int x = (int)tolua_tonumber(L, 2, 0);
int y = (int)tolua_tonumber(L, 3, 0);
pnormalize(&x, &y, self);
@ -666,14 +668,14 @@ static int tolua_plane_normalize(lua_State * L)
static int tolua_plane_tostring(lua_State * L)
{
plane *self = (plane *)tolua_tousertype(L, 1, 0);
plane *self = (plane *)tolua_tousertype(L, 1, NULL);
lua_pushstring(L, self->name);
return 1;
}
static int tolua_plane_get_size(lua_State * L)
{
plane *pl = (plane *)tolua_tousertype(L, 1, 0);
plane *pl = (plane *)tolua_tousertype(L, 1, NULL);
lua_pushinteger(L, plane_width(pl));
lua_pushinteger(L, plane_height(pl));
return 2;
@ -698,8 +700,8 @@ static int tolua_distance(lua_State * L)
}
static int tolua_region_get_curse(lua_State *L) {
region *self = (region *)tolua_tousertype(L, 1, 0);
const char *name = tolua_tostring(L, 2, 0);
region *self = (region *)tolua_tousertype(L, 1, NULL);
const char *name = tolua_tostring(L, 2, NULL);
if (self->attribs) {
curse * c = get_curse(self->attribs, ct_find(name));
if (c) {
@ -711,8 +713,8 @@ static int tolua_region_get_curse(lua_State *L) {
}
static int tolua_region_has_attrib(lua_State *L) {
region *self = (region *)tolua_tousertype(L, 1, 0);
const char *name = tolua_tostring(L, 2, 0);
region *self = (region *)tolua_tousertype(L, 1, NULL);
const char *name = tolua_tostring(L, 2, NULL);
attrib * a = a_find(self->attribs, at_find(name));
lua_pushboolean(L, a != NULL);
return 1;

View file

@ -481,7 +481,7 @@ static int tolua_get_region(lua_State * L)
int x = (int)tolua_tonumber(L, 1, 0);
int y = (int)tolua_tonumber(L, 2, 0);
region *r;
assert(!pnormalize(&x, &y, findplane(x, y)));
pnormalize(&x, &y, findplane(x, y));
r = findregion(x, y);
tolua_pushusertype(L, r, TOLUA_CAST "region");
return 1;

136
src/contact.c Normal file
View file

@ -0,0 +1,136 @@
#ifdef _MSC_VER
#include <platform.h>
#endif
#include "contact.h"
#include "kernel/attrib.h"
#include "kernel/faction.h"
#include "kernel/messages.h"
#include "kernel/order.h"
#include "kernel/unit.h"
#include "util/base36.h"
#include "util/param.h"
#include "util/parser.h"
#include <assert.h>
static attrib_type at_contact_unit = {
"contact_unit",
DEFAULT_INIT,
DEFAULT_FINALIZE,
DEFAULT_AGE,
NO_WRITE,
NO_READ
};
void contact_unit(unit * u, const unit * u2)
{
attrib *a = a_find(u->attribs, &at_contact_unit);
while (a && a->type == &at_contact_unit) {
if (a->data.v == u2) {
return;
}
a = a->next;
}
a_add(&u->attribs, a_new(&at_contact_unit))->data.v = (void *)u2;
}
static attrib_type at_contact_faction = {
"contact_faction",
DEFAULT_INIT,
DEFAULT_FINALIZE,
DEFAULT_AGE,
NO_WRITE,
NO_READ
};
void contact_faction(unit * u, const faction * f)
{
attrib *a = a_find(u->attribs, &at_contact_faction);
while (a && a->type == &at_contact_faction) {
if (a->data.v == f) {
return;
}
a = a->next;
}
a_add(&u->attribs, a_new(&at_contact_faction))->data.v = (void *)f;
}
bool ucontact(const unit * u, const unit * u2)
/* Prueft, ob u den Kontaktiere-Befehl zu u2 gesetzt hat. */
{
attrib *a;
if (u->faction == u2->faction) {
return true;
}
/* Explizites KONTAKTIERE */
for (a = u->attribs; a; a = a->next) {
if (a->type == &at_contact_unit) {
if (u2 == a->data.v) {
return true;
}
}
else if (a->type == &at_contact_faction) {
if (u2->faction == a->data.v) {
return true;
}
}
}
return false;
}
int contact_cmd(unit * u, order * ord)
{
char token[16];
const char *str;
param_t p;
init_order(ord, u->faction->locale);
str = gettoken(token, sizeof(token));
p = findparam(str, u->faction->locale);
if (p == P_FACTION) {
/* new-style syntax, KONTAKTIERE PARTEI foo */
faction * f = getfaction();
if (!f) {
cmistake(u, ord, 66, MSG_EVENT);
}
else {
contact_faction(u, f);
return 0;
}
}
else if (p == P_UNIT) {
/* new-style syntax, KONTAKTIERE EINHEIT [TEMP] foo */
unit *u2 = NULL;
if (GET_UNIT == getunit(u->region, u->faction, &u2)) {
assert(u2);
contact_unit(u, u2);
return 0;
}
ADDMSG(&u->faction->msgs, msg_feedback(u, ord,
"feedback_unit_not_found", NULL));
}
else {
/* old-style syntax, KONTAKTIERE foo */
unit *u2;
int n = 0;
if (p == P_TEMP) {
n = getid();
u2 = findnewunit(u->region, u->faction, n);
}
else {
n = atoi36((const char *)str);
u2 = findunit(n);
}
if (u2 != NULL) {
contact_unit(u, u2);
return 0;
}
ADDMSG(&u->faction->msgs, msg_feedback(u, ord,
"feedback_unit_not_found", NULL));
}
return -1;
}

12
src/contact.h Normal file
View file

@ -0,0 +1,12 @@
#pragma once
#include <stdbool.h>
struct faction;
struct order;
struct unit;
bool ucontact(const struct unit *u, const struct unit *u2);
void contact_unit(struct unit *u, const struct unit *c);
void contact_faction(struct unit * u, const struct faction * f);
int contact_cmd(struct unit * u, struct order * ord);

84
src/contact.test.c Normal file
View file

@ -0,0 +1,84 @@
#include "contact.h"
#include "kernel/faction.h"
#include "kernel/order.h"
#include "kernel/unit.h"
#include "util/language.h"
#include "util/param.h"
#include "tests.h"
#include <CuTest.h>
struct region;
static void test_contact(CuTest *tc) {
struct unit *u1, *u2, *u3;
struct region *r;
struct faction *f;
test_setup();
r = test_create_plain(0, 0);
f = test_create_faction(NULL);
u1 = test_create_unit(f, r);
u2 = test_create_unit(f, r);
u3 = test_create_unit(test_create_faction(NULL), r);
CuAssertTrue(tc, ucontact(u1, u1));
CuAssertTrue(tc, ucontact(u1, u2));
CuAssertTrue(tc, !ucontact(u1, u3));
contact_unit(u1, u3);
CuAssertTrue(tc, ucontact(u1, u3));
CuAssertTrue(tc, !ucontact(u2, u3));
test_teardown();
}
static void test_contact_cmd(CuTest *tc) {
struct unit *u, *u2;
struct region *r;
const struct locale *lang;
struct order *ord;
test_setup();
r = test_create_plain(0, 0);
u = test_create_unit(test_create_faction(NULL), r);
lang = u->faction->locale;
u2 = test_create_unit(test_create_faction(NULL), r);
ord = create_order(K_CONTACT, u->faction->locale, "%s %i",
LOC(lang, parameters[P_UNIT]), u2->no);
contact_cmd(u, ord);
CuAssertTrue(tc, ucontact(u, u2));
free_order(ord);
u2 = test_create_unit(test_create_faction(NULL), r);
ord = create_order(K_CONTACT, u->faction->locale, "%s %i",
LOC(lang, parameters[P_FACTION]), u2->faction->no);
contact_cmd(u, ord);
CuAssertTrue(tc, ucontact(u, u2));
free_order(ord);
u2 = test_create_unit(test_create_faction(NULL), r);
ord = create_order(K_CONTACT, u->faction->locale, "%i", u2->no);
contact_cmd(u, ord);
CuAssertTrue(tc, ucontact(u, u2));
free_order(ord);
u2 = test_create_unit(test_create_faction(NULL), r);
usetalias(u2, 42);
ord = create_order(K_CONTACT, u->faction->locale, "%s %i",
LOC(lang, parameters[P_TEMP]), ualias(u2));
contact_cmd(u, ord);
CuAssertTrue(tc, ucontact(u, u2));
free_order(ord);
test_teardown();
}
CuSuite *get_contact_suite(void)
{
CuSuite *suite = CuSuiteNew();
SUITE_ADD_TEST(suite, test_contact);
SUITE_ADD_TEST(suite, test_contact_cmd);
return suite;
}

View file

@ -16,6 +16,7 @@
#include <kernel/config.h>
#include "give.h"
#include "contact.h"
#include "economy.h"
#include "laws.h"

View file

@ -1,6 +1,8 @@
#include <platform.h>
#include "give.h"
#include "contact.h"
#include "economy.h"
#include <kernel/ally.h>
@ -193,7 +195,7 @@ static void test_give_men_limit(CuTest * tc) {
config_set("rules.give.max_men", "1");
/* below the limit, give men, increase newbies counter */
usetcontact(env.dst, env.src);
contact_unit(env.dst, env.src);
msg = give_men(1, env.src, env.dst, NULL);
CuAssertStrEquals(tc, "give_person", test_get_messagetype(msg));
CuAssertIntEquals(tc, 2, env.dst->number);
@ -202,7 +204,7 @@ static void test_give_men_limit(CuTest * tc) {
msg_release(msg);
/* beyond the limit, do nothing */
usetcontact(env.src, env.dst);
contact_unit(env.src, env.dst);
msg = give_men(2, env.dst, env.src, NULL);
CuAssertStrEquals(tc, "error129", test_get_messagetype(msg));
CuAssertIntEquals(tc, 2, env.dst->number);
@ -281,7 +283,7 @@ static void test_give_men_other_faction(CuTest * tc) {
env.f1 = test_create_faction(NULL);
env.f2 = test_create_faction(NULL);
setup_give(&env);
usetcontact(env.dst, env.src);
contact_unit(env.dst, env.src);
msg = give_men(1, env.src, env.dst, NULL);
CuAssertStrEquals(tc, "give_person", test_get_messagetype(msg));
CuAssertIntEquals(tc, 2, env.dst->number);

View file

@ -14,16 +14,18 @@
#include <curses.h>
#include <kernel/config.h>
#include "gmtool.h"
#include "direction.h"
#include <modules/autoseed.h>
#include "kernel/building.h"
#include "kernel/config.h"
#include "kernel/faction.h"
#include "kernel/item.h"
#include "kernel/plane.h"
#include "kernel/region.h"
#include "kernel/resources.h"
#include "kernel/terrainid.h"
#include "kernel/unit.h"
#include "kernel/save.h"
@ -35,6 +37,7 @@
#include <util/lists.h>
#include <util/macros.h>
#include "util/path.h"
#include "util/rand.h"
#include "util/rng.h"
#include "util/unicode.h"
@ -43,6 +46,8 @@
#include "listbox.h"
#include "teleport.h"
#include <selist.h>
#include <assert.h>
#include <limits.h>
#include <stdlib.h>
@ -437,7 +442,10 @@ static void paint_info_region(window * wnd, const state * st)
line++;
umvwprintw(win, line++, 1, "%s, age %d", r->terrain->_name, r->age);
if (r->land) {
int iron = region_getresource_level(r, get_resourcetype(R_IRON));
int stone = region_getresource_level(r, get_resourcetype(R_STONE));
mvwprintw(win, line++, 1, "$:%6d P:%5d", rmoney(r), rpeasants(r));
mvwprintw(win, line++, 1, "S:%6d I:%5d", stone, iron);
mvwprintw(win, line++, 1, "H:%6d %s:%5d", rhorses(r),
(r->flags & RF_MALLORN) ? "M" : "T",
r->land->trees[1] + r->land->trees[2]);
@ -515,6 +523,33 @@ static void statusline(WINDOW * win, const char *str)
wnoutrefresh(win);
}
static void reset_resources(region *r, const struct terrain_type *terrain)
{
int i;
for (i = 0; terrain->production[i].type; ++i) {
rawmaterial *rm;
const terrain_production *production = terrain->production + i;
const resource_type *rtype = production->type;
for (rm = r->resources; rm; rm = rm->next) {
if (rm->rtype == rtype)
break;
}
if (rm) {
struct rawmaterial_type *rmt;
set_resource(rm,
dice_rand(production->startlevel),
dice_rand(production->base),
dice_rand(production->divisor));
rmt = rmt_get(rtype);
if (rmt && rmt->terraform) {
rmt->terraform(rm, r);
}
}
}
}
static void reset_region(region *r) {
unit **up = &r->units;
bool players = false;
@ -540,6 +575,7 @@ static void reset_region(region *r) {
}
if (r->land) {
init_region(r);
reset_resources(r, r->terrain);
}
}
}
@ -585,6 +621,69 @@ static void terraform_at(coordinate * c, const terrain_type * terrain)
}
}
static void selection_walk(selection * selected, void(*callback)(region *, void *), void *udata) {
int i;
for (i = 0; i != MAXTHASH; ++i) {
tag **tp = &selected->tags[i];
while (*tp) {
region *r;
tag *t = *tp;
int nx = t->coord.x, ny = t->coord.y;
plane *pl = t->coord.pl;
pnormalize(&nx, &ny, pl);
r = findregion(nx, ny);
if (r != NULL) {
callback(r, udata);
}
tp = &t->nexthash;
}
}
}
static void reset_levels_cb(region *r, void *udata) {
struct rawmaterial *res;
UNUSED_ARG(udata);
for (res = r->resources; res; res = res->next) {
if (res->level > 3) {
res->level = 1;
}
}
}
/**
* BUG 2506: reset drained mountains to level 1
*/
static void
fix_selection(selection * selected)
{
selection_walk(selected, reset_levels_cb, NULL);
}
static void
reset_selection(selection * selected)
{
int i;
for (i = 0; i != MAXTHASH; ++i) {
tag **tp = &selected->tags[i];
while (*tp) {
region *r;
tag *t = *tp;
int nx = t->coord.x, ny = t->coord.y;
plane *pl = t->coord.pl;
pnormalize(&nx, &ny, pl);
r = findregion(nx, ny);
if (r != NULL) {
reset_region(r);
}
tp = &t->nexthash;
}
}
}
static void
terraform_selection(selection * selected, const terrain_type * terrain)
{
@ -694,7 +793,7 @@ void highlight_region(region * r, int toggle)
}
}
void select_coordinate(struct selection *selected, int nx, int ny, int toggle)
void select_coordinate(struct selection *selected, int nx, int ny, bool toggle)
{
if (toggle)
tag_region(selected, nx, ny);
@ -702,7 +801,50 @@ void select_coordinate(struct selection *selected, int nx, int ny, int toggle)
untag_region(selected, nx, ny);
}
enum { MODE_MARK, MODE_SELECT, MODE_UNMARK, MODE_UNSELECT };
enum select_t { MODE_MARK, MODE_SELECT, MODE_UNMARK, MODE_UNSELECT };
static void select_island(state *st, int selectmode)
{
region *r;
int nx = st->cursor.x;
int ny = st->cursor.y;
pnormalize(&nx, &ny, st->cursor.pl);
r = findregion(nx, ny);
if (r && r->land) {
selist *ql, *stack = NULL;
int qi = 0;
selist_push(&stack, r);
for (ql = stack, qi = 0; ql; selist_advance(&ql, &qi, 1)) {
region *r = (region *)selist_get(ql, qi);
region *rnext[MAXDIRECTIONS];
int i;
fset(r, RF_MARK);
if (selectmode & MODE_SELECT) {
select_coordinate(st->selected, r->x, r->y,
selectmode == MODE_SELECT);
}
else {
highlight_region(r, selectmode == MODE_MARK);
}
get_neighbours(r, rnext);
for (i = 0; i != MAXDIRECTIONS; ++i) {
region *rn = rnext[i];
if (rn && rn->land && !fval(rn, RF_MARK)) {
selist_push(&stack, rn);
}
}
}
for (ql = stack, qi = 0; ql; selist_advance(&ql, &qi, 1)) {
region *r = (region *)selist_get(ql, qi);
freset(r, RF_MARK);
}
selist_free(stack);
}
}
static void select_regions(state * st, int selectmode)
{
@ -856,6 +998,11 @@ static void select_regions(state * st, int selectmode)
}
}
}
else if (findmode == 'i') {
sprintf(sbuffer, "%swand: ", status);
statusline(st->wnd_status->handle, sbuffer);
select_island(st, selectmode);
}
else if (findmode == 't') {
const struct terrain_type *terrain;
sprintf(sbuffer, "%sterrain: ", status);
@ -1186,7 +1333,12 @@ static void handlekey(state * st, int c)
statusline(st->wnd_status->handle, "tag-");
doupdate();
switch (getch()) {
case 'r':
reset_selection(st->selected);
break;
case 'f':
fix_selection(st->selected);
break;
case 't':
terraform_selection(st->selected, select_terrain(st, NULL));
st->modified = 1;

View file

@ -29,7 +29,7 @@ extern "C" {
const char *prompt);
void highlight_region(struct region *r, int on);
void select_coordinate(struct selection *selected, int x, int y, int on);
void select_coordinate(struct selection *selected, int x, int y, bool on);
void run_mapper(void);
extern int force_color;

View file

@ -20,6 +20,8 @@ OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
#include <platform.h>
#include <kernel/config.h>
#include "guard.h"
#include "contact.h"
#include "laws.h"
#include "monsters.h"

View file

@ -178,7 +178,7 @@ static bool lua_equipunit(unit *u, const char *eqname, int mask) {
lua_pop(L, 1);
}
else {
result = (bool)lua_toboolean(L, -1);
result = lua_toboolean(L, -1) != 0;
lua_pop(L, 1);
}
}

View file

@ -527,28 +527,19 @@ int build_skill(unit *u, int basesk, int skill_mod) {
* of the first object have already been finished. return the
* actual size that could be built.
*/
int build(unit * u, const construction * ctype, int completed, int want, int skill_mod)
{
const construction *con = ctype;
int skills = INT_MAX; /* number of skill points remainig */
int basesk = 0;
static int build_limited(unit * u, const construction * con, int completed, int want, int basesk, int *skill_total) {
int skills = *skill_total;
int made = 0;
if (want <= 0)
if (want <= 0) {
return 0;
}
if (con == NULL) {
return ENOMATERIALS;
}
if (completed == con->maxsize) {
return ECOMPLETE;
}
if (con->skill != NOSKILL) {
basesk = effskill(u, con->skill, 0);
if (basesk == 0)
return ENEEDSKILL;
skills = build_skill(u, basesk, skill_mod);
}
for (; want > 0 && skills > 0;) {
int err, n;
@ -615,9 +606,27 @@ int build(unit * u, const construction * ctype, int completed, int want, int ski
want -= n;
completed = completed + n;
}
/* Nur soviel PRODUCEEXP wie auch tatsaechlich gemacht wurde */
produceexp(u, ctype->skill, (made < u->number) ? made : u->number);
*skill_total = skills;
return made;
}
int build(unit * u, const construction * con, int completed, int want, int skill_mod)
{
int skills = INT_MAX; /* number of skill points remainig */
int made, basesk = 0;
assert(con->skill != NOSKILL);
basesk = effskill(u, con->skill, 0);
if (basesk == 0) {
return ENEEDSKILL;
}
skills = build_skill(u, basesk, skill_mod);
made = build_limited(u, con, completed, want, basesk, &skills);
/* Nur soviel PRODUCEEXP wie auch tatsaechlich gemacht wurde */
if (made > 0) {
produceexp(u, con->skill, (made < u->number) ? made : u->number);
}
return made;
}
@ -686,7 +695,7 @@ static int build_failure(unit *u, order *ord, const building_type *btype, int wa
return err;
}
static int build_stages(unit *u, const building_type *btype, int built, int n) {
static int build_stages(unit *u, const building_type *btype, int built, int n, int basesk, int *skill_total) {
const building_stage *stage;
int made = 0;
@ -706,7 +715,7 @@ static int build_stages(unit *u, const building_type *btype, int built, int n) {
want = todo;
}
}
err = build(u, con, built, want, 0);
err = build_limited(u, con, built, want, basesk, skill_total);
if (err < 0) {
if (made == 0) {
/* could not make any part at all */
@ -744,10 +753,14 @@ build_building(unit * u, const building_type * btype, int id, int want, order *
const char *btname;
order *new_order = NULL;
const struct locale *lang = u->faction->locale;
int skills, basesk; /* number of skill points remainig */
assert(u->number);
assert(btype->stages && btype->stages->construction);
if (effskill(u, SK_BUILDING, 0) == 0) {
basesk = effskill(u, SK_BUILDING, 0);
skills = build_skill(u, basesk, 0);
if (skills == 0) {
cmistake(u, ord, 101, MSG_PRODUCE);
return 0;
}
@ -832,7 +845,7 @@ build_building(unit * u, const building_type * btype, int id, int want, order *
}
}
built = build_stages(u, btype, built, n);
built = build_stages(u, btype, built, n, basesk, &skills);
if (built < 0) {
return build_failure(u, ord, btype, want, built);

View file

@ -22,8 +22,9 @@
#include <CuTest.h>
#include <tests.h>
#include <stdlib.h>
#include <assert.h>
#include <stdlib.h>
#include <limits.h>
typedef struct build_fixture {
faction *f;
@ -57,6 +58,53 @@ static unit * setup_build(build_fixture *bf) {
return bf->u;
}
static building_type *setup_castle(item_type *it_stone) {
building_type *btype;
building_stage *stage;
construction * cons;
btype = test_create_buildingtype("castle");
stage = btype->stages = calloc(1, sizeof(building_stage));
cons = stage->construction = calloc(1, sizeof(construction));
cons->materials = calloc(2, sizeof(requirement));
cons->materials[0].number = 1;
cons->materials[0].rtype = it_stone->rtype;
cons->minskill = 1;
cons->maxsize = 2;
cons->reqsize = 1;
cons->skill = SK_BUILDING;
stage = stage->next = calloc(1, sizeof(building_stage));
cons = stage->construction = calloc(1, sizeof(construction));
cons->materials = calloc(2, sizeof(requirement));
cons->materials[0].number = 1;
cons->materials[0].rtype = it_stone->rtype;
cons->minskill = 1;
cons->maxsize = 8;
cons->reqsize = 1;
cons->skill = SK_BUILDING;
return btype;
}
static void test_build_building_stages(CuTest *tc) {
building_type *btype;
item_type *it_stone;
unit *u;
test_setup();
init_resources();
it_stone = test_create_itemtype("stone");
btype = setup_castle(it_stone);
u = test_create_unit(test_create_faction(NULL), test_create_plain(0, 0));
set_level(u, SK_BUILDING, 2);
i_change(&u->items, it_stone, 4);
build_building(u, btype, -1, INT_MAX, NULL);
CuAssertPtrNotNull(tc, u->building);
CuAssertIntEquals(tc, 2, u->building->size);
CuAssertIntEquals(tc, 2, i_get(u->items, it_stone));
test_teardown();
}
static void teardown_build(build_fixture *bf) {
free(bf->cons.materials);
test_teardown();
@ -395,6 +443,7 @@ CuSuite *get_build_suite(void)
SUITE_ADD_TEST(suite, test_build_with_ring);
SUITE_ADD_TEST(suite, test_build_with_potion);
SUITE_ADD_TEST(suite, test_build_building_success);
SUITE_ADD_TEST(suite, test_build_building_stages);
SUITE_ADD_TEST(suite, test_build_building_with_golem);
SUITE_ADD_TEST(suite, test_build_building_no_materials);
SUITE_ADD_TEST(suite, test_build_destroy_cmd);

View file

@ -22,7 +22,6 @@ struct critbit_tree;
static void test_read_unitid(CuTest *tc) {
unit *u;
order *ord;
attrib *a;
struct locale *lang;
struct terrain_type *t_plain;
@ -31,8 +30,7 @@ static void test_read_unitid(CuTest *tc) {
/* note that the english order is FIGHT, not COMBAT, so this is a poor example */
t_plain = test_create_terrain("plain", LAND_REGION);
u = test_create_unit(test_create_faction(NULL), test_create_region(0, 0, t_plain));
a = a_add(&u->attribs, a_new(&at_alias));
a->data.i = atoi36("42"); /* this unit is also TEMP 42 */
usetalias(u, atoi36("42"));
ord = create_order(K_GIVE, lang, "TEMP 42");
init_order_depr(ord);
@ -66,7 +64,6 @@ static void test_read_unitid(CuTest *tc) {
static void test_getunit(CuTest *tc) {
unit *u, *u2;
order *ord;
attrib *a;
struct region *r;
struct locale *lang;
struct terrain_type *t_plain;
@ -76,8 +73,9 @@ static void test_getunit(CuTest *tc) {
/* note that the english order is FIGHT, not COMBAT, so this is a poor example */
t_plain = test_create_terrain("plain", LAND_REGION);
u = test_create_unit(test_create_faction(NULL), test_create_region(0, 0, t_plain));
a = a_add(&u->attribs, a_new(&at_alias));
a->data.i = atoi36("42"); /* this unit is also TEMP 42 */
/* This unit is also TEMP 42: */
usetalias(u, atoi36("42"));
r = test_create_region(1, 0, t_plain);
ord = create_order(K_GIVE, lang, itoa36(u->no));

View file

@ -263,7 +263,7 @@ bool b_blocknone(const connection * b, const unit * u, const region * r)
bool b_rvisible(const connection * b, const region * r)
{
return (bool)(b->to == r || b->from == r);
return (b->to == r || b->from == r);
}
bool b_fvisible(const connection * b, const struct faction * f,
@ -412,7 +412,7 @@ b_blockfogwall(const connection * b, const unit * u, const region * r)
UNUSED_ARG(b);
if (!u)
return true;
return (bool)(effskill(u, SK_PERCEPTION, r) > 4); /* Das ist die alte Nebelwand */
return (effskill(u, SK_PERCEPTION, r) > 4); /* Das ist die alte Nebelwand */
}
/** Legacy type used in old Eressea games, no longer in use. */

View file

@ -63,7 +63,7 @@ extern "C" {
struct mlist ** merge_messages(message_list *ml, message_list *append);
void split_messages(message_list *ml, struct mlist **split);
#define ADDMSG(msgs, mcreate) { message * mx = mcreate; if (mx) { assert(mx->refcount>=1); add_message(msgs, mx); msg_release(mx); } }
#define ADDMSG(msgs, mcreate) { message * mx = mcreate; if (mx) { add_message(msgs, mx); msg_release(mx); } }
void syntax_error(const struct unit *u, struct order *ord);
void cmistake(const struct unit *u, struct order *ord, int mno, int mtype);

View file

@ -268,7 +268,7 @@ static int hash_requests;
static int hash_misses;
#endif
bool pnormalize(int *x, int *y, const plane * pl)
void pnormalize(int *x, int *y, const plane * pl)
{
if (pl) {
if (x) {
@ -284,7 +284,6 @@ bool pnormalize(int *x, int *y, const plane * pl)
*y = ny % height + pl->miny;
}
}
return false; /* TBD */
}
static region *rfindhash(int x, int y)
@ -343,8 +342,9 @@ region *r_connect(const region * r, direction_t dir)
int x, y;
region *rmodify = (region *)r;
assert(dir >= 0 && dir < MAXDIRECTIONS);
if (r->connect[dir])
if (r->connect[dir]) {
return r->connect[dir];
}
assert(dir < MAXDIRECTIONS);
x = r->x + delta_x[dir];
y = r->y + delta_y[dir];
@ -757,10 +757,6 @@ int rsettrees(const region * r, int ageclass, int value)
return 0;
}
static region *last;
static unsigned int max_index = 0;
region *region_create(int uid)
{
region *r = (region *)calloc(1, sizeof(region));
@ -770,19 +766,13 @@ region *region_create(int uid)
return r;
}
region *new_region(int x, int y, struct plane *pl, int uid)
{
region *r;
static region *last;
static unsigned int max_index;
pnormalize(&x, &y, pl);
r = rfindhash(x, y);
if (!r) {
r = region_create(uid);
}
void add_region(region *r, int x, int y) {
r->x = x;
r->y = y;
r->age = 1;
r->_plane = pl;
r->_plane = findplane(x, y);
rhash(r);
if (last) {
addlist(&last, r);
@ -793,6 +783,15 @@ region *new_region(int x, int y, struct plane *pl, int uid)
last = r;
assert(r->next == NULL);
r->index = ++max_index;
}
region *new_region(int x, int y, struct plane *pl, int uid)
{
region *r;
r = region_create(uid);
r->age = 1;
add_region(r, x, y);
assert(pl == r->_plane);
return r;
}
@ -830,7 +829,7 @@ void free_land(land_region * lr)
free(lr);
}
void region_setresource(region * r, const resource_type * rtype, int value)
void region_setresource(region * r, const struct resource_type *rtype, int value)
{
rawmaterial *rm = r->resources;
while (rm) {
@ -873,7 +872,18 @@ void region_setresource(region * r, const resource_type * rtype, int value)
}
}
int region_getresource(const region * r, const resource_type * rtype)
int region_getresource_level(const region * r, const struct resource_type * rtype)
{
const rawmaterial *rm;
for (rm = r->resources; rm; rm = rm->next) {
if (rm->rtype == rtype) {
return rm->level;
}
}
return -1;
}
int region_getresource(const region * r, const struct resource_type *rtype)
{
const rawmaterial *rm;
for (rm = r->resources; rm; rm = rm->next) {

View file

@ -226,11 +226,12 @@ extern "C" {
char *buffer, size_t size);
struct region *region_create(int uid);
void add_region(region *r, int x, int y);
struct region *new_region(int x, int y, struct plane *pl, int uid);
void remove_region(region ** rlist, region * r);
void terraform_region(struct region *r, const struct terrain_type *terrain);
void init_region(struct region *r);
bool pnormalize(int *x, int *y, const struct plane *pl);
void pnormalize(int *x, int *y, const struct plane *pl);
extern const int delta_x[MAXDIRECTIONS];
extern const int delta_y[MAXDIRECTIONS];
@ -262,6 +263,8 @@ extern "C" {
void region_setname(struct region *self, const char *name);
const char *region_getinfo(const struct region *self);
void region_setinfo(struct region *self, const char *name);
int region_getresource_level(const struct region * r,
const struct resource_type * rtype);
int region_getresource(const struct region *r,
const struct resource_type *rtype);
void region_setresource(struct region *r, const struct resource_type *rtype,

View file

@ -46,8 +46,6 @@ void update_resources(region * r)
}
}
extern int dice_rand(const char *s);
static void update_resource(struct rawmaterial *res, double modifier)
{
double amount = (res->level - res->startlevel) / 100.0 * res->divisor + 1;
@ -59,6 +57,15 @@ static void update_resource(struct rawmaterial *res, double modifier)
assert(res->amount > 0);
}
void set_resource(struct rawmaterial *rm, int level, int base, int divisor)
{
rm->level = level;
rm->startlevel = level;
rm->base = base;
rm->amount = base;
rm->divisor = divisor;
}
struct rawmaterial *
add_resource(region * r, int level, int base, int divisor,
const resource_type * rtype)
@ -67,13 +74,9 @@ const resource_type * rtype)
rm->next = r->resources;
r->resources = rm;
rm->level = level;
rm->startlevel = level;
rm->base = base;
rm->amount = base;
rm->divisor = divisor;
rm->flags = 0;
rm->rtype = rtype;
set_resource(rm, level, base, divisor);
return rm;
}

View file

@ -70,6 +70,7 @@ extern "C" {
const struct resource_type *);
struct rawmaterial_type *rmt_get(const struct resource_type *);
void set_resource(struct rawmaterial *rm, int level, int base, int divisor);
struct rawmaterial *add_resource(struct region *r, int level,
int base, int divisor, const struct resource_type *rtype);
struct rawmaterial_type *rmt_create(struct resource_type *rtype);

View file

@ -614,7 +614,7 @@ static void read_regioninfo(gamedata *data, const region *r, char *info, size_t
static region *readregion(gamedata *data, int x, int y)
{
region *r = findregion(x, y);
region *r;
const terrain_type *terrain;
char name[NAMESIZE];
char info[DISPLAYSIZE];
@ -622,26 +622,19 @@ static region *readregion(gamedata *data, int x, int y)
int n;
READ_INT(data->store, &uid);
r = findregionbyid(uid);
if (r == NULL) {
plane *pl = findplane(x, y);
r = new_region(x, y, pl, uid);
r = region_create(uid);
}
else {
assert(uid == 0 || r->uid == uid);
while (r->attribs)
a_remove(&r->attribs, r->attribs);
if (r->land) {
free_land(r->land);
r->land = 0;
}
while (r->resources) {
rawmaterial *rm = r->resources;
r->resources = rm->next;
free(rm);
}
r->land = 0;
/* make sure this was not read earlier */
assert(r->next == NULL);
assert(r->attribs == NULL);
assert(r->land == NULL);
assert(r->resources == NULL);
}
/* add region to the global list: */
add_region(r, x, y);
if (data->version < LANDDISPLAY_VERSION) {
read_regioninfo(data, r, info, sizeof(info));
}

View file

@ -26,7 +26,7 @@ extern "C" {
#endif
typedef struct skill {
skill_t id : 8;
int id : 8;
int level : 8;
int weeks : 8;
int old : 8;

View file

@ -430,7 +430,7 @@ unit *findnewunit(const region * r, const faction * f, int n)
/*********************/
/* at_alias */
/*********************/
attrib_type at_alias = {
static attrib_type at_alias = {
"alias",
DEFAULT_INIT,
DEFAULT_FINALIZE,
@ -451,6 +451,11 @@ int ualias(const unit * u)
return a->data.i;
}
void usetalias(unit *u, int alias)
{
a_add(&u->attribs, a_new(&at_alias))->data.i = alias;
}
int a_readprivate(variant *var, void *owner, gamedata *data)
{
struct storage *store = data->store;
@ -517,58 +522,6 @@ void usetprivate(unit * u, const char *str)
a->data.v = str_strdup(str);
}
/*********************/
/* at_target */
/*********************/
attrib_type at_target = {
"target",
DEFAULT_INIT,
DEFAULT_FINALIZE,
DEFAULT_AGE,
NO_WRITE,
NO_READ
};
/*********************/
/* at_contact */
/*********************/
attrib_type at_contact = {
"contact",
DEFAULT_INIT,
DEFAULT_FINALIZE,
DEFAULT_AGE,
NO_WRITE,
NO_READ
};
void usetcontact(unit * u, const unit * u2)
{
attrib *a = a_find(u->attribs, &at_contact);
while (a && a->type == &at_contact && a->data.v != u2)
a = a->next;
if (a && a->type == &at_contact)
return;
a_add(&u->attribs, a_new(&at_contact))->data.v = (void *)u2;
}
bool ucontact(const unit * u, const unit * u2)
/* Prueft, ob u den Kontaktiere-Befehl zu u2 gesetzt hat. */
{
attrib *ru;
if (u->faction == u2->faction)
return true;
/* Explizites KONTAKTIERE */
for (ru = a_find(u->attribs, &at_contact); ru && ru->type == &at_contact;
ru = ru->next) {
if (((unit *)ru->data.v) == u2) {
return true;
}
}
return false;
}
/***
** init & cleanup module
**/

View file

@ -120,15 +120,14 @@ extern "C" {
} unit;
extern struct attrib_type at_creator;
extern struct attrib_type at_alias;
extern struct attrib_type at_target;
extern struct attrib_type at_potionuser;
extern struct attrib_type at_contact;
extern struct attrib_type at_effect;
extern struct attrib_type at_private;
extern struct attrib_type at_showskchange;
int ualias(const struct unit *u);
void usetalias(unit *u, int alias);
int weight(const struct unit *u);
void renumber_unit(struct unit *u, int no);
@ -141,9 +140,6 @@ extern "C" {
const char *uprivate(const struct unit *u);
void usetprivate(struct unit *u, const char *c);
bool ucontact(const struct unit *u, const struct unit *u2);
void usetcontact(struct unit *u, const struct unit *c);
struct unit *findnewunit(const struct region *r, const struct faction *f,
int alias);

View file

@ -28,6 +28,7 @@ OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
#include "alchemy.h"
#include "automate.h"
#include "battle.h"
#include "contact.h"
#include "economy.h"
#include "market.h"
#include "morale.h"
@ -912,21 +913,6 @@ void demographics(void)
immigration();
}
int contact_cmd(unit * u, order * ord)
{
unit *u2;
int n;
init_order_depr(ord);
n = read_unitid(u->faction, u->region);
u2 = findunit(n);
if (u2 != NULL) {
usetcontact(u, u2);
}
return 0;
}
int leave_cmd(unit * u, struct order *ord)
{
region *r = u->region;
@ -2855,7 +2841,7 @@ void maketemp_cmd(unit *u, order **olist)
}
u2 = create_unit(u->region, u->faction, 0, u->faction->race, alias, s, u);
fset(u2, UFL_ISNEW);
a_add(&u2->attribs, a_new(&at_alias))->data.i = alias;
usetalias(u2, alias);
sh = leftship(u);
if (sh) {
set_leftship(u2, sh);
@ -3379,7 +3365,7 @@ int pay_cmd(unit * u, struct order *ord)
static int reserve_i(unit * u, struct order *ord, int flags)
{
char token[128];
if (u->number > 0 && (u_race(u)->ec_flags & ECF_GETITEM)) {
if (u->number > 0) {
int use, count, para;
const item_type *itype;
const char *s;
@ -3413,7 +3399,10 @@ static int reserve_i(unit * u, struct order *ord, int flags)
}
int reserve_cmd(unit * u, struct order *ord) {
return reserve_i(u, ord, GET_DEFAULT);
if ((u_race(u)->ec_flags & ECF_GETITEM)) {
return reserve_i(u, ord, GET_DEFAULT);
}
return 0;
}
int reserve_self(unit * u, struct order *ord) {

View file

@ -22,11 +22,12 @@ OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
#endif
#include "magic.h"
#include "skill.h"
#include "study.h"
#include "contact.h"
#include "helpers.h"
#include "laws.h"
#include "skill.h"
#include "spells.h"
#include "study.h"
#include <triggers/timeout.h>
#include <triggers/shock.h>
@ -1213,7 +1214,7 @@ target_resists_magic(unit * magician, void *obj, int objtyp, int t_bonus)
bool is_magic_resistant(unit * magician, unit * target, int resist_bonus)
{
return (bool)target_resists_magic(magician, target, TYP_UNIT,
return target_resists_magic(magician, target, TYP_UNIT,
resist_bonus);
}

View file

@ -71,7 +71,7 @@ attrib_type at_market = {
bool markets_module(void)
{
return (bool)config_get_int("modules.market", 0);
return config_get_int("modules.market", 0) != 0;
}
void do_markets(void)

View file

@ -44,18 +44,19 @@ OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
#include "kernel/terrainid.h"
#include "kernel/unit.h"
#include "move.h"
#include "alchemy.h"
#include "contact.h"
#include "guard.h"
#include "laws.h"
#include "lighthouse.h"
#include "monsters.h"
#include "move.h"
#include "piracy.h"
#include "reports.h"
#include "study.h"
#include "spy.h"
#include "alchemy.h"
#include "travelthru.h"
#include "vortex.h"
#include "monsters.h"
#include "lighthouse.h"
#include "piracy.h"
#include <spells/flyingship.h>
#include <spells/unitcurse.h>
@ -892,7 +893,7 @@ static void drifting_ships(region * r)
static bool present(region * r, unit * u)
{
return (bool)(u && u->region == r);
return (u && u->region == r);
}
static void caught_target(region * r, unit * u)

View file

@ -2,6 +2,7 @@
#include <stdlib.h>
#include "move.h"
#include "contact.h"
#include "lighthouse.h"
#include <kernel/attrib.h>
@ -129,7 +130,7 @@ static void test_ship_has_harbormaster_contact(CuTest * tc) {
u = test_create_unit(test_create_faction(NULL), mf.r);
u->building = mf.b;
building_set_owner(u);
usetcontact(mf.b->_owner, mf.sh->_owner);
contact_unit(mf.b->_owner, mf.sh->_owner);
CuAssertIntEquals(tc, SA_HARBOUR, check_ship_allowed(mf.sh, mf.r));
test_teardown();

View file

@ -683,7 +683,7 @@ bufunit(const faction * f, const unit * u, seen_mode mode, char *buf,
int i, dh;
int getarnt = fval(u, UFL_ANON_FACTION);
const char *pzTmp, *str;
bool isbattle = (bool)(mode == seen_battle);
bool isbattle = (mode == seen_battle);
item *itm, *show = NULL;
faction *fv;
char *bufp = buf;
@ -916,7 +916,7 @@ bufunit(const faction * f, const unit * u, seen_mode mode, char *buf,
}
if (!isbattle) {
int printed = 0;
order *ord;;
order *ord;
for (ord = u->old_orders; ord; ord = ord->next) {
keyword_t kwd = getkeyword(ord);
if (is_repeated(kwd)) {
@ -1133,7 +1133,6 @@ static void cb_add_address(region *r, unit *ut, void *cbdata) {
if (data->lastf != sf && cansee_unit(ut, u, data->stealthmod)) {
add_seen_faction_i(data->flist, sf);
data->lastf = sf;
break;
}
}
}

View file

@ -440,22 +440,34 @@ static void test_get_addresses_fstealth(CuTest *tc) {
static void test_get_addresses_travelthru(CuTest *tc) {
report_context ctx;
faction *f, *f2, *f1;
faction *f, *f4, *f3, *f2, *f1;
region *r1, *r2;
unit *u;
race *rc;
test_setup();
f = test_create_faction(NULL);
f1 = test_create_faction(NULL);
f2 = test_create_faction(NULL);
r1 = test_create_region(0, 0, NULL);
r2 = test_create_region(1, 0, 0);
u = test_create_unit(f, r2);
travelthru_add(r1, u);
f1 = test_create_faction(NULL);
u = test_create_unit(f1, r1);
f2 = test_create_faction(NULL);
set_factionstealth(u, f2);
u->building = test_create_building(u->region, test_create_buildingtype("tower"));
rc = rc_get_or_create("dragon");
rc->flags |= RCF_UNARMEDGUARD;
f3 = test_create_faction(rc);
u = test_create_unit(f3, r1);
setguard(u, true);
f4 = test_create_faction(NULL);
u = test_create_unit(f4, r1);
set_level(u, SK_STEALTH, 1);
prepare_report(&ctx, f);
CuAssertPtrEquals(tc, r1, ctx.first);
CuAssertPtrEquals(tc, NULL, ctx.last);
@ -464,7 +476,9 @@ static void test_get_addresses_travelthru(CuTest *tc) {
CuAssertTrue(tc, selist_contains(ctx.addresses, f, NULL));
CuAssertTrue(tc, !selist_contains(ctx.addresses, f1, NULL));
CuAssertTrue(tc, selist_contains(ctx.addresses, f2, NULL));
CuAssertIntEquals(tc, 2, selist_length(ctx.addresses));
CuAssertTrue(tc, selist_contains(ctx.addresses, f3, NULL));
CuAssertTrue(tc, !selist_contains(ctx.addresses, f4, NULL));
CuAssertIntEquals(tc, 3, selist_length(ctx.addresses));
finish_reports(&ctx);
test_teardown();
}

View file

@ -17,6 +17,7 @@
#include "spells.h"
#include "contact.h"
#include "guard.h"
#include "reports.h"
#include "spy.h"

View file

@ -125,6 +125,7 @@ int RunAllTests(int argc, char *argv[])
ADD_SUITE(automate);
ADD_SUITE(battle);
ADD_SUITE(calendar);
ADD_SUITE(contact);
ADD_SUITE(creport);
ADD_SUITE(donations);
ADD_SUITE(economy);

View file

@ -58,8 +58,8 @@ static const char *getbuf_utf8(FILE * F)
eatwhite(bp, &white); /* decoding errors will get caught later on, don't have to check */
bp += white;
comment = (bool)(comment && cont);
quote = (bool)(quote && cont);
comment = (comment && cont);
quote = (quote && cont);
if (tail[1] == 0) {
/* we read the maximum number of bytes! */