- 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:
parent
234ad74cf6
commit
8ed4b9aca0
11
data.c
11
data.c
|
@ -4057,7 +4057,7 @@ void initobjects(void) {
|
||||||
// death magic / necromancy
|
// death magic / necromancy
|
||||||
///////////////////
|
///////////////////
|
||||||
// l1
|
// 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_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_SPELLSCHOOL, SS_DEATH, NA, NA, NULL);
|
||||||
addflag(lastot->flags, F_SPELLLEVEL, 1, 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_TARGETTEDSPELL, TT_MONSTER, NA, NA, NULL);
|
||||||
addflag(lastot->flags, F_AICASTTOATTACK, ST_VICTIM, NA, NA, NULL);
|
addflag(lastot->flags, F_AICASTTOATTACK, ST_VICTIM, NA, NA, NULL);
|
||||||
addflag(lastot->flags, F_LOSLOF, B_TRUE, LOF_DONTNEED, 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);
|
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_EXTRADESC, NA, NA, NA, "Spell power determines resistability.");
|
||||||
addflag(lastot->flags, F_SPELLSCHOOL, SS_DEATH, NA, NA, NULL);
|
addflag(lastot->flags, F_SPELLSCHOOL, SS_DEATH, NA, NA, NULL);
|
||||||
|
|
1
defs.h
1
defs.h
|
@ -1926,6 +1926,7 @@ enum OBTYPE {
|
||||||
OT_S_BLIGHT,
|
OT_S_BLIGHT,
|
||||||
OT_S_COMMANDUNDEAD,
|
OT_S_COMMANDUNDEAD,
|
||||||
OT_S_CURSE,
|
OT_S_CURSE,
|
||||||
|
OT_S_DECAYFIELD,
|
||||||
OT_S_DEATHKEEN,
|
OT_S_DEATHKEEN,
|
||||||
OT_S_DRAINLIFE,
|
OT_S_DRAINLIFE,
|
||||||
OT_S_FEAR,
|
OT_S_FEAR,
|
||||||
|
|
81
god.c
81
god.c
|
@ -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
|
// remove all temporary bad status effects
|
||||||
getflags(player->flags, retflag, &nretflags, F_BLIND, F_CONFUSED, F_DEAF, F_CAFFEINATED, F_DRUNK, F_FROZEN,
|
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);
|
F_GRABBEDBY, F_NAUSEATED, F_PAIN, F_POISONED, F_SLOWACT, F_SLOWMOVE, F_SLOWACTMOVE, F_NONE);
|
||||||
|
@ -2428,39 +2425,60 @@ int prayto(lifeform_t *lf, lifeform_t *god) {
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
case R_GODDEATH:
|
case R_GODDEATH:
|
||||||
msg("\"Behold, the power of death!\"");
|
|
||||||
n = OT_NONE;
|
|
||||||
switch (rnd(0,1)) {
|
|
||||||
case 0: n = OT_S_FLAYFLESH; break;
|
|
||||||
case 1: n = OT_S_HECTASSERVANT; break;
|
|
||||||
}
|
|
||||||
|
|
||||||
for (i = 1; i < lf->nlos; i++) {
|
if (isinbattle(lf, B_INCLUDEDISTANT, B_FALSE)) {
|
||||||
lifeform_t *who;
|
msg("\"Behold, the power of death!\"");
|
||||||
who = lf->los[i]->lf;
|
n = OT_NONE;
|
||||||
if (who && !areallies(lf, who)) {
|
switch (rnd(0,1)) {
|
||||||
if (isundead(who)) {
|
case 0: n = OT_S_FLAYFLESH; break;
|
||||||
makepeaceful(who, god);
|
case 1: n = OT_S_HECTASSERVANT; break;
|
||||||
} else if (gettr(who) <= 5) {
|
}
|
||||||
// instakill
|
|
||||||
who->lastdamtype = DT_NECROTIC;
|
for (i = 1; i < lf->nlos; i++) {
|
||||||
setlastdam(who, "Hecta's finger of death.");
|
lifeform_t *who;
|
||||||
who->hp = 0;
|
who = lf->los[i]->lf;
|
||||||
} else if (n != OT_NONE) {
|
if (who && !areallies(lf, who)) {
|
||||||
if (n == OT_S_HECTASSERVANT) {
|
if (isundead(who)) {
|
||||||
c = getrandomadjcell(player->cell, &ccwalkable, B_ALLOWEXPAND);
|
makepeaceful(who, god);
|
||||||
if (c) {
|
} else if (gettr(who) <= 5) {
|
||||||
castspell(god, n, player, NULL, c, NULL, NULL);
|
// instakill
|
||||||
|
who->lastdamtype = DT_NECROTIC;
|
||||||
|
setlastdam(who, "Hecta's finger of death.");
|
||||||
|
who->hp = 0;
|
||||||
|
} else if (n != OT_NONE) {
|
||||||
|
if (n == OT_S_HECTASSERVANT) {
|
||||||
|
c = getrandomadjcell(player->cell, &ccwalkable, B_ALLOWEXPAND);
|
||||||
|
if (c) {
|
||||||
|
castspell(god, n, player, NULL, c, NULL, NULL);
|
||||||
|
}
|
||||||
|
n = OT_S_DRAINLIFE;
|
||||||
|
} else {
|
||||||
|
dospelleffects(god, n, 20, who, NULL, who->cell, B_UNCURSED, NULL, B_FALSE, NULL);
|
||||||
}
|
}
|
||||||
n = OT_S_DRAINLIFE;
|
break;
|
||||||
} else {
|
|
||||||
dospelleffects(god, n, 20, who, NULL, who->cell, B_UNCURSED, NULL, B_FALSE, NULL);
|
|
||||||
}
|
}
|
||||||
break;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
// 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);
|
||||||
}
|
}
|
||||||
dospelleffects(god, OT_S_ANIMATEDEAD, 10, lf, NULL, lf->cell, B_UNCURSED, NULL, B_TRUE, NULL);
|
|
||||||
break;
|
break;
|
||||||
case R_GODFIRE:
|
case R_GODFIRE:
|
||||||
// restore frozen weapons
|
// restore frozen weapons
|
||||||
|
@ -2515,6 +2533,9 @@ int prayto(lifeform_t *lf, lifeform_t *god) {
|
||||||
statdirty = B_TRUE;
|
statdirty = B_TRUE;
|
||||||
}
|
}
|
||||||
if (isinbattle(lf, B_INCLUDEDISTANT, B_FALSE)) {
|
if (isinbattle(lf, B_INCLUDEDISTANT, B_FALSE)) {
|
||||||
|
// turn undead
|
||||||
|
castspell(god, OT_S_TURNUNDEAD, lf, NULL, NULL, NULL, NULL);
|
||||||
|
|
||||||
if (plev >= PL_INDIFFERENT) {
|
if (plev >= PL_INDIFFERENT) {
|
||||||
int pow;
|
int pow;
|
||||||
pow = plev + 1;
|
pow = plev + 1;
|
||||||
|
|
17
objects.c
17
objects.c
|
@ -8225,6 +8225,23 @@ int istempobpile(obpile_t *op) {
|
||||||
return B_FALSE;
|
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) {
|
int isthrowmissile(object_t *o) {
|
||||||
if (hasflag(o->flags, F_THROWMISSILE)) {
|
if (hasflag(o->flags, F_THROWMISSILE)) {
|
||||||
return B_TRUE;
|
return B_TRUE;
|
||||||
|
|
|
@ -215,6 +215,7 @@ int ismagicalobtype(objecttype_t *ot);
|
||||||
int ismagical(object_t *o);
|
int ismagical(object_t *o);
|
||||||
int ismeleeweapon(object_t *o);
|
int ismeleeweapon(object_t *o);
|
||||||
int ismetal(enum MATERIAL mat);
|
int ismetal(enum MATERIAL mat);
|
||||||
|
int isorganicmat(enum MATERIAL mat);
|
||||||
int isthrowmissile(object_t *o);
|
int isthrowmissile(object_t *o);
|
||||||
int isvalidoverridemat(enum MATERIAL mat);
|
int isvalidoverridemat(enum MATERIAL mat);
|
||||||
int isinroof(object_t *o);
|
int isinroof(object_t *o);
|
||||||
|
|
79
spell.c
79
spell.c
|
@ -4948,7 +4948,6 @@ int dospelleffects(lifeform_t *caster, enum OBTYPE spellid, int power, lifeform_
|
||||||
} else {
|
} else {
|
||||||
strcpy(damstr, "a blight spell.");
|
strcpy(damstr, "a blight spell.");
|
||||||
}
|
}
|
||||||
losehp(targcell->lf, dam, DT_DECAY, caster, damstr);
|
|
||||||
if (isplayer(targcell->lf)) {
|
if (isplayer(targcell->lf)) {
|
||||||
msg("^%cA blight courses through your veins!", getlfcol(targcell->lf, CC_BAD));
|
msg("^%cA blight courses through your veins!", getlfcol(targcell->lf, CC_BAD));
|
||||||
} else if (cansee(player, targcell->lf)) {
|
} 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);
|
getlfname(targcell->lf, tname);
|
||||||
msg("%s looks unwell.", tname);
|
msg("%s looks unwell.", tname);
|
||||||
}
|
}
|
||||||
|
losehp(targcell->lf, dam, DT_DECAY, caster, damstr);
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
op = targcell->obpile;
|
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!");
|
msg("A cloud of darkness descends on you!");
|
||||||
if (seenbyplayer) *seenbyplayer = B_TRUE;
|
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) {
|
} else if (spellid == OT_S_DEATHKEEN) {
|
||||||
if (!isnighttime()) {
|
if (!isnighttime()) {
|
||||||
fizzle(caster);
|
fizzle(caster);
|
||||||
|
|
Loading…
Reference in New Issue