diff --git a/src/common/gamecode/economy.c b/src/common/gamecode/economy.c
index e6988b522..7ce5f0703 100644
--- a/src/common/gamecode/economy.c
+++ b/src/common/gamecode/economy.c
@@ -1221,6 +1221,10 @@ recruit_archetype(unit * u, order * ord)
/* no skill, or not enough skill points to build */
cmistake(u, ord, 50, MSG_PRODUCE);
break;
+ case EBUILDINGREQ:
+ ADDMSG(&u->faction->msgs,
+ msg_feedback(u, u->thisorder, "building_needed", "building", arch->ctype->btype->_name));
+ break;
default:
assert(!"unhandled return value from build() in recruit_archetype");
}
@@ -1338,6 +1342,10 @@ manufacture(unit * u, const item_type * itype, int want)
ADDMSG(&u->faction->msgs,
msg_feedback(u, u->thisorder, "skill_needed", "skill", sk));
return;
+ case EBUILDINGREQ:
+ ADDMSG(&u->faction->msgs,
+ msg_feedback(u, u->thisorder, "building_needed", "building", itype->construction->btype->_name));
+ return;
case ELOWSKILL:
ADDMSG(&u->faction->msgs,
msg_feedback(u, u->thisorder, "manufacture_skills", "skill minskill product",
@@ -1736,6 +1744,10 @@ create_potion(unit * u, const potion_type * ptype, int want)
/* no skill, or not enough skill points to build */
cmistake(u, u->thisorder, 50, MSG_PRODUCE);
break;
+ case EBUILDINGREQ:
+ ADDMSG(&u->faction->msgs,
+ msg_feedback(u, u->thisorder, "building_needed", "building", ptype->itype->construction->btype->_name));
+ break;
case ECOMPLETE:
assert(0);
break;
diff --git a/src/common/kernel/build.c b/src/common/kernel/build.c
index 1f3c7df0c..2587b9082 100644
--- a/src/common/kernel/build.c
+++ b/src/common/kernel/build.c
@@ -608,6 +608,14 @@ build(unit * u, const construction * ctype, int completed, int want)
if (type==NULL) return 0;
if (type->improvement==NULL && completed==type->maxsize)
return ECOMPLETE;
+ if (type->btype!=NULL) {
+ building * b;
+ if (!u->building || u->building->type!=type->btype) {
+ return EBUILDINGREQ;
+ }
+ b = inside_building(u);
+ if (b==NULL) return EBUILDINGREQ;
+ }
if (type->skill!=NOSKILL) {
int effsk;
diff --git a/src/common/kernel/build.h b/src/common/kernel/build.h
index 96dfe29ab..4468a00c7 100644
--- a/src/common/kernel/build.h
+++ b/src/common/kernel/build.h
@@ -35,29 +35,32 @@ extern "C" {
struct xml_tag;
typedef struct requirement {
- const struct resource_type * rtype;
- int number;
- double recycle; /* recycling quota */
+ const struct resource_type * rtype;
+ int number;
+ double recycle; /* recycling quota */
} requirement;
typedef struct construction {
- skill_t skill; /* skill req'd per point of size */
- int minskill; /* skill req'd per point of size */
+ skill_t skill; /* skill req'd per point of size */
+ int minskill; /* skill req'd per point of size */
- int maxsize; /* maximum size of this type */
- int reqsize; /* size of object using up 1 set of requirement. */
- requirement * materials; /* material req'd to build one object */
+ int maxsize; /* maximum size of this type */
+ int reqsize; /* size of object using up 1 set of requirement. */
+ requirement * materials; /* material req'd to build one object */
+ const struct building_type * btype;
+ /* building type required to make this thing */
+
+ struct construction * improvement;
+ /* next level, if upgradable. if more than one of these items
+ * can be built (weapons, armour) per turn, must not be NULL,
+ * but point to the same type again:
+ * const_sword.improvement = &const_sword
+ * last level of a building points to NULL, as do objects of
+ * an unlimited size.
+ */
+ struct attrib * attribs;
+ /* stores skill modifiers and other attributes */
- struct construction * improvement;
- /* next level, if upgradable. if more than one of these items
- * can be built (weapons, armour) per turn, must not be NULL,
- * but point to the same type again:
- * const_sword.improvement = &const_sword
- * last level of a building points to NULL, as do objects of
- * an unlimited size.
- */
- struct attrib * attribs;
- /* stores skill modifiers and other attributes */
} construction;
extern int destroy_cmd(struct unit * u, struct order * ord);
@@ -88,6 +91,7 @@ extern struct message * msg_materials_required(struct unit * u, struct order * o
#define ENEEDSKILL -2
#define ECOMPLETE -3
#define ENOMATERIALS -4
+#define EBUILDINGREQ -5
#ifdef __cplusplus
}
diff --git a/src/common/kernel/building.c b/src/common/kernel/building.c
index e3f86d37b..7aa7eb0fb 100644
--- a/src/common/kernel/building.c
+++ b/src/common/kernel/building.c
@@ -384,11 +384,11 @@ findbuildingtype(const char * name, const struct locale * lang)
void
register_buildings(void)
{
- register_function((pf_generic)&init_smithy, "init_smithy");
- register_function((pf_generic)&castle_name, "castle_name");
- register_function((pf_generic)&fort_name, "fort_name");
+ register_function((pf_generic)&init_smithy, "init_smithy");
+ register_function((pf_generic)&castle_name, "castle_name");
+ register_function((pf_generic)&fort_name, "fort_name");
#ifdef WDW_PYRAMID
- register_function((pf_generic)&pyramid_name, "pyramid_name");
+ register_function((pf_generic)&pyramid_name, "pyramid_name");
#endif
}
diff --git a/src/common/kernel/xmlreader.c b/src/common/kernel/xmlreader.c
index 3a4ea5057..b13289ef2 100644
--- a/src/common/kernel/xmlreader.c
+++ b/src/common/kernel/xmlreader.c
@@ -53,6 +53,20 @@ without prior permission by the authors of Eressea.
static boolean gamecode_enabled = false;
+static building_type * bt_get_or_create(const char * name)
+{
+ if (name!=NULL) {
+ building_type * btype = bt_find(name);
+ if (btype==NULL) {
+ btype = calloc(sizeof(building_type), 1);
+ btype->_name = strdup(name);
+ bt_register(btype);
+ }
+ return btype;
+ }
+ return NULL;
+}
+
void
enable_xml_gamecode(void)
{
@@ -180,6 +194,12 @@ xml_readconstruction(xmlXPathContextPtr xpath, xmlNodeSetPtr nodeSet, constructi
con->maxsize = xml_ivalue(node, "maxsize", -1);
con->minskill = xml_ivalue(node, "minskill", -1);
con->reqsize = xml_ivalue(node, "reqsize", -1);
+
+ propValue = xmlGetProp(node, BAD_CAST "building");
+ if (propValue!=NULL) {
+ con->btype = bt_get_or_create((const char*)propValue);
+ xmlFree(propValue);
+ }
/* read construction/requirement */
xpath->node = node;
@@ -244,12 +264,7 @@ parse_buildings(xmlDocPtr doc)
propValue = xmlGetProp(node, BAD_CAST "name");
assert(propValue!=NULL);
- btype = bt_find((const char*)propValue);
- if (btype==NULL) {
- btype = calloc(sizeof(building_type), 1);
- btype->_name = strdup((const char *)propValue);
- bt_register(btype);
- }
+ btype = bt_get_or_create((const char*)propValue);
xmlFree(propValue);
btype->capacity = xml_ivalue(node, "capacity", -1);
@@ -1026,12 +1041,7 @@ parse_resources(xmlDocPtr doc)
propValue = xmlGetProp(node, BAD_CAST "building");
if (propValue!=NULL) {
- btype = bt_find((const char*)propValue);
- if (btype==NULL) {
- btype = calloc(sizeof(building_type), 1);
- btype->_name = strdup((const char *)propValue);
- bt_register(btype);
- }
+ btype = bt_get_or_create((const char*)propValue);
xmlFree(propValue);
}
rdata->modifiers[k].btype = btype;
@@ -1050,12 +1060,7 @@ parse_resources(xmlDocPtr doc)
} else if (strcmp((const char *)propValue, "require")==0) {
xmlChar * propBldg = xmlGetProp(node, BAD_CAST "building");
if (propBldg!=NULL) {
- btype = bt_find((const char*)propBldg);
- if (btype==NULL) {
- btype = calloc(sizeof(building_type), 1);
- btype->_name = strdup((const char *)propBldg);
- bt_register(btype);
- }
+ btype = bt_get_or_create((const char*)propBldg);
rdata->modifiers[k].btype = btype;
rdata->modifiers[k].flags = RMF_REQUIREDBUILDING;
xmlFree(propBldg);
diff --git a/src/res/e2k9/items.xml b/src/res/e2k9/items.xml
new file mode 100644
index 000000000..9fde522db
--- /dev/null
+++ b/src/res/e2k9/items.xml
@@ -0,0 +1,14 @@
+
+
+
+
+ -
+
+
+
+
+
+
+
+
+
diff --git a/src/res/e2k9/races.xml b/src/res/e2k9/races.xml
index 6a211d751..bfe91263d 100644
--- a/src/res/e2k9/races.xml
+++ b/src/res/e2k9/races.xml
@@ -38,6 +38,7 @@
+
diff --git a/src/res/messages.xml b/src/res/messages.xml
index 769a13d03..5cb6a7b0b 100644
--- a/src/res/messages.xml
+++ b/src/res/messages.xml
@@ -6968,6 +6968,16 @@
"'$order($command)' - $race($race,0) are peace-loving and will not attack anyone."
"'$order($command)' - $race($race,0) are peace-loving and will not attack anyone."
+
+
+
+
+
+
+
+ "$unit($unit) in $region($region): '$order($command)' - Die Einheit steht nicht im benötigten Gebäude, $localize($building)."
+ "$unit($unit) in $region($region): '$order($command)' - The unit must be in a $localize($building) to produce this."
+