diff --git a/res/buildings/castle-2.xml b/res/buildings/castle-2.xml index 5f48e73ee..d1d07217b 100644 --- a/res/buildings/castle-2.xml +++ b/res/buildings/castle-2.xml @@ -1,24 +1,24 @@ - + - + - + - + - + - + - + diff --git a/res/buildings/castle.xml b/res/buildings/castle.xml index 296d1f716..9758d5b64 100644 --- a/res/buildings/castle.xml +++ b/res/buildings/castle.xml @@ -1,26 +1,26 @@ - - + + - + - + - + - + - + - + diff --git a/res/e3a/buildings.xml b/res/e3a/buildings.xml index b3e59f0a4..e6513851e 100644 --- a/res/e3a/buildings.xml +++ b/res/e3a/buildings.xml @@ -5,15 +5,15 @@ - + - + - + - + diff --git a/scripts/eressea/e3/rules.lua b/scripts/eressea/e3/rules.lua index 0c5e9be85..c0ac8978a 100644 --- a/scripts/eressea/e3/rules.lua +++ b/scripts/eressea/e3/rules.lua @@ -26,10 +26,6 @@ function item_canuse(u, iname) return true end -function building_protection(b, u) - return 1 -end - function building_taxes(b, blevel) btype = b.type if btype=="castle" then diff --git a/src/battle.c b/src/battle.c index 7065ad11b..ed4354049 100644 --- a/src/battle.c +++ b/src/battle.c @@ -1901,7 +1901,7 @@ int skilldiff(troop at, troop dt, int dist) init = true; } if (df->building->type->protection) { - int beff = df->building->type->protection(df->building, du); + int beff = df->building->type->protection(df->building, du, DEFENSE_BONUS); if (beff) { skdiff -= beff; is_protected = 2; @@ -1918,7 +1918,7 @@ int skilldiff(troop at, troop dt, int dist) if (magicwalls_ct && curse_active(get_curse(df->building->attribs, magicwalls_ct))) { /* Verdoppelt Burgenbonus */ - skdiff -= buildingeffsize(df->building, false); + skdiff -= df->building->type->protection(df->building, du, DEFENSE_BONUS); } } /* Goblin-Verteidigung diff --git a/src/battle.test.c b/src/battle.test.c index e35864c12..f0b647aaf 100644 --- a/src/battle.test.c +++ b/src/battle.test.c @@ -57,7 +57,7 @@ static void test_make_fighter(CuTest * tc) test_cleanup(); } -static int add_two(building * b, unit * u) { +static int add_two(building * b, unit * u, buildingbonus bonus) { return 2; } diff --git a/src/helpers.c b/src/helpers.c index 5f0b3a12d..7c4f0371c 100644 --- a/src/helpers.c +++ b/src/helpers.c @@ -388,32 +388,6 @@ static void lua_agebuilding(building * b) } } -static int lua_building_protection(building * b, unit * u) -{ - lua_State *L = (lua_State *) global.vm_state; - const char *fname = "building_protection"; - int result = 0; - - lua_getglobal(L, fname); - if (lua_isfunction(L, -1)) { - tolua_pushusertype(L, (void *)b, TOLUA_CAST "building"); - tolua_pushusertype(L, (void *)u, TOLUA_CAST "unit"); - - if (lua_pcall(L, 2, 1, 0) != 0) { - const char *error = lua_tostring(L, -1); - log_error("building_protection(%s, %s) calling '%s': %s.\n", buildingname(b), unitname(u), fname, error); - lua_pop(L, 1); - } else { - result = (int)lua_tonumber(L, -1); - lua_pop(L, 1); - } - } else { - log_error("building_protection(%s, %s) calling '%s': not a function.\n", buildingname(b), unitname(u), fname); - lua_pop(L, 1); - } - return result; -} - static double lua_building_taxes(building * b, int level) { lua_State *L = (lua_State *) global.vm_state; diff --git a/src/kernel/build.h b/src/kernel/build.h index 4e3bbedaa..5568fb915 100644 --- a/src/kernel/build.h +++ b/src/kernel/build.h @@ -45,6 +45,9 @@ extern "C" { int maxsize; /* maximum size of this type */ int reqsize; /* size of object using up 1 set of requirement. */ + int prot; /* protection bonus (defense) during combat */ + int ccbonus; /* close combat attack bonus*/ + int rangedbonus; /* ranged attack bonus */ requirement *materials; /* material req'd to build one object */ const struct building_type *btype; /* building type required to make this thing */ diff --git a/src/kernel/building.c b/src/kernel/building.c index a382a63bf..50a892c5a 100644 --- a/src/kernel/building.c +++ b/src/kernel/building.c @@ -316,12 +316,32 @@ const building_type *findbuildingtype(const char *name, return (const building_type *)type.v; } -static int eressea_building_protection(building * b, unit * u) +static int building_protection(building * b, unit * u, buildingbonus bonus) { - int beff = buildingeffsize(b, false) - 1; - /* -1 because the tradepost has no protection value */ - return beff; + int i = 0; + int bsize = buildingeffsize(b, false); + const construction *cons = b->type->construction; + if (!cons || !cons->improvement) { + return 0; + } + + for (i = 0; i < bsize; i++) + { + cons = cons->improvement; + } + + switch (bonus) + { + case DEFENSE_BONUS: + return cons->prot; + case CC_ATTACK_BONUS: + return cons->ccbonus; + case RANGED_ATTACK_BONUS: + return cons->rangedbonus; + default: + return 0; + } } static int meropis_building_protection(building * b, unit * u) @@ -331,8 +351,8 @@ static int meropis_building_protection(building * b, unit * u) void register_buildings(void) { - register_function((pf_generic)& eressea_building_protection, - "eressea_building_protection"); + register_function((pf_generic)& building_protection, + "building_protection"); register_function((pf_generic)& meropis_building_protection, "meropis_building_protection"); register_function((pf_generic)& init_smithy, "init_smithy"); diff --git a/src/kernel/building.h b/src/kernel/building.h index cf80de84f..a74e30c3c 100644 --- a/src/kernel/building.h +++ b/src/kernel/building.h @@ -48,6 +48,12 @@ extern "C" { #define BTF_ONEPERTURN 0x80 /* one one sizepoint can be added per turn */ #define BTF_NAMECHANGE 0x100 /* name and description can be changed more than once */ + typedef enum { + DEFENSE_BONUS, + CC_ATTACK_BONUS, + RANGED_ATTACK_BONUS, + } buildingbonus; + typedef struct building_type { char *_name; @@ -66,7 +72,7 @@ extern "C" { const struct building * b, int size); void (*init) (struct building_type *); void (*age) (struct building *); - int (*protection) (struct building *, struct unit *); + int (*protection) (struct building *, struct unit *, buildingbonus); double (*taxes) (const struct building *, int size); struct attrib *attribs; } building_type; diff --git a/src/kernel/xmlreader.c b/src/kernel/xmlreader.c index 77d2270e1..aa662c974 100644 --- a/src/kernel/xmlreader.c +++ b/src/kernel/xmlreader.c @@ -167,7 +167,10 @@ construction ** consPtr) con->maxsize = xml_ivalue(node, "maxsize", -1); con->minskill = xml_ivalue(node, "minskill", -1); con->reqsize = xml_ivalue(node, "reqsize", -1); - + con->prot = xml_ivalue(node, "prot", 0); + con->ccbonus = xml_ivalue(node, "ccbonus", 0); + con->rangedbonus = xml_ivalue(node, "rangedbonus", 0); + propValue = xmlGetProp(node, BAD_CAST "building"); if (propValue != NULL) { con->btype = bt_get_or_create((const char *)propValue); @@ -297,7 +300,7 @@ static int parse_buildings(xmlDocPtr doc) btype->age = (void(*)(struct building *))fun; } else if (strcmp((const char *)propValue, "protection") == 0) { - btype->protection = (int(*)(struct building *, struct unit *))fun; + btype->protection = (int(*)(struct building *, struct unit *, buildingbonus))fun; } else if (strcmp((const char *)propValue, "taxes") == 0) { btype->taxes = (double(*)(const struct building *, int))fun;