Ejemplo n.º 1
0
/* try to force a chest with your weapon */
int
doforce(const struct nh_cmd_arg *arg)
{
    struct obj *otmp;
    int c;
    const char *qbuf;

    if (!uwep_can_force())
        return 0;

    if (u.utracked[tos_lock] && u.uoccupation_progress[tos_lock]) {
        if (turnstate.continue_message)
            pline(msgc_occstart, "You resume your attempt to force the lock.");
        one_occupation_turn(forcelock, "forcing the lock", occ_lock);
        return 1;
    }

    /* A lock is made only for the honest man, the thief will break it. */
    u.utracked[tos_lock] = NULL;
    u.uoccupation_progress[tos_lock] = 0;
    for (otmp = level->objects[youmonst.mx][youmonst.my]; otmp; otmp = otmp->nexthere)
        if (Is_box(otmp)) {
            if (otmp->obroken || !otmp->olocked) {
                pline(msgc_cancelled,
                      "There is %s here, but its lock is already %s.",
                      doname(otmp), otmp->obroken ? "broken" : "unlocked");
                continue;
            }
            qbuf = msgprintf(
                "There is %s here, force its lock?",
                safe_qbuf("", sizeof ("There is  here, force its lock?"),
                          doname(otmp), an(simple_typename(otmp->otyp)),
                          "a box"));

            c = ynq(qbuf);
            if (c == 'q')
                return 0;
            if (c == 'n')
                continue;

            if (is_blade(uwep))
                pline(msgc_occstart,
                      "You force your %s into a crack and pry.", xname(uwep));
            else
                pline(msgc_occstart,
                      "You start bashing it with your %s.", xname(uwep));
            u.utracked[tos_lock] = otmp;
            break;
        }

    if (u.utracked[tos_lock]) {
        one_occupation_turn(forcelock, "forcing the lock", occ_lock);
        return 1;
    } else {
        pline(msgc_cancelled, "You decide not to force the issue.");
        return 0;
    }
}
Ejemplo n.º 2
0
/*       -1 if object could not be found (but was paid) */
static int
dopayobj(struct bill_x *bp)
{
	struct obj *obj;
	long ltmp;

	/* find the object on one of the lists */
	obj = bp_to_obj(bp);

	if (!obj) {
		impossible("Shopkeeper administration out of order.");
		setpaid();	/* be nice to the player */
		return (0);
	}

	if (!obj->unpaid && !bp->useup) {
		impossible("Paid object on bill??");
		return (1);
	}
	obj->unpaid = 0;
	ltmp = bp->price * bp->bquan;
	if (ANGRY(shopkeeper))
		ltmp += ltmp / 3;
	if (u.ugold < ltmp) {
		pline("You don't have gold enough to pay %s.",
		      doname(obj));
		obj->unpaid = 1;
		return (0);
	}
	pay(ltmp, shopkeeper);
	pline("You bought %s for %ld gold piece%s.",
	      doname(obj), ltmp, plur(ltmp));
	if (bp->useup) {
		struct obj *otmp = billobjs;
		if (obj == billobjs)
			billobjs = obj->nobj;
		else {
			while (otmp && otmp->nobj != obj)
				otmp = otmp->nobj;
			if (otmp)
				otmp->nobj = obj->nobj;
			else
				pline("Error in shopkeeper administration.");
		}
		free(obj);
	}
	return (1);
}
Ejemplo n.º 3
0
static int
drop(struct obj *obj)
{
	if(!obj) return(0);
	if(obj->olet == '$') {		/* pseudo object */
		long amount = OGOLD(obj);

		if(amount == 0)
			pline("You didn't drop any gold pieces.");
		else {
			mkgold(amount, u.ux, u.uy);
			pline("You dropped %ld gold piece%s.",
				amount, plur(amount));
			if(Invisible) newsym(u.ux, u.uy);
		}
		free(obj);
		return(1);
	}
	if(obj->owornmask & (W_ARMOR | W_RING)){
		pline("You cannot drop something you are wearing.");
		return(0);
	}
	if(obj == uwep) {
		if(uwep->cursed) {
			pline("Your weapon is welded to your hand!");
			return(0);
		}
		setuwep((struct obj *) 0);
	}
	pline("You dropped %s.", doname(obj));
	dropx(obj);
	return(1);
}
Ejemplo n.º 4
0
static int stealarm(void)
{
	struct monst *mtmp;
	struct obj *otmp;

	for (otmp = invent; otmp; otmp = otmp->nobj) {
	    if (otmp->o_id == stealoid) {
		for (mtmp = level->monlist; mtmp; mtmp = mtmp->nmon) {
		    if (mtmp->m_id == stealmid) {
			if (DEADMONSTER(mtmp)) warning("stealarm(): dead monster stealing");
			if (!dmgtype(mtmp->data, AD_SITM)) /* polymorphed */
			    goto botm;
			if (otmp->unpaid)
			    subfrombill(otmp, shop_keeper(level, *u.ushops));
			freeinv(otmp);
			pline("%s steals %s!", Monnam(mtmp), doname(otmp));
			mpickobj(mtmp,otmp);	/* may free otmp */
			/* Implies seduction, "you gladly hand over ..."
			   so we don't set mavenge bit here. */
			monflee(mtmp, 0, FALSE, FALSE);
			if (!tele_restrict(mtmp)) rloc(level, mtmp, FALSE);
		        break;
		    }
		}
		break;
	    }
	}
botm:   stealoid = 0;
	return 0;
}
Ejemplo n.º 5
0
void start(){
    one.symbol = '@';
    two.symbol = '*';
#ifdef PATCHED
#else
    one.lenname = lenofname;
    two.lenname = lenofname;
#endif
    if (transmit_all(1, ONE, sizeof(ONE)-1) != 0) {
        _terminate(0);
    }
#ifdef PATCHED
    if (receive_delim(0, one.name, sizeof(one.name), '\n', &(one.namelen)) != 0) {
        _terminate(0);
    }
    one.namelen--;
#else
    if (receive_delim(0, one.name, 64, '\n', &rxlen) != 0) {
        _terminate(0);
    }      
#endif
    if (transmit_all(1, TWO, sizeof(TWO)-1) != 0) {
        _terminate(0);
    }
#ifdef PATCHED
    if (receive_delim(0, two.name, sizeof(two.name), '\n', &(two.namelen)) != 0) {
        _terminate(0);
    }
    two.namelen--;
#else
    if (receive_delim(0, two.name, 64, '\n', &rxlen) != 0) {
        _terminate(0);
    }
#endif

#ifdef PATCHED
    doname(one.name, one.namelen);
    doname(two.name, two.namelen);
#else
    doname(one.name, one.lenname(one.name));
    doname(two.name, two.lenname(two.name));
#endif

    init_board();
    print_board();
}
Ejemplo n.º 6
0
/*       -1 if object could not be found (but was paid) */
static Short dopayobj(bill_t *bp)
{
  obj_t *obj;
  Long ltmp;

  /* find the object on one of the lists */
  obj = bp_to_obj(bp);

  if (!obj) {
    message("BUG: Shopkeeper administration out of order.");
    setpaid();	/* be nice to the player */
    return 0;
  }

  if (!(obj->bitflags & O_IS_UNPAID) && !bp->useup) {
    message("BUG: Paid object on bill??");
    return 1;
  }
  obj->bitflags &= ~O_IS_UNPAID;
  ltmp = bp->price * bp->bquantity;
  if (ANGRY(shopkeeper)) ltmp += ltmp/3;
  if (you.ugold < ltmp) {
    StrPrintF(ScratchBuffer, "You don't have gold enough to pay %s.",
	      doname(obj));
    message(ScratchBuffer);
    obj->bitflags |= O_IS_UNPAID;
    return 0;
  }
  pay(ltmp, shopkeeper);
  StrPrintF(ScratchBuffer, "You bought %s for %ld gold piece%s",
	    doname(obj), ltmp, (ltmp == 1 ? "." : "s."));
  message(ScratchBuffer);
  if (bp->useup) {
    obj_t *otmp = billobjs;
    if (obj == billobjs)
      billobjs = obj->nobj;
    else {
      while (otmp && otmp->nobj != obj) otmp = otmp->nobj;
      if (otmp) otmp->nobj = obj->nobj;
      else message("BUG: Error in shopkeeper administration.");
    }
    free_me((VoidPtr) obj);
  }
  return 1;
}
Ejemplo n.º 7
0
bool
hitu(struct monst *mtmp, int dam)
{
	bool res;
	int tmp;

	nomul(0);
	if (u.uswallow)
		return (0);

	if (mtmp->mhide && mtmp->mundetected) {
		mtmp->mundetected = 0;
		if (!Blind) {
			struct obj *obj;
			if ((obj = o_at(mtmp->mx, mtmp->my)) != NULL)
				pline("%s was hidden under %s!",
				      Xmonnam(mtmp), doname(obj));
		}
	}

	tmp = u.uac;
	/* give people with Ac = -10 at least some vulnerability */
	if (tmp < 0) {
		dam += tmp;	/* decrease damage */
		if (dam <= 0)
			dam = 1;
		tmp = -rn2(-tmp);
	}
	tmp += mtmp->data->mlevel;
	if (multi < 0)
		tmp += 4;
	if ((Invis && mtmp->data->mlet != 'I') || !mtmp->mcansee)
		tmp -= 2;
	if (mtmp->mtrapped)
		tmp -= 2;
	if (tmp <= rnd(20)) {
		if (Blind)
			pline("It misses.");
		else
			pline("%s misses.", Monnam(mtmp));
		res = 0;
	} else {
		if (Blind)
			pline("It hits!");
		else
			pline("%s hits!", Monnam(mtmp));
		losehp_m(dam, mtmp);
		res = 1;
	}
	stop_occupation();
	return (res);
}
Ejemplo n.º 8
0
/* hero is hit by something other than a monster */
int
thitu(int tlev, int dam, struct obj *obj, const char *name)
{       /* if null, then format `obj' */
    const char *onm, *killer;
    boolean is_acid;

    /* TODO: credit the monster that fired the object with the kill */
    if (!name) {
        if (!obj)
            panic("thitu: name & obj both null?");
        name = (obj->quan > 1L) ? doname(obj) : mshot_xname(obj);
        killer = killer_msg_obj(DIED, obj);
    } else {
        killer = killer_msg(DIED, an(name));
    }
    onm = (obj && obj_is_pname(obj)) ? the(name) :
      (obj && obj->quan > 1L) ? name : an(name);
    is_acid = (obj && obj->otyp == ACID_VENOM);

    if (get_player_ac() + tlev <= rnd(20)) {
        if (Blind || !flags.verbose)
            pline("It misses.");
        else
            pline("You are almost hit by %s.", onm);
        return 0;
    } else {
        if (Blind || !flags.verbose)
            pline("You are hit!");
        else
            pline("You are hit by %s%s", onm, exclam(dam));

        if (obj && objects[obj->otyp].oc_material == SILVER &&
            hates_silver(youmonst.data)) {
            dam += rnd(20);
            pline("The silver sears your flesh!");
            exercise(A_CON, FALSE);
        }
        if (is_acid && Acid_resistance)
            pline("It doesn't seem to hurt you.");
        else {
            if (is_acid)
                pline("It burns!");
            if (Half_physical_damage)
                dam = (dam + 1) / 2;
            losehp(dam, killer);
            exercise(A_STR, FALSE);
        }
        return 1;
    }
}
Ejemplo n.º 9
0
/** Dumps an object as list item. */
void
dump_list_item_object(struct obj *obj)
{
#ifdef DUMP_LOG
    if (dump_fp)
        fprintf(dump_fp, "  %s\n", doname(obj));
    if (html_dump_fp) {
        const char* str = doname(obj);
        char *link = html_link(dump_typename(obj->otyp), str);
#ifdef MENU_COLOR
# ifdef TTY_GRAPHICS
        int color;
        int attr;
        if (iflags.use_menu_color &&
                get_menu_coloring(str, &color, &attr)) {
            fprintf(html_dump_fp, "<li class=\"nh_color_%d\">%s</li>\n", color, link);
        } else
# endif
#endif
            fprintf(html_dump_fp, "<li>%s</li>\n", link);
    }
#endif
}
Ejemplo n.º 10
0
void Handler::handle() {
    int fd = this->conn->getClientFd();
    FILE *f = fdopen(fd, "r+");
    char line[LINE_LEN];
    char **params;
    int i = 0;
    int param_num = 0;
    while(fgets(line, LINE_LEN, f)) {
        if(line[0] == '*') {
            if(param_num != 0) {
                delete params;//memory leak
                i = 0;
            }
            param_num = atoi(line + 1);
            params = new char*[param_num];
        } 
        if(line[0] == '$') {
            size_t len = atol(line + 1);
            params[i] = new char[len + 1];
            params[i][len] = '\0';
            fread(params[i], len, 1, f);
            i++;
            fgets(line, LINE_LEN, f);
            if(i == param_num) {
                if(strncmp(params[0], "use", strlen("use")) == 0){
                    string doname(string(params[1], len));
                    this->handleUse(doname);
                } else {
                    if(this->domain == NULL) {
                        this->sendMsg("-Please select a domain");
                        continue;
                    }
                    if(strncmp(params[0], "set", strlen("set")) == 0) {
                        this->handleSet(params[1], params[2], len);
                    } else if(strncmp(params[0], "get", strlen("get")) == 0){
                        this->handleGet(params[1]);
                    } else if(strncmp(params[0], "del", strlen("del")) == 0){
                        this->handleDel(params[1]);
                    } else {
                        this->sendMsg("-Unknown Operation");
                    }
                }
            }
        }
    }
    pthread_exit(0);
}
Ejemplo n.º 11
0
int stealamulet(struct monst *mtmp)
{
    struct obj *otmp;

    for (otmp = invent; otmp; otmp = otmp->nobj) {
	if (otmp->olet == AMULET_SYM) {
	    // might be an imitation one
	    if (otmp == uwep)
		setuwep((struct obj *) 0);
	    freeinv(otmp);
	    mpickobj(mtmp, otmp);
	    pline("%s stole %s!", Monnam(mtmp), doname(otmp));
	    return 1;
	}
    }
    return 0;
}
Ejemplo n.º 12
0
void
stealamulet(struct monst *mtmp)
{
    struct obj *otmp = NULL;
    int real = 0, fake = 0;

    /* select the artifact to steal */
    if (u.uhave.amulet) {
        real = AMULET_OF_YENDOR;
        fake = FAKE_AMULET_OF_YENDOR;
    } else if (u.uhave.questart) {
        for (otmp = invent; otmp; otmp = otmp->nobj)
            if (is_quest_artifact(otmp))
                break;
        if (!otmp)
            return;     /* should we panic instead? */
    } else if (u.uhave.bell) {
        real = BELL_OF_OPENING;
        fake = BELL;
    } else if (u.uhave.book) {
        real = SPE_BOOK_OF_THE_DEAD;
    } else if (u.uhave.menorah) {
        real = CANDELABRUM_OF_INVOCATION;
    } else
        return; /* you have nothing of special interest */

    if (!otmp) {
        /* If we get here, real and fake have been set up. */
        for (otmp = invent; otmp; otmp = otmp->nobj)
            if (otmp->otyp == real || (otmp->otyp == fake && !mtmp->iswiz))
                break;
    }

    if (otmp) { /* we have something to snatch */
        if (otmp->owornmask)
            remove_worn_item(otmp, TRUE);
        freeinv(otmp);
        /* mpickobj wont merge otmp because none of the above things to steal
           are mergable */
        mpickobj(mtmp, otmp);   /* may merge and free otmp */
        pline("%s stole %s!", Monnam(mtmp), doname(otmp));
        if (can_teleport(mtmp->data) && !tele_restrict(mtmp))
            rloc(mtmp, FALSE);
    }
}
Ejemplo n.º 13
0
/*
 * Returns an obj->age for a corpse object on ice, that would be the
 * actual obj->age if the corpse had just been lifted from the ice.
 * This is useful when just using obj->age in a check or calculation because
 * rot timers pertaining to the object don't have to be stopped and
 * restarted etc.
 */
long
peek_at_iced_corpse_age(struct obj *otmp)
{
    long age, retval = otmp->age;

    if (otmp->otyp == CORPSE && ON_ICE(otmp)) {
        /* Adjust the age; must be same as obj_timer_checks() for off ice*/
        age = monstermoves - otmp->age;
        retval = otmp->age + (age / ROT_ICE_ADJUSTMENT);
#ifdef DEBUG_EFFECTS
        pline_The("%s age has ice modifications:otmp->age = %ld, returning %ld.",
                  s_suffix(doname(otmp)),otmp->age, retval);
        pline("Effective age of corpse: %ld.",
              monstermoves - retval);
#endif
    }
    return retval;
}
Ejemplo n.º 14
0
int stealarm(void)
{
    struct monst *mtmp;
    struct obj *otmp;

    for (otmp = invent; otmp; otmp = otmp->nobj)
	if (otmp->o_id == stealoid) {
	    for (mtmp = fmon; mtmp; mtmp = mtmp->nmon)
		if (mtmp->m_id == stealmid) {
		    if (dist(mtmp->mx, mtmp->my) < 3) {
			freeinv(otmp);
			pline("%s steals %s!", Monnam(mtmp), doname(otmp));
			mpickobj(mtmp, otmp);
			mtmp->mflee = 1;
			rloc(mtmp);
		    }
		    break;
		}
	    break;
	}
    stealoid = 0;
    return 0;
}
Ejemplo n.º 15
0
/* return 0 (no move), 1 (move) or 2 (dead) */
int
dog_move(struct monst *mtmp, int after)
{
	int nx, ny, omx, omy, appr, nearer, j;
	int udist, chi, i, whappr;
	struct monst *mtmp2;
	struct permonst *mdat = mtmp->data;
	struct edog *edog = EDOG(mtmp);
	struct obj *obj;
	struct trap *trap;
	xchar cnt, chcnt, nix, niy;
	schar dogroom, uroom;
	xchar gx, gy, gtyp, otyp;	/* current goal */
	coord poss[9];
	int info[9];
#define GDIST(x,y) ((x-gx)*(x-gx) + (y-gy)*(y-gy))
#define DDIST(x,y) ((x-omx)*(x-omx) + (y-omy)*(y-omy))

	if(moves <= edog->eattime) return(0);	/* dog is still eating */
	omx = mtmp->mx;
	omy = mtmp->my;
	whappr = (moves - EDOG(mtmp)->whistletime < 5);
	if(moves > edog->hungrytime + 500 && !mtmp->mconf){
		mtmp->mconf = 1;
		mtmp->mhpmax /= 3;
		if(mtmp->mhp > mtmp->mhpmax)
			mtmp->mhp = mtmp->mhpmax;
		if(cansee(omx,omy))
			pline("%s is confused from hunger.", Monnam(mtmp));
		else	pline("You feel worried about %s.", monnam(mtmp));
	} else
	if(moves > edog->hungrytime + 750 || mtmp->mhp < 1){
		if(cansee(omx,omy))
			pline("%s dies from hunger.", Monnam(mtmp));
		else
		pline("You have a sad feeling for a moment, then it passes.");
		mondied(mtmp);
		return(2);
	}
	dogroom = inroom(omx,omy);
	uroom = inroom(u.ux,u.uy);
	udist = dist(omx,omy);

	/* maybe we tamed him while being swallowed --jgm */
	if(!udist) return(0);

	/* if we are carrying sth then we drop it (perhaps near @) */
	/* Note: if apport == 1 then our behaviour is independent of udist */
	if(mtmp->minvent){
		if(!rn2(udist) || !rn2((int) edog->apport))
		if(rn2(10) < edog->apport){
			relobj(mtmp, (int) mtmp->minvis);
			if(edog->apport > 1) edog->apport--;
			edog->dropdist = udist;		/* hpscdi!jon */
			edog->droptime = moves;
		}
	} else {
		if ((obj = o_at(omx,omy)))
			if(!strchr("0_", obj->olet)){
				if((otyp = dogfood(obj)) <= CADAVER){
					nix = omx;
					niy = omy;
					goto eatobj;
				}
				if (obj->owt < 10*mtmp->data->mlevel)
					if (rn2(20) < edog->apport+3)
						if (rn2(udist) || !rn2((int) edog->apport)){
							freeobj(obj);
							unpobj(obj);
							/* if(levl[omx][omy].scrsym == obj->olet)
								newsym(omx,omy); */
							mpickobj(mtmp,obj);
						}
			}
	}

	/* first we look for food */
	gtyp = UNDEF;	/* no goal as yet */
	gx = gy = 0;
	for(obj = fobj; obj; obj = obj->nobj) {
		otyp = dogfood(obj);
		if(otyp > gtyp || otyp == UNDEF) continue;
		if(inroom(obj->ox,obj->oy) != dogroom) continue;
		if(otyp < MANFOOD &&
		 (dogroom >= 0 || DDIST(obj->ox,obj->oy) < 10)) {
			if(otyp < gtyp || (otyp == gtyp &&
				DDIST(obj->ox,obj->oy) < DDIST(gx,gy))){
				gx = obj->ox;
				gy = obj->oy;
				gtyp = otyp;
			}
		} else
		if(gtyp == UNDEF && dogroom >= 0 &&
		   uroom == dogroom &&
		   !mtmp->minvent && edog->apport > rn2(8)){
			gx = obj->ox;
			gy = obj->oy;
			gtyp = APPORT;
		}
	}
	if(gtyp == UNDEF ||
	  (gtyp != DOGFOOD && gtyp != APPORT && moves < edog->hungrytime)){
		if(dogroom < 0 || dogroom == uroom){
			gx = u.ux;
			gy = u.uy;
#ifndef QUEST
		} else {
			int tmp = rooms[(int)dogroom].fdoor;
			    cnt = rooms[(int)dogroom].doorct;

			gx = gy = FAR;	/* random, far away */
			while(cnt--){
			    if(dist(gx,gy) >
				dist(doors[tmp].x, doors[tmp].y)){
					gx = doors[tmp].x;
					gy = doors[tmp].y;
				}
				tmp++;
			}
			/* here gx == FAR e.g. when dog is in a vault */
			if(gx == FAR || (gx == omx && gy == omy)){
				gx = u.ux;
				gy = u.uy;
			}
#endif /* QUEST */
		}
		appr = (udist >= 9) ? 1 : (mtmp->mflee) ? -1 : 0;
		if(after && udist <= 4 && gx == u.ux && gy == u.uy)
			return(0);
		if(udist > 1){
			if (!IS_ROOM(levl[(int)u.ux][(int)u.uy].typ) || !rn2(4) ||
			   whappr ||
			   (mtmp->minvent && rn2((int) edog->apport)))
				appr = 1;
		}
		/* if you have dog food he'll follow you more closely */
		if (appr == 0) {
			obj = invent;
			while(obj){
				if(obj->otyp == TRIPE_RATION){
					appr = 1;
					break;
				}
				obj = obj->nobj;
			}
		}
	} else	appr = 1;	/* gtyp != UNDEF */
	if(mtmp->mconf) appr = 0;

	if(gx == u.ux && gy == u.uy && (dogroom != uroom || dogroom < 0)){
	coord *cp;
		cp = gettrack(omx,omy);
		if(cp){
			gx = cp->x;
			gy = cp->y;
		}
	}

	nix = omx;
	niy = omy;
	cnt = mfndpos(mtmp,poss,info,ALLOW_M | ALLOW_TRAPS);
	chcnt = 0;
	chi = -1;
	for(i=0; i<cnt; i++){
		nx = poss[i].x;
		ny = poss[i].y;
		if(info[i] & ALLOW_M){
			mtmp2 = m_at(nx,ny);
			if(mtmp2->data->mlevel >= mdat->mlevel+2 ||
			  mtmp2->data->mlet == 'c')
				continue;
			if(after) return(0); /* hit only once each move */

			if(hitmm(mtmp, mtmp2) == 1 && rn2(4) &&
			  mtmp2->mlstmv != moves &&
			  hitmm(mtmp2,mtmp) == 2) return(2);
			return(0);
		}

		/* dog avoids traps */
		/* but perhaps we have to pass a trap in order to follow @ */
		if((info[i] & ALLOW_TRAPS) && (trap = t_at(nx,ny))){
			if(!trap->tseen && rn2(40)) continue;
			if(rn2(10)) continue;
		}

		/* dog eschewes cursed objects */
		/* but likes dog food */
		obj = fobj;
		while(obj){
		    if(obj->ox != nx || obj->oy != ny)
			goto nextobj;
		    if(obj->cursed) goto nxti;
		    if(obj->olet == FOOD_SYM &&
			(otyp = dogfood(obj)) < MANFOOD &&
			(otyp < ACCFOOD || edog->hungrytime <= moves)){
			/* Note: our dog likes the food so much that he
			might eat it even when it conceals a cursed object */
			nix = nx;
			niy = ny;
			chi = i;
		     eatobj:
			edog->eattime =
			    moves + obj->quan * objects[obj->otyp].oc_delay;
			if(edog->hungrytime < moves)
			    edog->hungrytime = moves;
			edog->hungrytime +=
			    5*obj->quan * objects[obj->otyp].nutrition;
			mtmp->mconf = 0;
			if(cansee(nix,niy))
			    pline("%s ate %s.", Monnam(mtmp), doname(obj));
			/* perhaps this was a reward */
			if(otyp != CADAVER)
			edog->apport += 200/(edog->dropdist+moves-edog->droptime);
			delobj(obj);
			goto newdogpos;
		    }
		nextobj:
		    obj = obj->nobj;
		}

		for(j=0; j<MTSZ && j<cnt-1; j++)
			if(nx == mtmp->mtrack[j].x && ny == mtmp->mtrack[j].y)
				if(rn2(4*(cnt-j))) goto nxti;

/* Some stupid C compilers cannot compute the whole expression at once. */
		nearer = GDIST(nx,ny);
		nearer -= GDIST(nix,niy);
		nearer *= appr;
		if((nearer == 0 && !rn2(++chcnt)) || nearer<0 ||
			(nearer > 0 && !whappr &&
				((omx == nix && omy == niy && !rn2(3))
				|| !rn2(12))
			)){
			nix = nx;
			niy = ny;
			if(nearer < 0) chcnt = 0;
			chi = i;
		}
	nxti:	;
	}
newdogpos:
	if(nix != omx || niy != omy){
		if(info[chi] & ALLOW_U){
			(void) hitu(mtmp, d(mdat->damn, mdat->damd)+1);
			return(0);
		}
		mtmp->mx = nix;
		mtmp->my = niy;
		for(j=MTSZ-1; j>0; j--) mtmp->mtrack[j] = mtmp->mtrack[j-1];
		mtmp->mtrack[0].x = omx;
		mtmp->mtrack[0].y = omy;
	}
	if(mintrap(mtmp) == 2)	/* he died */
		return(2);
	pmon(mtmp);
	return(1);
}
Ejemplo n.º 16
0
/* pick a lock on a chest or door with a given object */
int
pick_lock(struct obj *pick, const struct nh_cmd_arg *arg)
{
    int picktyp, c;
    coord cc;
    schar dx, dy, dz;
    struct rm *door;
    struct obj *otmp;
    const char *qbuf;

    if (!getargdir(arg, NULL, &dx, &dy, &dz))
        return 0;
    cc.x = youmonst.mx + dx;
    cc.y = youmonst.my + dy;
    if (!isok(cc.x, cc.y))
        return 0;

    picktyp = pick->otyp;
    pick->lastused = moves;

    /* Check whether we're resuming an interrupted previous attempt.  For a
       floor pick, we have u.utracked[tos_lock] as a non-zeroobj and dx and dy
       as 0.  For a door, we have u.utracked_location[tl_lock] specifying the
       location and u.utracked[tos_lock] as &zeroobj. */
    if (u.uoccupation_progress[tos_lock] &&
        ((u.utracked_location[tl_lock].x == cc.x &&
          u.utracked_location[tl_lock].y == cc.y &&
          u.utracked[tos_lock] == &zeroobj) ||
         (dx == 0 && dy == 0 && u.utracked[tos_lock] != &zeroobj))) {
        static const char no_longer[] =
            "Unfortunately, you can no longer %s %s.";

        if (nohands(youmonst.data)) {
            const char *what = (picktyp == LOCK_PICK) ? "pick" : "key";

            if (picktyp == CREDIT_CARD)
                what = "card";
            pline(msgc_interrupted, no_longer, "hold the", what);
            return reset_pick();
        } else if (u.utracked[tos_lock] != &zeroobj && !can_reach_floor()) {
            pline(msgc_interrupted, no_longer, "reach the", "lock");
            return reset_pick();
        } else {
            const char *action = lock_action();

            if (turnstate.continue_message)
                pline(msgc_occstart, "You resume your attempt at %s.", action);

            one_occupation_turn(picklock, "picking the lock", occ_lock);
            return 1;
        }
    }

    if (nohands(youmonst.data)) {
        pline(msgc_cancelled, "You can't hold %s -- you have no hands!",
              doname(pick));
        return 0;
    }

    if ((picktyp != LOCK_PICK && picktyp != CREDIT_CARD &&
         picktyp != SKELETON_KEY)) {
        impossible("picking lock with object %d?", picktyp);
        return 0;
    }

    if (!dx && !dy) { /* pick lock on a container */
        const char *verb;
        boolean it;
        int count;

        if (dz < 0) {
            pline(msgc_cancelled, "There isn't any sort of lock up %s.",
                  Levitation ? "here" : "there");
            return 0;
        } else if (is_lava(level, youmonst.mx, youmonst.my)) {
            pline(msgc_cancelled, "Doing that would probably melt your %s.",
                  xname(pick));
            return 0;
        } else if (is_pool(level, youmonst.mx, youmonst.my) && !Underwater) {
            /* better YAFM - AIS */
            pline(msgc_cancelled,
                  "Canals might have locks, but this water doesn't.");
            return 0;
        }

        count = 0;
        c = 'n';        /* in case there are no boxes here */
        for (otmp = level->objects[cc.x][cc.y]; otmp; otmp = otmp->nexthere)
            if (Is_box(otmp)) {
                ++count;
                if (!can_reach_floor()) {
                    pline(msgc_cancelled, "You can't reach %s from up here.",
                          the(xname(otmp)));
                    return 0;
                }
                it = 0;
                if (otmp->obroken)
                    verb = "fix";
                else if (!otmp->olocked)
                    verb = "lock", it = 1;
                else if (picktyp != LOCK_PICK)
                    verb = "unlock", it = 1;
                else
                    verb = "pick";
                qbuf = msgprintf(
                    "There is %s here, %s %s?",
                    safe_qbuf("",
                              sizeof ("There is  here, unlock its lock?"),
                              doname(otmp), an(simple_typename(otmp->otyp)),
                              "a box"), verb, it ? "it" : "its lock");

                c = ynq(qbuf);
                if (c == 'q')
                    return 0;
                if (c == 'n')
                    continue;

                if (otmp->obroken) {
                    pline(msgc_cancelled,
                          "You can't fix its broken lock with %s.",
                          doname(pick));
                    return 0;
                } else if (picktyp == CREDIT_CARD && !otmp->olocked) {
                    /* credit cards are only good for unlocking */
                    pline(msgc_cancelled, "You can't do that with %s.",
                          doname(pick));
                    return 0;
                }

                u.utracked[tos_lock] = otmp;
                u.uoccupation_progress[tos_lock] = 0;
                break;
            }
        if (c != 'y') {
            if (!count)
                pline(msgc_cancelled,
                      "There doesn't seem to be any sort of lock here.");
            return 0;   /* decided against all boxes */
        }
    } else {    /* pick the lock in a door */
        struct monst *mtmp;

        if (u.utrap && u.utraptype == TT_PIT) {
            pline(msgc_cancelled,
                  "You can't reach over the edge of the pit.");
            return 0;
        }

        door = &level->locations[cc.x][cc.y];
        if ((mtmp = m_at(level, cc.x, cc.y)) && canseemon(mtmp)) {
            if (picktyp == CREDIT_CARD &&
                (mx_eshk(mtmp) || mtmp->data == &mons[PM_ORACLE]))
                verbalize(msgc_npcvoice, "No checks, no credit, no problem.");
            else
                pline(msgc_mispaste, "I don't think %s would appreciate that.",
                      mon_nam(mtmp));
            return 0;
        }
        if (mtmp && (mtmp->m_ap_type == M_AP_FURNITURE) &&
            (mtmp->mappearance == S_hcdoor || mtmp->mappearance == S_vcdoor) &&
            !Protection_from_shape_changers) {
            stumble_onto_mimic(mtmp, dx, dy);
            return 1;
        }
        if (!IS_DOOR(door->typ)) {
            if (is_drawbridge_wall(cc.x, cc.y) >= 0)
                pline(msgc_cancelled, "You %s no lock on the drawbridge.",
                      Blind ? "feel" : "see");
            else
                pline(msgc_mispaste, "You %s no door there.",
                      Blind ? "feel" : "see");
            return 0;
        }
        switch (door->doormask) {
        case D_NODOOR:
            pline(msgc_cancelled, "This doorway has no door.");
            return 0;
        case D_ISOPEN:
            pline(msgc_cancelled, "You cannot lock an open door.");
            return 0;
        case D_BROKEN:
            pline(msgc_cancelled, "This door is broken.");
            return 0;
        default:
            /* credit cards are only good for unlocking */
            if (picktyp == CREDIT_CARD && !(door->doormask & D_LOCKED)) {
                pline(msgc_cancelled,
                      "You can't lock a door with a credit card.");
                return 0;
            }

            /* At this point, the player knows that the door is a door, and
               whether it's locked, but not whether it's trapped; to do this,
               we set the mem_door_l flag and call map_background, which will
               clear it if necessary (i.e. not a door after all). */
            level->locations[cc.x][cc.y].mem_door_l = 1;
            map_background(cc.x, cc.y, TRUE);

            u.utracked[tos_lock] = &zeroobj;
            u.utracked_location[tl_lock] = cc;
            u.uoccupation_progress[tos_lock] = 0;
        }
    }

    one_occupation_turn(picklock, "picking the lock", occ_lock);
    return 1;
}
Ejemplo n.º 17
0
/* return 1 if action took 1 (or more) moves, 0 if error or aborted */
int doengrave(struct obj *otmp)
{
	boolean dengr = FALSE;	/* TRUE if we wipe out the current engraving */
	boolean doblind = FALSE;/* TRUE if engraving blinds the player */
	boolean doknown = FALSE;/* TRUE if we identify the stylus */
	boolean eow = FALSE;	/* TRUE if we are overwriting oep */
	boolean jello = FALSE;	/* TRUE if we are engraving in slime */
	boolean ptext = TRUE;	/* TRUE if we must prompt for engrave text */
	boolean teleengr =FALSE;/* TRUE if we move the old engraving */
	boolean zapwand = FALSE;/* TRUE if we remove a wand charge */
	xchar type = DUST;	/* Type of engraving made */
	char buf[BUFSZ];	/* Buffer for final/poly engraving text */
	char ebuf[BUFSZ];	/* Buffer for initial engraving text */
	char qbuf[QBUFSZ];	/* Buffer for query text */
	char post_engr_text[BUFSZ]; /* Text displayed after engraving prompt */
	const char *everb;	/* Present tense of engraving type */
	const char *eloc;	/* Where the engraving is (ie dust/floor/...) */
	char *sp;		/* Place holder for space count of engr text */
	int len;		/* # of nonspace chars of new engraving text */
	int maxelen;		/* Max allowable length of engraving text */
	struct engr *oep = engr_at(level, u.ux,u.uy);
				/* The current engraving */
	char *writer;

	multi = 0;		/* moves consumed */
	nomovemsg = NULL;	/* occupation end message */

	buf[0] = (char)0;
	ebuf[0] = (char)0;
	post_engr_text[0] = (char)0;
	maxelen = BUFSZ - 1;
	if (is_demon(youmonst.data) || youmonst.data->mlet == S_VAMPIRE)
	    type = ENGR_BLOOD;

	/* Can the adventurer engrave at all? */

	if (u.uswallow) {
		if (is_animal(u.ustuck->data)) {
			pline("What would you write?  \"Jonah was here\"?");
			return 0;
		} else if (is_whirly(u.ustuck->data)) {
			pline("You can't reach the %s.", surface(u.ux,u.uy));
                        return 0;
		} else
			jello = TRUE;
	} else if (is_lava(level, u.ux, u.uy)) {
		pline("You can't write on the lava!");
		return 0;
	} else if (Underwater) {
		pline("You can't write underwater!");
		return 0;
	} else if (is_pool(level, u.ux,u.uy) || IS_FOUNTAIN(level->locations[u.ux][u.uy].typ)) {
		pline("You can't write on the water!");
		return 0;
	}
	if (Is_airlevel(&u.uz) || Is_waterlevel(&u.uz)/* in bubble */) {
		pline("You can't write in thin air!");
		return 0;
	}
	if (cantwield(youmonst.data)) {
		pline("You can't even hold anything!");
		return 0;
	}
	if (check_capacity(NULL)) return 0;

	/* One may write with finger, or weapon, or wand, or..., or...
	 * Edited by GAN 10/20/86 so as not to change weapon wielded.
	 */

	if (otmp && !validate_object(otmp, styluses, "write with"))
		return 0;
	else if (!otmp)
		otmp = getobj(styluses, "write with");
	if (!otmp) return 0;		/* otmp == zeroobj if fingers */

	if (otmp == &zeroobj) writer = makeplural(body_part(FINGER));
	else writer = xname(otmp);

	/* There's no reason you should be able to write with a wand
	 * while both your hands are tied up.
	 */
	if (!freehand() && otmp != uwep && !otmp->owornmask) {
		pline("You have no free %s to write with!", body_part(HAND));
		return 0;
	}

	if (jello) {
		pline("You tickle %s with your %s.", mon_nam(u.ustuck), writer);
		pline("Your message dissolves...");
		return 0;
	}
	if (otmp->oclass != WAND_CLASS && !can_reach_floor()) {
		pline("You can't reach the %s!", surface(u.ux,u.uy));
                return 0;
	}
	if (IS_ALTAR(level->locations[u.ux][u.uy].typ)) {
		pline("You make a motion towards the altar with your %s.", writer);
		altar_wrath(u.ux, u.uy);
		return 0;
	}
	if (IS_GRAVE(level->locations[u.ux][u.uy].typ)) {
	    if (otmp == &zeroobj) { /* using only finger */
		pline("You would only make a small smudge on the %s.",
			surface(u.ux, u.uy));
		return 0;
	    } else if (!level->locations[u.ux][u.uy].disturbed) {
		pline("You disturb the undead!");
		level->locations[u.ux][u.uy].disturbed = 1;
		makemon(&mons[PM_GHOUL], level, u.ux, u.uy, NO_MM_FLAGS);
		exercise(A_WIS, FALSE);
		return 1;
	    }
	}

	/* SPFX for items */

	switch (otmp->oclass) {
	    default:
	    case AMULET_CLASS:
	    case CHAIN_CLASS:
	    case POTION_CLASS:
	    case COIN_CLASS:
		break;

	    case RING_CLASS:
		/* "diamond" rings and others should work */
	    case GEM_CLASS:
		/* diamonds & other hard gems should work */
		if (objects[otmp->otyp].oc_tough) {
			type = ENGRAVE;
			break;
		}
		break;

	    case ARMOR_CLASS:
		if (is_boots(otmp)) {
			type = DUST;
			break;
		}
		/* fall through */
	    /* Objects too large to engrave with */
	    case BALL_CLASS:
	    case ROCK_CLASS:
		pline("You can't engrave with such a large object!");
		ptext = FALSE;
		break;

	    /* Objects too silly to engrave with */
	    case FOOD_CLASS:
	    case SCROLL_CLASS:
	    case SPBOOK_CLASS:
		pline("Your %s would get %s.", xname(otmp),
			is_ice(level, u.ux, u.uy) ? "all frosty" : "too dirty");
		ptext = FALSE;
		break;

	    case RANDOM_CLASS:	/* This should mean fingers */
		break;

	    /* The charge is removed from the wand before prompting for
	     * the engraving text, because all kinds of setup decisions
	     * and pre-engraving messages are based upon knowing what type
	     * of engraving the wand is going to do.  Also, the player
	     * will have potentially seen "You wrest .." message, and
	     * therefore will know they are using a charge.
	     */
	    case WAND_CLASS:
		if (zappable(otmp)) {
		    check_unpaid(otmp);
		    zapwand = TRUE;
		    if (Levitation) ptext = FALSE;

		    switch (otmp->otyp) {
		    /* DUST wands */
		    default:
			break;

			/* NODIR wands */
		    case WAN_LIGHT:
		    case WAN_SECRET_DOOR_DETECTION:
		    case WAN_CREATE_MONSTER:
		    case WAN_WISHING:
		    case WAN_ENLIGHTENMENT:
			zapnodir(otmp);
			break;

			/* IMMEDIATE wands */
			/* If wand is "IMMEDIATE", remember to affect the
			 * previous engraving even if turning to dust.
			 */
		    case WAN_STRIKING:
			strcpy(post_engr_text,
			"The wand unsuccessfully fights your attempt to write!"
			);
			break;
		    case WAN_SLOW_MONSTER:
			if (!Blind) {
			   sprintf(post_engr_text,
				   "The bugs on the %s slow down!",
				   surface(u.ux, u.uy));
			}
			break;
		    case WAN_SPEED_MONSTER:
			if (!Blind) {
			   sprintf(post_engr_text,
				   "The bugs on the %s speed up!",
				   surface(u.ux, u.uy));
			}
			break;
		    case WAN_POLYMORPH:
			if (oep)  {
			    if (!Blind) {
				type = (xchar)0;	/* random */
				random_engraving(buf);
			    }
			    dengr = TRUE;
			}
			break;
		    case WAN_NOTHING:
		    case WAN_UNDEAD_TURNING:
		    case WAN_OPENING:
		    case WAN_LOCKING:
		    case WAN_PROBING:
			break;

			/* RAY wands */
		    case WAN_MAGIC_MISSILE:
			ptext = TRUE;
			if (!Blind) {
			   sprintf(post_engr_text,
				   "The %s is riddled by bullet holes!",
				   surface(u.ux, u.uy));
			}
			break;

		    /* can't tell sleep from death - Eric Backus */
		    case WAN_SLEEP:
		    case WAN_DEATH:
			if (!Blind) {
			   sprintf(post_engr_text,
				   "The bugs on the %s stop moving!",
				   surface(u.ux, u.uy));
			}
			break;

		    case WAN_COLD:
			if (!Blind)
			    strcpy(post_engr_text,
				"A few ice cubes drop from the wand.");
			if (!oep || (oep->engr_type != BURN))
			    break;
		    case WAN_CANCELLATION:
		    case WAN_MAKE_INVISIBLE:
			if (oep && oep->engr_type != HEADSTONE) {
			    if (!Blind)
				pline("The engraving on the %s vanishes!",
					surface(u.ux,u.uy));
			    dengr = TRUE;
			}
			break;
		    case WAN_TELEPORTATION:
			if (oep && oep->engr_type != HEADSTONE) {
			    if (!Blind)
				pline("The engraving on the %s vanishes!",
					surface(u.ux,u.uy));
			    teleengr = TRUE;
			}
			break;

		    /* type = ENGRAVE wands */
		    case WAN_DIGGING:
			ptext = TRUE;
			type  = ENGRAVE;
			if (!objects[otmp->otyp].oc_name_known) {
			    if (flags.verbose)
				pline("This %s is a wand of digging!",
				xname(otmp));
			    doknown = TRUE;
			}
			if (!Blind)
			    strcpy(post_engr_text,
				IS_GRAVE(level->locations[u.ux][u.uy].typ) ?
				"Chips fly out from the headstone." :
				is_ice(level, u.ux, u.uy) ?
				"Ice chips fly up from the ice surface!" :
				"Gravel flies up from the floor.");
			else
			    strcpy(post_engr_text, "You hear drilling!");
			break;

		    /* type = BURN wands */
		    case WAN_FIRE:
			ptext = TRUE;
			type  = BURN;
			if (!objects[otmp->otyp].oc_name_known) {
			if (flags.verbose)
			    pline("This %s is a wand of fire!", xname(otmp));
			    doknown = TRUE;
			}
			strcpy(post_engr_text,
				Blind ? "You feel the wand heat up." :
					"Flames fly from the wand.");
			break;
		    case WAN_LIGHTNING:
			ptext = TRUE;
			type  = BURN;
			if (!objects[otmp->otyp].oc_name_known) {
			    if (flags.verbose)
				pline("This %s is a wand of lightning!",
					xname(otmp));
			    doknown = TRUE;
			}
			if (!Blind) {
			    strcpy(post_engr_text,
				    "Lightning arcs from the wand.");
			    doblind = TRUE;
			} else
			    strcpy(post_engr_text, "You hear crackling!");
			break;

		    /* type = MARK wands */
		    /* type = ENGR_BLOOD wands */
		    }
		} else /* end if zappable */
		    if (!can_reach_floor()) {
			pline("You can't reach the %s!", surface(u.ux,u.uy));
			/* If it's a wrestable wand, the player wasted a
			   turn trying. */
			if (wrestable(otmp))
			    return 1;
			else
			    return 0;
		    }
		break;

	    case WEAPON_CLASS:
		if (is_blade(otmp)) {
		    if ((int)otmp->spe > -3)
			type = ENGRAVE;
		    else
			pline("Your %s too dull for engraving.", aobjnam(otmp,"are"));
		}
		break;

	    case TOOL_CLASS:
		if (otmp == ublindf) {
		    pline(
		"That is a bit difficult to engrave with, don't you think?");
		    return 0;
		}
		switch (otmp->otyp)  {
		    case MAGIC_MARKER:
			if (otmp->spe <= 0)
			    pline("Your marker has dried out.");
			else
			    type = MARK;
			break;
		    case TOWEL:
			/* Can't really engrave with a towel */
			ptext = FALSE;
			if (oep)
			    if ((oep->engr_type == DUST ) ||
				(oep->engr_type == ENGR_BLOOD) ||
				(oep->engr_type == MARK )) {
				if (!Blind)
				    pline("You wipe out the message here.");
				else
				    pline("Your %s %s %s.", xname(otmp),
					 otense(otmp, "get"),
					 is_ice(level, u.ux, u.uy) ?
					 "frosty" : "dusty");
				dengr = TRUE;
			    } else
				pline("Your %s can't wipe out this engraving.",
				     xname(otmp));
			else
			    pline("Your %s %s %s.", xname(otmp), otense(otmp, "get"),
				  is_ice(level, u.ux, u.uy) ? "frosty" : "dusty");
			break;
		    default:
			break;
		}
		break;

	    case VENOM_CLASS:
		if (wizard) {
		    pline("Writing a poison pen letter??");
		    break;
		}
	    case ILLOBJ_CLASS:
		impossible("You're engraving with an illegal object!");
		break;
	}

	if (IS_GRAVE(level->locations[u.ux][u.uy].typ)) {
	    if (type == ENGRAVE || type == 0)
		type = HEADSTONE;
	    else {
		/* ensures the "cannot wipe out" case */
		type = DUST;
		dengr = FALSE;
		teleengr = FALSE;
		buf[0] = (char)0;
	    }
	}

	/* End of implement setup */

	/* Identify stylus */
	if (doknown) {
	    makeknown(otmp->otyp);
	    more_experienced(0,10);
	}

	if (teleengr) {
	    rloc_engr(oep);
	    oep = NULL;
	}

	if (dengr) {
	    del_engr(oep, level);
	    oep = NULL;
	}

	/* Something has changed the engraving here */
	if (*buf) {
	    make_engr_at(level, u.ux, u.uy, buf, moves, type);
	    pline("The engraving now reads: \"%s\".", buf);
	    ptext = FALSE;
	}

	if (zapwand && (otmp->spe < 0)) {
	    pline("%s %sturns to dust.",
		  The(xname(otmp)), Blind ? "" : "glows violently, then ");
	    if (!IS_GRAVE(level->locations[u.ux][u.uy].typ))
		pline("You are not going to get anywhere trying to write in the %s with your dust.",
		    is_ice(level, u.ux, u.uy) ? "frost" : "dust");
	    useup(otmp);
	    ptext = FALSE;
	}

	if (!ptext) {		/* Early exit for some implements. */
	    if (otmp->oclass == WAND_CLASS && !can_reach_floor())
		pline("You can't reach the %s!", surface(u.ux,u.uy));
	    return 1;
	}

	/* Special effects should have deleted the current engraving (if
	 * possible) by now.
	 */

	if (oep) {
	    char c = 'n';

	    /* Give player the choice to add to engraving. */

	    if (type == HEADSTONE) {
		/* no choice, only append */
		c = 'y';
	    } else if ( (type == oep->engr_type) && (!Blind ||
		 (oep->engr_type == BURN) || (oep->engr_type == ENGRAVE)) ) {
		c = yn_function("Do you want to add to the current engraving?",
				ynqchars, 'y');
		if (c == 'q') {
		    pline("Never mind.");
		    return 0;
		}
	    }

	    if (c == 'n' || Blind) {

		if ( (oep->engr_type == DUST) || (oep->engr_type == ENGR_BLOOD) ||
		    (oep->engr_type == MARK) ) {
		    if (!Blind) {
			pline("You wipe out the message that was %s here.",
			    ((oep->engr_type == DUST)  ? "written in the dust" :
			    ((oep->engr_type == ENGR_BLOOD) ? "scrawled in blood"   :
							 "written")));
			del_engr(oep, level);
			oep = NULL;
		    } else
		   /* Don't delete engr until after we *know* we're engraving */
			eow = TRUE;
		} else
		    if ( (type == DUST) || (type == MARK) || (type == ENGR_BLOOD) ) {
			pline(
			 "You cannot wipe out the message that is %s the %s here.",
			 oep->engr_type == BURN ?
			   (is_ice(level, u.ux, u.uy) ? "melted into" : "burned into") :
			   "engraved in", surface(u.ux,u.uy));
			return 1;
		    } else
			if ( (type != oep->engr_type) || (c == 'n') ) {
			    if (!Blind || can_reach_floor())
				pline("You will overwrite the current message.");
			    eow = TRUE;
			}
	    }
	}

	eloc = surface(u.ux,u.uy);
	switch(type){
	    default:
		everb = (oep && !eow ? "add to the weird writing on" :
				       "write strangely on");
		break;
	    case DUST:
		everb = (oep && !eow ? "add to the writing in" :
				       "write in");
		eloc = is_ice(level, u.ux, u.uy) ? "frost" : "dust";
		break;
	    case HEADSTONE:
		everb = (oep && !eow ? "add to the epitaph on" :
				       "engrave on");
		break;
	    case ENGRAVE:
		everb = (oep && !eow ? "add to the engraving in" :
				       "engrave in");
		break;
	    case BURN:
		everb = (oep && !eow ?
			( is_ice(level, u.ux,u.uy) ? "add to the text melted into" :
					      "add to the text burned into") :
			( is_ice(level, u.ux,u.uy) ? "melt into" : "burn into"));
		break;
	    case MARK:
		everb = (oep && !eow ? "add to the graffiti on" :
				       "scribble on");
		break;
	    case ENGR_BLOOD:
		everb = (oep && !eow ? "add to the scrawl on" :
				       "scrawl on");
		break;
	}

	/* Tell adventurer what is going on */
	if (otmp != &zeroobj)
	    pline("You %s the %s with %s.", everb, eloc, doname(otmp));
	else
	    pline("You %s the %s with your %s.", everb, eloc,
		makeplural(body_part(FINGER)));

	/* Prompt for engraving! */
	sprintf(qbuf,"What do you want to %s the %s here?", everb, eloc);
	getlin(qbuf, ebuf);

	/* Count the actual # of chars engraved not including spaces */
	len = strlen(ebuf);
	for (sp = ebuf; *sp; sp++) if (isspace(*sp)) len -= 1;

	if (len == 0 || strchr(ebuf, '\033')) {
	    if (zapwand) {
		if (!Blind)
		    pline("%s, then %s.",
			  Tobjnam(otmp, "glow"), otense(otmp, "fade"));
		return 1;
	    } else {
		pline("Never mind.");
                if (otmp && otmp->oclass == WAND_CLASS && wrestable(otmp))
                    return 1; /* disallow zero turn wrest */
                else
                    return 0;
	    }
	}

	/* A single `x' is the traditional signature of an illiterate person */
	if (len != 1 || (!strchr(ebuf, 'x') && !strchr(ebuf, 'X')))
	    u.uconduct.literate++;

	/* Mix up engraving if surface or state of mind is unsound.
	   Note: this won't add or remove any spaces. */
	for (sp = ebuf; *sp; sp++) {
	    if (isspace(*sp)) continue;
	    if (((type == DUST || type == ENGR_BLOOD) && !rn2(25)) ||
		    (Blind && !rn2(11)) || (Confusion && !rn2(7)) ||
		    (Stunned && !rn2(4)) || (Hallucination && !rn2(2)))
		*sp = ' ' + rnd(96 - 2);	/* ASCII '!' thru '~'
						   (excludes ' ' and DEL) */
	}

	/* Previous engraving is overwritten */
	if (eow) {
	    del_engr(oep, level);
	    oep = NULL;
	}

	/* Figure out how long it took to engrave, and if player has
	 * engraved too much.
	 */
	switch(type){
	    default:
		multi = -(len/10);
		if (multi) nomovemsg = "You finish your weird engraving.";
		break;
	    case DUST:
		multi = -(len/10);
		if (multi) nomovemsg = "You finish writing in the dust.";
		break;
	    case HEADSTONE:
	    case ENGRAVE:
		multi = -(len/10);
		if ((otmp->oclass == WEAPON_CLASS) &&
		    ((otmp->otyp != ATHAME) || otmp->cursed)) {
		    multi = -len;
		    maxelen = ((otmp->spe + 3) * 2) + 1;
			/* -2 = 3, -1 = 5, 0 = 7, +1 = 9, +2 = 11
			 * Note: this does not allow a +0 anything (except
			 *	 an athame) to engrave "Elbereth" all at once.
			 *	 However, you could now engrave "Elb", then
			 *	 "ere", then "th".
			 */
		    pline("Your %s dull.", aobjnam(otmp, "get"));
		    if (otmp->unpaid) {
			struct monst *shkp = shop_keeper(level, *u.ushops);
			if (shkp) {
			    pline("You damage it, you pay for it!");
			    bill_dummy_object(otmp);
			}
		    }
		    if (len > maxelen) {
			multi = -maxelen;
			otmp->spe = -3;
		    } else if (len > 1)
			otmp->spe -= len >> 1;
		    else otmp->spe -= 1; /* Prevent infinite engraving */
		} else
Ejemplo n.º 18
0
/* Returns 1 when something was stolen (or at least, when N should flee now)
 * Returns -1 if the monster died in the attempt
 * Avoid stealing the object stealoid
 */
int steal(struct monst *mtmp, char *objnambuf)
{
	struct obj *otmp;
	int tmp, could_petrify, named = 0, armordelay;
	boolean monkey_business; /* true iff an animal is doing the thievery */

	if (objnambuf) *objnambuf = '\0';
	/* the following is true if successful on first of two attacks. */
	if (!monnear(mtmp, u.ux, u.uy)) return 0;

	/* food being eaten might already be used up but will not have
	   been removed from inventory yet; we don't want to steal that,
	   so this will cause it to be removed now */
	if (occupation) maybe_finished_meal(FALSE);

	if (!invent || (inv_cnt() == 1 && uskin)) {
nothing_to_steal:
	    /* Not even a thousand men in armor can strip a naked man. */
	    if (Blind)
	      pline("Somebody tries to rob you, but finds nothing to steal.");
	    else
	      pline("%s tries to rob you, but there is nothing to steal!",
		Monnam(mtmp));
	    return 1;	/* let her flee */
	}

	/* Monkey or mugger robbing you.
	   You don't wanna be charmed/seduced by a mugger. */
	monkey_business = is_robber(mtmp->data);
	if (monkey_business) {
	    ;	/* skip ring special cases */
	} else if (Adornment & LEFT_RING) {
	    otmp = uleft;
	    goto gotobj;
	} else if (Adornment & RIGHT_RING) {
	    otmp = uright;
	    goto gotobj;
	}

	tmp = 0;
	for (otmp = invent; otmp; otmp = otmp->nobj)
	    if ((!uarm || otmp != uarmc) && otmp != uskin
#ifdef INVISIBLE_OBJECTS
				&& (!otmp->oinvis || perceives(mtmp->data))
#endif
				)
		tmp += ((otmp->owornmask &
			(W_ARMOR | W_RING | W_AMUL | W_TOOL)) ? 5 : 1);
	if (!tmp) goto nothing_to_steal;
	tmp = rn2(tmp);
	for (otmp = invent; otmp; otmp = otmp->nobj)
	    if ((!uarm || otmp != uarmc) && otmp != uskin
#ifdef INVISIBLE_OBJECTS
				&& (!otmp->oinvis || perceives(mtmp->data))
#endif
			)
		if ((tmp -= ((otmp->owornmask &
			(W_ARMOR | W_RING | W_AMUL | W_TOOL)) ? 5 : 1)) < 0)
			break;
	if (!otmp) {
		warning("Steal fails!");
		return 0;
	}
	/* can't steal gloves while wielding - so steal the wielded item. */
	if (otmp == uarmg && uwep)
	    otmp = uwep;
	/* can't steal armor while wearing cloak - so steal the cloak. */
	else if (otmp == uarm && uarmc) otmp = uarmc;
	else if (otmp == uarmu && uarmc) otmp = uarmc;
	else if (otmp == uarmu && uarm) otmp = uarm;
gotobj:
	if (otmp->o_id == stealoid) return 0;

	/* animals can't overcome curse stickiness nor unlock chains */
	if (monkey_business) {
	    boolean ostuck;
	    /* is the player prevented from voluntarily giving up this item?
	       (ignores loadstones; the !can_carry() check will catch those) */
	    if (otmp == uball)
		ostuck = TRUE;	/* effectively worn; curse is implicit */
	    else if (otmp == uquiver || (otmp == uswapwep && !u.twoweap))
		ostuck = FALSE;	/* not really worn; curse doesn't matter */
	    else
		ostuck = (otmp->cursed && otmp->owornmask);

	    if (ostuck || !can_carry(mtmp, otmp)) {
		static const char * const how[] = { "steal","snatch","grab","take" };
 cant_take:
		pline("%s tries to %s your %s but gives up.",
		      Monnam(mtmp), how[rn2(SIZE(how))],
		      (otmp->owornmask & W_ARMOR) ? equipname(otmp) :
		       cxname(otmp));
		/* the fewer items you have, the less likely the thief
		   is going to stick around to try again (0) instead of
		   running away (1) */
		return !rn2(inv_cnt() / 5 + 2);
	    }
	}

	if (otmp->otyp == LEASH && otmp->leashmon) {
	    if (monkey_business && otmp->cursed) goto cant_take;
	    o_unleash(otmp);
	}

	/* you're going to notice the theft... */
	stop_occupation();

	if ((otmp->owornmask & (W_ARMOR | W_RING | W_AMUL | W_TOOL))){
		switch(otmp->oclass) {
		case TOOL_CLASS:
		case AMULET_CLASS:
		case RING_CLASS:
		case FOOD_CLASS: /* meat ring */
		    remove_worn_item(otmp, TRUE);
		    break;
		case ARMOR_CLASS:
		    armordelay = objects[otmp->otyp].oc_delay;
		    /* Stop putting on armor which has been stolen. */
		    if (donning(otmp)) {
			remove_worn_item(otmp, TRUE);
			break;
		    } else if (monkey_business) {
			/* animals usually don't have enough patience
			   to take off items which require extra time */
			if (armordelay >= 1 && rn2(10)) goto cant_take;
			remove_worn_item(otmp, TRUE);
			break;
		    } else {
			int curssv = otmp->cursed;
			int slowly;
			boolean seen = canspotmon(level, mtmp);

			otmp->cursed = 0;
			/* can't charm you without first waking you */
			if (multi < 0 && is_fainted()) unmul(NULL);
			slowly = (armordelay >= 1 || multi < 0);
			if (flags.female)
			    pline("%s charms you.  You gladly %s your %s.",
				  !seen ? "She" : Monnam(mtmp),
				  curssv ? "let her take" :
				  slowly ? "start removing" : "hand over",
				  equipname(otmp));
			else
			    pline("%s seduces you and %s off your %s.",
				  !seen ? "She" : Adjmonnam(mtmp, "beautiful"),
				  curssv ? "helps you to take" :
				  slowly ? "you start taking" : "you take",
				  equipname(otmp));
			named++;
			/* the following is to set multi for later on */
			nomul(-armordelay, "taking off clothes");
			remove_worn_item(otmp, TRUE);
			otmp->cursed = curssv;
			if (multi < 0){
				/*
				multi = 0;
				nomovemsg = 0;
				afternmv = 0;
				*/
				stealoid = otmp->o_id;
				stealmid = mtmp->m_id;
				afternmv = stealarm;
				return 0;
			}
		    }
		    break;
		default:
		    warning("Tried to steal a strange worn thing. [%d]",
			    otmp->oclass);
		}
	}
	else if (otmp->owornmask)
	    remove_worn_item(otmp, TRUE);

	/* do this before removing it from inventory */
	if (objnambuf) strcpy(objnambuf, yname(otmp));
	/* set mavenge bit so knights won't suffer an
	 * alignment penalty during retaliation;
	 */
	mtmp->mavenge = 1;

	freeinv(otmp);
	pline("%s stole %s.", named ? "She" : Monnam(mtmp), doname(otmp));
	could_petrify = (otmp->otyp == CORPSE &&
			 touch_petrifies(&mons[otmp->corpsenm]));
	mpickobj(mtmp,otmp);	/* may free otmp */
	if (could_petrify && !(mtmp->misc_worn_check & W_ARMG)) {
	    minstapetrify(mtmp, TRUE);
	    return -1;
	}
	return (multi < 0) ? 0 : 1;
}
Ejemplo n.º 19
0
/*
 *   Generic yes/no function. 'def' is the default (returned by space or
 *   return; 'esc' returns 'q', or 'n', or the default, depending on
 *   what's in the string. The 'query' string is printed before the user
 *   is asked about the string.
 *   If resp is NULL, any single character is accepted and returned.
 *   If not-NULL, only characters in it are allowed (exceptions:  the
 *   quitchars are always allowed, and if it contains '#' then digits
 *   are allowed); if it includes an <esc>, anything beyond that won't
 *   be shown in the prompt to the user but will be acceptable as input.
 */
char nds_yn_function(const char *ques, const char *cstr, CHAR_P def)
{
  char buffer[INPUT_BUFFER_SIZE];

  char *choices;
  ANY_P header_id;
  ANY_P *ids;
  winid win;
  menu_item *sel = NULL;
  int ret;
  int yn = 0;
  int ynaq = 0;
  char *direction_keys = nds_get_direction_keys();

  if ((strstr(ques, "In what direction") != NULL) ||
      (strstr(ques, "in what direction") != NULL)) {
    /*
     * We're going to use nh_poskey to get a command from the user.  However,
     * we must handle clicks specially.  Unlike normal movement, you can't
     * just click anywhere to pick a direction.  Instead, the user will be
     * expected to click in one of the adjacent squares around the player,
     * and the click will then be translated into a movement character.
     */
    while (1) {
      int x, y, mod;
      int sym;

      nds_draw_prompt("Tap an adjacent square or press a direction key.");
      nds_flush(0);
      sym = nds_get_input(&x, &y, &mod);
      nds_clear_prompt();

      if (mod == CLICK_1) {
        if ((x == u.ux - 1) && (y == u.uy - 1)) {
          return direction_keys[DIR_UP_LEFT];
        } else if ((x == u.ux) && (y == u.uy - 1)) {
          return direction_keys[DIR_UP];
        } else if ((x == u.ux + 1) && (y == u.uy - 1)) {
          return direction_keys[DIR_UP_RIGHT];
        } else if ((x == u.ux - 1) && (y == u.uy)) {
          return direction_keys[DIR_LEFT];
        } else if ((x == u.ux) && (y == u.uy)) {
          return direction_keys[DIR_WAIT];
        } else if ((x == u.ux + 1) && (y == u.uy)) {
          return direction_keys[DIR_RIGHT];
        } else if ((x == u.ux - 1) && (y == u.uy + 1)) {
          return direction_keys[DIR_DOWN_LEFT];
        } else if ((x == u.ux) && (y == u.uy + 1)) {
          return direction_keys[DIR_DOWN];
        } else if ((x == u.ux + 1) && (y == u.uy + 1)) {
          return direction_keys[DIR_DOWN_RIGHT];
        }
      } else if (mod == CLICK_2) {
        if ((x == u.ux) && (y == u.uy)) {
          return '>';
        }
      } else {
        return sym;
      }
    }
  } else if (! iflags.cmdwindow) {
    return nds_prompt_char(ques, cstr, 0);
  } else if (strstr(ques, "Adjust letter to what") != NULL) {
    return nds_prompt_char(ques, cstr, 0);
  } else if (strstr(ques, "What command?") != NULL) {
    nds_cmd_t cmd;
    
    nds_draw_prompt("Select a command.");
    nds_flush(0);
    cmd = nds_cmd_loop(CMDLOOP_WHATDOES);
    nds_clear_prompt();

    return cmd.f_char;
  } else if (strstr(ques, "What do you look for?") != NULL) {
    return nds_prompt_char(ques, cstr, 0);
  } else if (strstr(ques, "adjust?") != NULL) {
    cstr = ynchars;
  }

  if ((index(ques, '[') == NULL) && (cstr == NULL)) {
    nds_draw_prompt(ques);
    return '*';
  }

  win = create_nhwindow(NHW_MENU);

  start_menu(win);
  
  if ((cstr != NULL) && 
      ((strcasecmp(cstr, ynchars) == 0) ||
       (strcasecmp(cstr, ynqchars) == 0) ||
       ((ynaq = strcasecmp(cstr, ynaqchars)) == 0))) {

    ids = (ANY_P *)malloc(sizeof(ANY_P) * 2);

    yn = 1;

    ids[0].a_int = 'y';
    ids[1].a_int = 'n';

    add_menu(win, NO_GLYPH, &(ids[0]), 0, 0, 0, "Yes", 0);
    add_menu(win, NO_GLYPH, &(ids[1]), 0, 0, 0, "No", 0);

    if (ynaq) {
      ids[2].a_int = 'a';

      add_menu(win, NO_GLYPH, &(ids[2]), 0, 0, 0, "All", 0);
    }
  } else if ((cstr != NULL) && (strcasecmp(cstr, "rl") == 0)) {

    ids = (ANY_P *)malloc(sizeof(ANY_P) * 2);

    ids[0].a_int = 'r';
    ids[1].a_int = 'l';

    add_menu(win, NO_GLYPH, &(ids[0]), 0, 0, 0, "Right Hand", 0);
    add_menu(win, NO_GLYPH, &(ids[1]), 0, 0, 0, "Left Hand", 0);
  } else {
    int i;
    char curclass = -1;

    choices = _nds_parse_choices(ques);

    ids = (ANY_P *)malloc(sizeof(ANY_P) * strlen(choices));
    header_id.a_int = 0;

    for (i = 0; i < strlen(choices); i++) {

      ids[i].a_int = choices[i];

      if (choices[i] == ' ') {
        add_menu(win, NO_GLYPH, &(header_id), 0, 0, 0, "Other", 0);
      } else if (choices[i] == '*') {
        add_menu(win, NO_GLYPH, &(ids[i]), 0, 0, 0, "Something from your inventory", 0);
      } else if ((choices[i] == '-') || (choices[i] == '.')) {
        add_menu(win, NO_GLYPH, &(ids[i]), 0, 0, 0, "Nothing/your finger", 0);
      } else if (choices[i] == '?') {
        continue;
      } else {
        int oclass;
        char oname[BUFSZ];

        if (choices[i] == '$') {
          oclass = COIN_CLASS;
          sprintf(oname, "%ld gold piece%s", u.ugold, plur(u.ugold));
        } else {
          struct obj *otmp = obj_for_let(choices[i]);

          oclass = otmp->oclass;
          strcpy(oname, doname(otmp));
        }

        if (oclass != curclass) {
          add_menu(win, NO_GLYPH, &(header_id), 0, 0, 0, let_to_name(oclass, FALSE), 0);

          curclass = oclass;
        } 

        add_menu(win, NO_GLYPH, &(ids[i]), 0, 0, 0, oname, 0);
      }
    }
  }

  end_menu(win, ques);

  int mode = ((cstr == NULL) || (index(cstr, '#') != NULL)) ? PICK_ONE_TYPE : PICK_ONE;
  int cnt = select_menu(win, mode, &sel);

  if (cnt <= 0) {
    ret = yn ? 'n' : '\033';
  } else if ((mode == PICK_ONE) || (sel->count < 0)) {
    ret = sel->item.a_int;
  } else if (mode == PICK_ONE_TYPE) {
    sprintf(buffer, "%d%c", sel->count, sel->item.a_int);

    nds_input_buffer_append(buffer + 1);
    ret = *buffer;
  }

  if (sel != NULL) {
    free(sel);
  }

  free(ids);

  destroy_nhwindow(win);

  return ret;
}
Ejemplo n.º 20
0
int
doname(nameblkp p, int reclevel, time_t *tval, int nowait)
{
int errstat;
int okdel1;
int didwork;
int len;
time_t td, td1, tdep, ptime, ptime1;
depblkp q;
depblkp qtemp, suffp, suffp1;
nameblkp p1, p2;
struct shblock *implcom, *explcom;
lineblkp lp;
lineblkp lp1, lp2;
char sourcename[100], prefix[100], temp[100], concsuff[20];
char *stem;
char *pnamep, *p1namep;
chainp allchain, qchain;
char qbuf[QBUFMAX], tgsbuf[QBUFMAX];
wildp wp;
int nproc1;
char *lastslash, *s;

if(p == 0)
	{
	*tval = 0;
	return 0;
	}

if(dbgflag)
	{
	printf("doname(%s,%d)\n",p->namep,reclevel);
	fflush(stdout);
	}

if(p->done > 0)
	{
	*tval = p->modtime;
	return (p->done == 3);
	}

errstat = 0;
tdep = 0;
implcom = 0;
explcom = 0;
ptime = exists(p->namep);
ptime1 = 0;
didwork = NO;
p->done = 1;	/* avoid infinite loops */
nproc1 = nproc;	/* current depth of process stack */

qchain = NULL;
allchain = NULL;

/* define values of Bradford's $$@ and $$/ macros */
for(s = lastslash = p->namep; *s; ++s)
	if(*s == '/')
		lastslash = s;
setvar("$@", p->namep, YES);
setvar("$/", lastslash, YES);


/* expand any names that have embedded metacharacters */

for(lp = p->linep ; lp ; lp = lp->nxtlineblock)
	for(q = lp->depp ; q ; q=qtemp )
		{
		qtemp = q->nxtdepblock;
		expand(q);
		}

/* make sure all dependents are up to date */

for(lp = p->linep ; lp ; lp = lp->nxtlineblock)
	{
	td = 0;
	for(q = lp->depp ; q ; q = q->nxtdepblock)
		if(q->depname)
			{
			errstat += doname(q->depname, reclevel+1, &td1, q->nowait);
			if(dbgflag)
				printf("TIME(%s)=%ld\n",q->depname->namep, td1);
			if(td1 > td)
				td = td1;
			if(ptime < td1)
				qchain = appendq(qchain, q->depname->namep);
			allchain = appendq(allchain, q->depname->namep);
			}
	if(p->septype == SOMEDEPS)
		{
		if(lp->shp)
		     if( ptime<td || (ptime==0 && td==0) || lp->depp==0)
			{
			okdel1 = okdel;
			okdel = NO;
			set3var("@", p->namep);
			setvar("?", mkqlist(qchain,qbuf), YES);
			setvar("^", mkqlist(allchain,tgsbuf), YES);
			qchain = NULL;
			if( !questflag )
				errstat += docom(lp->shp, nowait, nproc1);
			set3var("@", CHNULL);
			okdel = okdel1;
			ptime1 = prestime();
			didwork = YES;
			}
		}

	else	{
		if(lp->shp != 0)
			{
			if(explcom)
				fprintf(stderr, "Too many command lines for `%s'\n",
					p->namep);
			else	explcom = lp->shp;
			}

		if(td > tdep) tdep = td;
		}
	}



/* Look for implicit dependents, using suffix rules */

for(lp = sufflist ; lp ; lp = lp->nxtlineblock)
    for(suffp = lp->depp ; suffp ; suffp = suffp->nxtdepblock)
	{
	pnamep = suffp->depname->namep;
	if(suffix(p->namep , pnamep , prefix))
		{
		(void)srchdir(concat(prefix,"*",temp), NO, (depblkp) NULL);
		for(lp1 = sufflist ; lp1 ; lp1 = lp1->nxtlineblock)
		    for(suffp1=lp1->depp; suffp1 ; suffp1 = suffp1->nxtdepblock)
			{
			p1namep = suffp1->depname->namep;
			if( (p1=srchname(concat(p1namep, pnamep ,concsuff))) &&
			    (p2=srchname(concat(prefix, p1namep ,sourcename))) )
				{
				errstat += doname(p2, reclevel+1, &td, NO);
				if(ptime < td)
					qchain = appendq(qchain, p2->namep);
if(dbgflag) printf("TIME(%s)=%ld\n", p2->namep, td);
				if(td > tdep) tdep = td;
				set3var("*", prefix);
				set3var("<", copys(sourcename));
				for(lp2=p1->linep ; lp2 ; lp2 = lp2->nxtlineblock)
					if(implcom = lp2->shp) break;
				goto endloop;
				}
			}
		}
	}

/* Look for implicit dependents, using pattern matching rules */

len = strlen(p->namep);
for(wp = firstwild ; wp ; wp = wp->next)
	if(stem = wildmatch(wp, p->namep, len) )
		{
		lp = wp->linep;
		for(q = lp->depp; q; q = q->nxtdepblock)
			{
			if(dbgflag>1 && q->depname)
				fprintf(stderr,"check dep of %s on %s\n", p->namep,
					wildsub(q->depname->namep,stem));
			if(q->depname &&
				! chkname(wildsub(q->depname->namep,stem)))
					break;
			}

		if(q)	/* some name not found, go to next line */
			continue;

		for(q = lp->depp; q; q = q->nxtdepblock)
			{
			nameblkp tamep;
			if(q->depname == NULL)
				continue;
			tamep = srchname( wildsub(q->depname->namep,stem));
/*TEMP fprintf(stderr,"check dep %s on %s =>%s\n",p->namep,q->depname->namep,tamep->namep);*/
/*TEMP*/if(dbgflag) printf("%s depends on %s. stem=%s\n", p->namep,tamep->namep, stem);
			errstat += doname(tamep, reclevel+1, &td, q->nowait);
			if(ptime < td)
				qchain = appendq(qchain, tamep->namep);
			allchain = appendq(allchain, tamep->namep);
			if(dbgflag) printf("TIME(%s)=%ld\n", tamep->namep, td);
			if(td > tdep)
				tdep = td;
			set3var("<", copys(tamep->namep) );
			}
		set3var("*", stem);
		setvar("%", stem, YES);
		implcom = lp->shp;
		goto endloop;
		}

endloop:


if(errstat==0 && (ptime<tdep || (ptime==0 && tdep==0) ) )
	{
	ptime = (tdep>0 ? tdep : prestime() );
	set3var("@", p->namep);
	setvar("?", mkqlist(qchain,qbuf), YES);
	setvar("^", mkqlist(allchain,tgsbuf), YES);
	if(explcom)
		errstat += docom(explcom, nowait, nproc1);
	else if(implcom)
		errstat += docom(implcom, nowait, nproc1);
	else if(p->septype == 0)
		if(p1=srchname(".DEFAULT"))
			{
			set3var("<", p->namep);
			for(lp2 = p1->linep ; lp2 ; lp2 = lp2->nxtlineblock)
				if(implcom = lp2->shp)
					{
					errstat += docom(implcom, nowait,nproc1);
					break;
					}
			}
		else if(keepgoing)
			{
			printf("Don't know how to make %s\n", p->namep);
			++errstat;
			}
		else
			fatal1(" Don't know how to make %s", p->namep);

	set3var("@", CHNULL);
	if(noexflag || nowait || (ptime = exists(p->namep)) == 0 )
		ptime = prestime();
	}

else if(errstat!=0 && reclevel==0)
	printf("`%s' not remade because of errors\n", p->namep);

else if(!questflag && reclevel==0  &&  didwork==NO)
	printf("`%s' is up to date.\n", p->namep);

if(questflag && reclevel==0)
	exit(ndocoms>0 ? -1 : 0);

p->done = (errstat ? 3 : 2);
if(ptime1 > ptime)
	ptime = ptime1;
p->modtime = ptime;
*tval = ptime;
return errstat;
}
Ejemplo n.º 21
0
/* u.dx and u.dy must be set */
bool
attack(struct monst *mtmp)
{
	schar tmp;
	boolean malive = TRUE;
	struct permonst *mdat;

	mdat = mtmp->data;
	u_wipe_engr(3);   /* andrew@orca: prevent unlimited pick-axe attacks */

	if (mdat->mlet == 'L' && !mtmp->mfroz && !mtmp->msleep &&
	    !mtmp->mconf && mtmp->mcansee && !rn2(7) &&
	    (m_move(mtmp, 0) == 2 /* he died */ || /* he moved: */
	     mtmp->mx != u.ux + u.dx || mtmp->my != u.uy + u.dy))
		return (FALSE);

	if (mtmp->mimic) {
		if (!u.ustuck && !mtmp->mflee)
			u.ustuck = mtmp;
		switch (levl[u.ux + u.dx][u.uy + u.dy].scrsym) {
		case '+':
			pline("The door actually was a Mimic.");
			break;
		case '$':
			pline("The chest was a Mimic!");
			break;
		default:
			pline("Wait! That's a Mimic!");
		}
		wakeup(mtmp);	/* clears mtmp->mimic */
		return (TRUE);
	}

	wakeup(mtmp);

	if (mtmp->mhide && mtmp->mundetected) {
		struct obj *obj;

		mtmp->mundetected = 0;
		if ((obj = o_at(mtmp->mx, mtmp->my)) && !Blind)
			pline("Wait! There's a %s hiding under %s!",
			      mdat->mname, doname(obj));
		return (TRUE);
	}

	tmp = u.uluck + u.ulevel + mdat->ac + abon();
	if (uwep) {
		if (uwep->olet == WEAPON_SYM || uwep->otyp == PICK_AXE)
			tmp += uwep->spe;
		if (uwep->otyp == TWO_HANDED_SWORD)
			tmp -= 1;
		else if (uwep->otyp == DAGGER)
			tmp += 2;
		else if (uwep->otyp == CRYSKNIFE)
			tmp += 3;
		else if (uwep->otyp == SPEAR &&
			 strchr("XDne", mdat->mlet))
			tmp += 2;
	}
	if (mtmp->msleep) {
		mtmp->msleep = 0;
		tmp += 2;
	}
	if (mtmp->mfroz) {
		tmp += 4;
		if (!rn2(10))
			mtmp->mfroz = 0;
	}
	if (mtmp->mflee)
		tmp += 2;
	if (u.utrap)
		tmp -= 3;

	/* with a lot of luggage, your agility diminishes */
	tmp -= (inv_weight() + 40) / 20;

	if (tmp <= rnd(20) && !u.uswallow) {
		if (Blind)
			pline("You miss it.");
		else
			pline("You miss %s.", monnam(mtmp));
	} else {
		/* we hit the monster; be careful: it might die! */

		if ((malive = hmon(mtmp, uwep, 0)) == TRUE) {
			/* monster still alive */
			if (!rn2(25) && mtmp->mhp < mtmp->mhpmax / 2) {
				mtmp->mflee = 1;
				if (!rn2(3))
					mtmp->mfleetim = rnd(100);
				if (u.ustuck == mtmp && !u.uswallow)
					u.ustuck = 0;
			}
#ifndef NOWORM
			if (mtmp->wormno)
				cutworm(mtmp, u.ux + u.dx, u.uy + u.dy,
					uwep ? uwep->otyp : 0);
#endif /* NOWORM */
		}
		if (mdat->mlet == 'a') {
			if (rn2(2)) {
				pline("You are splashed by the blob's acid!");
				losehp_m(rnd(6), mtmp);
				if (!rn2(30))
					corrode_armor();
			}
			if (!rn2(6))
				corrode_weapon();
		}
	}
	if (malive && mdat->mlet == 'E' && canseemon(mtmp)
	    && !mtmp->mcan && rn2(3)) {
		if (mtmp->mcansee) {
			pline("You are frozen by the floating eye's gaze!");
			nomul((u.ulevel > 6 || rn2(4)) ? rn1(20, -21) : -200);
		} else {
			pline("The blinded floating eye cannot defend itself.");
			if (!rn2(500))
				if ((int)u.uluck > LUCKMIN)
					u.uluck--;
		}
	}
	return (TRUE);
}
Ejemplo n.º 22
0
int doeat(void)
{
    struct obj *otmp;
    int tmp;

    // Is there some food (probably a heavy corpse) here on the ground?
    if (!Levitation)
	for (otmp = _level->objects; otmp; otmp = otmp->nobj) {
	    if (otmp->ox == _u.ux && otmp->oy == _u.uy && otmp->olet == FOOD_SYM) {
		pline("There %s %s here; eat %s? [ny] ", (otmp->quan == 1) ? "is" : "are", doname(otmp), (otmp->quan == 1) ? "it" : "one");
		if (readchar() == 'y') {
		    if (otmp->quan != 1)
			(void) splitobj(otmp, 1);
		    freeobj(otmp);
		    otmp = addinv(otmp);
		    addtobill(otmp);
		    goto gotit;
		}
	    }
	}
    otmp = getobj("%", "eat");
    if (!otmp)
	return 0;
  gotit:
    if (otmp->otyp == TIN) {
	if (uwep) {
	    switch (uwep->otyp) {
		case CAN_OPENER:
		    tmp = 1;
		    break;
		case DAGGER:
		    tmp = 3;
		    break;
		case PICK_AXE:
		case AXE:
		    tmp = 6;
		    break;
		default:
		    goto no_opener;
	    }
	    pline("Using your %s you try to open the tin.", aobjnam(uwep, NULL));
	} else {
	  no_opener:
	    pline("It is not so easy to open this tin.");
	    if (Glib) {
		pline("The tin slips out of your hands.");
		if (otmp->quan > 1) {
		    struct obj *obj;

		    obj = splitobj(otmp, 1);
		    if (otmp == uwep)
			setuwep(obj);
		}
		dropx(otmp);
		return 1;
	    }
	    tmp = 10 + rn2(1 + 500 / ((int) (_u.ulevel + _u.ustr)));
	}
	tin.reqtime = tmp;
	tin.usedtime = 0;
	tin.tin = otmp;
	occupation = opentin;
	occtxt = "opening the tin";
	return 1;
    }
    const struct objclass* ftmp = &c_Objects[otmp->otyp];
    multi = -ftmp->oc_delay;
    if (otmp->otyp >= CORPSE && eatcorpse(otmp))
	goto eatx;
    if (!rn2(7) && otmp->otyp != FORTUNE_COOKIE) {
	pline("Blecch!  Rotten food!");
	if (!rn2(4)) {
	    pline("You feel rather light headed.");
	    Confusion += d(2, 4);
	} else if (!rn2(4) && !Blind) {
	    pline("Everything suddenly goes dark.");
	    Blind = d(2, 10);
	    seeoff(0);
	} else if (!rn2(3)) {
	    if (Blind)
		pline("The world spins and you slap against the floor.");
	    else
		pline("The world spins and goes dark.");
	    nomul(-rnd(10));
	    nomovemsg = "You are conscious again.";
	}
	lesshungry(ftmp->nutrition / 4);
    } else {
	if (_u.uhunger >= 1500) {
	    pline("You choke over your food.");
	    pline("You die...");
	    killer = ftmp->oc_name;
	    done("choked");
	}
	switch (otmp->otyp) {
	    case FOOD_RATION:
		if (_u.uhunger <= 200)
		    pline("That food really hit the spot!");
		else if (_u.uhunger <= 700)
		    pline("That satiated your stomach!");
		else {
		    pline("You're having a hard time getting all that food down.");
		    multi -= 2;
		}
		lesshungry(ftmp->nutrition);
		if (multi < 0)
		    nomovemsg = "You finished your meal.";
		break;
	    case TRIPE_RATION:
		pline("Yak - dog food!");
		more_experienced(1, 0);
		_wflags.botl = 1;
		if (rn2(2)) {
		    pline("You vomit.");
		    morehungry(20);
		    if (Sick) {
			Sick = 0;	// David Neves
			pline("What a relief!");
		    }
		} else
		    lesshungry(ftmp->nutrition);
		break;
	    default:
		if (otmp->otyp >= CORPSE)
		    pline("That %s tasted terrible!", ftmp->oc_name);
		else
		    pline("That %s was delicious!", ftmp->oc_name);
		lesshungry(ftmp->nutrition);
		if (otmp->otyp == DEAD_LIZARD && (Confusion > 2))
		    Confusion = 2;
		else if (otmp->otyp == FORTUNE_COOKIE) {
		    if (Blind) {
			pline("This cookie has a scrap of paper inside!");
			pline("What a pity, that you cannot read it!");
		    } else
			print_rumor();
		} else if (otmp->otyp == LUMP_OF_ROYAL_JELLY) {
		    // This stuff seems to be VERY healthy!
		    if (_u.ustrmax < 118)
			++_u.ustrmax;
		    if (_u.ustr < _u.ustrmax)
			++_u.ustr;
		    _u.uhp += rnd(20);
		    if (_u.uhp > _u.uhpmax) {
			if (!rn2(17))
			    ++_u.uhpmax;
			_u.uhp = _u.uhpmax;
		    }
		    heal_legs();
		}
		break;
	}
    }
  eatx:
    if (multi < 0 && !nomovemsg) {
	static char msgbuf[BUFSZ];
	sprintf(msgbuf, "You finished eating the %s.", ftmp->oc_name);
	nomovemsg = msgbuf;
    }
    useup(otmp);
    return 1;
}
Ejemplo n.º 23
0
/* Be careful not to call panic from here! */
void
done(const char *st1)
{

#ifdef WIZARD
	if(wizard && *st1 == 'd'){
		u.uswldtim = 0;
		if(u.uhpmax < 0) u.uhpmax = 100;	/* arbitrary */
		u.uhp = u.uhpmax;
		pline("For some reason you are still alive.");
		flags.move = 0;
		if(multi > 0) multi = 0; else multi = -1;
		flags.botl = 1;
		return;
	}
#endif /* WIZARD */
	signal(SIGINT, done_intr);
	signal(SIGQUIT, done_intr);
	signal(SIGHUP, done_hangup);
	if(*st1 == 'q' && u.uhp < 1){
		st1 = "died";
		killer = "quit while already on Charon's boat";
	}
	if(*st1 == 's') killer = "starvation"; else
	if(*st1 == 'd' && st1[1] == 'r') killer = "drowning"; else
	if(*st1 == 'p') killer = "panic"; else
	if(*st1 == 't') killer = "trickery"; else
	if(!index("bcd", *st1)) killer = st1;
	paybill();
	clearlocks();
	if(flags.toplin == 1) more();
	if(index("bcds", *st1)){
#ifdef WIZARD
	    if(!wizard)
#endif /* WIZARD */
		savebones();
		if(!flags.notombstone)
			outrip();
	}
	if(*st1 == 'c') killer = st1;		/* after outrip() */
	settty(NULL);				/* does a clear_screen() */
	if(!done_stopprint)
		printf("Goodbye %s %s...\n\n", pl_character, plname);
	{ long int tmp;
	  tmp = u.ugold - u.ugold0;
	  if(tmp < 0)
		tmp = 0;
	  if(*st1 == 'd' || *st1 == 'b')
		tmp -= tmp/10;
	  u.urexp += tmp;
	  u.urexp += 50 * maxdlevel;
	  if(maxdlevel > 20)
		u.urexp += 1000*((maxdlevel > 30) ? 10 : maxdlevel - 20);
	}
	if(*st1 == 'e') {
		struct monst *mtmp;
		struct obj *otmp;
		int i;
		unsigned worthlessct = 0;
		boolean has_amulet = FALSE;

		killer = st1;
		keepdogs();
		mtmp = mydogs;
		if(mtmp) {
			if(!done_stopprint) printf("You");
			while(mtmp) {
				if(!done_stopprint)
					printf(" and %s", monnam(mtmp));
				if(mtmp->mtame)
					u.urexp += mtmp->mhp;
				mtmp = mtmp->nmon;
			}
			if(!done_stopprint)
		    printf("\nescaped from the dungeon with %ld points,\n",
			u.urexp);
		} else
		if(!done_stopprint)
		  printf("You escaped from the dungeon with %ld points,\n",
		    u.urexp);
		for(otmp = invent; otmp; otmp = otmp->nobj) {
			if(otmp->olet == GEM_SYM){
				i = otmp->quan*objects[otmp->otyp].g_val;
				if(i == 0) {
					worthlessct += otmp->quan;
					continue;
				}
				u.urexp += i;
				if(!done_stopprint)
				  printf("\t%s (worth %d Zorkmids),\n",
				    doname(otmp), i);
			} else if(otmp->olet == AMULET_SYM) {
				i = (otmp->spe < 0) ? 2 : 5000;
				u.urexp += i;
				if(!done_stopprint)
				  printf("\t%s (worth %d Zorkmids),\n",
				    doname(otmp), i);
				if(otmp->spe >= 0) {
					has_amulet = TRUE;
					killer = "escaped (with amulet)";
				}
			}
		}
		if(worthlessct) if(!done_stopprint)
		  printf("\t%u worthless piece%s of coloured glass,\n",
		  worthlessct, plur(worthlessct));
		if(has_amulet) u.urexp *= 2;
	} else
		if(!done_stopprint)
		  printf("You %s on dungeon level %d with %ld points,\n",
		    st1, dlevel, u.urexp);
	if(!done_stopprint)
	  printf("and %ld piece%s of gold, after %ld move%s.\n",
	    u.ugold, plur(u.ugold), moves, plur(moves));
	if(!done_stopprint)
  printf("You were level %u with a maximum of %d hit points when you %s.\n",
	    u.ulevel, u.uhpmax, st1);
	if(*st1 == 'e' && !done_stopprint){
		getret();	/* all those pieces of coloured glass ... */
		cls();
	}
#ifdef WIZARD
	if(!wizard)
#endif /* WIZARD */
		topten();
	if(done_stopprint) printf("\n\n");
	exit(0);
}
Ejemplo n.º 24
0
void subfrombill(struct obj *obj)
{
  Long ltmp;
  Short tmp;
  obj_t *otmp;
  bill_t *bp;
  eshk_t *eshk = (shopkeeper ? ESHK(shopkeeper) : NULL);
  if (!inshop() ||
      (you.ux == eshk->shk.x && you.uy == eshk->shk.y) ||
      (you.ux == eshk->shd.x && you.uy == eshk->shd.y))
    return;
  if ((bp = onbill(obj)) != 0) {
    obj->bitflags &= ~O_IS_UNPAID;
    if (bp->bquantity > obj->quantity) {
      otmp = (obj_t *) md_malloc(sizeof(obj_t));// newobj(0);
      *otmp = *obj;
      bp->bo_id = otmp->o_id = flags.ident++;
      otmp->quantity = (bp->bquantity -= obj->quantity);
      otmp->owt = 0;	/* superfluous */
      do_name(otmp, NULL); // otmp->onamelth = 0; // Undo name (if any)
      bp->useup = true;
      otmp->nobj = billobjs;
      billobjs = otmp;
      return;
    }
    eshk->billct--;
    *bp = bill[eshk->billct];
    return;
  }
  if (obj->bitflags & O_IS_UNPAID) {
    StrPrintF(ScratchBuffer, "%s didn't notice.", Monnam(shopkeeper));
    message(ScratchBuffer);
    obj->bitflags &= ~O_IS_UNPAID;
    return;		/* %% */
  }
  /* he dropped something of his own - probably wants to sell it */
  if ((shopkeeper->bitflags & (M_IS_ASLEEP | M_IS_FROZEN)) ||
      inroom(shopkeeper->mx,shopkeeper->my) != eshk->shoproom)
    return;
  if (eshk->billct == BILLSZ ||
      ((tmp = shtypes[rooms[eshk->shoproom].rtype-8]) && tmp != obj->olet) ||
      StrChr("_0", obj->olet)) {
    StrPrintF(ScratchBuffer, "%s seems not interested.", Monnam(shopkeeper));
    message(ScratchBuffer);
    return;
  }
  ltmp = getprice(obj) * obj->quantity;
  if (ANGRY(shopkeeper)) {
    ltmp /= 3;
    shopkeeper->bitflags |= M_IS_PEACEFUL; // NOTANGRY(shopkeeper) = 1;
  } else   ltmp /= 2;
  if (eshk->robbed) {
    if ((eshk->robbed -= ltmp) < 0)
      eshk->robbed = 0;
    message("Thank you for your contribution to restock this recently plundered shop.");
    return;
  }
  if (ltmp > shopkeeper->mgold)
    ltmp = shopkeeper->mgold;
  pay(-ltmp, shopkeeper);
  if (!ltmp)
    StrPrintF(ScratchBuffer,
	      "%s gladly accepts %s but cannot pay you at present.",
	      Monnam(shopkeeper), doname(obj));
  else
    StrPrintF(ScratchBuffer,
	      "You sold %s and got %ld gold piece%s",
	      doname(obj), ltmp, (ltmp == 1 ? "." : "s."));
  message(ScratchBuffer);
}
Ejemplo n.º 25
0
/* Check all object lists for consistency. */
void
obj_sanity_check(void)
{
    int x, y;
    struct obj *obj;
    struct monst *mon;
    const char *mesg;
    char obj_address[20], mon_address[20];  /* room for formatted pointers */

    mesg = "fobj sanity";
    for (obj = fobj; obj; obj = obj->nobj) {
        if (obj->where != OBJ_FLOOR) {
            pline("%s obj %s %s@(%d,%d): %s\n", mesg,
                  fmt_ptr((genericptr_t)obj, obj_address),
                  where_name(obj->where),
                  obj->ox, obj->oy, doname(obj));
        }
        check_contained(obj, mesg);
    }

    mesg = "location sanity";
    for (x = 0; x < COLNO; x++)
        for (y = 0; y < ROWNO; y++)
            for (obj = level.objects[x][y]; obj; obj = obj->nexthere)
                if (obj->where != OBJ_FLOOR) {
                    pline("%s obj %s %s@(%d,%d): %s\n", mesg,
                          fmt_ptr((genericptr_t)obj, obj_address),
                          where_name(obj->where),
                          obj->ox, obj->oy, doname(obj));
                }

    mesg = "invent sanity";
    for (obj = invent; obj; obj = obj->nobj) {
        if (obj->where != OBJ_INVENT) {
            pline("%s obj %s %s: %s\n", mesg,
                  fmt_ptr((genericptr_t)obj, obj_address),
                  where_name(obj->where), doname(obj));
        }
        check_contained(obj, mesg);
    }

    mesg = "migrating sanity";
    for (obj = migrating_objs; obj; obj = obj->nobj) {
        if (obj->where != OBJ_MIGRATING) {
            pline("%s obj %s %s: %s\n", mesg,
                  fmt_ptr((genericptr_t)obj, obj_address),
                  where_name(obj->where), doname(obj));
        }
        check_contained(obj, mesg);
    }

    mesg = "buried sanity";
    for (obj = level.buriedobjlist; obj; obj = obj->nobj) {
        if (obj->where != OBJ_BURIED) {
            pline("%s obj %s %s: %s\n", mesg,
                  fmt_ptr((genericptr_t)obj, obj_address),
                  where_name(obj->where), doname(obj));
        }
        check_contained(obj, mesg);
    }

    mesg = "bill sanity";
    for (obj = billobjs; obj; obj = obj->nobj) {
        if (obj->where != OBJ_ONBILL) {
            pline("%s obj %s %s: %s\n", mesg,
                  fmt_ptr((genericptr_t)obj, obj_address),
                  where_name(obj->where), doname(obj));
        }
        /* shouldn't be a full container on the bill */
        if (obj->cobj) {
            pline("%s obj %s contains %s! %s\n", mesg,
                  fmt_ptr((genericptr_t)obj, obj_address),
                  something, doname(obj));
        }
    }

    mesg = "minvent sanity";
    for (mon = fmon; mon; mon = mon->nmon)
        for (obj = mon->minvent; obj; obj = obj->nobj) {
            if (obj->where != OBJ_MINVENT) {
                pline("%s obj %s %s: %s\n", mesg,
                      fmt_ptr((genericptr_t)obj, obj_address),
                      where_name(obj->where), doname(obj));
            }
            if (obj->ocarry != mon) {
                pline("%s obj %s (%s) not held by mon %s (%s)\n", mesg,
                      fmt_ptr((genericptr_t)obj, obj_address),
                      doname(obj),
                      fmt_ptr((genericptr_t)mon, mon_address),
                      mon_nam(mon));
            }
            check_contained(obj, mesg);
        }
}
Ejemplo n.º 26
0
static void
off_msg(struct obj *otmp)
{
	pline("You were wearing %s.", doname(otmp));
}
Ejemplo n.º 27
0
void
subfrombill(struct obj *obj)
{
	long ltmp;
	int tmp;
	struct obj *otmp;
	struct bill_x *bp;

	if (!inshop() ||
	    (u.ux == ESHK(shopkeeper)->shk.x && u.uy == ESHK(shopkeeper)->shk.y) ||
	    (u.ux == ESHK(shopkeeper)->shd.x && u.uy == ESHK(shopkeeper)->shd.y))
		return;
	if ((bp = onbill(obj)) != NULL) {
		obj->unpaid = 0;
		if (bp->bquan > obj->quan) {
			otmp = newobj(0);
			*otmp = *obj;
			bp->bo_id = otmp->o_id = flags.ident++;
			otmp->quan = (bp->bquan -= obj->quan);
			otmp->owt = 0;	/* superfluous */
			otmp->onamelth = 0;
			bp->useup = 1;
			otmp->nobj = billobjs;
			billobjs = otmp;
			return;
		}
		ESHK(shopkeeper)->billct--;
		*bp = bill[ESHK(shopkeeper)->billct];
		return;
	}
	if (obj->unpaid) {
		pline("%s didn't notice.", Monnam(shopkeeper));
		obj->unpaid = 0;
		return;		/* %% */
	}
	/* he dropped something of his own - probably wants to sell it */
	if (shopkeeper->msleep || shopkeeper->mfroz ||
	    inroom(shopkeeper->mx, shopkeeper->my) != ESHK(shopkeeper)->shoproom)
		return;
	if (ESHK(shopkeeper)->billct == BILLSZ ||
	    ((tmp = shtypes[rooms[ESHK(shopkeeper)->shoproom].rtype - 8]) &&
	     tmp != obj->olet) || strchr("_0", obj->olet)) {
		pline("%s seems not interested.", Monnam(shopkeeper));
		return;
	}
	ltmp = getprice(obj) * obj->quan;
	if (ANGRY(shopkeeper)) {
		ltmp /= 3;
		NOTANGRY(shopkeeper) = 1;
	} else
		ltmp /= 2;
	if (ESHK(shopkeeper)->robbed) {
		if ((ESHK(shopkeeper)->robbed -= ltmp) < 0)
			ESHK(shopkeeper)->robbed = 0;
		pline("Thank you for your contribution to restock this recently plundered shop.");
		return;
	}
	if (ltmp > shopkeeper->mgold)
		ltmp = shopkeeper->mgold;
	pay(-ltmp, shopkeeper);
	if (!ltmp)
		pline("%s gladly accepts %s but cannot pay you at present.",
		      Monnam(shopkeeper), doname(obj));
	else
		pline("You sold %s and got %ld gold piece%s.", doname(obj), ltmp,
		      plur(ltmp));
}
Ejemplo n.º 28
0
// returns 1 when something was stolen
// (or at least, when N should flee now)
// avoid stealing the object stealoid
int steal(struct monst *mtmp)
{
    struct obj *otmp;
    int tmp;
    int named = 0;

    if (!invent) {
	if (Blind)
	    pline("Somebody tries to rob you, but finds nothing to steal.");
	else
	    pline("%s tries to rob you, but she finds nothing to steal!", Monnam(mtmp));
	return 1;	       // let her flee
    }
    tmp = 0;
    for (otmp = invent; otmp; otmp = otmp->nobj)
	if (otmp != uarm2)
	    tmp += ((otmp->owornmask & (W_ARMOR | W_RING)) ? 5 : 1);
    tmp = rn2(tmp);
    for (otmp = invent; otmp; otmp = otmp->nobj)
	if (otmp != uarm2)
	    if ((tmp -= ((otmp->owornmask & (W_ARMOR | W_RING)) ? 5 : 1))
		< 0)
		break;
    if (!otmp) {
	impossible("Steal fails!");
	return 0;
    }
    if (otmp->o_id == stealoid)
	return 0;
    if ((otmp->owornmask & (W_ARMOR | W_RING))) {
	switch (otmp->olet) {
	    case RING_SYM:
		ringoff(otmp);
		break;
	    case ARMOR_SYM:
		if (multi < 0 || otmp == uarms) {
		    setworn((struct obj *) 0, otmp->owornmask & W_ARMOR);
		    break;
		}
		{
		    int curssv = otmp->cursed;
		    otmp->cursed = 0;
		    stop_occupation();
		    pline("%s seduces you and %s off your %s.", Amonnam(mtmp, Blind ? "gentle" : "beautiful"), otmp->cursed ? "helps you to take" : "you start taking", (otmp == uarmg) ? "gloves" : (otmp == uarmh) ? "helmet" : "armor");
		    named++;
		    (void) armoroff(otmp);
		    otmp->cursed = curssv;
		    if (multi < 0) {
			// multi = 0;
			// nomovemsg = 0;
			// afternmv = 0;
			stealoid = otmp->o_id;
			stealmid = mtmp->m_id;
			afternmv = stealarm;
			return 0;
		    }
		    break;
		}
	    default:
		impossible("Tried to steal a strange worn thing.");
	}
    } else if (otmp == uwep)
	setuwep((struct obj *) 0);
    if (otmp->olet == CHAIN_SYM) {
	impossible("How come you are carrying that chain?");
    }
    if (Punished && otmp == uball) {
	Punished = 0;
	freeobj(uchain);
	free((char *) uchain);
	uchain = (struct obj *) 0;
	uball->spe = 0;
	uball = (struct obj *) 0;	// superfluous
    }
    freeinv(otmp);
    pline("%s stole %s.", named ? "She" : Monnam(mtmp), doname(otmp));
    mpickobj(mtmp, otmp);
    return multi < 0 ? 0 : 1;
}
Ejemplo n.º 29
0
static int doit(char *q,char qtype[2])
{
  unsigned int bpos;
  unsigned int anpos;
  unsigned int aupos;
  unsigned int arpos;
  char *control;
  char *wild;
  int flaggavesoa;
  int flagfound;
  int r;
  int flagns;
  int flagauthoritative;
  char x[20];
  uint16 u16;
  char addr[8][4];
  int addrnum;
  uint32 addrttl;
  int i;

  anpos = response_len;

  control = q;
  for (;;) {
    flagns = 0;
    flagauthoritative = 0;
    cdb_findstart(&c);
    while (r = find(control,0)) {
      if (r == -1) return 0;
      if (byte_equal(type,2,DNS_T_SOA)) flagauthoritative = 1;
      if (byte_equal(type,2,DNS_T_NS)) flagns = 1;
    }
    if (flagns) break;
    if (!*control) return 0; /* q is not within our bailiwick */
    control += *control;
    control += 1;
  }

  if (!flagauthoritative) {
    response[2] &= ~4;
    goto AUTHORITY; /* q is in a child zone */
  }


  flaggavesoa = 0;
  flagfound = 0;
  wild = q;

  for (;;) {
    addrnum = 0;
    addrttl = 0;
    cdb_findstart(&c);
    while (r = find(wild,wild != q)) {
      if (r == -1) return 0;
      flagfound = 1;
      if (flaggavesoa && byte_equal(type,2,DNS_T_SOA)) continue;
      if (byte_diff(type,2,qtype) && byte_diff(qtype,2,DNS_T_ANY) && byte_diff(type,2,DNS_T_CNAME)) continue;
      if (byte_equal(type,2,DNS_T_A) && (dlen - dpos == 4)) {
	addrttl = ttl;
	i = dns_random(addrnum + 1);
	if (i < 8) {
	  if ((i < addrnum) && (addrnum < 8))
	    byte_copy(addr[addrnum],4,addr[i]);
	  byte_copy(addr[i],4,data + dpos);
	}
	if (addrnum < 1000000) ++addrnum;
	continue;
      }
      if (!response_rstart(q,type,ttl)) return 0;
      if (byte_equal(type,2,DNS_T_NS) || byte_equal(type,2,DNS_T_CNAME) || byte_equal(type,2,DNS_T_PTR)) {
	if (!doname()) return 0;
      }
      else if (byte_equal(type,2,DNS_T_MX)) {
	if (!dobytes(2)) return 0;
	if (!doname()) return 0;
      }
      else if (byte_equal(type,2,DNS_T_SOA)) {
	if (!doname()) return 0;
	if (!doname()) return 0;
	if (!dobytes(20)) return 0;
        flaggavesoa = 1;
      }
      else
        if (!response_addbytes(data + dpos,dlen - dpos)) return 0;
      response_rfinish(RESPONSE_ANSWER);
    }
    for (i = 0;i < addrnum;++i)
      if (i < 8) {
	if (!response_rstart(q,DNS_T_A,addrttl)) return 0;
	if (!response_addbytes(addr[i],4)) return 0;
	response_rfinish(RESPONSE_ANSWER);
      }

    if (flagfound) break;
    if (wild == control) break;
    if (!*wild) break; /* impossible */
    wild += *wild;
    wild += 1;
  }

  if (!flagfound)
    response_nxdomain();


  AUTHORITY:
  aupos = response_len;

  if (flagauthoritative && (aupos == anpos)) {
    cdb_findstart(&c);
    while (r = find(control,0)) {
      if (r == -1) return 0;
      if (byte_equal(type,2,DNS_T_SOA)) {
        if (!response_rstart(control,DNS_T_SOA,ttl)) return 0;
	if (!doname()) return 0;
	if (!doname()) return 0;
	if (!dobytes(20)) return 0;
        response_rfinish(RESPONSE_AUTHORITY);
        break;
      }
    }
  }
  else
    if (want(control,DNS_T_NS)) {
      cdb_findstart(&c);
      while (r = find(control,0)) {
        if (r == -1) return 0;
        if (byte_equal(type,2,DNS_T_NS)) {
          if (!response_rstart(control,DNS_T_NS,ttl)) return 0;
	  if (!doname()) return 0;
          response_rfinish(RESPONSE_AUTHORITY);
        }
      }
    }

  arpos = response_len;

  bpos = anpos;
  while (bpos < arpos) {
    bpos = dns_packet_skipname(response,arpos,bpos); if (!bpos) return 0;
    bpos = dns_packet_copy(response,arpos,bpos,x,10); if (!bpos) return 0;
    if (byte_equal(x,2,DNS_T_NS) || byte_equal(x,2,DNS_T_MX)) {
      if (byte_equal(x,2,DNS_T_NS)) {
        if (!dns_packet_getname(response,arpos,bpos,&d1)) return 0;
      }
      else
        if (!dns_packet_getname(response,arpos,bpos + 2,&d1)) return 0;
      case_lowerb(d1,dns_domain_length(d1));
      if (want(d1,DNS_T_A)) {
	cdb_findstart(&c);
	while (r = find(d1,0)) {
          if (r == -1) return 0;
	  if (byte_equal(type,2,DNS_T_A)) {
            if (!response_rstart(d1,DNS_T_A,ttl)) return 0;
	    if (!dobytes(4)) return 0;
            response_rfinish(RESPONSE_ADDITIONAL);
	  }
        }
      }
    }
    uint16_unpack_big(x + 8,&u16);
    bpos += u16;
  }

  if (flagauthoritative && (response_len > 512)) {
    byte_zero(response + RESPONSE_ADDITIONAL,2);
    response_len = arpos;
    if (response_len > 512) {
      byte_zero(response + RESPONSE_AUTHORITY,2);
      response_len = aupos;
    }
  }

  return 1;
}
Ejemplo n.º 30
0
int
doinvbill(int mode)	/* 0: deliver count 1: paged */
{
	struct bill_x *bp;
	struct obj *obj;
	long totused, thisused;
	char buf[BUFSZ];

	if (mode == 0) {
		int cnt = 0;

		if (shopkeeper)
			for (bp = bill; bp - bill < ESHK(shopkeeper)->billct; bp++)
				if (bp->useup ||
				    ((obj = bp_to_obj(bp)) && obj->quan < bp->bquan))
					cnt++;
		return (cnt);
	}

	if (!shopkeeper) {
		impossible("doinvbill: no shopkeeper?");
		return (0);
	}

	set_pager(0);
	if (page_line("Unpaid articles already used up:") || page_line(""))
		goto quit;

	totused = 0;
	for (bp = bill; bp - bill < ESHK(shopkeeper)->billct; bp++) {
		obj = bp_to_obj(bp);
		if (!obj) {
			impossible("Bad shopkeeper administration.");
			goto quit;
		}
		if (bp->useup || bp->bquan > obj->quan) {
			int cnt, oquan, uquan;

			oquan = obj->quan;
			uquan = (bp->useup ? bp->bquan : bp->bquan - oquan);
			thisused = bp->price * uquan;
			totused += thisused;
			obj->quan = uquan;	/* cheat doname */
			sprintf(buf, "x -  %s", doname(obj));
			obj->quan = oquan;	/* restore value */
			for (cnt = 0; buf[cnt]; cnt++)
				; /* nothing */
			while (cnt < 50)
				buf[cnt++] = ' ';
			sprintf(&buf[cnt], " %5ld zorkmids", thisused);
			if (page_line(buf))
				goto quit;
		}
	}
	sprintf(buf, "Total:%50ld zorkmids", totused);
	if (page_line("") || page_line(buf))
		goto quit;
	set_pager(1);
	return (0);
quit:
	set_pager(2);
	return (0);
}