- new l2 death spell: "field of decay" - damage objects / lfs made from organic material

- If not in battle, praying to Hecta will restore stamina / mana, and sometimes cast field of decay
This commit is contained in:
Rob Pearce 2016-05-31 12:23:39 +10:00
parent 234ad74cf6
commit 8ed4b9aca0
6 changed files with 158 additions and 32 deletions

11
data.c
View File

@ -4057,7 +4057,7 @@ void initobjects(void) {
// death magic / necromancy
///////////////////
// l1
addot(OT_S_BLIGHT, "blight", "Covers the target location with a miasma of decay, tainting food and damaging living beings.", MT_NOTHING, 0, OC_SPELL, SZ_TINY);
addot(OT_S_BLIGHT, "blight", "Covers the target location with a miasma of sickness, tainting food and damaging living beings.", MT_NOTHING, 0, OC_SPELL, SZ_TINY);
addflag(lastot->flags, F_EXTRADESC, NA, NA, NA, "Spell power determines damage and amount of food affected.");
addflag(lastot->flags, F_SPELLSCHOOL, SS_DEATH, NA, NA, NULL);
addflag(lastot->flags, F_SPELLLEVEL, 1, NA, NA, NULL);
@ -4094,6 +4094,15 @@ void initobjects(void) {
addflag(lastot->flags, F_TARGETTEDSPELL, TT_MONSTER, NA, NA, NULL);
addflag(lastot->flags, F_AICASTTOATTACK, ST_VICTIM, NA, NA, NULL);
addflag(lastot->flags, F_LOSLOF, B_TRUE, LOF_DONTNEED, NA, NULL);
addot(OT_S_DECAYFIELD, "field of decay", "Emits a circular field unnatural deterioration, causing damage to all organic matter.", MT_NOTHING, 0, OC_SPELL, SZ_TINY);
addflag(lastot->flags, F_EXTRADESC, NA, NA, NA, "Spell power determines size of area affected.");
addflag(lastot->flags, F_EXTRADESC, NA, NA, NA, "Deals ^bpower * 3^n damage to objects, half that to creatures.");
addflag(lastot->flags, F_SPELLSCHOOL, SS_DEATH, NA, NA, NULL);
addflag(lastot->flags, F_SPELLLEVEL, 2, NA, NA, NULL);
addflag(lastot->flags, F_MAXPOWER, 10, NA, NA, NULL);
addflag(lastot->flags, F_AICASTTOATTACK, ST_ANYWHERE, NA, NA, NULL);
addflag(lastot->flags, F_LOSLOF, B_TRUE, LOF_DONTNEED, NA, NULL);
addflag(lastot->flags, F_PLEASESGOD, R_GODDEATH, 2, NA, NULL);
addot(OT_S_COMMANDUNDEAD, "command undead", "Compels an undead creature to follow a single simple command.", MT_NOTHING, 0, OC_SPELL, SZ_TINY);
addflag(lastot->flags, F_EXTRADESC, NA, NA, NA, "Spell power determines resistability.");
addflag(lastot->flags, F_SPELLSCHOOL, SS_DEATH, NA, NA, NULL);

1
defs.h
View File

@ -1926,6 +1926,7 @@ enum OBTYPE {
OT_S_BLIGHT,
OT_S_COMMANDUNDEAD,
OT_S_CURSE,
OT_S_DECAYFIELD,
OT_S_DEATHKEEN,
OT_S_DRAINLIFE,
OT_S_FEAR,

27
god.c
View File

@ -2354,9 +2354,6 @@ int prayto(lifeform_t *lf, lifeform_t *god) {
}
}
// turn undead TODO: move this to 'life' god
castspell(god, OT_S_TURNUNDEAD, lf, NULL, NULL, NULL, NULL);
// remove all temporary bad status effects
getflags(player->flags, retflag, &nretflags, F_BLIND, F_CONFUSED, F_DEAF, F_CAFFEINATED, F_DRUNK, F_FROZEN,
F_GRABBEDBY, F_NAUSEATED, F_PAIN, F_POISONED, F_SLOWACT, F_SLOWMOVE, F_SLOWACTMOVE, F_NONE);
@ -2428,6 +2425,8 @@ int prayto(lifeform_t *lf, lifeform_t *god) {
}
break;
case R_GODDEATH:
if (isinbattle(lf, B_INCLUDEDISTANT, B_FALSE)) {
msg("\"Behold, the power of death!\"");
n = OT_NONE;
switch (rnd(0,1)) {
@ -2460,7 +2459,26 @@ int prayto(lifeform_t *lf, lifeform_t *god) {
}
}
}
// animate dead
dospelleffects(god, OT_S_ANIMATEDEAD, 10, lf, NULL, lf->cell, B_UNCURSED, NULL, B_TRUE, NULL);
} else {
// restore mana or stamina
if (lf->mp < getmaxmp(lf)) {
gainmp(lf, getmaxmp(lf));
msg("An unholy energy revitalises your mind!");
} else if (getstamina(player) <= getmaxstamina(player)) {
setstamina(player, getmaxstamina(player));
msg("An unholy energy revitalises your muscles!");
}
if (rnd(1,2) == 1) {
// kill trees / decay wooden objects around you
dospelleffects(god, OT_S_DECAYFIELD, 10, NULL, NULL, lf->cell, B_UNCURSED, NULL, B_FALSE, NULL);
}
// animate dead
dospelleffects(god, OT_S_ANIMATEDEAD, 10, lf, NULL, lf->cell, B_UNCURSED, NULL, B_TRUE, NULL);
}
break;
case R_GODFIRE:
// restore frozen weapons
@ -2515,6 +2533,9 @@ int prayto(lifeform_t *lf, lifeform_t *god) {
statdirty = B_TRUE;
}
if (isinbattle(lf, B_INCLUDEDISTANT, B_FALSE)) {
// turn undead
castspell(god, OT_S_TURNUNDEAD, lf, NULL, NULL, NULL, NULL);
if (plev >= PL_INDIFFERENT) {
int pow;
pow = plev + 1;

View File

@ -8225,6 +8225,23 @@ int istempobpile(obpile_t *op) {
return B_FALSE;
}
int isorganicmat(enum MATERIAL mat) {
int organic = B_FALSE;
switch (mat) {
case MT_FLESH:
case MT_WOOD:
case MT_LEATHER:
case MT_PLANT:
organic = B_TRUE;
break;
default:
organic = B_FALSE;
break;
}
return organic;
}
int isthrowmissile(object_t *o) {
if (hasflag(o->flags, F_THROWMISSILE)) {
return B_TRUE;

View File

@ -215,6 +215,7 @@ int ismagicalobtype(objecttype_t *ot);
int ismagical(object_t *o);
int ismeleeweapon(object_t *o);
int ismetal(enum MATERIAL mat);
int isorganicmat(enum MATERIAL mat);
int isthrowmissile(object_t *o);
int isvalidoverridemat(enum MATERIAL mat);
int isinroof(object_t *o);

79
spell.c
View File

@ -4948,7 +4948,6 @@ int dospelleffects(lifeform_t *caster, enum OBTYPE spellid, int power, lifeform_
} else {
strcpy(damstr, "a blight spell.");
}
losehp(targcell->lf, dam, DT_DECAY, caster, damstr);
if (isplayer(targcell->lf)) {
msg("^%cA blight courses through your veins!", getlfcol(targcell->lf, CC_BAD));
} else if (cansee(player, targcell->lf)) {
@ -4956,6 +4955,7 @@ int dospelleffects(lifeform_t *caster, enum OBTYPE spellid, int power, lifeform_
getlfname(targcell->lf, tname);
msg("%s looks unwell.", tname);
}
losehp(targcell->lf, dam, DT_DECAY, caster, damstr);
}
} else {
op = targcell->obpile;
@ -6326,6 +6326,83 @@ int dospelleffects(lifeform_t *caster, enum OBTYPE spellid, int power, lifeform_
msg("A cloud of darkness descends on you!");
if (seenbyplayer) *seenbyplayer = B_TRUE;
}
} else if (spellid == OT_S_DECAYFIELD) {
obpile_t *op;
object_t *o,*nexto;
int range = 0, ncells,i,lfdam,obdam,walldam;
cell_t *cell[MAXCANDIDATES];
// default to radiating out from the caster's cell
if (!targcell) {
if (caster) {
targcell = caster->cell;
} else {
// fail
return B_TRUE;
}
}
// determine damage (will do double this to object)
lfdam = (power*3)/2;
obdam = power*3;
walldam = power*5;
// determine radius
range = (power/2)+1;
// announce
if (caster && (targcell == caster->cell)) {
sprintf(buf, "%s radiate%s a field of decay!",castername,isplayer(caster) ? "" : "s");
} else {
sprintf(buf, "A field of decay radiates outwards!");
}
animradial(targcell, range, '}', C_INDIGO, DT_ORTH, buf, "Something radiates a field of decay!");
// don't affect centre cell
getradiuscells(targcell, range, DT_COMPASS, B_FALSE, LOF_DONTNEED, B_FALSE, cell, &ncells, B_FALSE);
for (i = 0; i < ncells; i++) {
if (seenbyplayer) {
if (haslos(player, targcell)) {
*seenbyplayer = B_TRUE;
}
}
if (cell[i]->lf && isorganicmat(getlfmaterial(cell[i]->lf))) {
char damstr[BUFLEN];
if (caster) {
char cname[BUFLEN];
real_getlfnamea(caster, cname, NULL, B_SHOWALL, B_REALRACE);
sprintf(damstr, "%s%s field of decay spell.", cname, getpossessive(cname));
} else {
strcpy(damstr, "a field of decay spell.");
}
if (isplayer(cell[i]->lf)) {
msg("^%cPieces of your body decay away!", getlfcol(cell[i]->lf, CC_BAD));
} else if (cansee(player, cell[i]->lf)) {
char tname[BUFLEN];
getlfname(targcell->lf, tname);
msg("Pieces of %s decay away!", tname);
}
losehp(cell[i]->lf, lfdam, DT_DECAY, caster, damstr);
}
op = cell[i]->obpile;
// damage all organic objects here
for (o = op->first ; o ; o = nexto) {
nexto = o->next;
if (isorganicmat(o->material->id)) {
if (!cell[i]->lf && haslos(player, cell[i])) {
char obname[BUFLEN];
getobname(o, obname, o->amt);
msg("%s decays!", obname);
}
takedamage(o, obdam, DT_DECAY, caster);
}
}
// damage all organic walls here
if (isorganicmat(cell[i]->type->material->id)) {
damagecell(cell[i], walldam, DT_DECAY, caster);
}
}
} else if (spellid == OT_S_DEATHKEEN) {
if (!isnighttime()) {
fizzle(caster);