From 0bdb05270e4a0a72c7b6bcc410a3944d60d8f1f2 Mon Sep 17 00:00:00 2001 From: Enno Rehling Date: Wed, 3 Jun 2009 21:56:57 +0000 Subject: [PATCH] limiting items to specific races --- src/common/kernel/battle.c | 23 +++++++++++++++++------ src/common/kernel/item.h | 1 + src/common/kernel/xmlreader.c | 4 +++- src/eressea/tolua/helpers.c | 32 ++++++++++++++++++++++++++++++++ 4 files changed, 53 insertions(+), 7 deletions(-) diff --git a/src/common/kernel/battle.c b/src/common/kernel/battle.c index 7d3b8c400..42f7d3bd0 100644 --- a/src/common/kernel/battle.c +++ b/src/common/kernel/battle.c @@ -636,6 +636,14 @@ select_weapon(const troop t, boolean attacking, boolean ismissile) return preferred_weapon(t, attacking); } +static boolean can_use(const unit * u, const weapon_type * wtype) +{ + if (wtype->itype->canuse) { + return wtype->itype->canuse(u, wtype->itype); + } + return true; +} + static int weapon_skill(const weapon_type * wtype, const unit * u, boolean attacking) /* the 'pure' skill when using this weapon to attack or defend. @@ -648,7 +656,7 @@ weapon_skill(const weapon_type * wtype, const unit * u, boolean attacking) skill = effskill(u, SK_WEAPONLESS); if (skill<=0) { /* wenn kein waffenloser kampf, dann den rassen-defaultwert */ - if(u->race == new_race[RC_URUK]) { + if (u->race == new_race[RC_URUK]) { int sword = effskill(u, SK_MELEE); int spear = effskill(u, SK_SPEAR); skill = MAX(sword, spear) - 3; @@ -680,10 +688,11 @@ weapon_skill(const weapon_type * wtype, const unit * u, boolean attacking) } } else { /* changed: if we own a weapon, we have at least a skill of 0 */ + if (!can_use(u, wtype)) return -1; skill = effskill(u, wtype->skill); if (skill < wtype->minskill) skill = 0; if (skill > 0) { - if(attacking) { + if (attacking) { skill += u->race->at_bonus; } else { skill += u->race->df_bonus; @@ -3220,10 +3229,12 @@ make_fighter(battle * b, unit * u, side * s1, boolean attack) if (wtype==NULL || itm->number==0) continue; weapons[w].attackskill = weapon_skill(wtype, u, true); weapons[w].defenseskill = weapon_skill(wtype, u, false); - weapons[w].type = wtype; - weapons[w].used = 0; - weapons[w].count = itm->number; - ++w; + if (weapons[w].attackskill>=0 || weapons[w].defenseskill>=0) { + weapons[w].type = wtype; + weapons[w].used = 0; + weapons[w].count = itm->number; + ++w; + } assert(w!=WMAX); } fig->weapons = calloc(sizeof(weapon), w+1); diff --git a/src/common/kernel/item.h b/src/common/kernel/item.h index 73eed6380..52b24447d 100644 --- a/src/common/kernel/item.h +++ b/src/common/kernel/item.h @@ -127,6 +127,7 @@ typedef struct item_type { int capacity; struct construction * construction; /* --- functions --- */ + int (*canuse)(const struct unit * user, const struct item_type * itype); int (*use)(struct unit * user, const struct item_type * itype, int amount, struct order * ord); int (*useonother)(struct unit * user, int targetno, const struct item_type * itype, int amount, struct order * ord); int (*give)(struct unit * src, struct unit * dest, const struct item_type * itm, int number, struct order * ord); diff --git a/src/common/kernel/xmlreader.c b/src/common/kernel/xmlreader.c index af50dc520..ca8120419 100644 --- a/src/common/kernel/xmlreader.c +++ b/src/common/kernel/xmlreader.c @@ -862,8 +862,10 @@ xml_readitem(xmlXPathContextPtr xpath, resource_type * rtype) itype->give = (int (*)(struct unit*, struct unit*, const struct item_type *, int, struct order *))fun; } else if (strcmp((const char*)propValue, "use")==0) { itype->use = (int (*)(struct unit *, const struct item_type *, int, struct order *))fun; + } else if (strcmp((const char*)propValue, "canuse")==0) { + itype->canuse = (int (*)(const struct unit *, const struct item_type *))fun; } else if (strcmp((const char*)propValue, "useonother")==0) { - itype->useonother = (int (*)(struct unit *, int targetno, const struct item_type *, int, struct order *))fun; + itype->useonother = (int (*)(struct unit *, int, const struct item_type *, int, struct order *))fun; } else { log_error(("unknown function type '%s' for item '%s'\n", (const char*)propValue, rtype->_name[0])); diff --git a/src/eressea/tolua/helpers.c b/src/eressea/tolua/helpers.c index 5e5df8d88..edca1aeff 100644 --- a/src/eressea/tolua/helpers.c +++ b/src/eressea/tolua/helpers.c @@ -313,6 +313,37 @@ lua_getresource(unit * u, const struct resource_type * rtype) return result; } +static int +lua_canuse_item(const unit * u, const struct item_type * itype) +{ + lua_State * L = (lua_State *)global.vm_state; + int result = -1; + const char * fname = "item_canuse"; + + lua_pushstring(L, fname); + lua_rawget(L, LUA_GLOBALSINDEX); + if (lua_isfunction(L, 1)) { + tolua_pushusertype(L, (void *)u, "unit"); + tolua_pushstring(L, itype->rtype->_name[0]); + + if (lua_pcall(L, 2, 1, 0)!=0) { + const char* error = lua_tostring(L, -1); + log_error(("get(%s) calling '%s': %s.\n", + unitname(u), fname, error)); + lua_pop(L, 1); + } else { + result = lua_toboolean(L, -1); + lua_pop(L, 1); + } + } else { + log_error(("get(%s) calling '%s': not a function.\n", + unitname(u), fname)); + lua_pop(L, 1); + } + + return result; +} + static int lua_wage(const region * r, const faction * f, const race * rc) { @@ -505,6 +536,7 @@ register_tolua_helpers(void) register_function((pf_generic)&lua_initfamiliar, "lua_initfamiliar"); register_item_use(&lua_useitem, "lua_useitem"); register_function((pf_generic)&lua_getresource, "lua_getresource"); + register_function((pf_generic)&lua_canuse_item, "lua_canuse_item"); register_function((pf_generic)&lua_changeresource, "lua_changeresource"); register_function((pf_generic)&lua_equipmentcallback, "lua_equip");