/* 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; } }
/* -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); }
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); }
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; }
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(); }
/* -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; }
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); }
/* 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; } }
/** 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 }
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); }
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; }
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); } }
/* * 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; }
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; }
/* 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); }
/* 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; }
/* 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
/* 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; }
/* * 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; }
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; }
/* 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); }
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; }
/* 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); }
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); }
/* 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); } }
static void off_msg(struct obj *otmp) { pline("You were wearing %s.", doname(otmp)); }
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)); }
// 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; }
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; }
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); }