diff --git a/scripts/tests/e2/allies.lua b/scripts/tests/e2/allies.lua new file mode 100644 index 000000000..d7164c74b --- /dev/null +++ b/scripts/tests/e2/allies.lua @@ -0,0 +1,15 @@ +require "lunit" + +module("tests.e2.allies", package.seeall, lunit.testcase) + +function test_get_set_ally() + local f1 = faction.create("human") + local f2 = faction.create("human") + + assert_equal(false, f1:get_ally(f2, "guard")) + f1:set_ally(f2, "guard", true) + assert_equal(true, f1:get_ally(f2, "guard")) + assert_equal(false, f1:get_ally(f2, "give")) + f1:set_ally(f2, "give", true) + assert_equal(true, f1:get_ally(f2, "give")) +end diff --git a/scripts/tests/e2/init.lua b/scripts/tests/e2/init.lua index a7f6d8033..8e6cb3f66 100644 --- a/scripts/tests/e2/init.lua +++ b/scripts/tests/e2/init.lua @@ -1,4 +1,5 @@ --- require 'tests.e2.quit' +require 'tests.e2.allies' +require 'tests.e2.quit' require 'tests.e2.movement' require 'tests.e2.astral' require 'tests.e2.spells' diff --git a/src/bind_faction.c b/src/bind_faction.c index 518dddc27..131f32ba4 100644 --- a/src/bind_faction.c +++ b/src/bind_faction.c @@ -19,6 +19,7 @@ without prior permission by the authors of Eressea. #include "bindings.h" #include "magic.h" +#include #include #include #include @@ -59,13 +60,13 @@ int tolua_factionlist_next(lua_State * L) static int tolua_faction_get_units(lua_State * L) { - faction *self = (faction *)tolua_tousertype(L, 1, NULL); + faction *f = (faction *)tolua_tousertype(L, 1, NULL); unit **unit_ptr = (unit **)lua_newuserdata(L, sizeof(unit *)); luaL_getmetatable(L, TOLUA_CAST "unit"); lua_setmetatable(L, -2); - *unit_ptr = self->units; + *unit_ptr = f->units; lua_pushcclosure(L, tolua_unitlist_nextf, 1); return 1; @@ -73,7 +74,7 @@ static int tolua_faction_get_units(lua_State * L) int tolua_faction_add_item(lua_State * L) { - faction *self = (faction *)tolua_tousertype(L, 1, NULL); + faction *f = (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; @@ -81,7 +82,7 @@ int tolua_faction_add_item(lua_State * L) if (iname != NULL) { const resource_type *rtype = rt_find(iname); if (rtype && rtype->itype) { - item *i = i_change(&self->items, rtype->itype, number); + item *i = i_change(&f->items, rtype->itype, number); result = i ? i->number : 0; } /* if (itype!=NULL) */ } @@ -91,38 +92,38 @@ int tolua_faction_add_item(lua_State * L) static int tolua_faction_get_maxheroes(lua_State * L) { - faction *self = (faction *)tolua_tousertype(L, 1, NULL); - lua_pushinteger(L, maxheroes(self)); + faction *f = (faction *)tolua_tousertype(L, 1, NULL); + lua_pushinteger(L, maxheroes(f)); return 1; } static int tolua_faction_get_heroes(lua_State * L) { - faction *self = (faction *)tolua_tousertype(L, 1, NULL); - lua_pushinteger(L, countheroes(self)); + faction *f = (faction *)tolua_tousertype(L, 1, NULL); + lua_pushinteger(L, countheroes(f)); return 1; } static int tolua_faction_get_score(lua_State * L) { - faction *self = (faction *)tolua_tousertype(L, 1, NULL); - lua_pushnumber(L, (lua_Number)self->score); + faction *f = (faction *)tolua_tousertype(L, 1, NULL); + lua_pushnumber(L, (lua_Number)f->score); return 1; } static int tolua_faction_get_id(lua_State * L) { - faction *self = (faction *)tolua_tousertype(L, 1, NULL); - lua_pushinteger(L, self->no); + faction *f = (faction *)tolua_tousertype(L, 1, NULL); + lua_pushinteger(L, f->no); return 1; } static int tolua_faction_set_id(lua_State * L) { - faction *self = (faction *)tolua_tousertype(L, 1, NULL); + faction *f = (faction *)tolua_tousertype(L, 1, NULL); int id = (int)tolua_tonumber(L, 2, 0); if (findfaction(id) == NULL) { - renumber_faction(self, id); + renumber_faction(f, id); lua_pushboolean(L, 1); } else { @@ -133,20 +134,20 @@ 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, NULL); - lua_pushstring(L, magic_school[self->magiegebiet]); + faction *f = (faction *)tolua_tousertype(L, 1, NULL); + lua_pushstring(L, magic_school[f->magiegebiet]); return 1; } static int tolua_faction_set_magic(lua_State * L) { - faction *self = (faction *)tolua_tousertype(L, 1, NULL); + faction *f = (faction *)tolua_tousertype(L, 1, NULL); const char *type = tolua_tostring(L, 2, NULL); int mtype; for (mtype = 0; mtype != MAXMAGIETYP; ++mtype) { if (strcmp(magic_school[mtype], type) == 0) { - self->magiegebiet = (magic_t)mtype; + f->magiegebiet = (magic_t)mtype; break; } } @@ -155,89 +156,89 @@ 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, NULL); - lua_pushinteger(L, self->age); + faction *f = (faction *)tolua_tousertype(L, 1, NULL); + lua_pushinteger(L, f->age); return 1; } static int tolua_faction_set_age(lua_State * L) { - faction *self = (faction *)tolua_tousertype(L, 1, NULL); + faction *f = (faction *)tolua_tousertype(L, 1, NULL); int age = (int)tolua_tonumber(L, 2, 0); - self->age = age; + f->age = age; return 0; } static int tolua_faction_get_flags(lua_State * L) { - faction *self = (faction *)tolua_tousertype(L, 1, NULL); - lua_pushinteger(L, self->flags); + faction *f = (faction *)tolua_tousertype(L, 1, NULL); + lua_pushinteger(L, f->flags); return 1; } static int tolua_faction_set_flags(lua_State * L) { - faction *self = (faction *)tolua_tousertype(L, 1, NULL); - int flags = (int)tolua_tonumber(L, 2, self->flags); - self->flags = flags; + faction *f = (faction *)tolua_tousertype(L, 1, NULL); + int flags = (int)tolua_tonumber(L, 2, f->flags); + f->flags = flags; return 1; } static int tolua_faction_get_options(lua_State * L) { - faction *self = (faction *)tolua_tousertype(L, 1, NULL); - lua_pushinteger(L, self->options); + faction *f = (faction *)tolua_tousertype(L, 1, NULL); + lua_pushinteger(L, f->options); return 1; } static int tolua_faction_set_options(lua_State * L) { - faction *self = (faction *)tolua_tousertype(L, 1, NULL); - int options = (int)tolua_tonumber(L, 2, self->options); - self->options = options; + faction *f = (faction *)tolua_tousertype(L, 1, NULL); + int options = (int)tolua_tonumber(L, 2, f->options); + f->options = options; return 1; } static int tolua_faction_get_lastturn(lua_State * L) { - faction *self = (faction *)tolua_tousertype(L, 1, NULL); - lua_pushinteger(L, self->lastorders); + faction *f = (faction *)tolua_tousertype(L, 1, NULL); + lua_pushinteger(L, f->lastorders); return 1; } static int tolua_faction_set_lastturn(lua_State * L) { - faction *self = (faction *)tolua_tousertype(L, 1, NULL); - if (self) { - self->lastorders = (int)tolua_tonumber(L, 2, self->lastorders); + faction *f = (faction *)tolua_tousertype(L, 1, NULL); + if (f) { + f->lastorders = (int)tolua_tonumber(L, 2, f->lastorders); } return 0; } static int tolua_faction_renumber(lua_State * L) { - faction *self = (faction *)tolua_tousertype(L, 1, NULL); + faction *f = (faction *)tolua_tousertype(L, 1, NULL); int no = (int)tolua_tonumber(L, 2, 0); - renumber_faction(self, no); + renumber_faction(f, no); return 0; } static int tolua_faction_addnotice(lua_State * L) { - faction *self = (faction *)tolua_tousertype(L, 1, NULL); + faction *f = (faction *)tolua_tousertype(L, 1, NULL); const char *str = tolua_tostring(L, 2, NULL); - addmessage(NULL, self, str, MSG_MESSAGE, ML_IMPORTANT); + addmessage(NULL, f, str, MSG_MESSAGE, ML_IMPORTANT); return 0; } static int tolua_faction_getkey(lua_State * L) { - faction *self = (faction *)tolua_tousertype(L, 1, NULL); + faction *f = (faction *)tolua_tousertype(L, 1, NULL); const char *name = tolua_tostring(L, 2, NULL); int flag = atoi36(name); - int value = key_get(self->attribs, flag); + int value = key_get(f->attribs, flag); if (value != 0) { lua_pushinteger(L, value); return 1; @@ -247,30 +248,30 @@ static int tolua_faction_getkey(lua_State * L) static int tolua_faction_setkey(lua_State * L) { - faction *self = (faction *)tolua_tousertype(L, 1, NULL); + faction *f = (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) { - key_set(&self->attribs, flag, value); + key_set(&f->attribs, flag, value); } else { - key_unset(&self->attribs, flag); + key_unset(&f->attribs, flag); } return 0; } static int tolua_faction_get_messages(lua_State * L) { - faction *self = (faction *)tolua_tousertype(L, 1, NULL); + faction *f = (faction *)tolua_tousertype(L, 1, NULL); int i = 1; mlist *ml; - if (!self->msgs) { + if (!f->msgs) { return 0; } lua_newtable(L); - for (ml = self->msgs->begin; ml; ml = ml->next, ++i) { + for (ml = f->msgs->begin; ml; ml = ml->next, ++i) { lua_pushnumber(L, i); lua_pushstring(L, ml->msg->type->name); lua_rawset(L, -3); @@ -279,11 +280,11 @@ 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, NULL); + faction *f = (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; + if (f->msgs) { + mlist * ml = f->msgs->begin; while (ml) { if (strcmp(str, ml->msg->type->name) == 0) { ++n; @@ -324,9 +325,9 @@ 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, NULL); + faction *f = (faction *)tolua_tousertype(L, 1, NULL); int x = 0, y = 0; - faction_getorigin(self, 0, &x, &y); + faction_getorigin(f, 0, &x, &y); lua_pushinteger(L, x); lua_pushinteger(L, y); @@ -374,48 +375,48 @@ static int tolua_faction_create(lua_State * L) static int tolua_faction_get_password(lua_State * L) { - faction *self = (faction *)tolua_tousertype(L, 1, NULL); - tolua_pushstring(L, faction_getpassword(self)); + faction *f = (faction *)tolua_tousertype(L, 1, NULL); + tolua_pushstring(L, faction_getpassword(f)); return 1; } static int tolua_faction_set_password(lua_State * L) { - faction *self = (faction *)tolua_tousertype(L, 1, NULL); + faction *f = (faction *)tolua_tousertype(L, 1, NULL); const char * passw = tolua_tostring(L, 2, NULL); - faction_setpassword(self, + faction_setpassword(f, passw ? password_hash(passw, PASSWORD_DEFAULT) : NULL); return 0; } static int tolua_faction_get_email(lua_State * L) { - faction *self = (faction *)tolua_tousertype(L, 1, NULL); - tolua_pushstring(L, faction_getemail(self)); + faction *f = (faction *)tolua_tousertype(L, 1, NULL); + tolua_pushstring(L, faction_getemail(f)); return 1; } static int tolua_faction_set_email(lua_State * L) { - faction *self = (faction *)tolua_tousertype(L, 1, NULL); - faction_setemail(self, tolua_tostring(L, 2, NULL)); + faction *f = (faction *)tolua_tousertype(L, 1, NULL); + faction_setemail(f, tolua_tostring(L, 2, NULL)); return 0; } static int tolua_faction_get_locale(lua_State * L) { - faction *self = (faction *)tolua_tousertype(L, 1, NULL); - tolua_pushstring(L, locale_name(self->locale)); + faction *f = (faction *)tolua_tousertype(L, 1, NULL); + tolua_pushstring(L, locale_name(f->locale)); return 1; } static int tolua_faction_set_locale(lua_State * L) { - faction *self = (faction *)tolua_tousertype(L, 1, NULL); + faction *f = (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; + f->locale = loc; } else { tolua_pushstring(L, "invalid locale"); @@ -426,18 +427,18 @@ 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, NULL); - tolua_pushstring(L, self->race->_name); + faction *f = (faction *)tolua_tousertype(L, 1, NULL); + tolua_pushstring(L, f->race->_name); return 1; } static int tolua_faction_set_race(lua_State * L) { - faction *self = (faction *)tolua_tousertype(L, 1, NULL); + faction *f = (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; + f->race = rc; } return 0; @@ -445,15 +446,15 @@ 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, NULL); - tolua_pushstring(L, faction_getname(self)); + faction *f = (faction *)tolua_tousertype(L, 1, NULL); + tolua_pushstring(L, faction_getname(f)); return 1; } static int tolua_faction_set_name(lua_State * L) { - faction *self = (faction *)tolua_tousertype(L, 1, NULL); - faction_setname(self, tolua_tostring(L, 2, NULL)); + faction *f = (faction *)tolua_tousertype(L, 1, NULL); + faction_setname(f, tolua_tostring(L, 2, NULL)); return 0; } @@ -473,44 +474,78 @@ static int tolua_faction_set_uid(lua_State * L) static int tolua_faction_get_info(lua_State * L) { - faction *self = (faction *)tolua_tousertype(L, 1, NULL); - tolua_pushstring(L, faction_getbanner(self)); + faction *f = (faction *)tolua_tousertype(L, 1, NULL); + tolua_pushstring(L, faction_getbanner(f)); return 1; } static int tolua_faction_set_info(lua_State * L) { - faction *self = (faction *)tolua_tousertype(L, 1, NULL); - faction_setbanner(self, tolua_tostring(L, 2, NULL)); + faction *f = (faction *)tolua_tousertype(L, 1, NULL); + faction_setbanner(f, tolua_tostring(L, 2, NULL)); return 0; } -static int tolua_faction_get_alliance(lua_State * L) +static int tolua_faction_set_ally(lua_State * L) { - faction *self = (faction *)tolua_tousertype(L, 1, NULL); - tolua_pushusertype(L, f_get_alliance(self), TOLUA_CAST "alliance"); + faction *f1 = (faction *)tolua_tousertype(L, 1, NULL); + faction *f2 = (faction *)tolua_tousertype(L, 2, NULL); + const char *status = tolua_tostring(L, 3, NULL); + bool value = tolua_toboolean(L, 4, 1); + if (status) { + int flag = ally_status(status); + int flags = ally_get(f1->allies, f2); + if (value) { + flags |= flag; + } + else { + flags &= ~flag; + } + ally_set(&f1->allies, f2, flags); + } + return 0; +} + +static int tolua_faction_get_ally(lua_State * L) +{ + faction *f1 = (faction *)tolua_tousertype(L, 1, NULL); + faction *f2 = (faction *)tolua_tousertype(L, 2, NULL); + const char *status = tolua_tostring(L, 3, NULL); + if (f1 && f2 && status) { + int test = ally_status(status); + int flags = ally_get(f1->allies, f2); + lua_pushboolean(L, (test & flags) == test); + return 1; + } + return 0; +} + +static int tolua_faction_get_alliances(lua_State * L) +{ + faction *f = (faction *)tolua_tousertype(L, 1, NULL); + tolua_pushusertype(L, f_get_alliance(f), TOLUA_CAST "alliance"); return 1; } static int tolua_faction_set_alliance(lua_State * L) { - struct faction *self = (struct faction *)tolua_tousertype(L, 1, NULL); + struct faction *f = (struct faction *)tolua_tousertype(L, 1, NULL); struct alliance *alli = (struct alliance *) tolua_tousertype(L, 2, NULL); - setalliance(self, alli); + setalliance(f, alli); return 0; } static int tolua_faction_get_items(lua_State * L) { - faction *self = (faction *)tolua_tousertype(L, 1, NULL); + faction *f = (faction *)tolua_tousertype(L, 1, NULL); item **item_ptr = (item **)lua_newuserdata(L, sizeof(item *)); luaL_getmetatable(L, TOLUA_CAST "item"); lua_setmetatable(L, -2); - *item_ptr = self->items; + *item_ptr = f->items; lua_pushcclosure(L, tolua_itemlist_next, 1); @@ -519,8 +554,8 @@ static int tolua_faction_get_items(lua_State * L) static int tolua_faction_tostring(lua_State * L) { - faction *self = (faction *)tolua_tousertype(L, 1, NULL); - lua_pushstring(L, factionname(self)); + faction *f = (faction *)tolua_tousertype(L, 1, NULL); + lua_pushstring(L, factionname(f)); return 1; } @@ -563,8 +598,6 @@ void tolua_faction_open(lua_State * L) tolua_faction_set_locale); tolua_variable(L, TOLUA_CAST "race", tolua_faction_get_race, tolua_faction_set_race); - tolua_variable(L, TOLUA_CAST "alliance", tolua_faction_get_alliance, - tolua_faction_set_alliance); tolua_variable(L, TOLUA_CAST "score", tolua_faction_get_score, NULL); tolua_variable(L, TOLUA_CAST "magic", tolua_faction_get_magic, tolua_faction_set_magic); @@ -576,6 +609,12 @@ void tolua_faction_open(lua_State * L) tolua_variable(L, TOLUA_CAST "lastturn", tolua_faction_get_lastturn, tolua_faction_set_lastturn); + tolua_variable(L, TOLUA_CAST "alliance", tolua_faction_get_alliances, + tolua_faction_set_alliance); + + tolua_function(L, TOLUA_CAST "set_ally", tolua_faction_set_ally); + tolua_function(L, TOLUA_CAST "get_ally", tolua_faction_get_ally); + tolua_function(L, TOLUA_CAST "get_origin", tolua_faction_get_origin); tolua_function(L, TOLUA_CAST "set_origin", tolua_faction_set_origin); tolua_function(L, TOLUA_CAST "normalize", tolua_faction_normalize); diff --git a/src/kernel/ally.c b/src/kernel/ally.c index 5ecf728bc..4576a732b 100644 --- a/src/kernel/ally.c +++ b/src/kernel/ally.c @@ -185,6 +185,29 @@ static int ally_flag(const char *s, int help_mask) return 0; } +int ally_status(const char *s) +{ + if (strcmp(s, "give") == 0) { + return HELP_GIVE; + } + else if (strcmp(s, "fight") == 0) { + return HELP_FIGHT; + } + else if (strcmp(s, "money") == 0) { + return HELP_MONEY; + } + else if (strcmp(s, "travel") == 0) { + return HELP_TRAVEL; + } + else if (strcmp(s, "guard") == 0) { + return HELP_GUARD; + } + else if (strcmp(s, "all") == 0) { + return HELP_ALL; + } + return 0; +} + /** Specifies automatic alliance modes. * If this returns a value then the bits set are immutable between alliance * partners (faction::alliance) and cannot be changed with the HELP command. diff --git a/src/kernel/ally.h b/src/kernel/ally.h index 3d9058bc4..79863d51f 100644 --- a/src/kernel/ally.h +++ b/src/kernel/ally.h @@ -32,6 +32,7 @@ struct allies; extern struct attrib_type at_npcfaction; +int ally_status(const char *s); int ally_get(struct allies *al, const struct faction *f); void ally_set(struct allies **p_al, struct faction *f, int status); void write_allies(struct gamedata * data, const struct allies *alist);