"Todeswolke läßt sich nicht bannen"

Todeswolke in einen echten curse umgewandelt. Kompatibilitaet zur alten TW sollte gewaehrleistet sein. Alles muss nochmal getestet werden, denk ich.
This commit is contained in:
Enno Rehling 2006-07-28 01:31:23 +00:00
parent 146ccca658
commit 7077587834
3 changed files with 460 additions and 435 deletions

File diff suppressed because it is too large Load Diff

View File

@ -169,7 +169,8 @@ typedef enum {
/* typ von struct */ /* typ von struct */
enum { enum {
CURSETYP_NORM, CURSETYP_NORM,
CURSETYP_UNIT, CURSETYP_UNIT,
CURSETYP_REGION, /* stores the region in c->data.v */
MAXCURSETYP MAXCURSETYP
}; };
@ -254,6 +255,9 @@ curse * create_curse(struct unit *magician, struct attrib**ap, const curse_type
* nochmal gesondert auf min(get_cursedmen, u->number) gesetzt werden. * nochmal gesondert auf min(get_cursedmen, u->number) gesetzt werden.
*/ */
extern void destroy_curse(curse * c);
boolean is_cursed_internal(struct attrib *ap, const curse_type * ctype); boolean is_cursed_internal(struct attrib *ap, const curse_type * ctype);
/* ignoriert CURSE_ISNEW */ /* ignoriert CURSE_ISNEW */

View File

@ -16,13 +16,13 @@
#include <eressea.h> #include <eressea.h>
#include "spells.h" #include "spells.h"
#include "regioncurse.h"
#include "alp.h" #include "alp.h"
#include "combatspells.h" #include "combatspells.h"
#include <curse.h> #include <curse.h>
struct curse_type; struct curse_type;
extern const struct curse_type ct_firewall;
extern void ct_register(const struct curse_type * ct); extern void ct_register(const struct curse_type * ct);
/* kernel includes */ /* kernel includes */
@ -326,7 +326,7 @@ destr_curse(curse* c, int cast_level, double force)
} }
int int
destroy_curse(attrib **alist, int cast_level, double force, curse * c) break_curse(attrib **alist, int cast_level, double force, curse * c)
{ {
int succ = 0; int succ = 0;
/* attrib **a = a_find(*ap, &at_curse); */ /* attrib **a = a_find(*ap, &at_curse); */
@ -692,7 +692,7 @@ sp_destroy_magic(castorder *co)
return 0; return 0;
} }
succ = destroy_curse(ap, cast_level, force, c); succ = break_curse(ap, cast_level, force, c);
if (succ) { if (succ) {
ADDMSG(&mage->faction->msgs, msg_message( ADDMSG(&mage->faction->msgs, msg_message(
@ -3182,36 +3182,38 @@ sp_unholypower(castorder *co)
* (FARCASTING | REGIONSPELL | TESTRESISTANCE) * (FARCASTING | REGIONSPELL | TESTRESISTANCE)
*/ */
typedef struct dc_data { static struct curse_type ct_deathcloud = {
region * r; "deathcloud", CURSETYP_REGION, 0, NO_MERGE, NULL, cinfo_region,
unit * mage; };
double strength;
int countdown;
boolean active;
} dc_data;
static void static curse *
dc_initialize(struct attrib *a) mk_deathcloud(unit * mage, region * r, double force, int duration)
{ {
dc_data * data = (dc_data *)malloc(sizeof(dc_data)); variant effect;
a->data.v = data; curse * c;
data->active = true;
effect.f = (float)force/2;
c = create_curse(mage, &r->attribs, &ct_deathcloud, force, duration, effect, 0);
c->data.v = r;
return c;
} }
static void static void
dc_finalize(struct attrib * a) dc_finalize(struct attrib * a)
{ {
free(a->data.v); curse * c = (curse*)a->data.v;
c->data.v = NULL;
destroy_curse(c);
} }
static int static int
dc_age(struct attrib * a) dc_age(struct attrib * a)
/* age returns 0 if the attribute needs to be removed, !=0 otherwise */ /* age returns 0 if the attribute needs to be removed, !=0 otherwise */
{ {
dc_data * data = (dc_data *)a->data.v; curse * c = (curse*)a->data.v;
region * r = data->r; region * r = (region*)c->data.v;
unit ** up = &r->units; unit ** up = &r->units;
unit * mage = data->mage; unit * mage = c->magician;
unit * u; unit * u;
if (mage==NULL || mage->number==0) { if (mage==NULL || mage->number==0) {
@ -3219,9 +3221,9 @@ dc_age(struct attrib * a)
return 0; return 0;
} }
if (data->active) while (*up!=NULL) { if (curse_active(c)) while (*up!=NULL) {
unit * u = *up; unit * u = *up;
double damage = data->strength * u->number; double damage = c->effect.f * u->number;
freset(u->faction, FL_DH); freset(u->faction, FL_DH);
if (target_resists_magic(mage, u, TYP_UNIT, 0)){ if (target_resists_magic(mage, u, TYP_UNIT, 0)){
@ -3249,46 +3251,51 @@ dc_age(struct attrib * a)
"mage region", mage, r)); "mage region", mage, r));
} }
return --data->countdown; return --c->duration;
} }
static void
dc_write(const struct attrib * a, FILE* F)
{
const dc_data * data = (const dc_data *)a->data.v;
fprintf(F, "%d %lf ", data->countdown, data->strength);
write_unit_reference(data->mage, F);
write_region_reference(data->r, F);
}
static int
dc_read(struct attrib * a, FILE* F)
/* return AT_READ_OK on success, AT_READ_FAIL if attrib needs removal */
{
dc_data * data = (dc_data *)a->data.v;
fscanf(F, "%d %lf ", &data->countdown, &data->strength);
read_unit_reference(&data->mage, F);
return read_region_reference(&data->r, F);
}
attrib_type at_deathcloud = { attrib_type at_deathcloud = {
"zauber_todeswolke", dc_initialize, dc_finalize, dc_age, dc_write, dc_read "curse_dc", curse_init, curse_done, dc_age, curse_write, curse_read, ATF_CURSE
}; };
static attrib * #define COMPAT_DEATHCLOUD
mk_deathcloud(unit * mage, region * r, double strength, int duration) #ifdef COMPAT_DEATHCLOUD
static int
dc_read_compat(struct attrib * a, FILE* F)
/* return AT_READ_OK on success, AT_READ_FAIL if attrib needs removal */
{ {
attrib * a = a_new(&at_deathcloud); char zId[10];
dc_data * data = (dc_data *)a->data.v; region * r = NULL;
unit * u;
variant var;
int duration;
double strength;
data->countdown = duration; fscanf(F, "%d %lf %s", &duration, &strength, zId);
data->r = r; var.i = atoi36(zId);
data->mage = mage; u = findunit(var.i);
data->strength = strength;
data->active = false; read_region_reference(&r, F);
return a; if (r!=NULL) {
variant effect;
curse * c;
effect.f = (float)strength;
c = create_curse(u, &r->attribs, &ct_deathcloud, strength * 2, duration, effect, 0);
if (u==NULL) {
ur_add(var, (void**)&c->magician, resolve_unit);
}
}
return AT_READ_FAIL; /* we don't care for the attribute. */
} }
attrib_type at_deathcloud_compat = {
"zauber_todeswolke", NULL, NULL, NULL, NULL, dc_read_compat
};
#endif
static int static int
sp_deathcloud(castorder *co) sp_deathcloud(castorder *co)
{ {
@ -3302,7 +3309,7 @@ sp_deathcloud(castorder *co)
return 0; return 0;
} }
a_add(&r->attribs, mk_deathcloud(mage, r, co->force/2, co->level)); mk_deathcloud(mage, r, co->force, co->level);
return co->level; return co->level;
} }
@ -6908,7 +6915,7 @@ sp_q_antimagie(castorder *co)
return 0; return 0;
} }
succ = destroy_curse(ap, cast_level, force, c); succ = break_curse(ap, cast_level, force, c);
if (succ) { if (succ) {
ADDMSG(&mage->faction->msgs, msg_message( ADDMSG(&mage->faction->msgs, msg_message(
@ -6942,7 +6949,7 @@ sp_q_antimagie(castorder *co)
* (FARCASTING | SPELLLEVEL | ONSHIPCAST | TESTCANSEE) * (FARCASTING | SPELLLEVEL | ONSHIPCAST | TESTCANSEE)
*/ */
int int
sp_destroy_curse(castorder *co) sp_break_curse(castorder *co)
{ {
attrib **ap; attrib **ap;
int obj; int obj;
@ -9026,7 +9033,7 @@ static spelldata spelldaten[] =
{ 0, 0, 0 }, { 0, 0, 0 },
{ 0, 0, 0 } { 0, 0, 0 }
}, },
(spell_f)sp_destroy_curse, NULL (spell_f)sp_break_curse, NULL
}, },
{ {
SPL_ETERNIZEWALL, "eternal_walls", NULL, SPL_ETERNIZEWALL, "eternal_walls", NULL,
@ -9479,6 +9486,9 @@ register_spells(void)
register_alp(); register_alp();
/* init_firewall(); */ /* init_firewall(); */
ct_register(&ct_firewall); ct_register(&ct_firewall);
ct_register(&ct_deathcloud);
at_register(&at_deathcloud_compat);
register_curses(); register_curses();
register_function((pf_generic)&sp_wdwpyramid, "wdwpyramid"); register_function((pf_generic)&sp_wdwpyramid, "wdwpyramid");
} }