diff --git a/src/combined/gamecode.c b/src/combined/gamecode.c index 64252598c..6be4f6e20 100644 --- a/src/combined/gamecode.c +++ b/src/combined/gamecode.c @@ -12,6 +12,7 @@ #include "eressea/tolua/bind_message.c" #include "eressea/tolua/bind_hashtable.c" #include "eressea/tolua/bind_gmtool.c" +#include "eressea/tolua/bind_storage.c" #include "eressea/tolua/helpers.c" #endif diff --git a/src/common/kernel/eressea.c b/src/common/kernel/eressea.c index 9bc46ec18..8a611b186 100644 --- a/src/common/kernel/eressea.c +++ b/src/common/kernel/eressea.c @@ -211,6 +211,17 @@ HelpMask(void) * if this returns a non-zero value, then you cannot give those modes to a * faction unless they are in the same alliance. */ +int +HelpMask(void) +{ + static int help_mask = 0; + + if (help_mask==0) { + help_mask = get_param_int(global.parameters, "rules.help.mask", HELP_ALL); + } + return help_mask; +} + int AllianceRestricted(void) { diff --git a/src/common/kernel/item.c b/src/common/kernel/item.c index 23a0c9a77..17f1f311a 100644 --- a/src/common/kernel/item.c +++ b/src/common/kernel/item.c @@ -736,6 +736,14 @@ mod_elves_only(const unit * u, const region * r, skill_t sk, int value) return -118; } +static int +mod_dwarves_only(const unit * u, const region * r, skill_t sk, int value) +{ + if (u->race == new_race[RC_DWARF]) return value; + unused(r); + return -118; +} + static void init_olditems(void) { @@ -1159,6 +1167,7 @@ void register_resources(void) { register_function((pf_generic)mod_elves_only, "mod_elves_only"); + register_function((pf_generic)mod_dwarves_only, "mod_dwarves_only"); register_function((pf_generic)res_changeitem, "changeitem"); register_function((pf_generic)res_changeperson, "changeperson"); register_function((pf_generic)res_changepeasants, "changepeasants"); diff --git a/src/common/kernel/magic.c b/src/common/kernel/magic.c index ead7de5e4..b56504569 100644 --- a/src/common/kernel/magic.c +++ b/src/common/kernel/magic.c @@ -2159,7 +2159,7 @@ is_familiar(const unit *u) } static void -write_unit(const attrib * a, struct storage * store) +a_write_unit(const attrib * a, struct storage * store) { unit * u = (unit*)a->data.v; write_unit_reference(u, store); @@ -2418,7 +2418,7 @@ attrib_type at_familiarmage = { NULL, NULL, age_unit, - write_unit, + a_write_unit, read_magician, ATF_UNIQUE }; @@ -2428,7 +2428,7 @@ attrib_type at_familiar = { NULL, NULL, age_unit, - write_unit, + a_write_unit, read_familiar, ATF_UNIQUE }; @@ -2438,7 +2438,7 @@ attrib_type at_clonemage = { NULL, NULL, age_unit, - write_unit, + a_write_unit, read_magician, ATF_UNIQUE }; @@ -2448,7 +2448,7 @@ attrib_type at_clone = { NULL, NULL, age_unit, - write_unit, + a_write_unit, read_clone, ATF_UNIQUE }; diff --git a/src/common/kernel/save.c b/src/common/kernel/save.c index 8b59d9d27..17b1e40fc 100644 --- a/src/common/kernel/save.c +++ b/src/common/kernel/save.c @@ -646,7 +646,7 @@ writeorder(struct storage * store, const struct order * ord, const struct locale } unit * -readunit(struct storage * store) +read_unit(struct storage * store) { skill_t sk; unit * u; @@ -815,7 +815,7 @@ readunit(struct storage * store) } void -writeunit(struct storage * store, const unit * u) +write_unit(struct storage * store, const unit * u) { order * ord; int i, p = 0; @@ -1521,7 +1521,7 @@ readgame(const char * filename, int mode, int backup) up = &r->units; while (--p >= 0) { - unit * u = readunit(store); + unit * u = read_unit(store); sc_mage * mage; assert(u->region==NULL); @@ -1718,7 +1718,7 @@ writegame(const char *filename, int mode) store->w_int(store, listlen(r->units)); store->w_brk(store); for (u = r->units; u; u = u->next) { - writeunit(store, u); + write_unit(store, u); } } store->w_brk(store); diff --git a/src/common/kernel/save.h b/src/common/kernel/save.h index b4e731bbe..a0565184f 100644 --- a/src/common/kernel/save.h +++ b/src/common/kernel/save.h @@ -41,13 +41,6 @@ int writegame(const char *filename, int mode); extern void rsf(FILE * F, char *s, size_t len); -#define IO_READ 0x01 -#define IO_WRITE 0x02 -#define IO_BINARY 0x04 -#define IO_TEXT 0x08 - -#define IO_DEFAULT IO_BINARY - /* Versionsänderungen: */ extern int data_version; extern const char *xmlfile; @@ -59,6 +52,9 @@ extern int lastturn(void); extern void read_items(struct storage * store, struct item **it); extern void write_items(struct storage * store, struct item *it); +extern void write_unit(struct storage * store, const struct unit * u); +extern struct unit * read_unit(struct storage * store); + extern const char * datapath(void); extern int a_readint(struct attrib * a, struct storage * store); diff --git a/src/common/kernel/unit.c b/src/common/kernel/unit.c index ef51d0be4..fe3bcfb0c 100644 --- a/src/common/kernel/unit.c +++ b/src/common/kernel/unit.c @@ -1427,7 +1427,7 @@ create_unit(region * r, faction * f, int number, const struct race *urace, int i /* zuerst in die Region setzen, da zb Drachennamen den Regionsnamen * enthalten */ - move_unit(u, r, NULL); + if (r) move_unit(u, r, NULL); /* u->race muss bereits gesetzt sein, wird für default-hp gebraucht */ /* u->region auch */ diff --git a/src/common/util/storage.h b/src/common/util/storage.h index 998b3e113..686d3f0f9 100644 --- a/src/common/util/storage.h +++ b/src/common/util/storage.h @@ -33,6 +33,12 @@ typedef struct storage { void * userdata; } storage; +#define IO_READ 0x01 +#define IO_WRITE 0x02 +#define IO_BINARY 0x04 +#define IO_TEXT 0x08 +#define IO_DEFAULT IO_BINARY + #ifdef __cplusplus } #endif diff --git a/src/eressea.vcproj b/src/eressea.vcproj index f58ae52db..5517598ff 100644 --- a/src/eressea.vcproj +++ b/src/eressea.vcproj @@ -67,7 +67,7 @@ /> + + + + diff --git a/src/eressea/gmtool.c b/src/eressea/gmtool.c index 48894877b..ccc6944ae 100644 --- a/src/eressea/gmtool.c +++ b/src/eressea/gmtool.c @@ -57,6 +57,7 @@ #include #include +#include #include diff --git a/src/eressea/server.c b/src/eressea/server.c index c04964e72..06f411b54 100644 --- a/src/eressea/server.c +++ b/src/eressea/server.c @@ -111,6 +111,7 @@ #include "tolua/bind_building.h" #include "tolua/bind_region.h" #include "tolua/bind_gmtool.h" +#include "tolua/bind_storage.h" #endif // BINDINGS_TOLUA #ifdef BINDINGS_LUABIND @@ -301,6 +302,7 @@ lua_init(void) tolua_message_open(L); tolua_hashtable_open(L); tolua_gmtool_open(L); + tolua_storage_open(L); #endif #ifdef BINDINGS_LUABIND diff --git a/src/eressea/tolua/bind_faction.c b/src/eressea/tolua/bind_faction.c index aaa8647eb..ad5c581e2 100644 --- a/src/eressea/tolua/bind_faction.c +++ b/src/eressea/tolua/bind_faction.c @@ -116,6 +116,20 @@ tolua_faction_get_id(lua_State* tolua_S) return 1; } +static int +tolua_faction_set_id(lua_State* tolua_S) +{ + faction * self = (faction *)tolua_tousertype(tolua_S, 1, 0); + int id = (int)tolua_tonumber(tolua_S, 2, 0); + if (findfaction(id)==NULL) { + renumber_faction(self, id); + lua_pushboolean(tolua_S, 1); + } else { + lua_pushboolean(tolua_S, 0); + } + return 1; +} + static int tolua_faction_get_age(lua_State* tolua_S) { @@ -436,7 +450,7 @@ tolua_faction_open(lua_State* tolua_S) tolua_variable(tolua_S, "race", tolua_faction_get_race, tolua_faction_set_race); tolua_variable(tolua_S, "alliance", tolua_faction_get_alliance, tolua_faction_set_alliance); tolua_variable(tolua_S, "score", tolua_faction_get_score, NULL); - tolua_variable(tolua_S, "id", tolua_faction_get_id, NULL); + tolua_variable(tolua_S, "id", tolua_faction_get_id, tolua_faction_set_id); tolua_variable(tolua_S, "age", tolua_faction_get_age, tolua_faction_set_age); tolua_variable(tolua_S, "options", tolua_faction_get_options, NULL); tolua_variable(tolua_S, "flags", tolua_faction_get_flags, NULL); diff --git a/src/eressea/tolua/bind_ship.c b/src/eressea/tolua/bind_ship.c index 9098836a2..624b94ce3 100644 --- a/src/eressea/tolua/bind_ship.c +++ b/src/eressea/tolua/bind_ship.c @@ -51,6 +51,26 @@ static int tolua_ship_get_name(lua_State* tolua_S) return 1; } +static int tolua_ship_get_region(lua_State* tolua_S) +{ + ship* self = (ship*) tolua_tousertype(tolua_S, 1, 0); + if (self) { + tolua_pushusertype(tolua_S, self->region, "region"); + return 1; + } + return 0; +} + +static int tolua_ship_set_region(lua_State* tolua_S) +{ + ship* self = (ship*) tolua_tousertype(tolua_S, 1, 0); + region * r = (region*) tolua_tousertype(tolua_S, 1, 0); + if (self) { + move_ship(self, self->region, r, NULL); + } + return 0; +} + static int tolua_ship_set_name(lua_State* tolua_S) { ship* self = (ship*)tolua_tousertype(tolua_S, 1, 0); @@ -119,6 +139,7 @@ tolua_ship_open(lua_State* tolua_S) tolua_variable(tolua_S, "id", tolua_ship_get_id, NULL); tolua_variable(tolua_S, "name", tolua_ship_get_name, tolua_ship_set_name); tolua_variable(tolua_S, "units", tolua_ship_get_units, NULL); + tolua_variable(tolua_S, "region", tolua_ship_get_region, tolua_ship_set_region); #ifdef TODO .property("type", &ship_gettype) .property("weight", &ship_getweight) diff --git a/src/eressea/tolua/bind_storage.c b/src/eressea/tolua/bind_storage.c new file mode 100644 index 000000000..d4494b19c --- /dev/null +++ b/src/eressea/tolua/bind_storage.c @@ -0,0 +1,143 @@ +/* vi: set ts=2: ++-------------------+ +| | Enno Rehling +| Eressea PBEM host | Christian Schlittchen +| (c) 1998 - 2008 | Katja Zedel +| | Henning Peters ++-------------------+ + +This program may not be used, modified or distributed +without prior permission by the authors of Eressea. +*/ + +#include +#include "bind_storage.h" + +#include +#include +#include +#include + +#include + +#include +#include + + +static int +tolua_storage_create(lua_State* tolua_S) +{ + const char * filename = tolua_tostring(tolua_S, 1, 0); + const char * type = tolua_tostring(tolua_S, 2, "rb"); + storage * store = 0; + int mode = IO_READ; + if (strchr(type, 't')) { + store = malloc(sizeof(text_store)); + memcpy(store, &text_store, sizeof(text_store)); + } else { + store = malloc(sizeof(binary_store)); + memcpy(store, &binary_store, sizeof(binary_store)); + } + if (strchr(type, 'r')) mode = IO_READ; + if (strchr(type, 'w')) mode = IO_WRITE; + store->open(store, filename, mode); + tolua_pushusertype(tolua_S, (void*)store, "storage"); + return 1; +} + +static int +tolua_storage_read_unit(lua_State *tolua_S) +{ + storage * self = (storage *)tolua_tousertype(tolua_S, 1, 0); + struct unit * u = read_unit(self); + tolua_pushusertype(tolua_S, (void*)u, "unit"); + return 1; +} + +static int +tolua_storage_write_unit(lua_State *tolua_S) +{ + storage * self = (storage *)tolua_tousertype(tolua_S, 1, 0); + struct unit * u = (struct unit *)tolua_tousertype(tolua_S, 2, 0); + write_unit(self, u); + return 0; +} + + +static int +tolua_storage_read_float(lua_State *tolua_S) +{ + storage * self = (storage *)tolua_tousertype(tolua_S, 1, 0); + float num = self->r_flt(self); + tolua_pushnumber(tolua_S, (lua_Number)num); + return 1; +} + +static int +tolua_storage_read_int(lua_State *tolua_S) +{ + storage * self = (storage *)tolua_tousertype(tolua_S, 1, 0); + int num = self->r_int(self); + tolua_pushnumber(tolua_S, (lua_Number)num); + return 1; +} + +static int +tolua_storage_write(lua_State *tolua_S) +{ + storage * self = (storage *)tolua_tousertype(tolua_S, 1, 0); + if (tolua_isnumber(tolua_S, 2, 0, 0)) { + lua_Number num = tolua_tonumber(tolua_S, 2, 0); + double n; + if (modf(num, &n)==0.0) { + self->w_int(self, (int)num); + } else { + self->w_flt(self, (float)num); + } + } + return 0; +} + +static int +tolua_storage_tostring(lua_State *tolua_S) +{ + storage * self = (storage *)tolua_tousertype(tolua_S, 1, 0); + char name[64]; + snprintf(name, sizeof(name), "", self->encoding, self->version); + lua_pushstring(tolua_S, name); + return 1; +} + +static int +tolua_storage_close(lua_State *tolua_S) +{ + storage * self = (storage *)tolua_tousertype(tolua_S, 1, 0); + self->close(self); + return 0; +} + +void +tolua_storage_open(lua_State* tolua_S) +{ + /* register user types */ + tolua_usertype(tolua_S, "storage"); + + tolua_module(tolua_S, NULL, 0); + tolua_beginmodule(tolua_S, NULL); + { + tolua_cclass(tolua_S, "storage", "storage", "", NULL); + tolua_beginmodule(tolua_S, "storage"); + { + tolua_function(tolua_S, "__tostring", tolua_storage_tostring); + tolua_function(tolua_S, "write", tolua_storage_write); + tolua_function(tolua_S, "read_int", tolua_storage_read_int); + tolua_function(tolua_S, "read_float", tolua_storage_read_float); + tolua_function(tolua_S, "write_unit", tolua_storage_write_unit); + tolua_function(tolua_S, "read_unit", tolua_storage_read_unit); + tolua_function(tolua_S, "close", tolua_storage_close); + tolua_function(tolua_S, "create", tolua_storage_create); + } + tolua_endmodule(tolua_S); + } + tolua_endmodule(tolua_S); +} diff --git a/src/eressea/tolua/bind_storage.h b/src/eressea/tolua/bind_storage.h new file mode 100644 index 000000000..99a969420 --- /dev/null +++ b/src/eressea/tolua/bind_storage.h @@ -0,0 +1,22 @@ +/* vi: set ts=2: ++-------------------+ +| | Enno Rehling +| Eressea PBEM host | Christian Schlittchen +| (c) 1998 - 2008 | Katja Zedel +| | Henning Peters ++-------------------+ + +This program may not be used, modified or distributed +without prior permission by the authors of Eressea. +*/ + +#ifdef __cplusplus +extern "C" { +#endif + + struct lua_State; + void tolua_storage_open(struct lua_State *tolua_S); + +#ifdef __cplusplus +} +#endif diff --git a/src/eressea/tolua/bindings.c b/src/eressea/tolua/bindings.c index 8e260ccb9..217524fc5 100644 --- a/src/eressea/tolua/bindings.c +++ b/src/eressea/tolua/bindings.c @@ -53,6 +53,7 @@ without prior permission by the authors of Eressea. #include #include #include +#include #include #include diff --git a/src/res/buildings.xml b/src/res/buildings.xml index d2546fb0e..7c284e740 100644 --- a/src/res/buildings.xml +++ b/src/res/buildings.xml @@ -166,7 +166,7 @@ - + diff --git a/src/res/e2k9/items.xml b/src/res/e2k9/items.xml index c2351510a..28c53130c 100644 --- a/src/res/e2k9/items.xml +++ b/src/res/e2k9/items.xml @@ -1,6 +1,16 @@ + + + + + + + + + + diff --git a/src/res/messages.xml b/src/res/messages.xml index 55f37f1ec..b411b3bf6 100644 --- a/src/res/messages.xml +++ b/src/res/messages.xml @@ -868,7 +868,7 @@ "Auf dem Markt werden $resource($product,0) und $resource($herb,0) feilgeboten." - "The local market offers $resource($product,0) and $resource($herb,0)." + "The local market offers $resource($product,0) and $resource($herb,0)." diff --git a/src/scripts/tests.lua b/src/scripts/tests.lua index 115057a13..874566d0b 100644 --- a/src/scripts/tests.lua +++ b/src/scripts/tests.lua @@ -345,6 +345,30 @@ local function spells_csv() fail = 1 end +function test_storage() + free_game() + local r = region.create(0, 0, "plain") + local f = faction.create("enno@eressea.de", "human", "de") + f.id = 42 + local u = unit.create(f, r, 1) + u:add_item("money", u.number * 100) + store = storage.create("test.unit.dat", "wb") + assert(store) + store:write_unit(u) + store:close() + free_game() + -- recreate world: + r = region.create(0, 0, "plain") + f = faction.create("enno@eressea.de", "human", "de") + f.id = 42 + store = storage.create("test.unit.dat", "rb") + assert(store) + u = store:read_unit() + store:close() + assert(u) + assert(u:get_item("money") == u.number * 100) +end + loadscript("extensions.lua") tests = { ["alliance"] = test_alliance, @@ -364,9 +388,10 @@ tests = { ["spells"] = test_spells } mytests = { + ["storage"] = test_storage } fail = 0 -for k, v in pairs(tests) do +for k, v in pairs(mytests) do local status, err = pcall(v) if not status then fail = fail + 1