diff --git a/src/common/gamecode/economy.c b/src/common/gamecode/economy.c
index e323da435..e60b19715 100644
--- a/src/common/gamecode/economy.c
+++ b/src/common/gamecode/economy.c
@@ -583,6 +583,8 @@ givemen(int n, unit * u, unit * u2, const char * cmd)
error = 73;
} else if (u2 && (has_skill(u, SK_MAGIC) || has_skill(u2, SK_MAGIC))) {
error = 158;
+ } else if (fval(u, UFL_WERE) != fval(u2, UFL_WERE)) {
+ error = 312;
} else {
if (n > u->number) n = u->number;
if (n == 0) {
@@ -3002,6 +3004,11 @@ entertain(region * r, unit * u)
int max_e;
request *o;
+ if (fval(u, UFL_WERE)) {
+ cmistake(u, findorder(u, u->thisorder), 58, MSG_INCOME);
+ return;
+ }
+
if (!effskill(u, SK_ENTERTAINMENT)) {
cmistake(u, findorder(u, u->thisorder), 58, MSG_INCOME);
return;
@@ -3094,6 +3101,10 @@ work(region * r, unit * u)
request *o;
int w;
+ if(fval(u, UFL_WERE)) {
+ cmistake(u, findorder(u, u->thisorder), 313, MSG_INCOME);
+ return;
+ }
if (besieged(u)) {
cmistake(u, findorder(u, u->thisorder), 60, MSG_INCOME);
return;
@@ -3146,6 +3157,11 @@ tax(region * r, unit * u, request ** taxorders)
cmistake(u, findorder(u, u->thisorder), 228, MSG_INCOME);
return;
}
+
+ if (fval(u, UFL_WERE)) {
+ cmistake(u, findorder(u, u->thisorder), 228, MSG_INCOME);
+ return;
+ }
if (besieged(u)) {
cmistake(u, findorder(u, u->thisorder), 60, MSG_INCOME);
diff --git a/src/common/gamecode/laws.c b/src/common/gamecode/laws.c
index 3b7265e2c..0a9a0f73d 100644
--- a/src/common/gamecode/laws.c
+++ b/src/common/gamecode/laws.c
@@ -2405,6 +2405,10 @@ instant_orders(void)
setstealth(u, S);
break;
+ case K_WEREWOLF:
+ setwere(u, S);
+ break;
+
case K_STATUS:
param = getstrtoken();
switch (findparam(param, u->faction->locale)) {
@@ -3126,6 +3130,7 @@ setdefaults (void)
case K_WORK:
case K_DRIVE:
case K_MOVE:
+ case K_WEREWOLF:
cmd = S->s;
#if HUNGER_DISABLES_LONGORDERS
if (fval(u, FL_HUNGER)) {
@@ -3161,6 +3166,7 @@ setdefaults (void)
case K_MOVE:
case K_BIETE:
case K_ATTACK:
+ case K_WEREWOLF:
break;
default:
diff --git a/src/common/gamecode/randenc.c b/src/common/gamecode/randenc.c
index 4711f8ed1..f5b389d70 100644
--- a/src/common/gamecode/randenc.c
+++ b/src/common/gamecode/randenc.c
@@ -1044,6 +1044,7 @@ godcurse(void)
void
randomevents(void)
{
+ faction *f;
region *r;
building *b, *b2;
unit *u;
@@ -1471,6 +1472,19 @@ randomevents(void)
}
}
}
+
+ for (f = factions; f; f=f->next) {
+ int level = fspecial(f, FS_LYCANTROPE);
+ if(level > 0) {
+ for(u = f->units; u; u=u->nextF) {
+ if(rand()%100 < 2*level) {
+ ADDMSG(&u->faction->msgs, msg_message("becomewere",
+ "unit region", u, u->region));
+ fset(u, UFL_WERE);
+ }
+ }
+ }
+ }
/* Frühling, die Bäume schlagen aus. */
diff --git a/src/common/gamecode/spy.c b/src/common/gamecode/spy.c
index adaeea1dd..1682f5259 100644
--- a/src/common/gamecode/spy.c
+++ b/src/common/gamecode/spy.c
@@ -108,6 +108,45 @@ spy(region * r, unit * u)
}
}
+void
+setwere(unit *u, strlist *S)
+{
+ int level = fspecial(u->faction,FS_LYCANTROPE);
+ char *s;
+
+ if(!level) {
+ cmistake(u, S->s, 311, MSG_EVENT);
+ return;
+ }
+
+ s = getstrtoken();
+
+ if(s == NULL || *s == '\0') {
+ if(fval(u, UFL_WERE)) {
+ cmistake(u, S->s, 309, MSG_EVENT);
+ } else if(rand()%100 < 35+(level-1)*20) { /* 35, 55, 75, 95% */
+ fset(u, UFL_WERE);
+ } else {
+ cmistake(u, S->s, 311, MSG_EVENT);
+ }
+ return;
+ }
+
+ if(findparam(s, u->faction->locale) == P_NOT) {
+ if(fval(u, UFL_WERE)) {
+ cmistake(u, S->s, 310, MSG_EVENT);
+ } else if(rand()%100 < 90-level*20) { /* 70, 50, 30, 10% */
+ freset(u, UFL_WERE);
+ } else {
+ cmistake(u, S->s, 311, MSG_EVENT);
+ }
+
+ return;
+ }
+
+ return;
+}
+
void
setstealth(unit * u, strlist * S)
{
@@ -125,7 +164,6 @@ setstealth(unit * u, strlist * S)
return;
}
-
trace = findrace(s, u->faction->locale);
if (trace) {
/* Dämonen können sich nur als andere Spielerrassen tarnen */
diff --git a/src/common/gamecode/study.c b/src/common/gamecode/study.c
index 1c5afd284..4ff572be0 100644
--- a/src/common/gamecode/study.c
+++ b/src/common/gamecode/study.c
@@ -246,7 +246,7 @@ teach(region * r, unit * u)
char *s;
skill_t sk;
- if ((u->race->flags & RCF_NOTEACH)) {
+ if ((u->race->flags & RCF_NOTEACH) || fval(u, UFL_WERE)) {
cmistake(u, u->thisorder, 274, MSG_EVENT);
return;
}
@@ -471,7 +471,7 @@ learn(void)
cmistake(u, findorder(u, u->thisorder), 52, MSG_PRODUCE);
continue;
}
- if ((u->race->flags & RCF_NOLEARN)) {
+ if ((u->race->flags & RCF_NOLEARN) || fval(u, UFL_WERE)) {
sprintf(buf, "%s können nichts lernen", LOC(default_locale, rc_name(u->race, 1)));
mistake(u, u->thisorder, buf, MSG_EVENT);
continue;
diff --git a/src/common/kernel/battle.c b/src/common/kernel/battle.c
index ebef64f22..fdd625d82 100644
--- a/src/common/kernel/battle.c
+++ b/src/common/kernel/battle.c
@@ -773,9 +773,13 @@ select_armor(troop t)
int geschuetzt = 0;
/* Drachen benutzen keine Rüstungen */
-
if (!(t.fighter->unit->race->battle_flags & BF_EQUIPMENT))
return AR_NONE;
+
+ /* ... und Werwölfe auch nicht */
+ if(fval(t.fighter->unit, UFL_WERE)) {
+ return AR_NONE;
+ }
do {
if (armordata[a].shield == 0) {
@@ -1026,6 +1030,11 @@ terminate(troop dt, troop at, int type, const char *damage, boolean missile)
ar += armordata[shield].prot;
/* natürliche Rüstung */
an = du->race->armor;
+ if(fval(du, UFL_WERE)) {
+ int level = fspecial(du->faction, FS_LYCANTROPE);
+ an += level;
+ da += level;
+ }
/* magische Rüstung durch Artefakte oder Sprüche */
/* Momentan nur Trollgürtel */
am = select_magicarmor(dt);
@@ -1583,6 +1592,11 @@ skilldiff(troop at, troop dt, int dist)
skdiff += 5;
}
+ /* Werwolf */
+ if(fval(au, UFL_WERE)) {
+ skdiff += fspecial(au->faction, FS_LYCANTROPE);
+ }
+
if (old_race(au->race) == RC_GOBLIN &&
af->side->size[SUM_ROW] >= df->side->size[SUM_ROW] * 10)
skdiff += 1;
@@ -2862,12 +2876,12 @@ make_fighter(battle * b, unit * u, boolean attack)
if (fig->horses) {
if ((r->terrain != T_PLAIN && r->terrain != T_HIGHLAND
&& r->terrain != T_DESERT) || r_isforest(r)
- || eff_skill(u, SK_RIDING, r) < 2 || old_race(u->race) == RC_TROLL)
+ || eff_skill(u, SK_RIDING, r) < 2 || old_race(u->race) == RC_TROLL || fval(u, UFL_WERE))
fig->horses = 0;
}
if (fig->elvenhorses) {
- if (eff_skill(u, SK_RIDING, r) < 5 || old_race(u->race) == RC_TROLL)
+ if (eff_skill(u, SK_RIDING, r) < 5 || old_race(u->race) == RC_TROLL || fval(u, UFL_WERE))
fig->elvenhorses = 0;
}
diff --git a/src/common/kernel/eressea.c b/src/common/kernel/eressea.c
index 983b54e1c..3e35f4ebb 100644
--- a/src/common/kernel/eressea.c
+++ b/src/common/kernel/eressea.c
@@ -231,9 +231,8 @@ const char *keywords[MAXKEYWORDS] =
#endif
"PRÄFIX",
"SYNONYM",
-#if GROWING_TREES
"PFLANZEN",
-#endif
+ "WERWESEN"
};
const char *report_options[MAX_MSG] =
diff --git a/src/common/kernel/eressea.h b/src/common/kernel/eressea.h
index 7c80c5c8e..37489b19e 100644
--- a/src/common/kernel/eressea.h
+++ b/src/common/kernel/eressea.h
@@ -438,6 +438,7 @@ enum {
K_PREFIX,
K_SYNONYM,
K_PFLANZE,
+ K_WEREWOLF,
MAXKEYWORDS,
NOKEYWORD = (keyword_t) - 1
};
@@ -891,6 +892,8 @@ extern int max_unique_id;
#define FFL_RESTART (1<<2)
#define FFL_OVERRIDE (1<<27) /* Override-Passwort wurde benutzt */
+#define UFL_WERE (1<<28)
+
/* Flags, die gespeichert werden sollen: */
#define UFL_SAVEMASK (FL_NOAID | FL_OWNER | FL_PARTEITARNUNG | FL_LOCKED | FL_HUNGER | FL_NOIDLEOUT | FL_TAKEALL | FL_UNNAMED)
diff --git a/src/common/kernel/karma.c b/src/common/kernel/karma.c
index 469b66ee6..7b8e3cbe3 100644
--- a/src/common/kernel/karma.c
+++ b/src/common/kernel/karma.c
@@ -274,20 +274,21 @@ struct fspecialdata fspecials[MAXFACTIONSPECIALS] = {
"Auswirkungen.",
100
},
- /* TODO: Noch nicht implementiert */
{
"Lykanthrop",
"Angehörige einer Partei mit dieser Eigenschaft sind Werwesen. Einheiten "
- "einer solchen Partei können sich mit Hilfe der Befehle 'WERWESEN' und "
+ "einer solchen Partei können sich mit Hilfe der langen Befehle 'WERWESEN' und "
"'WERWESEN NICHT' in eine andere Form verwandeln. Beide Befehle haben "
- "nur eine gewisse Erfolgswahrscheinlichkeit und funktionieren nicht immer. "
- "In Werform erhalten die Einheiten +2 auf Angriff und Schaden und "
- "eine natürliche Rüstung von 2. Sie können sich so schnell "
- "bewegen, als wäre sie beritten, benutzen aber keine Pferde im "
- "Kampf, und verwenden als Rüstungen nur Schilde. Sie sind "
- "eingeschränkt und können in Werform kein Geld verdienen "
- "und nicht Lernen oder Lehren.",
- 1
+ "nur eine gewisse Erfolgswahrscheinlichkeit und funktionieren nicht immer: "
+ "Je höher die Stufe der Eigenschaft, desto größer die Wahrscheinlichkeit, "
+ "dass die Verwandlung gelingt, und je geringer die Chance, sich "
+ "zurückzuverwandeln. Zudem besteht eine zunehmende kleine Chance der "
+ "spontanen Verwandlung. In Werform erhalten die Einheiten einen Bonus auf "
+ "Angriff, Schaden und natürliche Rüstung in Höhe der Eigenschaft. Sie "
+ "benutzen jedoch keine Pferde im Kampf, und verwenden als Rüstungen nur "
+ "Schilde. Sie sind eingeschränkt und können in Werform kein Geld verdienen, "
+ "nicht Zaubern und nicht Lernen oder Lehren.",
+ 4
},
/* TODO: Noch nicht implementiert */
/* Einheitenlimit-Senkung sinnlos für alte Parteien. */
@@ -295,7 +296,9 @@ struct fspecialdata fspecials[MAXFACTIONSPECIALS] = {
"Elite",
"Für eine Partei mit dieser Eigenschaft verdoppeln sich alle Boni- und "
"Mali ihrer Rasse. Ihre Unterhaltskosten erhöhen sich auf 12 Silber pro "
- "Runde, ihr Einheitenlimit reduziert sich auf 25%%.",
+ "Runde, ihr Einheitenlimit reduziert sich auf 25%%. Diese Eigenschaft "
+ "kann nicht erworben werden, wenn die Partei nach dem Erwerb zuviele "
+ "Einheiten hätte.",
1
}
};
diff --git a/src/common/kernel/karma.h b/src/common/kernel/karma.h
index 836f84326..e41b7c31a 100644
--- a/src/common/kernel/karma.h
+++ b/src/common/kernel/karma.h
@@ -36,7 +36,7 @@ typedef enum {
FS_UNDEAD,
FS_QUICK,
FS_LUCKY,
- FS_LYCANTROP,
+ FS_LYCANTROPE,
FS_ELITE,
MAXFACTIONSPECIALS
} fspecial_t;
diff --git a/src/common/kernel/magic.c b/src/common/kernel/magic.c
index ff8214f40..d57c896a8 100644
--- a/src/common/kernel/magic.c
+++ b/src/common/kernel/magic.c
@@ -2888,6 +2888,10 @@ magic(void)
!is_cursed(u->attribs, C_KAELTESCHUTZ,0))
continue;
+ if(fval(u, UFL_WERE)) {
+ continue;
+ }
+
if (attacked(u)) {
continue;
}
diff --git a/src/common/kernel/spy.h b/src/common/kernel/spy.h
index 9b17e28a6..e6ce4d87c 100644
--- a/src/common/kernel/spy.h
+++ b/src/common/kernel/spy.h
@@ -26,6 +26,7 @@ struct unit;
struct region;
struct strlist;
+void setwere(struct unit * u, struct strlist * S);
void setstealth(struct unit * u, struct strlist * S);
void spy(struct region * r, struct unit * u);
void sabotage(struct region * r, struct unit * u);
diff --git a/src/res/de/messages.xml b/src/res/de/messages.xml
index e992c1a47..881182329 100644
--- a/src/res/de/messages.xml
+++ b/src/res/de/messages.xml
@@ -4340,6 +4340,96 @@
+
+
+
+
+
+
+
+
+
+ "$unit($unit) in $region($region): '$command' - Diese Einheit ist schon ein Werwesen."
+
+
+
+
+ "$unit($unit) in $region($region): '$command' - This unit already assumed lycantropic form."
+
+
+
+
+
+
+
+
+
+
+
+
+ "$unit($unit) in $region($region): '$command' - Diese Einheit ist kein Werwesen."
+
+
+
+
+ "$unit($unit) in $region($region): '$command' - This unit is not in lycantropic form."
+
+
+
+
+
+
+
+
+
+
+
+
+ "$unit($unit) in $region($region): '$command' - Die Einheit kann sich nicht verwandeln."
+
+
+
+
+ "$unit($unit) in $region($region): '$command' - This unit can not change shape."
+
+
+
+
+
+
+
+
+
+
+
+
+ "$unit($unit) in $region($region): '$command' - Werwesen können nicht mit anderen Personen gemischt werden."
+
+
+
+
+ "$unit($unit) in $region($region): '$command' - Lycantropes may not be mixed with normal people."
+
+
+
+
+
+
+
+
+
+
+
+
+ "$unit($unit) in $region($region): '$command' - Werwesen können nicht arbeiten."
+
+
+
+
+ "$unit($unit) in $region($region): '$command' - Lycantropes don't work."
+
+
+
@@ -7366,5 +7456,15 @@
"SIEG! $if($eq($n,1), "Die Partei $winners hat", "Die Parteien $winners haben") die Siegbedingung für die erforderliche Zeit erfüllt. Das Spiel ist damit beendet."
"VICTORY! $if($eq($n,1), "The faction $winners has", "The factions $winners have") fulfilled the victory condition for the necessary time. The game is over."
+
+
+
+
+
+
+ "$unit($unit) in $region($region) verwandelt sich in ein Werwesen."
+ "$unit($unit) in $region($region) becomes a lycantrope."
+
+
diff --git a/src/res/de/strings.xml b/src/res/de/strings.xml
index c0a3e5f55..bc48ef316 100644
--- a/src/res/de/strings.xml
+++ b/src/res/de/strings.xml
@@ -1780,7 +1780,9 @@
GM
-
+
+ WERWESEN
+
Adler
diff --git a/src/res/en/strings.xml b/src/res/en/strings.xml
index f206fa301..5a7d70965 100644
--- a/src/res/en/strings.xml
+++ b/src/res/en/strings.xml
@@ -1593,6 +1593,9 @@
GROW
+
+ LYCANTROPE
+
eagle