/* return TRUE if successful, FALSE if not */ boolean rloc(struct monst *mtmp, /* mx==0 implies migrating monster arrival */ boolean suppress_impossible) { int x, y, trycount; if (mtmp == u.usteed) { tele(); return TRUE; } if (mtmp->iswiz && mtmp->mx) { /* Wizard, not just arriving */ if (!In_W_tower(u.ux, u.uy, &u.uz)) x = level->upstair.sx, y = level->upstair.sy; else if (!level->dnladder.sx) /* bottom level of tower */ x = level->upladder.sx, y = level->upladder.sy; else x = level->dnladder.sx, y = level->dnladder.sy; /* if the wiz teleports away to heal, try the up staircase, to block the player's escaping before he's healed (deliberately use `goodpos' rather than `rloc_pos_ok' here) */ if (goodpos(level, x, y, mtmp, 0)) goto found_xy; } trycount = 0; do { x = rn1(COLNO - 3, 2); y = rn2(ROWNO); if ((trycount < 500) ? rloc_pos_ok(x, y, mtmp) : goodpos(level, x, y, mtmp, 0)) goto found_xy; } while (++trycount < 1000); /* last ditch attempt to find a good place */ for (x = 2; x < COLNO - 1; x++) for (y = 0; y < ROWNO; y++) if (goodpos(level, x, y, mtmp, 0)) goto found_xy; /* level either full of monsters or somehow faulty */ if (!suppress_impossible) impossible("rloc(): couldn't relocate monster"); return FALSE; found_xy: rloc_to(mtmp, x, y); return TRUE; }
void rloco_pos(struct level *lev, struct obj *obj, int *nx, int *ny) { xchar tx, ty, otx; boolean restricted_fall; int try_limit = 4000; otx = obj->ox; restricted_fall = (otx == -1 && lev->dndest.lx); do { tx = rn2(COLNO); ty = rn2(ROWNO); if (!--try_limit) break; } while (!goodpos(lev, tx, ty, NULL, 0) || /* bug: this lacks provision for handling the Wizard's tower */ (restricted_fall && (!within_bounded_area (tx, ty, lev->dndest.lx, lev->dndest.ly, lev->dndest.hx, lev->dndest.hy) || (level->dndest.nlx && within_bounded_area(tx, ty, lev->dndest.nlx, lev->dndest.nly, lev->dndest.nhx, lev->dndest.nhy))))); *nx = tx; *ny = ty; }
void rloc(struct monst *mtmp) { int tx, ty; char ch = mtmp->data->mlet; #ifndef NOWORM if (ch == 'w' && mtmp->mx) /* do not relocate worms */ return; #endif /* NOWORM */ do { tx = rn1(COLNO - 3, 2); ty = rn2(ROWNO); } while (!goodpos(tx, ty)); mtmp->mx = tx; mtmp->my = ty; if (u.ustuck == mtmp) { if (u.uswallow) { u.ux = tx; u.uy = ty; docrt(); } else u.ustuck = 0; } pmon(mtmp); }
static boolean teleok(int x, int y, boolean trapok) { if (!trapok && t_at(level, x, y)) return FALSE; if (!goodpos(level, x, y, &youmonst, 0)) return FALSE; if (!tele_jump_ok(u.ux, u.uy, x, y)) return FALSE; if (!in_out_region(level, x, y)) return FALSE; return TRUE; }
/* check whether monster can arrive at location <x,y> via Tport (or fall) */ static boolean rloc_pos_ok(int x, int y, /* coordinates of candidate location */ struct monst *mtmp) { int xx, yy; if (!goodpos(level, x, y, mtmp, 0)) return FALSE; /* * Check for restricted areas present in some special levels. * * `xx' is current column; if 0, then `yy' will contain flag bits * rather than row: bit #0 set => moving upwards; bit #1 set => * inside the Wizard's tower. */ xx = mtmp->mx; yy = mtmp->my; if (!xx) { /* no current location (migrating monster arrival) */ if (level->dndest.nlx && On_W_tower_level(&u.uz)) return ((yy & 2) != 0) ^ /* inside xor not within */ !within_bounded_area(x, y, level->dndest.nlx, level->dndest.nly, level->dndest.nhx, level->dndest.nhy); if (level->updest.lx && (yy & 1) != COLNO) /* moving up */ return (within_bounded_area (x, y, level->updest.lx, level->updest.ly, level->updest.hx, level->updest.hy) && (!level->updest.nlx || !within_bounded_area( x, y, level->updest.nlx, level->updest.nly, level->updest.nhx, level->updest.nhy))); if (level->dndest.lx && (yy & 1) == COLNO) /* moving down */ return (within_bounded_area (x, y, level->dndest.lx, level->dndest.ly, level->dndest.hx, level->dndest.hy) && (!level->dndest.nlx || !within_bounded_area( x, y, level->dndest.nlx, level->dndest.nly, level->dndest.nhx, level->dndest.nhy))); } else { /* [try to] prevent a shopkeeper or temple priest from being sent out of his room (caller might resort to goodpos() if we report failure here, so this isn't full prevention) */ if (mtmp->isshk && inhishop(mtmp)) { if (level->locations[x][y].roomno != ESHK(mtmp)->shoproom) return FALSE; } else if (mtmp->ispriest && inhistemple(mtmp)) { if (level->locations[x][y].roomno != EPRI(mtmp)->shroom) return FALSE; } /* current location is <xx,yy> */ if (!tele_jump_ok(xx, yy, x, y)) return FALSE; } /* <x,y> is ok */ return TRUE; }
coord enexto(xchar xx, xchar yy) { xchar x, y; coord foo[15], *tfoo; int range; tfoo = foo; range = 1; do { /* full kludge action. */ for (x = xx - range; x <= xx + range; x++) if (goodpos(x, yy - range)) { tfoo->x = x; tfoo++->y = yy - range; if (tfoo == &foo[15]) goto foofull; } for (x = xx - range; x <= xx + range; x++) if (goodpos(x, yy + range)) { tfoo->x = x; tfoo++->y = yy + range; if (tfoo == &foo[15]) goto foofull; } for (y = yy + 1 - range; y < yy + range; y++) if (goodpos(xx - range, y)) { tfoo->x = xx - range; tfoo++->y = y; if (tfoo == &foo[15]) goto foofull; } for (y = yy + 1 - range; y < yy + range; y++) if (goodpos(xx + range, y)) { tfoo->x = xx + range; tfoo++->y = y; if (tfoo == &foo[15]) goto foofull; } range++; } while (tfoo == foo); foofull: return (foo[rn2(tfoo - foo)]); }
struct coord enexto(int xx, int yy) { int8_t x, y; struct coord foo[15], *tfoo; int range; tfoo = foo; range = 1; do { // full kludge action. for (x = xx - range; x <= xx + range; ++x) if (goodpos(x, yy - range)) { tfoo->x = x; tfoo++->y = yy - range; if (tfoo == &foo[15]) goto foofull; } for (x = xx - range; x <= xx + range; ++x) if (goodpos(x, yy + range)) { tfoo->x = x; tfoo++->y = yy + range; if (tfoo == &foo[15]) goto foofull; } for (y = yy + 1 - range; y < yy + range; ++y) if (goodpos(xx - range, y)) { tfoo->x = xx - range; tfoo++->y = y; if (tfoo == &foo[15]) goto foofull; } for (y = yy + 1 - range; y < yy + range; ++y) if (goodpos(xx + range, y)) { tfoo->x = xx + range; tfoo++->y = y; if (tfoo == &foo[15]) goto foofull; } ++range; } while (tfoo == foo); foofull: return foo[rn2(tfoo - foo)]; }
void rloc(struct monst *mtmp) { int tx, ty; do { tx = rn1(COLNO - 3, 2); ty = rn2(ROWNO); } while (!goodpos(tx, ty)); mtmp->mx = tx; mtmp->my = ty; pmon(mtmp); }
static void mvault_tele(struct monst *mtmp) { struct mkroom *croom = search_special(level, VAULT); coord c; if (croom && somexy(level, croom, &c) && goodpos(level, c.x, c.y, mtmp, 0)) { rloc_to(mtmp, c.x, c.y); return; } rloc(mtmp, FALSE); }
/* * place_worm_tail_randomly() * * Place a worm tail somewhere on a level behind the head. * This routine essentially reverses the order of the wsegs from head * to tail while placing them. * x, and y are most likely the worm->mx, and worm->my, but don't *need* to * be, if somehow the head is disjoint from the tail. */ void place_worm_tail_randomly(struct monst *worm, xchar x, xchar y, enum rng rng) { int wnum = worm->wormno; struct level *lev = worm->dlevel; struct wseg *curr = lev->wtails[wnum]; struct wseg *new_tail; xchar ox = x, oy = y; /* if (!wnum) return; bullet proofing */ if (wnum && (!lev->wtails[wnum] || !lev->wheads[wnum])) { impossible("place_worm_tail_randomly: wormno is set without a tail!"); return; } lev->wheads[wnum] = new_tail = curr; curr = curr->nseg; new_tail->nseg = NULL; new_tail->wx = x; new_tail->wy = y; while (curr) { xchar nx, ny; char tryct = 0; /* pick a random direction from x, y and search for goodpos() */ do { random_dir(ox, oy, &nx, &ny, rng); } while (!goodpos(lev, nx, ny, worm, 0) && (tryct++ < 50)); if (tryct < 50) { place_worm_seg(worm, nx, ny); curr->wx = ox = nx; curr->wy = oy = ny; lev->wtails[wnum] = curr; curr = curr->nseg; lev->wtails[wnum]->nseg = new_tail; new_tail = lev->wtails[wnum]; if (lev == level) newsym(nx, ny); } else { /* Oops. Truncate because there was */ toss_wsegs(lev, curr, FALSE); /* no place for the rest of it */ curr = NULL; } } }
/* check whether monster can arrive at location <x,y> via Tport (or fall) */ static boolean rloc_pos_ok(int x, int y, /* coordinates of candidate location */ struct monst *mtmp) { int xx, yy; struct level *mdl = mtmp->dlevel; if (!goodpos(mdl, x, y, mtmp, 0)) return FALSE; /* * Check for restricted areas present in some special levels. * * `xx' is current column; if 0, then `yy' will contain flag bits * rather than row: bit #0 set => moving upwards; bit #1 set => * inside the Wizard's tower. */ xx = mtmp->mx; yy = mtmp->my; if (!xx) { /* no current location (migrating monster arrival) */ if (mdl->dndest.nlx && On_W_tower_level(m_mz(mtmp))) return ((yy & 2) != 0) ^ /* inside xor not within */ !within_bounded_area(x, y, mdl->dndest.nlx, mdl->dndest.nly, mdl->dndest.nhx, mdl->dndest.nhy); if (mdl->updest.lx && (yy & 1) != COLNO) /* moving up */ return (within_bounded_area (x, y, mdl->updest.lx, mdl->updest.ly, mdl->updest.hx, mdl->updest.hy) && (!mdl->updest.nlx || !within_bounded_area( x, y, mdl->updest.nlx, mdl->updest.nly, mdl->updest.nhx, mdl->updest.nhy))); if (mdl->dndest.lx && (yy & 1) == COLNO) /* moving down */ return (within_bounded_area (x, y, mdl->dndest.lx, mdl->dndest.ly, mdl->dndest.hx, mdl->dndest.hy) && (!mdl->dndest.nlx || !within_bounded_area( x, y, mdl->dndest.nlx, mdl->dndest.nly, mdl->dndest.nhx, mdl->dndest.nhy))); } else { /* current location is <xx,yy> */ if (!tele_jump_ok(mdl, xx, yy, x, y)) return FALSE; } /* <x,y> is ok */ return TRUE; }
static void rloco(struct obj *obj) { int tx,ty,otx,oty; otx = obj->ox; oty = obj->oy; do { tx = rn1(COLNO-3,2); ty = rn2(ROWNO); } while(!goodpos(tx,ty)); obj->ox = tx; obj->oy = ty; if(cansee(otx,oty)) newsym(otx,oty); }
void rloco(struct obj *obj) { xchar tx, ty, otx, oty; boolean restricted_fall; int try_limit = 4000; if (obj->otyp == CORPSE && is_rider(&mons[obj->corpsenm])) { if (revive_corpse(obj)) return; } obj_extract_self(obj); otx = obj->ox; oty = obj->oy; restricted_fall = (otx == 0 && level->dndest.lx); do { tx = rn1(COLNO-3,2); ty = rn2(ROWNO); if (!--try_limit) break; } while (!goodpos(level, tx, ty, NULL, 0) || /* bug: this lacks provision for handling the Wizard's tower */ (restricted_fall && (!within_bounded_area(tx, ty, level->dndest.lx, level->dndest.ly, level->dndest.hx, level->dndest.hy) || (level->dndest.nlx && within_bounded_area(tx, ty, level->dndest.nlx, level->dndest.nly, level->dndest.nhx, level->dndest.nhy))))); if (flooreffects(obj, tx, ty, "fall")) { return; } else if (otx == 0 && oty == 0) { ; /* fell through a trap door; no update of old loc needed */ } else { if (costly_spot(otx, oty) && (!costly_spot(tx, ty) || !strchr(in_rooms(level, tx, ty, 0), *in_rooms(level, otx, oty, 0)))) { if (costly_spot(u.ux, u.uy) && strchr(u.urooms, *in_rooms(level, otx, oty, 0))) addtobill(obj, FALSE, FALSE, FALSE); else stolen_value(obj, otx, oty, FALSE, FALSE); } newsym(otx, oty); /* update old location */ } place_object(obj, level, tx, ty); newsym(tx, ty); }
void rloc(struct monst *mtmp) { int tx; int ty; char ch = mtmp->data->mlet; #ifndef NOWORM if((ch == 'w') && (mtmp->mx)) { /* Do not relocate worms */ return; } #endif tx = rn1(COLNO - 3, 2); ty = rn2(ROWNO); while(goodpos(tx, ty) == 0) { tx = rn1(COLNO - 3, 2); ty = rn2(ROWNO); } mtmp->mx = tx; mtmp->my = ty; if(u.ustuck == mtmp) { if(u.uswallow != 0) { u.ux = tx; u.uy = ty; docrt(); } else { u.ustuck = 0; } } pmon(mtmp); }
/* return TRUE if successful, FALSE if not */ boolean rloc(struct monst *mtmp, /* mx==COLNO implies migrating monster arrival */ boolean suppress_impossible) { int x, y, trycount; int relaxed_goodpos; if (mtmp == u.usteed) { tele(); return TRUE; } if (!(mtmp->dlevel)) panic("trying to teleport monster onto which level?"); struct level *mdl = mtmp->dlevel; if (mtmp->iswiz && mtmp->mx != COLNO && mdl == level) { /* Wizard, not just arriving */ if (!In_W_tower(u.ux, u.uy, &u.uz)) x = mdl->upstair.sx, y = mdl->upstair.sy; else if (!isok(mdl->dnladder.sx, mdl->dnladder.sy)) x = mdl->upladder.sx, y = mdl->upladder.sy;/* bottom of tower */ else x = mdl->dnladder.sx, y = mdl->dnladder.sy; /* if the wiz teleports away to heal, try the up staircase, to block the player's escaping before he's healed (deliberately use `goodpos' rather than `rloc_pos_ok' here) */ if (goodpos(mdl, x, y, mtmp, 0)) goto found_xy; } for (relaxed_goodpos = 0; relaxed_goodpos < 2; relaxed_goodpos++) { /* first try sensible terrain; if none exists, ignore water, doors and boulders */ int gpflags = relaxed_goodpos ? MM_IGNOREWATER | MM_IGNOREDOORS : 0; /* try several pairs of positions; try the more restrictive rloc_pos_ok before we use the less restrictive goodpos */ trycount = 0; do { x = rn2(COLNO); y = rn2(ROWNO); if ((trycount < 500) ? rloc_pos_ok(x, y, mtmp) : goodpos(mdl, x, y, mtmp, gpflags)) goto found_xy; } while (++trycount < 1000); /* try every square on the mdl as a fallback */ for (x = 0; x < COLNO; x++) for (y = 0; y < ROWNO; y++) if (goodpos(mdl, x, y, mtmp, gpflags)) goto found_xy; } /* level either full of monsters or somehow faulty */ if (!suppress_impossible) impossible("rloc(): couldn't relocate monster"); return FALSE; found_xy: rloc_to(mtmp, x, y); return TRUE; }
boolean enexto_core(coord * cc, struct level *lev, xchar xx, xchar yy, const struct permonst *mdat, unsigned entflags) { #define MAX_GOOD 15 coord good[MAX_GOOD], *good_ptr; int x, y, range, i; int xmin, xmax, ymin, ymax; struct monst fakemon = zeromonst; /* dummy monster */ if (!mdat) { /* default to player's original monster type */ mdat = &mons[u.umonster]; } fakemon.data = mdat; /* set up for goodpos */ good_ptr = good; range = 1; /* * Walk around the border of the square with center (xx,yy) and * radius range. Stop when we find at least one valid position. */ do { xmin = max(0, xx - range); xmax = min(COLNO - 1, xx + range); ymin = max(0, yy - range); ymax = min(ROWNO - 1, yy + range); for (x = xmin; x <= xmax; x++) if (goodpos(lev, x, ymin, &fakemon, entflags)) { good_ptr->x = x; good_ptr->y = ymin; /* beware of accessing beyond segment boundaries.. */ if (good_ptr++ == &good[MAX_GOOD - 1]) goto full; } for (x = xmin; x <= xmax; x++) if (goodpos(lev, x, ymax, &fakemon, entflags)) { good_ptr->x = x; good_ptr->y = ymax; /* beware of accessing beyond segment boundaries.. */ if (good_ptr++ == &good[MAX_GOOD - 1]) goto full; } for (y = ymin + 1; y < ymax; y++) if (goodpos(lev, xmin, y, &fakemon, entflags)) { good_ptr->x = xmin; good_ptr->y = y; /* beware of accessing beyond segment boundaries.. */ if (good_ptr++ == &good[MAX_GOOD - 1]) goto full; } for (y = ymin + 1; y < ymax; y++) if (goodpos(lev, xmax, y, &fakemon, entflags)) { good_ptr->x = xmax; good_ptr->y = y; /* beware of accessing beyond segment boundaries.. */ if (good_ptr++ == &good[MAX_GOOD - 1]) goto full; } range++; /* return if we've grown too big (nothing is valid) */ if (range > ROWNO && range > COLNO) return FALSE; } while (good_ptr == good); full: i = rn2((int)(good_ptr - good)); cc->x = good[i].x; cc->y = good[i].y; return TRUE; }
/* return TRUE if successful, FALSE if not */ boolean rloc(struct monst *mtmp, /* mx==COLNO implies migrating monster arrival */ boolean suppress_impossible) { int x, y, trycount; int relaxed_goodpos; if (mtmp == u.usteed) { tele(); return TRUE; } if (mtmp->iswiz && mtmp->mx != COLNO) { /* Wizard, not just arriving */ if (!In_W_tower(u.ux, u.uy, &u.uz)) x = level->upstair.sx, y = level->upstair.sy; else if (!isok(level->dnladder.sx, level->dnladder.sy)) x = level->upladder.sx, y = level->upladder.sy;/* bottom of tower */ else x = level->dnladder.sx, y = level->dnladder.sy; /* if the wiz teleports away to heal, try the up staircase, to block the player's escaping before he's healed (deliberately use `goodpos' rather than `rloc_pos_ok' here) */ if (goodpos(level, x, y, mtmp, 0)) goto found_xy; } for (relaxed_goodpos = -1; relaxed_goodpos < 2; relaxed_goodpos++) { /* If this is a monster that blinks, try to do that first. */ if (relaxed_goodpos < 0) { if ((isok(mtmp->mx, mtmp->my)) && mtmp->data->mflags3 & M3_BLINKAWAY) { /* We're going to do a polar-to-rectangular conversion here, because it's a convenient way to select positions at the correct distance from where we're starting. We'll try with the maximum radius then back it off. */ int maxradius = 2 * mtmp->data->mlevel; int minradius = 2; int theta[24] = { 0, 15, 30, 45, 60, 75, 90, 105, 120, 135, 150, 165, 180, 195, 210, 225, 240, 255, 270, 285, 300, 315, 330, 345 }; int angle, fineangle, swi, sw; coord rectcoord; if (maxradius < minradius + 3) maxradius = minradius + 3; /* Shuffle the order of the angles so we don't always get the same one tried first. */ for (angle = 0; angle < 24; angle++) { swi = rn2(24); sw = theta[swi]; theta[swi] = theta[angle]; theta[angle] = sw; } for (trycount = maxradius; trycount >= minradius; trycount--) { for (angle = 0; angle < 24; angle++) for (fineangle = 0; fineangle < 15; fineangle += 3) { /* theta is shuffled so that the angle isn't the same all the time, but it isn't necessary to shuffle over a hundred different angles; we use fineangle to allow positions that don't line up to the 15-degree increments, but the randomness of the blink direction doesn't need that much precision. */ rectcoord = polartorect(trycount, theta[angle] + fineangle); x = mtmp->mx + rectcoord.x; y = mtmp->my + rectcoord.y; if (isok(x,y) && !m_at(level,x,y) && /* TODO: evaluate whether goodpos() should be * used here */ (level->locations[x][y].typ >= CORR) && /* Blinking only works with line-of-sight, but for now I am not requiring the monster to actually _see_ the tile, so e.g. blinking into the dark works ok. */ clear_path(mtmp->mx, mtmp->my, x, y, viz_array) ) { goto found_xy; } } } } continue; } /* first try sensible terrain; if none exists, ignore water, doors and boulders */ int gpflags = relaxed_goodpos ? MM_IGNOREWATER | MM_IGNOREDOORS : 0; /* try several pairs of positions; try the more restrictive rloc_pos_ok before we use the less restrictive goodpos */ trycount = 0; do { x = rn2(COLNO); y = rn2(ROWNO); if ((trycount < 500) ? rloc_pos_ok(x, y, mtmp) : goodpos(level, x, y, mtmp, gpflags)) goto found_xy; } while (++trycount < 1000); /* try every square on the level as a fallback */ for (x = 0; x < COLNO; x++) for (y = 0; y < ROWNO; y++) if (goodpos(level, x, y, mtmp, gpflags)) goto found_xy; } /* level either full of monsters or somehow faulty */ if (!suppress_impossible) impossible("rloc(): couldn't relocate monster"); return FALSE; found_xy: rloc_to(mtmp, x, y); return TRUE; }
/* exclusively for mktemple(); uses level creation RNG */ void priestini(struct level *lev, struct mkroom *sroom, int sx, int sy, boolean sanctum) { /* is it the seat of the high priest? */ struct monst *priest = NULL; struct obj *otmp; int cnt; coord *priest_pos, pos_array[] = { { sx + 1, sy }, { sx - 1, sy }, { sx, sy + 1 }, { sx, sy - 1 }, { sx, sy }, { COLNO, ROWNO }, }; /* Search for a good position for the priest. The -1 in the array bound is * to ensure that we stop on the { COLNO, ROWNO } entry which is not ok. Do * not pass a monster to goodpos(), because we will move any monster later. */ for (priest_pos = pos_array; !goodpos(lev, priest_pos->x, priest_pos->y, NULL, 0) && (priest_pos < pos_array + ARRAY_SIZE(pos_array) - 1); ++priest_pos) {} if (!isok(priest_pos->x, priest_pos->y)) { impossible("Unable to find location for priest in shrine"); } else { if (MON_AT(lev, priest_pos->x, priest_pos->y)) rloc(m_at(lev, priest_pos->x, priest_pos->y), FALSE); priest = makemon(&mons[sanctum ? PM_HIGH_PRIEST : PM_ALIGNED_PRIEST], lev, priest_pos->x, priest_pos->y, MM_ALLLEVRNG); } if (priest) { EPRI(priest)->shroom = (sroom - lev->rooms) + ROOMOFFSET; EPRI(priest)->shralign = Amask2align(lev->locations[sx][sy].altarmask); EPRI(priest)->shrpos.x = sx; EPRI(priest)->shrpos.y = sy; assign_level(&(EPRI(priest)->shrlevel), &lev->z); priest->mtrapseen = ~0; /* traps are known */ priest->mpeaceful = 1; priest->ispriest = 1; priest->msleeping = 0; set_malign(priest); /* mpeaceful may have changed */ /* now his/her goodies... */ if (sanctum && CONST_EPRI(priest)->shralign == A_NONE && on_level(&sanctum_level, &lev->z)) { mongets(priest, AMULET_OF_YENDOR, rng_for_level(&lev->z)); } /* 2 to 4 spellbooks */ for (cnt = rn1(3, 2); cnt > 0; --cnt) { mpickobj(priest, mkobj(level, SPBOOK_CLASS, FALSE, rng_for_level(&lev->z))); } /* robe [via makemon()] */ if (mklev_rn2(2, lev) && (otmp = which_armor(priest, os_armc)) != 0) { if (p_coaligned(priest)) uncurse(otmp); else curse(otmp); } } }