This commit is contained in:
Rob Pearce 2011-08-17 20:57:43 +00:00
parent 907ed43e40
commit 16fb58c3cf
14 changed files with 518 additions and 179 deletions

6
ai.c
View File

@ -88,9 +88,9 @@ int aiattack(lifeform_t *lf, lifeform_t *victim, int timelimit) {
}
// become hostile?
if (!hasflag(lf->flags, F_HOSTILE)) {
if (isplayer(victim) && !hasflag(lf->flags, F_HOSTILE) ) {
addflag(lf->flags, F_HOSTILE, B_TRUE, NA, NA, NULL);
innocentattack = 1;
//innocentattack = 1;
}
// change allegience ?
@ -104,7 +104,7 @@ int aiattack(lifeform_t *lf, lifeform_t *victim, int timelimit) {
// no longer a pet
f = lfhasflagval(lf, F_PETOF, victim->id, NA, NA, NULL);
if (f) {
innocentattack = 3;
if (isplayer(victim)) innocentattack = 3;
killflag(f);
}

View File

@ -111,10 +111,26 @@ void applyarmourdamreduction(lifeform_t *lf, object_t *wep, int reduceamt, int *
// figure out reduced damage value
if (dam) {
int ar;
newdam = *dam;
ar = getarmourrating(lf, NULL, NULL, NULL);
// if you did at least one damage...
if ((*dam >= 1) && (reduceamt >= 0)) {
int lowerlimit = 0,divideby;
// reduce it.
newdam -= reduceamt;
limit(&newdam, 1, NA); // don't reduce to <1 damage
// you will always take at least 1 hp of damage for every (ar/2) damage.
// ie. if you took ar/2 damage, you take at least 1.
// ie. if you took ar damage, you take at least 2.
// ie. if you took ar*2 damage, you take at least 3.
// stop at 3.
divideby = ar/2;
if (divideby <= 0) divideby = 1;
lowerlimit = (*dam / divideby);
limit(&lowerlimit, 0, 3);
limit(&newdam, lowerlimit, NA); // don't reduce too far.
}
if (db) {
@ -811,7 +827,7 @@ int attacklf(lifeform_t *lf, lifeform_t *victim, object_t *wep, flag_t *damflag)
strcpy(attackverb, getattackverb(lf, wep, damtype[i],dam[i],victim->maxhp));
if ((dam[i] == 0) && (damtype[i] != DT_TOUCH)) {
nodam = B_TRUE;
strcpy(nodamstr, " but does no damage");
strcpy(nodamstr, " ineffectually");
} else {
strcpy(nodamstr, "");
}

Binary file not shown.

7
defs.h
View File

@ -2352,6 +2352,10 @@ enum PIETYLEV {
#define B_FALSE (0)
#define B_TRUE (-1)
#define B_VIS (1)
#define B_UNKNOWN (0)
#define B_NOVIS (-1)
#define B_KEEPLOF (-1)
#define B_MALE (0)
@ -2807,6 +2811,9 @@ typedef struct lifeform_s {
int nlos;
cell_t **los;
int *viscell;
int visw;
int visrange;
// set to TRUE after lf has being created
int born;

24
flag.c
View File

@ -3,6 +3,7 @@
#include <string.h>
#include "defs.h"
#include "flag.h"
#include "god.h"
#include "io.h"
#include "lf.h"
#include "map.h"
@ -17,6 +18,9 @@ extern enum GAMEMODE gamemode;
extern int needredraw;
extern int statdirty;
extern lifeform_t *godlf[];
extern int ngodlfs;
extern lifeform_t *player;
int flagdb = B_FALSE;
@ -684,6 +688,11 @@ void killflag(flag_t *f) {
map_t *redolight = NULL;
int redostat = B_FALSE;
int redoscreen = B_FALSE;
int i,dopleasegod[MAXGODS];
for (i = 0; i < ngodlfs; i++) {
dopleasegod[i] = 0;
}
lf = f->pile->owner;
@ -705,6 +714,16 @@ void killflag(flag_t *f) {
if (lf && (isplayer(lf) || cansee(player, lf))) {
redolight = lf->cell->map;
}
} else if (f->id == F_FLEEFROM) {
if (lf && lf->cell) {
lifeform_t *fleefrom;
fleefrom = findlf(lf->cell->map, f->val[0]);
// ie. this lf was fleeing from the player, and
// got away.
if (isplayer(fleefrom) && !cansee(lf, fleefrom)) {
dopleasegod[R_GODMERCY] += 5;
}
}
}
}
@ -792,6 +811,11 @@ void killflag(flag_t *f) {
updatefpindex(f->pile);
if (gamemode == GM_GAMESTARTED) {
for (i = 0; i < ngodlfs; i++) {
if (dopleasegod[i]) {
pleasegodmaybe(godlf[i]->race->id, dopleasegod[i]);
}
}
if (redolight) {
calclight(redolight);
precalclos(player);

18
god.c
View File

@ -97,11 +97,20 @@ void angergod(enum RACE rid, int amt) {
// then...
if (piety > -100) {
int i,n;
lifeform_t *l;
// minor bad stuff
switch (rid) {
case R_GODDEATH:
castspell(god, OT_S_PAIN, player, NULL, player->cell);
castspell(god, OT_S_DRAINLIFE, player, NULL, player->cell);
// all undead in sight become hostile
for (l = player->cell->map->lf ; l ; l = l->next) {
if (!isplayer(l) && isundead(l) && cansee(l, player)) {
if (getallegiance(l) != AL_HOSTILE) {
aiattack(l, player, PERMENANT);
}
}
}
break;
case R_GODTHIEVES:
// take a random object
@ -139,12 +148,21 @@ void angergod(enum RACE rid, int amt) {
}
} else if (piety > -200) {
object_t *o;
lifeform_t *l;
int n,i;
// major bad stuff
switch (god->race->id) {
case R_GODDEATH:
castspell(god, OT_S_PAIN, player, NULL, player->cell);
castspell(god, OT_S_DRAINLIFE, player, NULL, player->cell);
// all undead in sight become hostile
for (l = player->cell->map->lf ; l ; l = l->next) {
if (!isplayer(l) && isundead(l) && cansee(l, player)) {
if (getallegiance(l) != AL_HOSTILE) {
aiattack(l, player, PERMENANT);
}
}
}
switch (rnd(1,2)) {
case 1:
msg("\"This will teach you some humility, mortal!\"");

1
io.c
View File

@ -6037,6 +6037,7 @@ void drawlevelfor(lifeform_t *lf) {
if (db) dblog("ending DRAWLEVEL");
sprintf(buf, "end. ndrawn was %d",ndrawn);
if (db) dblog("%s",buf);
//dbtimeend(buf);
// move cursor to the player's position and blit
if (ndrawn) {

308
lf.c
View File

@ -195,9 +195,10 @@ void bleed(lifeform_t *lf) {
}
}
void breakallgrabs(lifeform_t *lf) {
void breakgrabs(lifeform_t *lf, int fromme, int tome) {
flag_t *f;
lifeform_t *alf;
if (fromme) {
f = lfhasflag(lf, F_GRABBING);
if (f) {
lifeform_t *grabee;
@ -206,6 +207,12 @@ void breakallgrabs(lifeform_t *lf) {
killflagsofid(grabee->flags, F_GRABBEDBY);
killflagsofid(lf->flags, F_GRABBING);
}
f = lfhasflag(lf, F_ATTACHEDTO);
if (f) {
killflag(f);
}
}
if (tome) {
f = lfhasflag(lf, F_GRABBEDBY);
if (f) {
lifeform_t *graber;
@ -221,6 +228,7 @@ void breakallgrabs(lifeform_t *lf) {
killflag(f);
}
}
}
}
long calcscore(lifeform_t *lf) {
@ -3281,6 +3289,13 @@ int flee(lifeform_t *lf) {
flag_t *f;
lifeform_t *fleefrom = NULL;
int i;
int db = B_FALSE;
char lfname[BUFLEN];
if (lfhasflag(lf, F_DEBUG)) db = B_TRUE;
real_getlfname(lf, lfname, B_FALSE);
// mindless?
if (getattrbracket(getattr(lf, A_IQ), A_IQ, NULL) == IQ_MINDLESS) {
@ -3304,16 +3319,16 @@ int flee(lifeform_t *lf) {
// if we can't see the person we're running from, and it's not enforced for
// a certain time period (ie. f->lifetime == PERMENANT), we can now stop fleeing.
if (f->lifetime == PERMENANT) {
killflag(f);
} else {
// if the flag is temporary, keep fleeing and wait for it to time out normally
fleefrom = thisone;
}
// player let something flee?
if (isplayer(thisone)) {
pleasegodmaybe(R_GODMERCY, 5);
angergodmaybe(R_GODDEATH, 25);
}
killflag(f);
} else {
// if the flag is temporary, keep fleeing and wait for it to time out normally
fleefrom = thisone;
}
}
}
}
@ -3323,7 +3338,9 @@ int flee(lifeform_t *lf) {
if (fleefrom) {
object_t *stairs;
breakallgrabs(lf);
if (db) dblog("%s - fleeing from %s", lfname, fleefrom->race->name);
breakgrabs(lf, B_TRUE, B_FALSE); // stop grabbing anyone
// ways of fleeing other than movement?
if (!isplayer(lf)) {
@ -3339,14 +3356,23 @@ int flee(lifeform_t *lf) {
aigetspelltarget(lf, findot(spell), fleefrom, &targlf, &targcell, &targob, F_AICASTTOFLEE);
if (getschool(spell) == SS_ABILITY) {
return useability(lf, spell, targlf, targcell);
if (db) dblog("%s - using ability %s to flee", sp->name);
if (!useability(lf, spell, targlf, targcell)) {
if (db) dblog("%s - success.", lfname);
return B_TRUE;
}
} else {
return castspell(lf, spell, targlf, targob, targcell);
if (db) dblog("%s - casting %s to flee", sp->name);
if (!castspell(lf, spell, targlf, targob, targcell)) {
if (db) dblog("%s - success.", lfname);
return B_TRUE;
}
}
}
// if AI, use helpful fleeing items
if (!useitemwithflag(lf, F_AIFLEEITEM)) {
return B_FALSE;
if (db) dblog("%s - used an item to flee", lfname);
return B_TRUE;
}
}
@ -3362,13 +3388,16 @@ int flee(lifeform_t *lf) {
stairs = hasobwithflag(lf->cell->obpile, F_CLIMBABLE);
if (stairs) {
if (!usestairs(lf, stairs, B_TRUE)) {
if (db) dblog("%s - fleeing via %s", stairs->type->name);
return B_TRUE;
}
}
// move away from them
if (!moveawayfrom(lf, fleefrom->cell, DT_ORTH, B_FALSE)) {
if (db) dblog("%s - fleeing by moving away", lfname);
return B_TRUE;
}
if (db) dblog("%s - failed to flee!", lfname);
}
// if we get here, it means we didn't need to or couldn't flee
@ -3404,7 +3433,7 @@ void fleefrom(lifeform_t *lf, lifeform_t *enemy, int howlong, int onpurpose) {
// already fleeing?
f = hasflagval(lf->flags, F_FLEEFROM, enemy->id, NA, NA, NULL);
if (f) {
// update time
// just update time
if (f->lifetime != PERMENANT) {
if (f->lifetime < howlong) {
f->lifetime = howlong;
@ -3413,6 +3442,10 @@ void fleefrom(lifeform_t *lf, lifeform_t *enemy, int howlong, int onpurpose) {
} else {
addtempflag(lf->flags, F_FLEEFROM, enemy->id, NA, NA, NULL, howlong);
}
// stop targetting anyone or going anywhere
killflagsofid(lf->flags, F_TARGETLF);
killflagsofid(lf->flags, F_TARGETCELL);
}
int freezelf(lifeform_t *freezee, lifeform_t *freezer, int howlong) {
@ -7434,6 +7467,231 @@ int haslof(cell_t *src, cell_t *dest, enum LOFTYPE loftype, cell_t **newdest) {
return B_TRUE;
}
void idxtoxy(lifeform_t *lf, int idx, int *x, int *y) {
int xoffset,yoffset;
// get the offset form the lf's position.
xoffset = (idx % lf->visw) - lf->visrange;
yoffset = (idx / lf->visw) - lf->visrange;
// return the actual cell there
*x = lf->cell->x + xoffset;
*y = lf->cell->y + yoffset;
}
// confirmed good!
int xytoidx(lifeform_t *lf, int x, int y) {
int idx;
int xd,yd;
if (abs(x - lf->cell->x) > lf->visrange) return -1;
if (abs(y - lf->cell->y) > lf->visrange) return -1;
xd = lf->cell->x - lf->visrange;
yd = lf->cell->y - lf->visrange;
idx = (y - yd) * lf->visw + (x - xd);
return idx;
}
void setviscell(lifeform_t *lf, cell_t *cell, int how) {
int idx;
int x,y;
cell_t *c;
idx = xytoidx(lf, cell->x, cell->y);
assert(idx >= 0);
assert(idx < (lf->visw * lf->visw));
lf->viscell[idx] = how;
// checks
if (how == B_VIS) {
assert (abs(lf->cell->x - cell->x) <= 10);
assert (abs(lf->cell->y - cell->y) <= 10);
}
idxtoxy(lf, idx, &x, &y);
c = getcellat(lf->cell->map, x, y);
assert(c);
}
int getviscell(lifeform_t *lf, cell_t *cell) {
int idx;
idx = xytoidx(lf, cell->x, cell->y);
if ((idx < 0) || (idx >= (lf->visw * lf->visw)) ) {
return B_NOVIS;
}
return lf->viscell[idx];
}
// find los, remembering cells on the way
void calclos(lifeform_t *viewer, cell_t *dest) {
int numpixels;
int i,n;
int x1,y1;
int maxvisrange;
int nightvisrange;
int xray = 0;
flag_t *f;
int x2,y2;
map_t *map;
object_t *o;
int currange;
cell_t *retcell[MAXRETCELLS];
int allbad = B_FALSE;
if (!viewer) return ;
if (!dest) return ;
if (!viewer->cell) return ;
if (viewer->cell->map != dest->map) return ;
map = dest->map;
x1 = viewer->cell->x;
y1 = viewer->cell->y;
x2 = dest->x;
y2 = dest->y;
// find the path of cells
calcbresnham(map, x1, y1, x2, y2, retcell, &numpixels);
// can't see if you're blind
if (isblind(viewer)) {
allbad = 1;
}
maxvisrange = getvisrange(viewer);
nightvisrange = getnightvisrange(viewer);
//origheight = getheight(x1,y1,z);
if (allbad) {
// mark all as bad
for (i = 0; i < numpixels; i++ ){
setviscell(viewer, retcell[i], B_VIS);
}
return;
}
f = hasflag(viewer->flags, F_XRAYVIS);
if (f) {
xray = f->val[0];
} else {
xray = 0;
}
//shopwall = B_FALSE;
currange = 0;
for (i = 0; i < numpixels ; i++) {
cell_t *cell;
int cellopaque = B_FALSE;
int celldark = B_FALSE;
cell = retcell[i];
//already can't see this one?
if (getviscell(viewer, cell) == B_NOVIS) {
break;
}
if ((cell->x == x2) && (cell->y == y2)) {
// made it to the last cell
setviscell(viewer, cell, B_VIS);
return;
}
if (i == 0) {
// you can always see your own cell
setviscell(viewer, cell, B_VIS);
continue;
}
currange++;
if (currange > maxvisrange) {
break;
}
// check cell type
if (!cell->type->transparent) {
cellopaque = -1; // fullblock
}
// now check lighting
if (!cellopaque) {
// outside the range of our light, and not lit
if (getcelldist(viewer->cell, cell) > nightvisrange) {
if (!islit(cell)) {
celldark = B_TRUE;
}
} else {
// inside our nightvis range and magically dark
if (cell->lit == L_PERMDARK) {
celldark = B_TRUE;
}
}
}
// check for objects which block view
if (!cellopaque && !celldark) {
for (o = cell->obpile->first ; o ; o = o->next) {
f = hasflag(o->flags, F_BLOCKSVIEW);
if (f) {
if (!lfhasflagval(viewer, F_CANSEETHROUGHMAT, o->material->id, NA, NA, NULL)) {
if (f->val[0] == B_TRUE) {
cellopaque = -1; // fullblock
break;
} else {
cellopaque += f->val[0];
}
}
}
}
}
if (cellopaque) {
if (xray) {
xray--;
} else {
if (cellopaque == -1) {
// can see this one but not the rest.
setviscell(viewer, cell, B_VIS);
i++;
break;
} else {
currange += cellopaque;
if (currange > maxvisrange) {
// can see this one but not the rest.
setviscell(viewer, cell, B_VIS);
i++;
break;
}
}
}
}
// xray vision decreases by one
if (xray) xray--;
// this cell is visible (unless it's dark)
if (celldark) {
setviscell(viewer, cell, B_NOVIS);
} else {
setviscell(viewer, cell, B_VIS);
}
}
// rest of cells are not visible.
for (n = i; n < numpixels; n++) {
setviscell(viewer, retcell[n], B_NOVIS);
}
}
int haslos(lifeform_t *viewer, cell_t *dest) {
int numpixels;
int i;
@ -7463,6 +7721,7 @@ int haslos(lifeform_t *viewer, cell_t *dest) {
// can we use pre-calced los?
//
if ((viewer->cell->map->lf == viewer) && viewer->los) {
for (i = 0;i < viewer->nlos; i++) {
if (viewer->los[i] == dest) {
@ -7626,7 +7885,7 @@ void initjobs(void) {
addflag(lastjob->flags, F_STARTSKILL, SK_SS_DIVINATION, PR_MASTER, NA, NULL);
addflag(lastjob->flags, F_STARTSKILL, SK_SS_MENTAL, PR_MASTER, NA, NULL);
addflag(lastjob->flags, F_STARTSKILL, SK_SS_SUMMONING, PR_MASTER, NA, NULL);
addflag(lastjob->flags, F_HASPET, NA, NA, NA, "young wolf");
//addflag(lastjob->flags, F_HASPET, NA, NA, NA, "young wolf");
for (i = 1; i < MAXSKILLS; i++) {
addflag(lastjob->flags, F_CANLEARN, i, NA, NA, NULL);
}
@ -11378,7 +11637,10 @@ lifeform_t *real_addlf(cell_t *cell, enum RACE rid, int level, int controller) {
// for precalcing line of sight
a->nlos = 0;
a->los = NULL;
//a->los = malloc(sizeof(cell_t *) * MAXVISRANGE);
a->los = malloc( sizeof(cell_t *) * ((MAXVISRANGE*2+1)*(MAXVISRANGE*2+1)));
//a->viscell = NULL;
a->viscell = malloc( sizeof(int) * ((MAXVISRANGE*2+1)*(MAXVISRANGE*2+1)));
// for ai
@ -12990,20 +13252,15 @@ int noise(cell_t *c, lifeform_t *noisemaker, enum NOISECLASS nt, int volume, cha
// if anything nearby hears it, it might respond
for (l = c->map->lf; l ; l = l->next) {
int dist;
int difficulty;
int lbonus;
if (l == noisemaker) continue;
// ie. if this lf is in the process of swapping places
if (!l->cell) continue;
// if you make a noise while swapping position with
// something, its ->cell will be null here!
dist = getcelldist(l->cell, c);
if (l != noisemaker) {
int difficulty;
int lbonus;
//if (canhear(l, c) && haslos(l, c)) {
// listen check difficulty is based on sound distance vs max hearing distance
if (nt == NC_SPEECH) {
// you always hear it, as long as you're in range
@ -13021,8 +13278,8 @@ int noise(cell_t *c, lifeform_t *noisemaker, enum NOISECLASS nt, int volume, cha
}
// skillcheck to hear this
if ( (haslos(l, c) ||
(canhear(l, c, volume) && skillcheck(l, SC_LISTEN, difficulty, lbonus)))) {
if ( (isplayer(l) && haslos(l, c)) || // only player can "hear by seeing"
(canhear(l, c, volume) && skillcheck(l, SC_LISTEN, difficulty, lbonus)) ) {
flag_t *f;
// announce?
if (isplayer(l) && !lfhasflag(l, F_ASLEEP)) {
@ -13110,6 +13367,7 @@ int noise(cell_t *c, lifeform_t *noisemaker, enum NOISECLASS nt, int volume, cha
}
}
}
// wake up a little
f = lfhasflag(l, F_ASLEEP);
if (f) {
@ -13155,7 +13413,6 @@ int noise(cell_t *c, lifeform_t *noisemaker, enum NOISECLASS nt, int volume, cha
}
}
}
}
return rv;
}
@ -14877,7 +15134,8 @@ int real_skillcheck(lifeform_t *lf, enum CHECKTYPE ct, int diff, int mod, int *r
roll = rolldie(1, 20);
if (db) {
sprintf(mbuf, "%s skillcheck - need %d, got %d(rll)+%d(attr)+%d(lvm)+%d(othmod)+%d(mod)=",lf->race->name, diff, roll, attrib,levmod, othermod,mod);
sprintf(mbuf, "%s skillcheck (%d) - need %d, got %d(rll)+%d(attr)+%d(lvm)+%d(othmod)+%d(mod)=",lf->race->name,
ct, diff, roll, attrib,levmod, othermod,mod);
}
modroll = roll;
modroll += attrib;

6
lf.h
View File

@ -22,7 +22,7 @@ void autoweild(lifeform_t *lf);
int appearsrandomly(enum RACE rid);
void awardxpfor(lifeform_t *killed, float pct);
void bleed(lifeform_t *lf);
void breakallgrabs(lifeform_t *lf);
void breakgrabs(lifeform_t *lf, int fromme, int tome);
long calcscore(lifeform_t *lf);
int calcxp(lifeform_t *lf);
int calcxprace(enum RACE rid);
@ -145,6 +145,10 @@ int getmaxmp(lifeform_t *lf);
float getmaxpushweight(lifeform_t *lf);
int getmr(lifeform_t *lf);
int getvisrange(lifeform_t *lf);
void idxtoxy(lifeform_t *lf, int idx, int *x, int *y);
void setviscell(lifeform_t *lf, cell_t *cell, int how);
int getviscell(lifeform_t *lf, cell_t *cell);
int xytoidx(lifeform_t *lf, int x, int y);
int getmovespeed(lifeform_t *lf);
char *getmoveverb(lifeform_t *lf);
char *getmoveverbother(lifeform_t *lf);

4
map.c
View File

@ -2033,7 +2033,7 @@ void createmap(map_t *map, int depth, region_t *region, map_t *parentmap, int ex
enum HABITAT habitat;
regionthing_t *thing[MAXOUTLINETHINGS];
int nthings = 0;
int db = B_TRUE;
int db = B_FALSE;
// determine habitat based on region
// note: we might override this later based on our region outline
@ -2505,7 +2505,7 @@ int createvault(map_t *map, int roomid, vault_t *v, int *retw, int *reth, int *r
int w,h,x,y;
int xmargin = 0,ymargin = 0;
int minx,miny,maxx,maxy;
int db = B_TRUE;
int db = B_FALSE;
int rotation = 0;
flag_t *f;

11
move.c
View File

@ -695,7 +695,7 @@ int knockback(lifeform_t *lf, int dir, int howfar, lifeform_t *pusher, int fallc
howfar *= 2;
}
breakallgrabs(lf);
breakgrabs(lf, B_TRUE, B_TRUE);
for (i = 0; i < howfar; i++) {
if (moveclear(lf, dir, &reason)) {
@ -983,11 +983,18 @@ int movelf(lifeform_t *lf, cell_t *newcell) {
// update new cell
newcell->lf = lf;
/*
// update light
if (lfproduceslight(lf) || (changedlev && isplayer(lf))) {
calclight(lf->cell->map);
precalclos(lf);
}
*/
// update light
if (lfproduceslight(lf)) {
calclight(lf->cell->map);
}
precalclos(lf);
if (isplayer(lf) || cansee(player, lf)) {
needredraw = B_TRUE;
@ -1150,6 +1157,7 @@ int movelf(lifeform_t *lf, cell_t *newcell) {
// ISNT a vault, reveal it.
//
/*
if ((getskill(lf, SK_CARTOGRAPHY) >= PR_NOVICE) && (!lf->cell->vault)) {
if ((postroom > 0) && (postroom != preroom)) {
cell_t *c[MAX_MAPW*MAX_MAPH];
@ -1176,6 +1184,7 @@ int movelf(lifeform_t *lf, cell_t *newcell) {
}
}
*/
}
// does anyone else see you?

View File

@ -379,6 +379,7 @@ int main(int argc, char **argv) {
// show level (if required)
//if (haslos(player, curmap->lf->cell)) {
drawscreen();
//dblog("**** END of turn, numdraws = %d", numdraws);

View File

@ -4028,7 +4028,7 @@ int dospelleffects(lifeform_t *caster, enum OBTYPE spellid, int power, lifeform_
}
} else if (spellid == OT_S_GASEOUSFORM) {
if (!target) target = caster;
if (hasmr(target) && (target->race->id != R_VAMPIRE) && skillcheck(target, SC_RESISTMAG, 20 + power, 0)) {
if (getmr(target) && (target->race->id != R_VAMPIRE) && skillcheck(target, SC_RESISTMAG, 20 + power, 0)) {
if (isplayer(target)) {
msg("You feel momentarily insubstantial.");
if (seenbyplayer) *seenbyplayer = B_TRUE;
@ -5822,7 +5822,7 @@ int dospelleffects(lifeform_t *caster, enum OBTYPE spellid, int power, lifeform_
f = addtempflag(target->flags, F_NONCORPOREAL, B_TRUE, NA, NA, NULL, howlong);
f->obfrom = OT_S_PASSWALL;
breakallgrabs(caster);
breakgrabs(target, B_TRUE, B_TRUE);
} else if (spellid == OT_S_POLYMORPH) {
race_t *r = NULL;
flag_t *f;
@ -5930,6 +5930,7 @@ int dospelleffects(lifeform_t *caster, enum OBTYPE spellid, int power, lifeform_
if (haslos(player, target->cell)) {
if (seenbyplayer) *seenbyplayer = B_TRUE;
}
breakgrabs(target, B_TRUE, B_TRUE);
} else {
fizzle(caster);
return B_TRUE;

View File

@ -1,7 +1,7 @@
! filled with random monsters
@id:monsterzoo
@map
random(4,4)
random(3,3,5,5)
@end
@legend