forked from github/server
- largestbuilding() can take a filter
- morale (light) implemented - rider bonus on weapons is configurable by XML - wooden guard house - help status can be masked - shipspeed configurable (per race or via skill-level) - tax-creating buildings configurable by XML - bugfix: castles have no protection
This commit is contained in:
parent
418f611dcb
commit
cf5cad9b87
14 changed files with 164 additions and 68 deletions
|
@ -3208,7 +3208,7 @@ peasant_taxes(region * r)
|
|||
money = rmoney(r);
|
||||
if (money<=0) return;
|
||||
|
||||
b = largestbuilding(r, false);
|
||||
b = largestbuilding(r, &is_tax_building, false);
|
||||
if (b==NULL) return;
|
||||
|
||||
u = buildingowner(r, b);
|
||||
|
|
|
@ -1404,7 +1404,7 @@ display_cmd(unit * u, struct order * ord)
|
|||
cmistake(u, ord, 148, MSG_EVENT);
|
||||
break;
|
||||
}
|
||||
if (b != largestbuilding(r,false)) {
|
||||
if (b != largestbuilding(r, &is_castle, false)) {
|
||||
cmistake(u, ord, 147, MSG_EVENT);
|
||||
break;
|
||||
}
|
||||
|
@ -1639,7 +1639,7 @@ name_cmd(unit * u, struct order * ord)
|
|||
cmistake(u, ord, 148, MSG_EVENT);
|
||||
break;
|
||||
}
|
||||
if (b != largestbuilding(r,false)) {
|
||||
if (b != largestbuilding(r, &is_castle, false)) {
|
||||
cmistake(u, ord, 147, MSG_EVENT);
|
||||
break;
|
||||
}
|
||||
|
@ -2920,12 +2920,22 @@ static void age_region(region * r)
|
|||
{
|
||||
a_age(&r->attribs);
|
||||
handle_event(r->attribs, "timer", r);
|
||||
|
||||
if (r->land && r->land->ownership) {
|
||||
int stability = r->land->ownership->since_turn;
|
||||
int morale = MORALE_TAKEOVER + stability/10;
|
||||
if (r->land->ownership->owner && r->land->morale<MORALE_MAX) {
|
||||
r->land->morale = MIN(morale, MORALE_MAX);
|
||||
}
|
||||
if (!r->land->ownership->owner && r->land->morale<MORALE_DEFAULT) {
|
||||
r->land->morale = MIN(morale, MORALE_DEFAULT);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
ageing(void)
|
||||
{
|
||||
const building_type * bt_castle = bt_find("castle");
|
||||
faction *f;
|
||||
region *r;
|
||||
|
||||
|
@ -2993,24 +3003,17 @@ ageing(void)
|
|||
for (bp=&r->buildings;*bp;) {
|
||||
building * b = *bp;
|
||||
b = age_building(b);
|
||||
}
|
||||
|
||||
if (b==*bp) {
|
||||
if (b->type==bt_castle) {
|
||||
if (blargest==NULL || b->size>blargest->size) {
|
||||
blargest = b;
|
||||
}
|
||||
}
|
||||
bp = &(*bp)->next;
|
||||
}
|
||||
if (blargest) {
|
||||
/* region owners update? */
|
||||
faction * f = region_get_owner(r);
|
||||
unit * u = buildingowner(r, blargest);
|
||||
if (u==NULL) {
|
||||
region_set_owner(r, NULL, turn);
|
||||
} else if (u->faction!=f) {
|
||||
region_set_owner(r, f, turn);
|
||||
}
|
||||
blargest = largestbuilding(r, &is_tax_building, false);
|
||||
if (blargest) {
|
||||
/* region owners update? */
|
||||
faction * f = region_get_owner(r);
|
||||
unit * u = buildingowner(r, blargest);
|
||||
if (u==NULL) {
|
||||
region_set_owner(r, NULL, turn);
|
||||
} else if (u->faction!=f) {
|
||||
region_set_owner(r, f, turn);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -746,7 +746,7 @@ weapon_effskill(troop t, troop enemy, const weapon * w, boolean attacking, boole
|
|||
}
|
||||
|
||||
/* Burgenbonus, Pferdebonus */
|
||||
if (is_riding(t) && (wtype==NULL || !fval(wtype, WTF_MISSILE))) {
|
||||
if (is_riding(t) && (wtype==NULL || (fval(wtype, WTF_HORSEBONUS) && !fval(wtype, WTF_MISSILE)))) {
|
||||
skill += 2;
|
||||
if (wtype) skill = skillmod(urace(tu)->attribs, tu, tu->region, wtype->skill, skill, SMF_RIDING);
|
||||
}
|
||||
|
|
|
@ -266,24 +266,44 @@ init_smithy(struct building_type * bt)
|
|||
static const char *
|
||||
castle_name(const struct building_type* btype, int bsize)
|
||||
{
|
||||
const char * fname[MAXBUILDINGS] = {
|
||||
"site",
|
||||
"tradepost",
|
||||
"fortification",
|
||||
"tower",
|
||||
"castle",
|
||||
"fortress",
|
||||
"citadel" };
|
||||
const construction * ctype;
|
||||
int i = 0;
|
||||
const char * fname[MAXBUILDINGS] = {
|
||||
"site",
|
||||
"tradepost",
|
||||
"fortification",
|
||||
"tower",
|
||||
"castle",
|
||||
"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];
|
||||
ctype = btype->construction;
|
||||
while (ctype && ctype->maxsize != -1 && ctype->maxsize<=bsize) {
|
||||
bsize-=ctype->maxsize;
|
||||
ctype=ctype->improvement;
|
||||
++i;
|
||||
}
|
||||
return fname[i];
|
||||
}
|
||||
|
||||
static const char *
|
||||
fort_name(const struct building_type* btype, int bsize)
|
||||
{
|
||||
const char * fname[MAXBUILDINGS] = {
|
||||
"guardhouse",
|
||||
"guardtower",
|
||||
};
|
||||
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];
|
||||
}
|
||||
|
||||
#ifdef WDW_PYRAMID
|
||||
|
@ -364,10 +384,11 @@ findbuildingtype(const char * name, const struct locale * lang)
|
|||
void
|
||||
register_buildings(void)
|
||||
{
|
||||
register_function((pf_generic)init_smithy, "init_smithy");
|
||||
register_function((pf_generic)castle_name, "castle_name");
|
||||
register_function((pf_generic)&init_smithy, "init_smithy");
|
||||
register_function((pf_generic)&castle_name, "castle_name");
|
||||
register_function((pf_generic)&fort_name, "fort_name");
|
||||
#ifdef WDW_PYRAMID
|
||||
register_function((pf_generic)pyramid_name, "pyramid_name");
|
||||
register_function((pf_generic)&pyramid_name, "pyramid_name");
|
||||
#endif
|
||||
}
|
||||
|
||||
|
|
|
@ -43,6 +43,7 @@ typedef struct maintenance {
|
|||
#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;
|
||||
|
|
|
@ -154,7 +154,10 @@ ExpensiveMigrants(void)
|
|||
}
|
||||
return value;
|
||||
}
|
||||
|
||||
/** Specifies automatic alliance modes.
|
||||
* If this returns a value then the bits set are immutable between alliance
|
||||
* partners (faction::alliance) and cannot be changed with the HELP command.
|
||||
*/
|
||||
int
|
||||
AllianceAuto(void)
|
||||
{
|
||||
|
@ -172,20 +175,41 @@ AllianceAuto(void)
|
|||
free(sstr);
|
||||
}
|
||||
}
|
||||
return value;
|
||||
return value | ~HelpMask();
|
||||
}
|
||||
|
||||
/** Limits the available help modes
|
||||
* The bitfield returned by this function specifies the available help modes
|
||||
* in this game (so you can, for example, disable HELP GIVE globally).
|
||||
* Disabling a status will disable the command sequence entirely (order parsing
|
||||
* uses this function).
|
||||
*/
|
||||
int
|
||||
HelpMask(void)
|
||||
{
|
||||
static int help_mask = 0;
|
||||
|
||||
if (help_mask==0) {
|
||||
help_mask = get_param_int(global.parameters, "rules.help.mask", HELP_ALL);
|
||||
static int value = -1;
|
||||
if (value<0) {
|
||||
const char * str = get_param(global.parameters, "rules.help.mask");
|
||||
value = 0;
|
||||
if (str!=NULL) {
|
||||
char * sstr = strdup(str);
|
||||
char * tok = strtok(sstr, " ");
|
||||
while (tok) {
|
||||
value |= ally_flag(tok);
|
||||
tok = strtok(NULL, " ");
|
||||
}
|
||||
free(sstr);
|
||||
} else {
|
||||
value = HELP_ALL;
|
||||
}
|
||||
}
|
||||
return help_mask;
|
||||
return value;
|
||||
}
|
||||
|
||||
/** specifies modes that are restricted to members of the same alliance.
|
||||
* if this returns a non-zero value, then you cannot give those modes to a
|
||||
* faction unless they are in the same alliance.
|
||||
*/
|
||||
int
|
||||
AllianceRestricted(void)
|
||||
{
|
||||
|
@ -593,6 +617,20 @@ int verbosity = 0;
|
|||
|
||||
FILE *debug;
|
||||
|
||||
static int
|
||||
ShipSpeedBonus(const unit * u)
|
||||
{
|
||||
static int level = -1;
|
||||
if (level==-1) {
|
||||
level = get_param_int(global.parameters, "movement.shipspeed.skillbonus", 0);
|
||||
}
|
||||
if (level>0) {
|
||||
int skl = effskill(u, SK_SAILING);
|
||||
return skl/level;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
int
|
||||
shipspeed(const ship * sh, const unit * u)
|
||||
{
|
||||
|
@ -619,11 +657,13 @@ shipspeed(const ship * sh, const unit * u)
|
|||
|
||||
if (u->faction->race == u->race) {
|
||||
/* race bonus for this faction? */
|
||||
if (u->race == new_race[RC_AQUARIAN]) {
|
||||
if (fval(u->race, RCF_SHIPSPEED)) {
|
||||
k += 1;
|
||||
}
|
||||
}
|
||||
|
||||
k += ShipSpeedBonus(u);
|
||||
|
||||
a = a_find(sh->attribs, &at_speedup);
|
||||
while (a != NULL && a->type==&at_speedup) {
|
||||
k += a->data.sa[0];
|
||||
|
@ -837,9 +877,11 @@ static int
|
|||
autoalliance(const plane * pl, const faction * sf, const faction * f2)
|
||||
{
|
||||
static boolean init = false;
|
||||
static int automode;
|
||||
if (!init) {
|
||||
init_gms();
|
||||
init = true;
|
||||
automode = ~HelpMask();
|
||||
}
|
||||
if (pl && (pl->flags & PFL_FRIENDLY)) return HELP_ALL;
|
||||
/* if f2 is a gm in this plane, everyone has an auto-help to it */
|
||||
|
@ -857,7 +899,7 @@ autoalliance(const plane * pl, const faction * sf, const faction * f2)
|
|||
if (sf->alliance==f2->alliance) return AllianceAuto();
|
||||
}
|
||||
|
||||
return 0;
|
||||
return automode;
|
||||
}
|
||||
|
||||
static int
|
||||
|
@ -1641,11 +1683,10 @@ cstring(const char *s)
|
|||
}
|
||||
|
||||
building *
|
||||
largestbuilding (const region * r, boolean imaginary)
|
||||
largestbuilding (const region * r, boolean (*eval)(const struct building *), boolean imaginary)
|
||||
{
|
||||
static const building_type * btype = NULL;
|
||||
building *b, *best = NULL;
|
||||
if (!btype) btype = bt_find("castle"); /* TODO: parameter der funktion? */
|
||||
/* durch die verw. von '>' statt '>=' werden die aelteren burgen
|
||||
* bevorzugt. */
|
||||
|
||||
|
@ -1654,7 +1695,7 @@ largestbuilding (const region * r, boolean imaginary)
|
|||
if (imaginary) {
|
||||
const attrib * a = a_find(b->attribs, &at_icastle);
|
||||
if (!a) continue;
|
||||
if (a->data.v != btype) continue;
|
||||
if (eval && !eval(b)) continue;
|
||||
} else continue;
|
||||
}
|
||||
if (best==NULL || b->size > best->size)
|
||||
|
@ -2548,10 +2589,26 @@ static const int wagetable[7][4] = {
|
|||
{15, 13, 16, 2} /* Zitadelle */
|
||||
};
|
||||
|
||||
boolean
|
||||
is_castle(const struct building * b)
|
||||
{
|
||||
static const struct building_type * bt_castle;
|
||||
if (!bt_castle) bt_castle = bt_find("castle");
|
||||
return (b->type==bt_castle);
|
||||
}
|
||||
|
||||
boolean is_tax_building(const building * b)
|
||||
{
|
||||
if (b->type->flags&BTF_TAXES) {
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
static int
|
||||
default_wage(const region *r, const faction * f, const race * rc)
|
||||
{
|
||||
building *b = largestbuilding(r, false);
|
||||
building *b = largestbuilding(r, &is_castle, false);
|
||||
int esize = 0;
|
||||
curse * c;
|
||||
int wage;
|
||||
|
|
|
@ -247,8 +247,9 @@ extern char *cstring_i(char *s);
|
|||
extern const char *unitname(const struct unit * u);
|
||||
extern char * write_unitname(const struct unit * u, char * buffer, size_t size);
|
||||
|
||||
struct building *largestbuilding(const struct region * r, boolean imaginary);
|
||||
|
||||
struct building *largestbuilding(const struct region * r, boolean (*eval)(const struct building *), boolean imaginary);
|
||||
boolean is_castle(const struct building * b);
|
||||
boolean is_tax_building(const struct building * b);
|
||||
extern int count_all(const struct faction * f);
|
||||
extern int count_migrants (const struct faction * f);
|
||||
extern int count_maxmigrants(const struct faction * f);
|
||||
|
|
|
@ -188,14 +188,15 @@ typedef struct armor_type {
|
|||
unsigned int flags;
|
||||
} armor_type;
|
||||
|
||||
#define WTF_NONE 0x00
|
||||
#define WTF_MISSILE 0x01
|
||||
#define WTF_MAGICAL 0x02
|
||||
#define WTF_PIERCE 0x04
|
||||
#define WTF_CUT 0x08
|
||||
#define WTF_BLUNT 0x10
|
||||
#define WTF_SIEGE 0x20
|
||||
#define WTF_NONE 0x00
|
||||
#define WTF_MISSILE 0x01
|
||||
#define WTF_MAGICAL 0x02
|
||||
#define WTF_PIERCE 0x04
|
||||
#define WTF_CUT 0x08
|
||||
#define WTF_BLUNT 0x10
|
||||
#define WTF_SIEGE 0x20
|
||||
#define WTF_ARMORPIERCING 0x40 /* armor has only half value */
|
||||
#define WTF_HORSEBONUS 0x80
|
||||
|
||||
typedef struct weapon_type {
|
||||
const item_type * itype;
|
||||
|
|
|
@ -137,6 +137,7 @@ extern int rc_specialdamage(const race *, const race *, const struct weapon_type
|
|||
#define RCF_UNARMEDGUARD (1<<23) /* kann ohne Waffen bewachen */
|
||||
#define RCF_CANSAIL (1<<24) /* Einheit darf Schiffe betreten */
|
||||
#define RCF_INVISIBLE (1<<25) /* not visible in any report */
|
||||
#define RCF_SHIPSPEED (1<<26) /* race gets +1 on shipspeed */
|
||||
|
||||
/* Economic flags */
|
||||
#define GIVEITEM (1<<1) /* gibt Gegenstände weg */
|
||||
|
|
|
@ -1337,7 +1337,13 @@ region_get_owner(const struct region * r)
|
|||
void
|
||||
region_set_owner(struct region * r, struct faction * owner, int turn)
|
||||
{
|
||||
if (r->land && r->land->ownership) {
|
||||
if (r->land) {
|
||||
if (!r->land->ownership) {
|
||||
r->land->ownership = malloc(sizeof(region_owner));
|
||||
r->land->morale = MORALE_DEFAULT;
|
||||
} else if (r->land->ownership->owner) {
|
||||
r->land->morale = MORALE_TAKEOVER;
|
||||
}
|
||||
r->land->ownership->owner = owner;
|
||||
r->land->ownership->since_turn = turn;
|
||||
}
|
||||
|
|
|
@ -62,7 +62,9 @@ struct rawmaterial;
|
|||
struct donation;
|
||||
struct item;
|
||||
|
||||
#define MORALE_DEFAULT 2 /* Morale of peasants that have no lord */
|
||||
#define MORALE_MAX 4 /* Maximum morale allowed */
|
||||
#define MORALE_DEFAULT 2 /* Morale of peasants when they are conquered for the first time */
|
||||
#define MORALE_TAKEOVER 0 /* Morale of peasants after they lose their lord */
|
||||
|
||||
typedef struct region_owner {
|
||||
struct faction * owner;
|
||||
|
|
|
@ -269,6 +269,7 @@ parse_buildings(xmlDocPtr doc)
|
|||
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;
|
||||
|
@ -645,6 +646,7 @@ xml_readweapon(xmlXPathContextPtr xpath, item_type * itype)
|
|||
if (xml_bvalue(node, "cut", false)) flags |= WTF_CUT;
|
||||
if (xml_bvalue(node, "blunt", false)) flags |= WTF_BLUNT;
|
||||
if (xml_bvalue(node, "siege", false)) flags |= WTF_SIEGE;
|
||||
if (xml_bvalue(node, "horse", (flags&WTF_MISSILE)==0)) flags |= WTF_HORSEBONUS;
|
||||
|
||||
propValue = xmlGetProp(node, BAD_CAST "skill");
|
||||
assert(propValue!=NULL);
|
||||
|
@ -1579,6 +1581,7 @@ parse_races(xmlDocPtr doc)
|
|||
if (xml_bvalue(node, "illusionary", false)) rc->flags |= RCF_ILLUSIONARY;
|
||||
if (xml_bvalue(node, "undead", false)) rc->flags |= RCF_UNDEAD;
|
||||
if (xml_bvalue(node, "dragon", false)) rc->flags |= RCF_DRAGON;
|
||||
if (xml_bvalue(node, "shipspeed", false)) rc->flags |= RCF_SHIPSPEED;
|
||||
|
||||
if (xml_bvalue(node, "giveitem", false)) rc->ec_flags |= GIVEITEM;
|
||||
if (xml_bvalue(node, "giveperson", false)) rc->ec_flags |= GIVEPERSON;
|
||||
|
|
|
@ -166,7 +166,7 @@
|
|||
</construction>
|
||||
</building>
|
||||
|
||||
<building name="castle" capacity="1">
|
||||
<building name="castle" capacity="1" protection="yes" taxes="true">
|
||||
<function name="name" value="castle_name"/>
|
||||
<construction skill="building" minskill="1" maxsize="2" reqsize="1">
|
||||
<requirement type="stone" quantity="1"/>
|
||||
|
|
|
@ -759,7 +759,7 @@
|
|||
<attack type="4" damage="1d7"/>
|
||||
<attack type="5"/>
|
||||
</race>
|
||||
<race name="aquarian" magres="0.000000" maxaura="1.000000" regaura="1.000000" recruitcost="80" maintenance="10" weight="1000" capacity="540" speed="1.000000" hp="20" damage="1d5" unarmedattack="-2" unarmeddefense="-2" playerrace="yes" coastal="yes" walk="yes" giveitem="yes" giveperson="yes" giveunit="yes" getitem="yes" equipment="yes">
|
||||
<race name="aquarian" magres="0.000000" maxaura="1.000000" regaura="1.000000" recruitcost="80" maintenance="10" weight="1000" capacity="540" speed="1.000000" hp="20" damage="1d5" unarmedattack="-2" unarmeddefense="-2" shipspeed="yes" playerrace="yes" coastal="yes" walk="yes" giveitem="yes" giveperson="yes" giveunit="yes" getitem="yes" equipment="yes">
|
||||
<ai splitsize="10000" moverandom="yes" learn="yes"/>
|
||||
<function name="itemdrop" value="defaultdrops"/>
|
||||
<skill name="mining" modifier="-2"/>
|
||||
|
|
Loading…
Reference in a new issue