- delayed use of potions.

- combat bonus for ships
- new ship types
- new capacity rules for ships
- E3 island smoothing
This commit is contained in:
Enno Rehling 2009-06-25 19:40:10 +00:00
parent 8861fdfa7e
commit 6a6df68b5d
21 changed files with 517 additions and 127 deletions

View File

@ -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

View File

@ -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

View File

@ -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;
}

View File

@ -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);

View File

@ -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);

View File

@ -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
/**

View File

@ -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);

View File

@ -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];

View File

@ -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);

View File

@ -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",

View File

@ -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<numfactions) {
if (q>=1000 && nfactions<numfactions) {
terraform_region(r, newterrain(T_PLAIN));
minq = MIN(minq, q);
maxq = MAX(maxq, q);
prepare_starting_region(r);
r->land->money = 50 * 1000; /* 2% = 1000 silver */
u = addplayer(r, addfaction("enno@eressea.de", itoa36(rng_int()), races,
default_locale, 0));
++nfactions;

View File

@ -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);

View File

@ -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

View File

@ -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;

View File

@ -50,7 +50,7 @@
<item weight="0" score="10" herb="yes"/>
</resource>
<resource name="h12" appearance="herbbag">
<resource name="h12" appearance="herbbag"><!-- Windbeutel -->
<item weight="0" score="10" herb="yes"/>
</resource>
@ -58,7 +58,7 @@
<item weight="0" score="10" herb="yes"/>
</resource>
<resource name="h14" appearance="herbbag">
<resource name="h14" appearance="herbbag"><!-- Alraune -->
<item weight="0" score="10" herb="yes"/>
</resource>

View File

@ -15,13 +15,15 @@
<!--xi:include href="common/potions.xml" /-->
<xi:include href="spoils.xml"/>
<xi:include href="prefixes.xml"/>
<xi:include href="ships.xml"/>
<!--xi:include href="ships.xml"/-->
<xi:include href="buildings.xml"/>
<xi:include href="equipment.xml"/>
<!--xi:include href="terrains.xml"/-->
<xi:include href="dungeons.xml"/>
<xi:include href="directions.xml"/>
<xi:include href="e2k9/ships.xml"/>
<xi:include href="e2k9/shipnames.xml"/>
<xi:include href="e2k9/terrains.xml"/>
<xi:include href="e2k9/calendar.xml"/>
<xi:include href="e2k9/items.xml" />
@ -130,14 +132,17 @@
<param name="study.speedup" value="1"/>
<param name="rules.check_overload" value="0"/>
<param name="rules.combat.goblinbonus" value="3"/>
<param name="rules.ship.capacity" value="1"/> <!-- -->
<param name="rules.alliances" value="1"/>
<param name="rules.combat.herospeed" value="3"/>
<param name="rules.combat.demon_vampire" value="5"/> <!-- regen 1 hp per X points of damage done -->
<param name="rules.combat.skill_bonus" value="0"/>
<param name="rules.combat.loot" value="3"/> <!-- only self + monsters -->
<param name="rules.move.owner_leave" value="1"/> <!-- owner must leave before moving -->
<param name="rules.cavalry.skill" value="2"/>
<param name="rules.cavalry.mode" value="1"/>
<param name="rules.magic.factionlist" value="1"/>
<param name="rules.magic.multipotion" value="1"/>
<param name="rules.magic.wol_effect" value="5"/>
<param name="rules.magic.common" value="tybied"/> <!-- tybied spells can be cast by anyone -->
<param name="rules.magic.elfpower" value="1"/> <!-- elves get ring-of-power bonus in a forest -->
<param name="rules.magic.playerschools" value="gwyrrd illaun draig cerddor"/>

View File

@ -1,4 +1,4 @@
<?xml version="1.0" encoding="iso-8859-1" ?>
<?xml version="1.0" encoding="UTF-8" ?>
<resources>
<resource name="ointment" appearance="vial">
@ -58,7 +58,7 @@
</resource>
<resource name="p9" appearance="vial">
<!-- Pferdeglück -->
<!-- Pferdeglück -->
<item weight="0" score="90">
<function name="use" value="usepotion"/>
<potion level="3"/>

View File

@ -59,7 +59,7 @@
<function name="itemdrop" value="defaultdrops"/>
<param name="other_race" value="elf"/>
<param name="other_cost" value="500"/>
<skill name="riding" modifier="+2"/>
<skill name="riding" modifier="+1"/>
<skill name="shipcraft" modifier="2"/>
<skill name="sailing" modifier="2"/>
<skill name="magic" modifier="-99"/>

View File

@ -0,0 +1,55 @@
<?xml version="1.0" encoding="UTF-8"?>
<strings>
<string name="canoe">
<text locale="de">Einbaum</text>
<text locale="en">canoe</text>
</string>
<string name="raft">
<text locale="de">Floß</text>
<text locale="en">raft</text>
</string>
<string name="cutter">
<text locale="de">Kutter</text>
<text locale="en">cutter</text>
</string>
<string name="barge">
<text locale="de">Barke</text>
<text locale="en">barge</text>
</string>
<string name="royalbarge">
<text locale="de">Königsbarke</text>
<text locale="en">royal barge</text>
</string>
<string name="catamaran">
<text locale="de">Katamaran</text>
<text locale="en">catamaran</text>
</string>
<string name="cog">
<text locale="de">Kogge</text>
<text locale="en">cog</text>
</string>
<string name="caravel">
<text locale="de">Karavelle</text>
<text locale="en">caravel</text>
</string>
<string name="frigate">
<text locale="de">Fregatte</text>
<text locale="en">frigate</text>
</string>
<string name="galleon">
<text locale="de">Galeone</text>
<text locale="en">galleon</text>
</string>
<string name="dragonship">
<text locale="de">Drachenschiff</text>
<text locale="en">dragonship</text>
</string>
<string name="trireme">
<text locale="de">Trireme</text>
<text locale="en">trireme</text>
</string>
</strings>

154
src/res/e2k9/ships.xml Normal file
View File

@ -0,0 +1,154 @@
<?xml version="1.0"?>
<ships>
<ship name="canoe" range="3" storm="1.00" damage="1.00" cabins="2" cargo="2000" cptskill="1" minskill="1" sumskill="2" opensea="no">
<coast terrain="ocean"/>
<coast terrain="plain"/>
<coast terrain="swamp"/>
<coast terrain="desert"/>
<coast terrain="highland"/>
<coast terrain="mountain"/>
<coast terrain="glacier"/>
<coast terrain="volcano"/>
<coast terrain="activevolcano"/>
<coast terrain="iceberg_sleep"/>
<coast terrain="iceberg"/>
<construction skill="shipcraft" minskill="1" maxsize="3" reqsize="1">
<requirement type="log" quantity="1"/>
</construction>
</ship>
<ship name="raft" range="1" storm="1.00" damage="1.00" cabins="5" cargo="50000" cptskill="1" minskill="1" sumskill="7" opensea="no">
<coast terrain="ocean"/>
<coast terrain="plain"/>
<coast terrain="swamp"/>
<coast terrain="desert"/>
<construction skill="shipcraft" minskill="1" maxsize="10" reqsize="1">
<requirement type="log" quantity="1"/>
</construction>
</ship>
<ship name="cutter" range="2" storm="1.00" damage="1.00" cabins="5" cargo="5000" cptskill="2" minskill="1" sumskill="5" opensea="yes">
<coast terrain="ocean"/>
<coast terrain="plain"/>
<coast terrain="swamp"/>
<coast terrain="desert"/>
<coast terrain="highland"/>
<coast terrain="mountain"/>
<coast terrain="glacier"/>
<coast terrain="volcano"/>
<coast terrain="activevolcano"/>
<coast terrain="iceberg_sleep"/>
<coast terrain="iceberg"/>
<construction skill="shipcraft" minskill="2" maxsize="10" reqsize="1">
<requirement type="log" quantity="1"/>
</construction>
</ship>
<ship name="barge" range="4" storm="1.00" damage="1.00" cabins="10" cargo="5000" cptskill="2" minskill="1" sumskill="5" opensea="no">
<coast terrain="ocean"/>
<coast terrain="plain"/>
<coast terrain="swamp"/>
<coast terrain="desert"/>
<coast terrain="highland"/>
<coast terrain="mountain"/>
<coast terrain="glacier"/>
<coast terrain="volcano"/>
<coast terrain="activevolcano"/>
<coast terrain="iceberg_sleep"/>
<coast terrain="iceberg"/>
<construction skill="shipcraft" minskill="2" maxsize="10" reqsize="1">
<requirement type="log" quantity="1"/>
</construction>
</ship>
<ship name="royalbarge" range="6" storm="0.25" damage="1.00" cabins="10" cargo="5000" cptskill="6" minskill="1" sumskill="10" opensea="no">
<coast terrain="ocean"/>
<coast terrain="plain"/>
<coast terrain="swamp"/>
<coast terrain="desert"/>
<coast terrain="highland"/>
<coast terrain="mountain"/>
<coast terrain="glacier"/>
<coast terrain="volcano"/>
<coast terrain="activevolcano"/>
<coast terrain="iceberg_sleep"/>
<coast terrain="iceberg"/>
<construction skill="shipcraft" minskill="6" maxsize="10" reqsize="1">
<requirement type="mallorn" quantity="1"/>
<requirement type="money" quantity="100"/>
</construction>
</ship>
<ship name="catamaran" range="8" storm="0.25" damage="1.00" cabins="20" cargo="10000" cptskill="8" minskill="1" sumskill="20" opensea="yes">
<coast terrain="ocean"/>
<coast terrain="plain"/>
<construction skill="shipcraft" minskill="8" maxsize="30" reqsize="1">
<requirement type="mallorn" quantity="1"/>
<requirement type="money" quantity="100"/>
</construction>
</ship>
<ship name="cog" range="5" storm="0.50" damage="1.00" cabins="50" cargo="200000" cptskill="4" minskill="1" sumskill="20" opensea="yes">
<coast terrain="ocean"/>
<coast terrain="plain"/>
<construction skill="shipcraft" minskill="4" maxsize="100" reqsize="1">
<requirement type="log" quantity="1"/>
</construction>
</ship>
<ship name="caravel" range="5" storm="0.50" damage="1.00" cabins="150" cargo="600000" cptskill="6" minskill="1" sumskill="30" opensea="yes">
<coast terrain="ocean"/>
<coast terrain="plain"/>
<construction skill="shipcraft" minskill="6" maxsize="300" reqsize="1">
<requirement type="log" quantity="1"/>
</construction>
</ship>
<ship name="frigate" range="5" storm="1.00" damage="1.00" cabins="110" cargo="100000" cptskill="5" minskill="1" sumskill="40" opensea="yes">
<modifier type="attack" value="+2"/>
<modifier type="defense" value="+2"/>
<coast terrain="ocean"/>
<coast terrain="plain"/>
<construction skill="shipcraft" minskill="5" maxsize="100" reqsize="1">
<requirement type="log" quantity="1"/>
<requirement type="money" quantity="10"/>
</construction>
</ship>
<ship name="galleon" range="5" storm="1.00" damage="1.00" cabins="310" cargo="300000" cptskill="7" minskill="1" sumskill="60" opensea="yes">
<modifier type="attack" value="+2"/>
<modifier type="defense" value="+2"/>
<coast terrain="ocean"/>
<coast terrain="plain"/>
<construction skill="shipcraft" minskill="7" maxsize="300" reqsize="1">
<requirement type="log" quantity="1"/>
<requirement type="money" quantity="10"/>
</construction>
</ship>
<ship name="dragonship" range="7" storm="1.00" damage="1.00" cabins="110" cargo="50000" cptskill="5" minskill="1" sumskill="60" opensea="yes">
<modifier type="tactics" value="2.00"/>
<coast terrain="ocean"/>
<coast terrain="plain"/>
<construction skill="shipcraft" minskill="5" maxsize="100" reqsize="1">
<requirement type="log" quantity="1"/>
<requirement type="money" quantity="10"/>
</construction>
</ship>
<ship name="trireme" range="7" storm="1.00" damage="1.00" cabins="310" cargo="150000" cptskill="7" minskill="1" sumskill="90" opensea="yes">
<modifier type="tactics" value="2.00"/>
<coast terrain="ocean"/>
<coast terrain="plain"/>
<construction skill="shipcraft" minskill="7" maxsize="300" reqsize="1">
<requirement type="log" quantity="1"/>
<requirement type="money" quantity="10"/>
</construction>
</ship>
</ships>

View File

@ -6764,7 +6764,6 @@
<arg name="command" type="order"/>
</type>
<text locale="de">"$unit($unit) in $region($region): '$order($command)' - Das Schiff ist schon fertig."</text>
<text locale="fr">"$unit($unit) in $region($region): '$order($command)' - The ship is already completed."</text>
<text locale="en">"$unit($unit) in $region($region): '$order($command)' - The ship is already completed."</text>
</message>
<message name="error15" section="errors">
@ -6774,7 +6773,6 @@
<arg name="command" type="order"/>
</type>
<text locale="de">"$unit($unit) in $region($region): '$order($command)' - Das Schiff ist noch nicht fertig gebaut."</text>
<text locale="fr">"$unit($unit) in $region($region): '$order($command)' - The ship has not yet been completed."</text>
<text locale="en">"$unit($unit) in $region($region): '$order($command)' - The ship has not yet been completed."</text>
</message>
<message name="error14" section="errors">
@ -6784,7 +6782,6 @@
<arg name="command" type="order"/>
</type>
<text locale="de">"$unit($unit) in $region($region): '$order($command)' - Das Schiff ist auf hoher See."</text>
<text locale="fr">"$unit($unit) in $region($region): '$order($command)' - The ship is off shore."</text>
<text locale="en">"$unit($unit) in $region($region): '$order($command)' - The ship is off shore."</text>
</message>
<message name="error13" section="errors">
@ -6794,9 +6791,17 @@
<arg name="command" type="order"/>
</type>
<text locale="de">"$unit($unit) in $region($region): '$order($command)' - Das Schiff hat sich bereits bewegt."</text>
<text locale="fr">"$unit($unit) in $region($region): '$order($command)' - The ship has moved already."</text>
<text locale="en">"$unit($unit) in $region($region): '$order($command)' - The ship has moved already."</text>
</message>
<message name="error150" section="errors">
<type>
<arg name="unit" type="unit"/>
<arg name="region" type="region"/>
<arg name="command" type="order"/>
</type>
<text locale="de">"$unit($unit) in $region($region): '$order($command)' - Der Besitzer muss das Boot zuerst verlassen."</text>
<text locale="en">"$unit($unit) in $region($region): '$order($command)' - The owner must first LEAVE the building."</text>
</message>
<message name="error12" section="errors">
<type>
<arg name="unit" type="unit"/>
@ -6804,7 +6809,6 @@
<arg name="command" type="order"/>
</type>
<text locale="de">"$unit($unit) in $region($region): '$order($command)' - Das Schiff gehört uns nicht."</text>
<text locale="fr">"$unit($unit) in $region($region): '$order($command)' - The ship is not ours."</text>
<text locale="en">"$unit($unit) in $region($region): '$order($command)' - The ship is not ours."</text>
</message>
<message name="error11" section="errors">
@ -6814,7 +6818,6 @@
<arg name="command" type="order"/>
</type>
<text locale="de">"$unit($unit) in $region($region): '$order($command)' - Das Schiff befindet sich auf hoher See."</text>
<text locale="fr">"$unit($unit) in $region($region): '$order($command)' - The ship is still off shore."</text>
<text locale="en">"$unit($unit) in $region($region): '$order($command)' - The ship is still off shore."</text>
</message>
<message name="error10" section="errors">
@ -6824,7 +6827,6 @@
<arg name="command" type="order"/>
</type>
<text locale="de">"$unit($unit) in $region($region): '$order($command)' - Das macht wenig Sinn."</text>
<text locale="fr">"$unit($unit) in $region($region): '$order($command)' - That does not make much sense."</text>
<text locale="en">"$unit($unit) in $region($region): '$order($command)' - That does not make much sense."</text>
</message>
<message name="error9" section="errors">
@ -6834,7 +6836,6 @@
<arg name="command" type="order"/>
</type>
<text locale="de">"$unit($unit) in $region($region): '$order($command)' - Das kann man nicht sabotieren."</text>
<text locale="fr">"$unit($unit) in $region($region): '$order($command)' - That cannot be sabotaged."</text>
<text locale="en">"$unit($unit) in $region($region): '$order($command)' - That cannot be sabotaged."</text>
</message>
<message name="error8" section="errors">
@ -6844,7 +6845,6 @@
<arg name="command" type="order"/>
</type>
<text locale="de">"$unit($unit) in $region($region): '$order($command)' - Das ist sinnlos."</text>
<text locale="fr">"$unit($unit) in $region($region): '$order($command)' - That is useless."</text>
<text locale="en">"$unit($unit) in $region($region): '$order($command)' - That is useless."</text>
</message>
<message name="error7" section="errors">
@ -6854,8 +6854,7 @@
<arg name="command" type="order"/>
</type>
<text locale="de">"$unit($unit) in $region($region): '$order($command)' - Das geht nicht mehr."</text>
<text locale="fr">"$unit($unit) in $region($region): '$order($command)' - This is not possible any longer."</text>
<text locale="en">"$unit($unit) in $region($region): '$order($command)' - This is not possible any longer."</text>
<text locale="en">"$unit($unit) in $region($region): '$order($command)' - This is no longer possible."</text>
</message>
<message name="error6" section="errors">
<type>
@ -6864,7 +6863,6 @@
<arg name="command" type="order"/>
</type>
<text locale="de">"$unit($unit) in $region($region): '$order($command)' - Das Gebäude wurde nicht gefunden."</text>
<text locale="fr">"$unit($unit) in $region($region): '$order($command)' - Building could not be found."</text>
<text locale="en">"$unit($unit) in $region($region): '$order($command)' - Building could not be found."</text>
</message>
<message name="error5" section="errors">