- per-race morale improvements

- data-driven peasant multiplier
- lower cavalry bonus against trolls
- armor-limitations (goblins&pp)
This commit is contained in:
Enno Rehling 2009-06-04 20:52:42 +00:00
parent e0d68bb4e3
commit 72878c5788
19 changed files with 123 additions and 199 deletions

View File

@ -377,11 +377,10 @@ do_recruiting(recruitment * recruits, int available)
for (req=rec->requests;req;req=req->next) {
unit * u = req->unit;
const race * rc = u->faction->race;
int number, multi = 2;
int number, dec;
float multi = 2.0F * rc->recruit_multi;
if (rc==new_race[RC_URUK]) multi = 1;
number = MIN(req->qty, get / multi);
number = MIN(req->qty, (int)(get / multi));
if (rc->recruitcost) {
int afford = get_pooled(u, oldresourcetype[R_SILVER], GET_DEFAULT, number*rc->recruitcost) / rc->recruitcost;
number = MIN(number, afford);
@ -393,11 +392,12 @@ do_recruiting(recruitment * recruits, int available)
assert(number>=0);
}
add_recruits(u, number, req->qty);
dec = (int)(number * multi);
if ((rc->ec_flags & ECF_REC_ETHEREAL)==0) {
recruited += number * multi;
recruited += dec;
}
get -= number * multi;
get -= dec;
}
}
return recruited;

View File

@ -2934,19 +2934,30 @@ age_building(building * b)
return b;
}
static double rc_popularity(const struct race * rc)
{
int pop = get_param_int(rc->parameters, "morale", 10);
return 1.0/(pop-MORALE_COOLDOWN); /* 10 turns average */
}
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 = (short)MIN(morale, MORALE_MAX);
}
if (!r->land->ownership->owner && r->land->morale<MORALE_DEFAULT) {
r->land->morale = (short)MIN(morale, MORALE_DEFAULT);
if (r->land && r->land->ownership && r->land->ownership->owner) {
int stability = turn - r->land->ownership->morale_turn;
if (stability>MORALE_COOLDOWN) {
if (r->land->ownership->owner && r->land->morale<MORALE_MAX) {
double ch = rc_popularity(r->land->ownership->owner->race);
if (chance(ch)) {
++r->land->morale;
r->land->ownership->morale_turn = turn;
}
}
if (!r->land->ownership->owner && r->land->morale<MORALE_DEFAULT) {
r->land->morale = (short)MIN(r->land->morale, MORALE_DEFAULT);
}
}
}
}

View File

@ -671,19 +671,18 @@ nr_unit(FILE * F, const faction * f, const unit * u, int indent, int mode)
if (u->faction == f) {
marker = '*';
} else if (u->faction->alliance == f->alliance && f->alliance) {
marker = 'o';
} else if (a_otherfaction && f != u->faction && get_otherfaction(a_otherfaction) == f
&& !fval(u, UFL_PARTEITARNUNG)) {
marker = '!';
} else {
if (a_otherfaction && f != u->faction && get_otherfaction(a_otherfaction) == f
&& !fval(u, UFL_PARTEITARNUNG)) {
marker = '!';
if (dh && !fval(u, UFL_PARTEITARNUNG)) {
marker = '+';
} else {
if (dh && !fval(u, UFL_PARTEITARNUNG)) {
marker = '+';
} else {
marker = '-';
}
marker = '-';
}
}
rparagraph(F, buf, indent, 0, marker);
if (!isbattle) {

View File

@ -636,10 +636,11 @@ select_weapon(const troop t, boolean attacking, boolean ismissile)
return preferred_weapon(t, attacking);
}
static boolean can_use(const unit * u, const weapon_type * wtype)
static boolean
i_canuse(const unit * u, const item_type * itype)
{
if (wtype->itype->canuse) {
return wtype->itype->canuse(u, wtype->itype);
if (itype->canuse) {
return itype->canuse(u, itype);
}
return true;
}
@ -688,7 +689,7 @@ weapon_skill(const weapon_type * wtype, const unit * u, boolean attacking)
}
} else {
/* changed: if we own a weapon, we have at least a skill of 0 */
if (!can_use(u, wtype)) return -1;
if (!i_canuse(u, wtype->itype)) return -1;
skill = effskill(u, wtype->skill);
if (skill < wtype->minskill) skill = 0;
if (skill > 0) {
@ -719,7 +720,7 @@ static int CavalrySkill(void)
}
static int
CavalryBonus(const unit * u)
CavalryBonus(const unit * u, troop enemy)
{
static int mode = -1;
if (mode<0) {
@ -731,7 +732,12 @@ CavalryBonus(const unit * u)
} else {
/* new rule, chargers in Eressea 1.1 */
int skl = effskill(u, SK_RIDING);
skl = skl*3/2-3;
/* only half against trolls */
if (enemy.fighter->unit->race==new_race[RC_TROLL]) {
skl = (skl-2)*3/4;
} else {
skl = (skl-2)*3/2;
}
return MAX(skl, 0);
}
}
@ -784,7 +790,7 @@ weapon_effskill(troop t, troop enemy, const weapon * w, boolean attacking, boole
/* Burgenbonus, Pferdebonus */
if (is_riding(t) && (wtype==NULL || (fval(wtype, WTF_HORSEBONUS) && !fval(wtype, WTF_MISSILE)))) {
skill += CavalryBonus(tu);
skill += CavalryBonus(tu, enemy);
if (wtype) skill = skillmod(urace(tu)->attribs, tu, tu->region, wtype->skill, skill, SMF_RIDING);
}
@ -3307,14 +3313,16 @@ make_fighter(battle * b, unit * u, side * s1, boolean attack)
if (u->race->battle_flags & BF_EQUIPMENT) {
for (itm=u->items; itm; itm=itm->next) {
if (itm->type->rtype->atype) {
struct armor * adata = malloc(sizeof(armor)), **aptr;
adata->atype = itm->type->rtype->atype;
adata->count = itm->number;
for (aptr=&fig->armors;*aptr;aptr=&(*aptr)->next) {
if (adata->atype->prot > (*aptr)->atype->prot) break;
if (i_canuse(u, itm->type)) {
struct armor * adata = malloc(sizeof(armor)), **aptr;
adata->atype = itm->type->rtype->atype;
adata->count = itm->number;
for (aptr=&fig->armors;*aptr;aptr=&(*aptr)->next) {
if (adata->atype->prot > (*aptr)->atype->prot) break;
}
adata->next = *aptr;
*aptr = adata;
}
adata->next = *aptr;
*aptr = adata;
}
}
}

View File

@ -2165,6 +2165,16 @@ get_param_int(const struct param * p, const char * key, int def)
return def;
}
float
get_param_flt(const struct param * p, const char * key, float def)
{
while (p!=NULL) {
if (strcmp(p->name, key)==0) return (float)atof(p->data);
p = p->next;
}
return def;
}
void
set_param(struct param ** p, const char * key, const char * data)
{

View File

@ -394,6 +394,7 @@ extern const char * dbrace(const struct race * rc);
extern void set_param(struct param ** p, const char * name, const char * data);
extern const char* get_param(const struct param * p, const char * name);
extern int get_param_int(const struct param * p, const char * name, int def);
extern float get_param_flt(const struct param * p, const char * name, float def);
extern boolean ExpensiveMigrants(void);
extern int NMRTimeout(void);

View File

@ -58,6 +58,7 @@ typedef struct race {
float magres;
float maxaura; /* Faktor auf Maximale Aura */
float regaura; /* Faktor auf Regeneration */
float recruit_multi; /* Faktor für Bauernverbrauch */
int recruitcost;
int maintenance;
int splitsize;

View File

@ -1356,6 +1356,7 @@ region_set_owner(struct region * r, struct faction * owner, int turn)
}
r->land->ownership->owner = owner;
r->land->ownership->since_turn = turn;
r->land->ownership->morale_turn = turn;
}
}

View File

@ -65,10 +65,12 @@ struct item;
#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 */
#define MORALE_COOLDOWN 2 /* minimum cooldown before a morale change occurs */
typedef struct region_owner {
struct faction * owner;
int since_turn;
int since_turn; /* turn the region changed owners */
int morale_turn; /* turn when morale has changed most recently */
} region_owner;
typedef struct demand {

View File

@ -601,6 +601,7 @@ write_owner(struct storage * store, region_owner *owner)
{
if (owner) {
store->w_int(store, owner->since_turn);
store->w_int(store, owner->morale_turn);
write_faction_reference(owner->owner, store);
} else {
store->w_int(store, -1);
@ -614,6 +615,7 @@ read_owner(struct storage * store, region_owner **powner)
if (since_turn>=0) {
region_owner * owner = malloc(sizeof(region_owner));
owner->since_turn = since_turn;
owner->morale_turn = store->r_int(store);
read_reference(&owner->owner, store, read_faction_reference, resolve_faction);
*powner = owner;
} else {

View File

@ -1623,6 +1623,7 @@ parse_races(xmlDocPtr doc)
parse_param(&rc->parameters, child);
}
}
rc->recruit_multi = get_param_flt(rc->parameters, "recruit_multi", 1.0);
/* reading eressea/races/race/skill */
xpath->node = node;

View File

@ -2,67 +2,12 @@
<resources>
<!-- this file contains a lot of armor -->
<resource name="laenshield">
<item weight="0" score="1000">
<construction skill="armorer" minskill="7" reqsize="1">
<requirement type="laen" quantity="1"/>
</construction>
<armor ac="2" penalty="-0.25" magres="0.3" laen="yes" shield="yes" />
</item>
</resource>
<resource name="laenmail">
<item weight="100" score="1000">
<construction skill="armorer" minskill="9" reqsize="1">
<requirement type="laen" quantity="3"/>
</construction>
<armor ac="6" penalty="0.0" magres="0.3" laen="yes" />
</item>
</resource>
<resource name="rustyshield">
<item weight="100" score="10">
<construction skill="armorer" minskill="2" reqsize="1">
<requirement type="iron" quantity="1"/>
</construction>
<armor ac="1" penalty="0.0" magres="0.0" shield="yes"/>
</item>
</resource>
<resource name="rustychainmail">
<item weight="200" score="30">
<construction skill="armorer" minskill="3" reqsize="1">
<requirement type="iron" quantity="3"/>
</construction>
<armor ac="2" penalty="0.30" magres="0.0"/>
</item>
</resource>
<resource name="shield">
<item weight="100" score="30">
<construction skill="armorer" minskill="2" reqsize="1">
<requirement type="iron" quantity="1"/>
</construction>
<armor ac="1" penalty="-0.15" magres="0.0" shield="yes"/>
</item>
</resource>
<resource name="chainmail">
<item weight="200" score="90">
<construction skill="armorer" minskill="3" reqsize="1">
<requirement type="iron" quantity="3"/>
</construction>
<armor ac="3" penalty="0.15" magres="0.0"/>
</item>
</resource>
<resource name="plate">
<item weight="400" score="150">
<construction skill="armorer" minskill="4" reqsize="1">
<requirement type="iron" quantity="5"/>
</construction>
<armor ac="5" penalty="0.30" magres="0.0"/>
</item>
</resource>
<xi:include href="../armor/plate.xml"/>
<xi:include href="../armor/chainmail.xml"/>
<xi:include href="../armor/laenmail.xml"/>
<xi:include href="../armor/laenshield.xml"/>
<xi:include href="../armor/rustychainmail.xml"/>
<xi:include href="../armor/rustyshield.xml"/>
<xi:include href="../armor/shield.xml"/>
</resources>

View File

@ -1,74 +1,12 @@
<?xml version="1.0"?>
<resources>
<resources xmlns:xi="http://www.w3.org/2001/XInclude">
<!-- this file contains resources that can be mined in some way (anything with a resourcelimit) -->
<resource name="iron" limited="yes" material="rm_iron">
<item weight="500" score="10">
<construction skill="mining" minskill="1" reqsize="1"/>
</item>
<resourcelimit>
<modifier building="mine" type="skill" value="1"/>
<modifier building="mine" type="material" value="0.5"/>
<modifier race="dwarf" type="material" value="0.75"/>
<guard flag="mining"/>
</resourcelimit>
</resource>
<resource name="laen" limited="yes" material="rm_laen">
<item weight="200" score="100">
<construction skill="mining" minskill="7" reqsize="1"/>
</item>
<resourcelimit>
<modifier type="require" building="mine"/>
<guard flag="mining"/>
</resourcelimit>
</resource>
<resource name="stone" limited="yes" material="rm_stone">
<item weight="6000" score="10" big="yes">
<construction skill="quarrying" minskill="1" reqsize="1"/>
</item>
<resourcelimit>
<modifier building="quarry" type="skill" value="1"/>
<modifier building="quarry" type="material" value="0.5"/>
<modifier race="troll" type="material" value="0.75"/>
</resourcelimit>
</resource>
<resource name="horse" limited="yes" material="rm_horse">
<item big="yes" weight="5000" score="10" capacity="7000" animal="yes">
<construction skill="training" minskill="1" reqsize="1"/>
<function name="give" value="givehorses"/>
</item>
<resourcelimit>
<function name="produce" value="lua_produceresource"/>
<function name="limit" value="lua_limitresource"/>
</resourcelimit>
</resource>
<resource name="log" material="rm_tree">
<item weight="500" score="10">
<construction skill="forestry" minskill="1" reqsize="1"/>
</item>
<resourcelimit>
<modifier building="sawmill" type="skill" value="1"/>
<modifier building="sawmill" type="material" value="0.5"/>
<guard flag="logging"/>
<function name="produce" value="lua_produceresource"/>
<function name="limit" value="lua_limitresource"/>
</resourcelimit>
</resource>
<resource name="mallorn" material="rm_mallorn">
<item weight="500" score="30">
<construction skill="forestry" minskill="2" reqsize="1"/>
</item>
<resourcelimit>
<modifier building="sawmill" type="skill" value="1"/>
<modifier building="sawmill" type="material" value="0.5"/>
<guard flag="logging"/>
<function name="produce" value="lua_produceresource"/>
<function name="limit" value="lua_limitresource"/>
</resourcelimit>
</resource>
<xi:include href="../resources/iron.xml"/>
<xi:include href="../resources/stone.xml"/>
<xi:include href="../resources/laen.xml"/>
<xi:include href="../resources/horse.xml"/>
<xi:include href="../resources/mallorn.xml"/>
<xi:include href="../resources/log.xml"/>
</resources>

View File

@ -7,30 +7,32 @@
<xi:include href="en/strings.xml"/>
<xi:include href="common/items.xml" />
<xi:include href="common/armor.xml" />
<!-- xi:include href="common/weapons.xml" /-->
<xi:include href="common/resources.xml" />
<!--xi:include href="common/armor.xml" /-->
<!--xi:include href="common/weapons.xml" /-->
<!--xi:include href="common/resources.xml" /-->
<!--xi:include href="common/luxuries.xml" /-->
<xi:include href="common/herbs.xml" />
<!-- xi:include href="common/potions.xml" /-->
<!--xi:include href="common/potions.xml" /-->
<xi:include href="spoils.xml"/>
<xi:include href="prefixes.xml"/>
<xi:include href="ships.xml"/>
<xi:include href="buildings.xml"/>
<xi:include href="eressea/calendar.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/luxuries.xml" />
<xi:include href="e2k9/weapons.xml" />
<xi:include href="e2k9/calendar.xml"/>
<xi:include href="e2k9/items.xml" />
<xi:include href="e2k9/strings.xml"/>
<xi:include href="e2k9/races.xml"/>
<xi:include href="e2k9/buildings.xml"/>
<xi:include href="e2k9/equipment.xml"/>
<xi:include href="e2k9/spells.xml"/>
<xi:include href="e2k9/luxuries.xml" />
<xi:include href="e2k9/weapons.xml" />
<xi:include href="e2k9/armor.xml" />
<xi:include href="e2k9/resources.xml" />
<equipment>
<set name="first_unit">

View File

@ -1,19 +1,6 @@
<?xml version="1.0"?>
<resources>
<resource name="towershield">
<item weight="200" score="60">
<function name="canuse" value="lua_canuse_item"/>
<construction skill="armorer" minskill="6" reqsize="1">
<modifier function="mod_dwarves_only"/>
<requirement type="iron" quantity="2"/>
</construction>
<armor ac="2" projectile="0.30" penalty="-0.10" magres="0.0" shield="yes">
<modifier type="canuse" function="mod_elves_only"/>
</armor>
</item>
</resource>
<resource name="p2" appearance="vial">
<item weight="0" score="30">
<function name="use" value="usepotion"/>

View File

@ -3,12 +3,13 @@
<!-- begin main races -->
<race name="goblin" magres="-0.05" maxaura="1.0" regaura="1.0" recruitcost="100" maintenance="6" weight="600" capacity="440" speed="1.0" hp="16" damage="1d5" unarmedattack="-2" unarmeddefense="0" playerrace="yes" walk="yes" giveitem="yes" giveperson="yes" giveunit="yes" getitem="yes" equipment="yes">
<race name="goblin" magres="-0.05" maxaura="1.0" regaura="1.0" recruitcost="60" maintenance="6" weight="600" capacity="440" speed="1.0" hp="16" damage="1d5" unarmedattack="-2" unarmeddefense="0" playerrace="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"/>
<param name="hunger.damage" value="1d8+7"/>
<param name="other_race" value="demon"/>
<param name="other_cost" value="500"/>
<param name="hunger.damage" value="1d8+7"/>
<param name="other_race" value="demon"/>
<param name="other_cost" value="500"/>
<param name="recruit_multi" value="0.5"/>
<skill name="building" modifier="1"/>
<skill name="cartmaking" modifier="-1"/>
<skill name="catapult" modifier="1"/>
@ -58,12 +59,14 @@
<race name="human" magres="0.000000" maxaura="1.0" regaura="1.0" recruitcost="100" maintenance="10" weight="1000" capacity="540" speed="1.0" hp="20" damage="1d5" unarmedattack="-2" unarmeddefense="-2" playerrace="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"/>
<param name="other_race" value="elf"/>
<param name="other_cost" value="500"/>
<param name="other_race" value="elf"/>
<param name="other_cost" value="500"/>
<skill name="herbalism" modifier="-1"/>
<skill name="shipcraft" modifier="3"/>
<skill name="sailing" modifier="3"/>
<skill name="riding" modifier="+2"/>
<skill name="shipcraft" modifier="2"/>
<skill name="sailing" modifier="2"/>
<skill name="magic" modifier="-99"/>
<skill name="training" modifier="+1"/>
<skill name="unarmed" modifier="-99"/>
<attack type="1" damage="1d5"/>
<familiar race="dolphin" default="yes"/>
@ -73,8 +76,9 @@
<race name="halfling" defensemodifier="1" magres="0.05" maxaura="1.0" regaura="1.0" recruitcost="100" maintenance="10" weight="1000" capacity="540" speed="1.0" hp="20" damage="1d5" unarmedattack="-2" unarmeddefense="-2" playerrace="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"/>
<param name="other_race" value="dwarf"/>
<param name="other_cost" value="500"/>
<param name="other_race" value="dwarf"/>
<param name="other_cost" value="500"/>
<param name="popularity" value="5"/>
<skill name="bow" modifier="-1"/>
<skill name="building" modifier="1"/>
<skill name="cartmaking" modifier="2"/>
@ -88,6 +92,7 @@
<skill name="roadwork" modifier="1"/>
<skill name="sailing" modifier="-2"/>
<skill name="shipcraft" modifier="-1"/>
<skill name="tactics" modifier="1"/>
<skill name="training" modifier="-1"/>
<skill name="magic" modifier="-99"/>
<skill name="unarmed" modifier="-99"/>

View File

@ -7,6 +7,10 @@
_a: including article (ein Troll, a troll)
-->
<!--Fort-Ausbaustufen -->
<string name="thirdage">
<text locale="de">des dritten Zeitalters</text>
<text locale="en">the third age</text>
</string>
<string name="guardhouse">
<text locale="de">Wachstube</text>
<text locale="en">guard house</text>

View File

@ -1293,6 +1293,7 @@
</race>
<race name="uruk" magres="-0.050000" maxaura="1.000000" regaura="1.000000" recruitcost="70" maintenance="10" weight="1000" capacity="540" speed="1.000000" hp="24" damage="1d5" unarmedattack="-2" unarmeddefense="-2" playerrace="yes" walk="yes" giveitem="yes" giveperson="yes" giveunit="yes" getitem="yes" equipment="yes">
<ai splitsize="10000" moverandom="yes" learn="yes"/>
<param name="recruit_multi" value="0.5"/>
<skill name="alchemy" modifier="1"/>
<skill name="mining" modifier="1"/>
<skill name="building" modifier="1"/>

View File

@ -1,10 +1,16 @@
-- used internally to check greatbow and towershield
function item_canuse(u, iname)
if iname=="towershield" then
-- only dwarves allowed to use towershield
return u.race=="dwarf"
end
if iname=="greatbow" then
-- only elves use greatbow
return u.race=="elf"
end
if iname=="plate" then
-- goblins cannot use plate
return u.race~="goblin"
end
return true
end