diff --git a/src/common/gamecode/creport.c b/src/common/gamecode/creport.c index 866860236..92e1e0a2b 100644 --- a/src/common/gamecode/creport.c +++ b/src/common/gamecode/creport.c @@ -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)); diff --git a/src/common/gamecode/laws.c b/src/common/gamecode/laws.c index 000ce43b7..7536ed48f 100644 --- a/src/common/gamecode/laws.c +++ b/src/common/gamecode/laws.c @@ -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(); diff --git a/src/common/gamecode/luck.c b/src/common/gamecode/luck.c index 9fb23bced..69d011b81 100644 --- a/src/common/gamecode/luck.c +++ b/src/common/gamecode/luck.c @@ -55,8 +55,6 @@ #define STANDARD_LUCK 0 -extern struct item_type *i_silver; - static void lucky_silver(const unit *u) { diff --git a/src/common/gamecode/study.c b/src/common/gamecode/study.c index 1f43e2e52..b5d3f8492 100644 --- a/src/common/gamecode/study.c +++ b/src/common/gamecode/study.c @@ -20,7 +20,7 @@ */ #define TEACH_ALL 1 -#define TEACH_FRIENDS 1 +#define TEACH_FRIENDS #include #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) { diff --git a/src/common/kernel/battle.c b/src/common/kernel/battle.c index e1d77e512..8f4b844b7 100644 --- a/src/common/kernel/battle.c +++ b/src/common/kernel/battle.c @@ -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 || frontperson[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) { diff --git a/src/common/kernel/battle.h b/src/common/kernel/battle.h index 47f5167d8..e23080ded 100644 --- a/src/common/kernel/battle.h +++ b/src/common/kernel/battle.h @@ -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 diff --git a/src/common/kernel/build.c b/src/common/kernel/build.c index 58949f072..fe62b5e72 100644 --- a/src/common/kernel/build.c +++ b/src/common/kernel/build.c @@ -62,7 +62,6 @@ #include -#define NEW_TAVERN #define STONERECYCLE 50 /* Name, MaxGroesse, MinBauTalent, Kapazitaet, {Eisen, Holz, Stein, BauSilber, * Laen, Mallorn}, UnterSilber, UnterSpezialTyp, UnterSpezial */ diff --git a/src/common/kernel/combatspells.c b/src/common/kernel/combatspells.c index 086a19d00..b7006b6da 100644 --- a/src/common/kernel/combatspells.c +++ b/src/common/kernel/combatspells.c @@ -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; diff --git a/src/common/kernel/eressea.c b/src/common/kernel/eressea.c index de76d4688..7446155c8 100644 --- a/src/common/kernel/eressea.c +++ b/src/common/kernel/eressea.c @@ -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; } diff --git a/src/common/kernel/eressea.h b/src/common/kernel/eressea.h index b62226ff6..e21b833be 100644 --- a/src/common/kernel/eressea.h +++ b/src/common/kernel/eressea.h @@ -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 */ diff --git a/src/common/kernel/give.c b/src/common/kernel/give.c index 0582a16c9..5385e6af4 100644 --- a/src/common/kernel/give.c +++ b/src/common/kernel/give.c @@ -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; diff --git a/src/common/kernel/item.h b/src/common/kernel/item.h index ce3a130cc..e4e1648ed 100644 --- a/src/common/kernel/item.h +++ b/src/common/kernel/item.h @@ -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 diff --git a/src/common/kernel/magic.c b/src/common/kernel/magic.c index 652c931b5..67b4c5fa2 100644 --- a/src/common/kernel/magic.c +++ b/src/common/kernel/magic.c @@ -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; } diff --git a/src/common/kernel/movement.c b/src/common/kernel/movement.c index 668fcde9e..e42447d00 100644 --- a/src/common/kernel/movement.c +++ b/src/common/kernel/movement.c @@ -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; diff --git a/src/common/kernel/reports.c b/src/common/kernel/reports.c index e77354557..b738b9152 100644 --- a/src/common/kernel/reports.c +++ b/src/common/kernel/reports.c @@ -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)) { diff --git a/src/common/kernel/unit.c b/src/common/kernel/unit.c index 7003f8b8a..a14196b4c 100644 --- a/src/common/kernel/unit.c +++ b/src/common/kernel/unit.c @@ -49,6 +49,7 @@ #include #include #include +#include #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 diff --git a/src/common/kernel/unit.h b/src/common/kernel/unit.h index 937cdf0f5..fce7ab79d 100644 --- a/src/common/kernel/unit.h +++ b/src/common/kernel/unit.h @@ -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 */ diff --git a/src/common/settings-eressea.h b/src/common/settings-eressea.h index 43996a0be..7dce07264 100644 --- a/src/common/settings-eressea.h +++ b/src/common/settings-eressea.h @@ -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 diff --git a/src/eressea/main.c b/src/eressea/main.c index 632a349f9..d2d9ea08a 100644 --- a/src/eressea/main.c +++ b/src/eressea/main.c @@ -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; diff --git a/src/eressea/server.cpp b/src/eressea/server.cpp index 1979bc0c0..f0493ea18 100644 --- a/src/eressea/server.cpp +++ b/src/eressea/server.cpp @@ -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; diff --git a/src/res/de/strings.xml b/src/res/de/strings.xml index 45437ee8d..cd388fc5b 100644 --- a/src/res/de/strings.xml +++ b/src/res/de/strings.xml @@ -2042,6 +2042,10 @@ ALLIANZ ALLIANCE + + BEFÖRDERUNG + PROMOTION + PFLANZEN @@ -5899,4 +5903,14 @@ unknown faction + + Held + hero + + + + Helden + heroes + + diff --git a/src/res/messages.xml b/src/res/messages.xml index 14098177d..463a80a85 100644 --- a/src/res/messages.xml +++ b/src/res/messages.xml @@ -6028,5 +6028,18 @@ "$unit($unit) in $region($region): '$order($command)' - $race($race,0) können keine Helden erwählen." "$unit($unit) in $region($region): '$order($command)' - $race($race,0) cannot be heroes." + + + + + + + + + + "$unit($unit) in $region($region): '$order($command)' - Die Einheit hat nur $int($have) von $int($cost) benötigtem Silber." + "$unit($unit) in $region($region): '$order($command)' - The unit has $int($have) of $int($cost) silver required." + +