From a2475ebdc0ffce02877abd458c6a6b5fa12f82cb Mon Sep 17 00:00:00 2001 From: Enno Rehling Date: Sun, 19 Jul 2009 08:15:45 +0000 Subject: [PATCH] economy reorganization more gentle magic school parsing null banners fix: building taxes --- src/common/gamecode/creport.c | 4 +- src/common/gamecode/economy.c | 288 +++++++++++++++++----------------- src/common/gamecode/economy.h | 2 +- src/common/gamecode/laws.c | 4 +- src/common/gamecode/report.c | 2 +- src/common/gamecode/study.c | 14 +- src/common/kernel/building.h | 64 ++++---- src/common/kernel/xmlreader.c | 2 +- src/eressea/tolua/helpers.c | 4 +- src/scripts/e3a/rules.lua | 12 +- 10 files changed, 200 insertions(+), 196 deletions(-) diff --git a/src/common/gamecode/creport.c b/src/common/gamecode/creport.c index c680c3268..3e97085cf 100644 --- a/src/common/gamecode/creport.c +++ b/src/common/gamecode/creport.c @@ -977,7 +977,7 @@ cr_find_address(FILE * F, const faction * uf, const faction_list * addresses) fprintf(F, "PARTEI %d\n", f->no); fprintf(F, "\"%s\";Parteiname\n", f->name); if (f->email) fprintf(F, "\"%s\";email\n", f->email); - fprintf(F, "\"%s\";banner\n", f->banner); + if (f->banner) fprintf(F, "\"%s\";banner\n", f->banner); fprintf(F, "\"%s\";locale\n", locale_name(f->locale)); if (f->alliance!=NULL && f->alliance==uf->alliance) { fprintf(F, "%d;alliance\n", f->alliance->id); @@ -1412,7 +1412,7 @@ report_computer(const char * filename, report_context * ctx, const char * charse fprintf(F, "\"%s\";Parteiname\n", f->name); fprintf(F, "\"%s\";email\n", f->email); - fprintf(F, "\"%s\";banner\n", f->banner); + if (f->banner) fprintf(F, "\"%s\";banner\n", f->banner); print_items(F, f->items, f->locale); fputs("OPTIONEN\n", F); for (i=0;i!=MAXOPTIONS;++i) { diff --git a/src/common/gamecode/economy.c b/src/common/gamecode/economy.c index 8c35cc753..5a882365c 100644 --- a/src/common/gamecode/economy.c +++ b/src/common/gamecode/economy.c @@ -3219,12 +3219,11 @@ peasant_taxes(region * r) maxsize = buildingeffsize(b, false); morale = region_get_morale(r); - if (maxsize > morale) { + if (morale0) { - int taxmoney = (int)((money * maxsize) * b->type->taxes(b)); + if (maxsize>0 && morale>0) { + int taxmoney = (int)(money * b->type->taxes(b, maxsize)); if (taxmoney>0) { change_money(u, taxmoney); rsetmoney(r, money - taxmoney); @@ -3235,15 +3234,16 @@ peasant_taxes(region * r) } void -produce(void) +produce(struct region *r) { request workers[1024]; - region *r; request *taxorders, *sellorders, *stealorders, *buyorders; unit *u; int todo; - int rule_taxation = get_param_int(global.parameters, "rules.economy.taxation", 0); - int rule_autowork = get_param_int(global.parameters, "work.auto", 0); + static int rule_taxation = -1; + static int rule_autowork = -1; + boolean limited = true; + request * nextworker = workers; /* das sind alles befehle, die 30 tage brauchen, und die in thisorder * stehen! von allen 30-tage befehlen wird einfach der letzte verwendet @@ -3255,141 +3255,141 @@ produce(void) * * lehren vor lernen. */ - for (r = regions; r; r = r->next) { - boolean limited = true; - request * nextworker = workers; - - assert(rmoney(r) >= 0); - assert(rpeasants(r) >= 0); - - if (r->land && rule_taxation==1) { - /* new taxation rules, region owners make money based on morale and building */ - peasant_taxes(r); - } - - buyorders = 0; - sellorders = 0; - working = 0; - nextentertainer = &entertainers[0]; - entertaining = 0; - taxorders = 0; - stealorders = 0; - - for (u = r->units; u; u = u->next) { - order * ord; - boolean trader = false; - - if (u->race == new_race[RC_SPELL] || fval(u, UFL_LONGACTION)) - continue; - - if (u->race == new_race[RC_INSECT] && r_insectstalled(r) && - !is_cursed(u->attribs, C_KAELTESCHUTZ,0)) - continue; - - if (fval(u, UFL_LONGACTION) && u->thisorder==NULL) { - cmistake(u, u->thisorder, 52, MSG_PRODUCE); - continue; - } - - for (ord = u->orders;ord;ord=ord->next) { - switch (get_keyword(ord)) { - case K_BUY: - buy(u, &buyorders, ord); - trader = true; - break; - case K_SELL: - /* sell returns true if the sale is not limited - * by the region limit */ - limited &= !sell(u, &sellorders, ord); - trader = true; - break; - } - } - if (trader) { - attrib * a = a_find(u->attribs, &at_trades); - if (a && a->data.i) { - produceexp(u, SK_TRADE, u->number); - } - fset(u, UFL_LONGACTION|UFL_NOTMOVING); - continue; - } - - todo = get_keyword(u->thisorder); - if (todo == NOKEYWORD) continue; - - if (fval(r->terrain, SEA_REGION) && u->race != new_race[RC_AQUARIAN] - && !(u->race->flags & RCF_SWIM) - && todo != K_STEAL && todo != K_SPY && todo != K_SABOTAGE) - continue; - - switch (todo) { - - case K_ENTERTAIN: - entertain_cmd(u, u->thisorder); - break; - - case K_WORK: - if (!rule_autowork && do_work(u, u->thisorder, nextworker)==0) { - ++nextworker; - } - break; - - case K_TAX: - tax_cmd(u, u->thisorder, &taxorders); - break; - - case K_STEAL: - steal_cmd(u, u->thisorder, &stealorders); - break; - - case K_SPY: - spy_cmd(u, u->thisorder); - break; - - case K_SABOTAGE: - sabotage_cmd(u, u->thisorder); - break; - - case K_PLANT: - case K_BREED: - breed_cmd(u, u->thisorder); - break; - - case K_RESEARCH: - research_cmd(u, u->thisorder); - break; - } - } - - /* Entertainment (expandentertainment) und Besteuerung (expandtax) vor den - * Befehlen, die den Bauern mehr Geld geben, damit man aus den Zahlen der - * letzten Runde berechnen kann, wieviel die Bauern für Unterhaltung - * auszugeben bereit sind. */ - if (entertaining) expandentertainment(r); - if (!rule_autowork) { - expandwork(r, workers, nextworker, maxworkingpeasants(r)); - } - if (taxorders) expandtax(r, taxorders); - - /* An erster Stelle Kaufen (expandbuying), die Bauern so Geld bekommen, um - * nachher zu beim Verkaufen (expandselling) den Spielern abkaufen zu - * können. */ - - if (buyorders) expandbuying(r, buyorders); - - if (sellorders) { - int limit = rpeasants(r) / TRADE_FRACTION; - if (r->terrain == newterrain(T_DESERT) && buildingtype_exists(r, bt_find("caravan"))) - limit *= 2; - expandselling(r, sellorders, limited?limit:INT_MAX); - } - - /* Die Spieler sollen alles Geld verdienen, bevor sie beklaut werden - * (expandstealing). */ - - if (stealorders) expandstealing(r, stealorders); - - assert(rmoney(r) >= 0); - assert(rpeasants(r) >= 0); + if (rule_taxation<0) { + rule_taxation = get_param_int(global.parameters, "rules.economy.taxation", 0); + rule_autowork = get_param_int(global.parameters, "work.auto", 0); } + + assert(rmoney(r) >= 0); + assert(rpeasants(r) >= 0); + + if (r->land && rule_taxation==1) { + /* new taxation rules, region owners make money based on morale and building */ + peasant_taxes(r); + } + + buyorders = 0; + sellorders = 0; + working = 0; + nextentertainer = &entertainers[0]; + entertaining = 0; + taxorders = 0; + stealorders = 0; + + for (u = r->units; u; u = u->next) { + order * ord; + boolean trader = false; + + if (u->race == new_race[RC_SPELL] || fval(u, UFL_LONGACTION)) + continue; + + if (u->race == new_race[RC_INSECT] && r_insectstalled(r) && + !is_cursed(u->attribs, C_KAELTESCHUTZ,0)) + continue; + + if (fval(u, UFL_LONGACTION) && u->thisorder==NULL) { + cmistake(u, u->thisorder, 52, MSG_PRODUCE); + continue; + } + + for (ord = u->orders;ord;ord=ord->next) { + switch (get_keyword(ord)) { + case K_BUY: + buy(u, &buyorders, ord); + trader = true; + break; + case K_SELL: + /* sell returns true if the sale is not limited + * by the region limit */ + limited &= !sell(u, &sellorders, ord); + trader = true; + break; + } + } + if (trader) { + attrib * a = a_find(u->attribs, &at_trades); + if (a && a->data.i) { + produceexp(u, SK_TRADE, u->number); + } + fset(u, UFL_LONGACTION|UFL_NOTMOVING); + continue; + } + + todo = get_keyword(u->thisorder); + if (todo == NOKEYWORD) continue; + + if (fval(r->terrain, SEA_REGION) && u->race != new_race[RC_AQUARIAN] + && !(u->race->flags & RCF_SWIM) + && todo != K_STEAL && todo != K_SPY && todo != K_SABOTAGE) + continue; + + switch (todo) { + + case K_ENTERTAIN: + entertain_cmd(u, u->thisorder); + break; + + case K_WORK: + if (!rule_autowork && do_work(u, u->thisorder, nextworker)==0) { + ++nextworker; + } + break; + + case K_TAX: + tax_cmd(u, u->thisorder, &taxorders); + break; + + case K_STEAL: + steal_cmd(u, u->thisorder, &stealorders); + break; + + case K_SPY: + spy_cmd(u, u->thisorder); + break; + + case K_SABOTAGE: + sabotage_cmd(u, u->thisorder); + break; + + case K_PLANT: + case K_BREED: + breed_cmd(u, u->thisorder); + break; + + case K_RESEARCH: + research_cmd(u, u->thisorder); + break; + } + } + + /* Entertainment (expandentertainment) und Besteuerung (expandtax) vor den + * Befehlen, die den Bauern mehr Geld geben, damit man aus den Zahlen der + * letzten Runde berechnen kann, wieviel die Bauern für Unterhaltung + * auszugeben bereit sind. */ + if (entertaining) expandentertainment(r); + if (!rule_autowork) { + expandwork(r, workers, nextworker, maxworkingpeasants(r)); + } + if (taxorders) expandtax(r, taxorders); + + /* An erster Stelle Kaufen (expandbuying), die Bauern so Geld bekommen, um + * nachher zu beim Verkaufen (expandselling) den Spielern abkaufen zu + * können. */ + + if (buyorders) expandbuying(r, buyorders); + + if (sellorders) { + int limit = rpeasants(r) / TRADE_FRACTION; + if (r->terrain == newterrain(T_DESERT) && buildingtype_exists(r, bt_find("caravan"))) + limit *= 2; + expandselling(r, sellorders, limited?limit:INT_MAX); + } + + /* Die Spieler sollen alles Geld verdienen, bevor sie beklaut werden + * (expandstealing). */ + + if (stealorders) expandstealing(r, stealorders); + + assert(rmoney(r) >= 0); + assert(rpeasants(r) >= 0); } diff --git a/src/common/gamecode/economy.h b/src/common/gamecode/economy.h index 06d3b2958..32e700bb0 100644 --- a/src/common/gamecode/economy.h +++ b/src/common/gamecode/economy.h @@ -46,7 +46,7 @@ extern int income(const struct unit * u); #define MAXNEWBIES 5 void economics(struct region *r); -void produce(void); +void produce(struct region *r); void auto_work(struct region * r); enum { IC_WORK, IC_ENTERTAIN, IC_TAX, IC_TRADE, IC_TRADETAX, IC_STEAL, IC_MAGIC }; diff --git a/src/common/gamecode/laws.c b/src/common/gamecode/laws.c index 36649116a..a828132b3 100644 --- a/src/common/gamecode/laws.c +++ b/src/common/gamecode/laws.c @@ -3962,10 +3962,8 @@ init_processor(void) add_proc_order(p, K_STUDY, &learn_cmd, PROC_THISORDER|PROC_LONGORDER, "Lernen"); p+=10; - add_proc_order(p, K_MAKE, &make_cmd, PROC_THISORDER|PROC_LONGORDER, "Produktion"); - p+=10; - add_proc_global(p, &produce, "Arbeiten, Handel, Rekruten"); + add_proc_postregion(p, &produce, "Arbeiten, Handel, Rekruten"); add_proc_postregion(p, &split_allocations, "Produktion II"); p+=10; diff --git a/src/common/gamecode/report.c b/src/common/gamecode/report.c index a41fa1dcd..89f3d89eb 100644 --- a/src/common/gamecode/report.c +++ b/src/common/gamecode/report.c @@ -1698,7 +1698,7 @@ list_address(FILE * F, const faction * uf, const faction_list * seenfactions) char buf[8192]; char label = '-'; - sprintf(buf, "%s: %s; %s", factionname(f), f->email, f->banner); + sprintf(buf, "%s: %s; %s", factionname(f), f->email, f->banner?f->banner:""); if (ALLIED(uf, f)) label = '*'; else if (alliedfaction(NULL, uf, f, HELP_ALL)) label = '+'; rparagraph(F, buf, 4, 0, label); diff --git a/src/common/gamecode/study.c b/src/common/gamecode/study.c index ecf34c4ba..4c5fa057c 100644 --- a/src/common/gamecode/study.c +++ b/src/common/gamecode/study.c @@ -74,8 +74,18 @@ getmagicskill(const struct locale * lang) variant token; const char * s = getstrtoken(); - if (findtoken(tokens, s, &token)==E_TOK_SUCCESS) { - return (magic_t)token.i; + if (s && s[0]) { + if (findtoken(tokens, s, &token)==E_TOK_SUCCESS) { + return (magic_t)token.i; + } else { + char buffer[3]; + buffer[0] = s[0]; + buffer[1] = s[1]; + buffer[2] = '\0'; + if (findtoken(tokens, buffer, &token)==E_TOK_SUCCESS) { + return (magic_t)token.i; + } + } } return M_NONE; } diff --git a/src/common/kernel/building.h b/src/common/kernel/building.h index 8e46168ed..2775a2bbc 100644 --- a/src/common/kernel/building.h +++ b/src/common/kernel/building.h @@ -1,6 +1,6 @@ /* vi: set ts=2: * - * Eressea PB(E)M host Copyright (C) 1998-2003 + * Eressea PB(E)M host Copyright (C) 1998-2003 * Christian Schlittchen (corwin@amber.kn-bremen.de) * Katja Zedel (katze@felidae.kn-bremen.de) * Henning Peters (faroul@beyond.kn-bremen.de) @@ -23,8 +23,8 @@ extern "C" { /* maintenance::flags */ #define MTF_NONE 0x00 -#define MTF_VARIABLE 0x01 /* resource usage scales with size */ -#define MTF_VITAL 0x02 /* if resource missing, building may crash */ +#define MTF_VARIABLE 0x01 /* resource usage scales with size */ +#define MTF_VITAL 0x02 /* if resource missing, building may crash */ typedef struct maintenance { const struct resource_type * rtype; /* type of resource required */ @@ -44,25 +44,25 @@ typedef struct maintenance { #define BTF_NAMECHANGE 0x100 /* name and description can be changed more than once */ typedef struct building_type { - const char * _name; + 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 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 */ - struct maintenance * maintenance; /* array of requirements */ - struct construction * construction; /* construction of 1 building-level */ + 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 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 */ + struct maintenance * maintenance; /* array of requirements */ + struct construction * construction; /* construction of 1 building-level */ - const char * (*name)(const struct building_type*, int size); - void (*init)(struct building_type*); - void (*age)(struct building *); - int (*protection)(struct building *, struct unit *); - double (*taxes)(struct building *); - struct attrib * attribs; + const char * (*name)(const struct building_type*, int size); + void (*init)(struct building_type*); + void (*age)(struct building *); + int (*protection)(struct building *, struct unit *); + double (*taxes)(struct building *, int size); + struct attrib * attribs; } building_type; extern building_type * bt_find(const char* name); @@ -90,19 +90,19 @@ extern int bt_effsize(const struct building_type * btype, int bsize); #define BLD_SAVEMASK 0x00 /* mask for persistent flags */ typedef struct building { - struct building *next; - struct building *nexthash; + struct building *next; + struct building *nexthash; - const struct building_type * type; - struct region *region; - char *name; - char *display; - struct attrib * attribs; - int no; - int size; - int sizeleft; /* is only used during battle. should be a temporary attribute */ - int besieged; /* should be an attribute */ - unsigned int flags; + const struct building_type * type; + struct region *region; + char *name; + char *display; + struct attrib * attribs; + int no; + int size; + int sizeleft; /* is only used during battle. should be a temporary attribute */ + int besieged; /* should be an attribute */ + unsigned int flags; } building; typedef struct building_list { diff --git a/src/common/kernel/xmlreader.c b/src/common/kernel/xmlreader.c index fae566daf..9ce155b12 100644 --- a/src/common/kernel/xmlreader.c +++ b/src/common/kernel/xmlreader.c @@ -320,7 +320,7 @@ parse_buildings(xmlDocPtr doc) } 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 = (double (*)(struct building*))fun; + btype->taxes = (double (*)(struct building*, int))fun; } else if (strcmp((const char*)propValue, "age")==0) { btype->age = (void (*)(struct building*))fun; } else { diff --git a/src/eressea/tolua/helpers.c b/src/eressea/tolua/helpers.c index 4be67d700..54b16672f 100644 --- a/src/eressea/tolua/helpers.c +++ b/src/eressea/tolua/helpers.c @@ -448,9 +448,11 @@ lua_building_taxes(building * b) lua_rawget(L, LUA_GLOBALSINDEX); type=lua_type(L, 1); if (lua_isfunction(L, 1)) { + int level = buildingeffsize(b, false); tolua_pushusertype(L, (void *)b, TOLUA_CAST "building"); + tolua_pushnumber(L, level); - if (lua_pcall(L, 1, 1, 0)!=0) { + if (lua_pcall(L, 2, 1, 0)!=0) { const char* error = lua_tostring(L, -1); log_error(("building_taxes(%s) calling '%s': %s.\n", buildingname(b), fname, error)); diff --git a/src/scripts/e3a/rules.lua b/src/scripts/e3a/rules.lua index 5ee2a801d..f87eee5eb 100644 --- a/src/scripts/e3a/rules.lua +++ b/src/scripts/e3a/rules.lua @@ -31,18 +31,12 @@ function building_protection(b, u) return 1 end -function building_taxes(b) +function building_taxes(b, blevel) 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 + return blevel * 0.01 elseif btype=="watch" then - if bsize>=10 then return 0.01 end - if bsize>=5 then return 0.005 end + return blevel * 0.005 end return 0.0 end