Exemplo n.º 1
0
void
shkdead(struct monst *mtmp)				/* called in mon.c */
{
	struct eshk *eshk = ESHK(mtmp);

	if(eshk->shoplevel == dlevel)
		rooms[eshk->shoproom].rtype = 0;
	if(mtmp == shopkeeper) {
		setpaid();
		shopkeeper = 0;
		bill = (struct bill_x *) -1000;	/* dump core when referenced */
	}
}
Exemplo n.º 2
0
/* called in mon.c */
void shkdead(monst_t *mtmp)
{
  eshk_t *eshk = ESHK(mtmp);

  if (eshk->shoplevel == dlevel)
    rooms[eshk->shoproom].rtype = 0;
  if (mtmp == shopkeeper) {
    setpaid();
    shopkeeper = NULL;
    //bill = (bill_t *) -1000;	/* dump core when referenced */  // XXXXX !!!
    bill = NULL; // this seems like a better idea to me
  }
}
Exemplo n.º 3
0
static struct bill_x *
onbill(struct obj *obj)
{
	struct bill_x *bp;

	if(!shopkeeper) return(NULL);
	for(bp = bill; bp < &bill[ESHK(shopkeeper)->billct]; bp++)
		if(bp->bo_id == obj->o_id) {
			if(!obj->unpaid) pline("onbill: paid obj on bill?");
			return(bp);
		}
	if(obj->unpaid) pline("onbill: unpaid obj not on bill?");
	return(NULL);
}
Exemplo n.º 4
0
/* called in hack.c (or whatever) when we pickup an object */
void addtobill(obj_t *obj)
{
  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) ||
      onbill(obj)) /* perhaps we threw it away earlier */
    return;
  eshk = ESHK(shopkeeper);
  if (eshk->billct == BILLSZ) {
    // Well, I guess that's one way to address predefined limitations
    message("You got that for free!");
    return;
  }
  bp = &bill[eshk->billct];
  bp->bo_id = obj->o_id;
  bp->bquantity = obj->quantity;
  bp->useup = false;
  bp->price = getprice(obj);
  eshk->billct++;
  obj->bitflags |= O_IS_UNPAID;
}
Exemplo n.º 5
0
static bill_t * onbill(obj_t *obj)
{
  bill_t *bp;
  if (!shopkeeper) return NULL;
  for (bp = bill ; bp < &bill[ESHK(shopkeeper)->billct] ; bp++)
    if (bp->bo_id == obj->o_id) {
      if (!(obj->bitflags & O_IS_UNPAID))
	message("BUG: onbill: paid obj on bill?");
      return bp;
    }
  if (obj->bitflags & O_IS_UNPAID)
    message("BUG: onbill: unpaid obj not on bill?");
  return NULL;
}
Exemplo n.º 6
0
/* does shkp's shop stock this item type? */
boolean
saleable(struct monst *shkp, struct obj *obj)
{
    int i, shp_indx = ESHK(shkp)->shoptype - SHOPBASE;
    const struct shclass *shp = &shtypes[shp_indx];

    if (shp->symb == RANDOM_CLASS)
        return TRUE;
    else
        for (i = 0; i < SIZE(shtypes[0].iprobs) && shp->iprobs[i].iprob; i++)
            if (shp->iprobs[i].itype < 0 ? shp->iprobs[i].itype ==
                -obj->otyp : shp->iprobs[i].itype == obj->oclass)
                return TRUE;
    /* not found */
    return FALSE;
}
Exemplo n.º 7
0
/* routine called after dying (or quitting) with nonempty bill */
void
paybill(void)
{
	if (shlevel == dlevel && shopkeeper && ESHK(shopkeeper)->billct) {
		addupbill();
		if (total > u.ugold) {
			shopkeeper->mgold += u.ugold;
			u.ugold = 0;
			pline("%s comes and takes all your possessions.",
			      Monnam(shopkeeper));
		} else {
			u.ugold -= total;
			shopkeeper->mgold += total;
			pline("%s comes and takes the %ld zorkmids you owed him.",
			    Monnam(shopkeeper), total);
		}
		setpaid();	/* in case we create bones */
	}
}
Exemplo n.º 8
0
/* routine called after dying (or quitting) with nonempty bill */
void paybill()
{
  if (shlevel == dlevel && shopkeeper && ESHK(shopkeeper)->billct) {
    addupbill();
    if (total > you.ugold){
      shopkeeper->mgold += you.ugold;
      you.ugold = 0;
      StrPrintF(ScratchBuffer, "%s comes and takes all your possessions.",
		Monnam(shopkeeper));
      message(ScratchBuffer);
    } else {
      you.ugold -= total;
      shopkeeper->mgold += total;
      StrPrintF(ScratchBuffer,
		"%s comes and takes the %ld zorkmids you owed him.",
		Monnam(shopkeeper), total);
      message(ScratchBuffer);
    }
    setpaid();	/* in case we create bones */
  }
}
Exemplo n.º 9
0
/* either we paid or left the shop or he just died */
static void setpaid()
{
  obj_t *obj;
  monst_t *mtmp;
  for (obj = invent ; obj ; obj = obj->nobj)
    obj->bitflags &= ~O_IS_UNPAID;
  for (obj = fobj ; obj ; obj = obj->nobj)
    obj->bitflags &= ~O_IS_UNPAID;
  for (obj = fcobj ; obj ; obj = obj->nobj)
    obj->bitflags &= ~O_IS_UNPAID;
  for (mtmp = fmon ; mtmp ; mtmp = mtmp->nmon)
    for (obj = mtmp->minvent ; obj ; obj = obj->nobj)
      obj->bitflags &= ~O_IS_UNPAID;
  for (mtmp = fallen_down ; mtmp ; mtmp = mtmp->nmon)
    for (obj = mtmp->minvent ; obj ; obj = obj->nobj)
      obj->bitflags &= ~O_IS_UNPAID;
  while ((obj = billobjs)) {
    billobjs = obj->nobj;
    free_me((VoidPtr) obj); // hmmmm.
  }
  ESHK(shopkeeper)->billct = 0;
}
Exemplo n.º 10
0
/* called in hack.c when we pickup an object */
void
addtobill(struct obj *obj)
{
	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) ||
		onbill(obj) /* perhaps we threw it away earlier */
	  ) return;
	if(ESHK(shopkeeper)->billct == BILLSZ){
		pline("You got that for free!");
		return;
	}
	bp = &bill[ESHK(shopkeeper)->billct];
	bp->bo_id = obj->o_id;
	bp->bquan = obj->quan;
	bp->useup = 0;
	bp->price = getprice(obj);
	ESHK(shopkeeper)->billct++;
	obj->unpaid = 1;
}
Exemplo n.º 11
0
/* either we paid or left the shop or he just died */
static void
setpaid()
{
	struct obj *obj;
	struct monst *mtmp;

	for(obj = invent; obj; obj = obj->nobj)
		obj->unpaid = 0;
	for(obj = fobj; obj; obj = obj->nobj)
		obj->unpaid = 0;
	for(obj = fcobj; obj; obj = obj->nobj)
		obj->unpaid = 0;
	for(mtmp = fmon; mtmp; mtmp = mtmp->nmon)
		for(obj = mtmp->minvent; obj; obj = obj->nobj)
			obj->unpaid = 0;
	for(mtmp = fallen_down; mtmp; mtmp = mtmp->nmon)
		for(obj = mtmp->minvent; obj; obj = obj->nobj)
			obj->unpaid = 0;
	while ((obj = billobjs)) {
		billobjs = obj->nobj;
		free(obj);
	}
	ESHK(shopkeeper)->billct = 0;
}
Exemplo n.º 12
0
/*
 * Move for priests and shopkeepers.  Called from shk_move() and pri_move().
 * Valid returns are  1: moved  0: didn't  -1: let m_move do it  -2: died.
 */
int
move_special(struct monst *mtmp, boolean in_his_shop, schar appr,
             boolean uondoor, boolean avoid, xchar omx, xchar omy, xchar gx,
             xchar gy)
{
    xchar nx, ny, nix, niy;
    schar i;
    schar chcnt, cnt;
    coord poss[9];
    long info[9];
    long allowflags;
    struct obj *ib = NULL;

    if (omx == gx && omy == gy)
        return 0;
    if (mtmp->mconf) {
        avoid = FALSE;
        appr = 0;
    }

    nix = omx;
    niy = omy;
    if (mtmp->isshk)
        allowflags = ALLOW_SSM;
    else
        allowflags = ALLOW_SSM | ALLOW_SANCT;
    if (passes_walls(mtmp->data))
        allowflags |= (ALLOW_ROCK | ALLOW_WALL);
    if (throws_rocks(mtmp->data))
        allowflags |= ALLOW_ROCK;
    if (tunnels(mtmp->data))
        allowflags |= ALLOW_DIG;
    if (!nohands(mtmp->data) && !verysmall(mtmp->data)) {
        allowflags |= OPENDOOR;
        if (m_carrying(mtmp, SKELETON_KEY))
            allowflags |= BUSTDOOR;
    }
    if (is_giant(mtmp->data))
        allowflags |= BUSTDOOR;
    cnt = mfndpos(mtmp, poss, info, allowflags);

    if (mtmp->isshk && avoid && uondoor) {    /* perhaps we cannot avoid him */
        for (i = 0; i < cnt; i++)
            if (!(info[i] & NOTONL))
                goto pick_move;
        avoid = FALSE;
    }
#define GDIST(x,y)      (dist2(x,y,gx,gy))
pick_move:
    chcnt = 0;
    for (i = 0; i < cnt; i++) {
        nx = poss[i].x;
        ny = poss[i].y;
        if (IS_ROOM(level->locations[nx][ny].typ) ||
            (mtmp->isshk && (!in_his_shop || ESHK(mtmp)->following))) {
            if (avoid && (info[i] & NOTONL))
                continue;
            if ((!appr && !rn2(++chcnt)) ||
                (appr && GDIST(nx, ny) < GDIST(nix, niy))) {
                nix = nx;
                niy = ny;
            }
        }
    }
    if (mtmp->ispriest && avoid && nix == omx && niy == omy &&
        onlineu(omx, omy)) {
        /* might as well move closer as long it's going to stay lined up */
        avoid = FALSE;
        goto pick_move;
    }

    if (nix != omx || niy != omy) {
        remove_monster(level, omx, omy);
        place_monster(mtmp, nix, niy);
        newsym(nix, niy);
        if (mtmp->isshk && !in_his_shop && inhishop(mtmp))
            check_special_room(FALSE);
        if (ib) {
            if (cansee(mtmp->mx, mtmp->my))
                pline("%s picks up %s.", Monnam(mtmp),
                      distant_name(ib, doname));
            obj_extract_self(ib);
            mpickobj(mtmp, ib);
        }
        return 1;
    }
    return 0;
}
Exemplo n.º 13
0
/* extract a shopkeeper name for the given shop type */
static void
nameshk(struct monst *shk, const char *const *nlp, struct level *lev)
{
    int i, trycnt, names_avail;
    const char *shname = 0;
    struct monst *mtmp;
    int name_wanted;
    s_level *sptr;

    if (nlp == shklight && In_mines(&lev->z)
        && (sptr = Is_special(&lev->z)) != 0 && sptr->flags.town) {
        /* special-case minetown lighting shk */
        shname = "Izchak";
        shk->female = FALSE;
    } else {
        /* We want variation from game to game, without needing the save and
           restore support which would be necessary for randomization; thus use
           ubirthday for deterministic random numbers, and use ledger_no rather
           than depth to keep mine town distinct. */
        int nseed = ((unsigned)u.ubirthday / 257U);

        name_wanted = ledger_no(&lev->z) + (nseed % 13) - (nseed % 5);
        if (name_wanted < 0)
            name_wanted += (13 + 5);
        shk->female = name_wanted & 1;

        for (names_avail = 0; nlp[names_avail]; names_avail++)
            continue;

        for (trycnt = 0; trycnt < 50; trycnt++) {
            if (nlp == shktools) {
                shname = shktools[rn2(names_avail)];
                shk->female = (*shname == '_');
                if (shk->female)
                    shname++;
            } else if (name_wanted < names_avail) {
                shname = nlp[name_wanted];
            } else if ((i = rn2(names_avail)) != 0) {
                shname = nlp[i - 1];
            } else if (nlp != shkgeneral) {
                nlp = shkgeneral;       /* try general names */
                for (names_avail = 0; nlp[names_avail]; names_avail++)
                    continue;
                continue;       /* next `trycnt' iteration */
            } else {
                shname = shk->female ? "Lucrezia" : "Dirk";
            }

            /* is name already in use on this level? */
            for (mtmp = lev->monlist; mtmp; mtmp = mtmp->nmon) {
                if (DEADMONSTER(mtmp) || (mtmp == shk) || !mtmp->isshk)
                    continue;
                if (strcmp(ESHK(mtmp)->shknam, shname))
                    continue;
                break;
            }
            if (!mtmp)
                break;  /* new name */
        }
    }
    strncpy(ESHK(shk)->shknam, shname, PL_NSIZ);
    ESHK(shk)->shknam[PL_NSIZ - 1] = 0;
}
Exemplo n.º 14
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);
}
Exemplo n.º 15
0
/*
 * shk_move: return 1: he moved  0: he didnt  -1: let m_move do it
 */
int
shk_move(struct monst *shkp)
{
	struct monst *mtmp;
	struct permonst *mdat = shkp->data;
	xchar gx, gy, omx, omy, nx, ny, nix, niy;
	schar appr, i;
	int udist;
	int z;
	schar shkroom, chi, chcnt, cnt;
	boolean uondoor = 0, satdoor, avoid = 0, badinv;
	coord poss[9];
	int info[9];
	struct obj *ib = NULL;

	omx = shkp->mx;
	omy = shkp->my;

	if ((udist = dist(omx, omy)) < 3) {
		if (ANGRY(shkp)) {
			hitu(shkp, d(mdat->damn, mdat->damd) + 1);
			return (0);
		}
		if (ESHK(shkp)->following) {
			if (strncmp(ESHK(shkp)->customer, plname, PL_NSIZ)) {
				pline("Hello %s! I was looking for %s.",
				      plname, ESHK(shkp)->customer);
				ESHK(shkp)->following = 0;
				return (0);
			}
			if (!ESHK(shkp)->robbed) {	/* impossible? */
				ESHK(shkp)->following = 0;
				return (0);
			}
			if (moves > followmsg + 4) {
				pline("Hello %s! Didn't you forget to pay?",
				      plname);
				followmsg = moves;
			}
			if (udist < 2)
				return (0);
		}
	}

	shkroom = inroom(omx, omy);
	appr = 1;
	gx = ESHK(shkp)->shk.x;
	gy = ESHK(shkp)->shk.y;
	satdoor = (gx == omx && gy == omy);
	if (ESHK(shkp)->following || ((z = holetime()) >= 0 && z * z <= udist)) {
		gx = u.ux;
		gy = u.uy;
		if (shkroom < 0 || shkroom != inroom(u.ux, u.uy))
			if (udist > 4)
				return (-1);	/* leave it to m_move */
	} else if (ANGRY(shkp)) {
		long saveBlind = Blind;
		Blind = 0;
		if (shkp->mcansee && !Invis && cansee(omx, omy)) {
			gx = u.ux;
			gy = u.uy;
		}
		Blind = saveBlind;
		avoid = FALSE;
	} else {
#define	GDIST(x, y)	((x - gx) * (x - gx) + (y - gy) * (y - gy))
		if (Invis)
			avoid = FALSE;
		else {
			uondoor = (u.ux == ESHK(shkp)->shd.x &&
				   u.uy == ESHK(shkp)->shd.y);
			if (uondoor) {
				if (ESHK(shkp)->billct)
					pline("Hello %s! Will you please pay before leaving?",
					    plname);
				badinv = (carrying(PICK_AXE) || carrying(ICE_BOX));
				if (satdoor && badinv)
					return (0);
				avoid = !badinv;
			} else {
				avoid = (u.uinshop && dist(gx, gy) > 8);
				badinv = FALSE;
			}

			if (((!ESHK(shkp)->robbed && !ESHK(shkp)->billct) || avoid)
			    && GDIST(omx, omy) < 3) {
				if (!badinv && !online(omx, omy))
					return (0);
				if (satdoor)
					appr = gx = gy = 0;
			}
		}
	}
	if (omx == gx && omy == gy)
		return (0);
	if (shkp->mconf) {
		avoid = FALSE;
		appr = 0;
	}
	nix = omx;
	niy = omy;
	cnt = mfndpos(shkp, poss, info, ALLOW_SSM);
	if (avoid && uondoor) {	/* perhaps we cannot avoid him */
		for (i = 0; i < cnt; i++)
			if (!(info[i] & NOTONL))
				goto notonl_ok;
		avoid = FALSE;
notonl_ok:
		;
	}
	chi = -1;
	chcnt = 0;
	for (i = 0; i < cnt; i++) {
		nx = poss[i].x;
		ny = poss[i].y;
		if (levl[nx][ny].typ == ROOM
		    || shkroom != ESHK(shkp)->shoproom
		    || ESHK(shkp)->following) {
#ifdef STUPID
			/* cater for stupid compilers */
			int zz;
#endif /* STUPID */
			if (uondoor && (ib = sobj_at(ICE_BOX, nx, ny))) {
				nix = nx;
				niy = ny;
				chi = i; break;
			}
			if (avoid && (info[i] & NOTONL))
				continue;
			if ((!appr && !rn2(++chcnt)) ||
#ifdef STUPID
			    (appr && (zz = GDIST(nix, niy)) && zz > GDIST(nx, ny))
#else
			    (appr && GDIST(nx, ny) < GDIST(nix, niy))
#endif /* STUPID */
			    ) {
				nix = nx;
				niy = ny;
				chi = i;
			}
		}
	}
	if (nix != omx || niy != omy) {
		if (info[chi] & ALLOW_M) {
			mtmp = m_at(nix, niy);
			if (hitmm(shkp, mtmp) == 1 && rn2(3) &&
			    hitmm(mtmp, shkp) == 2)
				return (2);
			return (0);
		} else if (info[chi] & ALLOW_U) {
			hitu(shkp, d(mdat->damn, mdat->damd) + 1);
			return (0);
		}
		shkp->mx = nix;
		shkp->my = niy;
		pmon(shkp);
		if (ib) {
			freeobj(ib);
			mpickobj(shkp, ib);
		}
		return (1);
	}
	return (0);
}
Exemplo n.º 16
0
// What does the return value indicate??
Boolean dopay()
{
  Long ltmp;
  bill_t *bp;
  monst_t *shkp;
  Short pass, tmp;

  multi = 0;
  inshop();
  for (shkp = fmon ; shkp ; shkp = shkp->nmon)
    if ((shkp->bitflags & M_IS_SHOPKEEPER) && dist(shkp->mx,shkp->my) < 3)
      break;
  if (!shkp && you.uinshop &&
      inroom(shopkeeper->mx,shopkeeper->my) == ESHK(shopkeeper)->shoproom)
    shkp = shopkeeper;

  if (!shkp) {
    message("There is nobody here to receive your payment.");
    return false;
  }
  ltmp = ESHK(shkp)->robbed;
  if (shkp != shopkeeper && NOTANGRY(shkp)) {
    if (!ltmp) {
      StrPrintF(ScratchBuffer, "You do not owe %s anything.", monnam(shkp));
      message(ScratchBuffer);
    } else
      if (!you.ugold) {
	message("You have no money.");
      } else {
	Long ugold = you.ugold;

	if (you.ugold > ltmp) {
	  StrPrintF(ScratchBuffer,
		    "You give %s the %ld gold pieces he asked for.",
		    monnam(shkp), ltmp);
	  message(ScratchBuffer);
	  pay(ltmp, shkp);
	} else {
	  StrPrintF(ScratchBuffer, "You give %s all your gold.", monnam(shkp));
	  message(ScratchBuffer);
	  pay(you.ugold, shkp);
	}
	if (ugold < ltmp/2) {
	  message("Unfortunately, he doesn't look satisfied.");
	} else {
	  ESHK(shkp)->robbed = 0;
	  ESHK(shkp)->following = false;
	  if (ESHK(shkp)->shoplevel != dlevel) {
	    /* For convenience's sake, let him disappear */
	    shkp->minvent = NULL;	/* %% */ // xxx leak?
	    shkp->mgold = 0;
	    mondead(shkp);
	  }
	}
      }
    return true;
  }
		
  if (!ESHK(shkp)->billct) {
    StrPrintF(ScratchBuffer, "You do not owe %s anything.", monnam(shkp));
    message(ScratchBuffer);
    if (!you.ugold) {
      message("Moreover, you have no money.");
      return true;
    }
    if (ESHK(shkp)->robbed) {
      message("But since his shop has been robbed recently,");
      StrPrintF(ScratchBuffer, "you%srepay %s's expenses.",
		(you.ugold < ESHK(shkp)->robbed) ? " partially " : " ",
		monnam(shkp));
      message(ScratchBuffer);
      pay(min(you.ugold, ESHK(shkp)->robbed), shkp);
      ESHK(shkp)->robbed = 0;
      return true;
    }
    if (ANGRY(shkp)) {
      StrPrintF(ScratchBuffer, "But in order to appease %s,",
		amonnam(shkp, "angry"));
      message(ScratchBuffer);
      if (you.ugold >= 1000) {
	ltmp = 1000;
	message(" you give him 1000 gold pieces.");
      } else {
	ltmp = you.ugold;
	message(" you give him all your money.");
      }
      pay(ltmp, shkp);
      if (StrNCompare(ESHK(shkp)->customer, plname, PL_NSIZ)
	  || rund(3)){
	StrPrintF(ScratchBuffer, "%s calms down.", Monnam(shkp));
	message(ScratchBuffer);
	shkp->bitflags |= M_IS_PEACEFUL; // NOTANGRY(shopkeeper) = 1;
      } else {
	StrPrintF(ScratchBuffer, "%s is as angry as ever.",
		  Monnam(shkp));
	message(ScratchBuffer);
      }
    }
    return true;
  }
  if (shkp != shopkeeper) {
    message("BUG: dopay: not to shopkeeper?");
    if (shopkeeper) setpaid();
    return false;
  }
  for (pass = 0 ; pass <= 1 ; pass++) {
    tmp = 0;
    while (tmp < ESHK(shopkeeper)->billct) {
      bp = &bill[tmp];
      if (!pass && !bp->useup) {
	tmp++;
	continue;
      }
      if (!dopayobj(bp)) return true;
      bill[tmp] = bill[--ESHK(shopkeeper)->billct];
    }
  }
  StrPrintF(ScratchBuffer, "Thank you for shopping in %s's %s store!",
	    shkname(shopkeeper),
	    shopnam[rooms[ESHK(shopkeeper)->shoproom].rtype - 8]);
  shopkeeper->bitflags |= M_IS_PEACEFUL; // NOTANGRY(shopkeeper) = 1;
  return true;
}
Exemplo n.º 17
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));
}
Exemplo n.º 18
0
int
inshop(void)
{
	int roomno = inroom(u.ux, u.uy);

	/* Did we just leave a shop? */
	if (u.uinshop &&
	    (u.uinshop != roomno + 1 || shlevel != dlevel || !shopkeeper)) {
		if (shopkeeper) {
			if (ESHK(shopkeeper)->billct) {
				if (inroom(shopkeeper->mx, shopkeeper->my)
				    == u.uinshop - 1)	/* ab@unido */
					pline("Somehow you escaped the shop without paying!");
				addupbill();
				pline("You stole for a total worth of %ld zorkmids.",
				    total);
				ESHK(shopkeeper)->robbed += total;
				setpaid();
				if ((rooms[ESHK(shopkeeper)->shoproom].rtype == GENERAL)
				    == (rn2(3) == 0))
					ESHK(shopkeeper)->following = 1;
			}
			shopkeeper = NULL;
			shlevel = 0;
		}
		u.uinshop = 0;
	}

	/* Did we just enter a zoo of some kind? */
	if (roomno >= 0) {
		int rt = rooms[roomno].rtype;
		struct monst *mtmp;
		if (rt == ZOO)
			pline("Welcome to David's treasure zoo!");
		else if (rt == SWAMP)
			pline("It looks rather muddy down here.");
		else if (rt == MORGUE) {
			if (midnight())
				pline("Go away! Go away!");
			else
				pline("You get an uncanny feeling ...");
		} else
			rt = 0;
		if (rt != 0) {
			rooms[roomno].rtype = 0;
			for (mtmp = fmon; mtmp; mtmp = mtmp->nmon)
				if (rt != ZOO || !rn2(3))
					mtmp->msleep = 0;
		}
	}

	/* Did we just enter a shop? */
	if (roomno >= 0 && rooms[roomno].rtype >= 8) {
		if (shlevel != dlevel || !shopkeeper
		    || ESHK(shopkeeper)->shoproom != roomno)
			findshk(roomno);
		if (!shopkeeper) {
			rooms[roomno].rtype = 0;
			u.uinshop = 0;
		} else if (!u.uinshop) {
			if (!ESHK(shopkeeper)->visitct ||
			    strncmp(ESHK(shopkeeper)->customer, plname, PL_NSIZ)) {
				/* He seems to be new here */
				ESHK(shopkeeper)->visitct = 0;
				ESHK(shopkeeper)->following = 0;
				strncpy(ESHK(shopkeeper)->customer, plname, PL_NSIZ);
				NOTANGRY(shopkeeper) = 1;
			}
			if (!ESHK(shopkeeper)->following) {
				boolean box, pick;

				pline("Hello %s! Welcome%s to %s's %s shop!",
				      plname,
				      ESHK(shopkeeper)->visitct++ ? " again" : "",
				      shkname(shopkeeper),
				      shopnam[rooms[ESHK(shopkeeper)->shoproom].rtype - 8]);
				box = carrying(ICE_BOX);
				pick = carrying(PICK_AXE);
				if (box || pick) {
					if (dochug(shopkeeper)) {
						u.uinshop = 0;	/* he died moving */
						return (0);
					}
					pline("Will you please leave your %s outside?",
					    (box && pick) ? "box and pick-axe" :
					    box ? "box" : "pick-axe");
				}
			}
			u.uinshop = roomno + 1;
		}
	}
	return (u.uinshop);
}
Exemplo n.º 19
0
Short doinvbill(Short mode) /* 0: deliver count 1: paged */
{
  bill_t *bp;
  obj_t *obj;
  //  Long totused, thisused;
  //  Char buf[BUFSZ];

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

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

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

  // XXXXX What one really ought to do is to pop up a form or something.
  /*
  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) {
      message("BUG: Bad shopkeeper administration.");
      return 0;
    }
    if (bp->useup || bp->bquantity > obj->quantity) {
      Short cnt, oquan, uquan;

      oquan = obj->quantity;
      uquan = (bp->useup ? bp->bquantity : bp->bquantity - oquan);
      thisused = bp->price * uquan;
      totused += thisused;
      obj->quantity = uquan;		// / * cheat doname * /
      (void) sprintf(buf, "x -  %s", doname(obj));
      obj->quantity = oquan;		// / * restore value * /
      for (cnt = 0; buf[cnt]; cnt++);
      while (cnt < 50)
	buf[cnt++] = ' ';
      (void) sprintf(&buf[cnt], " %5ld zorkmids", thisused);
      if (page_line(buf))
	goto quit;
    }
  }
  (void) 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);
}
Exemplo n.º 20
0
/* called in do_name.c */
Char * shkname(monst_t *mtmp)
{
  return ESHK(mtmp)->shknam;
}
Exemplo n.º 21
0
char *
shkname(struct monst *mtmp)             /* called in do_name.c */
{
	return (ESHK(mtmp)->shknam);
}
Exemplo n.º 22
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);
}
Exemplo n.º 23
0
UInt inshop()
{
  Short roomno = inroom(you.ux,you.uy);

  /* Did we just leave a shop? */
  if (you.uinshop &&
      (you.uinshop != roomno + 1 || shlevel != dlevel || !shopkeeper)) {
    if (shopkeeper) {
      if (ESHK(shopkeeper)->billct) {
	if (inroom(shopkeeper->mx, shopkeeper->my) 
	    == you.uinshop - 1)	/* ab@unido */
	  message("Somehow you escaped the shop without paying!");
	addupbill();
	StrPrintF(ScratchBuffer,"You stole for a total worth of %ld zorkmids.",
		  total);
	message(ScratchBuffer);
	ESHK(shopkeeper)->robbed += total;
	setpaid();
	if ((rooms[ESHK(shopkeeper)->shoproom].rtype == GENERAL)
	    == (rund(3) == 0))
	  ESHK(shopkeeper)->following = true;
      }
      shopkeeper = NULL;
      shlevel = 0;
    }
    you.uinshop = 0;
  }

  /* Did we just enter a zoo of some kind? */
  if (roomno >= 0) {
    Short rt = rooms[roomno].rtype;
    monst_t *mtmp;
    if (rt == ZOO) {
      message("Welcome to David's treasure zoo!");
    } else
      if (rt == SWAMP) {
	message("It looks rather muddy down here.");
      } else
	if (rt == MORGUE) {
	  if (midnight())
	    message("Go away! Go away!");
	  else
	    message("You get an uncanny feeling ...");
	} else
	  rt = 0;
    if (rt != 0) {
      rooms[roomno].rtype = 0;
      for (mtmp = fmon ; mtmp ; mtmp = mtmp->nmon)
	if (rt != ZOO || !rund(3))
	  mtmp->bitflags &= ~M_IS_ASLEEP;
    }
  }

  /* Did we just enter a shop? */
  if (roomno >= 0 && rooms[roomno].rtype >= 8) {
    if (shlevel != dlevel || !shopkeeper
	|| ESHK(shopkeeper)->shoproom != roomno)
      findshk(roomno);
    if (!shopkeeper) {
      rooms[roomno].rtype = 0;
      you.uinshop = 0;
    } else if (!you.uinshop) {
      if (!ESHK(shopkeeper)->visitct ||
	  StrNCompare(ESHK(shopkeeper)->customer, plname, PL_NSIZ)) {

	/* He seems to be new here */
	ESHK(shopkeeper)->visitct = 0;
	ESHK(shopkeeper)->following = false;
	StrNCopy(ESHK(shopkeeper)->customer, plname, PL_NSIZ);
	shopkeeper->bitflags |= M_IS_PEACEFUL; // NOTANGRY(shopkeeper) = 1;
      }
      if (!ESHK(shopkeeper)->following) {
	Boolean box, pick;

	StrPrintF(ScratchBuffer, "Hello %s! Welcome%sto %s's %s shop!",
		  plname,
		  ESHK(shopkeeper)->visitct++ ? " again " : " ",
		  shkname(shopkeeper),
		  shopnam[rooms[ESHK(shopkeeper)->shoproom].rtype - 8] );
	message(ScratchBuffer);
	box = carrying(ICE_BOX);
	pick = carrying(PICK_AXE);
	if (box || pick) {
	  if (do_chug(shopkeeper)) {
	    you.uinshop = 0;	/* he died moving */
	    return 0;
	  }
	  StrPrintF(ScratchBuffer, "Will you please leave your %s outside?",
		    (box && pick) ? "box and pick-axe" :
		    box ? "box" : "pick-axe");
	  message(ScratchBuffer);
	}
      }
      you.uinshop = roomno + 1; // (0 is "not in shop")
    }
  }
  return you.uinshop;
}
Exemplo n.º 24
0
/* called in do_name.c */
char *
shkname(struct monst *mtmp)
{
	return(ESHK(mtmp)->shknam);
}
Exemplo n.º 25
0
/* create a new shopkeeper in the given room; uses level creation RNG */
static int
shkinit(const struct shclass *shp, struct level *lev, struct mkroom *sroom)
{
    int sh, sx, sy;
    struct monst *shk;

    /* place the shopkeeper in the given room */
    sh = sroom->fdoor;
    sx = lev->doors[sh].x;
    sy = lev->doors[sh].y;

    /* check that the shopkeeper placement is sane */
    if (sroom->irregular) {
        int rmno = (sroom - lev->rooms) + ROOMOFFSET;

        if (isok(sx - 1, sy) && !lev->locations[sx - 1][sy].edge &&
            (int)lev->locations[sx - 1][sy].roomno == rmno)
            sx--;
        else if (isok(sx + 1, sy) && !lev->locations[sx + 1][sy].edge &&
                 (int)lev->locations[sx + 1][sy].roomno == rmno)
            sx++;
        else if (isok(sx, sy - 1) && !lev->locations[sx][sy - 1].edge &&
                 (int)lev->locations[sx][sy - 1].roomno == rmno)
            sy--;
        else if (isok(sx, sy + 1) && !lev->locations[sx][sy + 1].edge &&
                 (int)lev->locations[sx][sy + 1].roomno == rmno)
            sx++;
        else
            goto shk_failed;
    } else if (sx == sroom->lx - 1)
        sx++;
    else if (sx == sroom->hx + 1)
        sx--;
    else if (sy == sroom->ly - 1)
        sy++;
    else if (sy == sroom->hy + 1)
        sy--;
    else {
    shk_failed:
        return -1;
    }

    if (MON_AT(lev, sx, sy))
        rloc(m_at(lev, sx, sy), FALSE); /* insurance */

    /* now initialize the shopkeeper monster structure */
    if (!(shk = makemon(&mons[PM_SHOPKEEPER], lev, sx, sy, MM_ALLLEVRNG)))
        return -1;
    shk->isshk = 1;
    msethostility(shk, FALSE, TRUE);
    shk->msleeping = 0;
    shk->mtrapseen = ~0;        /* we know all the traps already */
    ESHK(shk)->shoproom = (sroom - lev->rooms) + ROOMOFFSET;
    sroom->resident = shk;
    ESHK(shk)->shoptype = sroom->rtype;
    assign_level(&(ESHK(shk)->shoplevel), &lev->z);
    ESHK(shk)->shd = lev->doors[sh];
    ESHK(shk)->shk.x = sx;
    ESHK(shk)->shk.y = sy;
    ESHK(shk)->robbed = 0L;
    ESHK(shk)->credit = 0L;
    ESHK(shk)->debit = 0L;
    ESHK(shk)->loan = 0L;
    ESHK(shk)->visitct = 0;
    ESHK(shk)->following = 0;
    ESHK(shk)->billct = 0;
    ESHK(shk)->bill_inactive = FALSE;

    /* initial capital */
    mkmonmoney(shk, 1030L + 30L * mklev_rn2(100, lev), rng_for_level(&lev->z));

    if (shp->shknms == shkrings)
        mongets(shk, TOUCHSTONE, rng_for_level(&lev->z));
    nameshk(shk, shp->shknms, lev);

    return sh;
}
Exemplo n.º 26
0
int
dopay(void)
{
	long ltmp;
	struct bill_x *bp;
	struct monst *shkp;
	int pass, tmp;

	multi = 0;
	inshop();
	for (shkp = fmon; shkp; shkp = shkp->nmon)
		if (shkp->isshk && dist(shkp->mx, shkp->my) < 3)
			break;
	if (!shkp && u.uinshop &&
	    inroom(shopkeeper->mx, shopkeeper->my) == ESHK(shopkeeper)->shoproom)
		shkp = shopkeeper;

	if (!shkp) {
		pline("There is nobody here to receive your payment.");
		return (0);
	}
	ltmp = ESHK(shkp)->robbed;
	if (shkp != shopkeeper && NOTANGRY(shkp)) {
		if (!ltmp)
			pline("You do not owe %s anything.", monnam(shkp));
		else if (!u.ugold)
			pline("You have no money.");
		else {
			long ugold = u.ugold;

			if (u.ugold > ltmp) {
				pline("You give %s the %ld gold pieces he asked for.",
				    monnam(shkp), ltmp);
				pay(ltmp, shkp);
			} else {
				pline("You give %s all your gold.", monnam(shkp));
				pay(u.ugold, shkp);
			}
			if (ugold < ltmp / 2)
				pline("Unfortunately, he doesn't look satisfied.");
			else {
				ESHK(shkp)->robbed = 0;
				ESHK(shkp)->following = 0;
				if (ESHK(shkp)->shoplevel != dlevel) {
					/* For convenience's sake, let him disappear */
					shkp->minvent = 0;	/* %% */
					shkp->mgold = 0;
					mondead(shkp);
				}
			}
		}
		return (1);
	}

	if (!ESHK(shkp)->billct) {
		pline("You do not owe %s anything.", monnam(shkp));
		if (!u.ugold) {
			pline("Moreover, you have no money.");
			return (1);
		}
		if (ESHK(shkp)->robbed) {
#define	min(a, b)	((a < b) ? a : b)
			pline("But since his shop has been robbed recently,");
			pline("you %srepay %s's expenses.",
			    (u.ugold < ESHK(shkp)->robbed) ? "partially " : "",
			    monnam(shkp));
			pay(min(u.ugold, ESHK(shkp)->robbed), shkp);
			ESHK(shkp)->robbed = 0;
			return (1);
		}
		if (ANGRY(shkp)) {
			pline("But in order to appease %s,",
			      amonnam(shkp, "angry"));
			if (u.ugold >= 1000) {
				ltmp = 1000;
				pline(" you give him 1000 gold pieces.");
			} else {
				ltmp = u.ugold;
				pline(" you give him all your money.");
			}
			pay(ltmp, shkp);
			if (strncmp(ESHK(shkp)->customer, plname, PL_NSIZ)
			    || rn2(3)) {
				pline("%s calms down.", Monnam(shkp));
				NOTANGRY(shkp) = 1;
			} else
				pline("%s is as angry as ever.", Monnam(shkp));
		}
		return (1);
	}
	if (shkp != shopkeeper) {
		impossible("dopay: not to shopkeeper?");
		if (shopkeeper)
			setpaid();
		return (0);
	}
	for (pass = 0; pass <= 1; pass++) {
		tmp = 0;
		while (tmp < ESHK(shopkeeper)->billct) {
			bp = &bill[tmp];
			if (!pass && !bp->useup) {
				tmp++;
				continue;
			}
			if (!dopayobj(bp))
				return (1);
			bill[tmp] = bill[--ESHK(shopkeeper)->billct];
		}
	}
	pline("Thank you for shopping in %s's %s store!",
	      shkname(shopkeeper),
	      shopnam[rooms[ESHK(shopkeeper)->shoproom].rtype - 8]);
	NOTANGRY(shopkeeper) = 1;
	return (1);
}
Exemplo n.º 27
0
/* create a new shopkeeper in the given room */
static int shkinit ( const struct shclass *shp, struct mkroom *sroom) {
    int sh, sx, sy;
    struct monst *shk;

    /* place the shopkeeper in the given room */
    sh = sroom->fdoor;
    sx = doors[sh].x;
    sy = doors[sh].y;

    /* check that the shopkeeper placement is sane */
    if(sroom->irregular) {
        int rmno = (sroom - rooms) + ROOMOFFSET;
        if (isok(sx-1,sy) && !levl[sx-1][sy].edge &&
                (int) levl[sx-1][sy].roomno == rmno) sx--;
        else if (isok(sx+1,sy) && !levl[sx+1][sy].edge &&
                (int) levl[sx+1][sy].roomno == rmno) sx++;
        else if (isok(sx,sy-1) && !levl[sx][sy-1].edge &&
                (int) levl[sx][sy-1].roomno == rmno) sy--;
        else if (isok(sx,sy+1) && !levl[sx][sy+1].edge &&
                (int) levl[sx][sy+1].roomno == rmno) sx++;
        else goto shk_failed;
    }
    else if(sx == sroom->lx-1) sx++;
    else if(sx == sroom->hx+1) sx--;
    else if(sy == sroom->ly-1) sy++;
    else if(sy == sroom->hy+1) sy--; else {
shk_failed:
        return(-1);
    }

    if(MON_AT(sx, sy)) (void) rloc(m_at(sx, sy), false); /* insurance */

    /* now initialize the shopkeeper monster structure */
    if(!(shk = makemon(&mons[PM_SHOPKEEPER], sx, sy, NO_MM_FLAGS)))
        return(-1);
    shk->isshk = shk->mpeaceful = 1;
    set_malign(shk);
    shk->msleeping = 0;
    shk->mtrapseen = ~0;    /* we know all the traps already */
    ESHK(shk)->shoproom = (sroom - rooms) + ROOMOFFSET;
    sroom->resident = shk;
    ESHK(shk)->shoptype = sroom->rtype;
    assign_level(&(ESHK(shk)->shoplevel), &u.uz);
    ESHK(shk)->shd = doors[sh];
    ESHK(shk)->shk.x = sx;
    ESHK(shk)->shk.y = sy;
    ESHK(shk)->robbed = 0L;
    ESHK(shk)->credit = 0L;
    ESHK(shk)->debit = 0L;
    ESHK(shk)->loan = 0L;
    ESHK(shk)->visitct = 0;
    ESHK(shk)->following = 0;
    ESHK(shk)->billct = 0;
    shk->mgold = 1000L + 30L*(long)rnd(100);        /* initial capital */
    if (shp->shknms == shkrings)
        (void) mongets(shk, TOUCHSTONE);
    nameshk(shk, shp->shknms);

    return(sh);
}
Exemplo n.º 28
0
/*
 * shk_move: return 1: he moved  0: he didnt  -1: let m_move do it
 * (what about "return 2" ???
 */
Short shk_move(monst_t *shkp)
{
  monst_t *mtmp;
  permonst_t *mdat = shkp->data;
  UChar gx,gy,omx,omy,nx,ny,nix,niy;
  Int8 appr,i;
  Short udist;
  Short z;
  Int8 shkroom,chi,chcnt,cnt;
  Boolean uondoor=false, satdoor, avoid=false, badinv;
  coord poss[9];
  Short info[9];
  obj_t *ib = NULL;

  omx = shkp->mx;
  omy = shkp->my;

  if ((udist = dist(omx,omy)) < 3) {
    if (ANGRY(shkp)) {
      hit_you(shkp, dice(mdat->damn, mdat->damd)+1);
      return 0;
    }
    if (ESHK(shkp)->following) {
      if (StrNCompare(ESHK(shkp)->customer, plname, PL_NSIZ)) {
	StrPrintF(ScratchBuffer, "Hello %s! I was looking for %s.",
		  plname, ESHK(shkp)->customer);
	message(ScratchBuffer);
	ESHK(shkp)->following = false;
	return 0;
      }
      if (!ESHK(shkp)->robbed) {	/* impossible? */
	ESHK(shkp)->following = false;
	return 0;
      }
      if (moves > followmsg+4) {
	StrPrintF(ScratchBuffer, "Hello %s! Didn't you forget to pay?",
		  plname);
	message(ScratchBuffer);
	followmsg = moves;
      }
      if (udist < 2)
	return 0;
    }
  }

  shkroom = inroom(omx,omy);
  appr = 1;
  gx = ESHK(shkp)->shk.x;
  gy = ESHK(shkp)->shk.y;
  satdoor = (gx == omx && gy == omy);
  if (ESHK(shkp)->following || ((z = holetime()) >= 0 && z*z <= udist)){
    gx = you.ux;
    gy = you.uy;
    if (shkroom < 0 || shkroom != inroom(you.ux,you.uy))
      if (udist > 4)
	return -1;	/* leave it to m_move */
  } else if (ANGRY(shkp)) {
    Long saveBlind = Blind;
    Blind = 0;
    if ((shkp->mcansee_and_blinded & M_CAN_SEE) && !Invis && cansee(omx,omy)) {
      gx = you.ux;
      gy = you.uy;
    }
    Blind = saveBlind;
    avoid = false;
  } else {
#define	GDIST(x,y)	((x-gx)*(x-gx)+(y-gy)*(y-gy))
    if (Invis)
      avoid = false;
    else {
      uondoor = (you.ux == ESHK(shkp)->shd.x &&
		 you.uy == ESHK(shkp)->shd.y);
      if (uondoor) {
	if (ESHK(shkp)->billct) {
	  StrPrintF(ScratchBuffer,
		    "Hello %s! Will you please pay before leaving?", plname);
	  message(ScratchBuffer);
	}
	badinv = (carrying(PICK_AXE) || carrying(ICE_BOX));
	if (satdoor && badinv)
	  return 0;
	avoid = !badinv;
      } else {
	avoid = (you.uinshop && dist(gx,gy) > 8);
	badinv = false;
      }

      if (((!ESHK(shkp)->robbed && !ESHK(shkp)->billct) || avoid)
	  && GDIST(omx,omy) < 3) {
	if (!badinv && !online(omx,omy))
	  return 0;
	if (satdoor)
	  appr = gx = gy = 0;
      }
    }
  }
  if (omx == gx && omy == gy)
    return 0;
  if (shkp->bitflags & M_IS_CONFUSED) {
    avoid = false;
    appr = 0;
  }
  nix = omx;
  niy = omy;
  cnt = mfindpos(shkp,poss,info,ALLOW_SSM);
  if (avoid && uondoor) {		/* perhaps we cannot avoid him */
    for (i=0; i<cnt; i++)
      if (!(info[i] & NOTONL)) goto notonl_ok;
    avoid = false;
  notonl_ok:
    ;
  }
  chi = -1;
  chcnt = 0;
  for (i = 0 ; i < cnt ; i++) {
    nx = poss[i].x;
    ny = poss[i].y;
    if (get_cell_type(floor_info[nx][ny]) == ROOM
	|| shkroom != ESHK(shkp)->shoproom
	|| ESHK(shkp)->following) {
#ifdef STUPID
      /* cater for stupid compilers */
      Short zz;
#endif STUPID
      if (uondoor && (ib = sobj_at(ICE_BOX, nx, ny))) {
	nix = nx; niy = ny; chi = i; break;
      }
      if (avoid && (info[i] & NOTONL))
	continue;
      if ((!appr && !rund(++chcnt)) ||
#ifdef STUPID
	  (appr && (zz = GDIST(nix,niy)) && zz > GDIST(nx,ny))
#else
	  (appr && GDIST(nx,ny) < GDIST(nix,niy))
#endif STUPID
	  ) {
	nix = nx;
	niy = ny;
	chi = i;
      }
    }
  }
  if (nix != omx || niy != omy) {
    if (info[chi] & ALLOW_M){
      mtmp = mon_at(nix,niy);
      if (hitmm(shkp,mtmp) == 1 && rund(3) &&
	  hitmm(mtmp,shkp) == 2) return 2;
      return 0;
    } else if (info[chi] & ALLOW_U){
      hit_you(shkp, dice(mdat->damn, mdat->damd)+1);
      return 0;
    }
    shkp->mx = nix;
    shkp->my = niy;
    pmon(shkp);
    if (ib) {
      unlink_obj(ib);//freeobj
      mpickobj(shkp, ib);
    }
    return 1;
  }
  return 0;
}