New rules, with defines

This commit is contained in:
Enno Rehling 2004-08-03 15:34:26 +00:00
parent 73cda7a160
commit cd4fc9e2bc
22 changed files with 271 additions and 129 deletions

View File

@ -729,16 +729,25 @@ cr_output_unit(FILE * F, const region * r,
fputs("1;unaided\n", F);
}
i = u_geteffstealth(u);
if (i >= 0)
if (i >= 0) {
fprintf(F, "%d;Tarnung\n", i);
}
c = uprivate(u);
if (c)
if (c) {
fprintf(F, "\"%s\";privat\n", c);
}
c = hp_status(u);
if (c && *c && (u->faction == f || omniscient(f)))
if (c && *c && (u->faction == f || omniscient(f))) {
fprintf(F, "\"%s\";hp\n", add_translation(c, locale_string(u->faction->locale, c)));
if (fval(u, UFL_HUNGER) && (u->faction == f))
}
#ifdef HEROES
if (fval(u, UFL_HERO)) {
fputs("1;hero\n", F);
}
#endif
if (fval(u, UFL_HUNGER) && (u->faction == f)) {
fputs("1;hunger\n", F);
}
if (is_mage(u)) {
fprintf(F, "%d;Aura\n", get_spellpoints(u));
fprintf(F, "%d;Auramax\n", max_spellpoints(u->region,u));

View File

@ -2444,6 +2444,36 @@ reshow(unit * u, struct order * ord, const char * s, param_t p)
}
}
#ifdef HEROES
static int
promote_cmd(unit * u, struct order * ord)
{
int money, people;
if (maxheroes(u->faction) < countheroes(u->faction)+u->number) {
ADDMSG(&u->faction->msgs, msg_feedback(u, ord, "heroes_maxed", "max count",
maxheroes(u->faction), countheroes(u->faction)));
return 0;
}
if (!playerrace(u->race)) {
ADDMSG(&u->faction->msgs, msg_feedback(u, ord, "heroes_race", "race",
u->race));
return 0;
}
money = get_all(u, i_silver->rtype);
people = count_all(u->faction) * u->number;
if (people>money) {
ADDMSG(&u->faction->msgs, msg_feedback(u, ord, "heroes_cost", "cost have",
people, money));
return 0;
}
use_all(u, i_silver->rtype, people);
fset(u, UFL_HERO);
return 0;
}
#endif
static int
group_cmd(unit * u, struct order * ord)
{
@ -3320,7 +3350,7 @@ setdefaults (void)
order *ord;
boolean trade = false;
if (LongHunger() && fval(u, UFL_HUNGER)) {
if (LongHunger(u)) {
/* Hungernde Einheiten führen NUR den default-Befehl aus */
set_order(&u->thisorder, default_order(u->faction->locale));
continue;
@ -3465,27 +3495,17 @@ use_item(unit * u, const item_type * itype, int amount, struct order * ord)
}
static int
canheal(const unit *u)
static double
heal_factor(const race *rc)
{
switch(old_race(u->race)) {
case RC_DAEMON:
return 15;
break;
case RC_GOBLIN:
return 20;
break;
case RC_TROLL:
return 15;
break;
case RC_FIREDRAGON:
case RC_DRAGON:
case RC_WYRM:
return 10;
break;
switch(old_race(rc)) {
case RC_TROLL:
case RC_DAEMON:
return 1.5;
case RC_GOBLIN:
return 2.0;
}
if (u->race->flags & RCF_NOHEAL) return 0;
return 10;
return 1.0;
}
static void
@ -3508,55 +3528,53 @@ monthly_healing(void)
}
for (u = r->units; u; u = u->next) {
int umhp = unit_max_hp(u) * u->number;
int p;
double p = 1.0;
/* hp über Maximum bauen sich ab. Wird zb durch Elixier der Macht
* oder verändertes Ausdauertalent verursacht */
if (u->hp > umhp) {
u->hp -= (int) ceil((u->hp - umhp) / 2.0);
if (u->hp < umhp)
u->hp = umhp;
if (u->hp < umhp) u->hp = umhp;
continue;
}
if((u->race->flags & RCF_NOHEAL) || fval(u, UFL_HUNGER) || fspecial(u->faction, FS_UNDEAD))
continue;
if (u->race->flags & RCF_NOHEAL) continue;
if (fval(u, UFL_HUNGER)) continue;
if (fspecial(u->faction, FS_UNDEAD)) continue;
if(rterrain(r) == T_OCEAN && !u->ship && !(canswim(u)))
continue;
if (rterrain(r)==T_OCEAN && u->ship==NULL && !canswim(u)) continue;
if(fspecial(u->faction, FS_REGENERATION)) {
u->hp = umhp;
continue;
}
p = canheal(u);
if (u->hp < umhp && p > 0) {
/* Mind 1 HP wird pro Runde geheilt, weil angenommen wird,
das alle Personen mind. 10 HP haben. */
int max_unit = max(umhp, u->number * 10);
#ifdef NEW_TAVERN
p *= heal_factor(u->race);
if (u->hp < umhp) {
#ifdef NEW_DAEMONHUNGER_RULE
double maxheal = max(u->number, umhp/20.0);
#else
double maxheal = max(u->number, umhp/10.0);
#endif
int addhp;
struct building * b = inside_building(u);
const struct building_type * btype = b?b->type:NULL;
if (btype == bt_find("inn")) {
max_unit = max_unit * 3 / 2;
}
#endif
/* der healing curse verändert den Regenerationsprozentsatz.
* Wenn dies für negative Heilung benutzt wird, kann es zu
* negativen u->hp führen! */
if (healingcurse != 0) {
p += healingcurse;
p *= 1.5;
}
/* pro punkt 5% höher */
p *= (1.0 + healingcurse * 0.05);
maxheal = p * maxheal;
addhp = (int)maxheal;
maxheal -= addhp;
if (maxheal>0.0 && chance(maxheal)) ++addhp;
/* Aufaddieren der geheilten HP. */
u->hp = min(u->hp + max_unit*p/100, umhp);
if (u->hp < umhp && (rand() % 10 < max_unit % 10)){
++u->hp;
}
u->hp = min(u->hp + addhp, umhp);
/* soll man an negativer regeneration sterben können? */
if (u->hp <= 0){
u->hp = 1;
}
assert(u->hp > 0);
}
}
}
@ -3807,6 +3825,12 @@ processorders (void)
puts(" - Krieg & Frieden");
declare_war();
#endif
#ifdef HEROES
puts(" - Heldenbeförderung");
parse(K_PROMOTION, promote_cmd, false);
#endif
puts(" - Neue Nummern");
renumber();

View File

@ -55,8 +55,6 @@
#define STANDARD_LUCK 0
extern struct item_type *i_silver;
static void
lucky_silver(const unit *u)
{

View File

@ -20,7 +20,7 @@
*/
#define TEACH_ALL 1
#define TEACH_FRIENDS 1
#define TEACH_FRIENDS
#include <config.h>
#include "eressea.h"
@ -293,7 +293,12 @@ teach(unit * u, struct order * ord)
teachskill[i++]=sk;
} while (sk!=NOSKILL);
while (teaching && student) {
if (student->faction == u->faction && !fval(student, UFL_HUNGER)) {
if (student->faction == u->faction) {
#ifdef NEW_DAEMONHUNGER_RULE
if (LongHunger(student)) continue;
#else
if (fval(student, UFL_HUNGER)) continue;
#endif
if (get_keyword(student->thisorder) == K_STUDY) {
/* Input ist nun von student->thisorder !! */
init_tokens(student->thisorder);
@ -310,9 +315,14 @@ teach(unit * u, struct order * ord)
}
student = student->next;
}
#if TEACH_FRIENDS
#ifdef TEACH_FRIENDS
while (teaching && student) {
if (student->faction != u->faction && !fval(student, UFL_HUNGER) && alliedunit(u, student->faction, HELP_GUARD)) {
if (student->faction != u->faction && alliedunit(u, student->faction, HELP_GUARD)) {
#ifdef NEW_DAEMONHUNGER_RULE
if (LongHunger(student)) continue;
#else
if (fval(student, UFL_HUNGER)) continue;
#endif
if (get_keyword(student->thisorder) == K_STUDY) {
/* Input ist nun von student->thisorder !! */
init_tokens(student->thisorder);
@ -699,7 +709,7 @@ learn(void)
days *= 2;
}
if (fval(u, UFL_HUNGER)) days = days / 2;
if (fval(u, UFL_HUNGER)) days /= 2;
while (days) {
if (days>=u->number*30) {

View File

@ -19,9 +19,14 @@
#define CATAPULT_INITIAL_RELOAD 4 /* erster schuss in runde 1 + rand() % INITIAL */
#define CATAPULT_STRUCTURAL_DAMAGE
#define BASE_CHANCE 70 /* 70% Überlebenschance */
#define BASE_CHANCE 70 /* 70% Basis-Überlebenschance */
#ifdef NEW_COMBATSKILLS_RULE
#define TDIFF_CHANGE 5 /* 5% höher pro Stufe */
#define DAMAGE_QUOTIENT 2 /* damage += skilldiff/DAMAGE_QUOTIENT */
#else
#define TDIFF_CHANGE 10
# define DAMAGE_QUOTIENT 1 /* damage += skilldiff/DAMAGE_QUOTIENT */
#endif
typedef enum combatmagic {
DO_PRECOMBATSPELL,
@ -107,16 +112,12 @@ static int obs_count = 0;
#define MINSPELLRANGE 1
#define MAXSPELLRANGE 7
#ifndef ROW_FACTOR
# define ROW_FACTOR 10
#endif
static const double EFFECT_PANIC_SPELL = 0.25;
static const double TROLL_REGENERATION = 0.10;
#define MAX_ADVANTAGE 5
enum {
SI_DEFENDER,
SI_ATTACKER
};
extern weapon_type * oldweapontype[];
/* Nach dem alten System: */
@ -516,7 +517,7 @@ get_unitrow(const fighter * af)
if (enemyfront) {
for (line=FIRST_ROW;line!=NUMROWS;++line) {
front += size[line];
if (!front || front<enemyfront/10) ++retreat;
if (!front || front<enemyfront/ROW_FACTOR) ++retreat;
else if (front) break;
}
}
@ -568,21 +569,11 @@ contest(int skilldiff, armor_t ar, armor_t sh)
int p, vw = BASE_CHANCE - TDIFF_CHANGE * skilldiff;
double mod = 1.0;
/* Hardcodet, muß geändert werden. */
#ifdef OLD_ARMOR
if (ar != AR_NONE)
mod *= (1 - armordata[ar].penalty);
if (sh != AR_NONE)
mod *= (1 - armordata[sh].penalty);
vw = (int) (vw * mod);
#else
if (ar != AR_NONE)
mod *= (1 + armordata[ar].penalty);
if (sh != AR_NONE)
mod *= (1 + armordata[sh].penalty);
vw = (int)(100 - ((100 - vw) * mod));
#endif
do {
p = rand() % 100;
@ -1098,7 +1089,7 @@ terminate(troop dt, troop at, int type, const char *damage, boolean missile)
}
/* Skilldifferenzbonus */
da += max(0, sk-sd);
da += max(0, (sk-sd)/DAMAGE_QUOTIENT);
}
@ -1182,7 +1173,7 @@ terminate(troop dt, troop at, int type, const char *damage, boolean missile)
#ifdef TODO_RUNESWORD
if (select_weapon(dt, 0, -1) == WP_RUNESWORD) continue;
#endif
if (!(df->person[dt.index].flags & FL_HERO)) {
if (!(df->person[dt.index].flags & FL_COURAGE)) {
df->person[dt.index].flags |= FL_DAZZLED;
df->person[dt.index].defence--;
}
@ -1897,7 +1888,7 @@ dazzle(battle *b, troop *td)
return;
}
#endif
if (td->fighter->person[td->index].flags & FL_HERO) {
if (td->fighter->person[td->index].flags & FL_COURAGE) {
#ifdef SMALL_BATTLE_MESSAGES
if (b->small) {
sprintf(smallbuf, "Eine kurze Schwäche erfaßt %s/%d, vergeht jedoch "
@ -1964,6 +1955,29 @@ attacks_per_round(troop t)
return t.fighter->person[t.index].speed;
}
#ifdef HEROES
#define HERO_SPEED 10
static void
make_heroes(battle * b)
{
side * s;
cv_foreach(s, b->sides) {
fighter * fig;
cv_foreach(fig, s->fighters) {
unit * u = fig->unit;
if (fval(u, UFL_HERO)) {
int i;
assert(playerrace(u->race));
for (i=0;i!=u->number;++i) {
fig->person[i].speed += (HERO_SPEED-1);
}
}
} cv_next(fig);
} cv_next(s);
}
#endif
static void
attack(battle *b, troop ta, const att *a)
{
@ -2148,8 +2162,6 @@ do_attack(fighter * af)
unit *au = af->unit;
side *side = af->side;
battle *b = side->battle;
int apr;
int a;
ta.fighter = af;
@ -2165,11 +2177,21 @@ do_attack(fighter * af)
/* Wir suchen eine beliebige Feind-Einheit aus. An der können
* wir feststellen, ob noch jemand da ist. */
int enemies = count_enemies(b, af->side, FIGHT_ROW, LAST_ROW);
int apr, attacks = attacks_per_round(ta);
if (!enemies) break;
for (apr=attacks_per_round(ta); apr > 0; apr--) {
for (a=0; a!=10; ++a) {
if (au->race->attack[a].type != AT_NONE)
for (apr=0;apr!=attacks;++apr) {
int a;
for (a=0; a!=10 && au->race->attack[a].type!=AT_NONE; ++a) {
if (apr>0) {
/* Wenn die Waffe nachladen muss, oder es sich nicht um einen
* Waffen-Angriff handelt, dann gilt der Speed nicht. */
if (au->race->attack[a].type!=AT_STANDARD) continue;
else {
weapon * wp = preferred_weapon(ta, true);
if (wp->type->reload) continue;
}
}
attack(b, ta, &(au->race->attack[a]));
}
}
@ -2926,7 +2948,7 @@ make_fighter(battle * b, unit * u, side * s1, boolean attack)
fig->person[i].defence++;
fig->person[i].damage++;
fig->person[i].damage_rear++;
fig->person[i].flags |= FL_HERO;
fig->person[i].flags |= FL_COURAGE;
}
/* Leute mit Kraftzauber machen +2 Schaden im Nahkampf. */
if (i < strongmen) {
@ -3053,7 +3075,7 @@ make_fighter(battle * b, unit * u, side * s1, boolean attack)
if (t > 0 && get_unitrow(fig) > BEHIND_ROW)
t -= 1;
#endif
#if TACTICS_RANDOM
#ifdef TACTICS_RANDOM
if (t > 0) {
int bonus = 0;
@ -3074,9 +3096,6 @@ make_fighter(battle * b, unit * u, side * s1, boolean attack)
}
t += bonus;
}
/* Nicht gut, da nicht personenbezogen. */
/* if (t > 0) t += rand() % TACTICS_RANDOM; */
/* statt +/- 2 kann man auch random(5) nehmen */
#endif
add_tactics(&fig->side->leader, fig, t);
return fig;
@ -3393,8 +3412,6 @@ join_allies(battle * b)
}
}
extern struct item_type * i_silver;
static void
flee(const troop dt)
{
@ -3503,7 +3520,7 @@ init_battle(region * r, battle **bp)
msg_message("no_attack_after_advance", "unit region command", u, u->region, ord));
}
#endif
if (fval(u, UFL_HUNGER)) {
if (LongHunger(u)) {
cmistake(u, ord, 225, MSG_BATTLE);
continue;
}
@ -3708,7 +3725,9 @@ do_battle(void)
continue;
}
join_allies(b);
#ifdef HEROES
make_heroes(b);
#endif
/* Alle Mann raus aus der Burg! */
for (bu=r->buildings; bu!=NULL; bu=bu->next) bu->sizeleft = bu->size;
@ -3802,7 +3821,7 @@ do_battle(void)
if ((u->status == ST_FLEE
|| (b->turn>1 && fig->person[dt.index].hp <= runhp)
|| (fig->person[dt.index].flags & FL_PANICED))
&& !(fig->person[dt.index].flags & FL_HERO))
&& !(fig->person[dt.index].flags & FL_COURAGE))
{
double ispaniced = 0.0;
if (fig->person[dt.index].flags & FL_PANICED) {

View File

@ -105,7 +105,7 @@ extern "C" {
#define FL_TIRED 1
#define FL_DAZZLED 2 /* durch Untote oder Dämonen eingeschüchtert */
#define FL_PANICED 4
#define FL_HERO 8 /* Helden fliehen nie */
#define FL_COURAGE 8 /* Helden fliehen nie */
#define FL_SLEEPING 16
#define FL_STUNNED 32 /* eine Runde keinen Angriff */
@ -162,7 +162,7 @@ extern "C" {
int speed : 8; /* (Magie) Geschwindigkeitsmultiplkator. */
int reload : 4; /* Anzahl Runden, die die Waffe x noch laden muss.
* dahinter steckt ein array[RL_MAX] wenn er min. eine hat. */
int last_action : 8; /* In welcher Runde haben wir zuletzt etwas getan */
int last_action : 4; /* In welcher Runde haben wir zuletzt etwas getan */
struct weapon * missile; /* missile weapon */
struct weapon * melee; /* melee weapon */
#undef FIXED_OPPONENTS

View File

@ -62,7 +62,6 @@
#include <items/catapultammo.h>
#define NEW_TAVERN
#define STONERECYCLE 50
/* Name, MaxGroesse, MinBauTalent, Kapazitaet, {Eisen, Holz, Stein, BauSilber,
* Laen, Mallorn}, UnterSilber, UnterSpezialTyp, UnterSpezial */

View File

@ -1025,7 +1025,7 @@ sp_flee(fighter * fi, int level, double power, spell * sp)
df->person[n].attack -= 1;
--force;
++panik;
} else if (!(df->person[n].flags & FL_HERO)
} else if (!(df->person[n].flags & FL_COURAGE)
|| !fval(df->unit->race, RCF_UNDEAD))
{
if (is_magic_resistant(mage, df->unit, 0) == false) {
@ -1085,9 +1085,9 @@ sp_hero(fighter * fi, int level, double power, spell * sp)
--allies;
if (df) {
if (!(df->person[dt.index].flags & FL_HERO)) {
if (!(df->person[dt.index].flags & FL_COURAGE)) {
df->person[dt.index].defence += df_bonus;
df->person[dt.index].flags = df->person[dt.index].flags | FL_HERO;
df->person[dt.index].flags = df->person[dt.index].flags | FL_COURAGE;
targets++;
--force;
}
@ -1145,10 +1145,10 @@ sp_berserk(fighter * fi, int level, double power, spell * sp)
--allies;
if (df) {
if (!(df->person[dt.index].flags & FL_HERO)) {
if (!(df->person[dt.index].flags & FL_COURAGE)) {
df->person[dt.index].attack += at_bonus;
df->person[dt.index].defence -= df_malus;
df->person[dt.index].flags = df->person[dt.index].flags | FL_HERO;
df->person[dt.index].flags = df->person[dt.index].flags | FL_COURAGE;
targets++;
--force;
}
@ -1202,8 +1202,8 @@ sp_frighten(fighter * fi, int level, double power, spell * sp)
assert(!helping(fi->side, df->side));
if (df->person[dt.index].flags & FL_HERO) {
df->person[dt.index].flags &= ~(FL_HERO);
if (df->person[dt.index].flags & FL_COURAGE) {
df->person[dt.index].flags &= ~(FL_COURAGE);
}
if (is_magic_resistant(mage, df->unit, 0) == false) {
df->person[dt.index].attack -= at_malus;

View File

@ -194,8 +194,14 @@ FirstTurn(void)
}
int
LongHunger(void) {
LongHunger(const struct unit * u) {
static int value = -1;
if (u!=NULL) {
if (!fval(u, UFL_HUNGER)) return false;
#ifdef NEW_DAEMONHUNGER_RULE
if (u->race==new_race[RC_DAEMON]) return false;
#endif
}
if (value<0) {
const char * str = get_param(global.parameters, "hunger.long");
value = str?atoi(str):0;
@ -399,7 +405,8 @@ const char *keywords[MAXKEYWORDS] =
"PFLANZEN",
"WERWESEN",
"XONTORMIA",
"ALLIANZ"
"ALLIANZ",
"PROMOTION"
};
const char *report_options[MAX_MSG] =
@ -923,7 +930,7 @@ autoalliance(const plane * pl, const faction * sf, const faction * f2)
}
}
if (sf->alliance && AllianceAuto()) {
if (sf->alliance!=NULL && AllianceAuto()) {
if (sf->alliance==f2->alliance) return AllianceAuto();
}
@ -1223,11 +1230,12 @@ count_all(const faction * f)
{
int n = 0;
unit *u;
for (u=f->units;u;u=u->nextF)
for (u=f->units;u;u=u->nextF) {
if (playerrace(u->race)) {
n += u->number;
assert(f==u->faction);
}
}
return n;
}

View File

@ -100,7 +100,6 @@ struct building_type;
#define PARTIAL_STUDY /* Wenn nicht genug Silber vorhanden, wird ein Talent anteilig gelernt */
#define HUNGER_REDUCES_SKILL /* Hunger reduziert den Talentwert auf die Hälfte */
#define NEW_RECEIPIES /* Vereinfachte, besser verteilte Kräuterzutaten für Tränke */
#define NEW_TAVERN
#define GOBLINKILL
#define USE_FIREWALL 1
@ -450,6 +449,9 @@ enum {
K_WEREWOLF,
K_XE,
K_ALLIANCE,
#ifdef HEROES
K_PROMOTION,
#endif
MAXKEYWORDS,
NOKEYWORD = (keyword_t) - 1
};
@ -1169,7 +1171,7 @@ extern const char* get_param(const struct param * p, const char * name);
extern boolean ExpensiveMigrants(void);
extern int FirstTurn(void);
extern int NMRTimeout(void);
extern int LongHunger(void);
extern int LongHunger(const struct unit * u);
extern boolean TradeDisabled(void);
extern int SkillCap(skill_t sk);
extern int AllianceAuto(void); /* flags that allied factions get automatically */

View File

@ -126,7 +126,7 @@ give_item(int want, const item_type * itype, unit * src, unit * dest, struct ord
handle_event(&src->attribs, "give", dest);
handle_event(&dest->attribs, "receive", src);
#if defined(MUSEUM_MODULE) && defined(TODO)
TODO: Einen Trigger benutzen!
/* TODO: Einen Trigger für den museums-warden benutzen! */
if (a_find(dest->attribs, &at_warden)) {
/* warden_add_give(src, dest, itype, n); */
}
@ -158,6 +158,10 @@ givemen(int n, unit * u, unit * u2, struct order * ord)
} else if (!u2 && u->race == new_race[RC_SNOTLING]) {
/* Snotlings können nicht an Bauern übergeben werden. */
error = 307;
#endif
#ifdef HEROES
} else if (u2 && (fval(u, UFL_HERO)!=fval(u2, UFL_HERO))) {
error = 75;
#endif
} else if ((u && unit_has_cursed_item(u)) || (u2 && unit_has_cursed_item(u2))) {
error = 78;
@ -279,6 +283,12 @@ giveunit(unit * u, unit * u2, order * ord)
return;
}
#ifdef HEROES
if (fval(u, UFL_HERO)) {
cmistake(u, ord, 75, MSG_COMMERCE);
return;
}
#endif
if (fval(u, UFL_LOCKED) || fval(u, UFL_HUNGER)) {
cmistake(u, ord, 74, MSG_COMMERCE);
return;

View File

@ -552,6 +552,8 @@ extern void init_resources(void);
extern const char* resname(resource_t res, int index);
extern struct item_type *i_silver;
#ifdef __cplusplus
}
#endif

View File

@ -2424,7 +2424,7 @@ magic(void)
for (ord = u->orders; ord; ord = ord->next) {
if (get_keyword(ord) == K_CAST) {
if (LongHunger() && fval(u, UFL_HUNGER)) {
if (LongHunger(u)) {
cmistake(u, ord, 224, MSG_MAGIC);
continue;
}

View File

@ -270,10 +270,10 @@ walkingcapacity(const struct unit * u)
n += personen * personcapacity(u);
/* Goliathwasser */
tmp = get_effect(u, oldpotiontype[P_STRONG]);
n += min(u->number, tmp) * (HORSECAPACITY - personcapacity(u));
n += min(personen, tmp) * (HORSECAPACITY - personcapacity(u));
/* change_effect wird in ageing gemacht */
tmp = get_item(u, I_TROLLBELT);
n += min(tmp, u->number) * STRENGTHCAPACITY;
n += min(personen, tmp) * STRENGTHCAPACITY;
return n;
}
@ -876,7 +876,7 @@ init_drive(void)
* doesn't seem to be an easy way to speed this up. */
for(u=r->units; u; u=u->next) {
if (get_keyword(u->thisorder) == K_DRIVE && !fval(u, UFL_LONGACTION) && !fval(u, UFL_HUNGER)) {
if (get_keyword(u->thisorder) == K_DRIVE && !fval(u, UFL_LONGACTION) && !LongHunger(u)) {
boolean found = false;
order * ord;
@ -922,7 +922,7 @@ init_drive(void)
ut = getunit(r, u->faction);
if (ut==NULL) continue;
if (get_keyword(ut->thisorder) == K_DRIVE && !fval(ut, UFL_LONGACTION) && !fval(ut, UFL_HUNGER)) {
if (get_keyword(ut->thisorder) == K_DRIVE && !fval(ut, UFL_LONGACTION) && !LongHunger(ut)) {
init_tokens(ut->thisorder);
skip_token();
if (getunit(r, ut->faction) == u) {
@ -1349,7 +1349,7 @@ travel(unit * u, region * next, int flucht, region_list ** routep)
if (ut) {
boolean found = false;
if (get_keyword(ut->thisorder) == K_DRIVE
&& !fval(ut, UFL_LONGACTION) && !fval(ut, UFL_HUNGER)) {
&& !fval(ut, UFL_LONGACTION) && !LongHunger(ut)) {
init_tokens(ut->thisorder);
skip_token();
u2 = getunit(first, ut->faction);
@ -2201,7 +2201,7 @@ move_hunters(void)
break;
}
if (!fval(u, UFL_LONGACTION) && !fval(u, UFL_HUNGER) && hunt(u)) {
if (!fval(u, UFL_LONGACTION) && !LongHunger(u) && hunt(u)) {
up = &r->units;
break;
}
@ -2335,7 +2335,7 @@ follow_unit(void)
attrib * a;
order * ord;
if (fval(u, UFL_LONGACTION) || fval(u, UFL_HUNGER)) continue;
if (fval(u, UFL_LONGACTION) || LongHunger(u)) continue;
a = a_find(u->attribs, &at_follow);
for (ord=u->orders;ord;ord=ord->next) {
const struct locale * lang = u->faction->locale;

View File

@ -261,6 +261,12 @@ bufunit(const faction * f, const unit * u, int indent, int mode)
}
}
#ifdef HEROES
if (fval(u, UFL_HERO) && (u->faction == f || omniscient(f))) {
scat(", ");
scat(LOC(f->locale, "hero"));
}
#endif
/* status */
if (u->number && (u->faction == f || telepath_see || isbattle)) {

View File

@ -49,6 +49,7 @@
#include <string.h>
#include <assert.h>
#include <stdlib.h>
#include <math.h>
#define FIND_FOREIGN_TEMP
@ -1127,3 +1128,22 @@ unitlist_insert(struct unit_list **ul, struct unit *u)
*ul = rl2;
}
#ifdef HEROES
int
maxheroes(const struct faction * f)
{
return (int)(log10(count_all(f) / 50.0) * 20);
}
int
countheroes(const struct faction * f)
{
const unit * u = f->units;
int n = 0;
while (u) {
if (fval(u, UFL_HERO)) n+= u->number;
u = u->nextF;
}
return n;
}
#endif

View File

@ -34,13 +34,14 @@ struct skill;
#define UFL_PARTEITARNUNG (1<<4) /* 16 */
#define UFL_DISBELIEVES (1<<5) /* 32 */
#define UFL_WARMTH (1<<6) /* 64 */
/* UFL_HERO, defined below (1<<7) */
#define UFL_MOVED (1<<8)
#define UFL_FOLLOWING (1<<9)
#define UFL_FOLLOWED (1<<10)
#define UFL_HUNGER (1<<11) /* kann im Folgemonat keinen langen Befehl
außer ARBEITE ausführen */
#define UFL_HUNGER (1<<11) /* kann im Folgemonat keinen langen Befehl außer ARBEITE ausführen */
#define UFL_SIEGE (1<<12) /* speedup: belagert eine burg, siehe attribut */
#define UFL_TARGET (1<<13) /* speedup: hat ein target, siehe attribut */
#define UFL_WERE (1<<14)
/* warning: von 512/1024 gewechslet, wegen konflikt mit NEW_FOLLOW */
#define UFL_LOCKED (1<<16) /* Einheit kann keine Personen aufnehmen oder weggeben, nicht rekrutieren. */
@ -52,10 +53,15 @@ au
#define UFL_TAKEALL (1<<25) /* Einheit nimmt alle Gegenstände an */
#define UFL_WERE (1<<28)
/* Flags, die gespeichert werden sollen: */
#ifndef HEROES
#define UFL_SAVEMASK (UFL_NOAID | UFL_OWNER | UFL_PARTEITARNUNG | UFL_LOCKED | UFL_HUNGER | FFL_NOIDLEOUT | UFL_TAKEALL)
#else
# define UFL_HERO (1<<7)
# define UFL_SAVEMASK (UFL_NOAID | UFL_OWNER | UFL_PARTEITARNUNG | UFL_LOCKED | UFL_HUNGER | FFL_NOIDLEOUT | UFL_TAKEALL | UFL_HERO)
extern int maxheroes(const struct faction * f);
extern int countheroes(const struct faction * f);
#endif
typedef struct unit {
struct unit *next; /* needs to be first entry, for region's unitlist */

View File

@ -34,10 +34,14 @@
#define PEASANTS_DO_NOT_STARVE 0
#define NEW_MIGRATION 1
#define ASTRAL_HUNGER
#define NEWATSROI 0
#define MUSEUM_MODULE
#define ARENA_MODULE
#define WORMHOLE_MODULE
#define XECMD_MODULE
#define NEW_DAEMONHUNGER_RULE
#define NEW_COMBATSKILLS_RULE
#define ROW_FACTOR 3 /* factor for combat row advancement rule */
#define HEROES

View File

@ -102,7 +102,6 @@ extern char * g_reportdir;
extern char * g_datadir;
extern char * g_basedir;
extern char * g_resourcedir;
extern item_type * i_silver;
extern boolean nonr;
extern boolean nocr;

View File

@ -108,7 +108,6 @@ extern "C" {
extern char * g_datadir;
extern char * g_basedir;
extern char * g_resourcedir;
extern item_type * i_silver;
extern boolean nonr;
extern boolean nocr;

View File

@ -2042,6 +2042,10 @@
<text locale="de">ALLIANZ</text>
<text locale="en">ALLIANCE</text>
</string>
<string name="PROMOTION">
<text locale="de">BEFÖRDERUNG</text>
<text locale="en">PROMOTION</text>
</string>
<string name="PFLANZEN">
<text locale="de">PFLANZEN</text>
</string>
@ -5899,4 +5903,14 @@
<text locale="en">unknown faction</text>
</string>
<string name="hero">
<text locale="de">Held</text>
<text locale="en">hero</text>
</string>
<string name="hero_p">
<text locale="de">Helden</text>
<text locale="en">heroes</text>
</string>
</strings>

View File

@ -6028,5 +6028,18 @@
<text locale="de">"$unit($unit) in $region($region): '$order($command)' - $race($race,0) können keine Helden erwählen."</text>
<text locale="en">"$unit($unit) in $region($region): '$order($command)' - $race($race,0) cannot be heroes."</text>
</message>
<message name="heroes_cost" section="errors">
<type>
<arg name="command" type="order"/>
<arg name="region" type="region"/>
<arg name="unit" type="unit"/>
<arg name="cost" type="int"/>
<arg name="have" type="int"/>
</type>
<text locale="de">"$unit($unit) in $region($region): '$order($command)' - Die Einheit hat nur $int($have) von $int($cost) benötigtem Silber."</text>
<text locale="en">"$unit($unit) in $region($region): '$order($command)' - The unit has $int($have) of $int($cost) silver required."</text>
</message>
</messages>