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
File diff suppressed because it is too large
Load Diff
|
@ -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 */
|
||||||
|
|
||||||
|
|
|
@ -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");
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue