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);