memory_block_info compute_memory_block_info(memory_allocations const& alloc, address begin, size const num_bytes) { ASSUMPTION(begin <= std::numeric_limits<address>::max() - num_bytes); ASSUMPTION(num_bytes > 0ULL); // memory_allocations::const_iterator block_begin = alloc.lower_bound(begin); // if (block_begin == alloc.cend() || block_begin->first > begin) // { // block_begin = block_begin == alloc.cbegin() ? block_begin : std::prev(block_begin,1); // if (block_begin == alloc.cend() || block_begin->first > begin || block_begin->first + block_begin->second.num_bytes() <= begin) // return { BOOL3::NO, BOOL3::NO, BOOL3::NO, BOOL3::NO, BOOL3::YES_AND_NO, BOOL3::YES_AND_NO }; // } memory_allocations::const_iterator block_begin; { block_begin = alloc.lower_bound(begin); memory_allocations::const_iterator const prev_block_begin = block_begin == alloc.cbegin() ? alloc.cend() : std::prev(block_begin,1); if (prev_block_begin != alloc.cend() && prev_block_begin->first + prev_block_begin->second.num_bytes() > begin) block_begin = prev_block_begin; } if (block_begin == alloc.cend() || block_begin->first >= begin + num_bytes) return { BOOL3::NO, BOOL3::NO, BOOL3::NO, BOOL3::NO, BOOL3::YES_AND_NO, BOOL3::YES_AND_NO }; address const end = begin + num_bytes; memory_allocations::const_iterator const block_end = alloc.lower_bound(end); INVARIANT(block_begin != block_end); memory_block_info info{block_begin->second}; for ( ; block_begin != block_end && begin < end; ++block_begin) { if (block_begin->first > begin) return { BOOL3::YES_AND_NO, weaken_YES(info.readable), weaken_YES(info.writable), weaken_YES(info.executable), BOOL3::YES_AND_NO, BOOL3::YES_AND_NO }; info.readable = weaken(info.readable,block_begin->second.readable()); info.writable = weaken(info.writable,block_begin->second.writable()); info.executable = weaken(info.executable,block_begin->second.executable()); info.in_big_endian = weaken(info.in_big_endian,block_begin->second.is_in_big_endian()); info.has_mutable_endian = weaken(info.has_mutable_endian,block_begin->second.has_mutable_endian()); INVARIANT(block_begin->first + block_begin->second.num_bytes() > begin); size const block_rest = block_begin->first + block_begin->second.num_bytes() - begin; begin += block_rest; } return info; }
void do_hex (CHAR_DATA * ch, char *argument, int cmd) { int sn; int duration, modifier; CHAR_DATA *tch; char buf[MAX_STRING_LENGTH]; if (!real_skill (ch, SKILL_HEX)) { send_to_char ("You shiver at the thought.\n\r", ch); return; } argument = one_argument (argument, buf); if (!(tch = get_char_room_vis (ch, buf))) { send_to_char ("You don't see that person here.\n\r", ch); return; } if (IS_MORTAL (ch) && !IS_MORTAL (tch)) { send_to_char ("Immortals are total losers. It can't get any worse for them.\n\r", ch); return; } if (GET_HIT (ch) + GET_MOVE (ch) <= 35) { send_to_char ("You can't concentrate hard enough for that right now.\n\r", ch); return; } sprintf (buf, "Hexing %s", tch->tname); weaken (ch, 0, 20, buf); sense_activity (ch, SKILL_HEX); if (!skill_use (ch, SKILL_HEX, 0)) { send_to_char ("You lose your concentration, and your malignant energies dissipate.\n", ch); return; } act ("You channel a stream of malignant psychic energy into $N, entwining $M in an ethereal web of ill-fortune and grief.", false, ch, 0, tch, TO_CHAR | _ACT_FORMAT); act ("A chill runs down your spine.", false, ch, 0, tch, TO_VICT); sn = spell_lookup ("curse"); modifier = ch->skills[SKILL_HEX] / 5 + number (1, 10); duration = ch->skills[SKILL_HEX] / 5 + number (1, 48); magic_add_affect (tch, MAGIC_AFFECT_CURSE, duration, modifier, 0, 0, sn); tch->curse += ch->skills[SKILL_HEX] / 5 + number (1, 5); }