forked from github/server
move building names from function to construction data.
This commit is contained in:
parent
f2d8392206
commit
a313e78de5
|
@ -1,23 +1,22 @@
|
|||
<?xml version="1.0"?>
|
||||
<building name="castle" capacity="1" fort="yes">
|
||||
<function name="name" value="castle_name_2"/>
|
||||
<function name="taxes" value="lua_building_taxes"/>
|
||||
<construction skill="building" minskill="1" maxsize="10">
|
||||
<construction skill="building" minskill="1" maxsize="10" name="site">
|
||||
<requirement type="stone" quantity="1"/>
|
||||
</construction>
|
||||
<construction skill="building" minskill="2" maxsize="40">
|
||||
<construction skill="building" minskill="2" maxsize="40" name="fortification">
|
||||
<requirement type="stone" quantity="1"/>
|
||||
</construction>
|
||||
<construction skill="building" minskill="3" maxsize="200">
|
||||
<construction skill="building" minskill="3" maxsize="200" name="tower">
|
||||
<requirement type="stone" quantity="1"/>
|
||||
</construction>
|
||||
<construction skill="building" minskill="4" maxsize="1000">
|
||||
<construction skill="building" minskill="4" maxsize="1000" name="castle">
|
||||
<requirement type="stone" quantity="1"/>
|
||||
</construction>
|
||||
<construction skill="building" minskill="5" maxsize="5000">
|
||||
<construction skill="building" minskill="5" maxsize="5000" name="fortress">
|
||||
<requirement type="stone" quantity="1"/>
|
||||
</construction>
|
||||
<construction skill="building" minskill="6">
|
||||
<construction skill="building" minskill="6" name="citadel">
|
||||
<requirement type="stone" quantity="1"/>
|
||||
</construction>
|
||||
</building>
|
||||
|
|
|
@ -1,25 +1,24 @@
|
|||
<?xml version="1.0"?>
|
||||
<building name="castle" capacity="1" fort="yes">
|
||||
<function name="name" value="castle_name"/>
|
||||
<construction skill="building" minskill="1" maxsize="2">
|
||||
<construction skill="building" minskill="1" maxsize="2" name="site">
|
||||
<requirement type="stone" quantity="1"/>
|
||||
</construction>
|
||||
<construction skill="building" minskill="1" maxsize="8">
|
||||
<construction skill="building" minskill="1" maxsize="8" name="tradepost">
|
||||
<requirement type="stone" quantity="1"/>
|
||||
</construction>
|
||||
<construction skill="building" minskill="2" maxsize="40">
|
||||
<construction skill="building" minskill="2" maxsize="40" name="fortification">
|
||||
<requirement type="stone" quantity="1"/>
|
||||
</construction>
|
||||
<construction skill="building" minskill="3" maxsize="200">
|
||||
<construction skill="building" minskill="3" maxsize="200" name="tower">
|
||||
<requirement type="stone" quantity="1"/>
|
||||
</construction>
|
||||
<construction skill="building" minskill="4" maxsize="1000">
|
||||
<construction skill="building" minskill="4" maxsize="1000" name="castle">
|
||||
<requirement type="stone" quantity="1"/>
|
||||
</construction>
|
||||
<construction skill="building" minskill="5" maxsize="5000">
|
||||
<construction skill="building" minskill="5" maxsize="5000" name="fortress">
|
||||
<requirement type="stone" quantity="1"/>
|
||||
</construction>
|
||||
<construction skill="building" minskill="6">
|
||||
<construction skill="building" minskill="6" name="citadel">
|
||||
<requirement type="stone" quantity="1"/>
|
||||
</construction>
|
||||
</building>
|
||||
|
|
|
@ -4,15 +4,14 @@
|
|||
<xi:include href="config://default/buildings/castle-2.xml" />
|
||||
|
||||
<building name="watch" maxsize="10" capacity="1" fort="yes">
|
||||
<function name="name" value="fort_name"/>
|
||||
<function name="taxes" value="lua_building_taxes"/>
|
||||
<construction skill="building" minskill="1" maxsize="5">
|
||||
<construction skill="building" minskill="1" maxsize="5" name="scaffolding">
|
||||
<requirement type="log" quantity="1"/>
|
||||
</construction>
|
||||
<construction skill="building" minskill="2" maxsize="5">
|
||||
<construction skill="building" minskill="2" maxsize="5" name="guardhouse">
|
||||
<requirement type="log" quantity="1"/>
|
||||
</construction>
|
||||
<construction skill="building" minskill="2">
|
||||
<construction skill="building" minskill="2" name="guardtower">
|
||||
<requirement type="log" quantity="1"/>
|
||||
</construction>
|
||||
</building>
|
||||
|
|
|
@ -888,7 +888,7 @@ static void manufacture(unit * u, const item_type * itype, int want)
|
|||
case EBUILDINGREQ:
|
||||
ADDMSG(&u->faction->msgs,
|
||||
msg_feedback(u, u->thisorder, "building_needed", "building",
|
||||
itype->construction->btype->_name));
|
||||
itype->construction->extra.btype->_name));
|
||||
return;
|
||||
case ELOWSKILL:
|
||||
ADDMSG(&u->faction->msgs,
|
||||
|
@ -1239,7 +1239,7 @@ static void create_potion(unit * u, const potion_type * ptype, int want)
|
|||
case EBUILDINGREQ:
|
||||
ADDMSG(&u->faction->msgs,
|
||||
msg_feedback(u, u->thisorder, "building_needed", "building",
|
||||
ptype->itype->construction->btype->_name));
|
||||
ptype->itype->construction->extra.btype->_name));
|
||||
break;
|
||||
case ECOMPLETE:
|
||||
assert(0);
|
||||
|
|
|
@ -70,7 +70,6 @@ void game_init(void)
|
|||
register_spells();
|
||||
register_names();
|
||||
register_resources();
|
||||
register_buildings();
|
||||
register_itemfunctions();
|
||||
#if MUSEUM_MODULE
|
||||
register_museum();
|
||||
|
|
|
@ -502,20 +502,20 @@ static int count_materials(unit *u, const construction *type, int n, int complet
|
|||
*/
|
||||
int build(unit * u, const construction * ctype, int completed, int want, int skill_mod)
|
||||
{
|
||||
const construction *type = ctype;
|
||||
const construction *con = ctype;
|
||||
int skills = INT_MAX; /* number of skill points remainig */
|
||||
int basesk = 0;
|
||||
int made = 0;
|
||||
|
||||
if (want <= 0)
|
||||
return 0;
|
||||
if (type == NULL)
|
||||
if (con == NULL)
|
||||
return ENOMATERIALS;
|
||||
if (type->improvement == NULL && completed == type->maxsize)
|
||||
if (con->improvement == NULL && completed == con->maxsize)
|
||||
return ECOMPLETE;
|
||||
if (type->btype != NULL) {
|
||||
if (con->type==CONS_ITEM && con->extra.btype) {
|
||||
building *b;
|
||||
if (!u->building || u->building->type != type->btype) {
|
||||
if (!u->building || u->building->type != con->extra.btype) {
|
||||
return EBUILDINGREQ;
|
||||
}
|
||||
b = inside_building(u);
|
||||
|
@ -524,12 +524,12 @@ int build(unit * u, const construction * ctype, int completed, int want, int ski
|
|||
}
|
||||
}
|
||||
|
||||
if (type->skill != NOSKILL) {
|
||||
if (con->skill != NOSKILL) {
|
||||
int effsk;
|
||||
int dm = get_effect(u, oldpotiontype[P_DOMORE]);
|
||||
|
||||
assert(u->number);
|
||||
basesk = effskill(u, type->skill, 0);
|
||||
basesk = effskill(u, con->skill, 0);
|
||||
if (basesk == 0)
|
||||
return ENEEDSKILL;
|
||||
|
||||
|
@ -557,13 +557,13 @@ int build(unit * u, const construction * ctype, int completed, int want, int ski
|
|||
* type->improvement==type means build another object of the same time
|
||||
* while material lasts type->improvement==x means build x when type
|
||||
* is finished */
|
||||
while (type && type->improvement &&
|
||||
type->improvement != type &&
|
||||
type->maxsize > 0 && type->maxsize <= completed) {
|
||||
completed -= type->maxsize;
|
||||
type = type->improvement;
|
||||
while (con && con->improvement &&
|
||||
con->improvement != con &&
|
||||
con->maxsize > 0 && con->maxsize <= completed) {
|
||||
completed -= con->maxsize;
|
||||
con = con->improvement;
|
||||
}
|
||||
if (type == NULL) {
|
||||
if (con == NULL) {
|
||||
if (made == 0)
|
||||
return ECOMPLETE;
|
||||
break; /* completed */
|
||||
|
@ -574,15 +574,15 @@ int build(unit * u, const construction * ctype, int completed, int want, int ski
|
|||
* (enno): Nein, das ist f<EFBFBD>r Dinge, bei denen die n<EFBFBD>chste Ausbaustufe
|
||||
* die gleiche wie die vorherige ist. z.b. gegenst<EFBFBD>nde.
|
||||
*/
|
||||
if (type->maxsize > 0) {
|
||||
completed = completed % type->maxsize;
|
||||
if (con->maxsize > 0) {
|
||||
completed = completed % con->maxsize;
|
||||
}
|
||||
else {
|
||||
completed = 0;
|
||||
assert(type->reqsize >= 1);
|
||||
assert(con->reqsize >= 1);
|
||||
}
|
||||
|
||||
if (basesk < type->minskill) {
|
||||
if (basesk < con->minskill) {
|
||||
if (made == 0)
|
||||
return ELOWSKILL;
|
||||
else
|
||||
|
@ -590,15 +590,15 @@ int build(unit * u, const construction * ctype, int completed, int want, int ski
|
|||
}
|
||||
|
||||
/* n = maximum buildable size */
|
||||
if (type->minskill > 1) {
|
||||
n = skills / type->minskill;
|
||||
if (con->minskill > 1) {
|
||||
n = skills / con->minskill;
|
||||
}
|
||||
else {
|
||||
n = skills;
|
||||
}
|
||||
/* Flinkfingerring wirkt nicht auf Mengenbegrenzte (magische)
|
||||
* Talente */
|
||||
if (skill_limit(u->faction, type->skill) == INT_MAX) {
|
||||
if (skill_limit(u->faction, con->skill) == INT_MAX) {
|
||||
const resource_type *ring = get_resourcetype(R_RING_OF_NIMBLEFINGER);
|
||||
item *itm = ring ? *i_find(&u->items, ring->itype) : 0;
|
||||
int i = itm ? itm->number : 0;
|
||||
|
@ -610,26 +610,26 @@ int build(unit * u, const construction * ctype, int completed, int want, int ski
|
|||
|
||||
if (want < n) n = want;
|
||||
|
||||
if (type->maxsize > 0) {
|
||||
n = MIN(type->maxsize - completed, n);
|
||||
if (type->improvement == NULL) {
|
||||
if (con->maxsize > 0) {
|
||||
n = MIN(con->maxsize - completed, n);
|
||||
if (con->improvement == NULL) {
|
||||
want = n;
|
||||
}
|
||||
}
|
||||
|
||||
n = count_materials(u, type, n, completed);
|
||||
n = count_materials(u, con, n, completed);
|
||||
if (n <= 0) {
|
||||
if (made == 0)
|
||||
return ENOMATERIALS;
|
||||
else
|
||||
break;
|
||||
}
|
||||
err = use_materials(u, type, n, completed);
|
||||
err = use_materials(u, con, n, completed);
|
||||
if (err < 0) {
|
||||
return err;
|
||||
}
|
||||
made += n;
|
||||
skills -= n * type->minskill;
|
||||
skills -= n * con->minskill;
|
||||
want -= n;
|
||||
completed = completed + n;
|
||||
}
|
||||
|
|
|
@ -37,15 +37,27 @@ extern "C" {
|
|||
int number;
|
||||
} requirement;
|
||||
|
||||
typedef enum construct_t {
|
||||
CONS_OTHER,
|
||||
CONS_ITEM,
|
||||
CONS_BUILDING
|
||||
} construct_t;
|
||||
|
||||
typedef struct construction {
|
||||
construct_t type;
|
||||
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 */
|
||||
const struct building_type *btype;
|
||||
/* building type required to make this thing */
|
||||
|
||||
union {
|
||||
/* CONS_BUILDING: */
|
||||
char * name; /* building level name */
|
||||
/* CONS_ITEM: */
|
||||
const struct building_type *btype; /* building required to build item */
|
||||
} extra;
|
||||
|
||||
struct construction *improvement;
|
||||
/* next level, if upgradable. if more than one of these items
|
||||
|
|
|
@ -81,7 +81,8 @@ static void test_build_requires_building(CuTest *tc) {
|
|||
rtype = bf.cons.materials[0].rtype;
|
||||
i_change(&u->items, rtype->itype, 1);
|
||||
set_level(u, SK_ARMORER, 2);
|
||||
bf.cons.btype = btype = bt_get_or_create("hodor");
|
||||
bf.cons.type = CONS_ITEM;
|
||||
bf.cons.extra.btype = btype = bt_get_or_create("hodor");
|
||||
btype->maxcapacity = 1;
|
||||
btype->capacity = 1;
|
||||
CuAssertIntEquals_Msg(tc, "must be inside a production building", EBUILDINGREQ, build(u, &bf.cons, 0, 1, 0));
|
||||
|
|
|
@ -157,27 +157,52 @@ attrib_type at_building_generic_type = {
|
|||
ATF_UNIQUE
|
||||
};
|
||||
|
||||
/* TECH DEBT: simplest thing that works for E3 dwarf/halfling faction rules */
|
||||
static int adjust_size(const building *b, int bsize) {
|
||||
assert(b);
|
||||
if (config_get_int("rules.dwarf_castles", 0)
|
||||
&& strcmp(b->type->_name, "castle") == 0) {
|
||||
unit *u = building_owner(b);
|
||||
if (u && u->faction->race == get_race(RC_HALFLING)) {
|
||||
return bsize * 5 / 4;
|
||||
}
|
||||
}
|
||||
return bsize;
|
||||
}
|
||||
|
||||
/* Returns the (internal) name for a building of given size and type. Especially, returns the correct
|
||||
* name if it depends on the size (as for Eressea castles).
|
||||
*/
|
||||
const char *buildingtype(const building_type * btype, const building * b, int bsize)
|
||||
{
|
||||
const char *s;
|
||||
const construction *con;
|
||||
|
||||
assert(btype);
|
||||
|
||||
s = btype->_name;
|
||||
if (btype->name) {
|
||||
s = btype->name(btype, b, bsize);
|
||||
}
|
||||
if (b && b->attribs) {
|
||||
if (is_building_type(btype, "generic")) {
|
||||
const attrib *a = a_find(b->attribs, &at_building_generic_type);
|
||||
if (a) {
|
||||
s = (const char *)a->data.v;
|
||||
return (const char *)a->data.v;
|
||||
}
|
||||
}
|
||||
}
|
||||
return s;
|
||||
if (btype->name) {
|
||||
return btype->name(btype, b, bsize);
|
||||
}
|
||||
if (btype->construction->extra.name) {
|
||||
if (b) {
|
||||
assert(b->type == btype);
|
||||
bsize = adjust_size(b, bsize);
|
||||
}
|
||||
for (con = btype->construction; con; con = con->improvement) {
|
||||
bsize -= con->maxsize;
|
||||
if (!con->improvement || bsize <0) {
|
||||
return con->extra.name;
|
||||
}
|
||||
}
|
||||
}
|
||||
return btype->_name;
|
||||
}
|
||||
|
||||
#define BMAXHASH 7919
|
||||
|
@ -219,55 +244,6 @@ building *findbuilding(int i)
|
|||
{
|
||||
return bfindhash(i);
|
||||
}
|
||||
|
||||
static const char *castle_name_i(const struct building_type *btype,
|
||||
const struct building *b, int bsize, const char *fname[])
|
||||
{
|
||||
int i = bt_effsize(btype, b, bsize);
|
||||
|
||||
return fname[i];
|
||||
}
|
||||
|
||||
static const char *castle_name_2(const struct building_type *btype,
|
||||
const struct building *b, int bsize)
|
||||
{
|
||||
const char *fname[] = {
|
||||
"site",
|
||||
"fortification",
|
||||
"tower",
|
||||
"castle",
|
||||
"fortress",
|
||||
"citadel"
|
||||
};
|
||||
return castle_name_i(btype, b, bsize, fname);
|
||||
}
|
||||
|
||||
static const char *castle_name(const struct building_type *btype,
|
||||
const struct building *b, int bsize)
|
||||
{
|
||||
const char *fname[] = {
|
||||
"site",
|
||||
"tradepost",
|
||||
"fortification",
|
||||
"tower",
|
||||
"castle",
|
||||
"fortress",
|
||||
"citadel"
|
||||
};
|
||||
return castle_name_i(btype, b, bsize, fname);
|
||||
}
|
||||
|
||||
static const char *fort_name(const struct building_type *btype,
|
||||
const struct building *b, int bsize)
|
||||
{
|
||||
const char *fname[] = {
|
||||
"scaffolding",
|
||||
"guardhouse",
|
||||
"guardtower",
|
||||
};
|
||||
return castle_name_i(btype, b, bsize, fname);
|
||||
}
|
||||
|
||||
/* for finding out what was meant by a particular building string */
|
||||
|
||||
static local_names *bnames;
|
||||
|
@ -486,24 +462,19 @@ int buildingeffsize(const building * b, int img)
|
|||
|
||||
int bt_effsize(const building_type * btype, const building * b, int bsize)
|
||||
{
|
||||
int i = bsize, n = 0;
|
||||
int n = 0;
|
||||
const construction *cons = btype->construction;
|
||||
|
||||
/* TECH DEBT: simplest thing that works for E3 dwarf/halfling faction rules */
|
||||
if (b && config_get_int("rules.dwarf_castles", 0)
|
||||
&& strcmp(btype->_name, "castle") == 0) {
|
||||
unit *u = building_owner(b);
|
||||
if (u && u->faction->race == get_race(RC_HALFLING)) {
|
||||
i = bsize * 10 / 8;
|
||||
}
|
||||
if (b) {
|
||||
bsize = adjust_size(b, bsize);
|
||||
}
|
||||
|
||||
if (!cons || !cons->improvement) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
while (cons && cons->maxsize != -1 && i >= cons->maxsize) {
|
||||
i -= cons->maxsize;
|
||||
while (cons && cons->maxsize != -1 && bsize >= cons->maxsize) {
|
||||
bsize -= cons->maxsize;
|
||||
cons = cons->improvement;
|
||||
++n;
|
||||
}
|
||||
|
@ -883,10 +854,3 @@ int cmp_current_owner(const building * b, const building * a)
|
|||
}
|
||||
return -1;
|
||||
}
|
||||
|
||||
void register_buildings(void)
|
||||
{
|
||||
register_function((pf_generic)castle_name, "castle_name");
|
||||
register_function((pf_generic)castle_name_2, "castle_name_2");
|
||||
register_function((pf_generic)fort_name, "fort_name");
|
||||
}
|
||||
|
|
|
@ -84,7 +84,6 @@ extern "C" {
|
|||
bool bt_changed(int *cache);
|
||||
const building_type *bt_find(const char *name);
|
||||
void free_buildingtypes(void);
|
||||
void register_buildings(void);
|
||||
void bt_register(struct building_type *type);
|
||||
int bt_effsize(const struct building_type *btype,
|
||||
const struct building *b, int bsize);
|
||||
|
|
|
@ -214,7 +214,7 @@ xml_readrequirements(xmlNodePtr * nodeTab, int nodeNr, requirement ** reqArray)
|
|||
|
||||
void
|
||||
xml_readconstruction(xmlXPathContextPtr xpath, xmlNodeSetPtr nodeSet,
|
||||
construction ** consPtr)
|
||||
construction ** consPtr, construct_t type)
|
||||
{
|
||||
xmlNodePtr pushNode = xpath->node;
|
||||
int k;
|
||||
|
@ -241,15 +241,25 @@ construction ** consPtr)
|
|||
*consPtr = con = (construction *)calloc(sizeof(construction), 1);
|
||||
consPtr = &con->improvement;
|
||||
|
||||
con->type = type;
|
||||
con->skill = sk;
|
||||
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);
|
||||
if (type == CONS_ITEM) {
|
||||
propValue = xmlGetProp(node, BAD_CAST "building");
|
||||
if (propValue != NULL) {
|
||||
con->extra.btype = bt_get_or_create((const char *)propValue);
|
||||
xmlFree(propValue);
|
||||
}
|
||||
}
|
||||
else if (type == CONS_BUILDING) {
|
||||
propValue = xmlGetProp(node, BAD_CAST "name");
|
||||
if (propValue != NULL) {
|
||||
con->extra.name = strdup((const char *)propValue);
|
||||
xmlFree(propValue);
|
||||
}
|
||||
}
|
||||
|
||||
/* read construction/requirement */
|
||||
|
@ -337,7 +347,7 @@ static int parse_buildings(xmlDocPtr doc)
|
|||
/* reading eressea/buildings/building/construction */
|
||||
xpath->node = node;
|
||||
result = xmlXPathEvalExpression(BAD_CAST "construction", xpath);
|
||||
xml_readconstruction(xpath, result->nodesetval, &btype->construction);
|
||||
xml_readconstruction(xpath, result->nodesetval, &btype->construction, CONS_BUILDING);
|
||||
xmlXPathFreeObject(result);
|
||||
|
||||
/* reading eressea/buildings/building/function */
|
||||
|
@ -572,7 +582,7 @@ static int parse_ships(xmlDocPtr doc)
|
|||
/* reading eressea/ships/ship/construction */
|
||||
xpath->node = node;
|
||||
result = xmlXPathEvalExpression(BAD_CAST "construction", xpath);
|
||||
xml_readconstruction(xpath, result->nodesetval, &st->construction);
|
||||
xml_readconstruction(xpath, result->nodesetval, &st->construction, CONS_OTHER);
|
||||
xmlXPathFreeObject(result);
|
||||
|
||||
for (child = node->children; child; child = child->next) {
|
||||
|
@ -858,7 +868,7 @@ static item_type *xml_readitem(xmlXPathContextPtr xpath, resource_type * rtype)
|
|||
/* reading item/construction */
|
||||
xpath->node = node;
|
||||
result = xmlXPathEvalExpression(BAD_CAST "construction", xpath);
|
||||
xml_readconstruction(xpath, result->nodesetval, &itype->construction);
|
||||
xml_readconstruction(xpath, result->nodesetval, &itype->construction, CONS_ITEM);
|
||||
xmlXPathFreeObject(result);
|
||||
|
||||
/* reading item/weapon */
|
||||
|
|
Loading…
Reference in New Issue