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