diff --git a/src/common/gamecode/economy.c b/src/common/gamecode/economy.c index 406b17d68..4d1590ce5 100644 --- a/src/common/gamecode/economy.c +++ b/src/common/gamecode/economy.c @@ -3231,11 +3231,13 @@ peasant_taxes(region * r) } if (maxsize>0) { - int taxmoney = (money * maxsize) / 100; - change_money(u, taxmoney); - rsetmoney(r, money - taxmoney); - ADDMSG(&u->faction->msgs, msg_message("income_tax", - "unit region amount", u, r, taxmoney)); + int taxmoney = (int)((money * maxsize) * b->type->taxes(b)); + if (taxmoney>0) { + change_money(u, taxmoney); + rsetmoney(r, money - taxmoney); + ADDMSG(&u->faction->msgs, msg_message("income_tax", + "unit region amount", u, r, taxmoney)); + } } } diff --git a/src/common/gamecode/laws.c b/src/common/gamecode/laws.c index 962d11c60..38708c9cd 100644 --- a/src/common/gamecode/laws.c +++ b/src/common/gamecode/laws.c @@ -1426,7 +1426,7 @@ display_cmd(unit * u, struct order * ord) cmistake(u, ord, 148, MSG_EVENT); break; } - if (b != largestbuilding(r, &is_castle, false)) { + if (b != largestbuilding(r, &is_tax_building, false)) { cmistake(u, ord, 147, MSG_EVENT); break; } @@ -1661,7 +1661,7 @@ name_cmd(unit * u, struct order * ord) cmistake(u, ord, 148, MSG_EVENT); break; } - if (b != largestbuilding(r, &is_castle, false)) { + if (b != largestbuilding(r, &is_tax_building, false)) { cmistake(u, ord, 147, MSG_EVENT); break; } diff --git a/src/common/gamecode/report.c b/src/common/gamecode/report.c index 132a10a11..6059cd431 100644 --- a/src/common/gamecode/report.c +++ b/src/common/gamecode/report.c @@ -1910,7 +1910,7 @@ report_plaintext(const char * filename, report_context * ctx, const char * chars { int flag = 0; char ch; - int anyunits; + int anyunits, no_units, no_people; const struct region *r; faction * f = ctx->f; unit *u; @@ -2023,7 +2023,27 @@ report_plaintext(const char * filename, report_context * ctx, const char * chars centre(F, buf, true); } #endif - m = msg_message("nr_population", "population units", count_all(f), f->no_units); +#ifdef COUNT_AGAIN + no_units = 0; + no_people = 0; + for (u=f->units;u;u=u->nextF) { + if (playerrace(u->race)) { + ++no_people; + no_units += u->number; + assert(f==u->faction); + } + } + if (no_units!=f->no_units) { + f->no_units = no_units; + } + if (no_people!=f->num_people) { + f->num_people = no_people; + } +#else + no_units = f->no_units; + no_people = f->num_people; +#endif + m = msg_message("nr_population", "population units", no_people, no_units); nr_render(m, f->locale, buf, sizeof(buf), f); msg_release(m); centre(F, buf, true); diff --git a/src/common/kernel/battle.c b/src/common/kernel/battle.c index 87fe4c550..0a589f883 100644 --- a/src/common/kernel/battle.c +++ b/src/common/kernel/battle.c @@ -1917,18 +1917,12 @@ skilldiff(troop at, troop dt, int dist) magicwalls_ct = ct_find("magicwalls"); init=true; } - if (df->building->type->flags & BTF_PROTECTION) { - int beff = buildingeffsize(df->building, false)-1; - /* -1 because the tradepost has no protection value */ - -#if KARMA_MODULE - if (fspecial(au->faction, FS_SAPPER)) { - /* Halbe Schutzwirkung, aufgerundet */ - beff = (beff+1)/2; + if (df->building->type->protection) { + int beff = df->building->type->protection(df->building, du); + if (beff) { + skdiff -= beff; + is_protected = 2; } -#endif /* KARMA_MODULE */ - skdiff -= beff; - is_protected = 2; } if (strongwall_ct) { curse * c = get_curse(df->building->attribs, strongwall_ct); @@ -2078,7 +2072,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->flags & BTF_PROTECTION) { + if (bldg->type->protection) { side * s; bldg->sizeleft = bldg->size; diff --git a/src/common/kernel/building.c b/src/common/kernel/building.c index 82bea812f..955b8526d 100644 --- a/src/common/kernel/building.c +++ b/src/common/kernel/building.c @@ -252,6 +252,35 @@ init_smithy(struct building_type * bt) a_add(&bt->attribs, make_matmod(mm_smithy)); } +static const char * +castle_name_i(const struct building_type* btype, int bsize, const char * fname[]) +{ + const construction * ctype; + int i = 0; + + ctype = btype->construction; + while (ctype && ctype->maxsize != -1 && ctype->maxsize<=bsize) { + bsize-=ctype->maxsize; + ctype=ctype->improvement; + ++i; + } + return fname[i]; +} + +static const char * +castle_name_2(const struct building_type* btype, int bsize) +{ + const char * fname[] = { + "site", + "fortification", + "tower", + "castle", + "fortress", + "citadel" + }; + return castle_name_i(btype, bsize, fname); +} + static const char * castle_name(const struct building_type* btype, int bsize) { @@ -264,16 +293,7 @@ castle_name(const struct building_type* btype, int bsize) "fortress", "citadel" }; - const construction * ctype; - int i = 0; - - ctype = btype->construction; - while (ctype && ctype->maxsize != -1 && ctype->maxsize<=bsize) { - bsize-=ctype->maxsize; - ctype=ctype->improvement; - ++i; - } - return fname[i]; + return castle_name_i(btype, bsize, fname); } static const char * @@ -370,12 +390,27 @@ findbuildingtype(const char * name, const struct locale * lang) return (const building_type*)type.v; } +static int eressea_building_protection(building * b, unit * u) +{ + int beff = buildingeffsize(b, false)-1; + /* -1 because the tradepost has no protection value */ + +#if KARMA_MODULE + if (fspecial(u->faction, FS_SAPPER)) { + /* Halbe Schutzwirkung, aufgerundet */ + beff = (beff+1)/2; + } +#endif /* KARMA_MODULE */ + return beff; +} void register_buildings(void) { + register_function((pf_generic)&eressea_building_protection, "eressea_building_protection"); register_function((pf_generic)&init_smithy, "init_smithy"); 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"); #ifdef WDW_PYRAMID register_function((pf_generic)&pyramid_name, "pyramid_name"); diff --git a/src/common/kernel/building.h b/src/common/kernel/building.h index 10da91bbc..da12dbcdf 100644 --- a/src/common/kernel/building.h +++ b/src/common/kernel/building.h @@ -39,11 +39,9 @@ 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 */ #define BTF_ONEPERTURN 0x80 /* one one sizepoint can be added per turn */ #define BTF_NAMECHANGE 0x100 /* name and description can be changed more than once */ -#define BTF_TAXES 0x200 /* automatic taxes */ typedef struct building_type { const char * _name; @@ -62,6 +60,8 @@ typedef struct building_type { const char * (*name)(const struct building_type*, int size); void (*init)(struct building_type*); void (*age)(struct building *); + int (*protection)(struct building *, struct unit *); + float (*taxes)(struct building *); struct attrib * attribs; } building_type; diff --git a/src/common/kernel/eressea.c b/src/common/kernel/eressea.c index 2dac71fee..78f3edac5 100644 --- a/src/common/kernel/eressea.c +++ b/src/common/kernel/eressea.c @@ -1186,7 +1186,7 @@ int count_all(const faction * f) { #ifndef NDEBUG - int n = 0; + int n = 0, nunits = 0; unit *u; for (u=f->units;u;u=u->nextF) { if (playerrace(u->race)) { @@ -1197,7 +1197,6 @@ count_all(const faction * f) if (f->num_people != n) { log_error(("# of people in %s is != num_people: %d should be %d.\n", factionid(f), f->num_people, n)); - return n; } #endif return f->num_people; @@ -2617,7 +2616,7 @@ is_castle(const struct building * b) boolean is_tax_building(const building * b) { - if (b->type->flags&BTF_TAXES) { + if (b->type->taxes) { return true; } return false; diff --git a/src/common/kernel/xmlreader.c b/src/common/kernel/xmlreader.c index bad1445ea..0488274e4 100644 --- a/src/common/kernel/xmlreader.c +++ b/src/common/kernel/xmlreader.c @@ -288,8 +288,6 @@ parse_buildings(xmlDocPtr doc) if (xml_bvalue(node, "unique", false)) btype->flags |= BTF_UNIQUE; if (xml_bvalue(node, "decay", false)) btype->flags |= BTF_DECAY; if (xml_bvalue(node, "magic", false)) btype->flags |= BTF_MAGIC; - if (xml_bvalue(node, "protection", false)) btype->flags |= BTF_PROTECTION; - if (xml_bvalue(node, "taxes", false)) btype->flags |= BTF_TAXES; /* reading eressea/buildings/building/construction */ xpath->node = node; @@ -319,6 +317,12 @@ parse_buildings(xmlDocPtr doc) btype->init = (void (*)(struct building_type*))fun; } else if (strcmp((const char*)propValue, "age")==0) { btype->age = (void (*)(struct building*))fun; + } else if (strcmp((const char*)propValue, "protection")==0) { + btype->protection = (int (*)(struct building*, struct unit *))fun; + } else if (strcmp((const char*)propValue, "taxes")==0) { + btype->taxes = (float (*)(struct building*))fun; + } else if (strcmp((const char*)propValue, "age")==0) { + btype->age = (void (*)(struct building*))fun; } else { log_error(("unknown function type '%s' for building %s\n", (const char*)propValue, btype->_name)); diff --git a/src/eressea/tolua/helpers.c b/src/eressea/tolua/helpers.c index 661f4742e..e2d7a5f16 100644 --- a/src/eressea/tolua/helpers.c +++ b/src/eressea/tolua/helpers.c @@ -406,6 +406,63 @@ lua_agebuilding(building * b) } } +static int +lua_building_protection(building * b, unit * u) +{ + lua_State * L = (lua_State *)global.vm_state; + const char * fname = "building_protection"; + int result = 0; + + lua_pushstring(L, fname); + lua_rawget(L, LUA_GLOBALSINDEX); + if (lua_isfunction(L, 1)) { + tolua_pushusertype(L, (void *)b, "building"); + tolua_pushusertype(L, (void *)u, "unit"); + + if (lua_pcall(L, 2, 1, 0)!=0) { + const char* error = lua_tostring(L, -1); + log_error(("building_protection(%s, %s) calling '%s': %s.\n", + buildingname(b), unitname(u), fname, error)); + lua_pop(L, 1); + } else { + result = (int)lua_tonumber(L, -1); + } + } else { + log_error(("building_protection(%s, %s) calling '%s': not a function.\n", + buildingname(b), unitname(u), fname)); + lua_pop(L, 1); + } + return result; +} + +static float +lua_building_taxes(building * b) +{ + lua_State * L = (lua_State *)global.vm_state; + const char * fname = "building_taxes"; + float result = 0.0F; + + lua_pushstring(L, fname); + lua_rawget(L, LUA_GLOBALSINDEX); + if (lua_isfunction(L, 1)) { + tolua_pushusertype(L, (void *)b, "building"); + + if (lua_pcall(L, 1, 1, 0)!=0) { + const char* error = lua_tostring(L, -1); + log_error(("building_taxes(%s) calling '%s': %s.\n", + buildingname(b), fname, error)); + lua_pop(L, 1); + } else { + result = (float)lua_tonumber(L, -1); + } + } else { + log_error(("building_taxes(%s) calling '%s': not a function.\n", + buildingname(b), fname)); + lua_pop(L, 1); + } + return result; +} + static int lua_maintenance(const unit * u) { @@ -548,6 +605,8 @@ register_tolua_helpers(void) { at_building_action.age = lc_age; + register_function((pf_generic)&lua_building_protection, "lua_building_protection"); + register_function((pf_generic)&lua_building_taxes, "lua_building_taxes"); register_function((pf_generic)&lua_agebuilding, "lua_agebuilding"); register_function((pf_generic)&lua_recruit, "lua_recruit"); register_function((pf_generic)&lua_callspell, "lua_castspell"); diff --git a/src/eressea/tolua/helpers.h b/src/eressea/tolua/helpers.h index 0f22386d9..8d3370650 100644 --- a/src/eressea/tolua/helpers.h +++ b/src/eressea/tolua/helpers.h @@ -14,6 +14,7 @@ without prior permission by the authors of Eressea. extern "C" { #endif + struct lua_State; void register_tolua_helpers(void); int tolua_toid(struct lua_State* L, int idx, int def); diff --git a/src/res/asgard.xml b/src/res/asgard.xml index fd8b58a91..0c94ed943 100644 --- a/src/res/asgard.xml +++ b/src/res/asgard.xml @@ -21,7 +21,6 @@ <xi:include href="eressea/items.xml"/> <xi:include href="eressea/artrewards.xml"/> <xi:include href="eressea/dungeons.xml"/> - <xi:include href="eressea/temple.xml"/> <equipment> <set name="first_unit"> diff --git a/src/res/buildings/castle-2.xml b/src/res/buildings/castle-2.xml index caceb3c08..cda8b8f67 100644 --- a/src/res/buildings/castle-2.xml +++ b/src/res/buildings/castle-2.xml @@ -1,5 +1,5 @@ <?xml version="1.0"?> -<building name="castle" capacity="1" protection="yes" taxes="yes"> +<building name="castle" capacity="1"> <function name="name" value="castle_name_2"/> <function name="protection" value="lua_building_protection"/> <function name="taxes" value="lua_building_taxes"/> diff --git a/src/res/buildings/castle.xml b/src/res/buildings/castle.xml index 211381a71..296d1f716 100644 --- a/src/res/buildings/castle.xml +++ b/src/res/buildings/castle.xml @@ -1,8 +1,7 @@ <?xml version="1.0"?> -<building name="castle" capacity="1" protection="yes" taxes="yes"> +<building name="castle" capacity="1"> <function name="name" value="castle_name"/> <function name="protection" value="eressea_building_protection"/> - <function name="taxes" value="eressea_building_taxes"/> <construction skill="building" minskill="1" maxsize="2" reqsize="1"> <requirement type="stone" quantity="1"/> </construction> diff --git a/src/res/common/buildings.xml b/src/res/common/buildings.xml index 22d204267..a32d28e5c 100644 --- a/src/res/common/buildings.xml +++ b/src/res/common/buildings.xml @@ -1,5 +1,9 @@ <?xml version="1.0"?> <buildings> + <building name="temple" maxsize="50" maxcapacity="2" nobuild="yes" nodestroy="yes" unique="yes" auraregen="1.00" /> + <building name="wormhole" maxsize="4" capacity="1" maxcapacity="4" nobuild="yes" nodestroy="yes" unique="yes" /> + <building name="portal" maxsize="2" capacity="1" maxcapacity="2" nobuild="yes" nodestroy="yes" unique="yes" /> + <building name="pavilion" maxsize="2" capacity="1" maxcapacity="2" nobuild="yes" nodestroy="yes" unique="yes" /> <building name="illusioncastle" capacity="0" maxcapacity="0" maxsize="0" nobuild="yes"/> <building name="xmas_exit" maxsize="10" maxcapacity="2" nobuild="yes" nodestroy="yes" unique="yes"/> <building name="caldera" capacity="1" nodestroy="yes" nobuild="yes"/> diff --git a/src/res/e3a.xml b/src/res/e3a.xml index b03fe1cd6..6476faf32 100644 --- a/src/res/e3a.xml +++ b/src/res/e3a.xml @@ -170,7 +170,6 @@ <xi:include href="eressea/items.xml"/> <xi:include href="eressea/artrewards.xml"/> <xi:include href="eressea/dungeons.xml"/> - <xi:include href="eressea/temple.xml"/> <strings> <string name="mailto"> <text locale="de">eressea-server@eressea.de</text> diff --git a/src/res/e3a/buildings.xml b/src/res/e3a/buildings.xml index ed1105a00..e9121e6fb 100644 --- a/src/res/e3a/buildings.xml +++ b/src/res/e3a/buildings.xml @@ -3,7 +3,7 @@ <xi:include href="../buildings/castle-2.xml" /> - <building name="watch" capacity="1" protection="yes" taxes="true"> + <building name="watch" capacity="1"> <function name="name" value="fort_name"/> <function name="protection" value="lua_building_protection"/> <function name="taxes" value="lua_building_taxes"/> diff --git a/src/res/eressea.xml b/src/res/eressea.xml index ee6332116..b9f97ac69 100644 --- a/src/res/eressea.xml +++ b/src/res/eressea.xml @@ -93,7 +93,6 @@ <xi:include href="eressea/items.xml"/> <xi:include href="eressea/artrewards.xml"/> <xi:include href="eressea/dungeons.xml"/> - <xi:include href="eressea/temple.xml"/> <strings> <string name="mailto"> <text locale="de">eressea-server@eressea.de</text> diff --git a/src/res/eressea/buildings.xml b/src/res/eressea/buildings.xml index 374ce58e0..b25ce565b 100644 --- a/src/res/eressea/buildings.xml +++ b/src/res/eressea/buildings.xml @@ -1,8 +1,4 @@ <?xml version="1.0"?> <buildings xmlns:xi="http://www.w3.org/2001/XInclude"> - <building name="temple" maxsize="50" maxcapacity="2" nobuild="yes" nodestroy="yes" unique="yes" auraregen="1.00" /> - <building name="wormhole" maxsize="4" capacity="1" maxcapacity="4" nobuild="yes" nodestroy="yes" unique="yes" /> - <building name="portal" maxsize="2" capacity="1" maxcapacity="2" nobuild="yes" nodestroy="yes" unique="yes" /> - <building name="pavilion" maxsize="2" capacity="1" maxcapacity="2" nobuild="yes" nodestroy="yes" unique="yes" /> <xi:include href="../buildings/castle.xml" /> </buildings> diff --git a/src/res/eressea2.xml b/src/res/eressea2.xml index 6ef5faea4..38a0570d6 100644 --- a/src/res/eressea2.xml +++ b/src/res/eressea2.xml @@ -19,7 +19,7 @@ <xi:include href="spoils.xml"/> <xi:include href="prefixes.xml"/> <xi:include href="ships.xml"/> - <xi:include href="buildings.xml"/> + <xi:include href="common/buildings.xml"/> <xi:include href="eressea/calendar.xml"/> <xi:include href="equipment.xml"/> <xi:include href="dungeons.xml"/> @@ -116,7 +116,7 @@ <xi:include href="eressea/items.xml"/> <xi:include href="eressea/artrewards.xml"/> <xi:include href="eressea/dungeons.xml"/> - <xi:include href="eressea/temple.xml"/> + <xi:include href="eressea/buildings.xml"/> <strings> <string name="mailto"> <text locale="de">eressea-server@eressea.de</text> diff --git a/src/res/hse-05-01.xml b/src/res/hse-05-01.xml index 1d9ca103d..dd5e6d2c0 100644 --- a/src/res/hse-05-01.xml +++ b/src/res/hse-05-01.xml @@ -76,7 +76,7 @@ <xi:include href="eressea/races.xml"/> <xi:include href="eressea/items-hse05.xml"/> <xi:include href="eressea/dungeons.xml"/> - <xi:include href="eressea/temple.xml"/> + <xi:include href="eressea/buildings.xml"/> <strings> <string name="mailto"> <text locale="de">hse-server@eressea.de</text> diff --git a/src/res/hse4.xml b/src/res/hse4.xml index 053339f92..7d3d23b64 100644 --- a/src/res/hse4.xml +++ b/src/res/hse4.xml @@ -16,7 +16,7 @@ <xi:include href="races.xml"/> <xi:include href="prefixes.xml"/> <xi:include href="ships.xml"/> - <xi:include href="buildings.xml"/> + <xi:include href="common/buildings.xml"/> <xi:include href="calendar.xml"/> <xi:include href="equipment.xml"/> <xi:include href="spells.xml"/> @@ -79,7 +79,7 @@ <xi:include href="eressea/races.xml"/> <xi:include href="eressea/items-hse.xml"/> <xi:include href="eressea/dungeons.xml"/> - <xi:include href="eressea/temple.xml"/> + <xi:include href="eressea/buildings.xml"/> <strings> <string name="newbie_info_1"> <text locale="de">Bitte denke daran, deine Befehle mit dem Betreff ERESSEA BEFEHLE an hse-server@eressea.de zu senden. Am besten, du verwendest die Befehlsvorlage am Ende des Reports.</text> diff --git a/src/res/vinyambar-3.xml b/src/res/vinyambar-3.xml index 48168bb96..14bbe0450 100644 --- a/src/res/vinyambar-3.xml +++ b/src/res/vinyambar-3.xml @@ -8,7 +8,8 @@ <include href="races.xml" /> <include href="resources.xml" /> <include href="ships.xml" /> - <include href="buildings.xml" /> + <include href="common/buildings.xml" /> + <xi:include href="eressea/buildings.xml"/> <game name="Kreis der Macht" units="250" welcome="vinyambar"> <!-- Game specific --> diff --git a/src/res/vinyambar-wdw.xml b/src/res/vinyambar-wdw.xml index 44850e920..55278b3be 100644 --- a/src/res/vinyambar-wdw.xml +++ b/src/res/vinyambar-wdw.xml @@ -16,7 +16,7 @@ <xi:include href="races.xml"/> <xi:include href="prefixes.xml"/> <xi:include href="ships.xml"/> - <xi:include href="buildings.xml"/> + <xi:include href="common/buildings.xml"/> <xi:include href="calendar.xml"/> <xi:include href="equipment.xml"/> <xi:include href="spells.xml"/> diff --git a/src/scripts/e3a/rules.lua b/src/scripts/e3a/rules.lua index ee56d1a50..ab104bf8e 100644 --- a/src/scripts/e3a/rules.lua +++ b/src/scripts/e3a/rules.lua @@ -25,3 +25,23 @@ function item_canuse(u, iname) end return true end + +function building_protection(b, u) + return 1 +end + +function building_taxes(b) + btype = b.type + bsize = b.size + if btype=="castle" then + if bsize>=6250 then return 0.05 end + if bsize>=1250 then return 0.04 end + if bsize>=250 then return 0.03 end + if bsize>=50 then return 0.02 end + if bsize>=10 then return 0.01 end + elseif btype=="watch" then + if bsize>=10 then return 0.01 end + if bsize>=5 then return 0.005 end + end + return 0.0 +end diff --git a/src/scripts/run-e3a.lua b/src/scripts/run-e3a.lua index 4da490db6..b8882a042 100644 --- a/src/scripts/run-e3a.lua +++ b/src/scripts/run-e3a.lua @@ -30,7 +30,7 @@ function load_scripts() scripts = { "spells.lua", "extensions.lua", - "e2k9/rules.lua" + "e3a/rules.lua" } for index, value in pairs(scripts) do loadscript(value)