- curseids entfernt, bis auf ein paar wenige alte funktionen (wahnsinnsarbeit, das)

- englische Zauberübersetzungen, Code gebaut und Übersetzung angefangen
- Visual Studio Project, neue Files eingefügt
- strnzcpy für MSVC hat nicht so richtig geklappt. alles gleich gemacht.
This commit is contained in:
Enno Rehling 2002-05-01 19:08:32 +00:00
parent fc39ac45e7
commit 25685c79af
34 changed files with 920 additions and 828 deletions

View file

@ -660,13 +660,23 @@ cr_output_unit(FILE * F, const region * r,
fprintf(F, "SPRUECHE\n");
for (;spt; spt = spt->next) {
sp = find_spellbyid(spt->spellid);
fprintf(F, "\"%s\"\n", sp->name);
if (sp) {
const char * name = sp->sname;
if (sp->info==NULL) {
name = add_translation(mkname("spell", name), spell_name(sp, f->locale));
}
fprintf(F, "\"%s\"\n", name);
}
}
for (i=0;i!=MAXCOMBATSPELLS;++i) {
sp = find_spellbyid(mage->combatspell[i]);
if (sp) {
const char * name = sp->sname;
if (sp->info==NULL) {
name = add_translation(mkname("spell", name), spell_name(sp, f->locale));
}
fprintf(F, "KAMPFZAUBER %d\n", i);
fprintf(F, "\"%s\";name\n", sp->name);
fprintf(F, "\"%s\";name\n", name);
fprintf(F, "%d;level\n", mage->combatspelllevel[i]);
}
}
@ -776,12 +786,16 @@ cr_reportspell(FILE * F, spellid_t id, const struct locale * lang)
{
int k, itemanz, res, costtyp;
spell *sp = find_spellbyid(id);
const char * name = sp->sname;
if (sp->info==NULL) {
name = add_translation(mkname("spell", name), spell_name(sp, lang));
}
fprintf(F, "ZAUBER %d\n", hashstring(sp->name));
fprintf(F, "\"%s\";name\n", sp->name);
fprintf(F, "ZAUBER %d\n", hashstring(spell_name(sp, default_locale)));
fprintf(F, "\"%s\";name\n", name);
fprintf(F, "%d;level\n", sp->level);
fprintf(F, "%d;rank\n", sp->rank);
fprintf(F, "\"%s\";info\n", sp->beschreibung);
fprintf(F, "\"%s\";info\n", spell_info(sp, lang));
if (sp->sptyp & PRECOMBATSPELL) fputs("\"precombat\";class\n", F);
else if (sp->sptyp & COMBATSPELL) fputs("\"combat\";class\n", F);

View file

@ -689,9 +689,9 @@ horses(region * r)
horses = rhorses(r);
if(is_cursed(r->attribs, C_CURSED_BY_THE_GODS, 0)) {
rsethorses(r, (int)(horses*0.9));
} else if (maxhorses > 0) {
} else if (maxhorses > 0) {
int i;
int growth = (RESOURCE_QUANTITY * HORSEGROWTH * 200 * (maxhorses-horses))/maxhorses;
int growth = (int)((RESOURCE_QUANTITY * HORSEGROWTH * 200 * (maxhorses-horses))/maxhorses);
if(a_find(r->attribs, &at_horseluck)) growth *= 2;
/* printf("Horses: <%d> %d -> ", growth, horses); */
@ -2489,7 +2489,7 @@ instant_orders(void)
}
else level = 0;
spell = find_spellbyname(u, s);
spell = find_spellbyname(u, s, u->faction->locale);
if(!spell){
cmistake(u, S->s, 173, MSG_MAGIC);
@ -2554,7 +2554,7 @@ instant_orders(void)
break;
}
spell = find_spellbyname(u, s);
spell = find_spellbyname(u, s, u->faction->locale);
rc = findrace(s, u->faction->locale);
itype = finditemtype(s, u->faction->locale);
if (spell == NULL && itype == NULL && rc==NULL) {
@ -3003,7 +3003,7 @@ ageing(void)
}
if (is_cursed(u->attribs, C_OLDRACE, 0)){
curse *c = get_curse(u->attribs, C_OLDRACE, 0);
curse *c = get_curse(u->attribs, ct_find("oldrace"));
if (c->duration == 1 && !(c->flag & CURSE_NOAGE)) {
u->race = new_race[c->effect];
u->irace = new_race[c->effect];

View file

@ -1063,12 +1063,12 @@ randomevents(void)
for (r = regions; r; r = r->next) {
for (u = r->units; u; u = u->next) {
curse *c = get_curse(u->attribs, C_ORC, 0);
curse *c = get_curse(u->attribs, ct_find("orcish"));
if (c && !has_skill(u, SK_MAGIC) && !has_skill(u, SK_ALCHEMY)) {
int n;
int increase = 0;
int num = get_cursedmen(u, c);
int prob = get_curseeffect(u->attribs, C_ORC, 0);
int prob = curse_geteffect(c);
for (n = (num - get_item(u, I_CHASTITY_BELT)); n > 0; n--) {
if (rand() % 100 < prob) {

View file

@ -455,11 +455,11 @@ report_spell(FILE * F, spellid_t id, const struct locale * lang)
spell *sp = find_spellbyid(id);
rnl(F);
centre(F, sp->name, true);
centre(F, spell_name(sp, lang), true);
rnl(F);
strcpy(buf,"Beschreibung:");
rps(F, buf);
rparagraph(F, sp->beschreibung, 0, 0);
rparagraph(F, spell_info(sp, lang), 0, 0);
rnl(F);
@ -544,7 +544,7 @@ report_spell(FILE * F, spellid_t id, const struct locale * lang)
scat("[STUFE n] ");
}
scat("\"");
scat(sp->name);
scat(spell_name(sp, lang));
scat("\" ");
if (sp->sptyp & ONETARGET){
if (sp->sptyp & UNITSPELL) {

View file

@ -90,6 +90,10 @@ SOURCE=.\birthday_firework.h
# End Source File
# Begin Source File
SOURCE=.\catapultammo.h
# End Source File
# Begin Source File
SOURCE=.\demonseye.h
# End Source File
# Begin Source File
@ -102,6 +106,10 @@ SOURCE=.\lmsreward.h
# End Source File
# Begin Source File
SOURCE=.\questkeys.h
# End Source File
# Begin Source File
SOURCE=.\seed.h
# End Source File
# Begin Source File
@ -119,6 +127,10 @@ SOURCE=.\birthday_firework.c
# End Source File
# Begin Source File
SOURCE=.\catapultammo.c
# End Source File
# Begin Source File
SOURCE=.\demonseye.c
# End Source File
# Begin Source File
@ -131,6 +143,10 @@ SOURCE=.\lmsreward.c
# End Source File
# Begin Source File
SOURCE=.\questkeys.c
# End Source File
# Begin Source File
SOURCE=.\seed.c
# End Source File
# Begin Source File

View file

@ -39,7 +39,7 @@ info_lmsstory(const void* vp, int i, curse * c, int i2)
}
static curse_type ct_lmsstory = {
0, 0, 0, NULL, NULL, &info_lmsstory
"lmsstory", 0, 0, 0, "xxx", &info_lmsstory
};

View file

@ -54,7 +54,7 @@ use_questkey(struct unit * u, const struct item_type * itype, int amount, const
key1 = region_hashkey(r1);
key2 = region_hashkey(r2);
key = min(key2, key) % BMAXHASH;
key = min(key2, key1) % BMAXHASH;
bo = borders[key];
@ -68,10 +68,10 @@ use_questkey(struct unit * u, const struct item_type * itype, int amount, const
assert(bo != NULL);
lock = (int)bo->data;
if(itype == &it_questkey1) k = 1;
if(itype == &it_questkey2) k = 2;
if (itype == &it_questkey1) k = 1;
else k = 2;
if(lock & k) {
if (lock & k) {
m = msg_message("questportal_unlock","region unit key", u->region, u, k);
lock = lock & ~k;
} else {

View file

@ -1425,6 +1425,7 @@ do_combatmagic(battle *b, combatmagic_t was)
level = eff_skill(mage, SK_MAGIC, r);
if (level > 0) {
const struct locale * lang = mage->faction->locale;
char cmd[128];
switch(was) {
@ -1443,7 +1444,8 @@ do_combatmagic(battle *b, combatmagic_t was)
if (sp == NULL)
continue;
snprintf(cmd, 128, "ZAUBER %s", sp->name);
snprintf(cmd, 128, "%s \"%s\"",
LOC(lang, keywords[K_CAST]), spell_name(sp, lang));
if (cancast(mage, sp, 1, 1, cmd) == false)
continue;
@ -1452,7 +1454,7 @@ do_combatmagic(battle *b, combatmagic_t was)
if (sl > 0) level = min(sl, level);
if (level < 0) {
sprintf(buf, "%s versucht %s zu zaubern, doch der Zauber schlägt "
"fehl!", unitname(mage), sp->name);
"fehl!", unitname(mage), spell_name(sp, lang));
battlerecord(b, buf);
continue;
}
@ -1460,14 +1462,14 @@ do_combatmagic(battle *b, combatmagic_t was)
power = spellpower(r, mage, sp, level);
if (power <= 0) { /* Effekt von Antimagie */
sprintf(buf, "%s versucht %s zu zaubern, doch der Zauber schlägt "
"fehl!", unitname(mage), sp->name);
"fehl!", unitname(mage), spell_name(sp, lang));
battlerecord(b, buf);
continue;
}
if (fumble(r, mage, sp, sp->level) == true) {
sprintf(buf, "%s versucht %s zu zaubern, doch der Zauber schlägt "
"fehl!", unitname(mage), sp->name);
"fehl!", unitname(mage), spell_name(sp, lang));
battlerecord(b, buf);
pay_spell(mage, sp, level, 1);
continue;
@ -1512,6 +1514,7 @@ do_combatspell(troop at, int row)
void **mg;
int sl;
char cmd[128];
const struct locale * lang = mage->faction->locale;
if (row>BEHIND_ROW) return;
@ -1520,7 +1523,7 @@ do_combatspell(troop at, int row)
fi->magic = 0; /* Hat keinen Kampfzauber, kämpft nichtmagisch weiter */
return;
}
snprintf(cmd, 128, "ZAUBER %s", sp->name);
snprintf(cmd, 128, "ZAUBER %s", spell_name(sp, lang));
if (cancast(mage, sp, 1, 1, cmd) == false) {
fi->magic = 0; /* Kann nicht mehr Zaubern, kämpft nichtmagisch weiter */
return;
@ -1531,7 +1534,7 @@ do_combatspell(troop at, int row)
if (fumble(r, mage, sp, sp->level) == true) {
sprintf(buf, "%s versucht %s zu zaubern, doch der Zauber schlägt "
"fehl!", unitname(mage), sp->name);
"fehl!", unitname(mage), spell_name(sp, lang));
battlerecord(b, buf);
pay_spell(mage, sp, level, 1);
return;
@ -1550,14 +1553,14 @@ do_combatspell(troop at, int row)
/* Antimagie die Fehlschlag erhöht */
if (rand()%100 < fumblechance) {
sprintf(buf, "%s versucht %s zu zaubern, doch der Zauber schlägt "
"fehl!", unitname(mage), sp->name);
"fehl!", unitname(mage), spell_name(sp, lang));
battlerecord(b, buf);
return;
}
power = spellpower(r, mage, sp, level);
if (power <= 0) { /* Effekt von Antimagie */
sprintf(buf, "%s versucht %s zu zaubern, doch der Zauber schlägt "
"fehl!", unitname(mage), sp->name);
"fehl!", unitname(mage), spell_name(sp, lang));
battlerecord(b, buf);
pay_spell(mage, sp, level, 1);
return;
@ -1633,6 +1636,13 @@ skilldiff(troop at, troop dt, int dist)
#endif
if (df->building) {
boolean init = false;
static const curse_type * strongwall_ct, * magicstone_ct;
if (!init) {
strongwall_ct = ct_find("strongwall");
magicstone_ct = ct_find("magicstone");
init=true;
}
if (df->building->type->flags & BTF_PROTECTION) {
if(fspecial(au->faction, FS_SAPPER)) {
/* Halbe Schutzwirkung, aufgerundet */
@ -1643,12 +1653,15 @@ skilldiff(troop at, troop dt, int dist)
}
is_protected = 2;
}
if (is_cursed(df->building->attribs, C_STRONGWALL, 0)) {
/* wirkt auf alle Gebäude */
skdiff -= get_curseeffect(df->building->attribs, C_STRONGWALL, 0);
is_protected = 2;
if (strongwall_ct) {
curse * c = get_curse(df->building->attribs, strongwall_ct);
if (curse_active(c)) {
/* wirkt auf alle Gebäude */
skdiff -= curse_geteffect(c);
is_protected = 2;
}
}
if (is_cursed(df->building->attribs, C_MAGICSTONE, 0)) {
if (magicstone_ct && curse_active(get_curse(df->building->attribs, magicstone_ct))) {
/* Verdoppelt Burgenbonus */
skdiff -= buildingeffsize(df->building, false);
}
@ -2745,11 +2758,16 @@ make_fighter(battle * b, unit * u, boolean attack)
rest = u->hp % u->number;
/* Effekte von Sprüchen */
{
curse *c = get_curse(u->attribs, C_SPEED, 0);
if (c) {
speeded = get_cursedmen(u, c);
speed = get_curseeffect(u->attribs, C_SPEED, 0);
static const curse_type * speed_ct;
speed_ct = ct_find("speed");
if (speed_ct) {
curse *c = get_curse(u->attribs, speed_ct);
if (c) {
speeded = get_cursedmen(u, c);
speed = curse_geteffect(c);
}
}
}
@ -3354,6 +3372,14 @@ do_battle(void)
strlist *sl;
list_foreach(strlist, u->orders, sl) {
boolean init=false;
static const curse_type * peace_ct, * slave_ct, * calm_ct;
if (!init) {
init = true;
peace_ct = ct_find("peacezone");
slave_ct = ct_find("slavery");
calm_ct = ct_find("calmmonster");
}
if (igetkeyword(sl->s, u->faction->locale) == K_ATTACK) {
unit *u2;
fighter *c1, *c2;
@ -3385,14 +3411,14 @@ do_battle(void)
/* ist ein Flüchtling aus einem andern Kampf */
if (fval(u, FL_MOVED)) list_continue(sl);
if (is_spell_active(r, C_PEACE)) {
if (peace_ct && curse_active(get_curse(r->attribs, peace_ct))) {
sprintf(buf, "Hier ist es so schön friedlich, %s möchte "
"hier niemanden angreifen.", unitname(u));
mistake(u, sl->s, buf, MSG_BATTLE);
list_continue(sl);
}
if (is_cursed(u->attribs, C_SLAVE, 0)) {
if (slave_ct && curse_active(get_curse(u->attribs, slave_ct))) {
sprintf(buf, "%s kämpft nicht.", unitname(u));
mistake(u, sl->s, buf, MSG_BATTLE);
list_continue(sl);
@ -3467,13 +3493,13 @@ do_battle(void)
sprintf(buf, "%s ist böse gewesen...", unitname(u));
mistake(u, sl->s, buf, MSG_BATTLE);
list_continue(sl);
}if (u2->faction->age < IMMUN_GEGEN_ANGRIFF) {
} if (u2->faction->age < IMMUN_GEGEN_ANGRIFF) {
add_message(&u->faction->msgs,
msg_error(u, findorder(u, u->thisorder), "newbie_immunity_error", "turns", IMMUN_GEGEN_ANGRIFF));
list_continue(sl);
}
/* Fehler: "Die Einheit ist mit uns alliert" */
if (is_cursed(u->attribs, C_CALM, u2->faction->unique_id)) {
if (calm_ct && curse_active(get_cursex(u->attribs, calm_ct, (void*)u2->faction->unique_id, cmp_curseeffect))) {
cmistake(u, sl->s, 47, MSG_BATTLE);
list_continue(sl);
}

View file

@ -182,7 +182,9 @@ siege(region * r, unit * u)
building *b;
int d;
int bewaffnete, katapultiere = 0;
static boolean init = false;
static const curse_type * magicstone_ct;
if (!init) { init = true; magicstone_ct = ct_find("magicstone"); }
/* gibt es ueberhaupt Burgen? */
b = getbuilding(r);
@ -232,7 +234,7 @@ siege(region * r, unit * u)
d = min(d, b->size - 1);
/* meldung, schaden anrichten */
if (d && !(is_cursed(b->attribs, C_MAGICSTONE, 0))) {
if (d && !curse_active(get_curse(b->attribs, magicstone_ct))) {
b->size -= d;
new_use_pooled(u, &rt_catapultammo, GET_SLACK|GET_RESERVE|GET_POOLED_SLACK, d);
d = 100 * d / b->size;

View file

@ -121,7 +121,10 @@ buildingmaintenance(const building * b, resource_t rtype)
{
const building_type * bt = b->type;
int c, cost=0;
if (is_cursed(b->attribs, C_NOCOST, 0)) {
static boolean init = false;
static const curse_type * nocost_ct;
if (!init) { init = true; nocost_ct = ct_find("nocost"); }
if (curse_active(get_curse(b->attribs, nocost_ct))) {
return 0;
}
for (c=0;bt->maintenance && bt->maintenance[c].number;++c) {

View file

@ -113,7 +113,8 @@ sp_kampfzauber(fighter * fi, int level, int power, spell * sp)
if (power <= 0) return 0;
sprintf(buf, "%s zaubert %s", unitname(fi->unit), sp->name);
sprintf(buf, "%s zaubert %s", unitname(fi->unit),
spell_name(sp, default_locale));
switch(sp->id) {
/* lovar halbiert im Schnitt! */
@ -171,7 +172,8 @@ sp_versteinern(fighter * fi, int level, int power, spell * sp)
int force, enemies;
int stoned = 0;
sprintf(buf, "%s zaubert %s", unitname(fi->unit), sp->name);
sprintf(buf, "%s zaubert %s", unitname(fi->unit),
spell_name(sp, default_locale));
force = lovar(get_force(power,0));
@ -224,7 +226,8 @@ sp_stun(fighter * fi, int level, int power, spell * sp)
if (power <= 0) return 0;
sprintf(buf, "%s zaubert %s", unitname(fi->unit), sp->name);
sprintf(buf, "%s zaubert %s", unitname(fi->unit),
spell_name(sp, default_locale));
switch(sp->id) {
case SPL_SHOCKWAVE:
@ -374,7 +377,8 @@ sp_sleep(fighter * fi, int level, int power, spell * sp)
int minrow = FIGHT_ROW;
int maxrow = BEHIND_ROW;
sprintf(buf, "%s zaubert %s", unitname(mage), sp->name);
sprintf(buf, "%s zaubert %s", unitname(mage),
spell_name(sp, default_locale));
force = lovar(power * 25);
enemies = count_enemies(b, fi->side, FS_ENEMY, minrow, maxrow);
@ -448,7 +452,8 @@ sp_speed(fighter * fi, int level, int power, spell * sp)
int allies;
int targets = 0;
sprintf(buf, "%s zaubert %s", unitname(fi->unit), sp->name);
sprintf(buf, "%s zaubert %s", unitname(fi->unit),
spell_name(sp, default_locale));
scat(":");
battlerecord(b, buf);
@ -519,7 +524,8 @@ sp_mindblast(fighter * fi, int level, int power, spell * sp)
int minrow = FIGHT_ROW;
int maxrow = BEHIND_ROW;
sprintf(buf, "%s zaubert %s", unitname(mage), sp->name);
sprintf(buf, "%s zaubert %s", unitname(mage),
spell_name(sp, default_locale));
force = lovar(power * 25);
enemies = count_enemies(b, fi->side, FS_ENEMY, minrow, maxrow);
@ -600,7 +606,8 @@ sp_dragonodem(fighter * fi, int level, int power, spell * sp)
int killed = 0;
const char *damage;
sprintf(buf, "%s zaubert %s", unitname(fi->unit), sp->name);
sprintf(buf, "%s zaubert %s", unitname(fi->unit),
spell_name(sp, default_locale));
/* 11-26 HP */
damage = spell_damage(4);
/* Jungdrache 3->54, Drache 6->216, Wyrm 12->864 Treffer */
@ -649,7 +656,8 @@ sp_drainodem(fighter * fi, int level, int power, spell * sp)
int killed = 0;
const char *damage;
sprintf(buf, "%s zaubert %s", unitname(fi->unit), sp->name);
sprintf(buf, "%s zaubert %s", unitname(fi->unit),
spell_name(sp, default_locale));
/* 11-26 HP */
damage = spell_damage(4);
/* Jungdrache 3->54, Drache 6->216, Wyrm 12->864 Treffer */
@ -817,6 +825,10 @@ sp_strong_wall(fighter * fi, int level, int force, spell * sp)
unit *mage = fi->unit;
building *burg;
int effect;
static boolean init = false;
static const curse_type * strongwall_ct;
if (!init) { init = true; strongwall_ct = ct_find("strongwall"); }
unused(sp);
if (!mage->building) {
@ -831,7 +843,7 @@ sp_strong_wall(fighter * fi, int level, int force, spell * sp)
if (rand()%4 < force%4)
effect++;
create_curse(mage, &burg->attribs, C_STRONGWALL, 0, force, 1, effect, 0);
create_curse(mage, &burg->attribs, strongwall_ct, force, 1, effect, 0);
sprintf(buf, "%s Mauern erglühen in einem unheimlichen magischen Licht.",
buildingname(burg));
@ -949,7 +961,8 @@ sp_flee(fighter * fi, int level, int power, spell * sp)
switch(sp->id) {
case SPL_FLEE:
sprintf(buf, "%s zaubert %s", unitname(mage), sp->name);
sprintf(buf, "%s zaubert %s", unitname(mage),
spell_name(sp, default_locale));
force = get_force(power,4);
break;
case SPL_SONG_OF_FEAR:
@ -1019,7 +1032,8 @@ sp_hero(fighter * fi, int level, int power, spell * sp)
int allies;
int targets = 0;
sprintf(buf, "%s zaubert %s", unitname(mage), sp->name);
sprintf(buf, "%s zaubert %s", unitname(mage),
spell_name(sp, default_locale));
switch(sp->id) {
case SPL_HERO:
df_bonus = power/5;
@ -1075,7 +1089,8 @@ sp_berserk(fighter * fi, int level, int power, spell * sp)
int allies = 0;
int targets = 0;
sprintf(buf, "%s zaubert %s", unitname(mage), sp->name);
sprintf(buf, "%s zaubert %s", unitname(mage),
spell_name(sp, default_locale));
switch(sp->id) {
case SPL_BERSERK:
case SPL_BLOODTHIRST:
@ -1139,7 +1154,8 @@ sp_frighten(fighter * fi, int level, int power, spell * sp)
df_malus = 2;
force = get_force(power, 2);
sprintf(buf, "%s zaubert %s", unitname(mage), sp->name);
sprintf(buf, "%s zaubert %s", unitname(mage),
spell_name(sp, default_locale));
enemies = count_enemies(b, fi->side, FS_ENEMY,
minrow, maxrow);
if (!enemies) {
@ -1189,7 +1205,8 @@ sp_tiredsoldiers(fighter * fi, int level, int force, spell * sp)
force = force * force * 4;
sprintf(buf, "%s zaubert %s", unitname(mage), sp->name);
sprintf(buf, "%s zaubert %s", unitname(mage),
spell_name(sp, default_locale));
if (!count_enemies(b, fi->side, FS_ENEMY, FIGHT_ROW,
BEHIND_ROW)) {
scat(", aber niemand war in Reichweite.");
@ -1239,7 +1256,8 @@ sp_windshield(fighter * fi, int level, int power, spell * sp)
int minrow = BEHIND_ROW;
int maxrow = BEHIND_ROW;
sprintf(buf, "%s zaubert %s", unitname(mage), sp->name);
sprintf(buf, "%s zaubert %s", unitname(mage),
spell_name(sp, default_locale));
switch(sp->id) {
case SPL_WINDSHIELD:
force = get_force(power,4);
@ -1287,7 +1305,8 @@ sp_reeling_arrows(fighter * fi, int level, int force, spell * sp)
unused(force);
b->reelarrow = true;
sprintf(buf, "%s zaubert %s", unitname(mage), sp->name);
sprintf(buf, "%s zaubert %s", unitname(mage),
spell_name(sp, default_locale));
scat(": ");
scat("Ein Sturm kommt auf und die Schützen können kaum noch zielen.");
battlerecord(b, buf);
@ -1305,7 +1324,8 @@ sp_denyattack(fighter * fi, int level, int power, spell * sp)
region *r = b->region;
unused(power);
sprintf(buf, "%s zaubert %s", unitname(mage), sp->name);
sprintf(buf, "%s zaubert %s", unitname(mage),
spell_name(sp, default_locale));
scat(": ");
/* Fliehende Einheiten verlassen auf jeden Fall Gebäude und Schiffe. */
@ -1364,7 +1384,8 @@ sp_armorshield(fighter * fi, int level, int power, spell * sp)
unit *mage = fi->unit;
battle *b = fi->side->battle;
sprintf(buf, "%s zaubert %s", unitname(mage), sp->name);
sprintf(buf, "%s zaubert %s", unitname(mage),
spell_name(sp, default_locale));
battlerecord(b, buf);
/* gibt Rüstung +effect für duration Treffer */
@ -1391,7 +1412,8 @@ sp_reduceshield(fighter * fi, int level, int power, spell * sp)
unit *mage = fi->unit;
battle *b = fi->side->battle;
sprintf(buf, "%s zaubert %s", unitname(mage), sp->name);
sprintf(buf, "%s zaubert %s", unitname(mage),
spell_name(sp, default_locale));
battlerecord(b, buf);
/* jeder Schaden wird um effect% reduziert bis der Schild duration
@ -1419,7 +1441,8 @@ sp_fumbleshield(fighter * fi, int level, int power, spell * sp)
unit *mage = fi->unit;
battle *b = fi->side->battle;
sprintf(buf, "%s zaubert %s", unitname(mage), sp->name);
sprintf(buf, "%s zaubert %s", unitname(mage),
spell_name(sp, default_locale));
battlerecord(b, buf);
/* der erste Zauber schlägt mit 100% fehl */
@ -1477,7 +1500,8 @@ sp_reanimate(fighter * fi, int level, int force, spell * sp)
default:
sprintf(buf, "%s zaubert %s",
unitname(mage), sp->name);
unitname(mage),
spell_name(sp, default_locale));
k = EFFECT_HEALING_SPELL*force;
c = 0.50;
}
@ -1535,7 +1559,8 @@ sp_keeploot(fighter * fi, int level, int force, spell * sp)
{
battle *b = fi->side->battle;
sprintf(buf, "%s zaubert %s.", unitname(fi->unit), sp->name);
sprintf(buf, "%s zaubert %s.", unitname(fi->unit),
spell_name(sp, default_locale));
battlerecord(b, buf);
b->keeploot = max(50, b->keeploot + 5*force);

File diff suppressed because it is too large Load diff

View file

@ -140,32 +140,30 @@ enum {
C_FREE_24,
/* struct's vom untertyp curse_skill: */
C_SKILL,
C_DUMMY,
MAXCURSE
};
/* ------------------------------------------------------------- */
/* Flags */
#define CURSE_ISNEW 1 /* wirkt in der zauberrunde nicht (default)*/
#define CURSE_NOAGE 2 /* wirkt ewig */
#define CURSE_IMMUN 4 /* ignoriert Antimagie */
#define CURSE_ISNEW 1 /* wirkt in der zauberrunde nicht (default)*/
#define CURSE_NOAGE 2 /* wirkt ewig */
#define CURSE_IMMUNE 4 /* ignoriert Antimagie */
#define CURSE_ONLYONE 8 /* Verhindert, das ein weiterer Zauber dieser Art
auf das Objekt gezaubert wird */
/* Verhalten von Zaubern auf Units beim Übergeben von Personen */
enum{
typedef enum {
CURSE_SPREADNEVER, /* wird nie mit übertragen */
CURSE_SPREADALWAYS, /* wird immer mit übertragen */
CURSE_SPREADMODULO, /* personenweise weitergabe */
CURSE_SPREADCHANCE /* Ansteckungschance je nach Mengenverhältnis*/
};
} spread_t;
/* typ von struct */
enum {
CURSETYP_NORM,
CURSETYP_UNIT,
CURSETYP_SKILL,
MAXCURSETYP
};
@ -189,7 +187,7 @@ enum {
typedef struct curse {
struct curse *nexthash;
int no; /* 'Einheitennummer' dieses Curse */
struct curse_type * type; /* Zeiger auf ein curse_type-struct */
const struct curse_type * type; /* Zeiger auf ein curse_type-struct */
int flag; /* generelle Flags wie zb CURSE_ISNEW oder CURSE_NOAGE */
int duration; /* Dauer der Verzauberung. Wird jede Runde vermindert */
int vigour; /* Stärke der Verzauberung, Widerstand gegen Antimagie */
@ -207,17 +205,6 @@ typedef struct curse_unit {
int cursedmen; /* verzauberte Personen in der Einheit */
} curse_unit;
/* Einheitenzauber:
* Spezialtyp, der Talentmodifizierer. Bei Handwerkstalenten oder
* Kampftalenten können Personenbezogenen Boni oder Mali berücksichtigt
* werden, bei anderen Talenten muss sich der Implementiere genauere
* Gedanken zu den Auswirkungen bei nicht ganz voll verzauberten
* Einheiten machen.
*/
typedef struct curse_skill {
int cursedmen; /* verzauberte Personen in der Einheit */
skill_t skill; /* Talent auf das der Spruch wirkt (id2) */
} curse_skill;
typedef int (*cdesc_fun)(const void*, int, curse*, int);
/* Parameter: Objekt, auf dem curse liegt, Typ des Objekts, curse,
@ -226,19 +213,18 @@ typedef int (*cdesc_fun)(const void*, int, curse*, int);
/* ------------------------------------------------------------- */
typedef struct curse_type {
curse_t cspellid; /* Id des Cursezaubers */
const char *name; /* Name der Zauberwirkung, Identifizierung des curse */
const char *cname; /* Name der Zauberwirkung, Identifizierung des curse */
int typ;
int givemenacting;
int mergeflags;
const char *info; /* Wirkung des curse, wird bei einer gelungenen
spread_t spread;
unsigned int mergeflags;
const char *info_str; /* Wirkung des curse, wird bei einer gelungenen
Zauberanalyse angezeigt */
int (*curseinfo)(const void*, int, curse*, int);
void (*change_vigour)(curse*, int);
int (*read)(FILE * F, curse * c);
int (*write)(FILE * F, const curse * c);
} curse_type;
extern struct curse_type cursedaten[];
extern attrib_type at_curse;
extern void curse_write(const attrib * a,FILE * f);
extern int curse_read(struct attrib * a,FILE * f);
@ -247,8 +233,6 @@ extern int curse_read(struct attrib * a,FILE * f);
/* Kommentare:
* Bei einigen Typen von Verzauberungen (z.B.Skillmodif.) muss neben
* der curse-id noch ein weiterer Identifizierer angegeben werden (id2).
* Das ist bei curse_skill der Skill, bei curse_secondid irgendwas frei
* definierbares. In allen anderen Fällen ist id2 egal.
*
* Wenn der Typ korrekt definiert wurde, erfolgt die Verzweigung zum
* korrekten Typus automatisch, und die unterschiedlichen struct-typen
@ -257,7 +241,7 @@ extern int curse_read(struct attrib * a,FILE * f);
* allgemeine Funktionen *
*/
curse * create_curse(struct unit *magician, struct attrib**ap, curse_t id, int id2,
curse * create_curse(struct unit *magician, struct attrib**ap, const curse_type * ctype,
int vigour, int duration, int effect, int men);
/* Verzweigt automatisch zum passenden struct-typ. Sollte es schon
* einen Zauber dieses Typs geben, so wird der neue dazuaddiert. Die
@ -265,23 +249,18 @@ curse * create_curse(struct unit *magician, struct attrib**ap, curse_t id, int i
* nochmal gesondert auf min(get_cursedmen, u->number) gesetzt werden.
*/
boolean is_cursed(struct attrib *ap, curse_t id, int id2);
/* gibt true, wenn bereits ein Zauber dieses Typs vorhanden ist */
boolean is_cursed_internal(struct attrib *ap, curse_t id, int id2);
boolean is_cursed_internal(struct attrib *ap, const curse_type * ctype);
/* ignoriert CURSE_ISNEW */
void remove_curse(struct attrib **ap, curse_t id, int id2);
/* löscht einen Spruch auf einem Objekt. Bei einigen Typen von
* Verzauberungen (z.B. Skillmodif.) muss neben der curse-id noch
* ein weiterer Identifizierer angegeben werden, zb der Skill. In
* allen anderen Fällen ist id2 egal.
*/
void remove_allcurse(struct attrib **ap, const void * data, boolean(*compare)(const attrib *, const void *));
/* löscht alle Curse dieses Typs */
void remove_cursec(attrib **ap, curse *c);
void remove_cursetype(struct attrib **ap, const curse_type *ct);
/* löscht den curse c, wenn dieser in ap steht */
extern void remove_curse(struct attrib **ap, const curse * c);
/* löscht einen konkreten Spruch auf einem Objekt.
*/
int get_curseeffect(struct attrib *ap, curse_t id, int id2);
extern int curse_geteffect(const curse * c);
/* gibt die Auswirkungen der Verzauberungen zurück. zB bei
* Skillmodifiziernden Verzauberungen ist hier der Modifizierer
* gespeichert. Wird automatisch beim Anlegen eines neuen curse
@ -289,27 +268,17 @@ int get_curseeffect(struct attrib *ap, curse_t id, int id2);
*/
int get_cursevigour(struct attrib *ap, curse_t id, int id2);
/* gibt die allgemeine Stärke der Verzauberung zurück. id2 wird wie
* oben benutzt. Dies ist nicht die Wirkung, sondern die Kraft und
* damit der gegen Antimagie wirkende Widerstand einer Verzauberung */
void set_cursevigour(struct attrib *ap, curse_t id, int id2, int i);
/* setzt die Stärke der Verzauberung auf i */
int change_cursevigour(struct attrib **ap, curse_t id, int id2, int i);
extern int curse_changevigour(struct attrib **ap, curse * c, int i);
/* verändert die Stärke der Verzauberung um i */
int get_cursedmen(struct unit *u, struct curse *c);
extern int get_cursedmen(struct unit *u, struct curse *c);
/* gibt bei Personenbeschränkten Verzauberungen die Anzahl der
* betroffenen Personen zurück. Ansonsten wird 0 zurückgegeben. */
int change_cursedmen(struct attrib **ap, curse_t id, int id2, int cursedmen);
extern int change_cursedmen(struct attrib **ap, curse * c, int cursedmen);
/* verändert die Anzahl der betroffenen Personen um cursedmen */
void set_cursedmen(struct attrib *ap, curse_t id, int id2, int cursedmen);
/* setzt die Anzahl der betroffenen Personen auf cursedmen */
void set_curseflag(struct attrib *ap, curse_t id, int id2, int flag);
extern void curse_setflag(curse * c, int flag);
/* setzt Spezialflag einer Verzauberung (zB 'dauert ewig') */
void remove_curseflag(struct attrib *ap, curse_t id, int id2, int flag);
/* löscht Spezialflag einer Verzauberung (zB 'ist neu') */
void transfer_curse(struct unit * u, struct unit * u2, int n);
/* sorgt dafür, das bei der Übergabe von Personen die curse-attribute
@ -320,12 +289,19 @@ void remove_cursemagepointer(struct unit *magician, attrib *ap_target);
/* wird von remove_empty_units verwendet um alle Verweise auf
* gestorbene Magier zu löschen.
* */
curse * get_curse(struct attrib *ap, curse_t id, int id2);
/* gibt pointer auf die passende curse-struct zurück, oder einen
* NULL-pointer
extern curse * get_cursex(attrib *ap, const curse_type * ctype, void * data,
boolean(*compare)(const curse *, const void *));
/* gibt pointer auf die erste curse-struct zurück, deren Typ ctype ist,
* und für die compare() true liefert, oder einen NULL-pointer.
* */
struct unit * get_tracingunit(struct attrib **ap, curse_t id);
struct unit * get_cursingmagician(struct attrib *ap, curse_t id, int id2);
extern curse * get_curse(struct attrib *ap, const curse_type * ctype);
/* gibt pointer auf die erste curse-struct zurück, deren Typ ctype ist,
* oder einen NULL-pointer
* */
struct unit * get_tracingunit(struct attrib **ap, const curse_type * ct);
struct unit * get_cursingmagician(struct attrib *ap, const curse_type * ctype);
/* gibt struct unit-pointer auf Magier zurück, oder einen Nullpointer
* */
int find_cursebyname(const char *c);
@ -344,17 +320,30 @@ extern void curse_done(struct attrib * a);
extern int curse_age(struct attrib * a);
extern boolean cmp_curse(const attrib * a, const void * data);
/* compatibility mode für katjas curses: */
extern boolean cmp_cursetype(const attrib * a, const void * data);
extern boolean cmp_curseeffect(const curse * c, const void * data);
extern boolean cmp_cursedata(const curse * c, const void * data);
/* compatibility mode für katjas curses:
extern boolean cmp_oldcurse(const attrib * a, const void * data);
extern struct twoids * packids(int id, int id2);
*/
extern void * resolve_curse(void * data);
extern boolean is_spell_active(const struct region * r, curse_t id);
/* prüft, ob ein bestimmter Zauber auf einer struct region liegt */
extern boolean is_cursed_with(attrib *ap, curse *c);
const curse_type * find_cursetype(curse_t id);
extern boolean curse_active(const curse * c);
/* gibt true, wenn der Curse nicht NULL oder inaktiv ist */
/*** COMPATIBILITY MACROS. DO NOT USE FOR NEW CODE, REPLACE IN OLD CODE: */
extern const char * oldcursename(int id);
extern void register_curses(void);
#define get_oldcurse(id) \
get_curse(a, ct_find(oldcursename(id)))
#define is_cursed(a, id, id2) \
curse_active(get_curse(a, ct_find(oldcursename(id))))
#define get_curseeffect(a, id, id2) \
curse_geteffect(get_curse(a, ct_find(oldcursename(id))))
#endif

View file

@ -377,13 +377,21 @@ int
shipspeed (ship * sh, const unit * u)
{
int k = sh->type->range;
static const curse_type * stormwind_ct, * nodrift_ct;
static boolean init;
if (!init) {
init = true;
stormwind_ct = ct_find("stormwind");
nodrift_ct = ct_find("nodrift");
}
assert(u->ship==sh);
assert(sh->type->construction->improvement==NULL); /* sonst ist construction::size nicht ship_type::maxsize */
if (sh->size!=sh->type->construction->maxsize) return 0;
if( is_cursed(sh->attribs, C_SHIP_SPEEDUP, 0) )
if( curse_active(get_curse(sh->attribs, stormwind_ct)))
k *= 2;
if( is_cursed(sh->attribs, C_SHIP_NODRIFT, 0) )
if( curse_active(get_curse(sh->attribs, nodrift_ct)))
k += 1;
if (old_race(u->faction->race) == RC_AQUARIAN
@ -2688,8 +2696,16 @@ wage(const region *r, const unit *u, boolean img)
{
building *b = largestbuilding(r, img);
int esize = 0;
curse * c;
int wage;
attrib *a;
static const curse_type * drought_ct, * blessedharvest_ct;
static boolean init;
if (!init) {
init = true;
drought_ct = ct_find("drought");
blessedharvest_ct = ct_find("blessedharvest");
}
if (b) esize = buildingeffsize(b, img);
@ -2706,17 +2722,19 @@ wage(const region *r, const unit *u, boolean img)
} else {
wage = wagetable[esize][2];
}
wage += get_curseeffect(r->attribs, C_BLESSEDHARVEST, 0);
wage += curse_geteffect(get_curse(r->attribs, blessedharvest_ct));
}
/* Godcurse: Income -10 */
if(is_cursed(r->attribs, C_CURSED_BY_THE_GODS, 0)) {
if (curse_active(get_curse(r->attribs, ct_find("godcursezone")))) {
wage = max(0,wage-10);
}
/* Bei einer Dürre verdient man nur noch ein Viertel */
if (is_spell_active(r, C_DROUGHT))
wage /= get_curseeffect(r->attribs, C_DROUGHT, 0);
if (drought_ct) {
c = get_curse(r->attribs, drought_ct);
if (curse_active(c)) wage /= curse_geteffect(c);
}
a = a_find(r->attribs, &at_reduceproduction);
if (a) wage = (wage * a->data.sa[0])/100;
@ -2731,6 +2749,7 @@ fwage(const region *r, const faction *f, boolean img)
int esize = 0;
int wage;
attrib *a;
curse * c;
if (b) esize = buildingeffsize(b, img);
@ -2747,17 +2766,17 @@ fwage(const region *r, const faction *f, boolean img)
} else {
wage = wagetable[esize][2];
}
wage += get_curseeffect(r->attribs, C_BLESSEDHARVEST, 0);
wage += curse_geteffect(get_curse(r->attribs, ct_find("blessedharvest")));
}
/* Godcurse: Income -10 */
if(is_cursed(r->attribs, C_CURSED_BY_THE_GODS, 0)) {
if (curse_active(get_curse(r->attribs, ct_find("godcursezone")))) {
wage = max(0,wage-10);
}
/* Bei einer Dürre verdient man nur noch ein Viertel */
if (is_spell_active(r, C_DROUGHT))
wage /= get_curseeffect(r->attribs, C_DROUGHT, 0);
c = get_curse(r->attribs, ct_find("drought"));
if (curse_active(c)) wage /= curse_geteffect(c);
a = a_find(r->attribs, &at_reduceproduction);
if (a) wage = (wage * a->data.sa[0])/100;

View file

@ -38,7 +38,6 @@ typedef unsigned char order_t;
typedef char terrain_t;
typedef char direction_t;
typedef int race_t;
typedef int curse_t;
typedef int magic_t;
typedef short skill_t;
typedef int herb_t;
@ -50,6 +49,7 @@ typedef int resource_t;
typedef int spellid_t;
struct plane;
struct spell;
struct region;
struct race;
struct ship;
@ -152,9 +152,10 @@ struct xml_stack;
#define NEWSKILL_VERSION 309
#define WATCHERS_VERSION 310
#define OVERRIDE_VERSION 311
#define CURSETYPE_VERSION 312
#define UGROUPS_VERSION 400 /* nicht aktivieren, nicht fertig */
#define RELEASE_VERSION OVERRIDE_VERSION
#define RELEASE_VERSION CURSETYPE_VERSION
/*
#if RELEASE_VERSION >= UGROUPS_VERSION

View file

@ -829,7 +829,7 @@ use_antimagiccrystal(region * r, unit * mage, int amount, strlist * cmdstrings)
c = (curse*)a->data.v;
/* Immunität prüfen */
if (c->flag & CURSE_IMMUN) {
if (c->flag & CURSE_IMMUNE) {
do { ap = &(*ap)->next; } while (*ap && a->type==(*ap)->type);
continue;
}
@ -842,7 +842,7 @@ use_antimagiccrystal(region * r, unit * mage, int amount, strlist * cmdstrings)
}
if(force) {
create_curse(mage, &r->attribs, C_ANTIMAGICZONE, 0, force, duration, effect, 0);
create_curse(mage, &r->attribs, ct_find("antimagiczone"), force, duration, effect, 0);
}
}
@ -865,10 +865,10 @@ use_tacticcrystal(region * r, unit * u, int amount, strlist * cmdstrings)
int power = 5; /* Widerstand gegen Antimagiesprüche, ist in diesem
Fall egal, da der curse für den Kampf gelten soll,
der vor den Antimagiezaubern passiert */
curse * c = create_curse(u, &u->attribs, ct_find("skill"), power,
duration, effect, u->number);
c->data = (void*)SK_TACTICS;
unused(cmdstrings);
create_curse(u, &u->attribs, C_SKILL, SK_TACTICS, power,
duration, effect, u->number);
}
use_pooled(u, u->region, R_TACTICCRYSTAL, amount);
add_message(&u->faction->msgs,
@ -2596,7 +2596,6 @@ register_resources(void)
xml_register(&xml_resource, "eressea resource", 0);
}
#ifdef BETA_CODE
int
xml_writeitems(const char * file)
{
@ -2774,4 +2773,3 @@ xml_writeitems(const char * file)
fclose(stream);
return 0;
}
#endif

View file

@ -551,49 +551,44 @@ getspell(const unit *u, spellid_t spellid)
#include "umlaut.h"
#define SPELLNAMES_HACK 1
#if SPELLNAMES_HACK
struct tnode spellnames;
static void init_spellnames(void)
static local_names * spellnames;
static local_names *
init_spellnames(const struct locale * lang)
{
int i;
for (i=0; spelldaten[i].id != SPL_NOSPELL; i++)
addtoken(&spellnames, spelldaten[i].name, (void*)i);
local_names * sn = calloc(sizeof(local_names), 1);
sn->next = spellnames;
sn->lang = lang;
for (i=0; spelldaten[i].id != SPL_NOSPELL; i++) {
const char * n = spelldaten[i].sname;
if (spelldaten[i].info==NULL) n = locale_string(lang, n);
addtoken(&sn->names, n, (void*)(spelldaten+i));
}
return spellnames = sn;
}
#endif
spell *
find_spellbyname(unit *u, char *s)
find_spellbyname(unit *u, char *name, const struct locale * lang)
{
sc_mage *m;
local_names * sn = spellnames;
spell_ptr *spt;
spell *sp;
sc_mage * m = get_mage(u);
spell * sp;
m = get_mage(u);
if (!m) {
return (spell *) NULL;
if (!m) return NULL;
while (sn) {
if (sn->lang==lang) break;
sn=sn->next;
}
if (!sn) sn = init_spellnames(lang);
if (findtoken(&sn->names, name, &sp)==E_TOK_NOMATCH) return NULL;
for (spt = m->spellptr; spt; spt = spt->next) {
sp = find_spellbyid(spt->spellid);
if (!strncasecmp(sp->name, s, strlen(s))) {
return sp;
}
if (sp->id==spt->spellid) return sp;
}
#if SPELLNAMES_HACK /* enno: geht vorerst nicht mit locales */
{
static int init = 0;
int i;
if (!init) {
init=1;
init_spellnames();
}
if (findtoken(&spellnames, s, (void**)&i)==0 && getspell(u, spelldaten[i].id))
return &spelldaten[i];
}
#endif
return (spell *) NULL;
if (lang==default_locale) return NULL;
return find_spellbyname(u, name, default_locale);
}
spell *
@ -1022,7 +1017,7 @@ knowsspell(const region * r, const unit * u, const spell * sp)
}
if (eff_skill(u, SK_MAGIC, u->region) >= sp->level){
log_warning(("%s ist hat die erforderliche Stufe, kennt aber %s nicht.\n",
unitname(u), sp->name));
unitname(u), spell_name(sp, default_locale)));
}
return false;
}
@ -1054,7 +1049,7 @@ cancast(unit * u, spell * sp, int level, int range, char * cmd)
/* reicht die Stufe aus? */
if (eff_skill(u, SK_MAGIC, u->region) < sp->level) {
log_warning(("Zauber von %s schlug fehl: %s braucht Stufe %d.\n",
unitname(u), sp->name, sp->level));
unitname(u), spell_name(sp, default_locale), sp->level));
/* die Einheit ist nicht erfahren genug für diesen Zauber */
cmistake(u, strdup(cmd), 169, MSG_MAGIC);
return false;
@ -1096,7 +1091,8 @@ cancast(unit * u, spell * sp, int level, int range, char * cmd)
/* Noch fehlte keine Komponente, wir generieren den Anfang der
* Fehlermeldung */
sprintf(buf, "%s in %s: 'ZAUBER %s' Für diesen Zauber fehlen "
"noch %d ", unitname(u), regionid(u->region), sp->name,
"noch %d ", unitname(u), regionid(u->region),
spell_name(sp, u->faction->locale),
itemanz);
scat(locale_string(u->faction->locale,
resname(res, (itemanz == 1 ? 0 : 1))));
@ -1128,6 +1124,7 @@ cancast(unit * u, spell * sp, int level, int range, char * cmd)
int
spellpower(region * r, unit * u, spell * sp, int cast_level)
{
curse * c;
int force = cast_level;
if (sp==NULL) return 0;
else {
@ -1139,16 +1136,18 @@ spellpower(region * r, unit * u, spell * sp, int cast_level)
if (get_item(u, I_RING_OF_POWER) > 0) ++force;
/* Antimagie in der Zielregion */
if (is_spell_active(r, C_ANTIMAGICZONE)) {
force -= get_curseeffect(r->attribs, C_ANTIMAGICZONE, 0);
change_cursevigour(&r->attribs, C_ANTIMAGICZONE, 0, -cast_level);
c = get_curse(r->attribs, ct_find("antimagiczone"));
if (curse_active(c)) {
force -= curse_geteffect(c);
curse_changevigour(&r->attribs, c, -cast_level);
cmistake(u, findorder(u, u->thisorder), 185, MSG_MAGIC);
}
/* Patzerfluch-Effekt: */
if (is_cursed(u->attribs, C_FUMBLE, 0) == true) {
force -= get_curseeffect(u->attribs, C_FUMBLE, 0);
change_cursevigour(&u->attribs, C_FUMBLE, 0, -1);
c = get_curse(r->attribs, ct_find("fumble"));
if (curse_active(c)) {
force -= curse_geteffect(c);
curse_changevigour(&u->attribs, c, -1);
cmistake(u, findorder(u, u->thisorder), 185, MSG_MAGIC);
}
@ -1210,9 +1209,9 @@ magic_resistance(unit *target)
chance += effskill(target, SK_MAGIC)*5;
/* Auswirkungen von Zaubern auf der Einheit */
c = get_curse(target->attribs, C_MAGICRESISTANCE, 0);
c = get_curse(target->attribs, ct_find("magicresistance"));
if (c) {
chance += get_curseeffect(target->attribs, C_MAGICRESISTANCE, 0) * get_cursedmen(target, c);
chance += curse_geteffect(c) * get_cursedmen(target, c);
}
/* Unicorn +10 */
@ -1225,38 +1224,22 @@ magic_resistance(unit *target)
curse *c = (curse*)a->data.v;
unit *mage = c->magician;
if (c->type->cspellid == C_SONG_GOODMR) {
if (mage != NULL) {
if (mage!=NULL) {
if (c->type == ct_find("goodmagicresistancezone")) {
if (allied(mage, target->faction, HELP_GUARD)) {
chance += c->effect;
break;
}
} else {
a = a->nexttype;
continue;
}
}
a = a->nexttype;
}
a = a_find(target->region->attribs, &at_curse);
while (a) {
curse *c = (curse*)a->data.v;
unit *mage = c->magician;
if (c->type->cspellid == C_SONG_BADMR) {
if (mage != NULL) {
else if (c->type == ct_find("badmagicresistancezone")) {
if (allied(mage, target->faction, HELP_GUARD)) {
a = a->nexttype;
continue;
} else {
chance -= c->effect;
break;
}
}
}
a = a->nexttype;
}
/* Bonus durch Artefakte */
/* TODO (noch gibs keine)*/
@ -1425,6 +1408,7 @@ fumble(region * r, unit * u, spell * sp, int cast_grade)
void
do_fumble(castorder *co)
{
curse * c;
region * r = co->rt;
unit * u = (unit*)co->magician;
spell * sp = co->sp;
@ -1458,8 +1442,9 @@ do_fumble(castorder *co)
case 2:
/* temporärer Stufenverlust */
duration = max(rand()%level/2, 2);
create_curse(u, &u->attribs, C_SKILL, SK_MAGIC, level, duration,
-(level/2), 1);
c = create_curse(u, &u->attribs, ct_find("skil"), level, duration,
-(level/2), 1);
c->data = (void*)SK_MAGIC;
add_message(&u->faction->msgs,
new_message(u->faction, "patzer2%u:unit%r:region", u, r));
break;
@ -1467,9 +1452,9 @@ do_fumble(castorder *co)
case 4:
/* Spruch schlägt fehl, alle Magiepunkte weg */
set_spellpoints(u, 0);
add_message(&u->faction->msgs, new_message(u->faction,
"patzer3%u:unit%r:region%s:command",
u, r, sp->name));
add_message(&u->faction->msgs, msg_message("patzer3",
"unit region command",
u, r, spell_name(sp, u->faction->locale)));
break;
case 5:
@ -1482,7 +1467,7 @@ do_fumble(castorder *co)
"Gestalten kreisen um den Magier und scheinen sich von "
"den magischen Energien des Zaubers zu ernähren. Mit letzter "
"Kraft gelingt es %s dennoch den Spruch zu zaubern.",
unitname(u), sp->name, unitname(u));
unitname(u), spell_name(sp, u->faction->locale), unitname(u));
addmessage(0, u->faction, buf, MSG_MAGIC, ML_WARN);
break;
@ -1494,7 +1479,8 @@ do_fumble(castorder *co)
((nspell_f)sp->sp_function)(co);
sprintf(buf, "%s fühlt sich nach dem Zaubern von %s viel erschöpfter "
"als sonst und hat das Gefühl, dass alle weiteren Zauber deutlich "
"mehr Kraft als normalerweise kosten werden.", unitname(u), sp->name);
"mehr Kraft als normalerweise kosten werden.", unitname(u),
spell_name(sp, u->faction->locale));
addmessage(0, u->faction, buf, MSG_MAGIC, ML_WARN);
countspells(u,3);
}
@ -2962,7 +2948,7 @@ magic(void)
cmistake(u, so->s, 172, MSG_MAGIC);
continue;
}
sp = find_spellbyname(u, s);
sp = find_spellbyname(u, s, u->faction->locale);
/* Vertraute können auch Zauber sprechen, die sie selbst nicht
* können. find_spellbyname findet aber nur jene Sprüche, die
@ -2970,7 +2956,7 @@ magic(void)
if (sp == NULL && is_familiar(u)) {
familiar = u;
mage = get_familiar_mage(u);
sp = find_spellbyname(mage, s);
sp = find_spellbyname(mage, s, mage->faction->locale);
}
if (sp == NULL) {
@ -3028,7 +3014,9 @@ magic(void)
if (range > 1024) { /* (2^10) weiter als 10 Regionen entfernt */
sprintf(buf, "%s in %s: 'ZAUBER %s' Zu der Region %s kann keine "
"Verbindung hergestellt werden", unitname(u),
regionid(u->region), sp->name, regionid(target_r));
regionid(u->region),
spell_name(sp, u->faction->locale),
regionid(target_r));
addmessage(0, u->faction, buf, MSG_MAGIC, ML_MISTAKE);
continue;
}
@ -3040,7 +3028,8 @@ magic(void)
level = ilevel;
sprintf(buf, "%s in %s: 'ZAUBER %s' Dieser Zauber kann nicht "
"mit Stufenangabe gezaubert werden.", unitname(u),
regionid(u->region), sp->name);
regionid(u->region),
spell_name(sp, u->faction->locale));
addmessage(0, u->faction, buf, MSG_MAGIC, ML_WARN);
}
}
@ -3129,7 +3118,8 @@ magic(void)
* gezaubert, co->level ist aber defaultmäßig Stufe des Magiers */
if (spl_costtyp(sp) != SPC_FIX) {
sprintf(buf, "%s hat nur genügend Komponenten um %s auf Stufe %d "
"zu zaubern.", unitname(u), sp->name, level);
"zu zaubern.", unitname(u),
spell_name(sp, u->faction->locale), level);
addmessage(0, u->faction, buf, MSG_MAGIC, ML_INFO);
}
}
@ -3146,7 +3136,8 @@ magic(void)
force = spellpower(target_r, u, sp, level);
if (force < 1) {
sprintf(buf, "%s schafft es nicht genügend Kraft aufzubringen "
"um %s dennoch zu zaubern.", unitname(u), sp->name);
"um %s dennoch zu zaubern.", unitname(u),
spell_name(sp, u->faction->locale));
addmessage(0, u->faction, buf, MSG_MAGIC, ML_MISTAKE);
continue;
}
@ -3178,7 +3169,8 @@ magic(void)
pay_spell(u, sp, level, co->distance);
countspells(u,1);
sprintf(buf, "%s gelingt es %s zu zaubern, doch der Spruch zeigt "
"keine Wirkung.", unitname(u), sp->name);
"keine Wirkung.", unitname(u),
spell_name(sp, u->faction->locale));
addmessage(0, u->faction, buf, MSG_MAGIC, ML_MISTAKE);
continue; /* äußere Schleife, nächster Zauberer */
}
@ -3237,3 +3229,21 @@ create_special_direction(region *r, int x, int y, int duration,
return a;
}
const char *
spell_info(const struct spell * sp, const struct locale * lang)
{
if (sp->info==NULL) {
return LOC(lang, mkname("spellinfo", sp->sname));
}
return sp->info;
}
const char *
spell_name(const struct spell * sp, const struct locale * lang)
{
if (sp->info==NULL) {
return LOC(lang, mkname("spell", sp->sname));
}
return sp->sname;
}

View file

@ -145,8 +145,8 @@ struct spell_ptr {
typedef struct spell {
spellid_t id;
const char *name;
const char *beschreibung;
const char *sname;
const char *info;
const char *syntax;
const char *parameter;
magic_t magietyp;
@ -285,7 +285,7 @@ boolean is_familiar(const struct unit *u);
/* gibt true, wenn eine Familiar-Relation besteht. */
/* Sprüche */
spell *find_spellbyname(struct unit *u, char *s);
spell *find_spellbyname(struct unit *u, char *s, const struct locale * lang);
/* versucht einen Spruch über den Namen zu identifizieren, gibt
* ansonsten NULL zurück */
spell *find_spellbyid(spellid_t i);
@ -402,4 +402,7 @@ extern struct attrib *create_special_direction(struct region *r, int x, int y, i
extern struct plane * astral_plane;
extern const char * spell_info(const struct spell * sp, const struct locale * lang);
extern const char * spell_name(const struct spell * sp, const struct locale * lang);
#endif

View file

@ -385,6 +385,7 @@ new_message(struct faction * receiver, const char* sig, ...)
void * args[16];
memset(args, 0, sizeof(args));
assert(signature-sig < sizeof(buffer));
strnzcpy(buffer, sig, signature-sig);
mtype = mt_find(buffer);

View file

@ -903,6 +903,14 @@ travel(region * first, unit * u, region * next, int flucht)
unit *ut, *u2;
int gereist = 0;
static direction_t route[MAXSPEED];
static boolean init = false;
static const curse_type * speed_ct;
static const curse_type * fogtrap_ct;
if (!init) {
init = true;
speed_ct = ct_find("speed");
fogtrap_ct = ct_find("fogtrap");
}
/* tech:
*
@ -959,8 +967,8 @@ travel(region * first, unit * u, region * next, int flucht)
dk = u->race->speed;
{
curse *c = get_curse(u->attribs, C_SPEED, 0);
if (speed_ct) {
curse *c = get_curse(u->attribs, speed_ct);
if(c) {
int men = get_cursedmen(u, c);
dk *= 1.0 + (double)men/(double)u->number;
@ -1051,7 +1059,7 @@ travel(region * first, unit * u, region * next, int flucht)
if (k<0) break;
/* r2 -> Zielregion, r3 -> Momentane Region */
if (move_blocked(u, current, reldirection(current, next))
|| is_spell_active(current, C_FOGTRAP))
|| curse_active(get_curse(current->attribs, fogtrap_ct)))
{
ADDMSG(&u->faction->msgs, msg_message("leavefail",
"unit region", u, next));
@ -1064,19 +1072,21 @@ travel(region * first, unit * u, region * next, int flucht)
wache));
break;
}
if (is_spell_active(next, C_ANTIMAGICZONE) && fval(u->race, RCF_ILLUSIONARY)) {
change_cursevigour(&next->attribs, C_ANTIMAGICZONE, 0, - u->number);
add_message(&u->faction->msgs, new_message(u->faction,
"illusionantimagic%u:unit", u));
destroy_unit(u);
return route;
if (fval(u->race, RCF_ILLUSIONARY)) {
curse * c = get_curse(next->attribs, ct_find("antimagiczone"));
if (curse_active(c)) {
curse_changevigour(&next->attribs, c, - u->number);
add_message(&u->faction->msgs, new_message(u->faction,
"illusionantimagic%u:unit", u));
destroy_unit(u);
return route;
}
}
/* Ozeanfelder können nur von Einheiten mit Schwimmen und ohne
* Pferde betreten werden. Drachen können fliegen. */
if(rterrain(next) == T_OCEAN && !canswim(u)) {
if (rterrain(next) == T_OCEAN && !canswim(u)) {
plane *pl = getplane(next);
if(pl && fval(pl, PFL_NOCOORDS)) {
add_message(&u->faction->msgs, new_message(u->faction,
@ -1363,6 +1373,12 @@ sail(region * starting_point, unit * u, region * next_point, boolean move_on_lan
region *rv[MAXSPEED + 1];
region *tt[MAXSPEED + 1]; /* travelthru */
static direction_t route[MAXSPEED+1]; /* route[i] := direction from tt[i] to tt[i-1] */
static boolean init = false;
static const curse_type * fogtrap_ct;
if (!init) {
init = true;
fogtrap_ct = ct_find("fogtrap");
}
if (!ship_ready(starting_point, u))
return NULL;
@ -1449,7 +1465,7 @@ sail(region * starting_point, unit * u, region * next_point, boolean move_on_lan
/* Falls Blockade, endet die Seglerei hier */
if (move_blocked(u, current_point, reldirection(current_point, next_point))
|| is_spell_active(current_point, C_FOGTRAP)) {
|| curse_active(get_curse(current_point->attribs, fogtrap_ct))) {
add_message(&u->faction->msgs, new_message(u->faction,
"sailfail%h:ship%r:region", u->ship, current_point));
break;
@ -1967,10 +1983,17 @@ destroy_damaged_ships(void)
boolean
is_disorientated(unit *u)
{
if(u->ship && get_curse(u->ship->attribs, C_DISORIENTATION, 0))
static boolean init = false;
static const curse_type * shipconf_ct, * regconf_ct;
if (!init) {
init = true;
regconf_ct = ct_find("disorientationzone");
shipconf_ct = ct_find("shipdisorientation");
}
if (u->ship && curse_active(get_curse(u->ship->attribs, shipconf_ct)))
return true;
if(is_spell_active(u->region, C_REGCONF))
if (curse_active(get_curse(u->region->attribs, regconf_ct)))
return true;
return false;

View file

@ -1029,7 +1029,7 @@ production(const region *r)
{
/* muß r->terrain sein, nicht rterrain() wegen rekursion */
int p = terrain[r->terrain].production_max;
if (is_spell_active(r, C_DROUGHT)) p /= 2;
if (curse_active(get_curse(r->attribs, ct_find("drought")))) p /= 2;
return p;
}

View file

@ -34,6 +34,7 @@
#include "ship.h"
#include "skill.h"
#include "unit.h"
#include "spell.h"
#include "plane.h"
#ifdef USE_UGROUPS
# include "ugroup.h"
@ -373,7 +374,7 @@ bufunit(const faction * f, const unit * u, int indent, int mode)
}else{
scat(", ");
}
scat(sp->name);
scat(spell_name(sp, f->locale));
}
}
dh = 0;
@ -395,7 +396,7 @@ bufunit(const faction * f, const unit * u, int indent, int mode)
sp = get_combatspell(u,i);
if (sp) {
int sl;
scat(sp->name);
scat(spell_name(sp, u->faction->locale));
if((sl = get_combatspelllevel(u,i)) > 0) {
scat(" (");
icat(sl);
@ -736,7 +737,7 @@ spy_message(int spy, unit *u, unit *target)
} else {
scat(", ");
}
scat(sp->name);
scat(spell_name(sp, u->faction->locale));
}
if (found == 0) {
scat("Keine");

View file

@ -435,7 +435,7 @@ static faction *
factionorders(void)
{
char b[16];
char * fid = strnzcpy(b, getstrtoken(), 16);
char * fid = strnzcpy(b, getstrtoken(), 15);
char * pass = getstrtoken();
faction *f;
@ -1353,11 +1353,11 @@ writegame(char *path, char quiet)
/* ------------------------------------------------------------- */
void
curse_write(const attrib * a,FILE * f) {
curse_write(const attrib * a, FILE * f) {
int flag;
int mage_no;
curse * c = (curse*)a->data.v;
curse_type * ct = c->type;
const curse_type * ct = c->type;
flag = (c->flag & ~(CURSE_ISNEW));
@ -1367,45 +1367,39 @@ curse_write(const attrib * a,FILE * f) {
mage_no = -1;
}
fprintf(f, "%d %d %d %d %d %d %d ", c->no, (int)ct->cspellid, flag,
fprintf(f, "%d %s %d %d %d %d %d ", c->no, ct->cname, flag,
c->duration, c->vigour, mage_no, c->effect);
switch(c->type->typ){
case CURSETYP_UNIT:
{
curse_unit * cc = (curse_unit*)c->data;
fprintf(f, "%d ", cc->cursedmen);
break;
}
case CURSETYP_SKILL:
{
curse_skill * cc = (curse_skill*)c->data;
fprintf(f, "%d %d ", (int)cc->skill, cc->cursedmen);
break;
}
case CURSETYP_NORM:
default:
break;
if (c->type->write) c->type->write(f, c);
else if (c->type->typ == CURSETYP_UNIT) {
curse_unit * cc = (curse_unit*)c->data;
fprintf(f, "%d ", cc->cursedmen);
}
}
int
curse_read(attrib * a, FILE * f) {
int cspellid;
int mageid;
curse * c = (curse*)a->data.v;
curse_type * ct;
const curse_type * ct;
if (global.data_version < CURSE_NO_VERSION){
fscanf(f, "%d %d %d %d %d %d ",&cspellid, &c->flag, &c->duration,
&c->vigour, &mageid, &c->effect);
c->no = newunitid();
if (global.data_version >= CURSETYPE_VERSION) {
char cursename[64];
fscanf(f, "%d %s %d %d %d %d %d ", &c->no, cursename, &c->flag,
&c->duration, &c->vigour, &mageid, &c->effect);
ct = ct_find(cursename);
} else {
fscanf(f, "%d %d %d %d %d %d %d ", &c->no, &cspellid, &c->flag,
int cspellid;
if (global.data_version < CURSE_NO_VERSION) {
fscanf(f, "%d %d %d %d %d %d ",&cspellid, &c->flag, &c->duration,
&c->vigour, &mageid, &c->effect);
c->no = newunitid();
} else {
fscanf(f, "%d %d %d %d %d %d %d ", &c->no, &cspellid, &c->flag,
&c->duration, &c->vigour, &mageid, &c->effect);
}
ct = ct_find(oldcursename(cspellid));
}
ct = find_cursetype((curse_t)cspellid);
assert(ct!=NULL);
c->type = ct;
@ -1418,28 +1412,12 @@ curse_read(attrib * a, FILE * f) {
ur_add((void*)mageid, (void**)&c->magician, resolve_unit);
}
switch(c->type->typ){
case CURSETYP_UNIT:
{
curse_unit * cc = calloc(1, sizeof(curse_unit));
if (c->type->read) c->type->read(f, c);
else if (c->type->typ==CURSETYP_UNIT) {
curse_unit * cc = calloc(1, sizeof(curse_unit));
c->data = cc;
fscanf(f, "%d ", &cc->cursedmen);
break;
}
case CURSETYP_SKILL:
{
curse_skill * cc = calloc(1, sizeof(curse_skill));
int skill;
c->data = cc;
fscanf(f, "%d %d ", &skill, &cc->cursedmen);
cc->skill = (skill_t)skill;
break;
}
case CURSETYP_NORM:
default:
break;
c->data = cc;
fscanf(f, "%d ", &cc->cursedmen);
}
chash(c);

View file

@ -56,6 +56,7 @@
#include <base36.h>
#include <message.h>
#include <event.h>
#include <language.h>
#include <rand.h>
/* libc includes */
@ -169,6 +170,7 @@ magicanalyse_region(region *r, unit *mage, int force)
{
attrib *a;
boolean found = false;
const struct locale * lang = mage->faction->locale;
for (a=r->attribs;a;a=a->next) {
curse * c;
@ -186,14 +188,14 @@ magicanalyse_region(region *r, unit *mage, int force)
found = true;
if(rand()%100 < chance){ /* Analyse geglückt */
if(c->flag & CURSE_NOAGE){
if(c->flag & CURSE_NOAGE) {
add_message(&mage->faction->msgs, new_message(mage->faction,
"analyse_region_noage%u:mage%r:region%s:spell",
mage, r, c->type->name));
mage, r, LOC(lang, c->type->cname)));
}else{
add_message(&mage->faction->msgs, new_message(mage->faction,
"analyse_region_age%u:mage%r:region%s:spell%i:months",
mage, r, c->type->name, mon));
mage, r, LOC(lang, c->type->cname), mon));
}
} else {
add_message(&mage->faction->msgs, new_message(mage->faction,
@ -211,6 +213,7 @@ magicanalyse_unit(unit *u, unit *mage, int force)
{
attrib *a;
boolean found = false;
const struct locale * lang = mage->faction->locale;
for (a=u->attribs;a;a=a->next) {
curse * c;
@ -229,11 +232,11 @@ magicanalyse_unit(unit *u, unit *mage, int force)
if(c->flag & CURSE_NOAGE){
add_message(&mage->faction->msgs, new_message(mage->faction,
"analyse_unit_noage%u:mage%u:unit%s:spell",
mage, u, c->type->name));
mage, u, LOC(lang, c->type->cname)));
}else{
add_message(&mage->faction->msgs, new_message(mage->faction,
"analyse_unit_age%u:mage%u:unit%s:spell%i:months",
mage, u, c->type->name, mon));
mage, u, LOC(lang, c->type->cname), mon));
}
} else {
add_message(&mage->faction->msgs, new_message(mage->faction,
@ -251,6 +254,7 @@ magicanalyse_building(building *b, unit *mage, int force)
{
attrib *a;
boolean found = false;
const struct locale * lang = mage->faction->locale;
for (a=b->attribs;a;a=a->next) {
curse * c;
@ -269,11 +273,11 @@ magicanalyse_building(building *b, unit *mage, int force)
if(c->flag & CURSE_NOAGE){
add_message(&mage->faction->msgs, new_message(mage->faction,
"analyse_building_age%u:mage%b:building%s:spell",
mage, b, c->type->name));
mage, b, LOC(lang, c->type->cname)));
}else{
add_message(&mage->faction->msgs, new_message(mage->faction,
"analyse_building_age%u:mage%b:building%s:spell%i:months",
mage, b, c->type->name, mon));
mage, b, LOC(lang, c->type->cname)));
}
} else {
add_message(&mage->faction->msgs, new_message(mage->faction,
@ -292,6 +296,7 @@ magicanalyse_ship(ship *sh, unit *mage, int force)
{
attrib *a;
boolean found = false;
const struct locale * lang = mage->faction->locale;
for (a=sh->attribs;a;a=a->next) {
curse * c;
@ -310,11 +315,11 @@ magicanalyse_ship(ship *sh, unit *mage, int force)
if(c->flag & CURSE_NOAGE){
add_message(&mage->faction->msgs, new_message(mage->faction,
"analyse_ship_noage%u:mage%h:ship%s:spell",
mage, sh, c->type->name));
mage, sh, LOC(lang, c->type->cname)));
}else{
add_message(&mage->faction->msgs, new_message(mage->faction,
"analyse_ship_age%u:mage%h:ship%s:spell",
mage, sh, c->type->name, mon));
mage, sh, LOC(lang, c->type->cname)));
}
} else {
add_message(&mage->faction->msgs, new_message(mage->faction,
@ -387,7 +392,7 @@ destroy_curse(attrib **alist, int cast_level, int force,
c1 = (curse*)a->data.v;
/* Immunität prüfen */
if (c1->flag & CURSE_IMMUN) {
if (c1->flag & CURSE_IMMUNE) {
do { ap = &(*ap)->next; } while (*ap && a->type==(*ap)->type);
continue;
}
@ -850,7 +855,7 @@ sp_goodwinds(castorder *co)
/* keine Probleme mit C_SHIP_SPEEDUP und C_SHIP_FLYING */
/* NODRIFT bewirkt auch +1 Geschwindigkeit */
create_curse(mage, &sh->attribs, C_SHIP_NODRIFT, 0, power, cast_level, 0, 0);
create_curse(mage, &sh->attribs, ct_find("nodrift"), power, cast_level, 0, 0);
/* melden, 1x pro Partei */
freset(mage->faction, FL_DH);
@ -908,7 +913,7 @@ sp_magicstreet(castorder *co)
}
/* wirkt schon in der Zauberrunde! */
create_curse(mage, &r->attribs, C_MAGICSTREET, 0, power, cast_level, 0, 0);
create_curse(mage, &r->attribs, ct_find("magicstreet"), power, cast_level, 0, 0);
/* melden, 1x pro Partei */
{
@ -1056,6 +1061,7 @@ sp_maelstrom(castorder *co)
region *r = co->rt;
unit *mage = (unit *)co->magician;
int cast_level = co->level;
curse * c;
int power = co->force;
if(rterrain(r) != T_OCEAN) {
@ -1067,8 +1073,8 @@ sp_maelstrom(castorder *co)
/* Attribut auf Region.
* Existiert schon ein curse, so wird dieser verstärkt
* (Max(Dauer), Max(Stärke))*/
create_curse(mage,&mage->attribs,C_MAELSTROM,0,power,power,power,0);
set_curseflag(r->attribs, C_MAELSTROM, 0, CURSE_ISNEW);
c = create_curse(mage, &mage->attribs, ct_find("maelstrom"), power, power, power,0);
curse_setflag(c, CURSE_ISNEW);
/* melden, 1x pro Partei */
{
@ -1150,8 +1156,7 @@ sp_blessedharvest(castorder *co)
/* Attribut auf Region.
* Existiert schon ein curse, so wird dieser verstärkt
* (Max(Dauer), Max(Stärke))*/
create_curse(mage,&r->attribs,C_BLESSEDHARVEST,0,power,power,1,0);
create_curse(mage,&r->attribs, ct_find("blessedharvest"), power, power, 1, 0);
{
message * seen = msg_message("harvest_effect", "mage", mage);
message * unseen = msg_message("harvest_effect", "mage", NULL);
@ -1192,7 +1197,7 @@ sp_hain(castorder *co)
return 0;
}
trees = lovar(force * 10 * RESOURCE_QUANTITY) + force;
trees = lovar((int)(force * 10 * RESOURCE_QUANTITY)) + force;
#if GROWING_TREES
rsettrees(r, 1, rtrees(r,1) + trees);
#else
@ -1239,7 +1244,7 @@ sp_mallornhain(castorder *co)
return 0;
}
trees = lovar(force * 10 * RESOURCE_QUANTITY) + force;
trees = lovar((int)(force * 10 * RESOURCE_QUANTITY)) + force;
#if GROWING_TREES
rsettrees(r, 1, rtrees(r,1) + trees);
#else
@ -1431,7 +1436,7 @@ sp_kaelteschutz(castorder *co)
men = u->number;
}
create_curse(mage, &u->attribs, C_KAELTESCHUTZ, 0, cast_level,
create_curse(mage, &u->attribs, ct_find("insectfur"), cast_level,
duration, 1, men);
force -= u->number;
@ -1477,7 +1482,7 @@ sp_sparkle(castorder *co)
if(pa->param[0]->flag == TARGET_RESISTS) return cast_level;
u = pa->param[0]->data.u;
create_curse(mage, &u->attribs, C_SPARKLE, 0, cast_level,
create_curse(mage, &u->attribs, ct_find("sparkle"), cast_level,
cast_level, rand(), u->number);
add_message(&mage->faction->msgs, new_message(mage->faction,
@ -1531,7 +1536,7 @@ sp_create_irongolem(castorder *co)
return 0;
}
u2 = create_unit(r, mage->faction, max(1,force*8*RESOURCE_QUANTITY), new_race[RC_IRONGOLEM], 0,
u2 = create_unit(r, mage->faction, max(1,(int)(force*8*RESOURCE_QUANTITY)), new_race[RC_IRONGOLEM], 0,
LOC(mage->faction->locale, rc_name(new_race[RC_IRONGOLEM], 1)), mage);
set_level(u2, SK_ARMORER, 1);
@ -1592,7 +1597,7 @@ sp_create_stonegolem(castorder *co)
return 0;
}
u2 = create_unit(r, mage->faction, max(1,force*5*RESOURCE_QUANTITY), new_race[RC_STONEGOLEM], 0,
u2 = create_unit(r, mage->faction, max(1,(int)(force*5*RESOURCE_QUANTITY)), new_race[RC_STONEGOLEM], 0,
LOC(mage->faction->locale, rc_name(new_race[RC_STONEGOLEM], 1)), mage);
set_level(u2, SK_ROAD_BUILDING, 1);
set_level(u2, SK_BUILDING, 1);
@ -1668,7 +1673,7 @@ sp_great_drought(castorder *co)
rsethorses(r, rhorses(r)/2);
/* Arbeitslohn = 1/4 */
create_curse(mage, &r->attribs, C_DROUGHT, 0, force, 1, 4, 0);
create_curse(mage, &r->attribs, ct_find("drought"), force, 1, 4, 0);
/* terraforming */
if (rand() % 100 < 25){
@ -2042,13 +2047,14 @@ sp_holyground(castorder *co)
unit *mage = (unit *)co->magician;
int cast_level = co->level;
int power = co->force;
curse * c;
message * msg = r_addmessage(r, mage->faction, msg_message("holyground", "mage", mage));
msg_release(msg);
create_curse(mage, &r->attribs, C_HOLYGROUND, 0,
power*power, 1, 0, 0);
c = create_curse(mage, &r->attribs, ct_find("holyground"),
power*power, 1, 0, 0);
set_curseflag(mage->region->attribs, C_HOLYGROUND, 0, CURSE_NOAGE);
curse_setflag(c, CURSE_NOAGE);
a_removeall(&r->attribs, &at_deathcount);
@ -2072,7 +2078,7 @@ static int
sp_homestone(castorder *co)
{
unit *u;
curse * success;
curse * c;
region *r = co->rt;
unit *mage = (unit *)co->magician;
int cast_level = co->level;
@ -2083,23 +2089,20 @@ sp_homestone(castorder *co)
return 0;
}
success = create_curse(mage, &mage->building->attribs, C_MAGICSTONE, 0,
c = create_curse(mage, &mage->building->attribs, ct_find("magicstone"),
force*force, 1, 0, 0);
if(!success) {
if (c==NULL) {
cmistake(mage, strdup(co->order), 206, MSG_MAGIC);
return 0;
}
set_curseflag(mage->building->attribs, C_MAGICSTONE, 0, CURSE_NOAGE);
/* Nur ein Heimstein pro Burg möglich */
set_curseflag(mage->building->attribs, C_MAGICSTONE, 0, CURSE_ONLYONE);
curse_setflag(c, CURSE_NOAGE|CURSE_ONLYONE);
/* Magieresistenz der Burg erhöht sich um 50% */
create_curse(mage, &mage->building->attribs, C_RESIST_MAGIC, 0,
force*force, 1, 50, 0);
set_curseflag(mage->building->attribs, C_RESIST_MAGIC, 0, CURSE_NOAGE);
c = create_curse(mage, &mage->building->attribs,
ct_find("magicresistance"), force*force, 1, 50, 0);
curse_setflag(c, CURSE_NOAGE);
/* melden, 1x pro Partei in der Burg */
for (u = r->units; u; u = u->next) freset(u->faction, FL_DH);
@ -2169,8 +2172,8 @@ sp_drought(castorder *co)
* hoch (evtl dauert dann die Duerre laenger). Ansonsten volle
* Auswirkungen.
*/
c = get_curse(r->attribs, C_DROUGHT, 0);
if(c) {
c = get_curse(r->attribs, ct_find("drought"));
if (c) {
c->vigour = max(c->vigour, power);
c->duration = max(c->duration, power);
} else {
@ -2184,7 +2187,7 @@ sp_drought(castorder *co)
#endif
rsethorses(r, rhorses(r)/2);
create_curse(mage, &r->attribs, C_DROUGHT, 0, power, power, 4, 0);
create_curse(mage, &r->attribs, ct_find("drought"), power, power, 4, 0);
}
return cast_level;
}
@ -2221,6 +2224,7 @@ sp_fog_of_confusion(castorder *co)
rl = all_in_range(r, range);
for(rl2 = rl; rl2; rl2 = rl2->next) {
curse * c;
if(rterrain(rl2->region) != T_OCEAN
&& !r_isforest(rl2->region)) continue;
@ -2230,10 +2234,10 @@ sp_fog_of_confusion(castorder *co)
continue;
}
create_curse(mage, &rl2->region->attribs, C_REGCONF,0,
power, duration, cast_level*5, 0);
c = create_curse(mage, &rl2->region->attribs,
ct_find("disorientationzone"), power, duration, cast_level*5, 0);
/* Soll der schon in der Zauberrunde wirken? */
set_curseflag(rl2->region->attribs, C_REGCONF, 0, CURSE_ISNEW);
curse_setflag(c, CURSE_ISNEW);
for (u = rl2->region->units; u; u = u->next) freset(u->faction, FL_DH);
for(u = rl2->region->units; u; u = u->next ) {
@ -2360,7 +2364,7 @@ sp_stormwinds(castorder *co)
}
/* Duration = 1, nur diese Runde */
create_curse(mage, &sh->attribs, C_SHIP_SPEEDUP, 0, power, 1, 0, 0);
create_curse(mage, &sh->attribs, ct_find("stormwind"), power, 1, 0, 0);
/* Da der Spruch nur diese Runde wirkt, brauchen wir kein
* set_cursedisplay() zu benutzten - es sieht eh niemand... */
erfolg++;
@ -2685,6 +2689,7 @@ sp_fumblecurse(castorder *co)
unit *mage = (unit *)co->magician;
int cast_level = co->level;
int force = co->force;
curse * c;
spellparameter *pa = co->par;
/* wenn kein Ziel gefunden, Zauber abbrechen */
@ -2698,14 +2703,14 @@ sp_fumblecurse(castorder *co)
effect = force/2;
if (create_curse(mage, &target->attribs, C_FUMBLE, 0,
force, duration+1, effect, 0) == NULL)
{
c = create_curse(mage, &target->attribs, ct_find("fumble"),
force, duration+1, effect, 0);
if (c == NULL) {
report_failure(mage, co->order);
return 0;
}
set_curseflag(target->attribs, C_FUMBLE, 0, CURSE_ONLYONE);
curse_setflag(c, CURSE_ONLYONE);
add_message(&target->faction->msgs, new_message(target->faction,
"fumblecurse%u:unit%r:region", target, target->region));
@ -2719,16 +2724,17 @@ patzer_fumblecurse(castorder *co)
int cast_level = co->level;
int force = co->force;
int effect;
curse * c;
effect = force/2;
if (create_curse(mage, &mage->attribs, C_FUMBLE, 0, force,
(cast_level/2)+1, effect, 0))
{
c = create_curse(mage, &mage->attribs, ct_find("fumble"), force,
(cast_level/2)+1, effect, 0);
if (c!=NULL) {
add_message(&mage->faction->msgs, new_message(mage->faction,
"magic_fumble%u:unit%r:region%s:command",
mage, mage->region, strdup(co->order)));
set_curseflag(mage->attribs, C_FUMBLE, 0, CURSE_ONLYONE);
curse_setflag(c, CURSE_ONLYONE);
}
return;
}
@ -2862,7 +2868,7 @@ wall_vigour(curse* c, int delta)
}
const curse_type ct_firewall = {
C_DUMMY, "Feuerwand",
"Feuerwand",
CURSETYP_NORM, 0, (M_DURATION | M_VIGOUR | NO_MERGE),
"Eine Feuerwand blockiert die Ein- und Ausreise",
NULL, /* curseinfo */
@ -3575,6 +3581,7 @@ sp_chaossuction(castorder *co)
static int
sp_magicboost(castorder *co)
{
curse * c;
unit *mage = (unit *)co->magician;
int cast_level = co->level;
int power = co->force;
@ -3584,17 +3591,18 @@ sp_magicboost(castorder *co)
report_failure(mage, co->order);
return 0;
}
/* (magier, attribut, curseid, id2, power, duration, effect, men) */
create_curse(mage, &mage->attribs, C_MBOOST, 0, power, 10, 6, 1);
create_curse(mage, &mage->attribs, C_AURA, 0, power, 4, 200, 1);
c = create_curse(mage, &mage->attribs, ct_find("magicboost"), power, 10, 6, 1);
/* kann nicht durch Antimagie beeinflusst werden */
curse_setflag(c, CURSE_IMMUNE);
c = create_curse(mage, &mage->attribs, ct_find("aura"), power, 4, 200, 1);
{
trigger * tsummon = trigger_createcurse(mage, mage, C_AURA, 0, power, 6, 50, 1);
trigger * tsummon = trigger_createcurse(mage, mage, c->type, power, 6, 50, 1);
add_trigger(&mage->attribs, "timer", trigger_timeout(5, tsummon));
}
/* kann nicht durch Antimagie beeinflusst werden */
set_curseflag(mage->attribs, C_MBOOST, 0, CURSE_IMMUN);
add_message(&mage->faction->msgs, new_message(mage->faction,
"magicboost_effect%u:unit%r:region%s:command",
@ -3851,7 +3859,7 @@ sp_babbler(castorder *co)
*
* Wirkung:
* Zeigt die Verzauberungen eines Objekts an (curse->name,
* cures->info). Aus der Differenz Spruchstärke und Curse->vigour
* curse::info). Aus der Differenz Spruchstärke und Curse->vigour
* ergibt sich die Chance den Spruch zu identifizieren ((force -
* c->vigour)*10 + 100 %).
*
@ -3902,7 +3910,7 @@ sp_analysesong_obj(castorder *co)
* Gebiet: Cerddor
* Wirkung:
* Zeigt die Verzauberungen eines Objekts an (curse->name,
* cures->info). Aus der Differenz Spruchstärke und Curse->vigour
* curse::info). Aus der Differenz Spruchstärke und Curse->vigour
* ergibt sich die Chance den Spruch zu identifizieren ((force -
* c->vigour)*10 + 100 %).
*
@ -4014,7 +4022,7 @@ sp_charmingsong(castorder *co)
add_trigger(&mage->faction->attribs, "destroy", trigger_killunit(target));
}
/* sperre ATTACKIERE, GIB PERSON und überspringe Migranten */
create_curse(mage, &target->attribs, C_SLAVE, 0, force, duration, 0, 0);
create_curse(mage, &target->attribs, ct_find("slavery"), force, duration, 0, 0);
/* setze Partei um und lösche langen Befehl aus Sicherheitsgründen */
u_setfaction(target,mage->faction);
@ -4054,7 +4062,7 @@ sp_song_resistmagic(castorder *co)
int force = co->force;
create_curse(mage, &r->attribs, C_SONG_GOODMR, 0,
create_curse(mage, &r->attribs, ct_find("goodmagicresistancezone"),
force, force, mr_bonus, 0);
/* Erfolg melden */
@ -4084,7 +4092,7 @@ sp_song_susceptmagic(castorder *co)
int cast_level = co->level;
int force = co->force;
create_curse(mage, &r->attribs, C_SONG_BADMR, 0,
create_curse(mage, &r->attribs, ct_find("badmagicresistancezone"),
force, force, mr_malus, 0);
add_message(&mage->faction->msgs, new_message(mage->faction,
@ -4203,7 +4211,7 @@ sp_raisepeasantmob(castorder *co)
a->data.ca[1] = 15; /* 15% */
a_add(&u->attribs, a);
create_curse(mage, &r->attribs, C_RIOT, 0, cast_level, anteil, 0, 0);
create_curse(mage, &r->attribs, ct_find("riotzone"), cast_level, anteil, 0, 0);
for (u = r->units; u; u = u->next) freset(u->faction, FL_DH);
for (u = r->units; u; u = u->next ) {
@ -4264,7 +4272,8 @@ sp_migranten(castorder *co)
/* Keine Monstereinheiten */
if (!playerrace(target->race)){
sprintf(buf, "%s kann nicht auf Monster gezaubert werden.", sp->name);
sprintf(buf, "%s kann nicht auf Monster gezaubert werden.",
spell_name(sp, mage->faction->locale));
addmessage(0, mage->faction, buf, MSG_EVENT, ML_WARN);
return 0;
}
@ -4281,7 +4290,7 @@ sp_migranten(castorder *co)
{
sprintf(buf, "%s in %s: 'ZAUBER \"%s\"': So viele Personen übersteigen "
"meine Kräfte.", unitname(mage), regionid(mage->region),
sp->name);
spell_name(sp, mage->faction->locale));
addmessage(0, mage->faction, buf, MSG_MAGIC, ML_WARN);
}
@ -4324,7 +4333,8 @@ sp_migranten(castorder *co)
if (kontaktiert == 0){
sprintf(buf, "%s in %s: 'ZAUBER \"%s\"': Die Einheit %s hat keinen "
"Kontakt mit uns aufgenommen.", unitname(mage),
regionid(mage->region), sp->name, unitname(target));
regionid(mage->region), spell_name(sp, mage->faction->locale)
, unitname(target));
addmessage(0, mage->faction, buf, MSG_MAGIC, ML_MISTAKE);
return 0;
}
@ -4362,7 +4372,7 @@ sp_song_of_peace(castorder *co)
else
duration = lovar(force/2);
create_curse(mage,&r->attribs,C_PEACE,0,force,duration,1,0);
create_curse(mage,&r->attribs, ct_find("peacezone"), force, duration, 1,0);
for (u = r->units; u; u = u->next) freset(u->faction, FL_DH);
for (u = r->units; u; u = u->next ) {
@ -4409,7 +4419,7 @@ sp_generous(castorder *co)
addmessage(0, mage->faction, buf, MSG_MAGIC, ML_MISTAKE);
return 0;
}
create_curse(mage,&r->attribs,C_GENEROUS,0,force,force,2,0);
create_curse(mage,&r->attribs, ct_find("generous"), force,force,2,0);
for (u = r->units; u; u = u->next) freset(u->faction, FL_DH);
for (u = r->units; u; u = u->next ) {
@ -4509,7 +4519,8 @@ sp_pump(castorder *co)
target = pa->param[0]->data.u; /* Zieleinheit */
if (fval(target->race, RCF_UNDEAD)) {
sprintf(buf, "%s kann nicht auf Untote gezaubert werden.", sp->name);
sprintf(buf, "%s kann nicht auf Untote gezaubert werden.",
spell_name(sp, mage->faction->locale));
addmessage(0, mage->faction, buf, MSG_EVENT, ML_WARN);
return 0;
}
@ -4579,7 +4590,8 @@ sp_seduce(castorder *co)
target = pa->param[0]->data.u; /* Zieleinheit */
if (fval(target->race, RCF_UNDEAD)) {
sprintf(buf, "%s kann nicht auf Untote gezaubert werden.", sp->name);
sprintf(buf, "%s kann nicht auf Untote gezaubert werden.",
spell_name(sp, mage->faction->locale));
addmessage(0, mage->faction, buf, MSG_MAGIC, ML_WARN);
return 0;
}
@ -4669,6 +4681,7 @@ static int
sp_calm_monster(castorder *co)
{
int duration;
curse * c;
unit *target;
region *r = co->rt;
unit *mage = (unit *)co->magician;
@ -4685,18 +4698,20 @@ sp_calm_monster(castorder *co)
target = pa->param[0]->data.u; /* Zieleinheit */
if (fval(target->race, RCF_UNDEAD)) {
sprintf(buf, "%s kann nicht auf Untote gezaubert werden.", sp->name);
sprintf(buf, "%s kann nicht auf Untote gezaubert werden.",
spell_name(sp, mage->faction->locale));
addmessage(0, mage->faction, buf, MSG_MAGIC, ML_WARN);
return 0;
}
if (!create_curse(mage, &target->attribs, C_CALM, 0, force, duration,
mage->faction->unique_id, 0)){
c = create_curse(mage, &target->attribs, ct_find("calmmonster"), force, duration,
mage->faction->unique_id, 0);
if (c==NULL) {
report_failure(mage, co->order);
return 0;
}
/* Nur ein Beherrschungszauber pro Unit */
set_curseflag(target->attribs, C_CALM, 0, CURSE_ONLYONE);
curse_setflag(c, CURSE_ONLYONE);
sprintf(buf, "%s besänftigt %s.", unitname(mage), unitname(target));
addmessage(r, mage->faction, buf, MSG_MAGIC, ML_INFO);
@ -4858,7 +4873,7 @@ sp_depression(castorder *co)
int cast_level = co->level;
int power = co->force;
create_curse(mage,&r->attribs,C_DEPRESSION,0,power,power,0,0);
create_curse(mage,&r->attribs, ct_find("depression"), power, power, 0, 0);
for (u = r->units; u; u = u->next) freset(u->faction, FL_DH);
for (u = r->units; u; u = u->next ) {
@ -4948,18 +4963,14 @@ sp_songofAttraction(castorder *co)
{
region *r = co->rt; /* Zauberregion */
unit *mage = (unit *)co->magician;
unit *u;
int cast_level = co->level;
int power = co->force;
region *rn;
faction *f;
int range;
/* int power = co->force; */
/* TODO Wander Effekt */
add_message(&mage->faction->msgs, new_message(mage->faction,
"summon%u:unit%r:region%s:command%u:unit%r:region",
mage, mage->region, strdup(co->order),mage, co->rt));
mage, mage->region, strdup(co->order),mage, r));
return cast_level;
}
@ -5172,7 +5183,7 @@ sp_readmind(castorder *co)
* Kosten: SPC_FIX
* Wirkung:
* Zeigt die Verzauberungen eines Objekts an (curse->name,
* cures->info). Aus der Differenz Spruchstärke und Curse->vigour
* curse::info). Aus der Differenz Spruchstärke und Curse->vigour
* ergibt sich die Chance den Spruch zu identifizieren ((force -
* c->vigour)*10 + 100 %).
*/
@ -5196,7 +5207,7 @@ sp_analyseregionsdream(castorder *co)
* Kosten: SPC_FIX
* Wirkung:
* Zeigt die Verzauberungen eines Objekts an (curse->name,
* cures->info). Aus der Differenz Spruchstärke und Curse->vigour
* curse::info). Aus der Differenz Spruchstärke und Curse->vigour
* ergibt sich die Chance den Spruch zu identifizieren ((force -
* c->vigour)*10 + 100 %).
*/
@ -5242,6 +5253,7 @@ sp_baddreams(castorder *co)
int cast_level = co->level;
int power = co->force;
region *r = co->rt;
curse * c;
/* wirkt erst in der Folgerunde, soll mindestens eine Runde wirken,
* also duration+2 */
@ -5249,8 +5261,8 @@ sp_baddreams(castorder *co)
duration = 2 + rand()%duration;
/* Nichts machen als ein entsprechendes Attribut in die Region legen. */
create_curse(mage, &r->attribs, C_GBDREAM, 0, power, duration, -1, 0);
set_curseflag(r->attribs, C_GBDREAM, 0, CURSE_ISNEW);
c = create_curse(mage, &r->attribs, ct_find("gbdream"), power, duration, -1, 0);
curse_setflag(c, CURSE_ISNEW);
/* Erfolg melden*/
add_message(&mage->faction->msgs, new_message(mage->faction,
@ -5276,6 +5288,7 @@ int
sp_gooddreams(castorder *co)
{
int duration;
curse * c;
region *r = co->rt;
unit *mage = (unit *)co->magician;
int cast_level = co->level;
@ -5285,8 +5298,8 @@ sp_gooddreams(castorder *co)
* also duration+2 */
duration = max(1, power/2); /* Stufe 1 macht sonst mist */
duration = 2 + rand()%duration;
create_curse(mage, &r->attribs, C_GBDREAM, 0, power, duration, 1, 0);
set_curseflag(r->attribs, C_GBDREAM, 0, CURSE_ISNEW);
c = create_curse(mage, &r->attribs, ct_find("gbdream"), power, duration, 1, 0);
curse_setflag(c, CURSE_ISNEW);
/* Erfolg melden*/
add_message(&mage->faction->msgs, new_message(mage->faction,
@ -5392,7 +5405,6 @@ sp_dreamreading(castorder *co)
int
sp_sweetdreams(castorder *co)
{
unit *u;
region *r = co->rt;
unit *mage = (unit *)co->magician;
int cast_level = co->level;
@ -5404,12 +5416,13 @@ sp_sweetdreams(castorder *co)
/* Schleife über alle angegebenen Einheiten */
for (n = 0; n < pa->length; n++) {
curse * c;
unit *u;
/* sollte nie negativ werden */
if (opfer < 1)
break;
if (opfer < 1) break;
if(pa->param[n]->flag == TARGET_RESISTS
|| pa->param[n]->flag == TARGET_NOTFOUND)
if (pa->param[n]->flag == TARGET_RESISTS ||
pa->param[n]->flag == TARGET_NOTFOUND)
continue;
/* Zieleinheit */
@ -5419,8 +5432,8 @@ sp_sweetdreams(castorder *co)
opfer -= men;
/* Nichts machen als ein entsprechendes Attribut an die Einheit legen. */
create_curse(mage,&u->attribs,C_ORC,0,power,duration,5,men);
set_curseflag(u->attribs, C_ORC, 0, CURSE_ISNEW);
c = create_curse(mage,&u->attribs, ct_find("orcish"), power,duration,5,men);
curse_setflag(c, CURSE_ISNEW);
sprintf(buf, "%s verschafft %s ein interessanteres Nachtleben.",
unitname(mage), unitname(u));
@ -5449,9 +5462,8 @@ sp_disturbingdreams(castorder *co)
unit *mage = (unit *)co->magician;
int cast_level = co->level;
int power = co->force;
create_curse(mage, &r->attribs, C_BADLEARN, 0, power, power/6, 10, 0);
set_curseflag(r->attribs, C_BADLEARN, 0, CURSE_ISNEW);
curse * c = create_curse(mage, &r->attribs, ct_find("badlearn"), power, power/6, 10, 0);
curse_setflag(c, CURSE_ISNEW);
sprintf(buf, "%s sorgt für schlechten Schlaf in %s.",
unitname(mage), regionid(r));
@ -5475,17 +5487,17 @@ sp_dream_of_confusion(castorder *co)
rl = all_in_range(r, range);
for(rl2 = rl; rl2; rl2 = rl2->next) {
curse * c;
/* Magieresistenz jeder Region prüfen */
if (target_resists_magic(mage, rl2->region, TYP_REGION, 0)){
report_failure(mage, co->order);
continue;
}
create_curse(mage, &rl2->region->attribs, C_REGCONF,0,
power, duration, cast_level*5, 0);
c = create_curse(mage, &rl2->region->attribs,
ct_find("disorientationzone"), power, duration, cast_level*5, 0);
/* soll der Zauber schon in der Zauberrunde wirken? */
set_curseflag(rl2->region->attribs, C_REGCONF, 0, CURSE_ISNEW);
curse_setflag(c, CURSE_ISNEW);
for (u = rl2->region->units; u; u = u->next) freset(u->faction, FL_DH);
for (u = rl2->region->units; u; u = u->next ) {
@ -5517,7 +5529,7 @@ sp_dream_of_confusion(castorder *co)
*
* Wirkung:
* Zeigt die Verzauberungen eines Objekts an (curse->name,
* cures->info). Aus der Differenz Spruchstärke und Curse->vigour
* curse::info). Aus der Differenz Spruchstärke und Curse->vigour
* ergibt sich die Chance den Spruch zu identifizieren ((force -
* c->vigour)*10 + 100 %).
*
@ -5589,7 +5601,7 @@ sp_itemcloak(castorder *co)
/* Zieleinheit */
target = pa->param[0]->data.u;
create_curse(mage,&target->attribs,C_ITEMCLOAK,0,power,power,0,0);
create_curse(mage,&target->attribs, ct_find("itemcloak"), power,power,0,0);
add_message(&mage->faction->msgs, new_message(mage->faction,
"itemcloak%u:mage%u:target", mage, target));
@ -5647,8 +5659,8 @@ sp_resist_magic_bonus(castorder *co)
m = min(u->number,opfer);
opfer -= m;
create_curse(mage, &u->attribs, C_MAGICRESISTANCE, 0, power, duration,
resistbonus, m);
create_curse(mage, &u->attribs, ct_find("magicresistance"),
power, duration, resistbonus, m);
sprintf(buf, "%s wird kurz von einem magischen Licht umhüllt.",
unitname(u));
@ -5695,7 +5707,7 @@ sp_enterastral(castorder *co)
default:
sprintf(buf, "%s in %s: 'ZAUBER \"%s\"': Dieser Zauber funktioniert "
"nur in der materiellen Welt.", unitname(mage),
regionid(mage->region),sp->name);
regionid(mage->region), spell_name(sp, mage->faction->locale));
addmessage(r, mage->faction, buf, MSG_MAGIC, ML_MISTAKE);
return 0;
}
@ -5703,7 +5715,7 @@ sp_enterastral(castorder *co)
if(!rt) {
sprintf(buf, "%s in %s: 'ZAUBER \"%s\"': Es kann hier kein Kontakt zur "
"Astralwelt hergestellt werden.", unitname(mage),
regionid(mage->region),sp->name);
regionid(mage->region), spell_name(sp, mage->faction->locale));
addmessage(r, mage->faction, buf, MSG_MAGIC, ML_MISTAKE);
return 0;
}
@ -5712,7 +5724,7 @@ sp_enterastral(castorder *co)
is_cursed(ro->attribs, C_ASTRALBLOCK, 0)) {
sprintf(buf, "%s in %s: 'ZAUBER \"%s\"': Es kann kein Kontakt zu "
"dieser astralen Region hergestellt werden.", unitname(mage),
regionid(mage->region),sp->name);
regionid(mage->region), spell_name(sp, mage->faction->locale));
addmessage(r, mage->faction, buf, MSG_MAGIC, ML_MISTAKE);
return 0;
}
@ -5818,7 +5830,7 @@ sp_pullastral(castorder *co)
if(!rl2) {
sprintf(buf, "%s in %s: 'ZAUBER \"%s\"': Es kann kein Kontakt zu "
"dieser Region hergestellt werden.", unitname(mage),
regionid(mage->region),sp->name);
regionid(mage->region), spell_name(sp, mage->faction->locale));
addmessage(r, mage->faction, buf, MSG_MAGIC, ML_MISTAKE);
free_regionlist(rl);
return 0;
@ -5828,7 +5840,7 @@ sp_pullastral(castorder *co)
default:
sprintf(buf, "%s in %s: 'ZAUBER \"%s\"': Dieser Zauber funktioniert "
"nur in der astralen Welt.", unitname(mage),
regionid(mage->region),sp->name);
regionid(mage->region), spell_name(sp, mage->faction->locale));
addmessage(r, mage->faction, buf, MSG_MAGIC, ML_MISTAKE);
return 0;
}
@ -5837,7 +5849,7 @@ sp_pullastral(castorder *co)
is_cursed(ro->attribs, C_ASTRALBLOCK, 0)) {
sprintf(buf, "%s in %s: 'ZAUBER \"%s\"': Es kann kein Kontakt zu "
"dieser Region hergestellt werden.", unitname(mage),
regionid(mage->region),sp->name);
regionid(mage->region), spell_name(sp, mage->faction->locale));
addmessage(r, mage->faction, buf, MSG_MAGIC, ML_MISTAKE);
return 0;
}
@ -6346,8 +6358,8 @@ sp_disruptastral(castorder *co)
}
/* Kontakt unterbinden */
create_curse(mage,&rl2->region->attribs,C_ASTRALBLOCK,0,power,power/3,
100, 0);
create_curse(mage,&rl2->region->attribs, ct_find("astralblock"),
power, power/3, 100, 0);
addmessage(r, 0, "Mächtige Magie verhindert den Kontakt zur Realität.",
MSG_COMMENT, ML_IMPORTANT);
}
@ -6391,7 +6403,7 @@ static int
sp_eternizewall(castorder *co)
{
unit *u;
curse * success;
curse * c;
building *b;
region *r = co->rt;
unit *mage = (unit *)co->magician;
@ -6403,18 +6415,15 @@ sp_eternizewall(castorder *co)
if(pa->param[0]->flag == TARGET_NOTFOUND) return 0;
b = pa->param[0]->data.b;
success = create_curse(mage, &b->attribs, C_NOCOST, 0,
power*power, 1, 0, 0);
c = create_curse(mage, &b->attribs, ct_find("nocost"),
power*power, 1, 0, 0);
if(!success){ /* ist bereits verzaubert */
if(c==NULL) { /* ist bereits verzaubert */
cmistake(mage, strdup(co->order), 206, MSG_MAGIC);
return 0;
}
set_curseflag(b->attribs, C_NOCOST, 0, CURSE_NOAGE);
/* Nur einmal pro Burg möglich */
set_curseflag(b->attribs, C_NOCOST, 0, CURSE_ONLYONE);
curse_setflag(c, CURSE_NOAGE|CURSE_ONLYONE);
/* melden, 1x pro Partei in der Burg */
for (u = r->units; u; u = u->next) freset(u->faction, FL_DH);
@ -6521,7 +6530,8 @@ sp_movecastle(castorder *co)
if(dir == NODIRECTION) {
sprintf(buf, "%s in %s: 'ZAUBER \"%s\"': Ungültige Richtung %s.",
unitname(mage), regionid(mage->region), sp->name,
unitname(mage), regionid(mage->region),
spell_name(sp, mage->faction->locale),
pa->param[1]->data.s);
addmessage(0, mage->faction, buf, MSG_MAGIC, ML_MISTAKE);
return 0;
@ -6530,7 +6540,7 @@ sp_movecastle(castorder *co)
if(b->size > (cast_level-12) * 250) {
sprintf(buf, "%s in %s: 'ZAUBER \"%s\"': Der Elementar ist "
"zu klein, um das Gebäude zu tragen.", unitname(mage),
regionid(mage->region), sp->name);
regionid(mage->region), spell_name(sp, mage->faction->locale));
addmessage(0, mage->faction, buf, MSG_MAGIC, ML_MISTAKE);
return cast_level;
}
@ -6540,7 +6550,8 @@ sp_movecastle(castorder *co)
if(!(terrain[target_region->terrain].flags & LAND_REGION)) {
sprintf(buf, "%s in %s: 'ZAUBER \"%s\"': Der Erdelementar "
"weigert sich, nach %s zu gehen.",
unitname(mage), regionid(mage->region), sp->name,
unitname(mage), regionid(mage->region),
spell_name(sp, mage->faction->locale),
locale_string(mage->faction->locale, directions[dir]));
addmessage(0, mage->faction, buf, MSG_MAGIC, ML_MISTAKE);
return cast_level;
@ -6624,7 +6635,7 @@ sp_flying_ship(castorder *co)
/* mit C_SHIP_NODRIFT haben wir kein Problem */
/* Duration = 1, nur diese Runde */
create_curse(mage, &sh->attribs, C_SHIP_FLYING, 0, power, 1, 0, 0);
create_curse(mage, &sh->attribs, ct_find("flyingship"), power, 1, 0, 0);
/* Da der Spruch nur diese Runde wirkt, brauchen wir kein
* set_cursedisplay() zu benutzten - es sieht eh niemand...
*/
@ -6766,7 +6777,7 @@ sp_antimagiczone(castorder *co)
/* Reduziert die Stärke jedes Spruchs um effect */
effect = cast_level;
create_curse(mage, &r->attribs, C_ANTIMAGICZONE, 0, power, force,
create_curse(mage, &r->attribs, ct_find("antimagiczone"), power, force,
effect, 0);
/* Erfolg melden*/
@ -6809,8 +6820,8 @@ sp_antimagiczone(castorder *co)
* "kc"
*/
int
sp_antimagicshild(castorder *co)
static int
sp_magicrunes(castorder *co)
{
int duration;
unit *mage = (unit *)co->magician;
@ -6827,7 +6838,7 @@ sp_antimagicshild(castorder *co)
b = pa->param[0]->data.b;
/* Magieresistenz der Burg erhöht sich um 20% */
create_curse(mage, &b->attribs, C_RESIST_MAGIC, 0, force,
create_curse(mage, &b->attribs, ct_find("magicrunes"), force,
duration, 20, 0);
/* Erfolg melden */
@ -6841,7 +6852,7 @@ sp_antimagicshild(castorder *co)
ship *sh;
sh = pa->param[0]->data.sh;
/* Magieresistenz des Schiffs erhöht sich um 20% */
create_curse(mage, &sh->attribs, C_RESIST_MAGIC, 0, force,
create_curse(mage, &sh->attribs, ct_find("magicrunes"), force,
duration, 20, 0);
/* Erfolg melden */
@ -6892,7 +6903,7 @@ sp_speed2(castorder *co)
u = pa->param[n]->data.u;
men = min(maxmen,u->number);
create_curse(mage, &u->attribs, C_SPEED, 0, force, dur, 2, men);
create_curse(mage, &u->attribs, ct_find("speed"), force, dur, 2, men);
maxmen -= men;
used += men;
}
@ -7082,7 +7093,7 @@ sp_destroy_curse(castorder *co)
c->vigour = max(0, succ);
if(succ <= 0) {
remove_cursec(ap, c);
remove_curse(ap, c);
add_message(&mage->faction->msgs, new_message(mage->faction,
"destroy_magic_effect%u:unit%r:region%s:command%i:id%s:target",
@ -7440,10 +7451,8 @@ spell spelldaten[] =
/* M_DRUIDE */
{SPL_BLESSEDHARVEST, "Segen der Erde",
"Dieses Ernteritual verbessert die Erträge der arbeitenden Bauern in der "
"Region um ein Silberstück. Je mehr Kraft der Druide investiert, desto "
"länger wirkt der Zauber.",
{SPL_BLESSEDHARVEST, "blessedharvest",
NULL,
NULL,
NULL,
M_DRUIDE,
@ -7459,12 +7468,8 @@ spell spelldaten[] =
patzer
},
{SPL_GWYRRD_EARN_SILVER, "Viehheilung",
"Die Fähigkeiten der Gwyrrd-Magier in der Viehzucht und Heilung sind bei "
"den Bauern sehr begehrt. Grade auf Märkten sind ihre Dienste häufig sehr "
"gefragt. Manch einer mag auch sein Talent dazu nutzen, ein Tier für einen "
"besseren Preis zu verkaufen. Pro Stufe kann der Magier so 50 Silber "
"verdienen.",
{SPL_GWYRRD_EARN_SILVER, "veterinarian",
NULL,
NULL,
NULL,
M_DRUIDE,
@ -10253,7 +10258,7 @@ spell spelldaten[] =
{0, 0, 0},
{0, 0, 0},
{0, 0, 0}},
(spell_f)sp_antimagicshild, patzer
(spell_f)sp_magicrunes, patzer
},

View file

@ -266,4 +266,5 @@ typedef struct wall_data {
extern struct attrib_type at_cursewall;
extern struct attrib_type at_unitdissolve;
#endif

View file

@ -951,43 +951,44 @@ item_modification(const unit *u, skill_t sk, int val)
static int
att_modification(const unit *u, skill_t sk)
{
curse *c;
unit *mage;
int bonus = 0, malus = 0;
attrib * a;
int result = 0;
static boolean init = false;
static const curse_type * skillmod_ct;
static const curse_type * gbdream_ct;
if (!init) {
init = true;
skillmod_ct = ct_find("skillmod");
gbdream_ct = ct_find("gbdream");
}
result += get_curseeffect(u->attribs, C_ALLSKILLS, 0);
result += get_curseeffect(u->attribs, C_SKILL, (int)sk);
if (skillmod_ct) {
curse * c = get_cursex(u->attribs, skillmod_ct, (void*)(int)sk, cmp_cursedata);
result += curse_geteffect(c);
}
/* TODO hier kann nicht mit get/iscursed gearbeitet werden, da nur der
* jeweils erste vom Typ C_GBDREAM zurückgegen wird, wir aber alle
* durchsuchen und aufaddieren müssen */
if (is_cursed(u->region->attribs, C_GBDREAM, 0)){
attrib *a;
int bonus = 0, malus = 0;
int mod;
a = a_select(u->region->attribs, packids(C_GBDREAM, 0), cmp_oldcurse);
while(a) {
c = (curse*)a->data.v;
mage = c->magician;
mod = c->effect;
/* wir suchen jeweils den größten Bonus und den größten Malus */
if (mod > 0
&& (mage == NULL
|| allied(mage, u->faction, HELP_GUARD)))
{
if (mod > bonus ) bonus = mod;
} else if (mod < 0
&& (mage == NULL
|| !allied(mage, u->faction, HELP_GUARD)))
{
if (mod < malus ) malus = mod;
}
a = a_select(a->next, packids(C_GBDREAM, 0), cmp_oldcurse);
a = a_select(u->region->attribs, gbdream_ct, cmp_cursetype);
while (a) {
curse * c = (curse*)a->data.v;
int mod = c->effect;
unit * mage = c->magician;
/* wir suchen jeweils den größten Bonus und den größten Malus */
if (mod>0 && (mage==NULL || allied(mage, u->faction, HELP_GUARD)))
{
if (mod > bonus ) bonus = mod;
} else if (mod < 0 &&
(mage == NULL || !allied(mage, u->faction, HELP_GUARD)))
{
if (mod < malus ) malus = mod;
}
result = result + bonus + malus;
a = a_select(a->next, gbdream_ct, cmp_cursetype);
}
result = result + bonus + malus;
return result;
}

View file

@ -118,6 +118,10 @@ SOURCE=.\weather.h
# End Source File
# Begin Source File
SOURCE=.\xecmd.h
# End Source File
# Begin Source File
SOURCE=.\xmas.h
# End Source File
# Begin Source File
@ -163,6 +167,10 @@ SOURCE=.\weather.c
# End Source File
# Begin Source File
SOURCE=.\xecmd.c
# End Source File
# Begin Source File
SOURCE=.\xmas.c
# End Source File
# Begin Source File

View file

@ -156,11 +156,11 @@ alp_findet_opfer(unit *alp, region *r)
*/
a_removeall(&alp->attribs, &at_eventhandler);
/* Alp umwandeln in Curse */
c = create_curse(mage, &opfer->attribs, C_ALLSKILLS, 0, 0, 0, -2, opfer->number);
c = create_curse(mage, &opfer->attribs, ct_find("worse"), 0, 0, -2, opfer->number);
/* solange es noch keine spezielle alp-Antimagie gibt, reagiert der
* auch auf normale */
/* set_curseflag(opfer->attribs, C_ALLSKILLS, 0, CURSE_NOAGE+CURSE_IMMUN); */
set_curseflag(opfer->attribs, C_ALLSKILLS, 0, CURSE_NOAGE);
curse_setflag(c, CURSE_NOAGE);
destroy_unit(alp);
{

View file

@ -26,18 +26,13 @@
struct curse_type;
extern const struct curse_type ct_firewall;
extern void ct_register(const struct curse_type * ct);
extern curse_type cursedaten[MAXCURSE];
void
register_spells(void)
{
int i;
/* sp_summon_alp */
register_alp();
/* init_firewall(); */
ct_register(&ct_firewall);
for (i=0;i!=MAXCURSE;++i) {
ct_register(&cursedaten[i]);
}
register_curses();
}

View file

@ -39,8 +39,7 @@
typedef struct createcurse_data {
struct unit * mage;
struct unit * target;
curse_t id;
int id2;
const curse_type * type;
int vigour;
int duration;
int effect;
@ -68,7 +67,7 @@ createcurse_handle(trigger * t, void * data)
createcurse_data * td = (createcurse_data*)t->data.v;
if (td->mage!=NULL && td->target!=NULL) {
create_curse(td->mage, &td->target->attribs,
td->id, td->id2, td->vigour, td->duration, td->effect, td->men);
td->type, td->vigour, td->duration, td->effect, td->men);
} else {
log_error(("could not perform createcurse::handle()\n"));
}
@ -82,7 +81,7 @@ createcurse_write(const trigger * t, FILE * F)
createcurse_data * td = (createcurse_data*)t->data.v;
fprintf(F, "%s ", itoa36(td->mage->no));
fprintf(F, "%s ", itoa36(td->target->no));
fprintf(F, "%d %d %d %d %d %d ", td->id, td->id2, td->vigour, td->duration, td->effect, td->men);
fprintf(F, "%s %d %d %d %d ", td->type->cname, td->vigour, td->duration, td->effect, td->men);
}
static int
@ -102,7 +101,15 @@ createcurse_read(trigger * t, FILE * F)
td->target = findunit(i);
if (td->target==NULL) ur_add((void*)i, (void**)&td->target, resolve_unit);
fscanf(F, "%d %d %d %d %d %d ", &td->id, &td->id2, &td->vigour, &td->duration, &td->effect, &td->men);
if (global.data_version<CURSETYPE_VERSION) {
int id1, id2;
fscanf(F, "%d %d %d %d %d %d ", &id1, &id2, &td->vigour, &td->duration, &td->effect, &td->men);
assert(id2==0);
td->type = ct_find(oldcursename(id1));
} else {
fscanf(F, "%s %d %d %d %d ", zText, &td->vigour, &td->duration, &td->effect, &td->men);
td->type = ct_find(zText);
}
return AT_READ_OK;
}
@ -117,15 +124,14 @@ trigger_type tt_createcurse = {
trigger *
trigger_createcurse(struct unit * mage, struct unit * target,
curse_t id, int id2, int vigour, int duration,
int effect, int men)
const curse_type * ct, int vigour, int duration,
int effect, int men)
{
trigger * t = t_new(&tt_createcurse);
createcurse_data * td = (createcurse_data*)t->data.v;
td->mage = mage;
td->target = target;
td->id = id;
td->id2 = id2;
td->type = ct;
td->vigour = vigour;
td->duration = duration;
td->effect = effect;

View file

@ -16,6 +16,7 @@
#define CREATECURSE_H
/* all types we use are defined here to reduce dependencies */
struct curse_type;
struct trigger_type;
struct trigger;
struct region;
@ -24,6 +25,6 @@ struct unit;
extern struct trigger_type tt_createcurse;
extern struct trigger * trigger_createcurse(struct unit * mage, struct unit * target, curse_t id, int id2, int vigour, int duration, int effect, int men);
extern struct trigger * trigger_createcurse(struct unit * mage, struct unit * target, const struct curse_type * ct, int vigour, int duration, int effect, int men);
#endif

View file

@ -28,7 +28,7 @@ extern unsigned int locale_hashkey(const struct locale * lang);
extern const char * locale_name(const struct locale * lang);
extern const char * reverse_lookup(const struct locale * lang, const char * str);
extern const char * mkname(const char * name, const char * space);
extern const char * mkname(const char * namespc, const char * key);
extern void debug_language(const char * log);

View file

@ -610,8 +610,8 @@ main(int argc, char *argv[])
game_init();
#if defined(BETA_CODE)
/* xml_writeships(); */
xml_writebuildings();
/* xml_writeitems("items.xml"); */
/* xml_writebuildings(); */
xml_writeitems("items.xml");
return 0;
#endif

View file

@ -10,32 +10,32 @@
<text locale="de">Tresen</text>
<text locale="en">counter </text>
</string>
<string name="wenige">
<text locale="de">wenige</text>
<text locale="en">few </text>
</string>
<string name="viele">
<text locale="de">viele</text>
<text locale="en">many </text>
</string>
<string name="relativ viele">
<text locale="de">relativ viele</text>
<text locale="en">rather many </text>
</string>
<string name="sehr wenige">
<text locale="de">sehr wenige</text>
<text locale="en">very few </text>
</string>
<string name="sehr viele">
<text locale="de">sehr viele</text>
<text locale="en">a great many </text>
</string>
<string name="prefix_Dunkel">
<text locale="de">Dunkel</text>
<text locale="en">dark </text>
@ -1172,10 +1172,12 @@
<text locale="de">Feuerwerke</text>
</string>
<string name="lebkuchenherz">
<text locale="de">Lebkuchenherz mit der Aufschrift 'Erz und Stein, das ist fein'</text>
<text locale="de">Lebkuchenherz mit der Aufschrift 'Erz und
Stein, das ist fein'</text>
</string>
<string name="lebkuchenherz_p">
<text locale="de">Lebkuchenherzen mit der Aufschrift 'Erz und Stein, das ist fein'</text>
<text locale="de">Lebkuchenherzen mit der Aufschrift 'Erz und
Stein, das ist fein'</text>
</string>
<string name="questkey1">
<text locale="de">Achatener Schlüssel</text>
@ -1551,7 +1553,7 @@
<string name="ZAUBER">
<text locale="de">ZAUBER</text>
</string>
<string name="XEPOTION">
<text locale="de">XETRANK</text>
</string>
@ -2158,7 +2160,9 @@
<text locale="de">beschädigt</text>
</string>
<string name="nr_youaredead">
<text locale="de">Unglücklicherweise wurde deine Partei ausgelöscht. Du kannst gerne an einer anderen Stelle wieder einsteigen. Melde Dich einfach wieder an.</text>
<text locale="de">Unglücklicherweise wurde deine Partei
ausgelöscht. Du kannst gerne an einer anderen Stelle wieder
einsteigen. Melde Dich einfach wieder an.</text>
</string>
<string name="nr_skills">
<text locale="de">Talente</text>
@ -2200,16 +2204,23 @@
<comment>report newbie info</comment>
<string name="nr_nmr">
<text locale="de">Deine Partei hat letzte Runde keinen Zug abgegeben!</text>
<text locale="de">Deine Partei hat letzte Runde keinen Zug
abgegeben!</text>
</string>
<namespace name="info">
<string name="mistletoe">
<text locale="de">Im Mistelzweig ruht eine magische Kraft
besonderer Art. Der Anwender wird von seinen Feinden in Frieden
gelassen, eine Woche lang läßt jeder Kämpfer ihn unbeschadet
<text locale="de">Im Mistelzweig ruht eine magische
Kraft
besonderer Art. Der Anwender wird von seinen Feinden
in Frieden
gelassen, eine Woche lang läßt jeder Kämpfer ihn
unbeschadet
seines Weges ziehen.</text>
<text locale="en">The magical misteltoe has a wonderous property: It's use will make one person able to escape unharmed from every conflict, no enemy will lay hand on the bearer for one week.</text>
<text locale="en">The magical misteltoe has a
wonderous property: It's use will make one person able
to escape unharmed from every conflict, no enemy will
lay hand on the bearer for one week.</text>
</string>
</namespace>
<namespace name="race">
@ -3011,7 +3022,7 @@
<text locale="de">Schattendrachen</text>
<text locale="en">shadow dragon</text>
</string>
<string name="shadowbat">
<text locale="de">Todesflatter</text>
<text locale="en">darkbat</text>
@ -3028,7 +3039,7 @@
<text locale="de">Todesflatter</text>
<text locale="en">darkbat</text>
</string>
<string name="nightmare">
<text locale="de">Alptraum</text>
<text locale="en">nightmare</text>
@ -3045,7 +3056,7 @@
<text locale="de">Alptraum</text>
<text locale="en">nightmare</text>
</string>
<string name="vampunicorn">
<text locale="de">Nachteinhorn</text>
<text locale="en">vampiric unicorn</text>
@ -3300,7 +3311,7 @@
<text locale="de">Altork</text>
<text locale="en">oldorc</text>
</string>
<string name="snotling">
<text locale="de">Snotling</text>
<text locale="en">snotling</text>
@ -3317,7 +3328,7 @@
<text locale="de">Snotling</text>
<text locale="en">snotling</text>
</string>
<string name="uruk">
<text locale="de">Ork</text>
<text locale="en">orc</text>
@ -3409,4 +3420,44 @@
<text locale="en">exhausted</text>
</string>
</namespace>
<namespace name="spell">
<string name="blessedharvest">
<text locale="de">Segen der Erde</text>
<text locale="en">Blessed Harvest</text>
</string>
<string name="veterinarian">
<text locale="de">Viehheilung</text>
<text locale="en">Cattle Healing</text>
</string>
</namespace>
<namespace name="spellinfo">
<string name="blessedharvest">
<text locale="de">Dieses Ernteritual verbessert die
Erträge der arbeitenden Bauern in der Region um ein
Silberstück. Je mehr Kraft der Druide investiert,
desto länger wirkt der Zauber.</text>
<text locale="en">This harvest ritual increases the
income of each working peasant by one silver piece.
The more power the druid invests, the longer the spell
lasts.</text>
</string>
<string name="veterinarian">
<text locale="de">Die Fähigkeiten der Gwyrrd-Magier in
der Viehzucht und Heilung sind bei den Bauern sehr
begehrt. Grade auf Märkten sind ihre Dienste häufig
sehr gefragt. Manch einer mag auch sein Talent dazu
nutzen, ein Tier für einen besseren Preis zu
verkaufen. Pro Stufe kann der Magier so 50 Silber
verdienen.</text>
<text locale="en">The abilities of the mages of Gwyrrd
concerning the breeding and healing of cattle are
highly appreciated among the peasants. Especially at
the markets, their services are demanded frequently.
Some of them also use their talents to sell an animal
at a higher price. A mage can earn 50 silver pieces
per level in this way.</text>
</string>
</namespace>
</strings>