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;