diff --git a/src/common/kernel/curse.c b/src/common/kernel/curse.c index 85fce269b..7e625e6c6 100644 --- a/src/common/kernel/curse.c +++ b/src/common/kernel/curse.c @@ -554,6 +554,10 @@ create_curse(unit *magician, attrib **ap, curse_t id, int id2, int vigour, int duration, int effect, int men) { curse *c; + + /* die Kraft eines Spruchs darf nicht 0 sein*/ + assert(vigour >= 0); + c = get_curse(*ap, id, id2); if(c && (c->flag & CURSE_ONLYONE)){ @@ -709,6 +713,9 @@ is_cursed(attrib *ap, curse_t id, int id2) if (c->flag & CURSE_ISNEW) return false; + if (c->vigour <= 0) + return false; + return true; } diff --git a/src/common/kernel/item.c b/src/common/kernel/item.c index cae70d098..f17998dd2 100644 --- a/src/common/kernel/item.c +++ b/src/common/kernel/item.c @@ -805,22 +805,44 @@ use_antimagiccrystal(region * r, unit * mage, int amount, strlist * cmdstrings) { int i; for (i=0;i!=amount;++i) { - int effect, power, duration = 2; + int effect, force, duration = 2; spell *sp = find_spellbyid(SPL_ANTIMAGICZONE); + attrib ** ap = &r->attribs; unused(cmdstrings); /* Reduziert die Stärke jedes Spruchs um effect */ - effect = sp->level*4; /* Stufe 5 =~ 15 */ + effect = sp->level; /* Hält Sprüche bis zu einem summierten Gesamtlevel von power aus. * Jeder Zauber reduziert die 'Lebenskraft' (vigour) der Antimagiezone * um seine Stufe */ - power = sp->level * 20; /* Stufe 5 =~ 100 */ + force = sp->level * 20; /* Stufe 5 =~ 100 */ - power = destroy_curse(&r->attribs, effect, power, NULL); + /* Regionszauber auflösen */ + while (*ap && force > 0) { + curse * c; + attrib * a = *ap; + if (!fval(a->type, ATF_CURSE)) { + do { ap = &(*ap)->next; } while (*ap && a->type==(*ap)->type); + continue; + } + c = (curse*)a->data.v; - if(power) { - create_curse(mage, &r->attribs, C_ANTIMAGICZONE, 0, power, duration, effect, 0); + /* Immunität prüfen */ + if (c->flag & CURSE_IMMUN) { + do { ap = &(*ap)->next; } while (*ap && a->type==(*ap)->type); + continue; + } + + force = destr_curse(c, effect, force); + if(c->vigour <= 0) { + a_remove(ap, a); + } + if(*ap) ap = &(*ap)->next; + } + + if(force) { + create_curse(mage, &r->attribs, C_ANTIMAGICZONE, 0, force, duration, effect, 0); } } diff --git a/src/common/kernel/spell.c b/src/common/kernel/spell.c index 734cc0168..85b576b25 100644 --- a/src/common/kernel/spell.c +++ b/src/common/kernel/spell.c @@ -332,6 +332,43 @@ magicanalyse_ship(ship *sh, unit *mage, int force) /* ------------------------------------------------------------- */ /* Antimagie - curse auflösen */ /* ------------------------------------------------------------- */ + +/* Wenn der Curse schwächer ist als der cast_level, dann wird er + * aufgelöst, bzw seine Kraft (vigour) auf 0 gesetzt. + * Ist der cast_level zu gering, hat die Antimagie nur mit einer Chance + * von 100-20*Stufenunterschied % eine Wirkung auf den Curse. Dann wird + * die Kraft des Curse um die halbe Stärke der Antimagie reduziert. + * Zurückgegeben wird der noch unverbrauchte Rest von force. + */ +int +destr_curse(curse* c, int cast_level, int force) +{ + if (cast_level < c->vigour) { /* Zauber ist nicht stark genug */ + int chance; + /* pro Stufe Unterschied -20% */ + chance = (10 + (cast_level - c->vigour)*2); + if(rand()%10 >= chance){ + force -= c->vigour; + if (c->type->change_vigour){ + c->type->change_vigour(c, -(cast_level+1/2)); + } else { + c->vigour -= cast_level+1/2; + } + } + } else { /* Zauber ist stärker als curse */ + if (force >= c->vigour){ /* reicht die Kraft noch aus? */ + force -= c->vigour; + if (c->type->change_vigour){ + c->type->change_vigour(c, -c->vigour); + } else { + c->vigour = 0; + } + + } + } + return force; +} + int destroy_curse(attrib **alist, int cast_level, int force, const curse_type * ctype) @@ -355,29 +392,19 @@ destroy_curse(attrib **alist, int cast_level, int force, continue; } - if(!ctype || c->type==ctype) { /* wirkt auf alle */ - if (cast_level < c->vigour) { /* Zauber ist nicht stark genug */ - int chance; - /* pro Stufe Unterschied -20% */ - chance = (10 + (cast_level - c->vigour)*2); - if(rand()%10 >= chance){ - if (c->type->change_vigour) - c->type->change_vigour(c, -2); - force -= c->vigour; - c->vigour -= 2; - if(c->vigour <= 0) { - a_remove(alist, a); - } - succ = cast_level; - } - } else { /* Zauber ist stärker als curse */ - if (force >= c->vigour){ /* reicht die Kraft noch aus? */ - force -= c->vigour; - if (c->type->change_vigour) - c->type->change_vigour(c, -c->vigour); - a_remove(alist, a); - succ = cast_level; - } + /* Wenn kein spezieller cursetyp angegeben ist, soll die Antimagie + * auf alle Verzauberungen wirken. Ansonsten prüfe, ob der Curse vom + * richtigen Typ ist. */ + if(!ctype || c->type==ctype) { + int n; + n = destr_curse(c, cast_level, force); + if (n != force){ + assert(nvigour <= 0) { + a_remove(ap, a); } } if(*ap) ap = &(*ap)->next; diff --git a/src/common/kernel/spell.h b/src/common/kernel/spell.h index a024e59f9..61e477c89 100644 --- a/src/common/kernel/spell.h +++ b/src/common/kernel/spell.h @@ -213,7 +213,8 @@ int use_item_power(struct region * r, struct unit * u); int use_item_regeneration(struct region * r, struct unit * u); void showspells(struct region *r, struct unit *u); int sp_antimagiczone(struct castorder *co); -int destroy_curse(struct attrib **alist, int cast_level, int force, const struct curse_type * ctype); +int destr_curse(struct curse* c, int cast_level, int force); + /* Kampfzauber */ diff --git a/src/katze.mk b/src/katze.mk index b1a85bda0..19c304857 100644 --- a/src/katze.mk +++ b/src/katze.mk @@ -3,19 +3,17 @@ ifndef ERESSEA export ERESSEA=$(PWD) endif -# CONVERT_TRIGGERS = 1 - # Hier definieren, damit nicht '@gcc' -CC = gcc -DNEW_RESOURCEGROWTH +#CC = gcc -DNEW_RESOURCEGROWTH +CC = gcc-3.0 -D_GNU_SOURCE +DEPEND = @gcc-3.0 -MM -MG -r + AR = ar -CTAGS = ctags -CC = gcc -LD = gcc +CTAGS = ctags-exuberant +LD = gcc-3.0 INSTALL = cp -CFLAGS += -DNEW_RESOURCEGROWTH - -# CFLAGS += -Wshadow +CFLAGS += -minline-all-stringops # Ps = 0 -> Normal (default) # Ps = 1 -> Bold