From 52aa6bccc267279e5f5c9cb4d55591c8a7a47a10 Mon Sep 17 00:00:00 2001 From: Enno Rehling Date: Sun, 6 May 2001 21:49:16 +0000 Subject: [PATCH] updates vom beta-branch nach dev-version --- src/common/gamecode/economy.c | 5 +- src/common/gamecode/monster.c | 2 +- src/common/gamecode/study.c | 392 +++++++++++++++++----------------- src/common/kernel/battle.c | 10 +- src/common/kernel/build.c | 6 +- src/common/kernel/magic.c | 6 +- src/common/kernel/reports.c | 16 +- src/common/kernel/spell.c | 110 +++++++++- src/common/kernel/spell.h | 1 + src/common/spells/alp.c | 9 +- src/common/util/goodies.c | 4 +- src/common/util/goodies.h | 9 +- src/doc/spells_uebersicht.txt | 3 +- src/eressea/korrektur.c | 3 +- src/mapper/map_units.c | 4 +- src/res/de/messages.txt | 3 + 16 files changed, 369 insertions(+), 214 deletions(-) diff --git a/src/common/gamecode/economy.c b/src/common/gamecode/economy.c index 531a8c9f6..e842be559 100644 --- a/src/common/gamecode/economy.c +++ b/src/common/gamecode/economy.c @@ -2843,8 +2843,9 @@ produce(void) todo = igetkeyword(u->thisorder, u->faction->locale); if (todo == NOKEYWORD) continue; - if (rterrain(r) == T_OCEAN && u->race != RC_AQUARIAN && - todo != K_STEAL && todo != K_SPY && todo != K_SABOTAGE) + if (rterrain(r) == T_OCEAN && u->race != RC_AQUARIAN + && !(race[u->race].flags & RCF_SWIM) + && todo != K_STEAL && todo != K_SPY && todo != K_SABOTAGE) continue; switch (todo) { diff --git a/src/common/gamecode/monster.c b/src/common/gamecode/monster.c index 0eb2eae19..0bcbfbf6e 100644 --- a/src/common/gamecode/monster.c +++ b/src/common/gamecode/monster.c @@ -524,7 +524,7 @@ monster_seeks_target(region *r, unit *u) switch( u->race ) { case RC_ALP: - if( !(u->age % 2) ) /* bewegt sich nur jede zweite Runde */ + if( (u->age % 2) ) /* bewegt sich nur jede zweite Runde */ d = NODIRECTION; break; default: diff --git a/src/common/gamecode/study.c b/src/common/gamecode/study.c index d554ea585..90e4eb0cc 100644 --- a/src/common/gamecode/study.c +++ b/src/common/gamecode/study.c @@ -415,122 +415,127 @@ learn(void) /* lernen nach lehren */ - for (r = regions; r; r = r->next) - for (u = r->units; u; u = u->next) - if (rterrain(r) != T_OCEAN || u->race == RC_AQUARIAN) - if (igetkeyword(u->thisorder, u->faction->locale) == K_STUDY) { - double multi = 1.0; - attrib * a = NULL; - int money = 0; - int maxalchemy = 0; - if (rterrain(r) == T_GLACIER && u->race == RC_INSECT - && !is_cursed(u->attribs, C_KAELTESCHUTZ,0)){ - continue; - } - if (attacked(u)) { - cmistake(u, findorder(u, u->thisorder), 52, MSG_PRODUCE); - continue; - } + for (r = regions; r; r = r->next) { + for (u = r->units; u; u = u->next) { + if (rterrain(r) == T_OCEAN){ + /* sonderbehandlung aller die auf Ozeanen lernen können */ + if (u->race != RC_AQUARIAN + && !(race[u->race].flags & RCF_SWIM)) { + continue; + } + } + if (igetkeyword(u->thisorder, u->faction->locale) == K_STUDY) { + double multi = 1.0; + attrib * a = NULL; + int money = 0; + int maxalchemy = 0; + if (rterrain(r) == T_GLACIER && u->race == RC_INSECT + && !is_cursed(u->attribs, C_KAELTESCHUTZ,0)){ + continue; + } + if (attacked(u)) { + cmistake(u, findorder(u, u->thisorder), 52, MSG_PRODUCE); + continue; + } + + i = getskill(u->faction->locale); - i = getskill(u->faction->locale); + if (i < 0) { + cmistake(u, findorder(u, u->thisorder), 77, MSG_EVENT); + continue; + } + /* Hack: Talente mit Malus -99 können nicht gelernt werden */ + if (race[u->race].bonus[i] == -99) { + cmistake(u, findorder(u, u->thisorder), 77, MSG_EVENT); + continue; + } + if ((race[u->race].flags & RCF_NOLEARN)) { + sprintf(buf, "%s können nichts lernen", race[u->race].name[1]); + mistake(u, u->thisorder, buf, MSG_EVENT); + continue; + } else { + struct building * b = inside_building(u); + const struct building_type * btype = b?b->type:NULL; - if (i < 0) { - cmistake(u, findorder(u, u->thisorder), 77, MSG_EVENT); + p = studycost = study_cost(u,i); + a = a_find(u->attribs, &at_learning); + + if (btype == &bt_academy) { + studycost = max(50, studycost * 2); + } + } + if (i == SK_MAGIC) { + if (u->number > 1){ + cmistake(u, findorder(u, u->thisorder), 106, MSG_MAGIC); continue; } - /* Hack: Talente mit Malus -99 können nicht gelernt werden */ - if (race[u->race].bonus[i] == -99) { - cmistake(u, findorder(u, u->thisorder), 77, MSG_EVENT); - continue; - } - if ((race[u->race].flags & RCF_NOLEARN)) { - sprintf(buf, "%s können nichts lernen", race[u->race].name[1]); - mistake(u, u->thisorder, buf, MSG_EVENT); - continue; - } else { - struct building * b = inside_building(u); - const struct building_type * btype = b?b->type:NULL; - - p = studycost = study_cost(u,i); - a = a_find(u->attribs, &at_learning); - - if (btype == &bt_academy) { - studycost = max(50, studycost * 2); - } - } - if (i == SK_MAGIC){ - if (u->number > 1){ - cmistake(u, findorder(u, u->thisorder), 106, MSG_MAGIC); - continue; - } - if (is_familiar(u)){ - /* Vertraute zählen nicht zu den Magiern einer Partei, - * können aber nur Graue Magie lernen */ - mtyp = M_GRAU; - if (!get_skill(u, SK_MAGIC)){ - create_mage(u, mtyp); - } - } else if (!get_skill(u, SK_MAGIC)){ - /* Die Einheit ist noch kein Magier */ - if (count_skill(u->faction, SK_MAGIC) + u->number > - max_skill(u->faction, SK_MAGIC)) - { - sprintf(buf, "Es kann maximal %d Magier pro Partei geben", - max_skill(u->faction, SK_MAGIC)); - mistake(u, u->thisorder, buf, MSG_EVENT); - continue; - } - mtyp = getmagicskill(); - if (mtyp == M_NONE || mtyp == M_GRAU) { - /* wurde kein Magiegebiet angegeben, wird davon - * ausgegangen, daß das normal gelernt werden soll */ - if(u->faction->magiegebiet != 0) { - mtyp = u->faction->magiegebiet; - } else { - /* Es wurde kein Magiegebiet angegeben und die Partei - * hat noch keins gewählt. */ - cmistake(u, findorder(u, u->thisorder), 178, MSG_MAGIC); - continue; - } - } - if (mtyp != u->faction->magiegebiet){ - /* Es wurde versucht, ein anderes Magiegebiet zu lernen - * als das der Partei */ - if (u->faction->magiegebiet != 0){ - cmistake(u, findorder(u, u->thisorder), 179, MSG_MAGIC); - continue; - } else { - /* Lernt zum ersten mal Magie und legt damit das - * Magiegebiet der Partei fest */ - u->faction->magiegebiet = mtyp; - } - } + if (is_familiar(u)){ + /* Vertraute zählen nicht zu den Magiern einer Partei, + * können aber nur Graue Magie lernen */ + mtyp = M_GRAU; + if (!get_skill(u, SK_MAGIC)){ create_mage(u, mtyp); - } else { - /* ist schon ein Magier und kein Vertrauter */ - if(u->faction->magiegebiet == 0){ - /* die Partei hat noch kein Magiegebiet gewählt. */ - mtyp = getmagicskill(); - if (mtyp == M_NONE){ - cmistake(u, findorder(u, u->thisorder), 178, MSG_MAGIC); - continue; - } else { - /* Legt damit das Magiegebiet der Partei fest */ - u->faction->magiegebiet = mtyp; - } - } } - } - if (i == SK_ALCHEMY) { - maxalchemy = eff_skill(u, SK_ALCHEMY, r); - if (get_skill(u, SK_ALCHEMY)==0 - && count_skill(u->faction, SK_ALCHEMY) + u->number > - max_skill(u->faction, SK_ALCHEMY)) { - sprintf(buf, "Es kann maximal %d Alchemisten pro Partei geben", - max_skill(u->faction, SK_ALCHEMY)); + } else if (!get_skill(u, SK_MAGIC)){ + /* Die Einheit ist noch kein Magier */ + if (count_skill(u->faction, SK_MAGIC) + u->number > + max_skill(u->faction, SK_MAGIC)) + { + sprintf(buf, "Es kann maximal %d Magier pro Partei geben", + max_skill(u->faction, SK_MAGIC)); mistake(u, u->thisorder, buf, MSG_EVENT); continue; } + mtyp = getmagicskill(); + if (mtyp == M_NONE || mtyp == M_GRAU) { + /* wurde kein Magiegebiet angegeben, wird davon + * ausgegangen, daß das normal gelernt werden soll */ + if(u->faction->magiegebiet != 0) { + mtyp = u->faction->magiegebiet; + } else { + /* Es wurde kein Magiegebiet angegeben und die Partei + * hat noch keins gewählt. */ + cmistake(u, findorder(u, u->thisorder), 178, MSG_MAGIC); + continue; + } + } + if (mtyp != u->faction->magiegebiet){ + /* Es wurde versucht, ein anderes Magiegebiet zu lernen + * als das der Partei */ + if (u->faction->magiegebiet != 0){ + cmistake(u, findorder(u, u->thisorder), 179, MSG_MAGIC); + continue; + } else { + /* Lernt zum ersten mal Magie und legt damit das + * Magiegebiet der Partei fest */ + u->faction->magiegebiet = mtyp; + } + } + create_mage(u, mtyp); + } else { + /* ist schon ein Magier und kein Vertrauter */ + if(u->faction->magiegebiet == 0){ + /* die Partei hat noch kein Magiegebiet gewählt. */ + mtyp = getmagicskill(); + if (mtyp == M_NONE){ + cmistake(u, findorder(u, u->thisorder), 178, MSG_MAGIC); + continue; + } else { + /* Legt damit das Magiegebiet der Partei fest */ + u->faction->magiegebiet = mtyp; + } + } + } + } + if (i == SK_ALCHEMY) { + maxalchemy = eff_skill(u, SK_ALCHEMY, r); + if (get_skill(u, SK_ALCHEMY)==0 + && count_skill(u->faction, SK_ALCHEMY) + u->number > + max_skill(u->faction, SK_ALCHEMY)) { + sprintf(buf, "Es kann maximal %d Alchemisten pro Partei geben", + max_skill(u->faction, SK_ALCHEMY)); + mistake(u, u->thisorder, buf, MSG_EVENT); + continue; } if (is_migrant(u) && (i == SK_MAGIC || i == SK_ALCHEMY || i == SK_TACTICS @@ -543,106 +548,109 @@ learn(void) continue; } } - if (studycost) { - money = get_pooled(u, r, R_SILVER); - money = min(money, studycost * u->number); - } - if (money < studycost * u->number) { - studycost = p; /* Ohne Uni? */ - money = min(money, studycost); - if (p>0 && money < studycost * u->number) { + } + if (studycost) { + money = get_pooled(u, r, R_SILVER); + money = min(money, studycost * u->number); + } + if (money < studycost * u->number) { + studycost = p; /* Ohne Uni? */ + money = min(money, studycost); + if (p>0 && money < studycost * u->number) { #ifdef PARTIAL_STUDY - cmistake(u, findorder(u, u->thisorder), 65, MSG_EVENT); - multi = money / (double)(studycost * u->number); + cmistake(u, findorder(u, u->thisorder), 65, MSG_EVENT); + multi = money / (double)(studycost * u->number); #else - cmistake(u, findorder(u, u->thisorder), 65, MSG_EVENT); - continue; /* nein, Silber reicht auch so nicht */ + cmistake(u, findorder(u, u->thisorder), 65, MSG_EVENT); + continue; /* nein, Silber reicht auch so nicht */ #endif - } } + } - if (a==NULL) a = a_add(&u->attribs, a_new(&at_learning)); - - if (money>0) { - use_pooled(u, r, R_SILVER, money); - add_message(&u->faction->msgs, new_message(u->faction, - "studycost%u:unit%r:region%i:cost%t:skill", - u, u->region, money, i)); - } - - if (get_effect(u, oldpotiontype[P_WISE])) { - l = min(u->number, get_effect(u, oldpotiontype[P_WISE])); - a->data.i += l * 10; - change_effect(u, oldpotiontype[P_WISE], -l); - } - if (get_effect(u, oldpotiontype[P_FOOL])) { - l = min(u->number, get_effect(u, oldpotiontype[P_FOOL])); - a->data.i -= l * 30; - change_effect(u, oldpotiontype[P_FOOL], -l); - } - - warrior_skill = fspecial(u->faction, FS_WARRIOR); - if(warrior_skill > 0) { - if(i == SK_CROSSBOW || i == SK_LONGBOW - || i == SK_CATAPULT || i == SK_SWORD || i == SK_SPEAR - || i == SK_AUSDAUER || i == SK_WEAPONLESS) - { - a->data.i += u->number * (5+warrior_skill*5); - } else { - a->data.i -= u->number * (5+warrior_skill*5); - a->data.i = max(0, a->data.i); - } - } - - if (p != studycost) { - /* ist_in_gebaeude(r, u, BT_UNIVERSITAET) == 1) { */ - /* p ist Kosten ohne Uni, studycost mit; wenn - * p!=studycost, ist die Einheit zwangsweise - * in einer Uni */ - a->data.i += u->number * 10; - } - if (is_cursed(r->attribs,C_BADLEARN,0)) { - a->data.i -= u->number * 10; + if (a==NULL) a = a_add(&u->attribs, a_new(&at_learning)); + if (money>0) { + use_pooled(u, r, R_SILVER, money); + add_message(&u->faction->msgs, + new_message(u->faction, + "studycost%u:unit%r:region%i:cost%t:skill", + u, u->region, money, i)); + } + + if (get_effect(u, oldpotiontype[P_WISE])) { + l = min(u->number, get_effect(u, oldpotiontype[P_WISE])); + a->data.i += l * 10; + change_effect(u, oldpotiontype[P_WISE], -l); + } + if (get_effect(u, oldpotiontype[P_FOOL])) { + l = min(u->number, get_effect(u, oldpotiontype[P_FOOL])); + a->data.i -= l * 30; + change_effect(u, oldpotiontype[P_FOOL], -l); + } + + warrior_skill = fspecial(u->faction, FS_WARRIOR); + if(warrior_skill > 0) { + if(i == SK_CROSSBOW || i == SK_LONGBOW + || i == SK_CATAPULT || i == SK_SWORD || i == SK_SPEAR + || i == SK_AUSDAUER || i == SK_WEAPONLESS) + { + a->data.i += u->number * (5+warrior_skill*5); + } else { + a->data.i -= u->number * (5+warrior_skill*5); + a->data.i = max(0, a->data.i); } + } + + if (p != studycost) { + /* ist_in_gebaeude(r, u, BT_UNIVERSITAET) == 1) { */ + /* p ist Kosten ohne Uni, studycost mit; wenn + * p!=studycost, ist die Einheit zwangsweise + * in einer Uni */ + a->data.i += u->number * 10; + } + if (is_cursed(r->attribs,C_BADLEARN,0)) { + a->data.i -= u->number * 10; + } #ifdef SKILLFIX_SAVE - if (a && a->data.i) { - int skill = get_skill(u, (skill_t)i); - skillfix(u, (skill_t)i, skill, - (int)(u->number * 30 * multi), a->data.i); - } + if (a && a->data.i) { + int skill = get_skill(u, (skill_t)i); + skillfix(u, (skill_t)i, skill, + (int)(u->number * 30 * multi), a->data.i); + } #endif - + #ifdef RANDOMIZED_LEARNING - change_skill(u, (skill_t)i, (int)((u->number * dice(2,30) + a->data.i) * multi)); + change_skill(u, (skill_t)i, (int)((u->number * dice(2,30) + a->data.i) * multi)); #else - change_skill(u, (skill_t)i, (int)((u->number * 30 + a->data.i) * multi)); + change_skill(u, (skill_t)i, (int)((u->number * 30 + a->data.i) * multi)); #endif - if (a) { - a_remove(&u->attribs, a); - a = NULL; - } + if (a) { + a_remove(&u->attribs, a); + a = NULL; + } - /* Anzeigen neuer Tränke */ - /* Spruchlistenaktualiesierung ist in Regeneration */ + /* Anzeigen neuer Tränke */ + /* Spruchlistenaktualiesierung ist in Regeneration */ - if (i == SK_ALCHEMY) { - const potion_type * ptype; - faction * f = u->faction; - int skill = eff_skill(u, SK_ALCHEMY, r); - if (skill>maxalchemy) { - for (ptype=potiontypes; ptype; ptype=ptype->next) { - if (skill == ptype->level * 2) { - attrib * a = a_find(f->attribs, &at_showitem); - while (a && a->data.v != ptype) a=a->nexttype; - if (!a) { - a = a_add(&f->attribs, a_new(&at_showitem)); - a->data.v = (void*) ptype->itype; - } + if (i == SK_ALCHEMY) { + const potion_type * ptype; + faction * f = u->faction; + int skill = eff_skill(u, SK_ALCHEMY, r); + if (skill>maxalchemy) { + for (ptype=potiontypes; ptype; ptype=ptype->next) { + if (skill == ptype->level * 2) { + attrib * a = a_find(f->attribs, &at_showitem); + while (a && a->data.v != ptype) a=a->nexttype; + if (!a) { + a = a_add(&f->attribs, a_new(&at_showitem)); + a->data.v = (void*) ptype->itype; } } } } } + } + } + } } @@ -665,8 +673,10 @@ teaching(void) if (u->race == RC_SPELL || fval(u, FL_LONGACTION)) continue; - if (rterrain(r) == T_OCEAN && u->race != RC_AQUARIAN) - continue; + if (rterrain(r) == T_OCEAN + && u->race != RC_AQUARIAN + && !(race[u->race].flags & RCF_SWIM)) + continue; if (rterrain(r) == T_GLACIER && u->race == RC_INSECT && !is_cursed(u->attribs, C_KAELTESCHUTZ,0)) diff --git a/src/common/kernel/battle.c b/src/common/kernel/battle.c index 3fa98cd33..a1ae48a6a 100644 --- a/src/common/kernel/battle.c +++ b/src/common/kernel/battle.c @@ -1,6 +1,6 @@ /* vi: set ts=2: * - * + * * Eressea PB(E)M host Copyright (C) 1998-2000 * Christian Schlittchen (corwin@amber.kn-bremen.de) * Katja Zedel (katze@felidae.kn-bremen.de) @@ -594,11 +594,19 @@ contest(int skilldiff, armor_t ar, armor_t sh) /* Hardcodet, muß geändert werden. */ +#ifdef OLD_ARMOR if (ar != AR_NONE) mod *= (1 - armordata[ar].penalty); if (sh != AR_NONE) mod *= (1 - armordata[sh].penalty); vw = (int) (vw * mod); +#else + if (ar != AR_NONE) + mod *= (1 + armordata[ar].penalty); + if (sh != AR_NONE) + mod *= (1 + armordata[sh].penalty); + vw = (int)(100 - ((100 - vw) * mod)); +#endif do { p = rand() % 100; diff --git a/src/common/kernel/build.c b/src/common/kernel/build.c index 122c624af..34d9a2036 100644 --- a/src/common/kernel/build.c +++ b/src/common/kernel/build.c @@ -630,7 +630,11 @@ build(unit * u, const construction * ctype, int completed, int want) } /* n = maximum buildable size */ - n = skills / type->minskill; + if(type->minskill > 1) { + n = skills / type->minskill; + } else { + n = skills; + } itm = *i_find(&u->items, olditemtype[I_RING_OF_NIMBLEFINGER]); if (itm!=NULL) i = itm->number; if (i>0) { diff --git a/src/common/kernel/magic.c b/src/common/kernel/magic.c index ab8d006df..d756687fb 100644 --- a/src/common/kernel/magic.c +++ b/src/common/kernel/magic.c @@ -636,7 +636,7 @@ set_combatspell(unit *u, spell *sp, const char * cmd, int level) if (!m) return; /* knowsspell prüft auf ist_magier, ist_spruch, kennt_spruch */ - if (!sp || !knowsspell(u->region, u, sp)) { + if (knowsspell(u->region, u, sp) == false){ /* Fehler 'Spell not found' */ cmistake(u, cmd, 173, MSG_MAGIC); return; @@ -2801,7 +2801,9 @@ magic(void) * normalerweise nur Meermenschen, ausgenommen explizit als * OCEANCASTABLE deklarierte Sprüche */ if (rterrain(r) == T_OCEAN) { - if (u->race != RC_AQUARIAN && !(sp->sptyp & OCEANCASTABLE)) { + if (u->race != RC_AQUARIAN + && !(race[u->race].flags & RCF_SWIM) + && !(sp->sptyp & OCEANCASTABLE)) { continue; } /* Auf bewegenden Schiffen kann man nur explizit als diff --git a/src/common/kernel/reports.c b/src/common/kernel/reports.c index f1dd71b9b..ea6d20378 100644 --- a/src/common/kernel/reports.c +++ b/src/common/kernel/reports.c @@ -428,8 +428,14 @@ bufunit(const faction * f, const unit * u, int indent, int mode) dh=0; if (!getarnt && f && f->allies) { ally *sf; + faction *tf = u->faction; + + /* getarnte Partei bei a_otherfaction */ + if(a_otherfaction) { + tf = findfaction(a_otherfaction->data.i); + } for (sf = f->allies; sf && !dh; sf = sf->next) { - if (sf->status > 0 && sf->status <= HELP_ALL && sf->faction == u->faction) { + if (sf->status > 0 && sf->status <= HELP_ALL && sf->faction == tf) { dh = 1; } } @@ -582,8 +588,14 @@ bufunit_ugroupleader(const faction * f, const unit * u, int indent, int mode) dh=0; if (!getarnt && f && f->allies) { ally *sf; + faction *tf = u->faction; + + /* getarnte Partei bei a_otherfaction */ + if(a_otherfaction) { + tf = findfaction(a_otherfaction->data.i); + } for (sf = f->allies; sf && !dh; sf = sf->next) { - if (sf->status > 0 && sf->status <= HELP_ALL && sf->faction == u->faction) { + if (sf->status > 0 && sf->status <= HELP_ALL && sf->faction == tf) { dh = 1; } } diff --git a/src/common/kernel/spell.c b/src/common/kernel/spell.c index 4c99fda75..d2c100058 100644 --- a/src/common/kernel/spell.c +++ b/src/common/kernel/spell.c @@ -385,6 +385,7 @@ destroy_curse(attrib **alist, int cast_level, int force, * Allgemein sichtbare Auswirkungen in der Region sollten als * Regionsereignisse auch dort auftauchen. + freset(mage->faction, FL_DH); for(u = r->units; u; u = u->next ) freset(u->faction, FL_DH); for(u = r->units; u; u = u->next ) { if (!fval(u->faction, FL_DH) ) { @@ -392,6 +393,7 @@ destroy_curse(attrib **alist, int cast_level, int force, add_message(r, u->faction, buf, MSG_EVENT, ML_WARN | ML_INFO); } } + Sonderbehandlung Magierpartei nicht vergessen! * Meldungen an den Magier über Erfolg sollten, wenn sie nicht als * Regionsereigniss auftauchen, als MSG_MAGIC level ML_INFO unter @@ -937,6 +939,7 @@ sp_goodwinds(castorder *co) create_curse(mage, &sh->attribs, C_SHIP_NODRIFT, 0, power, cast_level, 0, 0); /* melden, 1x pro Partei */ + freset(mage->faction, FL_DH); for(u = r->units; u; u = u->next ) freset(u->faction, FL_DH); for(u = r->units; u; u = u->next ) { if(u->ship != sh ) /* nur den Schiffsbesatzungen! */ @@ -947,6 +950,11 @@ sp_goodwinds(castorder *co) "wind_effect%u:mage%h:ship", cansee(u->faction, r, mage, 0) ? mage:NULL, sh)); } } + if(!fval(mage->faction, FL_DH)){ + add_message(&mage->faction->msgs, new_message(mage->faction, + "wind_effect%u:mage%h:ship", mage, sh)); + } + return cast_level; } @@ -988,6 +996,7 @@ sp_magicstreet(castorder *co) create_curse(mage, &r->attribs, C_MAGICSTREET, 0, power, cast_level, 0, 0); /* melden, 1x pro Partei */ + freset(mage->faction, FL_DH); for(u = r->units; u; u = u->next ) freset(u->faction, FL_DH); for(u = r->units; u; u = u->next ) { if(!fval(u->faction, FL_DH) ) { @@ -996,6 +1005,10 @@ sp_magicstreet(castorder *co) "path_effect%u:mage%r:region", cansee(u->faction, r, mage, 0) ? mage:NULL, r)); } } + if(!fval(mage->faction, FL_DH)){ + add_message(&mage->faction->msgs, new_message(mage->faction, + "path_effect%u:mage%r:region", mage, r)); + } return cast_level; } @@ -1052,6 +1065,8 @@ sp_summonent(castorder *co) rsettrees(r, rtrees(r) - ents); + /* melden, 1x pro partei */ + freset(mage->faction, FL_DH); for(u2 = r->units; u2; u2 = u2->next ) freset(u2->faction, FL_DH); for(u2 = r->units; u2; u2 = u2->next ) { if (!fval(u2->faction, FL_DH) ) { @@ -1060,6 +1075,13 @@ sp_summonent(castorder *co) "ent_effect%u:mage%i:amount", cansee(u2->faction, r, mage, 0)?mage:NULL, u->number)); } } + if(!fval(mage->faction, FL_DH)){ + /* dann steht niemand von der Magierpartei in der Region, sieht also + * auch keine Regionsmeldung. ergo: global anzeigen */ + add_message(&mage->faction->msgs, new_message(mage->faction, + "ent_effect%u:mage%i:amount", mage, u->number)); + } + return cast_level; } @@ -1147,6 +1169,7 @@ sp_maelstrom(castorder *co) set_curseflag(r->attribs, C_MAELSTROM, 0, CURSE_ISNEW); /* melden, 1x pro partei */ + freset(mage->faction, FL_DH); for (u = r->units; u; u = u->next) freset(u->faction, FL_DH); for (u = r->units; u; u = u->next) { if (!fval(u->faction, FL_DH)) { @@ -1155,6 +1178,65 @@ sp_maelstrom(castorder *co) "maelstrom_effect%u:mage", cansee(u->faction, r, mage, 0) ? mage:NULL)); } } + if(!fval(mage->faction, FL_DH)){ + /* dann steht niemand von der Magierpartei in der Region, sieht also + * auch keine Regionsmeldung. ergo: global anzeigen */ + add_message(&mage->faction->msgs, new_message(mage->faction, + "maelstrom_effect%u:mage", mage)); + } + + return cast_level; +} + +/* ------------------------------------------------------------- */ +/* Name: Wurzeln der Magie + * Stufe: 16 + * Kategorie: Region, neutral + * Gebiet: Gwyrrd + * Wirkung: + * Wandelt einen Wald permanent in eine Mallornregion + * + * Flags: + * (FARCASTING | REGIONSPELL | TESTRESISTANCE) + */ +static int +sp_mallorn(castorder *co) +{ + unit *u; + region *r = co->rt; + int cast_level = co->level; + unit *mage = (unit *)co->magician; + + if(!landregion(rterrain(r))) { + cmistake(mage, strdup(co->order), 290, MSG_MAGIC); + return 0; + } + if(fval(r, RF_MALLORN)) { + cmistake(mage, strdup(co->order), 291, MSG_MAGIC); + return 0; + } + + /* half the trees will die */ + rsettrees(r, rtrees(r)/2); + fset(r, RF_MALLORN); + + /* melden, 1x pro partei */ + freset(mage->faction, FL_DH); + for (u = r->units; u; u = u->next) freset(u->faction, FL_DH); + for (u = r->units; u; u = u->next) { + if (!fval(u->faction, FL_DH)) { + fset(u->faction, FL_DH); + add_message(&r->msgs, new_message(u->faction, + "mallorn_effect%u:mage", cansee(u->faction, r, mage, 0) ? mage:NULL)); + } + } + if(!fval(mage->faction, FL_DH)){ + /* dann steht niemand von der Magierpartei in der Region, sieht also + * auch keine Regionsmeldung. ergo: global anzeigen */ + add_message(&mage->faction->msgs, new_message(mage->faction, + "mallorn_effect%u:mage", mage)); + } + return cast_level; } @@ -1185,6 +1267,7 @@ sp_blessedharvest(castorder *co) create_curse(mage,&r->attribs,C_BLESSEDHARVEST,0,power,power,1,0); /* melden, 1x pro partei */ + freset(mage->faction, FL_DH); for (u = r->units; u; u = u->next) freset(u->faction, FL_DH); for (u = r->units; u; u = u->next) { @@ -1195,6 +1278,8 @@ sp_blessedharvest(castorder *co) } } if (!fval(mage->faction, FL_DH)){ + /* dann steht niemand von der Magierpartei in der Region, sieht also + * auch keine Regionsmeldung. ergo: global anzeigen */ add_message(&mage->faction->msgs, new_message(mage->faction, "harvest_effect%u:mage", mage)); } @@ -1228,6 +1313,7 @@ sp_hain(castorder *co) rsettrees(r, rtrees(r) + trees); /* melden, 1x pro partei */ + freset(mage->faction, FL_DH); for (u = r->units; u; u = u->next) freset(u->faction, FL_DH); for (u = r->units; u; u = u->next) { if (!fval(u->faction, FL_DH)) { @@ -7349,7 +7435,9 @@ spell spelldaten[] = "Die Beschwörung von Elementargeistern der Stürme ist ein uraltes " "Ritual. Der Druide bannt die Elementare in die Segel der Schiffe, " "wo sie helfen, das Schiff mit hoher Geschwindigkeit über die Wellen " - "zu tragen.", + "zu tragen. Je mehr Kraft der Druide in den Zauber investiert, desto " + "größer ist die Zahl der Elementargeister, die sich bannen lassen. " + "Für jedes Schiff wird ein Elementargeist benötigt.", NULL, "s+", M_DRUIDE, @@ -7684,6 +7772,26 @@ spell spelldaten[] = {0, 0, 0}}, (spell_f)sp_maelstrom, patzer }, + + {SPL_MALLORN, "Wurzeln der Magie", + "Mit Hilfe dieses aufwändigen Rituals läßt der Druide einen Teil seiner " + "dauerhaft in den Boden und die Wälder der Region fliessen. Dadurch wird " + "das Gleichgewicht der Natur in der Region für immer verändert, und in " + "Zukunft werden nur noch die anspruchsvollen, aber kräftigen " + "Mallorngewächse in der Region gedeihen.", + NULL, + NULL, + M_DRUIDE, + (FARCASTING | REGIONSPELL | TESTRESISTANCE), + 5, 16, + { + {R_AURA, 250, SPC_FIX}, + {R_PERMAURA, 10, SPC_FIX}, + {R_TOADSLIME, 1, SPC_FIX}, + {0, 0, 0}, + {0, 0, 0}}, + (spell_f)sp_mallorn, patzer + }, {SPL_GREAT_DROUGHT, "Tor in die Ebene der Hitze", "Dieses mächtige Ritual öffnet ein Tor in die Elementarebene der " diff --git a/src/common/kernel/spell.h b/src/common/kernel/spell.h index e3f4ebccd..5b59df6cd 100644 --- a/src/common/kernel/spell.h +++ b/src/common/kernel/spell.h @@ -195,6 +195,7 @@ enum { SPL_UNHOLYPOWER, SPL_HOLYGROUND, SPL_BLOODSACRIFICE, + SPL_MALLORN, MAXALLSPELLS, NO_SPELL = (spellid_t) -1 }; diff --git a/src/common/spells/alp.c b/src/common/spells/alp.c index d58c440f3..9e55cd67f 100644 --- a/src/common/spells/alp.c +++ b/src/common/spells/alp.c @@ -104,6 +104,7 @@ sp_summon_alp(struct castorder *co) alp->ship = mage->ship; } set_skill(alp, SK_STEALTH, alp->number * 840); /* 840 Tage = T7 */ + set_string(&alp->name, "Alp"); alp->status = ST_FLEE; /* flieht */ { @@ -113,7 +114,7 @@ sp_summon_alp(struct castorder *co) ad->target = opfer; } - sprintf(buf, "Der Alp %s starb, ohne sein Ziel zu erreichen.", unitname(alp)); + strcpy(buf, "Ein Alp starb, ohne sein Ziel zu erreichen."); { #ifdef NEW_TRIGGER /* Wenn der Alp stirbt, den Magier nachrichtigen */ @@ -162,11 +163,11 @@ alp_findet_opfer(unit *alp, region *r) assert(mage); /* Magier und Opfer Bescheid geben */ - sprintf(buf, "Der Alp %s hat sein Opfer gefunden!", unitname(alp)); + strcpy(buf, "Ein Alp hat sein Opfer gefunden!"); addmessage(r, mage->faction, buf, MSG_MAGIC, ML_INFO); - sprintf(buf, "Der Alp %s springt auf den Rücken von %s.", - unitname(alp), unitname(opfer)); + sprintf(buf, "Ein Alp springt auf den Rücken von %s.", + unitname(opfer)); addmessage(r, opfer->faction, buf, MSG_EVENT, ML_IMPORTANT); /* Relations werden in destroy_unit(alp) automatisch gelöscht. diff --git a/src/common/util/goodies.c b/src/common/util/goodies.c index 9569378f3..c2c9bb7c2 100644 --- a/src/common/util/goodies.c +++ b/src/common/util/goodies.c @@ -31,7 +31,7 @@ /* Simple Integer-Liste */ char * -sncat(char * buffer, size_t size, const char * str) +fstrncat(char * buffer, const char * str, unsigned int size) { static char * b = NULL; static char * end = NULL; @@ -95,7 +95,7 @@ space_replace(char * str, char replace) } const char * -escape_string(const char * str, char * buffer, size_t len) +escape_string(const char * str, char * buffer, unsigned int len) { char s_buffer[4096]; const char * p = str; diff --git a/src/common/util/goodies.h b/src/common/util/goodies.h index 48451b0a7..11d1f9636 100644 --- a/src/common/util/goodies.h +++ b/src/common/util/goodies.h @@ -19,11 +19,12 @@ extern int *intlist_init(void); extern int *intlist_add(int *i_p, int i); extern int *intlist_find(int *i_p, int i); extern unsigned int hashstring(const char* s); -extern char *space_replace(char * str, char replace); -extern const char *escape_string(const char * str, char * buffer, size_t len); -extern boolean locale_check(void); -extern char *sncat(char * buffer, size_t size, const char * str); +extern char *space_replace(char * str, char replace); +extern const char *escape_string(const char * str, char * buffer, unsigned int len); +extern boolean locale_check(void); +extern char *fstrncat(char * buffer, const char * str, unsigned int size); +/* fast strncat */ /* grammar constants: */ #define GR_PLURAL 0x01 /* 0x02-0x08 left unused for individual use */ diff --git a/src/doc/spells_uebersicht.txt b/src/doc/spells_uebersicht.txt index 8ec6bd1d7..3211f649c 100644 --- a/src/doc/spells_uebersicht.txt +++ b/src/doc/spells_uebersicht.txt @@ -42,7 +42,8 @@ Druide/Gwyrrd (38 Spr 13 B... Hitzeelementar 600 halbiert Fruchtbarkeit der Region 14 Nebel der Verwirrung 8*L Bewegung wird zufällig (nur Wald+Ozean) 15 Mahlstrom 200,M Ozeanfeld beschädigt Schiffe schwer -16 T... die Ebene der Hitze 800 stärker als L13, kann Region wandeln +16 Wurzeln der Magie 250,10P,M Wald wird permanent Mallornwald +17 T... die Ebene der Hitze 800 stärker als L13, kann Region wandeln Chaos/Draig (27 Sprüche): diff --git a/src/eressea/korrektur.c b/src/eressea/korrektur.c index 31717ed58..3973e020d 100644 --- a/src/eressea/korrektur.c +++ b/src/eressea/korrektur.c @@ -975,7 +975,8 @@ show_newspells(void) spellid_t newspellids[] = { SPL_BLOODSACRIFICE, - SPL_NOSPELL }; + SPL_MALLORN, + SPL_NOSPELL }; /* die id's der neuen oder veränderten Sprüche werden in newspellids[] * abgelegt */ diff --git a/src/mapper/map_units.c b/src/mapper/map_units.c index a94c32a70..1c49d371a 100644 --- a/src/mapper/map_units.c +++ b/src/mapper/map_units.c @@ -14,15 +14,16 @@ #define BOOL_DEFINED /* wenn config.h nicht vor curses included wird, kompiliert es unter windows nicht */ + #include #include #include #include "mapper.h" /* kernel includes */ +#include #include #include -#include #include #include #include @@ -37,6 +38,7 @@ #include #include #include +#include #define findunit(f,r) findunitg(f,r) diff --git a/src/res/de/messages.txt b/src/res/de/messages.txt index b4d8b4478..6c4517b44 100644 --- a/src/res/de/messages.txt +++ b/src/res/de/messages.txt @@ -288,6 +288,8 @@ error286;errors:0;de;{unit} in {region}: '{command}' - Die Einheit transportiert error287;errors:0;de;{unit} in {region}: '{command}' - Dorthin können wir die Einheit nicht transportieren. error288;errors:0;de;{unit} in {region}: '{command}' - Wieviel sollen wir einreißen? error289;errors:0;de;{unit} in {region}: '{command}' - Tarne wie? +error290;errors:0;de;{unit} in {region}: '{command}' - Hier wachsen keine Bäume. +error291;errors:0;de;{unit} in {region}: '{command}' - Dies ist schon eine Mallornregion. # Meldungen und Ereignisse msg_event;events:0;de;{string} @@ -468,6 +470,7 @@ wind_effect;magic:0;de;{$mage mage} erfleht den Segen der G path_effect;magic:0;de;{$mage mage} sorgt für trockene Straßen in {region}. ent_effect;magic:0;de;{$mage mage} belebt {amount} Bäume. maelstrom_effect;magic:0;de;{$mage mage} beschwört die Mächte des Wassers und ein gigantischer Strudel bildet sich. +mallorn_effect;magic:0;de;{$mage mage} läßt seine Kraft in die Region fliessen. harvest_effect;magic:0;de;{$mage mage} segnet in einem kurzen Ritual die Felder. growtree_effect;magic:0;de;{$mage mage} erschuf einen heiligen Hain von {amount} Bäumen. rust_effect;magic:0;de;{$mage mage} legt einen Rosthauch auf {target}. {amount} Waffen wurden vom Rost zerfressen.