示例#1
0
/* NOTE: we must check if (mtmp->mimic) before calling this routine */
void see_mimic(monst_t *mtmp) // was seemimic
{
  mtmp->bitflags &= ~M_IS_MIMIC; // mtmp->mimic = 0;
  mtmp->mappearance = 0;  // hmmm
  unpmon(mtmp);
  pmon(mtmp);
}
示例#2
0
void mondead(struct monst *mtmp)
{
    relobj(mtmp, 1);
    unpmon(mtmp);
    relmon(mtmp);

    if(u.ustuck == mtmp) {
        u.ustuck = 0;
        
        if(u.uswallow != 0) {
            u.uswallow = 0;
            setsee();
            docrt();
        }
    }

    if(mtmp->isshk != 0) {
        shkdead();
    }

    if(mtmp->isgd != 0) {
        gddead();
    }

#ifndef NOWORM
    if(mtmp->wormno) {
        wormdead(mtmp);
    }
#endif

    monfree(mtmp);
}
示例#3
0
// NOTE: we must check if(mtmp->mimic) before calling this routine
void seemimic(struct monst *mtmp)
{
    mtmp->mimic = 0;
    mtmp->mappearance = 0;
    unpmon(mtmp);
    pmon(mtmp);
}
示例#4
0
void
worm_move(struct monst *mtmp)
{
	struct wseg *wtmp, *whd;
	int tmp = mtmp->wormno;

	wtmp = newseg();
	wtmp->wx = mtmp->mx;
	wtmp->wy = mtmp->my;
	wtmp->nseg = 0;
	(whd = wheads[tmp])->nseg = wtmp;
	wheads[tmp] = wtmp;
	if (cansee(whd->wx, whd->wy)) {
		unpmon(mtmp);
		atl(whd->wx, whd->wy, '~');
		whd->wdispl = 1;
	} else
		whd->wdispl = 0;
	if (wgrowtime[tmp] <= moves) {
		if (!wgrowtime[tmp])
			wgrowtime[tmp] = moves + rnd(5);
		else
			wgrowtime[tmp] += 2 + rnd(15);
		mtmp->mhpmax += 3;
		mtmp->mhp += 3;
		return;
	}
	whd = wsegs[tmp];
	wsegs[tmp] = whd->nseg;
	remseg(whd);
}
示例#5
0
/* make md run through the cave */
void
mdrush(struct monst *md, boolean away)
{
	int             uroom = inroom(u.ux, u.uy);
	if (uroom >= 0) {
		int             tmp = rooms[uroom].fdoor;
		int             cnt = rooms[uroom].doorct;
		int             fx = u.ux, fy = u.uy;
		while (cnt--) {
			if (dist(fx, fy) < dist(doors[tmp].x, doors[tmp].y)) {
				fx = doors[tmp].x;
				fy = doors[tmp].y;
			}
			tmp++;
		}
		tmp_at(-1, md->data->mlet);	/* open call */
		if (away) {	/* interchange origin and destination */
			unpmon(md);
			tmp = fx;
			fx = md->mx;
			md->mx = tmp;
			tmp = fy;
			fy = md->my;
			md->my = tmp;
		}
		while (fx != md->mx || fy != md->my) {
			int             dx, dy, nfx = fx, nfy = fy, d1,
			                d2;

			tmp_at(fx, fy);
			d1 = DIST(fx, fy, md->mx, md->my);
			for (dx = -1; dx <= 1; dx++)
				for (dy = -1; dy <= 1; dy++)
					if (dx || dy) {
						d2 = DIST(fx + dx, fy + dy, md->mx, md->my);
						if (d2 < d1) {
							d1 = d2;
							nfx = fx + dx;
							nfy = fy + dy;
						}
					}
			if (nfx != fx || nfy != fy) {
				fx = nfx;
				fy = nfy;
			} else {
				if (!away) {
					md->mx = fx;
					md->my = fy;
				}
				break;
			}
		}
		tmp_at(-1, -1);	/* close call */
	}
	if (!away)
		pmon(md);
}
示例#6
0
void
fall_down(struct monst *mtmp)
{
	relmon(mtmp);
	mtmp->nmon = fallen_down;
	fallen_down = mtmp;
	unpmon(mtmp);
	mtmp->mtame = 0;
}
示例#7
0
static void
clonewiz(struct monst *mtmp)
{
	struct monst *mtmp2;

	if ((mtmp2 = makemon(PM_WIZARD, mtmp->mx, mtmp->my))) {
		flags.no_of_wizards = 2;
		unpmon(mtmp2);
		mtmp2->mappearance = wizapp[rn2(sizeof(wizapp)-1)];
		pmon(mtmp);
	}
}
示例#8
0
/*
 * Make a chameleon look like a new monster
 * returns 1 if the monster actuall changed
 */
int newcham(struct monst *mtmp, struct permonst *mdat)
{
    int mhp;
    int hpn;
    int hpd;

    /* Still the same monster */
    if(mdat == mtmp->data) {
        return 0;
    }

#ifndef NOWORM
    /* Throw tail away */
    if(mtmp->wormno) {
        wormdead(mtmp);
    }
#endif

    hpn = mtmp->mhp;
    hpd = mtmp->data->mlevel * 8;
    
    if(hpd == 0) {
        hpd = 4;
    }

    mtmp->data = mdat;
    mhp = mdat->mlevel * 8;

    /* New hp: same fraction of max as before */
    mtmp->mhp = 2 + ((hpn * mhp) / hpd);
    hpn = mtmp->orig_hp;
    mtmp->orig_hp = 2 + ((hpn * mhp) / hpd);

    if(mdat->mlet == 'I') {
        mtmp->minvis = 1;
    }
    else {
        mtmp->minvis = 0;
    }

#ifndef NOWORM
    if((mdat->mlet == 'w') && (getwn(mtmp) != 0)) {
        initworm(mtmp);
    }
#endif
    
    /* Necessary for 'I' and to force pmon */
    unpmon(mtmp);
    pmon(mtmp);

    return 1;
}
示例#9
0
/* drop a rock and remove monster */
static void
monstone(struct monst *mdef)
{
	if (strchr(mlarge, mdef->data->mlet))
		mksobj_at(ENORMOUS_ROCK, mdef->mx, mdef->my);
	else
		mksobj_at(ROCK, mdef->mx, mdef->my);
	if (cansee(mdef->mx, mdef->my)) {
		unpmon(mdef);
		atl(mdef->mx, mdef->my, fobj->olet);
	}
	mondead(mdef);
}
示例#10
0
/* drop (perhaps) a cadaver and remove monster */
void
mondied(struct monst *mdef)
{
	const struct permonst *pd = mdef->data;
	if (letter(pd->mlet) && rn2(3)) {
		(void) mkobj_at(pd->mlet, mdef->mx, mdef->my);
		if (cansee(mdef->mx, mdef->my)) {
			unpmon(mdef);
			atl(mdef->mx, mdef->my, fobj->olet);
		}
		stackobj(fobj);
	}
	mondead(mdef);
}
示例#11
0
void
keepdogs()
{
	struct monst *mtmp;

	for(mtmp = fmon; mtmp; mtmp = mtmp->nmon)
	    if(dist(mtmp->mx,mtmp->my) < 3 && follower(mtmp)
		&& !mtmp->msleep && !mtmp->mfroz) {
		relmon(mtmp);
		mtmp->nmon = mydogs;
		mydogs = mtmp;
		unpmon(mtmp);
		keepdogs();	/* we destroyed the link, so use recursion */
		return;		/* (admittedly somewhat primitive) */
	}
}
示例#12
0
/* save bones and possessions of a deceased adventurer */
void
savebones()
{
	int fd;
	struct obj *otmp;
	struct trap *ttmp;
	struct monst *mtmp;

	if(dlevel <= 0 || dlevel > MAXLEVEL) return;
	if(!rn2(1 + dlevel/2)) return;	/* not so many ghosts on low levels */
	bones[6] = '0' + (dlevel/10);
	bones[7] = '0' + (dlevel%10);
	if((fd = open(bones, O_RDONLY)) >= 0){
		(void) close(fd);
		return;
	}
	/* drop everything; the corpse's possessions are usually cursed */
	otmp = invent;
	while(otmp){
		otmp->ox = u.ux;
		otmp->oy = u.uy;
		otmp->age = 0;		/* very long ago */
		otmp->owornmask = 0;
		if(rn2(5)) otmp->cursed = 1;
		if(!otmp->nobj){
			otmp->nobj = fobj;
			fobj = invent;
			invent = 0;	/* superfluous */
			break;
		}
		otmp = otmp->nobj;
	}
	if(!(mtmp = makemon(PM_GHOST, u.ux, u.uy))) return;
	mtmp->mx = u.ux;
	mtmp->my = u.uy;
	mtmp->msleep = 1;
	(void) strlcpy((char *) mtmp->mextra, plname, mtmp->mxlth);
	mkgold(somegold() + d(dlevel,30), u.ux, u.uy);
	for(mtmp = fmon; mtmp; mtmp = mtmp->nmon){
		mtmp->m_id = 0;
		if(mtmp->mtame) {
			mtmp->mtame = 0;
			mtmp->mpeaceful = 0;
		}
		mtmp->mlstmv = 0;
		if(mtmp->mdispl) unpmon(mtmp);
	}
	for(ttmp = ftrap; ttmp; ttmp = ttmp->ntrap)
		ttmp->tseen = 0;
	for(otmp = fobj; otmp; otmp = otmp->nobj) {
		otmp->o_id = 0;
	     /* otmp->o_cnt_id = 0; - superfluous */
		otmp->onamelth = 0;
		otmp->known = 0;
		otmp->invlet = 0;
		if(otmp->olet == AMULET_SYM && !otmp->spe) {
			otmp->spe = -1;      /* no longer the actual amulet */
			otmp->cursed = 1;    /* flag as gotten from a ghost */
		}
	}
	if((fd = open(bones, O_CREAT | O_TRUNC | O_WRONLY, FMASK)) < 0) return;
	savelev(fd,dlevel);
	(void) close(fd);
}
示例#13
0
void
potionhit(struct monst *mon, struct obj *obj)
{
	char *botlnam = bottlenames[rn2(SIZE(bottlenames))];
	boolean uclose, isyou = (mon == &youmonst);

	if(isyou) {
		uclose = TRUE;
		pline("The %s crashes on your head and breaks into shivers.",
			botlnam);
		losehp(rnd(2), "thrown potion");
	} else {
		uclose = (dist(mon->mx,mon->my) < 3);
		/* perhaps 'E' and 'a' have no head? */
		pline("The %s crashes on %s's head and breaks into shivers.",
			botlnam, monnam(mon));
		if(rn2(5) && mon->mhp > 1)
			mon->mhp--;
	}
	pline("The %s evaporates.", xname(obj));

	if(!isyou && !rn2(3)) switch(obj->otyp) {

	case POT_RESTORE_STRENGTH:
	case POT_GAIN_STRENGTH:
	case POT_HEALING:
	case POT_EXTRA_HEALING:
		if(mon->mhp < mon->mhpmax) {
			mon->mhp = mon->mhpmax;
			pline("%s looks sound and hale again!", Monnam(mon));
		}
		break;
	case POT_SICKNESS:
		if(mon->mhpmax > 3)
			mon->mhpmax /= 2;
		if(mon->mhp > 2)
			mon->mhp /= 2;
		break;
	case POT_CONFUSION:
	case POT_BOOZE:
		mon->mconf = 1;
		break;
	case POT_INVISIBILITY:
		unpmon(mon);
		mon->minvis = 1;
		pmon(mon);
		break;
	case POT_PARALYSIS:
		mon->mfroz = 1;
		break;
	case POT_SPEED:
		mon->mspeed = MFAST;
		break;
	case POT_BLINDNESS:
		mon->mblinded |= 64 + rn2(64);
		break;
/*	
	case POT_GAIN_LEVEL:
	case POT_LEVITATION:
	case POT_FRUIT_JUICE:
	case POT_MONSTER_DETECTION:
	case POT_OBJECT_DETECTION:
		break;
*/
	}
	if(uclose && rn2(5))
		potionbreathe(obj);
	obfree(obj, Null(obj));
}
示例#14
0
// NOTE: To hit "you" with a potion p, call "potionhit(NULL, p)". no "youmonst"
void potionhit(monst_t *mon, obj_t *obj)
{
  Char *botlnam = bottlenames[rund(MAX_BOTTLES)];
  Boolean uclose; // , isyou = (mon==NULL);

  if (!mon) {
    uclose = true;
    StrPrintF(ScratchBuffer, "The %s crashes on your head and breaks into shivers.",
	      botlnam);
    message(ScratchBuffer);
    losehp(rnd(2), "thrown potion");
  } else {
    uclose = (dist(mon->mx,mon->my) < 3);
    /* perhaps 'E' and 'a' have no head? */
    StrPrintF(ScratchBuffer, "The %s crashes on %s's head and breaks into shivers.",
	  botlnam, monnam(mon));
    message(ScratchBuffer);
    if (rund(5) && mon->mhp > 1)
      mon->mhp--;
  }
  StrPrintF(ScratchBuffer, "The %s evaporates.", xname(obj));
  message(ScratchBuffer);

  if (mon && !rund(3)) {
    switch(obj->otype) {
    case POT_RESTORE_STRENGTH:
    case POT_GAIN_STRENGTH:
    case POT_HEALING:
    case POT_EXTRA_HEALING:
      if (mon->mhp < mon->mhpmax) {
	mon->mhp = mon->mhpmax;
	StrPrintF(ScratchBuffer, "%s looks sound and hale again!",
		  Monnam(mon));
	message(ScratchBuffer);
      }
      break;
    case POT_SICKNESS:
      if (mon->mhpmax > 3)
	mon->mhpmax /= 2;
      if (mon->mhp > 2)
	mon->mhp /= 2;
      break;
    case POT_CONFUSION:
    case POT_BOOZE:
      mon->bitflags |= M_IS_CONFUSED; // mon->mconf = 1;
      break;
    case POT_INVISIBILITY:
      unpmon(mon);
      mon->bitflags |= M_IS_INVISIBLE; // mon->minvis = 1;
      pmon(mon);
      break;
    case POT_PARALYSIS:
      mon->bitflags |= M_IS_FROZEN; // mon->mfroz = 1;
      break;
    case POT_SPEED:
      mon->mspeed = MFAST;
      break;
    case POT_BLINDNESS:
      mon->mcansee_and_blinded |= 64 + rund(64); // "|="?  "=" to turn off SEE?
      break;
      /*	
	case POT_GAIN_LEVEL:
	case POT_LEVITATION:
	case POT_FRUIT_JUICE:
	case POT_MONSTER_DETECTION:
	case POT_OBJECT_DETECTION:
	break;
      */
    default: break;
    }
  }
  if (uclose && rund(5))
    potionbreathe(obj);
  free_obj(obj, NULL);
}