From bb50d7a9ef93bb8042da882935a4c3968e4627c7 Mon Sep 17 00:00:00 2001 From: Enno Rehling Date: Mon, 18 May 2009 14:52:35 +0000 Subject: [PATCH] - construction can have building-requirements --- src/common/gamecode/economy.c | 12 ++++++++++ src/common/kernel/build.c | 8 +++++++ src/common/kernel/build.h | 40 +++++++++++++++++++--------------- src/common/kernel/building.c | 8 +++---- src/common/kernel/xmlreader.c | 41 ++++++++++++++++++++--------------- src/res/e2k9/items.xml | 14 ++++++++++++ src/res/e2k9/races.xml | 1 + src/res/messages.xml | 10 +++++++++ 8 files changed, 94 insertions(+), 40 deletions(-) create mode 100644 src/res/e2k9/items.xml 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." +