void isc_heap_increased(isc_heap_t *heap, unsigned int index) { REQUIRE(VALID_HEAP(heap)); REQUIRE(index >= 1 && index <= heap->last); float_up(heap, index, heap->array[index]); }
/* * 从 i 开始, 其父节点路径中每个节点的 priority 小于该节点父节点的 priority, 则 TODO */ static void float_up_or_down(struct heap *heap, size_t i) { if (!float_up(heap, i)) { float_down(heap, i); } }
int heap_increased(heap_context ctx, int i) { if (ctx == NULL || i < 1 || i > ctx->heap_size) { errno = EINVAL; return (-1); } float_up(ctx, i, ctx->heap[i]); return (0); }
isc_result_t isc_heap_insert(isc_heap_t *heap, void *elt) { unsigned int i; i = ++heap->last; if (heap->last >= heap->size && !resize(heap)) return (ISC_R_NOMEMORY); float_up(heap, i, elt); return (ISC_R_SUCCESS); }
isc_result_t isc_heap_insert(isc_heap_t *heap, void *elt) { unsigned int new_last; REQUIRE(VALID_HEAP(heap)); new_last = heap->last + 1; RUNTIME_CHECK(new_last > 0); /* overflow check */ if (new_last >= heap->size && !resize(heap)) return (ISC_R_NOMEMORY); heap->last = new_last; float_up(heap, new_last, elt); return (ISC_R_SUCCESS); }
int heap_insert(heap_context ctx, void *elt) { int i; if (ctx == NULL || elt == NULL) { errno = EINVAL; return (-1); } i = ++ctx->heap_size; if (ctx->heap_size >= ctx->array_size && heap_resize(ctx) < 0) return (-1); float_up(ctx, i, elt); return (0); }
void isc_heap_delete(isc_heap_t *heap, unsigned int index) { void *elt; isc_boolean_t less; REQUIRE(index >= 1 && index <= heap->last); if (index == heap->last) { heap->last--; } else { elt = heap->array[heap->last--]; less = heap->compare(elt, heap->array[index]); heap->array[index] = elt; if (less) float_up(heap, index, heap->array[index]); else sink_down(heap, index, heap->array[index]); } }
int heap_delete(heap_context ctx, int i) { void *elt; int less; if (ctx == NULL || i < 1 || i > ctx->heap_size) { errno = EINVAL; return (-1); } if (i == ctx->heap_size) { ctx->heap_size--; } else { elt = ctx->heap[ctx->heap_size--]; less = ctx->higher_priority(elt, ctx->heap[i]); ctx->heap[i] = elt; if (less) float_up(ctx, i, ctx->heap[i]); else sink_down(ctx, i, ctx->heap[i]); } return (0); }
void isc_heap_delete(isc_heap_t *heap, unsigned int idx) { void *elt; isc_boolean_t less; REQUIRE(VALID_HEAP(heap)); REQUIRE(idx >= 1 && idx <= heap->last); if (idx == heap->last) { heap->array[heap->last] = NULL; heap->last--; } else { elt = heap->array[heap->last]; heap->array[heap->last] = NULL; heap->last--; less = heap->compare(elt, heap->array[idx]); heap->array[idx] = elt; if (less) float_up(heap, idx, heap->array[idx]); else sink_down(heap, idx, heap->array[idx]); } }
/* Inserts 'node' into 'heap' with the specified 'priority'. * * This takes time O(lg n). */ void heap_insert(struct heap *heap, struct heap_node *node, uint64_t priority) { heap_raw_insert(heap, node, priority); float_up(heap, node->idx); }
int dowearring(void) { struct obj *otmp; long mask = 0; long oldprop; if (uleft && uright) { pline("There are no more ring-fingers to fill."); return (0); } otmp = getobj("=", "wear"); if (!otmp) return (0); if (otmp->owornmask & W_RING) { pline("You are already wearing that!"); return (0); } if (otmp == uleft || otmp == uright) { pline("You are already wearing that."); return (0); } if (otmp == uwep && uwep->cursed) { pline("%s is welded to your hand.", Doname(uwep)); return (0); } if (uleft) mask = RIGHT_RING; else if (uright) mask = LEFT_RING; else do { char answer; pline("What ring-finger, Right or Left? "); if (strchr(quitchars, (answer = readchar()))) return (0); switch (answer) { case 'l': case 'L': mask = LEFT_RING; break; case 'r': case 'R': mask = RIGHT_RING; break; } } while (!mask); setworn(otmp, mask); if (otmp == uwep) setuwep((struct obj *) 0); oldprop = u.uprops[PROP(otmp->otyp)].p_flgs; u.uprops[PROP(otmp->otyp)].p_flgs |= mask; switch (otmp->otyp) { case RIN_LEVITATION: if (!oldprop) float_up(); break; case RIN_PROTECTION_FROM_SHAPE_CHANGERS: rescham(); break; case RIN_GAIN_STRENGTH: u.ustr += otmp->spe; u.ustrmax += otmp->spe; if (u.ustr > 118) u.ustr = 118; if (u.ustrmax > 118) u.ustrmax = 118; flags.botl = 1; break; case RIN_INCREASE_DAMAGE: u.udaminc += otmp->spe; break; } prinv(otmp); return (1); }
int dodrink() { struct obj *otmp,*objs; struct monst *mtmp; int unkn = 0, nothing = 0; otmp = getobj("!", "drink"); if(!otmp) return(0); if(!strcmp(objects[otmp->otyp].oc_descr, "smoky") && !rn2(13)) { ghost_from_bottle(); goto use_it; } switch(otmp->otyp){ case POT_RESTORE_STRENGTH: unkn++; pline("Wow! This makes you feel great!"); if(u.ustr < u.ustrmax) { u.ustr = u.ustrmax; flags.botl = 1; } break; case POT_BOOZE: unkn++; pline("Ooph! This tastes like liquid fire!"); Confusion += d(3,8); /* the whiskey makes us feel better */ if(u.uhp < u.uhpmax) losehp(-1, "bottle of whiskey"); if(!rn2(4)) { pline("You pass out."); multi = -rnd(15); nomovemsg = "You awake with a headache."; } break; case POT_INVISIBILITY: if(Invis || See_invisible) nothing++; else { if(!Blind) pline("Gee! All of a sudden, you can't see yourself."); else pline("You feel rather airy."), unkn++; newsym(u.ux,u.uy); } Invis += rn1(15,31); break; case POT_FRUIT_JUICE: pline("This tastes like fruit juice."); lesshungry(20); break; case POT_HEALING: pline("You begin to feel better."); flags.botl = 1; u.uhp += rnd(10); if(u.uhp > u.uhpmax) u.uhp = ++u.uhpmax; if(Blind) Blind = 1; /* see on next move */ if(Sick) Sick = 0; break; case POT_PARALYSIS: if(Levitation) pline("You are motionlessly suspended."); else pline("Your feet are frozen to the floor!"); nomul(-(rn1(10,25))); break; case POT_MONSTER_DETECTION: if(!fmon) { strange_feeling(otmp, "You feel threatened."); return(1); } else { cls(); for(mtmp = fmon; mtmp; mtmp = mtmp->nmon) if(mtmp->mx > 0) at(mtmp->mx,mtmp->my,mtmp->data->mlet); prme(); pline("You sense the presence of monsters."); more(); docrt(); } break; case POT_OBJECT_DETECTION: if(!fobj) { strange_feeling(otmp, "You feel a pull downward."); return(1); } else { for(objs = fobj; objs; objs = objs->nobj) if(objs->ox != u.ux || objs->oy != u.uy) goto outobjmap; pline("You sense the presence of objects close nearby."); break; outobjmap: cls(); for(objs = fobj; objs; objs = objs->nobj) at(objs->ox,objs->oy,objs->olet); prme(); pline("You sense the presence of objects."); more(); docrt(); } break; case POT_SICKNESS: pline("Yech! This stuff tastes like poison."); if(Poison_resistance) pline("(But in fact it was biologically contaminated orange juice.)"); losestr(rn1(4,3)); losehp(rnd(10), "contaminated potion"); break; case POT_CONFUSION: if(!Confusion) pline("Huh, What? Where am I?"); else nothing++; Confusion += rn1(7,16); break; case POT_GAIN_STRENGTH: pline("Wow do you feel strong!"); if(u.ustr >= 118) break; /* > 118 is impossible */ if(u.ustr > 17) u.ustr += rnd(118-u.ustr); else u.ustr++; if(u.ustr > u.ustrmax) u.ustrmax = u.ustr; flags.botl = 1; break; case POT_SPEED: if(Wounded_legs) { heal_legs(); unkn++; break; } if(!(Fast & ~INTRINSIC)) pline("You are suddenly moving much faster."); else pline("Your legs get new energy."), unkn++; Fast += rn1(10,100); break; case POT_BLINDNESS: if(!Blind) pline("A cloud of darkness falls upon you."); else nothing++; Blind += rn1(100,250); seeoff(0); break; case POT_GAIN_LEVEL: pluslvl(); break; case POT_EXTRA_HEALING: pline("You feel much better."); flags.botl = 1; u.uhp += d(2,20)+1; if(u.uhp > u.uhpmax) u.uhp = (u.uhpmax += 2); if(Blind) Blind = 1; if(Sick) Sick = 0; break; case POT_LEVITATION: if(!Levitation) float_up(); else nothing++; Levitation += rnd(100); u.uprops[PROP(RIN_LEVITATION)].p_tofn = float_down; break; default: impossible("What a funny potion! (%u)", otmp->otyp); return(0); } if(nothing) { unkn++; pline("You have a peculiar feeling for a moment, then it passes."); } if(otmp->dknown && !objects[otmp->otyp].oc_name_known) { if(!unkn) { objects[otmp->otyp].oc_name_known = 1; more_experienced(0,10); } else if(!objects[otmp->otyp].oc_uname) docall(otmp); } use_it: useup(otmp); return(1); }
static int arti_invoke(struct obj *obj) { const struct artifact *oart = get_artifact(obj); if (!oart || !oart->inv_prop) { if (obj->oclass == WAND_CLASS) return do_break_wand(obj); else if (obj->oclass == GEM_CLASS || obj->oclass == TOOL_CLASS) return dorub(obj); else if (obj->otyp == CRYSTAL_BALL) use_crystal_ball(obj); else pline("Nothing happens."); return 1; } if (oart->inv_prop > LAST_PROP) { /* It's a special power, not "just" a property */ if (obj->age > moves) { /* the artifact is tired :-) */ pline("You feel that %s %s ignoring you.", the(xname(obj)), otense(obj, "are")); /* and just got more so; patience is essential... */ obj->age += (long) dice(3,10); return 1; } obj->age = moves + rnz(100); switch(oart->inv_prop) { case TAMING: { struct obj pseudo; boolean unused_known; pseudo = zeroobj; /* neither cursed nor blessed */ pseudo.otyp = SCR_TAMING; seffects(&pseudo, &unused_known); break; } case HEALING: { int healamt = (u.uhpmax + 1 - u.uhp) / 2; long creamed = (long)u.ucreamed; if (Upolyd) healamt = (u.mhmax + 1 - u.mh) / 2; if (healamt || Sick || Slimed || Blinded > creamed) pline("You feel better."); else goto nothing_special; if (healamt > 0) { if (Upolyd) u.mh += healamt; else u.uhp += healamt; } if (Sick) make_sick(0L,NULL,FALSE,SICK_ALL); if (Slimed) Slimed = 0L; if (Blinded > creamed) make_blinded(creamed, FALSE); iflags.botl = 1; break; } case ENERGY_BOOST: { int epboost = (u.uenmax + 1 - u.uen) / 2; if (epboost > 120) epboost = 120; /* arbitrary */ else if (epboost < 12) epboost = u.uenmax - u.uen; if (epboost) { pline("You feel re-energized."); u.uen += epboost; iflags.botl = 1; } else goto nothing_special; break; } case UNTRAP: { if (!untrap(TRUE)) { obj->age = 0; /* don't charge for changing their mind */ return 0; } break; } case CHARGE_OBJ: { struct obj *otmp = getobj(recharge_type, "charge"); boolean b_effect; if (!otmp) { obj->age = 0; return 0; } b_effect = obj->blessed && (Role_switch == oart->role || !oart->role); recharge(otmp, b_effect ? 1 : obj->cursed ? -1 : 0); update_inventory(); break; } case LEV_TELE: level_tele(); break; case CREATE_PORTAL: { int i, num_ok_dungeons, last_ok_dungeon = 0; d_level newlev; extern int n_dgns; /* from dungeon.c */ struct nh_menuitem *items; items = malloc(n_dgns * sizeof(struct nh_menuitem)); num_ok_dungeons = 0; for (i = 0; i < n_dgns; i++) { if (!dungeons[i].dunlev_ureached) continue; items[num_ok_dungeons].id = i+1; items[num_ok_dungeons].accel = 0; items[num_ok_dungeons].role = MI_NORMAL; items[num_ok_dungeons].selected = FALSE; strcpy(items[num_ok_dungeons].caption, dungeons[i].dname); num_ok_dungeons++; last_ok_dungeon = i; } if (num_ok_dungeons > 1) { /* more than one entry; display menu for choices */ int n; int selected[1]; n = display_menu(items, num_ok_dungeons, "Open a portal to which dungeon?", PICK_ONE, selected); free(items); if (n <= 0) goto nothing_special; i = selected[0] - 1; } else { free(items); i = last_ok_dungeon; /* also first & only OK dungeon */ } /* * i is now index into dungeon structure for the new dungeon. * Find the closest level in the given dungeon, open * a use-once portal to that dungeon and go there. * The closest level is either the entry or dunlev_ureached. */ newlev.dnum = i; if (dungeons[i].depth_start >= depth(&u.uz)) newlev.dlevel = dungeons[i].entry_lev; else newlev.dlevel = dungeons[i].dunlev_ureached; if (u.uhave.amulet || In_endgame(&u.uz) || In_endgame(&newlev) || newlev.dnum == u.uz.dnum) { pline("You feel very disoriented for a moment."); } else { if (!Blind) pline("You are surrounded by a shimmering sphere!"); else pline("You feel weightless for a moment."); goto_level(&newlev, FALSE, FALSE, FALSE); } break; } case ENLIGHTENING: enlightenment(0); break; case CREATE_AMMO: { struct obj *otmp = mksobj(level, ARROW, TRUE, FALSE); if (!otmp) goto nothing_special; otmp->blessed = obj->blessed; otmp->cursed = obj->cursed; otmp->bknown = obj->bknown; if (obj->blessed) { if (otmp->spe < 0) otmp->spe = 0; otmp->quan += rnd(10); } else if (obj->cursed) { if (otmp->spe > 0) otmp->spe = 0; } else otmp->quan += rnd(5); otmp->owt = weight(otmp); hold_another_object(otmp, "Suddenly %s out.", aobjnam(otmp, "fall"), NULL); break; } } } else { long eprop = (u.uprops[oart->inv_prop].extrinsic ^= W_ARTI), iprop = u.uprops[oart->inv_prop].intrinsic; boolean on = (eprop & W_ARTI) != 0; /* true if invoked prop just set */ if (on && obj->age > moves) { /* the artifact is tired :-) */ u.uprops[oart->inv_prop].extrinsic ^= W_ARTI; pline("You feel that %s %s ignoring you.", the(xname(obj)), otense(obj, "are")); /* can't just keep repeatedly trying */ obj->age += (long) dice(3,10); return 1; } else if (!on) { /* when turning off property, determine downtime */ /* arbitrary for now until we can tune this -dlc */ obj->age = moves + rnz(100); } if ((eprop & ~W_ARTI) || iprop) { nothing_special: /* you had the property from some other source too */ if (carried(obj)) pline("You feel a surge of power, but nothing seems to happen."); return 1; } switch(oart->inv_prop) { case CONFLICT: if (on) pline("You feel like a rabble-rouser."); else pline("You feel the tension decrease around you."); break; case LEVITATION: if (on) { float_up(); spoteffects(FALSE); } else float_down(I_SPECIAL|TIMEOUT, W_ARTI); break; case INVIS: if (BInvis || Blind) goto nothing_special; newsym(u.ux, u.uy); if (on) pline("Your body takes on a %s transparency...", Hallucination ? "normal" : "strange"); else pline("Your body seems to unfade..."); break; } } return 1; }
// Note: this is a litte different, it will return true // iff the action is COMPLETE, and false if there was no action OR // the action is needing to finish up (after leaving SenseForm). // So if (do_drink) the caller should exit invform _and_ tick, // otherwise the caller should just exit invform. // (exiting the invform occurs _before_ calling do_drink..) // .. Ok, I've modified this again so that it lets the caller distinguish // between "it worked" and "it worked and I popped up EngraveForm". tri_val_t do_drink(obj_t *otmp) { obj_t *objs; // monst_t *mtmp; Boolean unkn = false, nothing = false, b; Short tmp; if (!otmp) return NO_OP; tmp = oc_descr_offset[otmp->otype]; if (tmp >= 0 && (0 == StrNCompare("smoky", oc_descrs+tmp, 5)) && !rund(13)) { ghost_from_bottle(); useup(otmp); return DONE; } switch(otmp->otype) { case POT_RESTORE_STRENGTH: unkn = true; message("Wow! This makes you feel great!"); if (you.ustr < you.ustrmax) { you.ustr = you.ustrmax; flags.botl |= BOTL_STR; } break; case POT_BOOZE: unkn = true; message("Ooph! This tastes like liquid fire!"); Confusion += dice(3,8); /* the whiskey makes us feel better */ if (you.uhp < you.uhpmax) losehp(-1, "bottle of whiskey"); if (!rund(4)) { tri_val_t t; // Short coma; message("You pass out."); multi = -rnd(15); spin_multi("You awake with a headache."); // coma = rnd(15); // // do { tick(); } while (--coma > 0); // message("You awake with a headache."); // // nomovemsg = "You awake with a headache."; t = finish_do_drink(otmp, nothing, unkn); //.... I guess.... return (t==DONE ? NO_OP : t); // so that we don't take any _more_ turns } break; case POT_INVISIBILITY: if (Invis || See_invisible) nothing = true; else { if (!Blind) message("Gee! All of a sudden, you can't see yourself."); else { message("You feel rather airy."); unkn = true; } newsym(you.ux,you.uy); } Invis += rund(15)+31; break; case POT_FRUIT_JUICE: message("This tastes like fruit juice."); lesshungry(20); break; case POT_HEALING: message("You begin to feel better."); you.uhp += rnd(10); if (you.uhp > you.uhpmax) you.uhp = ++you.uhpmax; if (Blind) Blind = 1; /* you'll see again on the next move */ if (Sick) Sick = 0; flags.botl |= BOTL_HP; break; case POT_PARALYSIS: if (Levitation) message("You are motionlessly suspended."); else message("Your feet are frozen to the floor!"); nomul(-(rund(10)+25)); break; case POT_MONSTER_DETECTION: if (!fmon) { b = strange_feeling(otmp, "You feel threatened."); return ((b) ? GO_ON : DONE); } else { sense_what = SENSE_MONSTERS; sense_by_what = otmp; sense_init_screen(); FrmPopupForm(SenseForm); return GO_ON; // to postpone the tick! } break; case POT_OBJECT_DETECTION: if (!fobj) { b = strange_feeling(otmp, "You feel a pull downward."); return ((b) ? GO_ON : DONE); } else { for (objs = fobj; objs; objs = objs->nobj) if (objs->ox != you.ux || objs->oy != you.uy) { sense_what = SENSE_OBJECTS; sense_by_what = otmp; sense_init_screen(); FrmPopupForm(SenseForm); return GO_ON; // to postpone the tick! } message("You sense the presence of objects close nearby."); break; } break; case POT_SICKNESS: message("Yech! This stuff tastes like poison."); if (Poison_resistance) message("(But in fact it was biologically contaminated orange juice.)"); losestr(rund(4)+3); losehp(rnd(10), "contaminated potion"); flags.botl |= BOTL_STR; break; case POT_CONFUSION: if (!Confusion) message("Huh, What? Where am I?"); else nothing = true; Confusion += rund(7)+16; break; case POT_GAIN_STRENGTH: message("Wow do you feel strong!"); if (you.ustr >= 118) break; /* > 118 is impossible */ if (you.ustr > 17) you.ustr += rnd(118-you.ustr); else you.ustr++; if (you.ustr > you.ustrmax) you.ustrmax = you.ustr; flags.botl |= BOTL_STR; break; case POT_SPEED: if (Wounded_legs) { heal_legs(); unkn = true; break; } if (!(Fast & ~INTRINSIC)) message("You are suddenly moving much faster."); else { message("Your legs get new energy."); unkn = true; } Fast += rund(10)+100; break; case POT_BLINDNESS: if (!Blind) message("A cloud of darkness falls upon you."); else nothing = true; Blind += rund(100)+250; seeoff(false); break; case POT_GAIN_LEVEL: pluslvl(); break; case POT_EXTRA_HEALING: message("You feel much better."); you.uhp += dice(2,20)+1; if (you.uhp > you.uhpmax) you.uhp = (you.uhpmax += 2); if (Blind) Blind = 1; if (Sick) Sick = 0; flags.botl |= BOTL_HP; break; case POT_LEVITATION: if (!Levitation) float_up(); else nothing = true; Levitation += rnd(100); // you.uprops[PROP(RIN_LEVITATION)].p_tofn = float_down; // UNNEEDED, // it has been replaced by tweaking timeout.c to call float_down directly! break; default: StrPrintF(ScratchBuffer, "What a funny potion! (%u)", otmp->otype); message(ScratchBuffer); return NO_OP; } return finish_do_drink(otmp, nothing, unkn); }