void read_scroll(void) { short ch; object *obj; char msg[DCOLS]; if(blind) { message("You can't see to read the scroll.",0); return; } ch = pack_letter("Read what?", SCROLL); if (ch == ROGUE_KEY_CANCEL) { return; } if (!(obj = get_letter_object(ch))) { message("No such item.", 0); return; } if (obj->what_is != SCROLL) { message("You can't read that!", 0); return; } switch(obj->which_kind) { case SCARE_MONSTER: message("You hear a maniacal laughter in the distance.", 0); break; case HOLD_MONSTER: hold_monster(); break; case ENCH_WEAPON: if (rogue.weapon) { if (rogue.weapon->what_is == WEAPON) { sprintf(msg, "Your %sglow%s %sfor a moment.", name_of(rogue.weapon), ((rogue.weapon->quantity <= 1) ? "s" : ""), get_ench_color()); message(msg, 0); if (coin_toss()) { rogue.weapon->hit_enchant++; } else { rogue.weapon->d_enchant++; } } rogue.weapon->is_cursed = 0; } else { message("Your hands tingle.", 0); } break; case ENCH_ARMOR: if (rogue.armor) { sprintf(msg, "Your armor glows %sfor a moment.", get_ench_color()); message(msg, 0); rogue.armor->d_enchant++; rogue.armor->is_cursed = 0; print_stats(STAT_ARMOR); } else { message("Your skin crawls.", 0); } break; case IDENTIFY: message("This is a scroll of identify.", 0); obj->identified = 1; id_scrolls[obj->which_kind].id_status = IDENTIFIED; identify_item(0) ; break; case TELEPORT: tele(); /* (zerogue 0.4.0) The first time a rogue uses this scroll, * he is briefly confused. */ if( ! obj->identified && id_scrolls[obj->which_kind].id_status != IDENTIFIED ) confused += get_rand(0,5) ; break; case SLEEP: sleepify(obj) ; break ; case PROTECT_ARMOR: if (rogue.armor) { message("Your armor is covered by a shimmering gold shield.", 0); rogue.armor->is_protected = 1; rogue.armor->is_cursed = 0; } else { message("Your acne seems to have disappeared.", 0); } break; case REMOVE_CURSE: message((!halluc) ? "You feel as though someone is watching over you." : "You feel in touch with the universal oneness.", 0); uncurse_all(); break; case CREATE_MONSTER: /* (zerogue 0.4.0) A summoned monster is briefly confused. */ create_monster(1) ; break; case AGGRAVATE_MONSTER: aggravate(); break; case MAGIC_MAPPING: message("This scroll seems to have a map on it.", 0); draw_magic_map(); break; } if (id_scrolls[obj->which_kind].id_status != CALLED) { id_scrolls[obj->which_kind].id_status = IDENTIFIED; } vanish(obj, (obj->which_kind != SLEEP), &rogue.pack); }
int dosit() { static const char sit_message[] = "sit on the %s."; register struct trap *trap; register int typ = levl[u.ux][u.uy].typ; #ifdef STEED if (u.usteed) { You("are already sitting on %s.", mon_nam(u.usteed)); return (0); } #endif if(!can_reach_floor()) { if (Levitation) You("tumble in place."); else You("are sitting on air."); return 0; } else if (is_pool(u.ux, u.uy) && !Underwater) { /* water walking */ goto in_water; } if(OBJ_AT(u.ux, u.uy)) { register struct obj *obj; obj = level.objects[u.ux][u.uy]; You("sit on %s.", the(xname(obj))); if (!(Is_box(obj) || objects[obj->otyp].oc_material == CLOTH)) pline("It's not very comfortable..."); } else if ((trap = t_at(u.ux, u.uy)) != 0 || (u.utrap && (u.utraptype >= TT_LAVA))) { if (u.utrap) { exercise(A_WIS, FALSE); /* you're getting stuck longer */ if(u.utraptype == TT_BEARTRAP) { You_cant("sit down with your %s in the bear trap.", body_part(FOOT)); u.utrap++; } else if(u.utraptype == TT_PIT) { if(trap->ttyp == SPIKED_PIT) { You("sit down on a spike. Ouch!"); losehp(1, "sitting on an iron spike", KILLED_BY); exercise(A_STR, FALSE); } else You("sit down in the pit."); u.utrap += rn2(5); } else if(u.utraptype == TT_WEB) { You("sit in the spider web and get entangled further!"); u.utrap += rn1(10, 5); } else if(u.utraptype == TT_LAVA) { /* Must have fire resistance or they'd be dead already */ You("sit in the lava!"); u.utrap += rnd(4); losehp(d(2,10), "sitting in lava", KILLED_BY); } else if(u.utraptype == TT_INFLOOR) { You_cant("maneuver to sit!"); u.utrap++; } } else { You("sit down."); dotrap(trap, 0); } } else if(Underwater || Is_waterlevel(&u.uz)) { if (Is_waterlevel(&u.uz)) There("are no cushions floating nearby."); else You("sit down on the muddy bottom."); } else if(is_pool(u.ux, u.uy)) { in_water: You("sit in the water."); if (!rn2(10) && uarm) (void) rust_dmg(uarm, "armor", 1, TRUE, &youmonst); if (!rn2(10) && uarmf && uarmf->otyp != WATER_WALKING_BOOTS) (void) rust_dmg(uarm, "armor", 1, TRUE, &youmonst); #ifdef SINKS } else if(IS_SINK(typ)) { You(sit_message, defsyms[S_sink].explanation); Your("%s gets wet.", humanoid(youmonst.data) ? "rump" : "underside"); #endif } else if(IS_ALTAR(typ)) { You(sit_message, defsyms[S_altar].explanation); altar_wrath(u.ux, u.uy); } else if(IS_GRAVE(typ)) { You(sit_message, defsyms[S_grave].explanation); } else if(typ == STAIRS) { You(sit_message, "stairs"); } else if(typ == LADDER) { You(sit_message, "ladder"); } else if (is_lava(u.ux, u.uy)) { /* must be WWalking */ You(sit_message, "lava"); burn_away_slime(); if (likes_lava(youmonst.data)) { pline_The("lava feels warm."); return 1; } pline_The("lava burns you!"); losehp(d((Fire_resistance ? 2 : 10), 10), "sitting on lava", KILLED_BY); } else if (is_ice(u.ux, u.uy)) { You(sit_message, defsyms[S_ice].explanation); if (!Cold_resistance) pline_The("ice feels cold."); } else if (typ == DRAWBRIDGE_DOWN) { You(sit_message, "drawbridge"); } else if(IS_THRONE(typ)) { You(sit_message, defsyms[S_throne].explanation); if (rnd(6) > 4) { switch (rnd(13)) { case 1: (void) adjattrib(rn2(A_MAX), -rn1(4,3), FALSE); losehp(rnd(10), "cursed throne", KILLED_BY_AN); break; case 2: (void) adjattrib(rn2(A_MAX), 1, FALSE); break; case 3: pline("A%s electric shock shoots through your body!", (Shock_resistance) ? "n" : " massive"); losehp(Shock_resistance ? rnd(6) : rnd(30), "electric chair", KILLED_BY_AN); exercise(A_CON, FALSE); break; case 4: You_feel("much, much better!"); if (Upolyd) { if (u.mh >= (u.mhmax - 5)) u.mhmax += 4; u.mh = u.mhmax; } if(u.uhp >= (u.uhpmax - 5)) u.uhpmax += 4; u.uhp = u.uhpmax; make_blinded(0L,TRUE); make_sick(0L, (char *) 0, FALSE, SICK_ALL); heal_legs(); flags.botl = 1; break; case 5: take_gold(); break; case 6: if(u.uluck + rn2(5) < 0) { You_feel("your luck is changing."); change_luck(1); } else makewish(); break; case 7: { register int cnt = rnd(10); pline("A voice echoes:"); verbalize("Thy audience hath been summoned, %s!", flags.female ? "Dame" : "Sire"); while(cnt--) (void) makemon(courtmon(), u.ux, u.uy, NO_MM_FLAGS); break; } case 8: case 9: pline("A voice echoes:"); verbalize("A curse upon thee for sitting upon this most holy throne!"); if (Luck > 0) { make_blinded(Blinded + rn1(100,250),TRUE); } else rndcurse(); break; case 10: if (Luck < 0 || (HSee_invisible & INTRINSIC)) { if (level.flags.nommap) { pline( "A terrible drone fills your head!"); make_confused(HConfusion + rnd(30), FALSE); } else { pline("An image forms in your mind."); do_mapping(); } } else { Your("vision becomes clear."); HSee_invisible |= FROMOUTSIDE; newsym(u.ux, u.uy); } break; case 11: if (Luck < 0) { You_feel("threatened."); aggravate(); } else { You_feel("a wrenching sensation."); tele(); /* teleport him */ } break; case 12: You("are granted an insight!"); if (invent) { /* rn2(5) agrees w/seffects() */ identify_pack(rn2(5)); } break; case 13: Your("mind turns into a pretzel!"); make_confused(HConfusion + rn1(7,16),FALSE); break; default: impossible("throne effect"); break; } } else { if (is_prince(youmonst.data)) You_feel("very comfortable here."); else You_feel("somehow out of place..."); } if (!rn2(3) && IS_THRONE(levl[u.ux][u.uy].typ)) { /* may have teleported */ levl[u.ux][u.uy].typ = ROOM; pline_The("throne vanishes in a puff of logic."); newsym(u.ux,u.uy); } } else if (lays_eggs(youmonst.data)) { struct obj *uegg; if (!flags.female) { pline("Males can't lay eggs!"); return 0; } if (u.uhunger < (int)objects[EGG].oc_nutrition) { You("don't have enough energy to lay an egg."); return 0; } uegg = mksobj(EGG, FALSE, FALSE); uegg->spe = 1; uegg->quan = 1; uegg->owt = weight(uegg); uegg->corpsenm = egg_type_from_parent(u.umonnum, FALSE); uegg->known = uegg->dknown = 1; attach_egg_hatch_timeout(uegg); You("lay an egg."); dropy(uegg); stackobj(uegg); morehungry((int)objects[EGG].oc_nutrition); } else if (u.uswallow) There("are no seats in here!"); else pline("Having fun sitting on the %s?", surface(u.ux,u.uy)); return(1); }
void* WorldBuilder::unpack(void* buf) { // unpack world database from network transfer // read style header uint16_t code, len; buf = nboUnpackUShort(buf, len); buf = nboUnpackUShort(buf, code); if (code != WorldCodeHeader) return NULL; // read style uint16_t gameStyle, maxPlayers, maxShots, maxFlags,serverMapVersion; buf = nboUnpackUShort(buf, serverMapVersion); if (serverMapVersion != mapVersion) return NULL; float worldSize; buf = nboUnpackFloat(buf, worldSize); BZDB.set(StateDatabase::BZDB_WORLDSIZE, string_util::format("%f", worldSize)); buf = nboUnpackUShort(buf, gameStyle); setGameStyle(short(gameStyle)); buf = nboUnpackUShort(buf, maxPlayers); setMaxPlayers(int(maxPlayers)); buf = nboUnpackUShort(buf, maxShots); setMaxShots(int(maxShots)); buf = nboUnpackUShort(buf, maxFlags); setMaxFlags(int(maxFlags)); buf = nboUnpackFloat(buf, world->linearAcceleration); buf = nboUnpackFloat(buf, world->angularAcceleration); uint16_t shakeTimeout = 0, shakeWins; buf = nboUnpackUShort(buf, shakeTimeout); setShakeTimeout(0.1f * float(shakeTimeout)); buf = nboUnpackUShort(buf, shakeWins); setShakeWins(shakeWins); uint32_t epochOffset; buf = nboUnpackUInt(buf, epochOffset); setEpochOffset(epochOffset); // read geometry buf = nboUnpackUShort(buf, len); buf = nboUnpackUShort(buf, code); while (code != WorldCodeEnd) { switch (code) { case WorldCodeBox: { float data[7]; unsigned char tempflags; if (len != WorldCodeBoxSize) return NULL; memset(data, 0, sizeof(float) * 7); buf = nboUnpackFloat(buf, data[0]); buf = nboUnpackFloat(buf, data[1]); buf = nboUnpackFloat(buf, data[2]); buf = nboUnpackFloat(buf, data[3]); buf = nboUnpackFloat(buf, data[4]); buf = nboUnpackFloat(buf, data[5]); buf = nboUnpackFloat(buf, data[6]); buf = nboUnpackUByte(buf, tempflags); BoxBuilding box(data, data[3], data[4], data[5], data[6], (tempflags & _DRIVE_THRU)!=0, (tempflags & _SHOOT_THRU)!=0); append(box); break; } case WorldCodePyramid: { float data[7]; unsigned char tempflags; if (len != WorldCodePyramidSize) return NULL; buf = nboUnpackFloat(buf, data[0]); buf = nboUnpackFloat(buf, data[1]); buf = nboUnpackFloat(buf, data[2]); buf = nboUnpackFloat(buf, data[3]); buf = nboUnpackFloat(buf, data[4]); buf = nboUnpackFloat(buf, data[5]); buf = nboUnpackFloat(buf, data[6]); buf = nboUnpackUByte(buf, tempflags); PyramidBuilding pyr(data, data[3], data[4], data[5], data[6], (tempflags & _DRIVE_THRU)!=0, (tempflags & _SHOOT_THRU)!=0); if (tempflags & _FLIP_Z) pyr.setZFlip(); append(pyr); break; } case WorldCodeTeleporter: { float data[8]; unsigned char tempflags; if (len != WorldCodeTeleporterSize) return NULL; buf = nboUnpackFloat(buf, data[0]); buf = nboUnpackFloat(buf, data[1]); buf = nboUnpackFloat(buf, data[2]); buf = nboUnpackFloat(buf, data[3]); buf = nboUnpackFloat(buf, data[4]); buf = nboUnpackFloat(buf, data[5]); buf = nboUnpackFloat(buf, data[6]); buf = nboUnpackFloat(buf, data[7]); buf = nboUnpackUByte(buf, tempflags); Teleporter tele(data, data[3], data[4], data[5], data[6],data[7], (tempflags & _DRIVE_THRU)!=0, (tempflags & _SHOOT_THRU)!=0); append(tele); break; } case WorldCodeLink: { uint16_t data[2]; if (len != WorldCodeLinkSize) return NULL; buf = nboUnpackUShort(buf, data[0]); buf = nboUnpackUShort(buf, data[1]); setTeleporterTarget(int(data[0]), int(data[1])); break; } case WorldCodeWall: { float data[6]; if (len != WorldCodeWallSize) return NULL; buf = nboUnpackFloat(buf, data[0]); buf = nboUnpackFloat(buf, data[1]); buf = nboUnpackFloat(buf, data[2]); buf = nboUnpackFloat(buf, data[3]); buf = nboUnpackFloat(buf, data[4]); buf = nboUnpackFloat(buf, data[5]); WallObstacle wall(data, data[3], data[4], data[5]); append(wall); break; } case WorldCodeBase: { uint16_t team; float data[10]; if (len != WorldCodeBaseSize) return NULL; buf = nboUnpackUShort(buf, team); buf = nboUnpackFloat(buf, data[0]); buf = nboUnpackFloat(buf, data[1]); buf = nboUnpackFloat(buf, data[2]); buf = nboUnpackFloat(buf, data[3]); buf = nboUnpackFloat(buf, data[4]); buf = nboUnpackFloat(buf, data[5]); buf = nboUnpackFloat(buf, data[6]); buf = nboUnpackFloat(buf, data[7]); buf = nboUnpackFloat(buf, data[8]); buf = nboUnpackFloat(buf, data[9]); BaseBuilding base(data, data[3], data +4, team); append(base); setBase(TeamColor(team), data, data[3], data[4], data[5], data[6]); break; } case WorldCodeWeapon: { Weapon weapon; uint16_t delays; buf = FlagType::unpack(buf, weapon.type); buf = nboUnpackFloat(buf, weapon.pos[0]); buf = nboUnpackFloat(buf, weapon.pos[1]); buf = nboUnpackFloat(buf, weapon.pos[2]); buf = nboUnpackFloat(buf, weapon.dir); buf = nboUnpackFloat(buf, weapon.initDelay); buf = nboUnpackUShort(buf, delays); uint16_t weapon_len = WorldCodeWeaponSize + (delays * sizeof(float)); if (len != weapon_len) { return NULL; } int i; for (i = 0; i < delays; i++) { float delay; buf = nboUnpackFloat(buf, delay); weapon.delay.push_back(delay); } append(weapon); break; } case WorldCodeZone: { EntryZone zone; uint16_t flags, teams, safety; buf = nboUnpackFloat(buf, zone.pos[0]); buf = nboUnpackFloat(buf, zone.pos[1]); buf = nboUnpackFloat(buf, zone.pos[2]); buf = nboUnpackFloat(buf, zone.size[0]); buf = nboUnpackFloat(buf, zone.size[1]); buf = nboUnpackFloat(buf, zone.size[2]); buf = nboUnpackFloat(buf, zone.rot); buf = nboUnpackUShort(buf, flags); buf = nboUnpackUShort(buf, teams); buf = nboUnpackUShort(buf, safety); uint16_t zone_len = WorldCodeZoneSize; zone_len += FlagType::packSize * flags; zone_len += sizeof(uint16_t) * teams; zone_len += sizeof(uint16_t) * safety; if (len != zone_len) { return NULL; } int i; for (i = 0; i < flags; i++) { FlagType *type; buf = FlagType::unpack (buf, type); zone.flags.push_back(type); } for (i = 0; i < teams; i++) { uint16_t team; buf = nboUnpackUShort(buf, team); zone.teams.push_back((TeamColor)team); } for (i = 0; i < safety; i++) { uint16_t safety; buf = nboUnpackUShort(buf, safety); zone.safety.push_back((TeamColor)safety); } append(zone); break; } default: return NULL; } buf = nboUnpackUShort(buf, len); buf = nboUnpackUShort(buf, code); } return buf; }
void moveloop() { #if defined(MICRO) || defined(WIN32) char ch; int abort_lev; #endif int moveamt = 0, wtcap = 0, change = 0; boolean didmove = FALSE, monscanmove = FALSE; flags.moonphase = phase_of_the_moon(); if(flags.moonphase == FULL_MOON) { /*JP You("are lucky! Full moon tonight."); */ pline("ラッキー!今晩は満月だ。"); change_luck(1); } else if(flags.moonphase == NEW_MOON) { /*JP pline("Be careful! New moon tonight."); */ pline("注意しろ!今晩は新月だ。"); } flags.friday13 = friday_13th(); if (flags.friday13) { /*JP pline("Watch out! Bad things can happen on Friday the 13th."); */ pline("用心しろ!13日の金曜日にはよくないことがある。") ; change_luck(-1); } initrack(); /* Note: these initializers don't do anything except guarantee that we're linked properly. */ decl_init(); monst_init(); monstr_init(); /* monster strengths */ objects_init(); dragons_init(); shop_selection_init(); #ifdef WIZARD if (wizard) add_debug_extended_commands(); #endif (void) encumber_msg(); /* in case they auto-picked up something */ u.uz0.dlevel = u.uz.dlevel; youmonst.movement = NORMAL_SPEED; /* give the hero some movement points */ #ifdef WHEREIS_FILE touch_whereis(); #endif for(;;) { get_nh_event(); #ifdef POSITIONBAR do_positionbar(); #endif didmove = flags.move; if(didmove) { /* actual time passed */ youmonst.movement -= NORMAL_SPEED; do { /* hero can't move this turn loop */ wtcap = encumber_msg(); flags.mon_moving = TRUE; do { monscanmove = movemon(); if (youmonst.movement > NORMAL_SPEED) break; /* it's now your turn */ } while (monscanmove); flags.mon_moving = FALSE; if (!monscanmove && youmonst.movement < NORMAL_SPEED) { /* both you and the monsters are out of steam this round */ /* set up for a new turn */ struct monst *mtmp; mcalcdistress(); /* adjust monsters' trap, blind, etc */ /* reallocate movement rations to monsters */ for (mtmp = fmon; mtmp; mtmp = mtmp->nmon) mtmp->movement += mcalcmove(mtmp); if(!rn2(u.uevent.udemigod ? 25 : (depth(&u.uz) > depth(&stronghold_level)) ? 50 : 70)) (void) makemon((struct permonst *)0, 0, 0, NO_MM_FLAGS); /* calculate how much time passed. */ #ifdef STEED if (u.usteed && u.umoved) { /* your speed doesn't augment steed's speed */ moveamt = mcalcmove(u.usteed); } else #endif { moveamt = youmonst.data->mmove; if (Very_fast) { /* speed boots or potion */ /* average movement is 1.67 times normal */ moveamt += NORMAL_SPEED / 2; if (rn2(3) == 0) moveamt += NORMAL_SPEED / 2; } else if (Fast) { /* average movement is 1.33 times normal */ if (rn2(3) != 0) moveamt += NORMAL_SPEED / 2; } } switch (wtcap) { case UNENCUMBERED: break; case SLT_ENCUMBER: moveamt -= (moveamt / 4); break; case MOD_ENCUMBER: moveamt -= (moveamt / 2); break; case HVY_ENCUMBER: moveamt -= ((moveamt * 3) / 4); break; case EXT_ENCUMBER: moveamt -= ((moveamt * 7) / 8); break; default: break; } youmonst.movement += moveamt; if (youmonst.movement < 0) youmonst.movement = 0; settrack(); monstermoves++; moves++; /********************************/ /* once-per-turn things go here */ /********************************/ if (flags.bypasses) clear_bypasses(); if(Glib) glibr(); nh_timeout(); run_regions(); #ifdef DUNGEON_GROWTH dgn_growths(TRUE, TRUE); #endif if (u.ublesscnt) u.ublesscnt--; if(flags.time && !flags.run) flags.botl = 1; /* One possible result of prayer is healing. Whether or * not you get healed depends on your current hit points. * If you are allowed to regenerate during the prayer, the * end-of-prayer calculation messes up on this. * Another possible result is rehumanization, which requires * that encumbrance and movement rate be recalculated. */ if (u.uinvulnerable) { /* for the moment at least, you're in tiptop shape */ wtcap = UNENCUMBERED; } else if (Upolyd && youmonst.data->mlet == S_EEL && !is_pool(u.ux,u.uy) && !Is_waterlevel(&u.uz)) { if (u.mh > 1) { u.mh--; flags.botl = 1; } else if (u.mh < 1) rehumanize(); } else if (Upolyd && u.mh < u.mhmax) { if (u.mh < 1) rehumanize(); else if (Regeneration || (wtcap < MOD_ENCUMBER && !(moves%20))) { flags.botl = 1; u.mh++; /*JP interrupt_multi("Hit points", u.mh, u.mhmax); */ interrupt_multi("体力", u.mh, u.mhmax); } } else if (u.uhp < u.uhpmax && (wtcap < MOD_ENCUMBER || !u.umoved || Regeneration)) { if (u.ulevel > 9 && !(moves % 3)) { int heal, Con = (int) ACURR(A_CON); if (Con <= 12) { heal = 1; } else { heal = rnd(Con); if (heal > u.ulevel-9) heal = u.ulevel-9; } flags.botl = 1; u.uhp += heal; if(u.uhp > u.uhpmax) u.uhp = u.uhpmax; /*JP interrupt_multi("Hit points", u.uhp, u.uhpmax); */ interrupt_multi("体力", u.uhp, u.uhpmax); } else if (Regeneration || (u.ulevel <= 9 && !(moves % ((MAXULEV+12) / (u.ulevel+2) + 1)))) { flags.botl = 1; u.uhp++; /*JP interrupt_multi("Hit points", u.uhp, u.uhpmax); */ interrupt_multi("体力", u.uhp, u.uhpmax); } } /* moving around while encumbered is hard work */ if (wtcap > MOD_ENCUMBER && u.umoved) { if(!(wtcap < EXT_ENCUMBER ? moves%30 : moves%10)) { if (Upolyd && u.mh > 1) { u.mh--; } else if (!Upolyd && u.uhp > 1) { u.uhp--; } else { /*JP You("pass out from exertion!"); */ pline("疲労で意識を失った!"); exercise(A_CON, FALSE); fall_asleep(-10, FALSE); } } } if ((u.uen < u.uenmax) && ((wtcap < MOD_ENCUMBER && (!(moves%((MAXULEV + 8 - u.ulevel) * (Role_if(PM_WIZARD) ? 3 : 4) / 6)))) || Energy_regeneration)) { u.uen += rn1((int)(ACURR(A_WIS) + ACURR(A_INT)) / 15 + 1,1); if (u.uen > u.uenmax) u.uen = u.uenmax; flags.botl = 1; /*JP interrupt_multi("Magic energy", u.uen, u.uenmax); */ interrupt_multi("魔力", u.uen, u.uenmax); } if(!u.uinvulnerable) { if(Teleportation && !rn2(85)) { xchar old_ux = u.ux, old_uy = u.uy; tele(); if (u.ux != old_ux || u.uy != old_uy) { if (!next_to_u()) { check_leash(old_ux, old_uy); } #ifdef REDO /* clear doagain keystrokes */ pushch(0); savech(0); #endif } } /* delayed change may not be valid anymore */ if ((change == 1 && !Polymorph) || (change == 2 && u.ulycn == NON_PM)) change = 0; if(Polymorph && !rn2(100)) change = 1; else if (u.ulycn >= LOW_PM && !Upolyd && !rn2(80 - (20 * night()))) change = 2; if (change && !Unchanging) { if (multi >= 0) { if (occupation) stop_occupation(); else nomul(0, 0); if (change == 1) polyself(FALSE); else you_were(); change = 0; } } } if(Searching && multi >= 0) (void) dosearch0(1); dosounds(); do_storms(); gethungry(); age_spells(); exerchk(); invault(); if (u.uhave.amulet) amulet(); if (!rn2(40+(int)(ACURR(A_DEX)*3))) u_wipe_engr(rnd(3)); if (u.uevent.udemigod && !u.uinvulnerable) { if (u.udg_cnt) u.udg_cnt--; if (!u.udg_cnt) { intervene(); u.udg_cnt = rn1(200, 50); } } restore_attrib(); /* underwater and waterlevel vision are done here */ if (Is_waterlevel(&u.uz)) movebubbles(); else if (Underwater) under_water(0); /* vision while buried done here */ else if (u.uburied) under_ground(0); /* when immobile, count is in turns */ if(multi < 0) { if (++multi == 0) { /* finished yet? */ unmul((char *)0); /* if unmul caused a level change, take it now */ if (u.utotype) deferred_goto(); } } } } while (youmonst.movement<NORMAL_SPEED); /* hero can't move loop */ /******************************************/ /* once-per-hero-took-time things go here */ /******************************************/ if (u.utrap && u.utraptype == TT_LAVA) { if (!is_lava(u.ux,u.uy)) u.utrap = 0; else if (!u.uinvulnerable) { u.utrap -= 1<<8; if (u.utrap < 1<<8) { killer_format = KILLED_BY; /*JP killer = "molten lava"; */ killer = "どろどろの溶岩で"; /*JP You("sink below the surface and die."); */ You("溶岩に深く沈み、溶けた。"); done(DISSOLVED); } else if (!u.umoved) { /*JP Norep("You sink deeper into the lava."); */ Norep("溶岩に深く沈んだ。"); u.utrap += rnd(4); } } } } /* actual time passed */ /****************************************/ /* once-per-player-input things go here */ /****************************************/ find_ac(); if(!flags.mv || Blind) { /* redo monsters if hallu or wearing a helm of telepathy */ if (Hallucination) { /* update screen randomly */ see_monsters(); see_objects(); see_traps(); if (u.uswallow) swallowed(0); } else if (Unblind_telepat) { see_monsters(); } else if (Warning || Warn_of_mon) see_monsters(); if (vision_full_recalc) vision_recalc(0); /* vision! */ } #ifdef REALTIME_ON_BOTL if(iflags.showrealtime) { /* Update the bottom line if the number of minutes has * changed */ if(get_realtime() / 60 != realtime_data.last_displayed_time / 60) flags.botl = 1; } #endif if(flags.botl || flags.botlx) bot(); flags.move = 1; if(multi >= 0 && occupation) { #if defined(MICRO) || defined(WIN32) abort_lev = 0; if (kbhit()) { if ((ch = Getchar()) == ABORT) abort_lev++; # ifdef REDO else pushch(ch); # endif /* REDO */ } if (!abort_lev && (*occupation)() == 0) #else if ((*occupation)() == 0) #endif occupation = 0; if( #if defined(MICRO) || defined(WIN32) abort_lev || #endif monster_nearby()) { stop_occupation(); reset_eat(); } #if defined(MICRO) || defined(WIN32) if (!(++occtime % 7)) display_nhwindow(WIN_MAP, FALSE); #endif continue; } if ((u.uhave.amulet || Clairvoyant) && !In_endgame(&u.uz) && !BClairvoyant && !(moves % 15) && !rn2(2)) do_vicinity_map(); #ifdef WIZARD if (iflags.sanity_check) sanity_check(); #endif #ifdef CLIPPING /* just before rhack */ cliparound(u.ux, u.uy); #endif u.umoved = FALSE; if (multi > 0) { lookaround(); if (!multi) { /* lookaround may clear multi */ flags.move = 0; if (flags.time) flags.botl = 1; continue; } if (flags.mv) { if(multi < COLNO && !--multi) flags.travel = iflags.travel1 = flags.mv = flags.run = 0; domove(); } else { --multi; rhack(save_cm); } } else if (multi == 0) { #ifdef MAIL ckmailstatus(); #endif maybe_tutorial(); rhack((char *)0); } if (u.utotype) /* change dungeon level */ deferred_goto(); /* after rhack() */ /* !flags.move here: multiple movement command stopped */ else if (flags.time && (!flags.move || !flags.mv)) flags.botl = 1; if (vision_full_recalc) vision_recalc(0); /* vision! */ /* when running in non-tport mode, this gets done through domove() */ if ((!flags.run || iflags.runmode == RUN_TPORT) && (multi && (!flags.travel ? !(multi % 7) : !(moves % 7L)))) { if (flags.time && flags.run) flags.botl = 1; display_nhwindow(WIN_MAP, FALSE); } } }
void do_trap(trap_t *trap) // was dotrap { Short ttype = get_trap_type(trap->trap_info); nomul(0); if (get_trap_seen(trap->trap_info) && !rund(5) && ttype != PIT) { StrPrintF(ScratchBuffer, "You escape a%s.", traps[ttype]); message(ScratchBuffer); } else { trap->trap_info |= SEEN_TRAP; switch(ttype) { case SLP_GAS_TRAP: message("A cloud of gas puts you to sleep!"); nomul(-rnd(25)); break; case BEAR_TRAP: if (Levitation) { message("You float over a bear trap."); break; } you.utrap = 4 + rund(4); you.utraptype = TT_BEARTRAP; message("A bear trap closes on your foot!"); break; case PIERC: deltrap(trap); if (makemon(PM_PIERCER, you.ux, you.uy)) { message("A piercer suddenly drops from the ceiling!"); if (uarmh) message("Its blow glances off your helmet."); else thing_hit_you(3, dice(4,6), "falling piercer"); } break; case ARROW_TRAP: message("An arrow shoots out at you!"); if (!thing_hit_you(8, rnd(6), "arrow")){ mksobj_at(ARROW, you.ux, you.uy); fobj->quantity = 1; } break; case TRAPDOOR: if (!xdnstair) { message("A trap door in the ceiling opens and a rock falls on your head!"); if (uarmh) message("Fortunately, you are wearing a helmet!"); losehp((uarmh ? 2 : dice(2,10)), "falling rock"); mksobj_at(ROCK, you.ux, you.uy); fobj->quantity = 1; stackobj(fobj); if (Invisible) newsym(you.ux, you.uy); } else { Short newlevel = dlevel + 1; while (!rund(4) && newlevel < 29) newlevel++; message("A trap door opens up under you!"); if (Levitation || you.ustuck) { message("For some reason you don't fall in."); break; } goto_level(newlevel, false); } break; case DART_TRAP: message("A little dart shoots out at you!"); if (thing_hit_you(7, rnd(3), "little dart")) { if (!rund(6)) poisoned("dart", "poison dart"); } else { mksobj_at(DART, you.ux, you.uy); fobj->quantity = 1; } break; case TELEP_TRAP: map_mode_teleport = TELE_TRAP; if (get_trap_once(trap->trap_info)) { deltrap(trap); newsym(you.ux,you.uy); vtele(); } else { newsym(you.ux,you.uy); tele(); } break; case PIT: if (Levitation) { message("A pit opens up under you!"); message("You don't fall in!"); break; } message("You fall into a pit!"); you.utrap = rund(6) + 2; you.utraptype = TT_PIT; losehp(rnd(6),"fall into a pit"); selftouch("Falling, you"); break; default: StrPrintF(ScratchBuffer, "BUG: You hit a trap with info=%u", trap->trap_info); message(ScratchBuffer); } } }
static void you_moved(void) { int moveamt = 0, wtcap = 0, change = 0; boolean monscanmove = FALSE; /* Begin turn-tracking for delay_msg. */ if (delay_start == 0) delay_start = moves; /* actual time passed */ youmonst.movement -= NORMAL_SPEED; do { /* hero can't move this turn loop */ wtcap = encumber_msg(); calc_attr_bonus(); flags.mon_moving = TRUE; do { monscanmove = movemon(); if (youmonst.movement > NORMAL_SPEED) break; /* it's now your turn */ } while (monscanmove); flags.mon_moving = FALSE; if (!monscanmove && youmonst.movement < NORMAL_SPEED) { /* both you and the monsters are out of steam this round */ /* set up for a new turn */ struct monst *mtmp; mcalcdistress(); /* adjust monsters' trap, blind, etc */ /* reallocate movement rations to monsters */ for (mtmp = level->monlist; mtmp; mtmp = mtmp->nmon) mtmp->movement += mcalcmove(mtmp); if (!rn2(u.uevent.udemigod ? 25 : (depth(&u.uz) > depth(&stronghold_level)) ? 50 : 70)) makemon(NULL, level, 0, 0, NO_MM_FLAGS); /* calculate how much time passed. */ if (u.usteed && u.umoved) { /* your speed doesn't augment steed's speed */ moveamt = mcalcmove(u.usteed); } else { moveamt = youmonst.data->mmove; if (Very_fast) { /* speed boots or potion */ /* average movement is 1.67 times normal */ moveamt += NORMAL_SPEED / 2; if (rn2(3) == 0) moveamt += NORMAL_SPEED / 2; } else if (Fast) { /* average movement is 1.33 times normal */ if (rn2(3) != 0) moveamt += NORMAL_SPEED / 2; } } switch (wtcap) { case UNENCUMBERED: break; case SLT_ENCUMBER: moveamt -= (moveamt / 4); break; case MOD_ENCUMBER: moveamt -= (moveamt / 2); break; case HVY_ENCUMBER: moveamt -= ((moveamt * 3) / 4); break; case EXT_ENCUMBER: moveamt -= ((moveamt * 7) / 8); break; default: break; } youmonst.movement += moveamt; if (youmonst.movement < 0) youmonst.movement = 0; settrack(); moves++; level->lastmoves = moves; /********************************/ /* once-per-turn things go here */ /********************************/ if (flags.bypasses) clear_bypasses(); if (Glib) glibr(); nh_timeout(); run_regions(level); dgn_growths(level, TRUE, TRUE); if (u.ublesscnt) u.ublesscnt--; iflags.botl = 1; /* One possible result of prayer is healing. Whether or * not you get healed depends on your current hit points. * If you are allowed to regenerate during the prayer, the * end-of-prayer calculation messes up on this. * Another possible result is rehumanization, which requires * that encumbrance and movement rate be recalculated. */ if (u.uinvulnerable) { /* for the moment at least, you're in tiptop shape */ wtcap = UNENCUMBERED; } else if (Upolyd && youmonst.data->mlet == S_EEL && !is_pool(level, u.ux,u.uy) && !Is_waterlevel(&u.uz)) { if (u.mh > 1) { u.mh--; iflags.botl = 1; } else if (u.mh < 1) rehumanize(); } else if (Upolyd && u.mh < u.mhmax) { if (u.mh < 1) rehumanize(); else if (Regeneration || (wtcap < MOD_ENCUMBER && !(moves%20))) { iflags.botl = 1; u.mh++; interrupt_multi("Hit points", u.mh, u.mhmax); } } else if (u.uhp < u.uhpmax && (wtcap < MOD_ENCUMBER || !u.umoved || Regeneration)) { if (u.ulevel > 9 && !(moves % 3)) { int heal, Con = (int) ACURR(A_CON); if (Con <= 12) { heal = 1; } else { heal = rnd(Con); if (heal > u.ulevel-9) heal = u.ulevel-9; } iflags.botl = 1; u.uhp += heal; if (u.uhp > u.uhpmax) u.uhp = u.uhpmax; interrupt_multi("Hit points", u.uhp, u.uhpmax); } else if (Regeneration || (u.ulevel <= 9 && !(moves % ((MAXULEV+12) / (u.ulevel+2) + 1)))) { iflags.botl = 1; u.uhp++; interrupt_multi("Hit points", u.uhp, u.uhpmax); } } /* moving around while encumbered is hard work */ if (wtcap > MOD_ENCUMBER && u.umoved) { if (!(wtcap < EXT_ENCUMBER ? moves%30 : moves%10)) { if (Upolyd && u.mh > 1) { u.mh--; } else if (!Upolyd && u.uhp > 1) { u.uhp--; } else { pline("你用力过度昏倒了!"); exercise(A_CON, FALSE); fall_asleep(-10, FALSE); } } } if ((u.uen < u.uenmax) && ((wtcap < MOD_ENCUMBER && (!(moves%((MAXULEV + 8 - u.ulevel) * (Role_if (PM_WIZARD) ? 3 : 4) / 6)))) || Energy_regeneration)) { u.uen += rn1((int)(ACURR(A_WIS) + ACURR(A_INT)) / 15 + 1,1); if (u.uen > u.uenmax) u.uen = u.uenmax; iflags.botl = 1; interrupt_multi("Magic energy", u.uen, u.uenmax); } if (!u.uinvulnerable) { if (Teleportation && !rn2(85)) { xchar old_ux = u.ux, old_uy = u.uy; tele(); if (u.ux != old_ux || u.uy != old_uy) { if (!next_to_u()) { check_leash(old_ux, old_uy); } } } /* delayed change may not be valid anymore */ if ((change == 1 && !Polymorph) || (change == 2 && u.ulycn == NON_PM)) change = 0; if (Polymorph && !rn2(100)) change = 1; else if (u.ulycn >= LOW_PM && !Upolyd && !rn2(80 - (20 * night()))) change = 2; if (change && !Unchanging) { if (multi >= 0) { if (occupation) stop_occupation(); else nomul(0, NULL); if (change == 1) polyself(FALSE); else you_were(); change = 0; } } } if (Searching && multi >= 0) dosearch0(1); dosounds(); do_storms(); gethungry(); age_spells(); exerchk(); invault(); if (u.uhave.amulet) amulet(); if (!rn2(40+(int)(ACURR(A_DEX)*3))) u_wipe_engr(rnd(3)); if (u.uevent.udemigod && !u.uinvulnerable) { if (u.udg_cnt) u.udg_cnt--; if (!u.udg_cnt) { intervene(); u.udg_cnt = rn1(200, 50); } } restore_attrib(); /* underwater and waterlevel vision are done here */ if (Is_waterlevel(&u.uz)) movebubbles(); else if (Underwater) under_water(0); /* vision while buried done here */ else if (u.uburied) under_ground(0); /* when immobile, count is in turns */ if (multi < 0) { if (++multi == 0) { /* finished yet? */ unmul(NULL); /* if unmul caused a level change, take it now */ if (u.utotype) deferred_goto(); } } } } while (youmonst.movement<NORMAL_SPEED); /* hero can't move loop */ /******************************************/ /* once-per-hero-took-time things go here */ /******************************************/ if (u.utrap && u.utraptype == TT_LAVA) handle_lava_trap(TRUE); if (iflags.hp_notify && prev_hp_notify != uhp()) { pline("%s", hp_notify_format_str(iflags.hp_notify_fmt ? iflags.hp_notify_fmt : "[HP%c%a=%h]")); prev_hp_notify = uhp(); } }