diff --git a/src/common/gamecode/gamecode.vcproj b/src/common/gamecode/gamecode.vcproj
index ce854f405..94e793854 100644
--- a/src/common/gamecode/gamecode.vcproj
+++ b/src/common/gamecode/gamecode.vcproj
@@ -196,13 +196,6 @@
RelativePath=".\randenc.h">
-
-
-
-
diff --git a/src/common/gamecode/laws.c b/src/common/gamecode/laws.c
index 4b956c977..4babdbbe3 100644
--- a/src/common/gamecode/laws.c
+++ b/src/common/gamecode/laws.c
@@ -3349,77 +3349,75 @@ canheal(const unit *u)
static void
monthly_healing(void)
{
- region *r;
- unit *u;
- int p;
- int healingcurse = 0;
- curse *c = NULL;
- static const curse_type * heal_ct;
- heal_ct = ct_find("healingzone");
+ region *r;
+ static const curse_type * heal_ct = NULL;
+ if (heal_ct==NULL) heal_ct = ct_find("healingzone");
- for (r = regions; r; r = r->next) {
- if (heal_ct) {
- /* bonus zurücksetzen */
- healingcurse = 0;
- c = get_curse(r->attribs, heal_ct);
- if (c) {
- healingcurse = curse_geteffect(c);
- }
- }
- for (u = r->units; u; u = u->next) {
- int umhp;
+ for (r = regions; r; r = r->next) {
+ unit *u;
+ int healingcurse = 0;
- umhp = unit_max_hp(u) * u->number;
+ if (heal_ct!=NULL) {
+ /* bonus zurücksetzen */
+ curse * c = get_curse(r->attribs, heal_ct);
+ if (c!=NULL) {
+ healingcurse = curse_geteffect(c);
+ }
+ }
+ for (u = r->units; u; u = u->next) {
+ int umhp = unit_max_hp(u) * u->number;
+ int p;
- /* hp über Maximum bauen sich ab. Wird zb durch Elixier der Macht
- * oder verändertes Ausdauertalent verursacht */
- if (u->hp > umhp) {
- u->hp -= (int) ceil((u->hp - umhp) / 2.0);
- if (u->hp < umhp)
- u->hp = umhp;
- }
+ /* hp über Maximum bauen sich ab. Wird zb durch Elixier der Macht
+ * oder verändertes Ausdauertalent verursacht */
+ if (u->hp > umhp) {
+ u->hp -= (int) ceil((u->hp - umhp) / 2.0);
+ if (u->hp < umhp)
+ u->hp = umhp;
+ }
- if((u->race->flags & RCF_NOHEAL) || fval(u, UFL_HUNGER) || fspecial(u->faction, FS_UNDEAD))
- continue;
+ if((u->race->flags & RCF_NOHEAL) || fval(u, UFL_HUNGER) || fspecial(u->faction, FS_UNDEAD))
+ continue;
- if(rterrain(r) == T_OCEAN && !u->ship && !(canswim(u)))
- continue;
+ if(rterrain(r) == T_OCEAN && !u->ship && !(canswim(u)))
+ continue;
- if(fspecial(u->faction, FS_REGENERATION)) {
- u->hp = umhp;
- continue;
- }
+ if(fspecial(u->faction, FS_REGENERATION)) {
+ u->hp = umhp;
+ continue;
+ }
- if (u->hp < umhp && (p=canheal(u)) > 0) {
- /* Mind 1 HP wird pro Runde geheilt, weil angenommen wird,
- das alle Personen mind. 10 HP haben. */
- int max_unit = max(umhp, u->number * 10);
+ p = canheal(u);
+ if (u->hp < umhp && p > 0) {
+ /* Mind 1 HP wird pro Runde geheilt, weil angenommen wird,
+ das alle Personen mind. 10 HP haben. */
+ int max_unit = max(umhp, u->number * 10);
#ifdef NEW_TAVERN
- struct building * b = inside_building(u);
- const struct building_type * btype = b?b->type:NULL;
- if (btype == bt_find("inn")) {
- max_unit = max_unit * 3 / 2;
- }
+ struct building * b = inside_building(u);
+ const struct building_type * btype = b?b->type:NULL;
+ if (btype == bt_find("inn")) {
+ max_unit = max_unit * 3 / 2;
+ }
#endif
- /* der healing curse verändert den Regenerationsprozentsatz.
- * Wenn dies für negative Heilung benutzt wird, kann es zu
- * negativen u->hp führen! */
- if (healingcurse != 0) {
- p += healingcurse;
- }
+ /* der healing curse verändert den Regenerationsprozentsatz.
+ * Wenn dies für negative Heilung benutzt wird, kann es zu
+ * negativen u->hp führen! */
+ if (healingcurse != 0) {
+ p += healingcurse;
+ }
- /* Aufaddieren der geheilten HP. */
- u->hp = min(u->hp + max_unit*p/100, umhp);
- if (u->hp < umhp && (rand() % 10 < max_unit % 10)){
- ++u->hp;
- }
- /* soll man an negativer regeneration sterben können? */
- if (u->hp <= 0){
- u->hp = 1;
- }
- }
- }
- }
+ /* Aufaddieren der geheilten HP. */
+ u->hp = min(u->hp + max_unit*p/100, umhp);
+ if (u->hp < umhp && (rand() % 10 < max_unit % 10)){
+ ++u->hp;
+ }
+ /* soll man an negativer regeneration sterben können? */
+ if (u->hp <= 0){
+ u->hp = 1;
+ }
+ }
+ }
+ }
}
static void
@@ -3518,7 +3516,8 @@ use(void)
itype = finditemtype(t, u->faction->locale);
if (itype!=NULL) {
- use_item(u, itype, n, S->s);
+ int i = use_item(u, itype, n, S->s);
+ assert(i<=0);
} else {
cmistake(u, S->s, 43, MSG_PRODUCE);
}
diff --git a/src/common/kernel/combatspells.c b/src/common/kernel/combatspells.c
index fc9d12b03..1d6eeceed 100644
--- a/src/common/kernel/combatspells.c
+++ b/src/common/kernel/combatspells.c
@@ -1580,15 +1580,15 @@ sp_reanimate(fighter * fi, int level, double power, spell * sp)
int
sp_keeploot(fighter * fi, int level, double power, spell * sp)
{
- battle *b = fi->side->battle;
+ battle *b = fi->side->battle;
- sprintf(buf, "%s zaubert %s.", unitname(fi->unit),
- spell_name(sp, default_locale));
- battlerecord(b, buf);
+ sprintf(buf, "%s zaubert %s.", unitname(fi->unit),
+ spell_name(sp, default_locale));
+ battlerecord(b, buf);
- b->keeploot = (int)max(50, b->keeploot + 5*power);
+ b->keeploot = (int)max(25, b->keeploot + 5*power);
- return level;
+ return level;
}
int
diff --git a/src/common/kernel/item.c b/src/common/kernel/item.c
index 2cdb3f366..3ca67e78a 100644
--- a/src/common/kernel/item.c
+++ b/src/common/kernel/item.c
@@ -2296,30 +2296,55 @@ attrib_type at_showitem = {
static local_names * inames;
+void
+init_itemnames(void)
+{
+ int i;
+ for (i=0;localenames[i];++i) {
+ const struct locale * lang = find_locale(localenames[i]);
+ const item_type * itl = itemtypes;
+ boolean exist = false;
+ local_names * in = inames;
+
+ while (in!=NULL) {
+ if (in->lang==lang) {
+ exist = true;
+ break;
+ }
+ in = in->next;
+ }
+ if (in==NULL) in = calloc(sizeof(local_names), 1);
+ in->next = inames;
+ in->lang = lang;
+ while (itl) {
+ void * result = NULL;
+ const char * iname = locale_string(lang, itl->rtype->_name[0]);
+ if (!exist || findtoken(&in->names, iname, &result)==E_TOK_NOMATCH || result!=itl) {
+ addtoken(&in->names, iname, (void*)itl);
+ addtoken(&in->names, locale_string(lang, itl->rtype->_name[1]), (void*)itl);
+ }
+ itl=itl->next;
+ }
+ inames = in;
+ }
+}
+
const item_type *
finditemtype(const char * name, const struct locale * lang)
{
- local_names * in = inames;
- void * i;
+ local_names * in = inames;
+ void * i;
- while (in) {
- if (in->lang==lang) break;
- in=in->next;
- }
- if (!in) {
- const item_type * itl = itemtypes;
- in = calloc(sizeof(local_names), 1);
- in->next = inames;
- in->lang = lang;
- while (itl) {
- addtoken(&in->names, locale_string(lang, itl->rtype->_name[0]), (void*)itl);
- addtoken(&in->names, locale_string(lang, itl->rtype->_name[1]), (void*)itl);
- itl=itl->next;
- }
- inames = in;
- }
- if (findtoken(&in->names, name, &i)==E_TOK_NOMATCH) return NULL;
- return (const item_type*)i;
+ while (in!=NULL) {
+ if (in->lang==lang) break;
+ in=in->next;
+ }
+ if (in==NULL) {
+ init_itemnames();
+ for (in=inames;in->lang!=lang;in=in->next) ;
+ }
+ if (findtoken(&in->names, name, &i)==E_TOK_NOMATCH) return NULL;
+ return (const item_type*)i;
}
static void
diff --git a/src/common/kernel/item.h b/src/common/kernel/item.h
index 5a2e2a7a5..bde8be211 100644
--- a/src/common/kernel/item.h
+++ b/src/common/kernel/item.h
@@ -137,6 +137,7 @@ typedef struct item_type {
extern item_type * itemtypes;
extern const item_type * finditemtype(const char * name, const struct locale * lang);
+extern void init_itemnames(void);
typedef struct luxury_type {
struct luxury_type * next;
diff --git a/src/eressea/Jamfile b/src/eressea/Jamfile
index 408bf5775..b933c3af3 100644
--- a/src/eressea/Jamfile
+++ b/src/eressea/Jamfile
@@ -22,6 +22,7 @@ LUASERVER_SOURCES =
ship.cpp
spell.cpp
unit.cpp
+ item.cpp
server.cpp
korrektur.c
console.c
diff --git a/src/eressea/eressea-lua.vcproj b/src/eressea/eressea-lua.vcproj
index 4d32a3c5d..445fcf743 100644
--- a/src/eressea/eressea-lua.vcproj
+++ b/src/eressea/eressea-lua.vcproj
@@ -211,6 +211,9 @@
+
+
@@ -269,6 +272,9 @@
DisableLanguageExtensions="FALSE"/>
+
+
diff --git a/src/eressea/lua/bindings.h b/src/eressea/lua/bindings.h
index 9d1fae102..1283f76ee 100644
--- a/src/eressea/lua/bindings.h
+++ b/src/eressea/lua/bindings.h
@@ -11,5 +11,6 @@ extern void bind_faction(struct lua_State * L);
extern void bind_alliance(struct lua_State * L);
extern void bind_eressea(struct lua_State * L);
extern void bind_spell(lua_State * L) ;
+extern void bind_item(struct lua_State * L);
#endif
diff --git a/src/eressea/lua/eressea.cpp b/src/eressea/lua/eressea.cpp
index c5f7f1242..8c096f03e 100644
--- a/src/eressea/lua/eressea.cpp
+++ b/src/eressea/lua/eressea.cpp
@@ -98,6 +98,13 @@ get_gamename(void)
return global.gamename;
}
+static void
+lua_setstring(const char * lname, const char * key, const char * str)
+{
+ struct locale * lang = find_locale(lname);
+ locale_setstring(lang, key, str);
+}
+
void
bind_eressea(lua_State * L)
{
@@ -113,6 +120,7 @@ bind_eressea(lua_State * L)
def("add_equipment", &lua_addequipment),
def("get_turn", &get_turn),
def("remove_empty_units", &remove_empty_units),
+ def("set_string", &lua_setstring),
def("set_flag", &set_flag),
def("get_flag", &get_flag),
diff --git a/src/eressea/lua/item.cpp b/src/eressea/lua/item.cpp
new file mode 100644
index 000000000..001093bc7
--- /dev/null
+++ b/src/eressea/lua/item.cpp
@@ -0,0 +1,62 @@
+#include
+#include
+
+// kernel includes
+#include
+#include
+#include
+
+// lua includes
+#include
+#include
+#include
+
+using namespace luabind;
+
+static int
+lua_useitem(struct unit * u, const struct item_type * itype,
+ int amount, const char *cmd)
+{
+ char fname[64];
+ lua_State * L = (lua_State *)global.vm_state;
+ int retval;
+ const char * iname = itype->rtype->_name[0];
+
+ assert(u!=NULL);
+ strcat(strcpy(fname, iname), "_use");
+
+ {
+ luabind::object globals = luabind::get_globals(L);
+ if (globals.at(fname).type()!=LUA_TFUNCTION) return -1;
+ }
+
+ retval = luabind::call_function(L, fname, *u, amount);
+ return retval;
+}
+
+static void
+item_register(const char * name, const char * appearance)
+{
+ resource_type * rtype = (resource_type *)calloc(1, sizeof(resource_type));
+ item_type * itype = (item_type *)calloc(1, sizeof(item_type));
+
+ rtype->_name[0] = strdup(name);
+ rtype->_name[1] = strcat(strcpy((char*)malloc(strlen(name)+3), name), "_p");
+ rtype->_appearance[0] = strdup(appearance);
+ rtype->_appearance[1] = strcat(strcpy((char*)malloc(strlen(appearance)+3), appearance), "_p");
+
+ itype->use = lua_useitem;
+ itype->rtype = rtype;
+
+ rt_register(rtype);
+ it_register(itype);
+ init_itemnames();
+}
+
+void
+bind_item(lua_State * L)
+{
+ module(L)[
+ def("register_item", &item_register)
+ ];
+}
diff --git a/src/eressea/server.cpp b/src/eressea/server.cpp
index c31552617..f2bb2d953 100644
--- a/src/eressea/server.cpp
+++ b/src/eressea/server.cpp
@@ -277,6 +277,7 @@ lua_init(void)
bind_alliance(luaState);
#endif
bind_region(luaState);
+ bind_item(luaState);
bind_faction(luaState);
bind_unit(luaState);
bind_ship(luaState);