From 865f40ec9aa9c8f1edeae83f601ecb0cd3010991 Mon Sep 17 00:00:00 2001 From: Enno Rehling Date: Wed, 27 Mar 2002 21:49:27 +0000 Subject: [PATCH] =?UTF-8?q?Geb=C3=A4udetypen=20sind=20jetzt=20in=20einer?= =?UTF-8?q?=20XML-Datei.=20Neue=20allgemeine=20Eigenschaften=20f=C3=BCr=20?= =?UTF-8?q?Geb=C3=A4ude:=20-=20Magieresistenz,=20-=20Magieresistenz=20f?= =?UTF-8?q?=C3=BCr=20insassen,=20-=20Auraregenerationsmodifikator=20f?= =?UTF-8?q?=C3=BCr=20Insassen,=20-=20Schutz=20im=20Kampf,=20-=20Magisch?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/askalon/main.c | 1 + src/common/attributes/attributes.dsp | 6 +- src/common/gamecode/economy.c | 36 +- src/common/gamecode/gamecode.dsp | 8 +- src/common/gamecode/laws.c | 16 +- src/common/gamecode/randenc.c | 2 +- src/common/gamecode/report.c | 6 +- src/common/gamecode/study.c | 6 +- src/common/items/items.dsp | 6 +- src/common/kernel/battle.c | 4 +- src/common/kernel/build.c | 31 +- src/common/kernel/building.c | 795 ++++++++------------------- src/common/kernel/building.h | 36 +- src/common/kernel/eressea.c | 45 +- src/common/kernel/kernel.dsp | 2 +- src/common/kernel/magic.c | 48 +- src/common/kernel/movement.c | 6 +- src/common/kernel/race.c | 2 +- src/common/kernel/save.c | 14 +- src/common/kernel/ship.c | 156 ------ src/common/kernel/ship.h | 9 - src/common/kernel/spell.c | 14 +- src/common/modules/arena.c | 15 +- src/common/modules/modules.dsp | 2 +- src/common/modules/museum.c | 13 +- src/common/races/races.dsp | 22 +- src/common/spells/spells.dsp | 22 +- src/common/triggers/triggers.dsp | 8 +- src/common/util/util.dsp | 8 +- src/eressea/eressea.dsp | 2 +- src/eressea/korrektur.c | 8 +- src/eressea/main.c | 8 +- src/res/buildings.xml | 175 ++++++ src/res/eressea.xml | 1 + 34 files changed, 571 insertions(+), 962 deletions(-) create mode 100644 src/res/buildings.xml diff --git a/src/askalon/main.c b/src/askalon/main.c index cb0a73c0e..93f9075f7 100644 --- a/src/askalon/main.c +++ b/src/askalon/main.c @@ -88,6 +88,7 @@ init_game(void) init_resources(); register_items(); + register_buildings(); init_weapons(); init_conversion(); diff --git a/src/common/attributes/attributes.dsp b/src/common/attributes/attributes.dsp index 503a1957e..c9eb17cad 100644 --- a/src/common/attributes/attributes.dsp +++ b/src/common/attributes/attributes.dsp @@ -8,12 +8,12 @@ CFG=attributes - Win32 Debug !MESSAGE This is not a valid makefile. To build this project using NMAKE, !MESSAGE use the Export Makefile command and run !MESSAGE -!MESSAGE NMAKE /f "attributes-6.mak". +!MESSAGE NMAKE /f "attributes.mak". !MESSAGE !MESSAGE You can specify a configuration when running NMAKE !MESSAGE by defining the macro CFG on the command line. For example: !MESSAGE -!MESSAGE NMAKE /f "attributes-6.mak" CFG="attributes - Win32 Debug" +!MESSAGE NMAKE /f "attributes.mak" CFG="attributes - Win32 Debug" !MESSAGE !MESSAGE Possible choices for configuration are: !MESSAGE @@ -64,7 +64,7 @@ LIB32=link.exe -lib # PROP Intermediate_Dir "Debug" # PROP Target_Dir "" # ADD BASE CPP /nologo /W3 /GX /Z7 /Od /D "WIN32" /D "_DEBUG" /D "_WINDOWS" /YX /FD /c -# ADD CPP /nologo /Za /W4 /Z7 /Od /I "../util" /I "../kernel" /I "../.." /I ".." /D "_WINDOWS" /D "WIN32" /D "_DEBUG" /D "BETA_CODE" /FR /YX"stdafx.h" /FD /c +# ADD CPP /nologo /Za /W4 /Z7 /Od /I "../util" /I "../kernel" /I "../.." /I ".." /D "_WINDOWS" /D "WIN32" /D "_DEBUG" /FR /YX"stdafx.h" /FD /c # ADD BASE RSC /l 0x407 # ADD RSC /l 0x407 BSC32=bscmake.exe diff --git a/src/common/gamecode/economy.c b/src/common/gamecode/economy.c index f8e5f92b7..e323da435 100644 --- a/src/common/gamecode/economy.c +++ b/src/common/gamecode/economy.c @@ -1206,9 +1206,9 @@ gebaeude_stuerzt_ein(region * r, building * b) /* Falls Karawanserei, Damm oder Tunnel einstürzen, wird die schon * gebaute Straße zur Hälfte vernichtet */ for (d=0;d!=MAXDIRECTIONS;++d) if (rroad(r, d) > 0 && - (b->type == &bt_caravan || - b->type == &bt_dam || - b->type == &bt_tunnel)) + (b->type == bt_find("caravan") || + b->type == bt_find("dam") || + b->type == bt_find("tunnel"))) { rsetroad(r, d, rroad(r, d) / 2); road = 1; @@ -1446,7 +1446,7 @@ allocate_resource(unit * u, const resource_type * rtype, int want) if (itype == olditemtype[I_LAEN]) { struct building * b = inside_building(u); const struct building_type * btype = b?b->type:NULL; - if (btype != &bt_mine) { + if (btype != bt_find("mine")) { cmistake(u, findorder(u, u->thisorder), 104, MSG_PRODUCE); return; } @@ -1514,16 +1514,16 @@ allocate_resource(unit * u, const resource_type * rtype, int want) } else { struct building * b = inside_building(u); const struct building_type * btype = b?b->type:NULL; - if (itype == olditemtype[I_IRON] && btype == &bt_mine) { + if (itype == olditemtype[I_IRON] && btype == bt_find("mine")) { ++skill; } - else if (itype == olditemtype[I_STONE] && btype == &bt_quarry) { + else if (itype == olditemtype[I_STONE] && btype == bt_find("quarry")) { ++skill; } - else if (itype == olditemtype[I_WOOD] && btype == &bt_sawmill) { + else if (itype == olditemtype[I_WOOD] && btype == bt_find("sawmill")) { ++skill; } - else if (itype == olditemtype[I_MALLORN] && btype == &bt_sawmill) { + else if (itype == olditemtype[I_MALLORN] && btype == bt_find("sawmill")) { ++skill; } } @@ -1564,7 +1564,7 @@ allocate_resource(unit * u, const resource_type * rtype, int want) if (itype==olditemtype[I_IRON]) { struct building * b = inside_building(u); const struct building_type * btype = b?b->type:NULL; - if (btype==&bt_mine) + if (btype==bt_find("mine")) al->save *= 0.5; if (u->race == new_race[RC_DWARF]) #if RACE_ADJUSTMENTS @@ -1575,7 +1575,7 @@ allocate_resource(unit * u, const resource_type * rtype, int want) } else if (itype==olditemtype[I_STONE]) { struct building * b = inside_building(u); const struct building_type * btype = b?b->type:NULL; - if (btype==&bt_quarry) + if (btype==bt_find("quarry")) al->save = al->save*0.5; #if RACE_ADJUSTMENTS if (u->race == new_race[RC_TROLL]) @@ -1584,12 +1584,12 @@ allocate_resource(unit * u, const resource_type * rtype, int want) } else if (itype==olditemtype[I_MALLORN]) { struct building * b = inside_building(u); const struct building_type * btype = b?b->type:NULL; - if (btype==&bt_sawmill) + if (btype==bt_find("sawmill")) al->save *= 0.5; } else if (itype==olditemtype[I_WOOD]) { struct building * b = inside_building(u); const struct building_type * btype = b?b->type:NULL; - if (btype==&bt_sawmill) + if (btype==bt_find("sawmill")) al->save *= 0.5; } } @@ -2168,17 +2168,17 @@ expandselling(region * r, request * sellorders) for (b = rbuildings(r); b; b = b->next) { if (b->size > maxsize && buildingowner(r, b) != NULL - && b->type == &bt_castle) { + && b->type == bt_find("castle")) { maxb = b; maxsize = b->size; maxowner = buildingowner(r, b); - } else if (b->size == maxsize && b->type == &bt_castle) { + } else if (b->size == maxsize && b->type == bt_find("castle")) { maxb = (building *) NULL; maxowner = (unit *) NULL; } } - hafenowner = owner_buildingtyp(r, &bt_harbour); + hafenowner = owner_buildingtyp(r, bt_find("harbour")); if (maxb != (building *) NULL && maxowner != (unit *) NULL) { maxeffsize = buildingeffsize(maxb, false); @@ -2198,7 +2198,7 @@ expandselling(region * r, request * sellorders) max_products = rpeasants(r) / TRADE_FRACTION; if (max_products <= 0) return; - if (rterrain(r) == T_DESERT && buildingtype_exists(r, &bt_caravan)) { + if (rterrain(r) == T_DESERT && buildingtype_exists(r, bt_find("caravan"))) { max_products = rpeasants(r) * 2 / TRADE_FRACTION; } /* Verkauf: so programmiert, dass er leicht auf mehrere Gueter pro @@ -2328,7 +2328,7 @@ sell(region * r, unit * u, request ** sellorders, const char * cmd) s = getstrtoken(); if (findparam(s, u->faction->locale) == P_ANY) { n = rpeasants(r) / TRADE_FRACTION; - if (rterrain(r) == T_DESERT && buildingtype_exists(r, &bt_caravan)) + if (rterrain(r) == T_DESERT && buildingtype_exists(r, bt_find("caravan"))) n *= 2; if (n==0) { cmistake(u, cmd, 303, MSG_COMMERCE); @@ -2708,7 +2708,7 @@ breedhorses(region *r, unit *u) struct building * b = inside_building(u); const struct building_type * btype = b?b->type:NULL; - if (btype!=&bt_stables) { + if (btype!=bt_find("stables")) { cmistake(u, findorder(u, u->thisorder), 122, MSG_PRODUCE); return; } diff --git a/src/common/gamecode/gamecode.dsp b/src/common/gamecode/gamecode.dsp index 5e44f4b1e..3a29be2b6 100644 --- a/src/common/gamecode/gamecode.dsp +++ b/src/common/gamecode/gamecode.dsp @@ -8,12 +8,12 @@ CFG=gamecode - Win32 Profile !MESSAGE This is not a valid makefile. To build this project using NMAKE, !MESSAGE use the Export Makefile command and run !MESSAGE -!MESSAGE NMAKE /f "gamecode-6.mak". +!MESSAGE NMAKE /f "gamecode.mak". !MESSAGE !MESSAGE You can specify a configuration when running NMAKE !MESSAGE by defining the macro CFG on the command line. For example: !MESSAGE -!MESSAGE NMAKE /f "gamecode-6.mak" CFG="gamecode - Win32 Profile" +!MESSAGE NMAKE /f "gamecode.mak" CFG="gamecode - Win32 Profile" !MESSAGE !MESSAGE Possible choices for configuration are: !MESSAGE @@ -65,7 +65,7 @@ LIB32=link.exe -lib # PROP Intermediate_Dir "Debug" # PROP Target_Dir "" # ADD BASE CPP /nologo /W3 /GX /Z7 /Od /D "WIN32" /D "_DEBUG" /D "_WINDOWS" /YX /FD /c -# ADD CPP /nologo /Za /W4 /Z7 /Od /I "../kernel" /I "../util" /I "../.." /I ".." /D "_WINDOWS" /D "WIN32" /D "_DEBUG" /D "BETA_CODE" /FR /YX"stdafx.h" /FD /c +# ADD CPP /nologo /Za /W4 /Z7 /Od /I "../kernel" /I "../util" /I "../.." /I ".." /D "_WINDOWS" /D "WIN32" /D "_DEBUG" /FR /YX"stdafx.h" /FD /c # ADD BASE RSC /l 0x407 # ADD RSC /l 0x407 BSC32=bscmake.exe @@ -73,7 +73,7 @@ BSC32=bscmake.exe # ADD BSC32 /nologo LIB32=link.exe -lib # ADD BASE LIB32 /nologo -# ADD LIB32 /nologo /out:"Debug\gamecode.lib" +# ADD LIB32 /nologo !ELSEIF "$(CFG)" == "gamecode - Win32 Profile" diff --git a/src/common/gamecode/laws.c b/src/common/gamecode/laws.c index 046e5be5d..e3e984020 100644 --- a/src/common/gamecode/laws.c +++ b/src/common/gamecode/laws.c @@ -1012,7 +1012,7 @@ demographics(void) if (r->land) for (dmd=r->land->demands;dmd;dmd=dmd->next) { if (dmd->value>0 && dmd->value < MAXDEMAND) { int rise = DMRISE; - if (buildingtype_exists(r, &bt_harbour)) rise = DMRISEHAFEN; + if (buildingtype_exists(r, bt_find("harbour"))) rise = DMRISEHAFEN; if (rand() % 100 < rise) dmd->value++; } } @@ -1375,11 +1375,11 @@ set_display(region * r, unit * u, strlist * S) cmistake(u, S->s, 5, MSG_PRODUCE); break; } - if (u->building->type == &bt_generic) { + if (u->building->type == bt_find("generic")) { cmistake(u, S->s, 279, MSG_PRODUCE); break; } - if (u->building->type == &bt_monument && u->building->display[0] != 0) { + if (u->building->type == bt_find("monument") && u->building->display[0] != 0) { cmistake(u, S->s, 29, MSG_PRODUCE); break; } @@ -1571,7 +1571,7 @@ set_name(region * r, unit * u, strlist * S) break; } - if (b->type == &bt_generic) { + if (b->type == bt_find("generic")) { cmistake(u, S->s, 278, MSG_EVENT); break; } @@ -1601,12 +1601,12 @@ set_name(region * r, unit * u, strlist * S) cmistake(u, S->s, 148, MSG_PRODUCE); break; } - if (u->building->type == &bt_generic) { + if (u->building->type == bt_find("generic")) { cmistake(u, S->s, 278, MSG_EVENT); break; } sprintf(buf, "Monument %d", u->building->no); - if (u->building->type == &bt_monument + if (u->building->type == bt_find("monument") && !strcmp(u->building->name, buf)) { cmistake(u, S->s, 29, MSG_EVENT); break; @@ -3265,7 +3265,7 @@ monthly_healing(void) #ifdef NEW_TAVERN struct building * b = inside_building(u); const struct building_type * btype = b?b->type:NULL; - if (btype == &bt_inn) { + if (btype == bt_find("inn")) { max_unit = max_unit * 3 / 2; } #endif @@ -3348,7 +3348,7 @@ age_factions(void) faction *f; for (f = factions; f; f = f->next) { - f->age = f->age + 1; + ++f->age; if (f->age < IMMUN_GEGEN_ANGRIFF) { add_message(&f->msgs, new_message(f, "newbieimmunity%i:turns", IMMUN_GEGEN_ANGRIFF - f->age)); diff --git a/src/common/gamecode/randenc.c b/src/common/gamecode/randenc.c index b2d939d28..680be4e9c 100644 --- a/src/common/gamecode/randenc.c +++ b/src/common/gamecode/randenc.c @@ -1213,7 +1213,7 @@ randomevents(void) if (!(u->race->ec_flags & NOGIVE)) { struct building * b = inside_building(u); const struct building_type * btype = b?b->type:NULL; - if (btype == &bt_blessedstonecircle) { + if (btype == bt_find("blessedstonecircle")) { int n, c = 0; for (n=0; nnumber; n++) if (rand()%100 < 2) { change_item(u, I_UNICORN, 1); diff --git a/src/common/gamecode/report.c b/src/common/gamecode/report.c index 0c5ddfcfc..afdfddbb2 100644 --- a/src/common/gamecode/report.c +++ b/src/common/gamecode/report.c @@ -1363,7 +1363,7 @@ statistics(FILE * F, region * r, faction * f) p / RECRUITFRACTION); rps(F, buf); - if (buildingtype_exists(r, &bt_caravan)) { + if (buildingtype_exists(r, bt_find("caravan"))) { sprintf(buf, "Luxusgüter zum angegebenen Preis: %d", (p * 2) / TRADE_FRACTION); } else { @@ -3156,7 +3156,7 @@ writemonument(void) for (r = regions; r; r = r->next) { for (b = r->buildings; b; b = b->next) { - if (b->type == &bt_monument && b->display && *b->display) { + if (b->type == bt_find("monument") && b->display && *b->display) { freset(b, FL_DH); count++; if(b->size > size[6]) { @@ -3203,7 +3203,7 @@ writemonument(void) j = 0; for (r = regions; r; r = r->next) { for (b = r->buildings; b; b = b->next) { - if (b->type == &bt_monument && b->display && *b->display && !fval(b, FL_DH)) { + if (b->type == bt_find("monument") && b->display && *b->display && !fval(b, FL_DH)) { j++; if(j == ra) { fprintf(F, "In %s", rname(b->region, NULL)); diff --git a/src/common/gamecode/study.c b/src/common/gamecode/study.c index 5e7d90dcf..1c5afd284 100644 --- a/src/common/gamecode/study.c +++ b/src/common/gamecode/study.c @@ -186,8 +186,8 @@ teach_unit(unit * teacher, unit * student, int nteaching, skill_t sk, /* Solange Akademien größenbeschränkt sind, sollte Lehrer und * Student auch in unterschiedlichen Gebäuden stehen dürfen */ - if (btype == &bt_academy - && student->building && student->building->type == &bt_academy) + if (btype == bt_find("academy") + && student->building && student->building->type == bt_find("academy")) { int j = study_cost(student, sk); j = max(50, j * 2); @@ -516,7 +516,7 @@ learn(void) struct building * b = inside_building(u); const struct building_type * btype = b?b->type:NULL; - if (btype == &bt_academy) { + if (btype == bt_find("academy")) { studycost = max(50, studycost * 2); } } diff --git a/src/common/items/items.dsp b/src/common/items/items.dsp index b41fcda3d..530983756 100644 --- a/src/common/items/items.dsp +++ b/src/common/items/items.dsp @@ -8,12 +8,12 @@ CFG=items - Win32 Debug !MESSAGE This is not a valid makefile. To build this project using NMAKE, !MESSAGE use the Export Makefile command and run !MESSAGE -!MESSAGE NMAKE /f "items-6.mak". +!MESSAGE NMAKE /f "items.mak". !MESSAGE !MESSAGE You can specify a configuration when running NMAKE !MESSAGE by defining the macro CFG on the command line. For example: !MESSAGE -!MESSAGE NMAKE /f "items-6.mak" CFG="items - Win32 Debug" +!MESSAGE NMAKE /f "items.mak" CFG="items - Win32 Debug" !MESSAGE !MESSAGE Possible choices for configuration are: !MESSAGE @@ -64,7 +64,7 @@ LIB32=link.exe -lib # PROP Intermediate_Dir "Debug" # PROP Target_Dir "" # ADD BASE CPP /nologo /W3 /GX /Z7 /Od /D "WIN32" /D "_DEBUG" /D "_WINDOWS" /YX /FD /c -# ADD CPP /nologo /Za /W4 /Z7 /Od /I "../kernel" /I "../util" /I "../.." /I ".." /D "_WINDOWS" /D "WIN32" /D "_DEBUG" /D "BETA_CODE" /FR /YX"stdafx.h" /FD /c +# ADD CPP /nologo /Za /W4 /Z7 /Od /I "../kernel" /I "../util" /I "../.." /I ".." /D "_WINDOWS" /D "WIN32" /D "_DEBUG" /FR /YX"stdafx.h" /FD /c # ADD BASE RSC /l 0x407 # ADD RSC /l 0x407 BSC32=bscmake.exe diff --git a/src/common/kernel/battle.c b/src/common/kernel/battle.c index 4eac4ccf0..2f61cf259 100644 --- a/src/common/kernel/battle.c +++ b/src/common/kernel/battle.c @@ -1602,7 +1602,7 @@ skilldiff(troop at, troop dt, int dist) #endif if (df->building) { - if (df->building->type == &bt_castle) { + if (df->building->type->flags & BTF_PROTECTION) { if(fspecial(au->faction, FS_SAPPER)) { /* Halbe Schutzwirkung, aufgerundet */ /* -1 because the tradepost has no protection value */ @@ -1824,7 +1824,7 @@ damage_building(battle *b, building *bldg, int damage_abs) /* Wenn Burg, dann gucken, ob die Leute alle noch in das Gebäude passen. */ - if (bldg->type == &bt_castle) { + if (bldg->type->flags & BTF_PROTECTION) { fighter *fi; bldg->sizeleft = bldg->size; diff --git a/src/common/kernel/build.c b/src/common/kernel/build.c index 943ae6540..011160ee5 100644 --- a/src/common/kernel/build.c +++ b/src/common/kernel/build.c @@ -440,24 +440,36 @@ build_road(region * r, unit * u, int size, direction_t d) return; } - if (rterrain(r) == T_SWAMP) + if (rterrain(r) == T_SWAMP) { /* wenn kein Damm existiert */ - if (!buildingtype_exists(r, &bt_dam)) { + static const struct building_type * bt_dam; + if (!bt_dam) bt_dam = bt_find("dam"); + assert(bt_dam); + if (!buildingtype_exists(r, bt_dam)) { cmistake(u, findorder(u, u->thisorder), 132, MSG_PRODUCE); return; } - if (rterrain(r) == T_DESERT) + } + if (rterrain(r) == T_DESERT) { + static const struct building_type * bt_caravan; + if (!bt_caravan) bt_caravan = bt_find("caravan"); + assert(bt_caravan); /* wenn keine Karawanserei existiert */ - if (!buildingtype_exists(r, &bt_caravan)) { + if (!buildingtype_exists(r, bt_caravan)) { cmistake(u, findorder(u, u->thisorder), 133, MSG_PRODUCE); return; } - if (rterrain(r) == T_GLACIER) + } + if (rterrain(r) == T_GLACIER) { + static const struct building_type * bt_tunnel; + if (!bt_tunnel) bt_tunnel = bt_find("tunnel"); + assert(bt_tunnel); /* wenn kein Tunnel existiert */ - if (!buildingtype_exists(r, &bt_tunnel)) { + if (!buildingtype_exists(r, bt_tunnel)) { cmistake(u, findorder(u, u->thisorder), 131, MSG_PRODUCE); return; } + } if (!get_pooled(u, r, R_STONE) && old_race(u->race) != RC_STONEGOLEM) { cmistake(u, findorder(u, u->thisorder), 151, MSG_PRODUCE); return; @@ -840,8 +852,8 @@ build_building(unit * u, const building_type * btype, int want) newbuilding = 1; } - if(b->type==&bt_castle) { - string2 = locale_string(u->faction->locale, bt_castle._name); + if (b->type->name) { + string2 = LOC(u->faction->locale, b->type->_name); } else { string2 = LOC(u->faction->locale, buildingtype(b, b->size)); if( newbuilding && b->type->maxsize != -1 ) @@ -857,8 +869,7 @@ build_building(unit * u, const building_type * btype, int want) set_string(&u->lastorder, buffer); b->size += built; - if (b->type == &bt_lighthouse) - update_lighthouse(b); + update_lighthouse(b); add_message(&u->faction->msgs, new_message( u->faction, "buildbuilding%b:building%u:unit%i:size", b, u, built)); diff --git a/src/common/kernel/building.c b/src/common/kernel/building.c index 4d5bf2e4c..a93fd1ab0 100644 --- a/src/common/kernel/building.c +++ b/src/common/kernel/building.c @@ -26,9 +26,11 @@ /* util includes */ #include +#include #include #include #include +#include /* libc includes */ #include @@ -65,13 +67,15 @@ bt_find(const char* name) btl = buildingtypes; while (btl && strncasecmp(btl->type->_name, name, strlen(name))) btl = btl->next; } + assert(btl); return btl?btl->type:NULL; } void -bt_register(const building_type * type) +bt_register(building_type * type) { struct building_typelist * btl = malloc(sizeof(building_type)); + if (type->init) type->init(type); btl->type = type; btl->next = buildingtypes; buildingtypes = btl; @@ -98,8 +102,11 @@ buildingtype(const building * b, int bsize) { const char * s = NULL; const building_type * btype = b->type; + static const struct building_type * bt_generic; + if (!bt_generic) bt_generic = bt_find("generic"); + assert(bt_generic); - if (btype == &bt_generic) { + if (btype == bt_generic) { const attrib *a = a_find(b->attribs, &at_building_generic_type); if (a) s = (const char*)a->data.v; } @@ -191,6 +198,26 @@ enum { }; #endif +static int +sm_smithy(const unit * u, const region * r, skill_t sk, int value) /* skillmod */ +{ + if (sk==SK_WEAPONSMITH || sk==SK_ARMORER) { + if (u->region == r) return value + 1; + } + return value; +} +static int +mm_smithy(const unit * u, const resource_type * rtype, int value) /* material-mod */ +{ + if (rtype == oldresourcetype[R_IRON]) return value * 2; + return value; +} +static void +init_smithy(struct building_type * bt) +{ + a_add(&bt->attribs, make_skillmod(NOSKILL, SMF_PRODUCTION, sm_smithy, 0, 0)); + a_add(&bt->attribs, make_matmod(mm_smithy)); +} static const char * castle_name(int bsize) { @@ -204,8 +231,13 @@ castle_name(int bsize) "castle", "fortress", "citadel" }; - const construction * ctype = bt_castle.construction; + const construction * ctype; + static const struct building_type * bt_castle; int i = 0; + + if (!bt_castle) bt_castle = bt_find("castle"); + assert(bt_castle); + ctype = bt_castle->construction; while (ctype && ctype->maxsize != -1 && ctype->maxsize<=bsize) { @@ -216,546 +248,6 @@ castle_name(int bsize) return fname[i]; } -static requirement castle_req[] = { - { R_STONE, 1, 0.5 }, - { NORESOURCE, 0, 0.0 }, -}; - -#if LARGE_CASTLES -static construction castle_bld[MAXBUILDINGS] = { - { SK_BUILDING, 1, 2, 1, castle_req, &castle_bld[1] }, - { SK_BUILDING, 1, 8, 1, castle_req, &castle_bld[2] }, - { SK_BUILDING, 2, 40, 1, castle_req, &castle_bld[3] }, - { SK_BUILDING, 3, 200, 1, castle_req, &castle_bld[4] }, - { SK_BUILDING, 4, 1000, 1, castle_req, &castle_bld[5] }, - { SK_BUILDING, 5, 5000, 1, castle_req, &castle_bld[6] }, - { SK_BUILDING, 6, -1, 1, castle_req, NULL } -}; -#else -static construction castle_bld[MAXBUILDINGS] = { - { SK_BUILDING, 1, 2, 1, castle_req, &castle_bld[1] }, - { SK_BUILDING, 2, 8, 1, castle_req, &castle_bld[2] }, - { SK_BUILDING, 3, 40, 1, castle_req, &castle_bld[3] }, - { SK_BUILDING, 4, 200, 1, castle_req, &castle_bld[4] }, - { SK_BUILDING, 5, 1000, 1, castle_req, &castle_bld[5] }, - { SK_BUILDING, 6, -1, 1, castle_req, NULL } -}; -#endif - -building_type bt_castle = { - "castle", - BFL_NONE, - 1, 4, -1, - NULL, - &castle_bld[0], - castle_name -}; - - -/** Building: Lighthouse */ -static const maintenance lighthouse_keep[] = { - { R_SILVER, 100, MTF_VITAL }, - { NORESOURCE, 0, MTF_NONE }, -}; -static requirement lighthouse_req[] = { - { R_IRON, 1, 0.5 }, - { R_WOOD, 1, 0.5 }, - { R_STONE, 2, 0.5 }, - { R_SILVER, 100, 0.0 }, - { NORESOURCE, 0, 0.0 }, -}; -static const construction lighthouse_bld = { - SK_BUILDING, 3, - -1, 1, lighthouse_req, - NULL -}; -building_type bt_lighthouse = { - "lighthouse", - BFL_NONE, - 1, 4, -1, - lighthouse_keep, - &lighthouse_bld -}; - - -/** Building: Mine */ -static const maintenance mine_keep[] = { - /* resource, number, flags */ - { R_SILVER, 500, MTF_VITAL }, - { NORESOURCE, 0, MTF_NONE }, -}; -static requirement mine_req[] = { - /* resource, number, recycle */ - { R_IRON, 1, 0.5 }, - { R_WOOD, 10, 0.5 }, - { R_STONE, 5, 0.5 }, - { R_SILVER, 250, 0.0 }, - { NORESOURCE, 0, 0.0 }, -}; -static const construction mine_bld = { - SK_BUILDING, 4, /* skill, minskill */ - -1, 1, mine_req, /* maxsize, reqsize, required */ - NULL /* improvement */ -}; -building_type bt_mine = { - "mine", /* _name */ - BFL_NONE, /* flags */ - 1, -1, -1, /* capac, maxcap, maxsize */ - mine_keep, /* maintenance */ - &mine_bld, /* construction */ - NULL /* name() */ -}; - - -/** Building: Quarry */ -static const maintenance quarry_keep[] = { - /* resource, number, flags */ - { R_SILVER, 250, MTF_VITAL }, - { NORESOURCE, 0, MTF_NONE }, -}; -static requirement quarry_req[] = { - /* resource, number, recycle */ - { R_IRON, 1, 0.5 }, - { R_WOOD, 5, 0.5 }, - { R_STONE, 1, 0.5 }, - { R_SILVER, 250, 0.0 }, - { NORESOURCE, 0, 0.0 }, -}; -static const construction quarry_bld = { - SK_BUILDING, 2, /* skill, minskill */ - -1, 1, quarry_req, /* maxsize, reqsize, required */ - NULL /* improvement */ -}; -building_type bt_quarry = { - "quarry", /* _name */ - BFL_NONE, /* flags */ - 1, -1, -1, /* capac, maxcap, maxsize */ - quarry_keep, /* maintenance */ - &quarry_bld, /* construction */ - NULL /* name() */ -}; - - -/** Building: harbour */ -static const maintenance harbour_keep[] = { - /* resource, number, flags */ - { R_SILVER, 250, MTF_VITAL }, - { NORESOURCE, 0, MTF_NONE }, -}; -static requirement harbour_req[] = { - /* resource, number, recycle */ - { R_WOOD, 125, 0.5 }, - { R_STONE, 125, 0.5 }, - { R_SILVER, 6250, 0.0 }, - { NORESOURCE, 0, 0.0 }, -}; -static const construction harbour_bld = { - SK_BUILDING, 3, /* skill, minskill */ - 25, 25, harbour_req, /* maxsize, reqsize, required for size */ - NULL /* improvement */ -}; -building_type bt_harbour = { - "harbour", /* _name */ - BFL_NONE, /* flags */ - 1, 25, 25, /* capac/size, maxcapac, maxsize */ - harbour_keep, /* maintenance */ - &harbour_bld, /* construction */ - NULL /* name() */ -}; - - -/** Building: academy */ -static const maintenance academy_keep[] = { - /* resource, number, flags */ - { R_SILVER, 1000, MTF_VITAL }, - { NORESOURCE, 0, MTF_NONE }, -}; -static requirement academy_req[] = { - /* resource, number, recycle */ - { R_WOOD, 125, 0.5 }, - { R_STONE, 125, 0.5 }, - { R_IRON, 25, 0.0 }, - { R_SILVER, 12500, 0.0 }, - { NORESOURCE, 0, 0.0 }, -}; -static const construction academy_bld = { - SK_BUILDING, 3, /* skill, minskill */ - 25, 25, academy_req, /* maxsize, reqsize, required for size */ - NULL /* improvement */ -}; -building_type bt_academy = { - "academy", /* _name */ - BFL_NONE, /* flags */ - -1, 25, 25, /* capac/size, maxcapac, maxsize */ - academy_keep, /* maintenance */ - &academy_bld, /* construction */ - NULL /* name() */ -}; - - -/** Building: magictower */ -static const maintenance magictower_keep[] = { - /* resource, number, flags */ - { R_SILVER, 1000, MTF_VITAL }, - { NORESOURCE, 0, MTF_NONE }, -}; -static requirement magictower_req[] = { - /* resource, number, recycle */ - { R_WOOD, 150, 0.5 }, - { R_STONE, 250, 0.5 }, - { R_MALLORN, 100, 0.5 }, - { R_IRON, 150, 0.5 }, - { R_EOG, 100, 0.5 }, - { R_SILVER, 25000, 0.0 }, - { NORESOURCE, 0, 0.0 }, -}; - -static const construction magictower_bld = { - SK_BUILDING, 5, /* skill, minskill */ - 50, 50, magictower_req, /* maxsize, reqsize, required for size */ - NULL /* improvement */ -}; -building_type bt_magictower = { - "magictower", /* _name */ - BFL_NONE, /* flags */ - -1, 2, 50, /* capac/size, maxcapac, maxsize */ - magictower_keep, /* maintenance */ - &magictower_bld, /* construction */ - NULL /* name() */ -}; - - -/** Building: smithy */ -static const maintenance smithy_keep[] = { - /* resource, number, flags */ - { R_SILVER, 300, MTF_VITAL }, - { R_WOOD, 1, MTF_NONE }, - { NORESOURCE, 0, MTF_NONE }, -}; -static requirement smithy_req[] = { - /* resource, number, recycle */ - { R_WOOD, 5, 0.5 }, - { R_STONE, 5, 0.5 }, - { R_IRON, 2, 0.5 }, - { R_SILVER, 200, 0.0 }, - { NORESOURCE, 0, 0.0 }, -}; -static const construction smithy_bld = { - SK_BUILDING, 3, /* skill, minskill */ - -1, 1, smithy_req, /* maxsize, reqsize, required for size */ - NULL /* improvement */ -}; -building_type bt_smithy = { - "smithy", /* _name */ - BFL_NONE, /* flags */ - 1, -1, -1, /* capac/size, maxcapac, maxsize */ - smithy_keep, /* maintenance */ - &smithy_bld, /* construction */ - NULL /* name() */ -}; - - -/** Building: sawmill */ -static const maintenance sawmill_keep[] = { - /* resource, number, flags */ - { R_SILVER, 250, MTF_VITAL }, - { NORESOURCE, 0, MTF_NONE }, -}; -static requirement sawmill_req[] = { - /* resource, number, recycle */ - { R_WOOD, 5, 0.5 }, - { R_STONE, 5, 0.5 }, - { R_IRON, 3, 0.5 }, - { R_SILVER, 200, 0.0 }, - { NORESOURCE, 0, 0.0 }, -}; -static const construction sawmill_bld = { - SK_BUILDING, 3, /* skill, minskill */ - -1, 1, sawmill_req, /* maxsize, reqsize, required for size */ - NULL /* improvement */ -}; -building_type bt_sawmill = { - "sawmill", /* _name */ - BFL_NONE, /* flags */ - 1, -1, -1, /* capac/size, maxcapac, maxsize */ - sawmill_keep, /* maintenance */ - &sawmill_bld, /* construction */ - NULL /* name() */ -}; - - -/** Building: stables */ -static const maintenance stables_keep[] = { - /* resource, number, flags */ - { R_SILVER, 150, MTF_VITAL }, - { NORESOURCE, 0, MTF_NONE }, -}; -static requirement stables_req[] = { - /* resource, number, recycle */ - { R_WOOD, 4, 0.5 }, - { R_STONE, 2, 0.5 }, - { R_IRON, 1, 0.5 }, - { R_SILVER, 100, 0.0 }, - { NORESOURCE, 0, 0.0 }, -}; -static const construction stables_bld = { - SK_BUILDING, 2, /* skill, minskill */ - -1, 1, stables_req, /* maxsize, reqsize, required for size */ - NULL /* improvement */ -}; -building_type bt_stables = { - "stables", /* _name */ - BFL_NONE, /* flags */ - 1, -1, -1, /* capac/size, maxcapac, maxsize */ - stables_keep, /* maintenance */ - &stables_bld, /* construction */ - NULL /* name() */ -}; - - -static requirement monument_req[] = { - /* resource, number, recycle */ - { R_WOOD, 1, 0.5 }, - { R_STONE, 1, 0.5 }, - { R_IRON, 1, 0.5 }, - { R_SILVER, 400, 0.0 }, - { NORESOURCE, 0, 0.0 }, -}; -static const construction monument_bld = { - SK_BUILDING, 4, /* skill, minskill */ - -1, 1, monument_req, /* maxsize, reqsize, required for size */ - NULL /* improvement */ -}; -building_type bt_monument = { - "monument", /* _name */ - BFL_NONE, /* flags */ - 1, -1, -1, /* capac/size, maxcapac, maxsize */ - NULL, /* maintenance */ - &monument_bld, /* construction */ - NULL /* name() */ -}; - - -/** Building: dam */ -static const maintenance dam_keep[] = { - /* resource, number, flags */ - { R_WOOD, 3, MTF_NONE }, - { R_SILVER, 1000, MTF_VITAL }, - { NORESOURCE, 0, MTF_NONE }, -}; -static requirement dam_req[] = { - /* resource, number, recycle */ - { R_IRON, 50, 0.5 }, - { R_WOOD, 500, 0.5 }, - { R_STONE, 250, 0.5 }, - { R_SILVER, 25000, 0.0 }, - { NORESOURCE, 0, 0.0 }, -}; -static const construction dam_bld = { - SK_BUILDING, 4, /* skill, minskill */ - 50, 50, dam_req, /* maxsize, reqsize, required for size */ - NULL /* improvement */ -}; -building_type bt_dam = { - "dam", /* _name */ - BFL_NONE, /* flags */ - 1, -1, 50, /* capac/size, maxcapac, maxsize */ - dam_keep, /* maintenance */ - &dam_bld, /* construction */ - NULL /* name() */ -}; - - -/** Building: caravan */ -static const maintenance caravan_keep[] = { - /* resource, number, flags */ - { R_HORSE, 2, MTF_NONE }, - { R_SILVER, 3000, MTF_VITAL }, - { NORESOURCE, 0, MTF_NONE }, -}; -static requirement caravan_req[] = { - /* resource, number, recycle */ - { R_IRON, 10, 0.5 }, - { R_WOOD, 50, 0.5 }, - { R_STONE, 10, 0.5 }, - { R_SILVER, 5000, 0.0 }, - { NORESOURCE, 0, 0.0 }, -}; -static const construction caravan_bld = { - SK_BUILDING, 2, /* skill, minskill */ - 10, 10, caravan_req, /* maxsize, reqsize, required for size */ - NULL /* improvement */ -}; -building_type bt_caravan = { - "caravan", /* _name */ - BFL_NONE, /* flags */ - 1, -1, 10, /* capac/size, maxcapac, maxsize */ - caravan_keep, /* maintenance */ - &caravan_bld, /* construction */ - NULL /* name() */ -}; - - -/** Building: tunnel */ -static const maintenance tunnel_keep[] = { - /* resource, number, flags */ - { R_STONE, 2, MTF_NONE }, - { R_SILVER, 100, MTF_VITAL }, - { NORESOURCE, 0, MTF_NONE }, -}; -static requirement tunnel_req[] = { - /* resource, number, recycle */ - { R_IRON, 100, 0.5 }, - { R_WOOD, 500, 0.5 }, - { R_STONE, 1000, 0.5 }, - { R_SILVER,30000, 0.0 }, - { NORESOURCE, 0, 0.0 }, -}; -static const construction tunnel_bld = { - SK_BUILDING, 6, /* skill, minskill */ - 100, 100, tunnel_req, /* maxsize, reqsize, required for size */ - NULL /* improvement */ -}; -building_type bt_tunnel = { - "tunnel", /* _name */ - BFL_NONE, /* flags */ - 1, -1, 100, /* capac/size, maxcapac, maxsize */ - tunnel_keep, /* maintenance */ - &tunnel_bld, /* construction */ - NULL /* name() */ -}; - - -/** Building: inn */ -static const maintenance inn_keep[] = { - /* resource, number, flags */ - { R_SILVER, 5, MTF_VARIABLE|MTF_VITAL }, - { NORESOURCE, 0, MTF_NONE }, -}; -static requirement inn_req[] = { - /* resource, number, recycle */ - { R_IRON, 10, 0.5 }, - { R_WOOD, 30, 0.5 }, - { R_STONE, 40, 0.5 }, - { R_SILVER, 2000, 0.0 }, - { NORESOURCE, 0, 0.0 }, -}; -static const construction inn_bld = { - SK_BUILDING, 2, /* skill, minskill */ - -1, 10, inn_req, /* maxsize, reqsize, required for size */ - NULL /* improvement */ -}; -building_type bt_inn = { - "inn", /* _name */ - BFL_NONE, /* flags */ - 1, -1, -1, /* capac/size, maxcapac, maxsize */ - inn_keep, /* maintenance */ - &inn_bld, /* construction */ - NULL /* name() */ -}; - - -/** Building: stonecircle */ -static requirement stonecircle_req[] = { - /* resource, number, recycle */ - { R_WOOD, 500, 0.5 }, - { R_STONE, 500, 0.5 }, - { R_SILVER, 0, 0.0 }, - { NORESOURCE, 0, 0.0 }, -}; -static const construction stonecircle_bld = { - SK_BUILDING, 2, /* skill, minskill */ - 100, 100, stonecircle_req, /* maxsize, reqsize, required for size */ - NULL /* improvement */ -}; -building_type bt_stonecircle = { - "stonecircle", /* _name */ - BFL_NONE, /* flags */ - -1, -1, 100, /* capac/size, maxcapac, maxsize */ - NULL, /* maintenance */ - &stonecircle_bld, /* construction */ - NULL /* name() */ -}; - - -/** Building: blessedstonecircle */ -building_type bt_blessedstonecircle = { - "blessedstonecircle", /* _name */ - BTF_NOBUILD, /* flags */ - -1, -1, 100, /* capac/size, maxcapac, maxsize */ - NULL, /* maintenance */ - &stonecircle_bld, /* construction */ - NULL /* name() */ -}; - - -/** Building: illusion */ -building_type bt_illusion = { - "illusioncastle", /* _name */ - BTF_NOBUILD, /* flags */ - 0, 0, 0, /* capac/size, maxcapac, maxsize */ - NULL, /* maintenance */ - NULL, /* construction */ - NULL /* name() */ -}; - -/** Building: Generisches Gebäude */ -building_type bt_generic = { - "genericbuilding", /* _name */ - BTF_NOBUILD, /* flags */ - -1, -1, 1, /* capac/size, maxcapac, maxsize */ - NULL, /* maintenance */ - NULL, /* construction */ - NULL /* name() */ -}; - -/* -name, maxsize, minskill, kapazitaet, -M_EISEN, M_HOLZ, M_STEIN, M_SILBER, M_EOG, M_MALLORN, M_MAX_MAT, -unterhalt, per_size, spezial, unterhalt_spezial, flags -buildingt buildingdaten[MAXBUILDINGTYPES] = -{ - {"Burg", -1, 1, -1, {0, 0, 1, 0, 0, 0}, 0, 0, 0, 0, 0}, - {"Leuchtturm", -1, 3, 4, {1, 1, 2, 100, 0, 0}, 100, 0, 0, 0, 0}, - {"Bergwerk", -1, 4, -1, {1, 10, 5, 250, 0, 0}, 500, 0, 0, 0, 0}, - {"Steinbruch", -1, 2, -1, {1, 5, 1, 250, 0, 0}, 250, 0, 0, 0, 0}, - {"Hafen", 25, 3, -1, {0, 5, 5, 250, 0, 0}, 250, 0, 0, 0, 0}, - {"Akademie", 25, 3, 25, {1, 5, 5, 500, 0, 0}, 1000, 0, 0, 0, 0}, - {"Magierturm", 50, 5, 2, {3, 3, 5, 500, 2, 2}, 1000, 0, 0, 0, 0}, - {"Schmiede", -1, 3, -1, {2, 5, 5, 200, 0, 0}, 300, 0, I_WOOD, 1, 0}, - {"Sägewerk", -1, 3, -1, {3, 5, 5, 200, 0, 0}, 250, 0, 0, 0, 0}, - {"Pferdezucht", -1, 2, -1, {1, 4, 2, 100, 0, 0}, 150, 0, 0, 0, 0}, - {"Monument", -1, 4, -1, {1, 1, 1, 400, 0, 0}, 0, 0, 0, 0, 0}, - {"Damm", 50, 4, -1, {1, 10, 5, 500, 0, 0}, 1000, 0, I_WOOD, 3, 0}, - {"Karawanserei", 10, 2, -1, {1, 5, 1, 500, 0, 0}, 3000, 0, I_HORSE, 2, 0}, - {"Tunnel", 100, 6, -1, {1, 5, 10, 300, 0, 0}, 100, 0, I_STONE, 2, 0}, - {"Taverne", -1, 2, 10, {1, 3, 4, 200, 0, 0}, 0, 5, 0, 0, 0}, - {"Tempel", 100, 5, -1, {0, 5, 5, 0, 0, 0}, 0, 0, 0, 0, 0}, - {"Gesegneter Tempel", 100, 5, -1, {0, 5, 5, 0, 0, 0}, 0, 0, 0, 0, NO_BUILD}, - {"Traumschlößchen", 0, 0, 0, {0, 0, 0, 0, 0, 0}, 0, 0, 0, 0, NO_BUILD} -}; -*/ -const building_type * oldbuildings[MAXBUILDINGTYPES] = { - &bt_castle, - &bt_lighthouse, - &bt_mine, - &bt_quarry, - &bt_harbour, - &bt_academy, - &bt_magictower, - &bt_smithy, - &bt_sawmill, - &bt_stables, - &bt_monument, - &bt_dam, - &bt_caravan, - &bt_tunnel, - &bt_inn, - &bt_stonecircle, - &bt_blessedstonecircle, - &bt_illusion, -}; - /* for finding out what was meant by a particular building string */ static local_names * bnames; @@ -786,27 +278,139 @@ findbuildingtype(const char * name, const locale * lang) return (const building_type*)i; } -static int -sm_smithy(const unit * u, const region * r, skill_t sk, int value) /* skillmod */ +static int +tagend(struct xml_stack * stack) { - if (sk==SK_WEAPONSMITH || sk==SK_ARMORER) { - if (u->region == r) return value + 1; + const xml_tag * tag = stack->tag; + if (strcmp(tag->name, "building")==0) { + bt_register((building_type*)stack->state); + stack->state = 0; } - return value; + return XML_OK; } -static int -mm_smithy(const unit * u, const resource_type * rtype, int value) /* material-mod */ +static int +tagbegin(struct xml_stack * stack) { - if (rtype == oldresourcetype[R_IRON]) return value * 2; - return value; + building_type * bt = (building_type *)stack->state; + const xml_tag * tag = stack->tag; + if (strcmp(tag->name, "building")==0) { + const char * name = xml_value(tag, "name"); + if (name!=NULL) { + const char * x; + bt = stack->state = calloc(sizeof(building_type), 1); + bt->_name = strdup(name); + bt->magres = xml_ivalue(tag, "magres"); + bt->magresbonus = xml_ivalue(tag, "magresbonus"); + bt->fumblebonus = xml_ivalue(tag, "fumblebonus"); + bt->auraregen = xml_fvalue(tag, "auraregen"); + if ((x = xml_value(tag, "capacity"))!=0) bt->capacity = atoi(x); + else bt->capacity = -1; + if ((x = xml_value(tag, "maxcapacity"))!=0) bt->maxcapacity = atoi(x); + else bt->maxcapacity = -1; + if ((x = xml_value(tag, "maxsize"))!=0) bt->maxsize = atoi(x); + else bt->maxsize = -1; + + if (xml_bvalue(tag, "nodestroy")) bt->flags |= BTF_INDESTRUCTIBLE; + if (xml_bvalue(tag, "nobuild")) bt->flags |= BTF_NOBUILD; + if (xml_bvalue(tag, "unique")) bt->flags |= BTF_UNIQUE; + if (xml_bvalue(tag, "decay")) bt->flags |= BTF_DECAY; + if (xml_bvalue(tag, "magic")) bt->flags |= BTF_MAGIC; + if (xml_bvalue(tag, "protection")) bt->flags |= BTF_PROTECTION; + } + } else if (bt!=NULL) { + if (strcmp(tag->name, "construction")==0) { + const char * x; + construction * con = calloc(sizeof(construction), 1); + if ((x=xml_value(tag, "maxsize"))!=0) con->maxsize = atoi(x); + else con->maxsize = -1; + if ((x=xml_value(tag, "minskill"))!=0) con->minskill = atoi(x); + else con->minskill = -1; + if ((x=xml_value(tag, "reqsize"))!=0) con->reqsize = atoi(x); + else con->reqsize = -1; + con->skill = sk_find(xml_value(tag, "skill")); + bt->construction = con; + } else if (strcmp(tag->name, "function")==0) { + const char * name = xml_value(tag, "name"); + const char * value = xml_value(tag, "value"); + if (name && value) { + pf_generic fun = get_function(value); + if (fun==NULL) { + log_error(("unknown function value '%s=%s' for building %s\n", name, value, bt->_name)); + } else { + if (strcmp(name, "name")==0) { + bt->name = (const char * (*)(int size))fun; + } else if (strcmp(name, "init")==0) { + bt->init = (void (*)(struct building_type*))fun; + } else { + log_error(("unknown function type '%s=%s' for building %s\n", name, value, bt->_name)); + } + } + } + } else if (strcmp(tag->name, "maintenance")==0) { + size_t len = 0; + if (bt->maintenance) { + const resource_type * rtype; + maintenance * mt = (maintenance*)bt->maintenance; + resource_t type = NORESOURCE; + while (mt[len].number) ++len; + mt = realloc(mt, sizeof(maintenance)*(len+1)); + mt[len+1].number = 0; + mt[len].number = xml_ivalue(tag, "amount"); + rtype = rt_find(xml_value(tag, "type")); + for (type=0;type!=MAX_RESOURCES;++type) { + if (oldresourcetype[type]==rtype) { + mt[len].type = type; + break; + } + } + if (xml_bvalue(tag, "variable")) mt[len].flags |= MTF_VARIABLE; + if (xml_bvalue(tag, "vital")) mt[len].flags |= MTF_VITAL; + } + } else if (strcmp(tag->name, "requirement")==0) { + construction * con = (construction *)bt->construction; + if (con!=NULL) { + const resource_type * rtype; + resource_t type = NORESOURCE; + requirement * radd = con->materials; + if (radd) { + requirement * rnew; + int size; + for (size=0;radd[size++].number;); + rnew = malloc(sizeof(requirement) * (size+2)); + memcpy(rnew, radd, size*sizeof(requirement)); + free(radd); + con->materials = rnew; + radd = rnew+size; + } else { + radd = con->materials = calloc(sizeof(requirement), 2); + } + radd[0].number = xml_ivalue(tag, "quantity"); + rtype = rt_find(xml_value(tag, "type")); + for (type=0;type!=MAX_RESOURCES;++type) { + if (oldresourcetype[type]==rtype) { + radd[0].type = type; + break; + } + } + radd[1].number = 0; + radd[1].type = 0; + } + } + } + return XML_OK; } +static xml_callbacks xml_buildings = { + tagbegin, tagend, NULL +}; + void -init_buildings(void) +register_buildings(void) { - a_add(&bt_smithy.attribs, make_skillmod(NOSKILL, SMF_PRODUCTION, sm_smithy, 0, 0)); - a_add(&bt_smithy.attribs, make_matmod(mm_smithy)); + xml_register(&xml_buildings, "eressea building", 0); + register_function((pf_generic)init_smithy, "init_smithy"); + register_function((pf_generic)castle_name, "castle_name"); } void @@ -939,7 +543,7 @@ new_building(const struct building_type * btype, region * r, const struct locale { static char buffer[IDSIZE + 1 + NAMESIZE + 1]; - if(b->type==&bt_castle) + if (b->type->name) sprintf(buffer, "%s", locale_string(lang, btype->_name)); else sprintf(buffer, "%s", LOC(lang, buildingtype(b, 0))); @@ -959,7 +563,7 @@ destroy_building(building * b) } b->size = 0; - if (b->type == &bt_lighthouse) update_lighthouse(b); + update_lighthouse(b); bunhash(b); #if 0 /* Memoryleak. Aber ohne klappt das Rendern nicht! */ @@ -976,17 +580,20 @@ int buildingeffsize(const building * b, boolean img) { int i = b->size, n = 0; - const building_type * btype = &bt_castle; - const construction * cons = btype->construction; + const construction * cons; + static const struct building_type * bt_castle; + if (!bt_castle) bt_castle = bt_find("castle"); + assert(bt_castle); if (b==NULL) return 0; - if (b->type!=btype) { + if (b->type!=bt_castle) { if (img) { const attrib * a = a_find(b->attribs, &at_icastle); - if (!a || a->data.v != btype) return 0; + if (!a || a->data.v != bt_castle) return 0; } else return 0; } + cons = bt_castle->construction; assert(cons); while (cons && cons->maxsize != -1 && i>=cons->maxsize) { @@ -995,10 +602,7 @@ buildingeffsize(const building * b, boolean img) ++n; } - if (n>0) - return n; - return 0; - + return n; } unit * @@ -1029,3 +633,64 @@ buildingowner(const region * r, const building * b) fset(first, FL_OWNER); return first; } + +#ifdef BETA_CODE +void +xml_writebuildings(void) +{ + FILE * F = fopen("buildings.xml", "w"); + building_typelist *btl= buildingtypes; + while (btl) { + int i; + const building_type * bt = btl->type; + fprintf(F, "_name); + if (bt->capacity>=0) fprintf(F, " capacity=\"%d\"", bt->capacity); + if (bt->maxcapacity>=0) fprintf(F, " maxcapacity=\"%d\"", bt->maxcapacity); + if (bt->maxsize>=0) fprintf(F, " maxsize=\"%d\"", bt->maxsize); + if (bt->flags & BTF_INDESTRUCTIBLE) fputs(" nodestroy", F); + if (bt->flags & BTF_NOBUILD) fputs(" nobuild", F); + if (bt->flags & BTF_UNIQUE) fputs(" unique", F); + if (bt->flags & BTF_DECAY) fputs(" decay", F); + if (bt->flags & BTF_PROTECTION) fputs(" protection", F); + if (bt->flags & BTF_MAGIC) fputs(" magic", F); + fputs(">\n", F); + if (bt->name) { + const char * name = get_functionname((pf_generic)bt->name); + assert(name); + fprintf(F, "\t\n", + name); + } + if (bt->init) { + const char * name = get_functionname((pf_generic)bt->init); + assert(name); + fprintf(F, "\t\n", + name); + } + for (i=0;bt->maintenance && bt->maintenance[i].number;++i) { + const maintenance * m = bt->maintenance + i; + fprintf(F, "\ttype]->_name[0], m->number); + if (m->flags & MTF_VARIABLE) fputs(" variable", F); + if (m->flags & MTF_VITAL) fputs(" vital", F); + fputs(">\n", F); + } + if (bt->construction) { + fprintf(F, "\tconstruction->skill, NULL), bt->construction->minskill, + bt->construction->reqsize); + if (bt->construction->maxsize>=0) fprintf(F, " maxsize=\"%d\"", bt->construction->maxsize); + fputs(">\n", F); + for (i=0;bt->construction->materials[i].number!=0;++i) { + fprintf(F, "\t\t\n", + oldresourcetype[bt->construction->materials[i].type]->_name[0], + bt->construction->materials[i].number); + } + fputs("\t\n", F); + } + fputs("\n\n", F); + btl=btl->next; + } + fclose(F); +} + +#endif diff --git a/src/common/kernel/building.h b/src/common/kernel/building.h index ee7ee7ac9..3ad92a95c 100644 --- a/src/common/kernel/building.h +++ b/src/common/kernel/building.h @@ -32,24 +32,31 @@ typedef struct maintenance { #define BTF_UNIQUE 0x04 /* only one per struct region (harbour) */ #define BTF_DECAY 0x08 /* decays when not occupied */ #define BTF_DYNAMIC 0x10 /* dynamic type, needs bt_write */ +#define BTF_PROTECTION 0x20 /* protection in combat */ +#define BTF_MAGIC 0x40 /* magical effect */ typedef struct building_type { const char * _name; int flags; /* flags */ int capacity; /* Kapazität pro Größenpunkt */ - int maxcapacity; /* Max. Kapazität */ - int maxsize; /* how big can it get, with all the extensions? */ + int maxcapacity; /* Max. Kapazität */ + int maxsize; /* how big can it get, with all the extensions? */ + int magres; /* how well it resists against spells */ + int magresbonus; /* bonus it gives the target against spells */ + int fumblebonus; /* bonus that reduces fumbling */ + double auraregen; /* modifier for aura regeneration inside building */ const struct maintenance * maintenance; /* array of requirements */ const struct construction * construction; /* construction of 1 building-level */ const char * (*name)(int size); + void (*init)(struct building_type*); struct attrib * attribs; } building_type; extern const building_type * bt_find(const char* name); -extern void bt_register(const building_type * type); -extern void init_buildings(void); +extern void bt_register(building_type * type); +extern void register_buildings(void); typedef struct building_typelist { struct building_typelist * next; @@ -99,26 +106,6 @@ void build_building(struct unit * u, const struct building_type * typ, int size) /* Alte Gebäudetypen: */ -extern struct building_type bt_castle; -extern struct building_type bt_lighthouse; -extern struct building_type bt_mine; -extern struct building_type bt_quarry; -extern struct building_type bt_harbour; -extern struct building_type bt_academy; -extern struct building_type bt_magictower; -extern struct building_type bt_smithy; -extern struct building_type bt_sawmill; -extern struct building_type bt_stables; -extern struct building_type bt_monument; -extern struct building_type bt_dam; -extern struct building_type bt_caravan; -extern struct building_type bt_tunnel; -extern struct building_type bt_inn; -extern struct building_type bt_stonecircle; -extern struct building_type bt_blessedstonecircle; -extern struct building_type bt_illusion; -extern struct building_type bt_generic; - /* old functions, still in build.c: */ int buildingeffsize(const building * b, boolean img); void bhash(struct building * b); @@ -133,7 +120,6 @@ extern void bt_write(FILE * F, const building_type * bt); extern struct building_type * bt_make(const char * name, int flags, int capacity, int maxcapacity, int maxsize); #include "build.h" -extern const struct building_type * oldbuildings[MAXBUILDINGTYPES]; #define NOBUILDING NULL extern void * resolve_building(void * data); diff --git a/src/common/kernel/eressea.c b/src/common/kernel/eressea.c index ac08cab68..29a969ccc 100644 --- a/src/common/kernel/eressea.c +++ b/src/common/kernel/eressea.c @@ -971,6 +971,11 @@ update_lighthouse(building * lh) region * r = lh->region; int d = (int)log10(lh->size) + 1; int x, y; + static const struct building_type * bt_lighthouse; + if (!bt_lighthouse) bt_lighthouse = bt_find("lighthouse"); + assert(bt_lighthouse); + + if (lh->type!=bt_lighthouse) return; for (x=-d;x<=d;++x) { for (y=-d;y<=d;++y) { @@ -1490,8 +1495,9 @@ buildingname (const building * b) building * largestbuilding (const region * r, boolean img) { - const building_type * btype = &bt_castle; /* TODO: parameter der funktion? */ + static const building_type * btype = NULL; building *b, *best = NULL; + if (!btype) btype = bt_find("castle"); /* TODO: parameter der funktion? */ /* durch die verw. von '>' statt '>=' werden die aelteren burgen * bevorzugt. */ @@ -1720,7 +1726,7 @@ check_leuchtturm(region * r, faction * f) building *b = (building *)a->data.v; region *r2 = b->region; - assert(b->type == &bt_lighthouse); + assert(b->type == bt_find("lighthouse")); if (fval(b, BLD_WORKING) && b->size >= 10) { int c = 0; unit *u; @@ -2174,41 +2180,6 @@ attrib_type at_germs = { void attrib_init(void) { - /* Gebäudetypen registrieren */ - init_buildings(); - bt_register(&bt_castle); - bt_register(&bt_lighthouse); - bt_register(&bt_mine); - bt_register(&bt_quarry); - bt_register(&bt_harbour); - bt_register(&bt_academy); - bt_register(&bt_magictower); - bt_register(&bt_smithy); - bt_register(&bt_sawmill); - bt_register(&bt_stables); - bt_register(&bt_monument); - bt_register(&bt_dam); - bt_register(&bt_caravan); - bt_register(&bt_tunnel); - bt_register(&bt_inn); - bt_register(&bt_stonecircle); - bt_register(&bt_blessedstonecircle); - bt_register(&bt_illusion); - bt_register(&bt_generic); - bt_register(&bt_caldera); - -#ifdef NOXMLBOATS - /* Schiffstypen registrieren: */ - st_register(&st_boat); - st_register(&st_balloon); - st_register(&st_longboat); - st_register(&st_dragonship); - st_register(&st_caravelle); - st_register(&st_trireme); -#endif - - /* disable: st_register(&st_transport); */ - /* Alle speicherbaren Attribute müssen hier registriert werden */ at_register(&at_unitdissolve); at_register(&at_traveldir_new); diff --git a/src/common/kernel/kernel.dsp b/src/common/kernel/kernel.dsp index cf7b07fad..d901f17a3 100644 --- a/src/common/kernel/kernel.dsp +++ b/src/common/kernel/kernel.dsp @@ -65,7 +65,7 @@ LIB32=link.exe -lib # PROP Intermediate_Dir "Debug" # PROP Target_Dir "" # ADD BASE CPP /nologo /W3 /GX /Z7 /Od /D "WIN32" /D "_DEBUG" /D "_WINDOWS" /YX /FD /c -# ADD CPP /nologo /Za /W4 /Z7 /Od /I "../util" /I "../.." /I ".." /D "_WINDOWS" /D "WIN32" /D "_DEBUG" /D "BETA_CODE" /FR /YX"stdafx.h" /FD /c +# ADD CPP /nologo /Za /W4 /Z7 /Od /I "../util" /I "../.." /I ".." /D "_WINDOWS" /D "WIN32" /D "_DEBUG" /FR /YX"stdafx.h" /FD /c # ADD BASE RSC /l 0x407 # ADD RSC /l 0x407 BSC32=bscmake.exe diff --git a/src/common/kernel/magic.c b/src/common/kernel/magic.c index 0bce16a75..5ec84ada8 100644 --- a/src/common/kernel/magic.c +++ b/src/common/kernel/magic.c @@ -144,16 +144,11 @@ a_readicastle(attrib * a, FILE * f) { icastle_data * data = (icastle_data*)a->data.v; if (global.data_versiontime = old.sa[1]; - t = old.sa[0]; - if (t<0 || t >= MAXBUILDINGS) t = 0; - data->type = oldbuildings[t]; + fscanf(f, "%d", &t); + data->time = 0; + data->type = NULL; + return 0; /* no longer supported */ } else { int bno; fscanf(f, "%s %d %d", buf, &bno, &data->time); @@ -163,8 +158,8 @@ a_readicastle(attrib * a, FILE * f) ur_add((void*)bno, (void**)&data->building, resolve_building); } data->type = bt_find(buf); + return 1; } - return 1; } static void @@ -1139,16 +1134,9 @@ spellpower(region * r, unit * u, spell * sp, int cast_level) /* Bonus durch Magieturm und gesegneten Steinkreis */ struct building * b = inside_building(u); const struct building_type * btype = b?b->type:NULL; - if (btype == &bt_magictower) { - force++; - } else - if (btype == &bt_blessedstonecircle){ - force++; - } - } - if (get_item(u, I_RING_OF_POWER) > 0) { - force++; + if (btype && btype->flags & BTF_MAGIC) ++force; } + if (get_item(u, I_RING_OF_POWER) > 0) ++force; /* Antimagie in der Zielregion */ if (is_spell_active(r, C_ANTIMAGICZONE)) { @@ -1272,10 +1260,9 @@ magic_resistance(unit *target) { struct building * b = inside_building(target); const struct building_type * btype = b?b->type:NULL; + /* gesegneter Steinkreis gibt 30% dazu */ - if (btype == &bt_blessedstonecircle){ - chance += 30; - } + if (btype) chance += btype->magresbonus; } return chance; } @@ -1333,10 +1320,7 @@ target_resists_magic(unit *magician, void *obj, int objtyp, int t_bonus) chance += get_curseeffect(((building *)obj)->attribs, C_RESIST_MAGIC, 0); /* Bonus durch Typ */ - if (((building *)obj)->type == &bt_magictower) - chance += 40; - if (((building *)obj)->type == &bt_blessedstonecircle) - chance += 60; + chance += ((building *)obj)->type->magres; break; @@ -1397,9 +1381,7 @@ fumble(region * r, unit * u, spell * sp, int cast_grade) struct building * b = inside_building(u); const struct building_type * btype = b?b->type:NULL; - if (btype==&bt_magictower) { - patzer -= 10; - } + if (btype) patzer -= btype->fumblebonus; /* CHAOSPATZERCHANCE 10 : +10% Chance zu Patzern */ if (sp->magietyp == M_CHAOS) { patzer += CHAOSPATZERCHANCE; @@ -1568,13 +1550,7 @@ regeneration_magiepunkte(void) reg_aura = (double)regeneration(u); /* Magierturm erhöht die Regeneration um 75% */ - if (btype == &bt_magictower) { - reg_aura *= 1.75; - } - /* gesegnerter Steinkreis erhöht die Regeneration um 50% */ - if (btype == &bt_blessedstonecircle) { - reg_aura *= 1.50; - } + if (btype) reg_aura*=btype->auraregen; /* Bonus/Malus durch Zauber */ n = get_curseeffect(u->attribs, C_AURA, 0); diff --git a/src/common/kernel/movement.c b/src/common/kernel/movement.c index adb78a158..b70065e5c 100644 --- a/src/common/kernel/movement.c +++ b/src/common/kernel/movement.c @@ -1323,7 +1323,7 @@ check_takeoff(ship *sh, region *from, region *to) coastl = (direction_t)((coast+MAXDIRECTIONS-1) % MAXDIRECTIONS); if(dir != coast && dir != coastl && dir != coastr - && check_working_buildingtype(from, &bt_harbour) == false) + && check_working_buildingtype(from, bt_find("harbour")) == false) { return false; } @@ -1336,7 +1336,7 @@ boolean ship_allowed(const struct ship_type * type, region * r) { int c = 0; - if (check_working_buildingtype(r, &bt_harbour)) return true; + if (check_working_buildingtype(r, bt_find("harbour"))) return true; for (c=0;type->coast[c]!=NOTERRAIN;++c) { if (type->coast[c]==rterrain(r)) return true; } @@ -1606,7 +1606,7 @@ sail(region * starting_point, unit * u, region * next_point, boolean move_on_lan /* Hafengebühren ? */ - hafenmeister = owner_buildingtyp(current_point, &bt_harbour); + hafenmeister = owner_buildingtyp(current_point, bt_find("harbour")); if (sh && hafenmeister != NULL) { item * itm; assert(trans==NULL); diff --git a/src/common/kernel/race.c b/src/common/kernel/race.c index 7a3ad53d4..5427cc53a 100644 --- a/src/common/kernel/race.c +++ b/src/common/kernel/race.c @@ -223,7 +223,7 @@ give_starting_equipment(struct region *r, struct unit *u) break; case RC_HUMAN: { - building *b = new_building(&bt_castle, r, u->faction->locale); + building *b = new_building(bt_find("castle"), r, u->faction->locale); b->size = 10; u->building = b; fset(u, FL_OWNER); diff --git a/src/common/kernel/save.c b/src/common/kernel/save.c index c390a8329..3d1a74375 100644 --- a/src/common/kernel/save.c +++ b/src/common/kernel/save.c @@ -937,8 +937,8 @@ readgame(boolean backup) rds(F, &b->display); b->size = ri(F); if (global.data_version < TYPES_VERSION) { - int i = ri(F); - b->type = oldbuildings[i]; + assert(!"data format is no longer supported"); + /* b->type = oldbuildings[ri(F)]; */ } else { rs(F, buf); @@ -966,13 +966,7 @@ readgame(boolean backup) rds(F, &sh->display); if (global.data_version < SHIPTYPE_VERSION) { -#ifdef NOXMLBOATS - const ship_type * oldship[] = { &st_boat, &st_balloon, &st_longboat, &st_dragonship, &st_caravelle, &st_trireme }; - int i = ri(F); - sh->type = oldship[i]; -#else assert(!"cannot read old datafile with xml ship support"); -#endif } else { rs(F, buf); @@ -1080,9 +1074,7 @@ readgame(boolean backup) for (r=regions;r;r=r->next) { building * b; - for (b=r->buildings;b;b=b->next) { - if (b->type==&bt_lighthouse) update_lighthouse(b); - } + for (b=r->buildings;b;b=b->next) update_lighthouse(b); } printf(" - Regionen initialisieren & verbinden...\n"); for (r = regions; r; r = r->next) { diff --git a/src/common/kernel/ship.c b/src/common/kernel/ship.c index ab1b6795a..72a6321ce 100644 --- a/src/common/kernel/ship.c +++ b/src/common/kernel/ship.c @@ -147,126 +147,6 @@ captain(ship *sh, region *r) /* Alte Schiffstypen: */ -#ifdef NOXMLBOATS -static const terrain_t coast_large[] = { - T_OCEAN, T_PLAIN, NOTERRAIN -}; - -static terrain_t coast_small[] = { - T_OCEAN, T_PLAIN, T_SWAMP, T_DESERT, T_HIGHLAND, T_MOUNTAIN, T_GLACIER, - T_GRASSLAND, T_VOLCANO, T_VOLCANO_SMOKING, T_ICEBERG_SLEEP, T_ICEBERG, - NOTERRAIN -}; - -static requirement boat_req[] = { - {I_WOOD, 1}, - {0, 0} -}; - -static const construction boat_bld = { - SK_SHIPBUILDING, 1, - 5, 1, boat_req, - NULL -}; - -const ship_type st_boat = { - { "Boot", "ein Boot" }, 2, - SFL_OPENSEA, 0, 1.00, 1.00, - 5, 50*100, - 1, 1, 2, coast_small, - &boat_bld -}; - - -static requirement balloon_req[] = { - {0, 0} -}; - -static const construction balloon_bld = { - SK_SHIPBUILDING, 100, - 5, 1, balloon_req, - NULL -}; - -const ship_type st_balloon = { - { "Ballon", "ein Ballon" }, 2, - SFL_OPENSEA|SFL_FLY, 0, 1.00, 1.00, - 5, 50*100, - 6, 6, 6, coast_small, - &balloon_bld -}; - - -static requirement longboat_req[] = { - {I_WOOD, 1}, - {0, 0} -}; - -static const construction longboat_bld = { - SK_SHIPBUILDING, 1, - 50, 1, longboat_req, - NULL -}; - -const ship_type st_longboat = { - { "Langboot", "ein Langboot" }, 3, - SFL_OPENSEA, 0, 1.00, 1.00, - 50, 500*100, - 1, 1, 10, coast_large, - &longboat_bld -}; - -static requirement dragonship_req[] = { - {I_WOOD, 1}, - {0, 0} -}; -static const construction dragonship_bld = { - SK_SHIPBUILDING, 2, - 100, 1, dragonship_req, - NULL -}; -const ship_type st_dragonship = { - { "Drachenschiff", "ein Drachenschiff" }, 5, - SFL_OPENSEA, 0, 1.00, 1.00, - 100, 1000*100, - 2, 1, 50, coast_large, - &dragonship_bld -}; - -static requirement caravelle_req[] = { - {I_WOOD, 1}, - {0, 0} -}; -static const construction caravelle_bld = { - SK_SHIPBUILDING, 3, - 250, 1, caravelle_req, - NULL -}; -const ship_type st_caravelle = { - { "Karavelle", "eine Karavelle" }, 5, - SFL_OPENSEA, 0, 1.00, 1.00, - 300, 3000*100, - 3, 1, 30, coast_large, - &caravelle_bld -}; - -static requirement trireme_req[] = { - {I_WOOD, 1}, - {0, 0} -}; -static const construction trireme_bld = { - SK_SHIPBUILDING, 4, - 200, 1, trireme_req, - NULL -}; -const ship_type st_trireme = { - { "Trireme", "eine Trireme" }, 7, - SFL_OPENSEA, 0, 1.00, 1.00, - 200, 2000*100, - 4, 1, 120, coast_large, - &trireme_bld -}; -#endif ship * new_ship(const ship_type * stype, region * r) @@ -342,40 +222,6 @@ shipowner(const region * r, const ship * sh) return first; } -#ifdef NOXMLBOATS -void -xml_writeships(void) -{ - FILE * F = fopen("ships.xml", "w"); - ship_typelist *stl= shiptypes; - while (stl) { - int i; - const ship_type * st = stl->type; - fprintf(F, "name[0]), st->range, st->storm, st->damage, st->cabins, st->cargo, - st->cptskill, st->minskill, st->sumskill); - if (st->flags & SFL_OPENSEA) fputs(" opensea", F); - if (st->flags & SFL_FLY) fputs(" fly", F); - fputs(">\n", F); - for (i=0;st->coast[i]!=NOTERRAIN;++i) { - fprintf(F, "\t\n", terrain[st->coast[i]].name); - } - fprintf(F, "\t\n", - skillname(st->construction->skill, NULL), st->construction->minskill, - st->construction->maxsize, st->construction->reqsize); - for (i=0;st->construction->materials[i].number!=0;++i) { - fprintf(F, "\t\t\n", - oldresourcetype[st->construction->materials[i].type]->_name[0], - st->construction->materials[i].number); - } - fputs("\t\n", F); - fputs("\n\n", F); - stl=stl->next; - } - fclose(F); -} -#endif - static int tagend(struct xml_stack * stack) { @@ -483,8 +329,6 @@ static xml_callbacks xml_ships = { void register_ships(void) { -#ifndef NOXMLBOATS xml_register(&xml_ships, "eressea ship", 0); -#endif } diff --git a/src/common/kernel/ship.h b/src/common/kernel/ship.h index 0e57f1184..983426891 100644 --- a/src/common/kernel/ship.h +++ b/src/common/kernel/ship.h @@ -53,15 +53,6 @@ typedef struct ship_typelist { extern ship_typelist *shiptypes; /* Alte Schiffstypen: */ -#ifdef NOXMLBOATS -extern const ship_type st_boat; -extern const ship_type st_balloon; -extern const ship_type st_longboat; -extern const ship_type st_dragonship; -extern const ship_type st_caravelle; -extern const ship_type st_trireme; -extern const ship_type st_transport; -#endif extern const ship_type * st_find(const char* name); extern void st_register(const ship_type * type); diff --git a/src/common/kernel/spell.c b/src/common/kernel/spell.c index ed8523bc5..734cc0168 100644 --- a/src/common/kernel/spell.c +++ b/src/common/kernel/spell.c @@ -987,7 +987,7 @@ sp_blessstonecircle(castorder *co) b = p->param[0]->data.b; - if(b->type != &bt_stonecircle) { + if(b->type != bt_find("stonecircle")) { sprintf(buf, "%s in %s: 'ZAUBER \"%s\"': %s ist kein Steinkreis.", unitname(mage), regionid(mage->region), co->order, buildingname(b)); addmessage(0, mage->faction, buf, MSG_MAGIC, ML_MISTAKE); @@ -1002,7 +1002,7 @@ sp_blessstonecircle(castorder *co) return 0; } - b->type = &bt_blessedstonecircle; + b->type = bt_find("blessedstonecircle"); sprintf(buf, "%s weiht %s.", unitname(mage), buildingname(b)); addmessage(r, 0, buf, MSG_MAGIC, ML_INFO); @@ -2052,7 +2052,7 @@ sp_homestone(castorder *co) int cast_level = co->level; int force = co->force; - if(!mage->building || mage->building->type != &bt_castle){ + if(!mage->building || mage->building->type != bt_find("castle")){ cmistake(mage, strdup(co->order), 197, MSG_MAGIC); return 0; } @@ -4908,13 +4908,13 @@ sp_icastle(castorder *co) icastle_data * data; if((type=bt_find(pa->param[0]->data.s)) == NOBUILDING) { - type = &bt_castle; + type = bt_find("castle"); } - b = new_building(&bt_illusion, r, mage->faction->locale); + b = new_building(bt_find("illusion"), r, mage->faction->locale); /* Größe festlegen. */ - if(type == &bt_illusion) { + if(type == bt_find("illusion")) { b->size = (rand()%(power*power)+1)*10; } else if (b->type->maxsize == -1) { b->size = ((rand()%power)+1)*5; @@ -6453,7 +6453,7 @@ sp_movecastle(castorder *co) "erheben das Gebäude und tragen es in Richtung %s.", buildingname(b), locale_string(mage->faction->locale, directions[dir])); - if((b->type==&bt_caravan || b->type==&bt_dam || b->type==&bt_tunnel)) { + if((b->type==bt_find("caravan") || b->type==bt_find("dam") || b->type==bt_find("tunnel"))) { boolean damage = false; direction_t d; for (d=0;d!=MAXDIRECTIONS;++d) { diff --git a/src/common/modules/arena.c b/src/common/modules/arena.c index d5dcf80a2..f3355ce9c 100644 --- a/src/common/modules/arena.c +++ b/src/common/modules/arena.c @@ -309,7 +309,7 @@ tower_init(void) start_region[i] = findregion(arena_center->x+delta_x[i]*2, arena_center->y+delta_y[i]*2); if (r->terrain!=T_DESERT) terraform(r, T_DESERT); if (!r->buildings) { - building * b = new_building(&bt_castle, r, NULL); + building * b = new_building(bt_find("castle"), r, NULL); b->size = 10; if (i!=0) sprintf(buf, "Turm des %s", neue_gebiete[i]); else sprintf(buf, "Turm der Ahnungslosen"); @@ -318,7 +318,7 @@ tower_init(void) } } if (first && !arena_center->buildings) { - building * b = new_building(&bt_castle, arena_center, NULL); + building * b = new_building(bt_find("castle"), arena_center, NULL); attrib * a; item * items; @@ -389,15 +389,6 @@ block_create(int x1, int y1, char terrain) } #ifdef CENTRAL_VOLCANO -building_type bt_caldera = { - "caldera", /* _name */ - BTF_NOBUILD|BTF_INDESTRUCTIBLE, /* flags */ - 1, -1, -1, /* capac, maxcap, maxsize */ - NULL, /* maintenance */ - NULL, /* construction */ - NULL /* name() */ -}; - static int caldera_handle(trigger * t, void * data) @@ -483,7 +474,7 @@ init_volcano(void) assert(arena_center); if (r->terrain!=T_DESERT) return; /* been done before */ terraform(arena_center, T_VOLCANO_SMOKING); - b = new_building(&bt_caldera, r, NULL); + b = new_building(bt_find("caldera"), r, NULL); b->size = 1; b->name = strdup("Igjarjuk's Schlund"); b->display = strdup("Feurige Lava fließt aus dem Krater des großen Vulkans. Alles wird von ihr verschlungen."); diff --git a/src/common/modules/modules.dsp b/src/common/modules/modules.dsp index 9f8cfe12d..1b930a38f 100644 --- a/src/common/modules/modules.dsp +++ b/src/common/modules/modules.dsp @@ -64,7 +64,7 @@ LIB32=link.exe -lib # PROP Intermediate_Dir "Debug" # PROP Target_Dir "" # ADD BASE CPP /nologo /W3 /GX /Z7 /Od /D "WIN32" /D "_DEBUG" /D "_WINDOWS" /YX /FD /c -# ADD CPP /nologo /Za /W4 /Z7 /Od /I "../kernel" /I "../util" /I "../.." /I ".." /D "_WINDOWS" /D "WIN32" /D "_DEBUG" /D "BETA_CODE" /FR /YX"stdafx.h" /FD /c +# ADD CPP /nologo /Za /W4 /Z7 /Od /I "../kernel" /I "../util" /I "../.." /I ".." /D "_WINDOWS" /D "WIN32" /D "_DEBUG" /FR /YX"stdafx.h" /FD /c # ADD BASE RSC /l 0x407 # ADD RSC /l 0x407 BSC32=bscmake.exe diff --git a/src/common/modules/museum.c b/src/common/modules/museum.c index 8c1a03a0f..8cb4cefa5 100644 --- a/src/common/modules/museum.c +++ b/src/common/modules/museum.c @@ -262,27 +262,28 @@ create_museum(void) r = findregion(9526, 9525); if(!r->buildings) { - b = new_building(&bt_generic, r, NULL); + const building_type * bt_generic = bt_find("generic"); + b = new_building(bt_generic, r, NULL); set_string(&b->name, "Séparée im dämonischen Stil"); set_string(&b->display, "Diese ganz im dämonischen Stil gehaltene Sitzgruppe ist ganz in dunklen Schwarztönen gehalten. Muster fremdartiger Runen bedecken das merkwürdig geformte Mobiliar, das unangenehm lebendig wirkt."); - b = new_building(&bt_generic, r, NULL); + b = new_building(bt_generic, r, NULL); set_string(&b->name, "Séparée im elfischen Stil"); set_string(&b->display, "Ganz in Grün- und Brauntönen gehalten wirkt die Sitzgruppe fast lebendig. Bei näherer Betrachtung erschließt sich dem Betrachter, daß sie tatsächlich aus lebenden Pflanzen erstellt ist. So ist der Tisch aus einem eizigen Baum gewachsen, und die Polster bestehen aus weichen Grassoden. Ein wunderschön gemusterter Webteppich mit tausenden naturgetreu eingestickter Blumensarten bedeckt den Boden."); - b = new_building(&bt_generic, r, NULL); + b = new_building(bt_generic, r, NULL); set_string(&b->name, "Séparée im halblingschen Stil"); set_string(&b->display, "Dieses rustikale Mobiliar ist aus einem einzigen, gewaltigen Baum hergestellt worden. Den Stamm haben fleißige Halblinge der Länge nach gevierteilt und aus den vier langen Viertelstämmen die Sitzbänke geschnitzt, während der verbleibende Stumpf als Tisch dient. Schon von weitem steigen dem Besucher die Gerüche der Köstlichkeiten entgegen, die auf dem Tisch stapeln."); - b = new_building(&bt_generic, r, NULL); + b = new_building(bt_generic, r, NULL); set_string(&b->name, "Séparée im orkischen Stil"); set_string(&b->display, "Grobgeschreinerte, elfenhautbespannte Stühle und ein Tisch aus Knochen, über deren Herkunft man sich lieber keine Gedanken macht, bilden die Sitzgruppe im orkischen Stil. Überall haben Orks ihre Namen, und anderes wenig zitierenswertes in das Holz und Gebein geritzt."); - b = new_building(&bt_generic, r, NULL); + b = new_building(bt_generic, r, NULL); set_string(&b->name, "Séparée im Meermenschenstil"); set_string(&b->display, "Ganz in Blau- und Grüntönen gehalten, mit Algen und Muscheln verziert wirken die aus altem Meerholz geschnitzten Stühle immer ein wenig feucht. Seltsammerweise hat der schwere aus alten Planken gezimmerte Tisch einen Mast mit kompletten Segel in der Mitte."); - b = new_building(&bt_generic, r, NULL); + b = new_building(bt_generic, r, NULL); set_string(&b->name, "Séparée im Katzenstil"); set_string(&b->display, "Die Wände dieses Séparée sind aus dunklem Holz. Was aus der Ferne wie ein chaotisch durchbrochenes Flechtwerk wirkt, entpuppt sich bei näherer Betrachtung als eine bis in winzige Details gestaltete dschungelartige Landschaft, in die eine Vielzahl von kleinen Bildergeschichten eingewoben sind. Wie es scheint hat sich der Künstler Mühe gegeben wirklich jedes Katzenvolk Eresseas zu porträtieren. Das schummrige Innere wird von einem Kamin dominiert, vor dem einige Sessel und weiche Kissen zu einem gemütlichen Nickerchen einladen. Feiner Anduner Sisal bezieht die Lehnen der Sessel und verlockt dazu, seine Krallen hinein zu versenken. Auf einem kleinen Ecktisch steht ein großer Korb mit roten Wollknäulen und grauen und braunen Spielmäusen."); } else { diff --git a/src/common/races/races.dsp b/src/common/races/races.dsp index 3d7fa949c..c137fd239 100644 --- a/src/common/races/races.dsp +++ b/src/common/races/races.dsp @@ -7,19 +7,19 @@ CFG=races - Win32 Debug !MESSAGE This is not a valid makefile. To build this project using NMAKE, !MESSAGE use the Export Makefile command and run -!MESSAGE -!MESSAGE NMAKE /f "races-6.mak". -!MESSAGE +!MESSAGE +!MESSAGE NMAKE /f "races.mak". +!MESSAGE !MESSAGE You can specify a configuration when running NMAKE !MESSAGE by defining the macro CFG on the command line. For example: -!MESSAGE -!MESSAGE NMAKE /f "races-6.mak" CFG="races - Win32 Debug" -!MESSAGE +!MESSAGE +!MESSAGE NMAKE /f "races.mak" CFG="races - Win32 Debug" +!MESSAGE !MESSAGE Possible choices for configuration are: -!MESSAGE +!MESSAGE !MESSAGE "races - Win32 Release" (based on "Win32 (x86) Static Library") !MESSAGE "races - Win32 Debug" (based on "Win32 (x86) Static Library") -!MESSAGE +!MESSAGE # Begin Project # PROP AllowPerConfigDependencies 0 @@ -64,7 +64,7 @@ LIB32=link.exe -lib # PROP Intermediate_Dir "Debug" # PROP Target_Dir "" # ADD BASE CPP /nologo /W3 /GX /Z7 /Od /D "WIN32" /D "_DEBUG" /D "_WINDOWS" /YX /FD /c -# ADD CPP /nologo /Za /W4 /Z7 /Od /I "../kernel" /I "../util" /I "../.." /I ".." /D "_WINDOWS" /D "WIN32" /D "_DEBUG" /D "BETA_CODE" /FR /YX"stdafx.h" /FD /c +# ADD CPP /nologo /Za /W4 /Z7 /Od /I "../kernel" /I "../util" /I "../.." /I ".." /D "_WINDOWS" /D "WIN32" /D "_DEBUG" /FR /YX"stdafx.h" /FD /c # ADD BASE RSC /l 0x407 # ADD RSC /l 0x407 BSC32=bscmake.exe @@ -72,9 +72,9 @@ BSC32=bscmake.exe # ADD BSC32 /nologo LIB32=link.exe -lib # ADD BASE LIB32 /nologo -# ADD LIB32 /nologo /out:"Debug\races.lib" +# ADD LIB32 /nologo -!ENDIF +!ENDIF # Begin Target diff --git a/src/common/spells/spells.dsp b/src/common/spells/spells.dsp index 26a94e862..d08fd3828 100644 --- a/src/common/spells/spells.dsp +++ b/src/common/spells/spells.dsp @@ -7,19 +7,19 @@ CFG=spells - Win32 Debug !MESSAGE This is not a valid makefile. To build this project using NMAKE, !MESSAGE use the Export Makefile command and run -!MESSAGE -!MESSAGE NMAKE /f "spells-6.mak". -!MESSAGE +!MESSAGE +!MESSAGE NMAKE /f "spells.mak". +!MESSAGE !MESSAGE You can specify a configuration when running NMAKE !MESSAGE by defining the macro CFG on the command line. For example: -!MESSAGE -!MESSAGE NMAKE /f "spells-6.mak" CFG="spells - Win32 Debug" -!MESSAGE +!MESSAGE +!MESSAGE NMAKE /f "spells.mak" CFG="spells - Win32 Debug" +!MESSAGE !MESSAGE Possible choices for configuration are: -!MESSAGE +!MESSAGE !MESSAGE "spells - Win32 Release" (based on "Win32 (x86) Static Library") !MESSAGE "spells - Win32 Debug" (based on "Win32 (x86) Static Library") -!MESSAGE +!MESSAGE # Begin Project # PROP AllowPerConfigDependencies 0 @@ -64,7 +64,7 @@ LIB32=link.exe -lib # PROP Intermediate_Dir "Debug" # PROP Target_Dir "" # ADD BASE CPP /nologo /W3 /GX /Z7 /Od /D "WIN32" /D "_DEBUG" /D "_WINDOWS" /YX /FD /c -# ADD CPP /nologo /Za /W4 /Z7 /Od /I "../kernel" /I "../util" /I "../.." /I ".." /D "_WINDOWS" /D "WIN32" /D "_DEBUG" /D "BETA_CODE" /FR /YX"stdafx.h" /FD /c +# ADD CPP /nologo /Za /W4 /Z7 /Od /I "../kernel" /I "../util" /I "../.." /I ".." /D "_WINDOWS" /D "WIN32" /D "_DEBUG" /FR /YX"stdafx.h" /FD /c # ADD BASE RSC /l 0x407 # ADD RSC /l 0x407 BSC32=bscmake.exe @@ -72,9 +72,9 @@ BSC32=bscmake.exe # ADD BSC32 /nologo LIB32=link.exe -lib # ADD BASE LIB32 /nologo -# ADD LIB32 /nologo /out:"Debug\spells.lib" +# ADD LIB32 /nologo -!ENDIF +!ENDIF # Begin Target diff --git a/src/common/triggers/triggers.dsp b/src/common/triggers/triggers.dsp index 869215b52..054becc5e 100644 --- a/src/common/triggers/triggers.dsp +++ b/src/common/triggers/triggers.dsp @@ -8,12 +8,12 @@ CFG=triggers - Win32 Debug !MESSAGE This is not a valid makefile. To build this project using NMAKE, !MESSAGE use the Export Makefile command and run !MESSAGE -!MESSAGE NMAKE /f "triggers-6.mak". +!MESSAGE NMAKE /f "triggers.mak". !MESSAGE !MESSAGE You can specify a configuration when running NMAKE !MESSAGE by defining the macro CFG on the command line. For example: !MESSAGE -!MESSAGE NMAKE /f "triggers-6.mak" CFG="triggers - Win32 Debug" +!MESSAGE NMAKE /f "triggers.mak" CFG="triggers - Win32 Debug" !MESSAGE !MESSAGE Possible choices for configuration are: !MESSAGE @@ -64,7 +64,7 @@ LIB32=link.exe -lib # PROP Intermediate_Dir "Debug" # PROP Target_Dir "" # ADD BASE CPP /nologo /W3 /GX /Z7 /Od /D "WIN32" /D "_DEBUG" /D "_WINDOWS" /YX /FD /c -# ADD CPP /nologo /Za /W4 /Z7 /Od /I "../util" /I "../kernel" /I "../.." /I ".." /D "_WINDOWS" /D "WIN32" /D "_DEBUG" /D "BETA_CODE" /FR /YX"stdafx.h" /FD /c +# ADD CPP /nologo /Za /W4 /Z7 /Od /I "../util" /I "../kernel" /I "../.." /I ".." /D "_WINDOWS" /D "WIN32" /D "_DEBUG" /FR /YX"stdafx.h" /FD /c # ADD BASE RSC /l 0x407 # ADD RSC /l 0x407 BSC32=bscmake.exe @@ -72,7 +72,7 @@ BSC32=bscmake.exe # ADD BSC32 /nologo LIB32=link.exe -lib # ADD BASE LIB32 /nologo -# ADD LIB32 /nologo /out:"Debug\triggers.lib" +# ADD LIB32 /nologo !ENDIF diff --git a/src/common/util/util.dsp b/src/common/util/util.dsp index b6977ca73..b303cddae 100644 --- a/src/common/util/util.dsp +++ b/src/common/util/util.dsp @@ -8,12 +8,12 @@ CFG=util - Win32 Profile !MESSAGE This is not a valid makefile. To build this project using NMAKE, !MESSAGE use the Export Makefile command and run !MESSAGE -!MESSAGE NMAKE /f "util-6.mak". +!MESSAGE NMAKE /f "util.mak". !MESSAGE !MESSAGE You can specify a configuration when running NMAKE !MESSAGE by defining the macro CFG on the command line. For example: !MESSAGE -!MESSAGE NMAKE /f "util-6.mak" CFG="util - Win32 Profile" +!MESSAGE NMAKE /f "util.mak" CFG="util - Win32 Profile" !MESSAGE !MESSAGE Possible choices for configuration are: !MESSAGE @@ -65,7 +65,7 @@ LIB32=link.exe -lib # PROP Intermediate_Dir "Debug" # PROP Target_Dir "" # ADD BASE CPP /nologo /W3 /GX /Z7 /Od /D "WIN32" /D "_DEBUG" /D "_WINDOWS" /YX /FD /c -# ADD CPP /nologo /Za /W4 /Z7 /Od /I "../.." /I ".." /D "_WINDOWS" /D "WIN32" /D "_DEBUG" /D "BETA_CODE" /FR /YX"stdafx.h" /FD /c +# ADD CPP /nologo /Za /W4 /Z7 /Od /I "../.." /I ".." /D "_WINDOWS" /D "WIN32" /D "_DEBUG" /FR /YX"stdafx.h" /FD /c # ADD BASE RSC /l 0x407 # ADD RSC /l 0x407 BSC32=bscmake.exe @@ -73,7 +73,7 @@ BSC32=bscmake.exe # ADD BSC32 /nologo LIB32=link.exe -lib # ADD BASE LIB32 /nologo -# ADD LIB32 /nologo /out:"Debug\util.lib" +# ADD LIB32 /nologo !ELSEIF "$(CFG)" == "util - Win32 Profile" diff --git a/src/eressea/eressea.dsp b/src/eressea/eressea.dsp index 914638b76..8ec190344 100644 --- a/src/eressea/eressea.dsp +++ b/src/eressea/eressea.dsp @@ -67,7 +67,7 @@ LINK32=link.exe # PROP Ignore_Export_Lib 0 # PROP Target_Dir "" # ADD BASE CPP /nologo /W3 /Gm /GX /Zi /Od /D "WIN32" /D "_DEBUG" /D "_CONSOLE" /D "_MBCS" /YX /FD /c -# ADD CPP /nologo /Za /W4 /Gm /ZI /Od /I "../common/kernel" /I "../common/gamecode" /I "../common/util" /I "../common" /I ".." /D "_CONSOLE" /D "_MBCS" /D "WIN32" /D "_DEBUG" /D "BETA_CODE" /FR /YX"stdafx.h" /FD /c +# ADD CPP /nologo /Za /W4 /Gm /ZI /Od /I "../common/kernel" /I "../common/gamecode" /I "../common/util" /I "../common" /I ".." /D "_CONSOLE" /D "_MBCS" /D "WIN32" /D "_DEBUG" /FR /YX"stdafx.h" /FD /c # ADD BASE RSC /l 0x407 /d "_DEBUG" # ADD RSC /l 0x407 /d "_DEBUG" BSC32=bscmake.exe diff --git a/src/eressea/korrektur.c b/src/eressea/korrektur.c index b19a374c9..da6d828a2 100644 --- a/src/eressea/korrektur.c +++ b/src/eressea/korrektur.c @@ -1108,19 +1108,19 @@ fix_icastles(void) building * b; for (b=r->buildings; b; b=b->next) { attrib * a; - const building_type * btype = &bt_castle; + const building_type * btype = bt_find("castle"); icastle_data * data; a = a_find(b->attribs, &at_icastle); - if (b->type!=&bt_illusion && !a) continue; + if (b->type!=bt_find("illusion") && !a) continue; if (!a) { /* attribut hat gefehle */ a = a_add(&b->attribs, a_new(&at_icastle)); } - if (b->type!=&bt_illusion) { + if (b->type!=bt_find("illusion")) { /* gebäudetyp war falsch */ btype = b->type; - b->type = &bt_illusion; + b->type = bt_find("illusion"); } data = (icastle_data*)a->data.v; if (data->time<=0) { diff --git a/src/eressea/main.c b/src/eressea/main.c index 5a8f077c0..61334256e 100644 --- a/src/eressea/main.c +++ b/src/eressea/main.c @@ -149,6 +149,7 @@ game_init(void) debug_language("locales.log"); register_races(); register_resources(); + register_buildings(); register_ships(); register_items(); register_spells(); @@ -517,6 +518,8 @@ read_args(int argc, char **argv) #ifdef BETA_CODE extern int xml_writeitems(const char * filename); +extern int xml_writeships(void); +extern int xml_writebuildings(void); #endif typedef struct lostdata { @@ -565,9 +568,10 @@ main(int argc, char *argv[]) kernel_init(); game_init(); -#if defined(BETA_CODE) && 0 +#if defined(BETA_CODE) /* xml_writeships(); */ - xml_writeitems("items.xml"); + xml_writebuildings(); + /* xml_writeitems("items.xml"); */ return 0; #endif diff --git a/src/res/buildings.xml b/src/res/buildings.xml new file mode 100644 index 000000000..392e9109b --- /dev/null +++ b/src/res/buildings.xml @@ -0,0 +1,175 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/src/res/eressea.xml b/src/res/eressea.xml index 3b19dc37f..88de07484 100644 --- a/src/res/eressea.xml +++ b/src/res/eressea.xml @@ -10,6 +10,7 @@ + Game specific