angefangen curse umzustellen, weg von der id

neuer Zauber Tybied
neue zauber vorbereitet
This commit is contained in:
Katja Zedel 2002-04-27 20:09:44 +00:00
parent c2aba8357f
commit b682917dd1
13 changed files with 417 additions and 270 deletions

View File

@ -423,6 +423,7 @@ calculate_emigration(region *r)
int overpopulation = rpeasants(r) - maxworkingpeasants(r); int overpopulation = rpeasants(r) - maxworkingpeasants(r);
int weight[MAXDIRECTIONS], weightall; int weight[MAXDIRECTIONS], weightall;
/* Bauern wandern nur bei Überbevölkerung, sonst gar nicht */
if(overpopulation <= 0) return; if(overpopulation <= 0) return;
weightall = 0; weightall = 0;

View File

@ -1063,11 +1063,11 @@ randomevents(void)
for (r = regions; r; r = r->next) { for (r = regions; r; r = r->next) {
for (u = r->units; u; u = u->next) { for (u = r->units; u; u = u->next) {
if (is_cursed(u->attribs, C_ORC, 0) curse *c = get_curse(u->attribs, C_ORC, 0);
&& !has_skill(u, SK_MAGIC) && !has_skill(u, SK_ALCHEMY)) { if (c && !has_skill(u, SK_MAGIC) && !has_skill(u, SK_ALCHEMY)) {
int n; int n;
int increase = 0; int increase = 0;
int num = min(get_cursedmen(u->attribs, C_ORC, 0), u->number); int num = get_cursedmen(u, c);
int prob = get_curseeffect(u->attribs, C_ORC, 0); int prob = get_curseeffect(u->attribs, C_ORC, 0);
for (n = (num - get_item(u, I_CHASTITY_BELT)); n > 0; n--) { for (n = (num - get_item(u, I_CHASTITY_BELT)); n > 0; n--) {

View File

@ -2743,13 +2743,19 @@ make_fighter(battle * b, unit * u, boolean attack)
h = u->hp / u->number; h = u->hp / u->number;
assert(h); assert(h);
rest = u->hp % u->number; rest = u->hp % u->number;
speeded = get_cursedmen(u->attribs, C_SPEED, 0);
speed = get_curseeffect(u->attribs, C_SPEED, 0); /* 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);
}
}
/* Effekte von Alchemie */ /* Effekte von Alchemie */
berserk = get_effect(u, oldpotiontype[P_BERSERK]); berserk = get_effect(u, oldpotiontype[P_BERSERK]);
/* Effekte von Sprüchen */
/* Effekte von Artefakten */ /* Effekte von Artefakten */
strongmen = min(fig->unit->number, get_item(u, I_TROLLBELT)); strongmen = min(fig->unit->number, get_item(u, I_TROLLBELT));

View File

@ -166,9 +166,6 @@ ct_register(const curse_type * ct)
const curse_type * const curse_type *
ct_find(const char *c) ct_find(const char *c)
{ {
/* TODO: findet nur curse_types, die auch in curse_data sind.
* da fehlt noch eine registrierung wie für attrib_type
*/
cursetype_list * ctl = cursetypes; cursetype_list * ctl = cursetypes;
while (ctl) { while (ctl) {
int k = min(strlen(c), strlen(ctl->type->name)); int k = min(strlen(c), strlen(ctl->type->name));
@ -178,11 +175,28 @@ ct_find(const char *c)
return NULL; return NULL;
} }
const curse_type *
find_cursetype(curse_t id)
{
cursetype_list * ctl = cursetypes;
/* sollte eigendlich nie mit 0 aufgerufen werden */
if (!id) return NULL;
while (ctl) {
if(ctl->type->cspellid == id) return ctl->type;
ctl = ctl->next;
}
return NULL;
}
/* ------------------------------------------------------------- */ /* ------------------------------------------------------------- */
boolean boolean
is_normalcurse(curse_t id) is_normalcurse(curse_t id)
{ {
if (cursedaten[id].typ == CURSETYP_NORM) const curse_type *ct = find_cursetype(id);
if (ct->typ == CURSETYP_NORM)
return true; return true;
return false; return false;
@ -191,7 +205,9 @@ is_normalcurse(curse_t id)
boolean boolean
is_curseunit(curse_t id) is_curseunit(curse_t id)
{ {
if (cursedaten[id].typ == CURSETYP_UNIT) const curse_type *ct = find_cursetype(id);
if (ct->typ == CURSETYP_UNIT)
return true; return true;
return false; return false;
@ -200,7 +216,20 @@ is_curseunit(curse_t id)
boolean boolean
is_curseskill(curse_t id) is_curseskill(curse_t id)
{ {
if (cursedaten[id].typ == CURSETYP_SKILL) const curse_type *ct = find_cursetype(id);
if (ct->typ == CURSETYP_SKILL)
return true;
return false;
}
boolean
is_cursesecondid(curse_t id)
{
const curse_type *ct = find_cursetype(id);
if (ct->typ == CURSETYP_SECONDID)
return true; return true;
return false; return false;
@ -230,24 +259,21 @@ cmp_oldcurse(const attrib * a, const void * data)
{ {
twoids * ti = (twoids*)data; twoids * ti = (twoids*)data;
const curse * c = (const curse*)a->data.v; const curse * c = (const curse*)a->data.v;
if (a->type!=&at_curse || c->cspellid!=ti->id) return false; const curse_type * ct;
switch(cursedaten[ti->id].typ) {
case CURSETYP_SKILL: if (a->type!=&at_curse) return false;
{ ct = c->type;
curse_skill * cc = (curse_skill*)c->data;
if (cc->skill == (skill_t) ti->id2) return true; if (ct->cspellid != ti->id) return false;
}
case CURSETYP_SECONDID: if (is_curseskill(ti->id)){
{ curse_skill * cc = (curse_skill*)c->data;
curse_secondid * cc = (curse_secondid*)c->data; if (cc->skill == (skill_t) ti->id2) return true;
if (cc->secondid == ti->id2) return true; } else if (is_cursesecondid(ti->id)) {
} curse_secondid * cc = (curse_secondid*)c->data;
case CURSETYP_UNIT: if (cc->secondid == ti->id2) return true;
case CURSETYP_NORM: } else {
return true; return true;
break;
default:
assert(!"unbekannter cursetyp entdeckt");
} }
return false; return false;
} }
@ -398,77 +424,65 @@ remove_cursemagepointer(unit *magician, attrib *ap_target)
/* ------------------------------------------------------------- */ /* ------------------------------------------------------------- */
int int
get_cursedmen(attrib *ap, curse_t id, int id2) get_cursedmen(unit *u, curse *c)
{ {
switch (cursedaten[id].typ){ int cursedmen = u->number;
case CURSETYP_UNIT:
{ if (!c) return 0;
curse *c = get_curse(ap, id, id2);
if (c){ /* je nach curse_type andere data struct */
curse_unit * cc = (curse_unit*)c->data; if (c->type->typ == CURSETYP_UNIT){
return cc->cursedmen; curse_unit * cc = (curse_unit*)c->data;
} cursedmen = cc->cursedmen;
}
case CURSETYP_SKILL:
{
curse *c = get_curse(ap, id, id2);
if (c){
curse_skill * cc = (curse_skill*)c->data;
return cc->cursedmen;
}
}
case CURSETYP_NORM:
default:
break;
} }
return 0; if (c->type->typ == CURSETYP_SKILL){
curse_skill * cc = (curse_skill*)c->data;
cursedmen = cc->cursedmen;
}
return min(u->number, cursedmen);
} }
void void
set_cursedmen(attrib *ap, curse_t id, int id2, int cursedmen) set_cursedmen(attrib *ap, curse_t id, int id2, int cursedmen)
{ {
switch (cursedaten[id].typ){ curse *c = get_curse(ap, id, id2);
case CURSETYP_UNIT:
{ if (!c) return;
curse *c = get_curse(ap, id, id2);
if (c){ /* je nach curse_type andere data struct */
curse_unit * cc = (curse_unit*)c->data; if (c->type->typ == CURSETYP_UNIT) {
cc->cursedmen = cursedmen; curse_unit * cc = (curse_unit*)c->data;
} cc->cursedmen = cursedmen;
break; }
} if (c->type->typ == CURSETYP_SKILL) {
case CURSETYP_SKILL: curse_skill * cc = (curse_skill*)c->data;
{ cc->cursedmen = cursedmen;
curse *c = get_curse(ap, id, id2);
if (c){
curse_skill * cc = (curse_skill*)c->data;
cc->cursedmen = cursedmen;
}
break;
}
case CURSETYP_NORM:
default:
break;
} }
} }
int int
change_cursedmen(attrib **ap, curse_t id, int id2, int cursedmen) change_cursedmen(attrib **ap, curse_t id, int id2, int cursedmen)
{ {
switch (cursedaten[id].typ){ curse *c = get_curse(*ap, id, id2);
case CURSETYP_UNIT:
case CURSETYP_SKILL: if (!c) return 0;
cursedmen += get_cursedmen(*ap, id, id2);
if (cursedmen <= 0){ /* je nach curse_type andere data struct */
remove_curse(ap,id,id2); if (c->type->typ == CURSETYP_UNIT) {
} else { curse_unit * cc = (curse_unit*)c->data;
set_cursedmen(*ap, id, id2, cursedmen); cursedmen += cc->cursedmen;
}
break;
case CURSETYP_NORM:
default:
break;
} }
if (c->type->typ == CURSETYP_SKILL) {
curse_skill * cc = (curse_skill*)c->data;
cursedmen += cc->cursedmen;
}
if (cursedmen <= 0){
remove_curse(ap,id,id2);
} else {
set_cursedmen(*ap, id, id2, cursedmen);
}
return cursedmen; return cursedmen;
} }
@ -503,7 +517,7 @@ set_curse(unit *mage, attrib **ap, curse_t id, int id2, int vigour,
a_add(ap, a); a_add(ap, a);
c = (curse*)a->data.v; c = (curse*)a->data.v;
c->type = &cursedaten[id]; c->type = find_cursetype(id);
c->cspellid = id; c->cspellid = id;
c->flag = (0); c->flag = (0);
c->vigour = vigour; c->vigour = vigour;
@ -554,6 +568,7 @@ create_curse(unit *magician, attrib **ap, curse_t id, int id2, int vigour,
int duration, int effect, int men) int duration, int effect, int men)
{ {
curse *c; curse *c;
const curse_type *ct;
/* die Kraft eines Spruchs darf nicht 0 sein*/ /* die Kraft eines Spruchs darf nicht 0 sein*/
assert(vigour >= 0); assert(vigour >= 0);
@ -563,28 +578,34 @@ create_curse(unit *magician, attrib **ap, curse_t id, int id2, int vigour,
if(c && (c->flag & CURSE_ONLYONE)){ if(c && (c->flag & CURSE_ONLYONE)){
return NULL; return NULL;
} }
if(c){
ct = c->type;
} else {
ct = find_cursetype(id);
}
/* es gibt schon eins diese Typs */ /* es gibt schon eins diese Typs */
if (c && cursedaten[id].mergeflags != NO_MERGE) { if (c && ct->mergeflags != NO_MERGE) {
if(cursedaten[id].mergeflags & M_DURATION){ if(ct->mergeflags & M_DURATION){
c->duration = max(c->duration, duration); c->duration = max(c->duration, duration);
} }
if(cursedaten[id].mergeflags & M_SUMDURATION){ if(ct->mergeflags & M_SUMDURATION){
c->duration += duration; c->duration += duration;
} }
if(cursedaten[id].mergeflags & M_SUMEFFECT){ if(ct->mergeflags & M_SUMEFFECT){
c->effect += effect; c->effect += effect;
} }
if(cursedaten[id].mergeflags & M_MAXEFFECT){ if(ct->mergeflags & M_MAXEFFECT){
c->effect = max(c->effect, effect); c->effect = max(c->effect, effect);
} }
if(cursedaten[id].mergeflags & M_VIGOUR){ if(ct->mergeflags & M_VIGOUR){
c->vigour = max(vigour, c->vigour); c->vigour = max(vigour, c->vigour);
} }
if(cursedaten[id].mergeflags & M_VIGOUR_ADD){ if(ct->mergeflags & M_VIGOUR_ADD){
c->vigour = vigour + c->vigour; c->vigour = vigour + c->vigour;
} }
if(cursedaten[id].mergeflags & M_MEN){ if(ct->mergeflags & M_MEN){
switch (cursedaten[id].typ) { switch (ct->typ) {
case CURSETYP_UNIT: case CURSETYP_UNIT:
{ {
curse_unit * cc = (curse_unit*)c->data; curse_unit * cc = (curse_unit*)c->data;
@ -621,8 +642,9 @@ do_transfer_curse(curse *c, unit * u, unit * u2, int n)
int cursedmen = 0; int cursedmen = 0;
int men = 0; int men = 0;
boolean dogive = false; boolean dogive = false;
const curse_type *ct = c->type;
switch (cursedaten[id].typ) { switch (ct->typ) {
case CURSETYP_UNIT: case CURSETYP_UNIT:
{ {
curse_unit * cc = (curse_unit*)c->data; curse_unit * cc = (curse_unit*)c->data;
@ -640,7 +662,7 @@ do_transfer_curse(curse *c, unit * u, unit * u2, int n)
cursedmen = u->number; cursedmen = u->number;
} }
switch (cursedaten[id].givemenacting){ switch (ct->givemenacting){
case CURSE_SPREADALWAYS: case CURSE_SPREADALWAYS:
dogive = true; dogive = true;
men = u2->number + n; men = u2->number + n;
@ -678,7 +700,7 @@ do_transfer_curse(curse *c, unit * u, unit * u2, int n)
effect, men); effect, men);
set_curseflag(u2->attribs, id, id2, flag); set_curseflag(u2->attribs, id, id2, flag);
switch (cursedaten[id].typ){ switch (ct->typ){
case CURSETYP_UNIT: case CURSETYP_UNIT:
case CURSETYP_SKILL: case CURSETYP_SKILL:
set_cursedmen(u2->attribs, id, id2, men); set_cursedmen(u2->attribs, id, id2, men);
@ -1353,95 +1375,100 @@ cinfo_riot(void * obj, typ_t typ, curse *c, int self)
curse_type cursedaten[MAXCURSE] = curse_type cursedaten[MAXCURSE] =
{ {
/* struct's vom typ curse: */ /* struct's vom typ curse: */
{ /* C_FOGTRAP, */ {
C_FOGTRAP,
"ct_fogtrap",
CURSETYP_NORM, 0, (M_DURATION | M_VIGOUR), CURSETYP_NORM, 0, (M_DURATION | M_VIGOUR),
"", "",
"",
(cdesc_fun)cinfo_fogtrap (cdesc_fun)cinfo_fogtrap
}, },
{ /* C_ANTIMAGICZONE, */ {
C_ANTIMAGICZONE,
"ct_antimagiczone",
CURSETYP_NORM, 0, (M_DURATION | M_VIGOUR), CURSETYP_NORM, 0, (M_DURATION | M_VIGOUR),
"Magieschwächezone",
"Dieser Zauber scheint magische Energien irgendwie abzuleiten und " "Dieser Zauber scheint magische Energien irgendwie abzuleiten und "
"so alle in der Region gezauberten Sprüche in ihrer Wirkung zu " "so alle in der Region gezauberten Sprüche in ihrer Wirkung zu "
"schwächen oder ganz zu verhindern.", "schwächen oder ganz zu verhindern.",
NULL NULL
}, },
{ /* C_FARVISION, */ {
C_FARVISION,
"ct_farvision",
CURSETYP_NORM, 0, (NO_MERGE), CURSETYP_NORM, 0, (NO_MERGE),
"", "",
"",
NULL NULL
}, },
{ /* C_GBDREAM, */ {
C_GBDREAM,
"ct_gbdream",
CURSETYP_NORM, 0, (NO_MERGE), CURSETYP_NORM, 0, (NO_MERGE),
"", "",
"",
(cdesc_fun)cinfo_dreamcurse (cdesc_fun)cinfo_dreamcurse
}, },
{ /* C_AURA, Verändert die max Aura und Regeneration um effect% */ { /* Verändert die max Aura und Regeneration um effect% */
C_AURA,
"ct_auraboost",
CURSETYP_NORM, CURSE_SPREADMODULO, (NO_MERGE), CURSETYP_NORM, CURSE_SPREADMODULO, (NO_MERGE),
"Aurafokus",
"Dieser Zauber greift irgendwie in die Verbindung zwischen Magier " "Dieser Zauber greift irgendwie in die Verbindung zwischen Magier "
"und Magischer Essenz ein. Mit positiver Ausrichtung kann er wohl " "und Magischer Essenz ein. Mit positiver Ausrichtung kann er wohl "
"wie ein Fokus für Aura wirken, jedoch genauso für das Gegenteil " "wie ein Fokus für Aura wirken, jedoch genauso für das Gegenteil "
"benutzt werden.", "benutzt werden.",
(cdesc_fun)cinfo_auraboost (cdesc_fun)cinfo_auraboost
}, },
{ /* C_MAELSTROM, */ { C_MAELSTROM,
"ct_maelstrom",
CURSETYP_NORM, 0, (M_DURATION | M_VIGOUR), CURSETYP_NORM, 0, (M_DURATION | M_VIGOUR),
"Mahlstrom",
"Dieser Zauber verursacht einen gigantischen magischen Strudel. Der " "Dieser Zauber verursacht einen gigantischen magischen Strudel. Der "
"Mahlstrom wird alle Schiffe, die in seinen Sog geraten, schwer " "Mahlstrom wird alle Schiffe, die in seinen Sog geraten, schwer "
"beschädigen.", "beschädigen.",
NULL NULL
}, },
{ /* C_BLESSEDHARVEST, */ { C_BLESSEDHARVEST,
"ct_blessedharvest",
CURSETYP_NORM, 0, ( M_DURATION | M_VIGOUR ), CURSETYP_NORM, 0, ( M_DURATION | M_VIGOUR ),
"Segen der Felder",
"Dieser Fruchtbarkeitszauber erhöht die Erträge der Felder.", "Dieser Fruchtbarkeitszauber erhöht die Erträge der Felder.",
(cdesc_fun)cinfo_blessedharvest (cdesc_fun)cinfo_blessedharvest
}, },
{ /* C_DROUGHT, */ { C_DROUGHT,
"ct_drought",
CURSETYP_NORM, 0, ( M_DURATION | M_VIGOUR ), CURSETYP_NORM, 0, ( M_DURATION | M_VIGOUR ),
"Dürre",
"Dieser Zauber strahlt starke negative Energien aus. Warscheinlich " "Dieser Zauber strahlt starke negative Energien aus. Warscheinlich "
"ist er die Ursache der Dürre." , "ist er die Ursache der Dürre." ,
(cdesc_fun)cinfo_drought (cdesc_fun)cinfo_drought
}, },
{ /* C_BADLEARN, */ { C_BADLEARN,
"ct_badlearn",
CURSETYP_NORM, 0, ( M_DURATION | M_VIGOUR ), CURSETYP_NORM, 0, ( M_DURATION | M_VIGOUR ),
"",
"Dieser Zauber scheint die Ursache für die Schlaflosigkeit und " "Dieser Zauber scheint die Ursache für die Schlaflosigkeit und "
"Mattigkeit zu sein, unter der die meisten Leute hier leiden und " "Mattigkeit zu sein, unter der die meisten Leute hier leiden und "
"die dazu führt, das Lernen weniger Erfolg bringt. ", "die dazu führt, das Lernen weniger Erfolg bringt. ",
(cdesc_fun)cinfo_badlearn (cdesc_fun)cinfo_badlearn
}, },
{ /* C_SHIP_SPEEDUP, Sturmwind-Zauber, wirkt nur 1 Runde */ { C_SHIP_SPEEDUP, /* Sturmwind-Zauber, wirkt nur 1 Runde */
"ct_stormwind",
CURSETYP_NORM, 0, NO_MERGE, CURSETYP_NORM, 0, NO_MERGE,
"Sturmwind",
"", "",
NULL NULL
}, },
{ /* C_SHIP_FLYING, Luftschiff-Zauber, wirkt nur 1 Runde */ { C_SHIP_FLYING, /* Luftschiff-Zauber, wirkt nur 1 Runde */
"ct_flyingship",
CURSETYP_NORM, 0, NO_MERGE, CURSETYP_NORM, 0, NO_MERGE,
"Luftschiff",
"", "",
NULL NULL
}, },
{ /* C_SHIP_NODRIFT, GünstigeWinde-Zauber */ { C_SHIP_NODRIFT, /* GünstigeWinde-Zauber */
"ct_nodrift",
CURSETYP_NORM, 0, ( M_DURATION | M_VIGOUR ), CURSETYP_NORM, 0, ( M_DURATION | M_VIGOUR ),
"Günstige Winde",
"Der Zauber auf diesem Schiff ist aus den elementaren Magien der Luft " "Der Zauber auf diesem Schiff ist aus den elementaren Magien der Luft "
"und des Wassers gebunden. Der dem Wasser verbundene Teil des Zaubers " "und des Wassers gebunden. Der dem Wasser verbundene Teil des Zaubers "
"läßt es leichter durch die Wellen gleiten und der der Luft verbundene " "läßt es leichter durch die Wellen gleiten und der der Luft verbundene "
"Teil scheint es vor widrigen Winden zu schützen.", "Teil scheint es vor widrigen Winden zu schützen.",
(cdesc_fun)cinfo_shipnodrift (cdesc_fun)cinfo_shipnodrift
}, },
{ /* C_DEPRESSION, Trübsal-Zauber */ { C_DEPRESSION, /* Trübsal-Zauber */
"ct_depression",
CURSETYP_NORM, 0, ( M_DURATION | M_VIGOUR ), CURSETYP_NORM, 0, ( M_DURATION | M_VIGOUR ),
"Schwermut",
"Wie schon zu vermuten war, sind der ewig graue Himmel und die " "Wie schon zu vermuten war, sind der ewig graue Himmel und die "
"depressive Stimmung in der Region nicht natürlich. Dieser Fluch " "depressive Stimmung in der Region nicht natürlich. Dieser Fluch "
"hat sich wie ein bleiernes Tuch auf die Gemüter der Bevölkerung " "hat sich wie ein bleiernes Tuch auf die Gemüter der Bevölkerung "
@ -1449,9 +1476,9 @@ curse_type cursedaten[MAXCURSE] =
"sich an Gaukelleien erfreuen können.", "sich an Gaukelleien erfreuen können.",
(cdesc_fun)cinfo_depression (cdesc_fun)cinfo_depression
}, },
{ /* C_MAGICSTONE, Heimstein-Zauber */ { C_MAGICSTONE, /* Heimstein-Zauber */
"ct_magicwalls",
CURSETYP_NORM, 0, NO_MERGE, CURSETYP_NORM, 0, NO_MERGE,
"Felsenmauern",
"Die Macht dieses Zaubers ist fast greifbar und tief in die Mauern " "Die Macht dieses Zaubers ist fast greifbar und tief in die Mauern "
"gebunden. Starke elementarmagische Kräfte sind zu spüren. " "gebunden. Starke elementarmagische Kräfte sind zu spüren. "
"Vieleicht wurde gar ein Erdelementar in diese Mauern gebannt. " "Vieleicht wurde gar ein Erdelementar in diese Mauern gebannt. "
@ -1459,275 +1486,275 @@ curse_type cursedaten[MAXCURSE] =
"gefährden können.", "gefährden können.",
(cdesc_fun)cinfo_magicstone (cdesc_fun)cinfo_magicstone
}, },
{ /* C_STRONGWALL, Feste Mauer - Präkampfzauber, wirkt nur 1 Runde */ { C_STRONGWALL, /* Feste Mauer - Präkampfzauber, wirkt nur 1 Runde */
"ct_strongwall",
CURSETYP_NORM, 0, NO_MERGE, CURSETYP_NORM, 0, NO_MERGE,
"Burgschutzzauber",
"", "",
NULL NULL
}, },
{ /* C_ASTRALBLOCK, Astralblock, auf Astralregion */ { C_ASTRALBLOCK, /* Astralblock, auf Astralregion */
"ct_astralblock",
CURSETYP_NORM, 0, NO_MERGE, CURSETYP_NORM, 0, NO_MERGE,
"", "",
"",
(cdesc_fun)cinfo_astralblock (cdesc_fun)cinfo_astralblock
}, },
{ /* C_GENEROUS, Unterhaltungsanteil vermehren */ { C_GENEROUS, /* Unterhaltungsanteil vermehren */
"ct_generous",
CURSETYP_NORM, 0, ( M_DURATION | M_VIGOUR | M_MAXEFFECT ), CURSETYP_NORM, 0, ( M_DURATION | M_VIGOUR | M_MAXEFFECT ),
"Feierlaune",
"Dieser Zauber beeinflusst die allgemeine Stimmung in der Region positiv. " "Dieser Zauber beeinflusst die allgemeine Stimmung in der Region positiv. "
"Die gute Laune macht die Leute freigiebiger.", "Die gute Laune macht die Leute freigiebiger.",
(cdesc_fun)cinfo_generous (cdesc_fun)cinfo_generous
}, },
{ /* C_PEACE, verhindert Attackiere regional */ { C_PEACE, /* verhindert Attackiere regional */
"ct_peacezone",
CURSETYP_NORM, 0, NO_MERGE, CURSETYP_NORM, 0, NO_MERGE,
"Friedensbann",
"Dieser machtvoller Beeinflussungszauber erstickt jeden Streit schon im " "Dieser machtvoller Beeinflussungszauber erstickt jeden Streit schon im "
"Keim.", "Keim.",
(cdesc_fun)cinfo_peace (cdesc_fun)cinfo_peace
}, },
{ /* C_REGCONF, erschwert geordnete Bewegungen */ { C_REGCONF, /* erschwert geordnete Bewegungen */
"ct_disorientationzone",
CURSETYP_NORM, 0, NO_MERGE, CURSETYP_NORM, 0, NO_MERGE,
"", "",
"",
(cdesc_fun)cinfo_regconf (cdesc_fun)cinfo_regconf
}, },
{ /* C_MAGICSTREET, erzeugt Straßennetz */ { C_MAGICSTREET, /* erzeugt Straßennetz */
"ct_magicstreet",
CURSETYP_NORM, 0, (M_DURATION | M_VIGOUR), CURSETYP_NORM, 0, (M_DURATION | M_VIGOUR),
"magische Pfade",
"Es scheint sich um einen elementarmagischen Zauber zu handeln, der alle " "Es scheint sich um einen elementarmagischen Zauber zu handeln, der alle "
"Pfade und Wege so gut festigt, als wären sie gepflastert. Wie auf einer " "Pfade und Wege so gut festigt, als wären sie gepflastert. Wie auf einer "
"Straße kommt man so viel besser und schneller vorwärts.", "Straße kommt man so viel besser und schneller vorwärts.",
(cdesc_fun)cinfo_magicstreet (cdesc_fun)cinfo_magicstreet
}, },
{ /* C_RESIST_MAGIC, */ { C_RESIST_MAGIC,
"ct_magicresistance",
CURSETYP_NORM, 0, M_SUMEFFECT, CURSETYP_NORM, 0, M_SUMEFFECT,
"Magieschutz",
"Dieses Zauber verstärkt die natürliche Widerstandskraft gegen eine " "Dieses Zauber verstärkt die natürliche Widerstandskraft gegen eine "
"Verzauberung.", "Verzauberung.",
(cdesc_fun)cinfo_magicrunes (cdesc_fun)cinfo_magicrunes
}, },
{ /* C_SONG_BADMR, { /* erniedigt Magieresistenz von nicht-aliierten Einheiten, wirkt nur
erniedigt Magieresistenz von nicht-aliierten Einheiten, wirkt nur
1x pro Einheit */ 1x pro Einheit */
C_SONG_BADMR,
"ct_badmagicresistancezone",
CURSETYP_NORM, 0, NO_MERGE, CURSETYP_NORM, 0, NO_MERGE,
"Gesang des schwachen Geistes",
"Dieses Lied, das irgendwie in die magische Essenz der Region gewoben " "Dieses Lied, das irgendwie in die magische Essenz der Region gewoben "
"ist, schwächt die natürliche Widerstandskraft gegen eine " "ist, schwächt die natürliche Widerstandskraft gegen eine "
"Verzauberung. Es scheint jedoch nur auf bestimmte Einheiten zu wirken.", "Verzauberung. Es scheint jedoch nur auf bestimmte Einheiten zu wirken.",
NULL NULL
}, },
{ /* C_SONG_GOODMR, { /* erhöht Magieresistenz von aliierten Einheiten, wirkt nur 1x pro
erhöht Magieresistenz von aliierten Einheiten, wirkt nur 1x pro
Einheit */ Einheit */
C_SONG_GOODMR,
"ct_goodmagicresistancezone",
CURSETYP_NORM, 0, NO_MERGE, CURSETYP_NORM, 0, NO_MERGE,
"Gesang des wachen Geistes",
"Dieser Lied, das irgendwie in die magische Essenz der Region gewoben " "Dieser Lied, das irgendwie in die magische Essenz der Region gewoben "
"ist, verstärkt die natürliche Widerstandskraft gegen eine " "ist, verstärkt die natürliche Widerstandskraft gegen eine "
"Verzauberung. Es scheint jedoch nur auf bestimmte Einheiten zu wirken.", "Verzauberung. Es scheint jedoch nur auf bestimmte Einheiten zu wirken.",
NULL NULL
}, },
{ /* C_SLAVE, { /* dient fremder Partei. Zählt nicht zu Migranten, attackiert nicht */
dient fremder Partei. Zählt nicht zu Migranten, attackiert nicht */ C_SLAVE,
"ct_slavery",
CURSETYP_NORM, 0, NO_MERGE, CURSETYP_NORM, 0, NO_MERGE,
"Sklavenketten",
"Dieser mächtige Bann scheint die Einheit ihres freien Willens " "Dieser mächtige Bann scheint die Einheit ihres freien Willens "
"zu berauben. Solange der Zauber wirkt, wird sie nur den Befehlen " "zu berauben. Solange der Zauber wirkt, wird sie nur den Befehlen "
"ihres neuen Herrn gehorchen.", "ihres neuen Herrn gehorchen.",
(cdesc_fun)cinfo_slave (cdesc_fun)cinfo_slave
}, },
{ /* C_DISORIENTATION, */ { C_DISORIENTATION,
"ct_shipdisorientation",
CURSETYP_NORM, 0, NO_MERGE, CURSETYP_NORM, 0, NO_MERGE,
"Irrfahrt",
"Dieses Schiff hat sich verfahren.", "Dieses Schiff hat sich verfahren.",
(cdesc_fun)cinfo_disorientation (cdesc_fun)cinfo_disorientation
}, },
{ /* C_CALM, */ { C_CALM,
"ct_calmmonster",
CURSETYP_NORM, CURSE_SPREADNEVER, NO_MERGE, CURSETYP_NORM, CURSE_SPREADNEVER, NO_MERGE,
"Besänftigen",
"Dieser Beeinflussungszauber scheint die Einheit einem ganz " "Dieser Beeinflussungszauber scheint die Einheit einem ganz "
"bestimmten Volk wohlgesonnen zu machen.", "bestimmten Volk wohlgesonnen zu machen.",
(cdesc_fun)cinfo_calm (cdesc_fun)cinfo_calm
}, },
{ /* C_OLDRACE, { /* Merkt sich die alte 'richtige' Rasse einer gestalltwandelnden
Merkt sich die alte 'richtige' Rasse einer gestalltwandelnden
Einheit */ Einheit */
C_OLDRACE,
"ct_oldrace",
CURSETYP_NORM, CURSE_SPREADALWAYS, NO_MERGE, CURSETYP_NORM, CURSE_SPREADALWAYS, NO_MERGE,
"", "",
"",
NULL NULL
}, },
{ /* C_FUMBLE, */ { C_FUMBLE,
"ct_fumble",
CURSETYP_NORM, CURSE_SPREADNEVER, NO_MERGE, CURSETYP_NORM, CURSE_SPREADNEVER, NO_MERGE,
"Tollpatschfluch",
"Eine Wolke negativer Energie umgibt die Einheit.", "Eine Wolke negativer Energie umgibt die Einheit.",
(cdesc_fun)cinfo_fumble (cdesc_fun)cinfo_fumble
}, },
{ /* C_RIOT, */ { C_RIOT,
"ct_riotzone",
CURSETYP_NORM, 0, (M_DURATION), CURSETYP_NORM, 0, (M_DURATION),
"Aufruhr",
"Eine Wolke negativer Energie liegt über der Region.", "Eine Wolke negativer Energie liegt über der Region.",
(cdesc_fun)cinfo_riot (cdesc_fun)cinfo_riot
}, },
{ /* C_NOCOST, Ewige Mauern-Zauber */ { C_NOCOST, /* Ewige Mauern-Zauber */
"ct_nocostbuilding",
CURSETYP_NORM, 0, NO_MERGE, CURSETYP_NORM, 0, NO_MERGE,
"Ewige Mauern",
"Die Macht dieses Zaubers ist fast greifbar und tief in die Mauern " "Die Macht dieses Zaubers ist fast greifbar und tief in die Mauern "
"gebunden. Unbeeindruck vom Zahn der Zeit wird dieses Gebäude wohl " "gebunden. Unbeeindruck vom Zahn der Zeit wird dieses Gebäude wohl "
"auf Ewig stehen.", "auf Ewig stehen.",
(cdesc_fun)cinfo_nocost (cdesc_fun)cinfo_nocost
}, },
{ /* C_HOLYGROUND, */ { C_HOLYGROUND,
"ct_holyground",
CURSETYP_NORM, 0, (M_VIGOUR_ADD), CURSETYP_NORM, 0, (M_VIGOUR_ADD),
"Heiliger Boden",
"Verschiedene Naturgeistern sind im Boden der Region gebunden und " "Verschiedene Naturgeistern sind im Boden der Region gebunden und "
"beschützen diese vor dem der dunklen Magie des lebenden Todes.", "beschützen diese vor dem der dunklen Magie des lebenden Todes.",
(cdesc_fun)cinfo_holyground (cdesc_fun)cinfo_holyground
}, },
{ /* C_CURSED_BY_THE_GODS, */ { C_CURSED_BY_THE_GODS,
"ct_goodcursezone",
CURSETYP_NORM, 0, (NO_MERGE), CURSETYP_NORM, 0, (NO_MERGE),
"Verflucht von den Göttern",
"Diese Region wurde von den Göttern verflucht. Stinkende Nebel ziehen " "Diese Region wurde von den Göttern verflucht. Stinkende Nebel ziehen "
"über die tote Erde, furchbare Kreaturen ziehen über das Land. Die Brunnen " "über die tote Erde, furchbare Kreaturen ziehen über das Land. Die Brunnen "
"sind vergiftet, und die wenigen essbaren Früchte sind von einem rosa Pilz " "sind vergiftet, und die wenigen essbaren Früchte sind von einem rosa Pilz "
"überzogen. Niemand kann hier lange überleben.", "überzogen. Niemand kann hier lange überleben.",
(cdesc_fun)cinfo_cursed_by_the_gods, (cdesc_fun)cinfo_cursed_by_the_gods,
}, },
{ /* C_FREE_14, */ { C_FREE_14,
CURSETYP_NORM, 0, (NO_MERGE),
"", "",
CURSETYP_NORM, 0, (NO_MERGE),
"", "",
NULL NULL
}, },
{ /* C_FREE_15, */ { C_FREE_15,
CURSETYP_NORM, 0, (NO_MERGE),
"", "",
CURSETYP_NORM, 0, (NO_MERGE),
"", "",
NULL NULL
}, },
{ /* C_FREE_16, */ { C_FREE_16,
CURSETYP_NORM, 0, (NO_MERGE),
"", "",
CURSETYP_NORM, 0, (NO_MERGE),
"", "",
NULL NULL
}, },
{ /* C_FREE_17, */ { C_FREE_17,
CURSETYP_NORM, 0, (NO_MERGE),
"", "",
CURSETYP_NORM, 0, (NO_MERGE),
"", "",
NULL NULL
}, },
{ /* C_FREE_18, */ { C_FREE_18,
CURSETYP_NORM, 0, (NO_MERGE),
"", "",
CURSETYP_NORM, 0, (NO_MERGE),
"", "",
NULL NULL
}, },
{ /* C_FREE_19, */ { C_FREE_19,
CURSETYP_NORM, 0, (NO_MERGE),
"", "",
CURSETYP_NORM, 0, (NO_MERGE),
"", "",
NULL NULL
}, },
/* struct's vom typ curse_unit: */ /* struct's vom typ curse_unit: */
{ /* C_SPEED, */ { C_SPEED,
CURSETYP_UNIT, CURSE_SPREADNEVER, M_MEN,
"Beschleunigen II", "Beschleunigen II",
CURSETYP_UNIT, CURSE_SPREADNEVER, M_MEN,
"Diese Einheit bewegt sich doppelt so schnell.", "Diese Einheit bewegt sich doppelt so schnell.",
(cdesc_fun)cinfo_speed (cdesc_fun)cinfo_speed
}, },
{ /* C_ORC, */ { C_ORC,
CURSETYP_UNIT, CURSE_SPREADMODULO, M_MEN,
"Orkfieber", "Orkfieber",
CURSETYP_UNIT, CURSE_SPREADMODULO, M_MEN,
"Dieser Zauber scheint die Einheit zu 'orkisieren'. Wie bei Orks " "Dieser Zauber scheint die Einheit zu 'orkisieren'. Wie bei Orks "
"ist eine deutliche Neigung zur Fortpflanzung zu beobachten.", "ist eine deutliche Neigung zur Fortpflanzung zu beobachten.",
(cdesc_fun)cinfo_orc (cdesc_fun)cinfo_orc
}, },
{ /* C_MBOOST, */ { C_MBOOST,
CURSETYP_UNIT, CURSE_SPREADMODULO, M_MEN,
"", "",
CURSETYP_UNIT, CURSE_SPREADMODULO, M_MEN,
"", "",
NULL NULL
}, },
{ /* C_KAELTESCHUTZ, */ { C_KAELTESCHUTZ,
CURSETYP_UNIT, CURSE_SPREADMODULO, ( M_MEN | M_DURATION ),
"Winterfell", "Winterfell",
CURSETYP_UNIT, CURSE_SPREADMODULO, ( M_MEN | M_DURATION ),
"Dieser Zauber schützt vor den Auswirkungen der Kälte.", "Dieser Zauber schützt vor den Auswirkungen der Kälte.",
(cdesc_fun)cinfo_kaelteschutz (cdesc_fun)cinfo_kaelteschutz
}, },
{ /* C_STRENGTH, */ { C_STRENGTH, /* */
CURSETYP_UNIT, CURSE_SPREADMODULO, M_MEN,
"Trollstärke", "Trollstärke",
CURSETYP_UNIT, CURSE_SPREADMODULO, M_MEN,
"Dieser Zauber vermehrt die Stärke der verzauberten Personen um ein " "Dieser Zauber vermehrt die Stärke der verzauberten Personen um ein "
"vielfaches.", "vielfaches.",
(cdesc_fun)cinfo_strength (cdesc_fun)cinfo_strength
}, },
{ /* C_ALLSKILLS, Alp */ { C_ALLSKILLS, /* Alp */
CURSETYP_UNIT, CURSE_SPREADMODULO, M_MEN,
"", "",
CURSETYP_UNIT, CURSE_SPREADMODULO, M_MEN,
"", "",
(cdesc_fun)cinfo_allskills (cdesc_fun)cinfo_allskills
}, },
{ /* C_MAGICRESISTANCE, */ { C_MAGICRESISTANCE, /* */
CURSETYP_UNIT, CURSE_SPREADMODULO, M_MEN,
"Magieschutz", "Magieschutz",
CURSETYP_UNIT, CURSE_SPREADMODULO, M_MEN,
"Dieser Zauber verstärkt die natürliche Widerstandskraft gegen eine " "Dieser Zauber verstärkt die natürliche Widerstandskraft gegen eine "
"Verzauberung.", "Verzauberung.",
NULL NULL
}, },
{ /* C_ITEMCLOAK, */ { C_ITEMCLOAK, /* */
CURSETYP_UNIT, CURSE_SPREADNEVER, M_DURATION,
"Schleieraura", "Schleieraura",
CURSETYP_UNIT, CURSE_SPREADNEVER, M_DURATION,
"Dieser Zauber macht die Ausrüstung unsichtbar.", "Dieser Zauber macht die Ausrüstung unsichtbar.",
(cdesc_fun)cinfo_itemcloak (cdesc_fun)cinfo_itemcloak
}, },
{ /* C_SPARKLE, */ { C_SPARKLE, /* */
CURSETYP_UNIT, CURSE_SPREADMODULO, ( M_MEN | M_DURATION ),
"Leichte Verzauberung", "Leichte Verzauberung",
CURSETYP_UNIT, CURSE_SPREADMODULO, ( M_MEN | M_DURATION ),
"Dieser Zauber ist einer der ersten, den junge Magier in der Schule lernen.", "Dieser Zauber ist einer der ersten, den junge Magier in der Schule lernen.",
(cdesc_fun)cinfo_sparkle (cdesc_fun)cinfo_sparkle
}, },
{ /* C_FREE_22, */ { C_FREE_22, /* */
CURSETYP_UNIT, 0, (NO_MERGE),
"", "",
CURSETYP_UNIT, 0, (NO_MERGE),
"", "",
NULL NULL
}, },
{ /* C_FREE_23, */ { C_FREE_23, /* */
CURSETYP_UNIT, 0, (NO_MERGE),
"", "",
CURSETYP_UNIT, 0, (NO_MERGE),
"", "",
NULL NULL
}, },
{ /* C_FREE_24, */ { C_FREE_24, /* */
CURSETYP_UNIT, 0, (NO_MERGE),
"", "",
CURSETYP_UNIT, 0, (NO_MERGE),
"", "",
NULL NULL
}, },
/* struct's vom typ curse_skill: */ /* struct's vom typ curse_skill: */
{ /* C_SKILL, */ { C_SKILL, /* */
CURSETYP_SKILL, CURSE_SPREADMODULO, M_MEN,
"", "",
CURSETYP_SKILL, CURSE_SPREADMODULO, M_MEN,
"", "",
(cdesc_fun)cinfo_skill (cdesc_fun)cinfo_skill
}, },
{ /* C_FREE_30, */ { C_FREE_30, /* */
CURSETYP_UNIT, 0, (NO_MERGE),
"", "",
CURSETYP_UNIT, 0, (NO_MERGE),
"", "",
NULL NULL
}, },
{ /* C_FREE_31, */ { C_FREE_31, /* */
CURSETYP_UNIT, 0, (NO_MERGE),
"", "",
CURSETYP_UNIT, 0, (NO_MERGE),
"", "",
NULL NULL
}, },
{ /* C_FREE_32, */ { C_FREE_32, /* */
CURSETYP_UNIT, 0, (NO_MERGE),
"", "",
CURSETYP_UNIT, 0, (NO_MERGE),
"", "",
NULL NULL
}, },

View File

@ -179,8 +179,8 @@ enum {
#define NO_MERGE 0 /* erzeugt jedesmal einen neuen Zauber */ #define NO_MERGE 0 /* erzeugt jedesmal einen neuen Zauber */
#define M_DURATION 1 /* Die Zauberdauer ist die maximale Dauer beider */ #define M_DURATION 1 /* Die Zauberdauer ist die maximale Dauer beider */
#define M_SUMDURATION 2 /* die Dauer des Zaubers wird summiert */ #define M_SUMDURATION 2 /* die Dauer des Zaubers wird summiert */
#define M_MAXEFFECT 4 /* der Effekt summiert sich */ #define M_MAXEFFECT 4 /* der Effekt ist der maximale Effekt beider */
#define M_SUMEFFECT 8 /* der Effekt ist der maximale Effekt beider */ #define M_SUMEFFECT 8 /* der Effekt summiert sich */
#define M_MEN 16 /* die Anzahl der betroffenen Personen summiert #define M_MEN 16 /* die Anzahl der betroffenen Personen summiert
sich */ sich */
#define M_VIGOUR 32 /* das Maximum der beiden Stärken wird die #define M_VIGOUR 32 /* das Maximum der beiden Stärken wird die
@ -193,8 +193,8 @@ enum {
typedef struct curse { typedef struct curse {
struct curse *nexthash; struct curse *nexthash;
int no; /* 'Einheitennummer' dieses Curse */ int no; /* 'Einheitennummer' dieses Curse */
struct curse_type * type; /* Zeiger auf ein curse_type-struct */
curse_t cspellid; /* Id des Cursezaubers */ curse_t cspellid; /* Id des Cursezaubers */
const struct curse_type * type; /* Zeiger auf ein curse_type-struct */
int flag; /* generelle Flags wie zb CURSE_ISNEW oder CURSE_NOAGE */ int flag; /* generelle Flags wie zb CURSE_ISNEW oder CURSE_NOAGE */
int duration; /* Dauer der Verzauberung. Wird jede Runde vermindert */ int duration; /* Dauer der Verzauberung. Wird jede Runde vermindert */
int vigour; /* Stärke der Verzauberung, Widerstand gegen Antimagie */ int vigour; /* Stärke der Verzauberung, Widerstand gegen Antimagie */
@ -237,11 +237,11 @@ typedef int (*cdesc_fun)(const void*, int, curse*, int);
/* ------------------------------------------------------------- */ /* ------------------------------------------------------------- */
typedef struct curse_type { typedef struct curse_type {
curse_t cspellid; /* Id des Cursezaubers */
const char *name; /* Name der Zauberwirkung, Identifizierung des curse */
int typ; int typ;
int givemenacting; int givemenacting;
int mergeflags; int mergeflags;
const char *name; /* Name der Zauberwirkung, wird bei gezielter Antimagie
zur Identifizierung des curse genutzt */
const char *info; /* Wirkung des curse, wird bei einer gelungenen const char *info; /* Wirkung des curse, wird bei einer gelungenen
Zauberanalyse angezeigt */ Zauberanalyse angezeigt */
int (*curseinfo)(const void*, int, curse*, int); int (*curseinfo)(const void*, int, curse*, int);
@ -309,7 +309,7 @@ void set_cursevigour(struct attrib *ap, curse_t id, int id2, int i);
int change_cursevigour(struct attrib **ap, curse_t id, int id2, int i); int change_cursevigour(struct attrib **ap, curse_t id, int id2, int i);
/* verändert die Stärke der Verzauberung um i */ /* verändert die Stärke der Verzauberung um i */
int get_cursedmen(struct attrib *ap, curse_t id, int id2); int get_cursedmen(struct unit *u, struct curse *c);
/* gibt bei Personenbeschränkten Verzauberungen die Anzahl der /* gibt bei Personenbeschränkten Verzauberungen die Anzahl der
* betroffenen Personen zurück. Ansonsten wird 0 zurückgegeben. */ * betroffenen Personen zurück. Ansonsten wird 0 zurückgegeben. */
int change_cursedmen(struct attrib **ap, curse_t id, int id2, int cursedmen); int change_cursedmen(struct attrib **ap, curse_t id, int id2, int cursedmen);
@ -365,5 +365,7 @@ extern boolean is_spell_active(const struct region * r, curse_t id);
/* prüft, ob ein bestimmter Zauber auf einer struct region liegt */ /* prüft, ob ein bestimmter Zauber auf einer struct region liegt */
extern boolean is_cursed_with(attrib *ap, curse *c); extern boolean is_cursed_with(attrib *ap, curse *c);
const curse_type * find_cursetype(curse_t id);
#endif #endif

View File

@ -1199,6 +1199,7 @@ int
magic_resistance(unit *target) magic_resistance(unit *target)
{ {
attrib * a; attrib * a;
curse *c;
int chance; int chance;
int n; int n;
@ -1209,9 +1210,9 @@ magic_resistance(unit *target)
chance += effskill(target, SK_MAGIC)*5; chance += effskill(target, SK_MAGIC)*5;
/* Auswirkungen von Zaubern auf der Einheit */ /* Auswirkungen von Zaubern auf der Einheit */
if (is_cursed(target->attribs, C_MAGICRESISTANCE, 0)) { c = get_curse(target->attribs, C_MAGICRESISTANCE, 0);
chance += get_curseeffect(target->attribs, C_MAGICRESISTANCE, 0) * if (c) {
get_cursedmen(target->attribs, C_MAGICRESISTANCE, 0) / target->number; chance += get_curseeffect(target->attribs, C_MAGICRESISTANCE, 0) * get_cursedmen(target, c);
} }
/* Unicorn +10 */ /* Unicorn +10 */

View File

@ -959,10 +959,12 @@ travel(region * first, unit * u, region * next, int flucht)
dk = u->race->speed; dk = u->race->speed;
if(is_cursed(u->attribs, C_SPEED, 0)) { {
int men = get_cursedmen(u->attribs, C_SPEED, 0); curse *c = get_curse(u->attribs, C_SPEED, 0);
men = max(u->number, men); if(c) {
dk *= 1.0 + men/(double)u->number; int men = get_cursedmen(u, c);
dk *= 1.0 + (double)men/(double)u->number;
}
} }
switch(canride(u)) { switch(canride(u)) {

View File

@ -103,8 +103,6 @@ rc_find(const char * name)
return rc; return rc;
} }
/* TODO: Tragkraft in die Struktur */
/** dragon movement **/ /** dragon movement **/
boolean boolean
allowed_dragon(const region * src, const region * target) allowed_dragon(const region * src, const region * target)
@ -648,6 +646,7 @@ tagbegin(struct xml_stack * stack)
if (xml_bvalue(tag, "shapeshiftany")) rc->flags |= RCF_SHAPESHIFTANY; if (xml_bvalue(tag, "shapeshiftany")) rc->flags |= RCF_SHAPESHIFTANY;
if (xml_bvalue(tag, "illusionary")) rc->flags |= RCF_ILLUSIONARY; if (xml_bvalue(tag, "illusionary")) rc->flags |= RCF_ILLUSIONARY;
if (xml_bvalue(tag, "undead")) rc->flags |= RCF_UNDEAD; if (xml_bvalue(tag, "undead")) rc->flags |= RCF_UNDEAD;
if (xml_bvalue(tag, "dragon")) rc->flags |= RCF_DRAGON;
if (xml_bvalue(tag, "nogive")) rc->ec_flags |= NOGIVE; if (xml_bvalue(tag, "nogive")) rc->ec_flags |= NOGIVE;
if (xml_bvalue(tag, "giveitem")) rc->ec_flags |= GIVEITEM; if (xml_bvalue(tag, "giveitem")) rc->ec_flags |= GIVEITEM;

View File

@ -116,6 +116,7 @@ extern int rc_specialdamage(const race *, const race *, const struct weapon_type
#define RCF_SHAPESHIFT (1<<18) /* Kann TARNE RASSE benutzen. */ #define RCF_SHAPESHIFT (1<<18) /* Kann TARNE RASSE benutzen. */
#define RCF_SHAPESHIFTANY (1<<19) /* Kann TARNE RASSE "string" benutzen. */ #define RCF_SHAPESHIFTANY (1<<19) /* Kann TARNE RASSE "string" benutzen. */
#define RCF_UNDEAD (1<<20) /* Undead. */ #define RCF_UNDEAD (1<<20) /* Undead. */
#define RCF_DRAGON (1<<21) /* Drachenart (für Zauber)*/
/* Economic flags */ /* Economic flags */
#define NOGIVE (1<<0) /* gibt niemals nix */ #define NOGIVE (1<<0) /* gibt niemals nix */

View File

@ -1369,7 +1369,7 @@ curse_write(const attrib * a,FILE * f) {
fprintf(f, "%d %d %d %d %d %d %d ", c->no, (int)c->cspellid, flag, fprintf(f, "%d %d %d %d %d %d %d ", c->no, (int)c->cspellid, flag,
c->duration, c->vigour, mage_no, c->effect); c->duration, c->vigour, mage_no, c->effect);
switch(cursedaten[c->cspellid].typ){ switch(c->type->typ){
case CURSETYP_UNIT: case CURSETYP_UNIT:
{ {
curse_unit * cc = (curse_unit*)c->data; curse_unit * cc = (curse_unit*)c->data;
@ -1409,10 +1409,9 @@ curse_read(attrib * a, FILE * f) {
&c->duration, &c->vigour, &mageid, &c->effect); &c->duration, &c->vigour, &mageid, &c->effect);
} }
c->type = &cursedaten[cspellid]; c->type = find_cursetype((curse_t)cspellid);
c->cspellid = (curse_t)cspellid; c->cspellid = (curse_t)cspellid;
/* beim Einlesen sind noch nicht alle units da, muss also /* beim Einlesen sind noch nicht alle units da, muss also
* zwischengespeichert werden. */ * zwischengespeichert werden. */
if (mageid == -1){ if (mageid == -1){
@ -1421,7 +1420,7 @@ curse_read(attrib * a, FILE * f) {
ur_add((void*)mageid, (void**)&c->magician, resolve_unit); ur_add((void*)mageid, (void**)&c->magician, resolve_unit);
} }
switch(cursedaten[cspellid].typ){ switch(c->type->typ){
case CURSETYP_UNIT: case CURSETYP_UNIT:
{ {
curse_unit * cc = calloc(1, sizeof(curse_unit)); curse_unit * cc = calloc(1, sizeof(curse_unit));

View File

@ -371,23 +371,23 @@ destr_curse(curse* c, int cast_level, int force)
int int
destroy_curse(attrib **alist, int cast_level, int force, destroy_curse(attrib **alist, int cast_level, int force,
const curse_type * ctype) curse * c)
{ {
int succ = 0; int succ = 0;
/* attrib **a = a_find(*ap, &at_curse); */ /* attrib **a = a_find(*ap, &at_curse); */
attrib ** ap = alist; attrib ** ap = alist;
while (*ap && force > 0) { while (*ap && force > 0) {
curse * c; curse * c1;
attrib * a = *ap; attrib * a = *ap;
if (!fval(a->type, ATF_CURSE)) { if (!fval(a->type, ATF_CURSE)) {
do { ap = &(*ap)->next; } while (*ap && a->type==(*ap)->type); do { ap = &(*ap)->next; } while (*ap && a->type==(*ap)->type);
continue; continue;
} }
c = (curse*)a->data.v; c1 = (curse*)a->data.v;
/* Immunität prüfen */ /* Immunität prüfen */
if (c->flag & CURSE_IMMUN) { if (c1->flag & CURSE_IMMUN) {
do { ap = &(*ap)->next; } while (*ap && a->type==(*ap)->type); do { ap = &(*ap)->next; } while (*ap && a->type==(*ap)->type);
continue; continue;
} }
@ -395,7 +395,7 @@ destroy_curse(attrib **alist, int cast_level, int force,
/* Wenn kein spezieller cursetyp angegeben ist, soll die Antimagie /* Wenn kein spezieller cursetyp angegeben ist, soll die Antimagie
* auf alle Verzauberungen wirken. Ansonsten prüfe, ob der Curse vom * auf alle Verzauberungen wirken. Ansonsten prüfe, ob der Curse vom
* richtigen Typ ist. */ * richtigen Typ ist. */
if(!ctype || c->type==ctype) { if(!c || c==c1) {
int n; int n;
n = destr_curse(c, cast_level, force); n = destr_curse(c, cast_level, force);
if (n != force){ if (n != force){
@ -673,7 +673,7 @@ sp_destroy_magic(castorder *co)
int cast_level = co->level; int cast_level = co->level;
int force = co->force; int force = co->force;
spellparameter *pa = co->par; spellparameter *pa = co->par;
const curse_type * ctype; curse * c = NULL;
char ts[80]; char ts[80];
attrib **ap; attrib **ap;
int obj; int obj;
@ -685,7 +685,6 @@ sp_destroy_magic(castorder *co)
/* Objekt ermitteln */ /* Objekt ermitteln */
obj = pa->param[0]->typ; obj = pa->param[0]->typ;
ctype = NULL;
switch(obj) { switch(obj) {
case SPP_REGION: case SPP_REGION:
@ -723,7 +722,7 @@ sp_destroy_magic(castorder *co)
return 0; return 0;
} }
succ = destroy_curse(ap, cast_level, force, ctype); succ = destroy_curse(ap, cast_level, force, c);
if(succ) { if(succ) {
add_message(&mage->faction->msgs, new_message(mage->faction, add_message(&mage->faction->msgs, new_message(mage->faction,
@ -4873,6 +4872,100 @@ sp_depression(castorder *co)
return cast_level; return cast_level;
} }
/* ------------------------------------------------------------- */
/* Name: Hoher Gesang der Drachen
* Stufe: 14
* Gebiet: Cerddor
* Kategorie: Monster, Beschwörung, positiv
*
* Wirkung:
* Erhöht HP-Regeneration in der Region und lockt drachenartige (Wyrm,
* Drache, Jungdrache, Seeschlange, ...) aus der Umgebung an
*
* Flag:
* (FARCASTING | REGIONSPELL | TESTRESISTANCE)
*/
/* TODO zur Aktivierung in Zauberliste aufnehmen*/
static int
sp_dragonsong(castorder *co)
{
region *r = co->rt; /* Zauberregion */
unit *mage = (unit *)co->magician;
unit *u;
int cast_level = co->level;
int power = co->force;
regionlist *rl,*rl2;
faction *f;
int range;
/* TODO HP-Effekt */
f = findfaction(MONSTER_FACTION);
range = power;
rl = all_in_range(r, range);
for(rl2 = rl; rl2; rl2 = rl2->next) {
for(u = rl2->region->units; u; u = u->next) {
if (u->race->flags & RCF_DRAGON) {
attrib * a = a_find(u->attribs, &at_targetregion);
if (!a) {
a = a_add(&u->attribs, make_targetregion(r));
} else {
a->data.v = r;
}
sprintf(buf, "Kommt aus: %s, Will nach: %s", regionid(rl2->region), regionid(r));
usetprivate(u, buf);
}
}
}
add_message(&mage->faction->msgs, new_message(mage->faction,
"summondragon%u:unit%r:region%s:command%u:unit%r:region",
mage, mage->region, strdup(co->order),mage, co->rt));
free_regionlist(rl);
return cast_level;
}
/* ------------------------------------------------------------- */
/* Name: Hoher Gesang der Verlockung
* Stufe: 17
* Gebiet: Cerddor
* Kategorie: Monster, Beschwörung, positiv
*
* Wirkung:
* Lockt Bauern aus den umliegenden Regionen her
*
* Flag:
* (FARCASTING | REGIONSPELL | TESTRESISTANCE)
*/
/* TODO zur Aktivierung in Zauberliste aufnehmen*/
static int
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;
/* 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));
return cast_level;
}
/* ------------------------------------------------------------- */ /* ------------------------------------------------------------- */
/* TRAUM - Illaun */ /* TRAUM - Illaun */
/* ------------------------------------------------------------- */ /* ------------------------------------------------------------- */
@ -6819,11 +6912,11 @@ sp_speed2(castorder *co)
* Kann eine bestimmte Verzauberung angreifen und auflösen. Die Stärke * Kann eine bestimmte Verzauberung angreifen und auflösen. Die Stärke
* des Zaubers muss stärker sein als die der Verzauberung. * des Zaubers muss stärker sein als die der Verzauberung.
* Syntax: * Syntax:
* ZAUBERE \"Magiefresser\" REGION [Zaubername] * ZAUBERE \"Magiefresser\" REGION
* ZAUBERE \"Magiefresser\" EINHEIT <Einheit-Nr> [Zaubername] * ZAUBERE \"Magiefresser\" EINHEIT <Einheit-Nr>
* ZAUBERE \"Magiefresser\" BURG <Burg-Nr> [Zaubername] * ZAUBERE \"Magiefresser\" BURG <Burg-Nr>
* ZAUBERE \"Magiefresser\" GEBÄUDE <Gebäude-Nr> [Zaubername] * ZAUBERE \"Magiefresser\" GEBÄUDE <Gebäude-Nr>
* ZAUBERE \"Magiefresser\" SCHIFF <Schiff-Nr> [Zaubername] * ZAUBERE \"Magiefresser\" SCHIFF <Schiff-Nr>
* *
* "kc?c" * "kc?c"
* Flags: * Flags:
@ -6836,7 +6929,7 @@ sp_q_antimagie(castorder *co)
{ {
attrib **ap; attrib **ap;
int obj; int obj;
const curse_type * ctype; curse * c = NULL;
int succ; int succ;
region *r = co->rt; region *r = co->rt;
unit *mage = (unit *)co->magician; unit *mage = (unit *)co->magician;
@ -6847,10 +6940,6 @@ sp_q_antimagie(castorder *co)
obj = pa->param[0]->typ; obj = pa->param[0]->typ;
ctype = NULL;
if(pa->length == 2)
ctype = ct_find(pa->param[1]->data.s);
switch(obj){ switch(obj){
case SPP_REGION: case SPP_REGION:
ap = &r->attribs; ap = &r->attribs;
@ -6884,7 +6973,7 @@ sp_q_antimagie(castorder *co)
return 0; return 0;
} }
succ = destroy_curse(ap, cast_level, force, ctype); succ = destroy_curse(ap, cast_level, force, c);
if(succ) { if(succ) {
add_message(&mage->faction->msgs, new_message(mage->faction, add_message(&mage->faction->msgs, new_message(mage->faction,
@ -9940,6 +10029,27 @@ spell spelldaten[] =
(spell_f)sp_createitem_trueseeing, patzer_createitem (spell_f)sp_createitem_trueseeing, patzer_createitem
}, },
{SPL_TYBIED_DESTROY_MAGIC, "Magiefresser",
"Dieser Zauber ermöglicht dem Magier, Verzauberungen einer Einheit, "
"eines Schiffes, Gebäudes oder auch der Region aufzulösen.",
"ZAUBERE [REGION x y] [STUFE n] \"Magiefresser\" REGION\n"
"ZAUBERE [REGION x y] [STUFE n] \"Magiefresser\" EINHEIT <Einheit-Nr>\n"
"ZAUBERE [REGION x y] [STUFE n] \"Magiefresser\" BURG <Burg-Nr>\n"
"ZAUBERE [REGION x y] [STUFE n] \"Magiefresser\" GEBÄUDE <Gebäude-Nr>\n"
"ZAUBERE [REGION x y] [STUFE n] \"Magiefresser\" SCHIFF <Schiff-Nr>",
"kc",
M_ASTRAL,
(FARCASTING | SPELLLEVEL | ONSHIPCAST | ONETARGET | TESTCANSEE),
2, 5,
{
{R_AURA, 4, SPC_LEVEL},
{0, 0, 0},
{0, 0, 0},
{0, 0, 0},
{0, 0, 0}},
(spell_f)sp_destroy_magic, patzer
},
{SPL_PULLASTRAL, "Astraler Ruf", {SPL_PULLASTRAL, "Astraler Ruf",
"Ein Magier, der sich in der astralen Ebene befindet, kann mit Hilfe " "Ein Magier, der sich in der astralen Ebene befindet, kann mit Hilfe "
"dieses Zaubers andere Einheiten zu sich holen. Der Magier kann " "dieses Zaubers andere Einheiten zu sich holen. Der Magier kann "
@ -10050,27 +10160,24 @@ spell spelldaten[] =
(spell_f)sp_create_antimagiccrystal, patzer_createitem (spell_f)sp_create_antimagiccrystal, patzer_createitem
}, },
{SPL_Q_ANTIMAGIE, "Magiefresser", {SPL_DESTROY_MAGIC, "Fluch brechen",
"Dieser Zauber ermöglicht dem Magier, gezielt eine bestimmte " "Dieser Zauber ermöglicht dem Magier, gezielt eine bestimmte "
"Verzauberung einer Einheit, eines Schiffes, Gebäudes oder auch " "Verzauberung einer Einheit, eines Schiffes, Gebäudes oder auch "
"der Region aufzulösen. Dazu muss er den Namen des Fluchs, " "der Region aufzulösen.",
"den er aufheben will, beim Zaubern angeben. Ist der Name ihm " "ZAUBERE [REGION x y] [STUFE n] \"Fluch brechen\" REGION <Zauber-Nr>\n"
"unbekannt, so wird der Zauberspruch zufällig gegen irgendeine " "ZAUBERE [REGION x y] [STUFE n] \"Fluch brechen\" EINHEIT <Einheit-Nr> <Zauber-Nr>\n"
"Verzauberung des Ziels wirken.", "ZAUBERE [REGION x y] [STUFE n] \"Fluch brechen\" BURG <Burg-Nr> <Zauber-Nr>\n"
"ZAUBERE [REGION x y] [STUFE n] \"Magiefresser\" REGION [Zaubername]\n" "ZAUBERE [REGION x y] [STUFE n] \"Fluch brechen\" GEBÄUDE <Gebäude-Nr> <Zauber-Nr>\n"
"ZAUBERE [REGION x y] [STUFE n] \"Magiefresser\" EINHEIT <Einheit-Nr> [Zaubername]\n" "ZAUBERE [REGION x y] [STUFE n] \"Fluch brechen\" SCHIFF <Schiff-Nr> <Zauber-Nr>",
"ZAUBERE [REGION x y] [STUFE n] \"Magiefresser\" BURG <Burg-Nr> [Zaubername]\n" "kcc",
"ZAUBERE [REGION x y] [STUFE n] \"Magiefresser\" GEBÄUDE <Gebäude-Nr> [Zaubername]\n" M_ASTRAL, (FARCASTING | SPELLLEVEL | ONSHIPCAST | TESTCANSEE), 3, 7,
"ZAUBERE [REGION x y] [STUFE n] \"Magiefresser\" SCHIFF <Schiff-Nr> [Zaubername]", {
"kc?c",
M_ASTRAL, (FARCASTING | SPELLLEVEL | ONSHIPCAST | TESTCANSEE), 3, 7,
{
{R_AURA, 3, SPC_LEVEL}, {R_AURA, 3, SPC_LEVEL},
{0, 0, 0}, {0, 0, 0},
{0, 0, 0}, {0, 0, 0},
{0, 0, 0}, {0, 0, 0},
{0, 0, 0}}, {0, 0, 0}},
(spell_f)sp_q_antimagie, patzer (spell_f)sp_destroy_curse, patzer
}, },
{SPL_ETERNIZEWALL, "Mauern der Ewigkeit", {SPL_ETERNIZEWALL, "Mauern der Ewigkeit",

View File

@ -131,8 +131,8 @@ enum {
SPL_ANALYSEDREAM, SPL_ANALYSEDREAM,
SPL_UNIT_ANALYSESONG, SPL_UNIT_ANALYSESONG,
SPL_OBJ_ANALYSESONG, SPL_OBJ_ANALYSESONG,
SPL_Q_ANTIMAGIE, /* alt */ SPL_TYBIED_DESTROY_MAGIC,
SPL_DESTROY_MAGIC, /* gibs nicht mehr */ SPL_DESTROY_MAGIC,
SPL_METEORRAIN, SPL_METEORRAIN,
SPL_REDUCESHIELD, SPL_REDUCESHIELD,
SPL_ARMORSHIELD, SPL_ARMORSHIELD,

View File

@ -582,6 +582,8 @@ show_newspells(void)
spellid_t newspellids[] = { spellid_t newspellids[] = {
SPL_IRONKEEPER, SPL_IRONKEEPER,
SPL_BLOODSACRIFICE, SPL_BLOODSACRIFICE,
SPL_TYBIED_DESTROY_MAGIC,
SPL_DESTROY_MAGIC,
SPL_NOSPELL }; SPL_NOSPELL };
/* die id's der neuen oder veränderten Sprüche werden in newspellids[] /* die id's der neuen oder veränderten Sprüche werden in newspellids[]