From 6a6df68b5d68539223e3018cb3cc1607158fdf67 Mon Sep 17 00:00:00 2001 From: Enno Rehling Date: Thu, 25 Jun 2009 19:40:10 +0000 Subject: [PATCH] - delayed use of potions. - combat bonus for ships - new ship types - new capacity rules for ships - E3 island smoothing --- src/common/kernel/alchemy.c | 150 +++++++++++++++++++++++++-------- src/common/kernel/alchemy.h | 5 +- src/common/kernel/battle.c | 4 + src/common/kernel/build.c | 16 +++- src/common/kernel/eressea.c | 1 + src/common/kernel/eressea.h | 1 + src/common/kernel/move.c | 12 ++- src/common/kernel/race.h | 8 +- src/common/kernel/ship.h | 62 +++++++------- src/common/kernel/xmlreader.c | 20 +++-- src/common/modules/autoseed.c | 58 ++++++++++++- src/common/util/attrib.h | 54 ++++++------ src/common/util/goodies.h | 1 + src/eressea/gmtool.c | 2 +- src/res/common/herbs.xml | 4 +- src/res/e2k9.xml | 9 +- src/res/e2k9/items.xml | 4 +- src/res/e2k9/races.xml | 2 +- src/res/e2k9/shipnames.xml | 55 ++++++++++++ src/res/e2k9/ships.xml | 154 ++++++++++++++++++++++++++++++++++ src/res/messages.xml | 22 +++-- 21 files changed, 517 insertions(+), 127 deletions(-) create mode 100644 src/res/e2k9/shipnames.xml create mode 100644 src/res/e2k9/ships.xml diff --git a/src/common/kernel/alchemy.c b/src/common/kernel/alchemy.c index ce6e7e924..8d82be925 100644 --- a/src/common/kernel/alchemy.c +++ b/src/common/kernel/alchemy.c @@ -1,7 +1,7 @@ /* 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) @@ -90,20 +90,41 @@ herbsearch(region * r, unit * u, int max) } } -int -use_potion(unit * u, const item_type * itype, int amount, struct order *ord) +static int +begin_potion(unit * u, const potion_type * ptype, struct order *ord) { - const potion_type * ptype = resource2potion(itype->rtype); - const potion_type * use = ugetpotionuse(u); + static int rule_multipotion = -1; assert(ptype!=NULL); - - if (use != NULL && use!=ptype) { - ADDMSG(&u->faction->msgs, - msg_message("errusingpotion", "unit using command", - u, use->itype->rtype, ord)); - return ECUSTOM; + + if (rule_multipotion<0) { + /* should we allow multiple different potions to be used the same turn? */ + rule_multipotion = get_param_int(global.parameters, "rules.magic.multipotion", 0); } + if (!rule_multipotion) { + const potion_type * use = ugetpotionuse(u); + if (use != NULL && use!=ptype) { + ADDMSG(&u->faction->msgs, + msg_message("errusingpotion", "unit using command", + u, use->itype->rtype, ord)); + return ECUSTOM; + } + } + return 0; +} + +static void +end_potion(unit * u, const potion_type * ptype, int amount) +{ + use_pooled(u, ptype->itype->rtype, GET_SLACK|GET_RESERVE|GET_POOLED_SLACK, amount); + usetpotionuse(u, ptype); + ADDMSG(&u->faction->msgs, msg_message("usepotion", + "unit potion", u, ptype->itype->rtype)); +} + +void +do_potion(unit * u, const potion_type * ptype, int amount) +{ if (ptype==oldpotiontype[P_LIFE]) { region * r = u->region; int holz = 0; @@ -125,8 +146,6 @@ use_potion(unit * u, const item_type * itype, int amount, struct order *ord) rsettrees(r, 1, rtrees(r, 1) + holz); ADDMSG(&u->faction->msgs, msg_message("growtree_effect", "mage amount", u, holz)); - } else if (ptype==oldpotiontype[P_HEAL]) { - return EUNUSABLE; } else if (ptype==oldpotiontype[P_HEILWASSER]) { u->hp = MIN(unit_max_hp(u) * u->number, u->hp + 400 * amount); } else if (ptype==oldpotiontype[P_PEOPLE]) { @@ -148,11 +167,72 @@ use_potion(unit * u, const item_type * itype, int amount, struct order *ord) } else { change_effect(u, ptype, 10*amount); } - use_pooled(u, ptype->itype->rtype, GET_SLACK|GET_RESERVE|GET_POOLED_SLACK, amount); - usetpotionuse(u, ptype); - - ADDMSG(&u->faction->msgs, msg_message("usepotion", - "unit potion", u, ptype->itype->rtype)); +} + +int +use_potion(unit * u, const item_type * itype, int amount, struct order *ord) +{ + const potion_type * ptype = resource2potion(itype->rtype); + + if (ptype==oldpotiontype[P_HEAL]) { + return EUNUSABLE; + } else { + int result = begin_potion(u, ptype, ord); + if (result) return result; + do_potion(u, ptype, amount); + end_potion(u, ptype, amount); + } + return 0; +} + +typedef struct potiondelay { + unit * u; + const potion_type * ptype; + int amount; +} potiondelay; + +static void init_potiondelay(attrib * a) { + a->data.v = malloc(sizeof(potiondelay)); +} + +static void free_potiondelay(attrib * a) { + free(a->data.v); +} + +static int age_potiondelay(attrib * a) { + potiondelay * pd = (potiondelay *)a->data.v; + do_potion(pd->u, pd->ptype, pd->amount); + return AT_AGE_REMOVE; +} + +attrib_type at_potiondelay = { + "eventhandler", + init_potiondelay, + free_potiondelay, + age_potiondelay, 0, 0 +}; + +static attrib * +make_potiondelay(unit * u, const potion_type* ptype, int amount) +{ + attrib * a = a_new(&at_potiondelay); + potiondelay * pd = (potiondelay *)a->data.v; + pd->u = u; + pd->ptype = ptype; + pd->amount = amount; + return a; +} + +static int +use_wateroflife_delayed(unit * u, const item_type * itype, int amount, struct order *ord) +{ + const potion_type * ptype = resource2potion(itype->rtype); + int result = begin_potion(u, ptype, ord); + if (result) return result; + + a_add(&u->attribs, make_potiondelay(u, ptype, amount)); + + end_potion(u, ptype, amount); return 0; } @@ -163,21 +243,21 @@ use_potion(unit * u, const item_type * itype, int amount, struct order *ord) static void a_initeffect(attrib *a) { - a->data.v = calloc(sizeof(effect_data), 1); + a->data.v = calloc(sizeof(effect_data), 1); } static void a_finalizeeffect(attrib * a) { - free(a->data.v); + free(a->data.v); } static void a_writeeffect(const attrib *a, storage * store) { - effect_data * edata = (effect_data*)a->data.v; + effect_data * edata = (effect_data*)a->data.v; store->w_tok(store, resourcename(edata->type->itype->rtype, 0)); - store->w_int(store, edata->value); + store->w_int(store, edata->value); } static int @@ -201,23 +281,23 @@ a_readeffect(attrib *a, storage * store) } attrib_type at_effect = { - "effect", - a_initeffect, - a_finalizeeffect, - DEFAULT_AGE, - a_writeeffect, - a_readeffect, + "effect", + a_initeffect, + a_finalizeeffect, + DEFAULT_AGE, + a_writeeffect, + a_readeffect, }; int get_effect(const unit * u, const potion_type * effect) { - const attrib * a; - for (a=a_find(u->attribs, &at_effect); a!=NULL && a->type==&at_effect; a=a->next) { - const effect_data * data = (const effect_data *)a->data.v; - if (data->type==effect) return data->value; - } - return 0; + const attrib * a; + for (a=a_find(u->attribs, &at_effect); a!=NULL && a->type==&at_effect; a=a->next) { + const effect_data * data = (const effect_data *)a->data.v; + if (data->type==effect) return data->value; + } + return 0; } int diff --git a/src/common/kernel/alchemy.h b/src/common/kernel/alchemy.h index f9444fee6..22c3c4623 100644 --- a/src/common/kernel/alchemy.h +++ b/src/common/kernel/alchemy.h @@ -58,11 +58,12 @@ extern void init_potions(void); extern int get_effect(const struct unit * u, const struct potion_type * effect); extern int change_effect(struct unit * u, const struct potion_type * effect, int value); extern struct attrib_type at_effect; +extern struct attrib_type at_potiondelay; /* rausnehmen, sobald man attribute splitten kann: */ typedef struct effect_data { - const struct potion_type * type; - int value; + const struct potion_type * type; + int value; } effect_data; #ifdef __cplusplus diff --git a/src/common/kernel/battle.c b/src/common/kernel/battle.c index a971ae34f..a50827568 100644 --- a/src/common/kernel/battle.c +++ b/src/common/kernel/battle.c @@ -683,8 +683,10 @@ weapon_skill(const weapon_type * wtype, const unit * u, boolean attacking) } if (attacking) { skill += u->race->at_bonus; + if (u->ship) skill += u->ship->type->at_bonus; } else { skill += u->race->df_bonus; + if (u->ship) skill += u->ship->type->df_bonus; } } else { /* changed: if we own a weapon, we have at least a skill of 0 */ @@ -1583,6 +1585,8 @@ select_opponent(battle * b, troop at, int mindist, int maxdist) int tactics = get_tactics(dt.fighter->side); /* percentage chance to get this attack */ double tacch = 0.1 * (b->max_tactics - tactics); + ship * sh = at.fighter->unit->ship; + if (sh) tacch *= sh->type->tac_bonus; if (!chance(tacch)) { dt.fighter = NULL; } diff --git a/src/common/kernel/build.c b/src/common/kernel/build.c index 51a85e0ca..d63962782 100644 --- a/src/common/kernel/build.c +++ b/src/common/kernel/build.c @@ -1170,13 +1170,27 @@ enter_ship(unit * u, struct order * ord, int id, boolean report) return false; } if (CheckOverload()) { + static int rule_capacity = -1; int sweight, scabins; int mweight = shipcapacity(sh); int mcabins = sh->type->cabins; + + if (rule_capacity<0) { + rule_capacity = get_param_int(global.parameters, "rules.ship.capacity", 0); + } + if (rule_capacity!=0) { + mcabins *= PERSON_WEIGHT; + } if (mweight>0 && mcabins>0) { getshipweight(sh, &sweight, &scabins); sweight += weight(u); - scabins += u->number; + if (rule_capacity==0) { + scabins += u->number; + } else { + /* weight goes into number of cabins, not cargo */ + scabins += u->number * u->race->weight; + sweight -= u->number * u->race->weight; + } if (sweight > mweight || scabins > mcabins) { if (report) cmistake(u, ord, 34, MSG_MOVE); diff --git a/src/common/kernel/eressea.c b/src/common/kernel/eressea.c index be3c23c9c..1058206e1 100644 --- a/src/common/kernel/eressea.c +++ b/src/common/kernel/eressea.c @@ -2955,6 +2955,7 @@ attrib_init(void) /* neue UNIT-Attribute */ at_register(&at_siege); at_register(&at_effect); + at_register(&at_potiondelay); at_register(&at_private); at_register(&at_icastle); diff --git a/src/common/kernel/eressea.h b/src/common/kernel/eressea.h index 850c9e59c..c489de11c 100644 --- a/src/common/kernel/eressea.h +++ b/src/common/kernel/eressea.h @@ -85,6 +85,7 @@ extern "C" { #define BP_NORMAL 3 #define BP_ROAD 2 +#define PERSON_WEIGHT 1000 /* weight of a "normal" human unit */ #define STAMINA_AFFECTS_HP 1<<0 /** diff --git a/src/common/kernel/move.c b/src/common/kernel/move.c index b45f1b888..c82e23f48 100644 --- a/src/common/kernel/move.c +++ b/src/common/kernel/move.c @@ -1677,7 +1677,7 @@ sail(unit * u, order * ord, boolean move_on_land, region_list **routep) stormchance = stormyness / shipspeed(sh, u); if (check_leuchtturm(next_point, NULL)) stormchance /= 3; - if (rng_int()%10000 < stormchance && fval(current_point->terrain, SEA_REGION)) { + if (rng_int()%10000 < stormchance*sh->type->storm && fval(current_point->terrain, SEA_REGION)) { if (!is_cursed(sh->attribs, C_SHIP_NODRIFT, 0)) { region * rnext = NULL; boolean storm = true; @@ -1987,6 +1987,16 @@ travel(unit * u, region_list ** routep) /* a few pre-checks that need not be done for each step: */ if (!fval(r->terrain, SEA_REGION)) { ship * sh = u->ship; + static int rule_leave = -1; + + if (rule_leave<0) { + rule_leave = get_param_int(global.parameters, "rules.move.owner_leave", 0); + } + if (rule_leave && u->building && u==buildingowner(u->region, u->building)) { + cmistake(u, u->thisorder, 150, MSG_MOVE); + return; + } + /* An Land kein NACH wenn in dieser Runde Schiff VERLASSEN! */ if (sh == NULL) { sh = leftship(u); diff --git a/src/common/kernel/race.h b/src/common/kernel/race.h index 1484e69d9..c778b8a67 100644 --- a/src/common/kernel/race.h +++ b/src/common/kernel/race.h @@ -72,10 +72,10 @@ typedef struct race { int hitpoints; const char *def_damage; char armor; - char at_default; /* Angriffsskill Unbewaffnet (default: -2)*/ - char df_default; /* Verteidigungsskill Unbewaffnet (default: -2)*/ - char at_bonus; /* Verändert den Angriffsskill (default: 0)*/ - char df_bonus; /* Verändert den Verteidigungskill (default: 0)*/ + int at_default; /* Angriffsskill Unbewaffnet (default: -2)*/ + int df_default; /* Verteidigungsskill Unbewaffnet (default: -2)*/ + int at_bonus; /* Verändert den Angriffsskill (default: 0)*/ + int df_bonus; /* Verändert den Verteidigungskill (default: 0)*/ const spell * precombatspell; struct att attack[10]; char bonus[MAXSKILLS]; diff --git a/src/common/kernel/ship.h b/src/common/kernel/ship.h index 099f19c9b..2c352c18b 100644 --- a/src/common/kernel/ship.h +++ b/src/common/kernel/ship.h @@ -1,7 +1,7 @@ /* 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) @@ -27,30 +27,34 @@ extern "C" { #define SFL_FLY 0x02 typedef struct ship_type { - const char * name[2]; + const char * name[2]; - int range; /* range in regions */ - int flags; /* flags */ - int combat; /* modifier for combat */ + int range; /* range in regions */ + int flags; /* flags */ + int combat; /* modifier for combat */ - double storm; /* multiplier for chance to drift in storm */ - double damage; /* multiplier for damage taken by the ship */ + double storm; /* multiplier for chance to drift in storm */ + double damage; /* multiplier for damage taken by the ship */ - int cabins; /* max. cabins (people) */ - int cargo; /* max. cargo (weight) */ + int cabins; /* max. cabins (people) */ + int cargo; /* max. cargo (weight) */ - int cptskill; /* min. skill of captain */ - int minskill; /* min. skill to sail this (crew) */ - int sumskill; /* min. sum of crew+captain */ + int cptskill; /* min. skill of captain */ + int minskill; /* min. skill to sail this (crew) */ + int sumskill; /* min. sum of crew+captain */ - const struct terrain_type ** coasts; /* coast that this ship can land on */ + int at_bonus; /* Verändert den Angriffsskill (default: 0)*/ + int df_bonus; /* Verändert den Verteidigungskill (default: 0)*/ + float tac_bonus; - struct construction * construction; /* how to build a ship */ + const struct terrain_type ** coasts; /* coast that this ship can land on */ + + struct construction * construction; /* how to build a ship */ } ship_type; typedef struct ship_typelist { - struct ship_typelist * next; - const ship_type * type; + struct ship_typelist * next; + const ship_type * type; } ship_typelist; extern ship_typelist *shiptypes; @@ -68,18 +72,18 @@ extern void st_register(const ship_type * type); #define SF_SELECT 1<<3 /* previously FL_DH */ typedef struct ship { - struct ship *next; - struct ship *nexthash; - int no; - struct region *region; - char *name; - char *display; - struct attrib * attribs; - int size; - int damage; /* damage in 100th of a point of size */ - unsigned int flags; - const struct ship_type * type; - direction_t coast; + struct ship *next; + struct ship *nexthash; + int no; + struct region *region; + char *name; + char *display; + struct attrib * attribs; + int size; + int damage; /* damage in 100th of a point of size */ + unsigned int flags; + const struct ship_type * type; + direction_t coast; } ship; extern void damage_ship(ship *sh, double percent); diff --git a/src/common/kernel/xmlreader.c b/src/common/kernel/xmlreader.c index 866d29e5f..6f7ed5d00 100644 --- a/src/common/kernel/xmlreader.c +++ b/src/common/kernel/xmlreader.c @@ -513,7 +513,7 @@ parse_ships(xmlDocPtr doc) if (ships->nodesetval!=NULL) { xmlNodeSetPtr nodes = ships->nodesetval; for (i=0;i!=nodes->nodeNr;++i) { - xmlNodePtr node = nodes->nodeTab[i]; + xmlNodePtr child, node = nodes->nodeTab[i]; xmlChar * propValue; ship_type * st = calloc(sizeof(ship_type), 1); xmlXPathObjectPtr result; @@ -537,13 +537,23 @@ parse_ships(xmlDocPtr doc) st->storm = xml_fvalue(node, "storm", 1.0); st->sumskill = xml_ivalue(node, "sumskill", 0); - /* reading eressea/ships/ship/construction */ + /* reading eressea/ships/ship/construction */ xpath->node = node; result = xmlXPathEvalExpression(BAD_CAST "construction", xpath); xml_readconstruction(xpath, result->nodesetval, &st->construction); xmlXPathFreeObject(result); - /* reading eressea/ships/ship/coast */ + for (child=node->children;child;child=child->next) { + if (strcmp((const char *)child->name, "modifier")==0) { + double value = xml_fvalue(child, "value", 0.0); + propValue = xmlGetProp(child, BAD_CAST "type"); + if (strcmp((const char *)propValue, "tactics")==0) st->tac_bonus = (float)value; + else if (strcmp((const char *)propValue, "attack")==0) st->at_bonus = (int)value; + else if (strcmp((const char *)propValue, "defense")==0) st->df_bonus = (int)value; + xmlFree(propValue); + } + } + /* reading eressea/ships/ship/coast */ xpath->node = node; result = xmlXPathEvalExpression(BAD_CAST "coast", xpath); for (c=0,k=0;k!=result->nodesetval->nodeNr;++k) { @@ -1567,7 +1577,7 @@ parse_races(xmlDocPtr doc) rc->regaura = (float)xml_fvalue(node, "regaura", 1.0); rc->recruitcost = xml_ivalue(node, "recruitcost", 0); rc->maintenance = xml_ivalue(node, "maintenance", 0); - rc->weight = xml_ivalue(node, "weight", 0); + rc->weight = xml_ivalue(node, "weight", PERSON_WEIGHT); rc->capacity = xml_ivalue(node, "capacity", 540); rc->speed = (float)xml_fvalue(node, "speed", 1.0F); rc->hitpoints = xml_ivalue(node, "hp", 0); @@ -1645,7 +1655,7 @@ parse_races(xmlDocPtr doc) rc->bonus[sk] = (char)mod; if (speed) { if (!rc->study_speed) rc->study_speed = calloc(1, MAXSKILLS); - rc->study_speed[sk] = speed; + rc->study_speed[sk] = (char)speed; } } else { log_error(("unknown skill '%s' in race '%s'\n", diff --git a/src/common/modules/autoseed.c b/src/common/modules/autoseed.c index 6f9e6210a..c6573b429 100644 --- a/src/common/modules/autoseed.c +++ b/src/common/modules/autoseed.c @@ -775,7 +775,7 @@ static struct geo { { 3, T_SWAMP }, { 1, T_VOLCANO }, { 3, T_DESERT }, - { 3, T_HIGHLAND }, + { 4, T_HIGHLAND }, { 3, T_MOUNTAIN }, { 2, T_GLACIER }, { 1, T_PLAIN } @@ -831,13 +831,61 @@ int region_quality(const region * r) get_neighbours(r, rn); for (n=0;n!=MAXDIRECTIONS;++n) { if (rn[n] && rn[n]->land) { + if (rn[n]->terrain==newterrain(T_VOLCANO)) { + /* nobody likes volcanoes */ + result -= 2000; + } result += rn[n]->land->peasants; } } -// result += r->land->peasants * 2; return result; } +static void smooth_island(region_list * island) +{ + region * rn[MAXDIRECTIONS]; + region_list * rlist = NULL; + for (rlist=island;rlist;rlist=rlist->next) { + region * r = rlist->data; + int n, nland = 0; + + assert(r->land); + get_neighbours(r, rn); + for (n=0;n!=MAXDIRECTIONS && nland<=1;++n) { + if (rn[n]->land) { + ++nland; + r = rn[n]; + } + } + + if (nland==1) { + get_neighbours(r, rn); + for (n=0;n!=MAXDIRECTIONS;++n) { + int n1 = (n+1)%MAXDIRECTIONS; + int n2 = (n+1+MAXDIRECTIONS)%MAXDIRECTIONS; + if (!rn[n]->land && rn[n1]!=r && rn[n2]!=r) { + r = rlist->data; + runhash(r); + runhash(rn[n]); + SWAP(short, r->x, rn[n]->x); + SWAP(short, r->y, rn[n]->y); + rhash(r); + rhash(rn[n]); + rlist->data = r; + for (n=0;n!=MAXDIRECTIONS;++n) { + region * rx = rconnect(r, n); + if (rx==NULL) { + rx = new_region(r->x+delta_x[n], r->y+delta_y[n], 0); + terraform_region(rx, newterrain(T_OCEAN)); + } + } + break; + } + } + } + } +} + /* E3A island generation */ int build_island_e3(short x, short y, int numfactions, int minsize) @@ -863,6 +911,9 @@ build_island_e3(short x, short y, int numfactions, int minsize) } r = regionqueue_pop(&rlist); } + + smooth_island(island); + for (rlist=island;rlist;rlist=rlist->next) { r = rlist->data; if (fval(r, RF_MARK)) { @@ -876,11 +927,12 @@ build_island_e3(short x, short y, int numfactions, int minsize) freset(rn[n], RF_MARK); } q = region_quality(r); - if (q>1500 && nfactions=1000 && nfactionsland->money = 50 * 1000; /* 2% = 1000 silver */ u = addplayer(r, addfaction("enno@eressea.de", itoa36(rng_int()), races, default_locale, 0)); ++nfactions; diff --git a/src/common/util/attrib.h b/src/common/util/attrib.h index a4026a5b4..82b1ecbb7 100644 --- a/src/common/util/attrib.h +++ b/src/common/util/attrib.h @@ -1,7 +1,7 @@ /* 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) @@ -22,20 +22,20 @@ struct storage; typedef void (*afun)(void); typedef struct attrib { - const struct attrib_type * type; - union { - afun f; - void * v; - int i; - float flt; - char c; - short s; - short sa[2]; - char ca[4]; - } data; - /* internal data, do not modify: */ - struct attrib * next; /* next attribute in the list */ - struct attrib * nexttype; /* skip to attribute of a different type */ + const struct attrib_type * type; + union { + afun f; + void * v; + int i; + float flt; + char c; + short s; + short sa[2]; + char ca[4]; + } data; + /* internal data, do not modify: */ + struct attrib * next; /* next attribute in the list */ + struct attrib * nexttype; /* skip to attribute of a different type */ } attrib; #define ATF_UNIQUE (1<<0) /* only one per attribute-list */ @@ -43,17 +43,17 @@ typedef struct attrib { #define ATF_USER_DEFINED (1<<2) /* use this to make udf */ typedef struct attrib_type { - const char* name; - void (*initialize)(struct attrib *); - void (*finalize)(struct attrib *); - int (*age)(struct attrib *); - /* age returns 0 if the attribute needs to be removed, !=0 otherwise */ - void (*write)(const struct attrib *, struct storage *); - int (*read)(struct attrib *, struct storage *); /* return AT_READ_OK on success, AT_READ_FAIL if attrib needs removal */ - unsigned int flags; - /* ---- internal data, do not modify: ---- */ - struct attrib_type * nexthash; - unsigned int hashkey; + const char* name; + void (*initialize)(struct attrib *); + void (*finalize)(struct attrib *); + int (*age)(struct attrib *); + /* age returns 0 if the attribute needs to be removed, !=0 otherwise */ + void (*write)(const struct attrib *, struct storage *); + int (*read)(struct attrib *, struct storage *); /* return AT_READ_OK on success, AT_READ_FAIL if attrib needs removal */ + unsigned int flags; + /* ---- internal data, do not modify: ---- */ + struct attrib_type * nexthash; + unsigned int hashkey; } attrib_type; extern void at_register(attrib_type * at); diff --git a/src/common/util/goodies.h b/src/common/util/goodies.h index 9fd390cdb..88fc712df 100644 --- a/src/common/util/goodies.h +++ b/src/common/util/goodies.h @@ -52,6 +52,7 @@ extern unsigned int wang_hash(unsigned int a); #define HASH1 JENKINS_HASH1 #define HASH2 JENKINS_HASH2 +#define SWAP(T, a, b) { T x = a; a = b; b = x; } #ifdef __cplusplus } #endif diff --git a/src/eressea/gmtool.c b/src/eressea/gmtool.c index 55133d4fc..da8853ba5 100644 --- a/src/eressea/gmtool.c +++ b/src/eressea/gmtool.c @@ -792,7 +792,7 @@ handlekey(state * st, int c) make_block((short)st->cursor.x, (short)st->cursor.y, 6, select_terrain(st, NULL)); */ n = rng_int() % 8 + 8; - build_island_e3((short)st->cursor.x, (short)st->cursor.y, n, n*4); + build_island_e3((short)st->cursor.x, (short)st->cursor.y, n, n*3); st->modified = 1; st->wnd_info->update |= 1; st->wnd_status->update |= 1; diff --git a/src/res/common/herbs.xml b/src/res/common/herbs.xml index c1f968870..d7d0ef2e6 100644 --- a/src/res/common/herbs.xml +++ b/src/res/common/herbs.xml @@ -50,7 +50,7 @@ - + @@ -58,7 +58,7 @@ - + diff --git a/src/res/e2k9.xml b/src/res/e2k9.xml index 862ebf93c..1aa47feca 100644 --- a/src/res/e2k9.xml +++ b/src/res/e2k9.xml @@ -15,13 +15,15 @@ - + + + @@ -130,14 +132,17 @@ + + - + + diff --git a/src/res/e2k9/items.xml b/src/res/e2k9/items.xml index 81d11c5c1..0c2e5053b 100644 --- a/src/res/e2k9/items.xml +++ b/src/res/e2k9/items.xml @@ -1,4 +1,4 @@ - + @@ -58,7 +58,7 @@ - + diff --git a/src/res/e2k9/races.xml b/src/res/e2k9/races.xml index 27c03171b..df8438519 100644 --- a/src/res/e2k9/races.xml +++ b/src/res/e2k9/races.xml @@ -59,7 +59,7 @@ - + diff --git a/src/res/e2k9/shipnames.xml b/src/res/e2k9/shipnames.xml new file mode 100644 index 000000000..53d68f18f --- /dev/null +++ b/src/res/e2k9/shipnames.xml @@ -0,0 +1,55 @@ + + + + Einbaum + canoe + + + Floß + raft + + + Kutter + cutter + + + Barke + barge + + + + Königsbarke + royal barge + + + Katamaran + catamaran + + + + Kogge + cog + + + Karavelle + caravel + + + + Fregatte + frigate + + + Galeone + galleon + + + + Drachenschiff + dragonship + + + Trireme + trireme + + diff --git a/src/res/e2k9/ships.xml b/src/res/e2k9/ships.xml new file mode 100644 index 000000000..d12f998e7 --- /dev/null +++ b/src/res/e2k9/ships.xml @@ -0,0 +1,154 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/src/res/messages.xml b/src/res/messages.xml index b411b3bf6..14e1a14ea 100644 --- a/src/res/messages.xml +++ b/src/res/messages.xml @@ -6764,7 +6764,6 @@ "$unit($unit) in $region($region): '$order($command)' - Das Schiff ist schon fertig." - "$unit($unit) in $region($region): '$order($command)' - The ship is already completed." "$unit($unit) in $region($region): '$order($command)' - The ship is already completed." @@ -6774,7 +6773,6 @@ "$unit($unit) in $region($region): '$order($command)' - Das Schiff ist noch nicht fertig gebaut." - "$unit($unit) in $region($region): '$order($command)' - The ship has not yet been completed." "$unit($unit) in $region($region): '$order($command)' - The ship has not yet been completed." @@ -6784,7 +6782,6 @@ "$unit($unit) in $region($region): '$order($command)' - Das Schiff ist auf hoher See." - "$unit($unit) in $region($region): '$order($command)' - The ship is off shore." "$unit($unit) in $region($region): '$order($command)' - The ship is off shore." @@ -6794,9 +6791,17 @@ "$unit($unit) in $region($region): '$order($command)' - Das Schiff hat sich bereits bewegt." - "$unit($unit) in $region($region): '$order($command)' - The ship has moved already." "$unit($unit) in $region($region): '$order($command)' - The ship has moved already." + + + + + + + "$unit($unit) in $region($region): '$order($command)' - Der Besitzer muss das Boot zuerst verlassen." + "$unit($unit) in $region($region): '$order($command)' - The owner must first LEAVE the building." + @@ -6804,7 +6809,6 @@ "$unit($unit) in $region($region): '$order($command)' - Das Schiff gehört uns nicht." - "$unit($unit) in $region($region): '$order($command)' - The ship is not ours." "$unit($unit) in $region($region): '$order($command)' - The ship is not ours." @@ -6814,7 +6818,6 @@ "$unit($unit) in $region($region): '$order($command)' - Das Schiff befindet sich auf hoher See." - "$unit($unit) in $region($region): '$order($command)' - The ship is still off shore." "$unit($unit) in $region($region): '$order($command)' - The ship is still off shore." @@ -6824,7 +6827,6 @@ "$unit($unit) in $region($region): '$order($command)' - Das macht wenig Sinn." - "$unit($unit) in $region($region): '$order($command)' - That does not make much sense." "$unit($unit) in $region($region): '$order($command)' - That does not make much sense." @@ -6834,7 +6836,6 @@ "$unit($unit) in $region($region): '$order($command)' - Das kann man nicht sabotieren." - "$unit($unit) in $region($region): '$order($command)' - That cannot be sabotaged." "$unit($unit) in $region($region): '$order($command)' - That cannot be sabotaged." @@ -6844,7 +6845,6 @@ "$unit($unit) in $region($region): '$order($command)' - Das ist sinnlos." - "$unit($unit) in $region($region): '$order($command)' - That is useless." "$unit($unit) in $region($region): '$order($command)' - That is useless." @@ -6854,8 +6854,7 @@ "$unit($unit) in $region($region): '$order($command)' - Das geht nicht mehr." - "$unit($unit) in $region($region): '$order($command)' - This is not possible any longer." - "$unit($unit) in $region($region): '$order($command)' - This is not possible any longer." + "$unit($unit) in $region($region): '$order($command)' - This is no longer possible." @@ -6864,7 +6863,6 @@ "$unit($unit) in $region($region): '$order($command)' - Das Gebäude wurde nicht gefunden." - "$unit($unit) in $region($region): '$order($command)' - Building could not be found." "$unit($unit) in $region($region): '$order($command)' - Building could not be found."