forked from github/server
"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:
parent
146ccca658
commit
7077587834
|
@ -119,16 +119,21 @@ curse_age(attrib * a)
|
|||
}
|
||||
|
||||
void
|
||||
curse_done(attrib * a) {
|
||||
curse *c = (curse *)a->data.v;
|
||||
|
||||
destroy_curse(curse * c)
|
||||
{
|
||||
cunhash(c);
|
||||
|
||||
if( c->data.v && c->type->typ == CURSETYP_UNIT)
|
||||
if (c->data.v && c->type->typ == CURSETYP_UNIT) {
|
||||
free(c->data.v);
|
||||
}
|
||||
free(c);
|
||||
}
|
||||
|
||||
void
|
||||
curse_done(attrib * a) {
|
||||
destroy_curse((curse *)a->data.v);
|
||||
}
|
||||
|
||||
/* ------------------------------------------------------------- */
|
||||
|
||||
int
|
||||
|
@ -178,6 +183,9 @@ curse_read(attrib * a, FILE * f) {
|
|||
c->data.v = cc;
|
||||
fscanf(f, "%d ", &cc->cursedmen);
|
||||
}
|
||||
if (c->type->typ == CURSETYP_REGION) {
|
||||
read_region_reference((region**)&c->data.v, f);
|
||||
}
|
||||
chash(c);
|
||||
|
||||
return AT_READ_OK;
|
||||
|
@ -206,6 +214,9 @@ curse_write(const attrib * a, FILE * f) {
|
|||
curse_unit * cc = (curse_unit*)c->data.v;
|
||||
fprintf(f, "%d ", cc->cursedmen);
|
||||
}
|
||||
if (c->type->typ == CURSETYP_REGION) {
|
||||
write_region_reference((region*)c->data.v, f);
|
||||
}
|
||||
}
|
||||
|
||||
attrib_type at_curse =
|
||||
|
|
|
@ -170,6 +170,7 @@ typedef enum {
|
|||
enum {
|
||||
CURSETYP_NORM,
|
||||
CURSETYP_UNIT,
|
||||
CURSETYP_REGION, /* stores the region in c->data.v */
|
||||
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.
|
||||
*/
|
||||
|
||||
extern void destroy_curse(curse * c);
|
||||
|
||||
|
||||
boolean is_cursed_internal(struct attrib *ap, const curse_type * ctype);
|
||||
/* ignoriert CURSE_ISNEW */
|
||||
|
||||
|
|
|
@ -16,13 +16,13 @@
|
|||
#include <eressea.h>
|
||||
#include "spells.h"
|
||||
|
||||
#include "regioncurse.h"
|
||||
#include "alp.h"
|
||||
#include "combatspells.h"
|
||||
|
||||
#include <curse.h>
|
||||
|
||||
struct curse_type;
|
||||
extern const struct curse_type ct_firewall;
|
||||
extern void ct_register(const struct curse_type * ct);
|
||||
|
||||
/* kernel includes */
|
||||
|
@ -326,7 +326,7 @@ destr_curse(curse* c, int cast_level, double force)
|
|||
}
|
||||
|
||||
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;
|
||||
/* attrib **a = a_find(*ap, &at_curse); */
|
||||
|
@ -692,7 +692,7 @@ sp_destroy_magic(castorder *co)
|
|||
return 0;
|
||||
}
|
||||
|
||||
succ = destroy_curse(ap, cast_level, force, c);
|
||||
succ = break_curse(ap, cast_level, force, c);
|
||||
|
||||
if (succ) {
|
||||
ADDMSG(&mage->faction->msgs, msg_message(
|
||||
|
@ -3182,36 +3182,38 @@ sp_unholypower(castorder *co)
|
|||
* (FARCASTING | REGIONSPELL | TESTRESISTANCE)
|
||||
*/
|
||||
|
||||
typedef struct dc_data {
|
||||
region * r;
|
||||
unit * mage;
|
||||
double strength;
|
||||
int countdown;
|
||||
boolean active;
|
||||
} dc_data;
|
||||
static struct curse_type ct_deathcloud = {
|
||||
"deathcloud", CURSETYP_REGION, 0, NO_MERGE, NULL, cinfo_region,
|
||||
};
|
||||
|
||||
static void
|
||||
dc_initialize(struct attrib *a)
|
||||
static curse *
|
||||
mk_deathcloud(unit * mage, region * r, double force, int duration)
|
||||
{
|
||||
dc_data * data = (dc_data *)malloc(sizeof(dc_data));
|
||||
a->data.v = data;
|
||||
data->active = true;
|
||||
variant effect;
|
||||
curse * c;
|
||||
|
||||
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
|
||||
dc_finalize(struct attrib * a)
|
||||
{
|
||||
free(a->data.v);
|
||||
curse * c = (curse*)a->data.v;
|
||||
c->data.v = NULL;
|
||||
destroy_curse(c);
|
||||
}
|
||||
|
||||
static int
|
||||
dc_age(struct attrib * a)
|
||||
/* age returns 0 if the attribute needs to be removed, !=0 otherwise */
|
||||
{
|
||||
dc_data * data = (dc_data *)a->data.v;
|
||||
region * r = data->r;
|
||||
curse * c = (curse*)a->data.v;
|
||||
region * r = (region*)c->data.v;
|
||||
unit ** up = &r->units;
|
||||
unit * mage = data->mage;
|
||||
unit * mage = c->magician;
|
||||
unit * u;
|
||||
|
||||
if (mage==NULL || mage->number==0) {
|
||||
|
@ -3219,9 +3221,9 @@ dc_age(struct attrib * a)
|
|||
return 0;
|
||||
}
|
||||
|
||||
if (data->active) while (*up!=NULL) {
|
||||
if (curse_active(c)) while (*up!=NULL) {
|
||||
unit * u = *up;
|
||||
double damage = data->strength * u->number;
|
||||
double damage = c->effect.f * u->number;
|
||||
|
||||
freset(u->faction, FL_DH);
|
||||
if (target_resists_magic(mage, u, TYP_UNIT, 0)){
|
||||
|
@ -3249,45 +3251,50 @@ dc_age(struct attrib * a)
|
|||
"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 = {
|
||||
"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 *
|
||||
mk_deathcloud(unit * mage, region * r, double strength, int duration)
|
||||
#define COMPAT_DEATHCLOUD
|
||||
#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);
|
||||
dc_data * data = (dc_data *)a->data.v;
|
||||
char zId[10];
|
||||
region * r = NULL;
|
||||
unit * u;
|
||||
variant var;
|
||||
int duration;
|
||||
double strength;
|
||||
|
||||
data->countdown = duration;
|
||||
data->r = r;
|
||||
data->mage = mage;
|
||||
data->strength = strength;
|
||||
data->active = false;
|
||||
return a;
|
||||
fscanf(F, "%d %lf %s", &duration, &strength, zId);
|
||||
var.i = atoi36(zId);
|
||||
u = findunit(var.i);
|
||||
|
||||
read_region_reference(&r, F);
|
||||
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
|
||||
sp_deathcloud(castorder *co)
|
||||
|
@ -3302,7 +3309,7 @@ sp_deathcloud(castorder *co)
|
|||
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;
|
||||
}
|
||||
|
@ -6908,7 +6915,7 @@ sp_q_antimagie(castorder *co)
|
|||
return 0;
|
||||
}
|
||||
|
||||
succ = destroy_curse(ap, cast_level, force, c);
|
||||
succ = break_curse(ap, cast_level, force, c);
|
||||
|
||||
if (succ) {
|
||||
ADDMSG(&mage->faction->msgs, msg_message(
|
||||
|
@ -6942,7 +6949,7 @@ sp_q_antimagie(castorder *co)
|
|||
* (FARCASTING | SPELLLEVEL | ONSHIPCAST | TESTCANSEE)
|
||||
*/
|
||||
int
|
||||
sp_destroy_curse(castorder *co)
|
||||
sp_break_curse(castorder *co)
|
||||
{
|
||||
attrib **ap;
|
||||
int obj;
|
||||
|
@ -9026,7 +9033,7 @@ static spelldata spelldaten[] =
|
|||
{ 0, 0, 0 },
|
||||
{ 0, 0, 0 }
|
||||
},
|
||||
(spell_f)sp_destroy_curse, NULL
|
||||
(spell_f)sp_break_curse, NULL
|
||||
},
|
||||
{
|
||||
SPL_ETERNIZEWALL, "eternal_walls", NULL,
|
||||
|
@ -9479,6 +9486,9 @@ register_spells(void)
|
|||
register_alp();
|
||||
/* init_firewall(); */
|
||||
ct_register(&ct_firewall);
|
||||
ct_register(&ct_deathcloud);
|
||||
|
||||
at_register(&at_deathcloud_compat);
|
||||
register_curses();
|
||||
register_function((pf_generic)&sp_wdwpyramid, "wdwpyramid");
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue