Press n or j to go to the next uncovered block, b, p or k for the previous block.
| 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 271 272 273 274 275 276 277 278 279 280 281 282 283 284 285 286 287 288 289 290 291 292 293 294 295 296 297 298 299 300 301 302 303 304 305 306 307 308 309 310 311 312 313 314 315 316 317 318 319 320 321 322 323 324 325 326 327 328 329 330 331 332 333 334 335 336 337 | 73x 73x 73x 73x 73x 73x 73x 73x 73x 73x 73x 73x 73x 73x 73x 73x 73x 73x 73x 73x 73x 73x 73x 73x 73x 73x 73x 73x 73x 73x 73x 73x 73x 73x 73x 73x 73x 73x 73x 73x 73x 73x 73x 73x 73x 73x 73x 73x 73x 73x 73x 73x 73x 73x 73x 73x 73x 73x 73x 73x 73x 73x 73x 73x 73x 73x 73x 73x 73x 73x 73x 73x 73x 73x 73x 73x 73x 73x 73x 73x 73x 73x 73x 73x 73x 73x 73x 73x 73x 73x 73x 73x 73x 73x 73x 73x 73x 73x 73x 73x 73x 73x 73x 73x 73x 73x 73x 73x 73x 73x 115x 115x 115x 115x 115x 115x 115x 115x 115x 115x 115x 73x 73x 73x 195x 195x 195x 195x 73x 73x 73x 17x 17x 17x 17x 17x 17x 17x 17x 17x 17x 17x 17x 17x 17x 17x 17x 17x 17x 17x 17x 103x 103x 103x 103x 17x 17x 17x 17x 17x 17x 17x 73x 73x 73x 18x 18x 18x 18x 18x 18x 18x 18x 18x 18x 18x 18x 18x 18x 18x 18x 18x 328x 328x 18x 18x 18x 18x 18x 18x 73x 73x 73x 3x 3x 3x 3x 3x 3x 3x 3x 3x 3x 73x 73x 73x 6x 6x 6x 6x 6x 6x 6x 396x 396x 396x 396x 390x 390x 396x 396x 396x 396x 6x 6x 6x 6x 6x 6x 6x 6x 6x 6x 6x 6x 6x 6x 6x 6x 6x 6x 6x 6x 6x 6x 6x 3x 3x 6x 6x 6x 6x 6x 6x 6x 6x 6x 6x 6x 3x 3x 3x 3x 6x 6x 6x 6x 6x 6x 6x 6x | // wizcmds.js — Wizard/debug commands (port slice from wizcmds.c)
import { game } from './gstate.js';
import { level_tele } from './teleport.js';
import { makewish } from './zap.js';
import { getlin } from './input.js';
import { mungspaces } from './hacklib.js';
import { pluslvl, losexp } from './exper.js';
import {
ACID_RES, AGGRAVATE_MONSTER, ANTIMAGIC, BLINDED, BLND_RES, CLAIRVOYANT,
COLD_RES, CONFLICT, CONFUSION, DEAF, DETECT_MONSTERS, DISINT_RES, DISPLACED,
DRAIN_RES, FAST, FIRE_RES, FIXED_ABIL, FLYING, FREE_ACTION, FUMBLING, GLIB,
HALLUC, HALLUC_RES, HUNGER, INFRAVISION, INVIS, INVULNERABLE, JUMPING,
LEVITATION, LIFESAVED, MAGICAL_BREATHING, MAXULEV, Never_mind, PASSES_WALLS,
POISON_RES, POLYMORPH, POLYMORPH_CONTROL, PROTECTION, PROT_FROM_SHAPE_CHANGERS,
REGENERATION, REFLECTING, SEARCHING, SEE_INVIS, SHOCK_RES, SICK, SICK_NONVOMITABLE,
SICK_RES, SICK_VOMITABLE, SLEEP_RES, SLEEPY, SLIMED, SLOW_DIGESTION, STONE_RES,
STONED, STRANGLED, STUNNED, SWIMMING, TELEPAT, TELEPORT, TELEPORT_CONTROL,
TIMEOUT, UNCHANGING, VOMITING, WARNING, WARN_OF_MON, WOUNDED_LEGS, WWALKING,
ENERGY_REGENERATION, ADORNED, HALF_PHDAM, HALF_SPDAM,
} from './const.js';
import { You, pline1 } from './pline.js';
import { do_mapping } from './detect.js';
import { docrt, map_trap, setBotl } from './display.js';
import { create_particular } from './read.js';
import { add_menu, add_menu_str, create_nhwindow_menu, destroy_nhwindow_menu, end_menu, select_menu, start_menu } from './menu.js';
import { ATR_NONE, NO_COLOR } from './terminal.js';
import { PICK_ANY, KILLED_BY } from './const.js';
import { incr_itimeout } from './timeout.js';
import { make_blinded, make_deaf, make_hallucinated, make_sick, make_slimed, make_stoned, make_stunned, make_vomiting } from './potion.js';
import { make_glib } from './mhitu.js';
import { float_vs_flight } from './polyself.js';
import { H, Slimed, Stoned } from './macros.js';
import { rn2 } from './rng.js';
import { mons, PM_GRID_BUG } from './monsters.js';
const DEFAULT_TIMEOUT_INCR = 30;
// C ref: timeout.c propertynames[] ordering used by #wizintrinsic.
const WIZ_INTRINSIC_PROPS = [
{ prop: INVULNERABLE, name: 'invulnerable' },
{ prop: STONED, name: 'petrifying' },
{ prop: SLIMED, name: 'becoming slime' },
{ prop: STRANGLED, name: 'strangling' },
{ prop: SICK, name: 'fatally sick' },
{ prop: STUNNED, name: 'stunned' },
{ prop: CONFUSION, name: 'confused' },
{ prop: HALLUC, name: 'hallucinating' },
{ prop: BLINDED, name: 'blinded' },
{ prop: DEAF, name: 'deafness' },
{ prop: VOMITING, name: 'vomiting' },
{ prop: GLIB, name: 'slippery fingers' },
{ prop: WOUNDED_LEGS, name: 'wounded legs' },
{ prop: SLEEPY, name: 'sleepy' },
{ prop: TELEPORT, name: 'teleporting' },
{ prop: POLYMORPH, name: 'polymorphing' },
{ prop: LEVITATION, name: 'levitating' },
{ prop: FAST, name: 'very fast' },
{ prop: CLAIRVOYANT, name: 'clairvoyant' },
{ prop: DETECT_MONSTERS, name: 'monster detection' },
{ prop: SEE_INVIS, name: 'see invisible' },
{ prop: INVIS, name: 'invisible' },
{ prop: ACID_RES, name: 'acid resistance' },
{ prop: STONE_RES, name: 'stoning resistance' },
{ prop: DISPLACED, name: 'displaced' },
{ prop: PASSES_WALLS, name: 'pass thru walls' },
{ prop: MAGICAL_BREATHING, name: 'magical breathing' },
{ prop: WWALKING, name: 'water walking' },
{ prop: FIRE_RES, name: 'fire resistance' },
{ prop: COLD_RES, name: 'cold resistance' },
{ prop: SLEEP_RES, name: 'sleep resistance' },
{ prop: DISINT_RES, name: 'disintegration resistance' },
{ prop: SHOCK_RES, name: 'shock resistance' },
{ prop: POISON_RES, name: 'poison resistance' },
{ prop: DRAIN_RES, name: 'drain resistance' },
{ prop: SICK_RES, name: 'sickness resistance' },
{ prop: ANTIMAGIC, name: 'magic resistance' },
{ prop: HALLUC_RES, name: 'hallucination resistance' },
{ prop: BLND_RES, name: 'light-induced blindness resistance' },
{ prop: FUMBLING, name: 'fumbling' },
{ prop: HUNGER, name: 'voracious hunger' },
{ prop: TELEPAT, name: 'telepathic' },
{ prop: WARNING, name: 'warning' },
{ prop: WARN_OF_MON, name: 'warn: monster type or class' },
{ prop: SEARCHING, name: 'searching' },
{ prop: INFRAVISION, name: 'infravision' },
{ prop: ADORNED, name: 'adorned (+/- Cha)' },
{ prop: AGGRAVATE_MONSTER, name: 'monster aggravation' },
{ prop: CONFLICT, name: 'conflict' },
{ prop: JUMPING, name: 'jumping' },
{ prop: TELEPORT_CONTROL, name: 'teleport control' },
{ prop: FLYING, name: 'flying' },
{ prop: SWIMMING, name: 'swimming' },
{ prop: SLOW_DIGESTION, name: 'slow digestion' },
{ prop: HALF_SPDAM, name: 'half spell damage' },
{ prop: HALF_PHDAM, name: 'half physical damage' },
{ prop: REGENERATION, name: 'HP regeneration' },
{ prop: ENERGY_REGENERATION, name: 'energy regeneration' },
{ prop: PROTECTION, name: 'extra protection' },
{ prop: PROT_FROM_SHAPE_CHANGERS, name: 'protection from shape changers' },
{ prop: POLYMORPH_CONTROL, name: 'polymorph control' },
{ prop: UNCHANGING, name: 'unchanging' },
{ prop: REFLECTING, name: 'reflecting' },
{ prop: FREE_ACTION, name: 'free action' },
{ prop: FIXED_ABIL, name: 'fixed abilities' },
{ prop: LIFESAVED, name: 'life will be saved' },
];
// C ref: wizcmds.c:wiz_wish()
export async function wiz_wish() {
if (!game.flags?.debug) return 0;
const saveVerbose = !!game.flags.verbose;
game.flags.verbose = false;
try {
await makewish();
} finally {
game.flags.verbose = saveVerbose;
}
return 0;
}
// C ref: wizcmds.c:wiz_level_tele()
export async function wiz_level_tele() {
if (!game.flags?.debug) return 0;
await level_tele();
return 0;
}
// C ref: wizcmds.c:wiz_map()
export async function wiz_map() {
if (!game.flags?.debug) return 0;
const uprops = game?.u?.uprops || {};
const confProp = uprops[CONFUSION] || {};
const hallProp = uprops[HALLUC] || {};
const savedConf = confProp.intrinsic || 0;
const savedHallu = hallProp.intrinsic || 0;
// C clears HConfusion and HHallucination for mapping output.
confProp.intrinsic = 0;
hallProp.intrinsic = 0;
uprops[CONFUSION] = confProp;
uprops[HALLUC] = hallProp;
game.u.uprops = uprops;
try {
const seen = new Set();
for (let t = game.ftrap; t; t = t.ntrap) {
t.tseen = 1;
// C ref: wizcmds.c:wiz_map() -> map_trap(t, TRUE)
map_trap(t, true);
seen.add(t);
}
const levelTraps = game.level?.traps || [];
for (const t of levelTraps) {
if (seen.has(t)) continue;
t.tseen = 1;
map_trap(t, true);
}
await do_mapping();
} finally {
confProp.intrinsic = savedConf;
hallProp.intrinsic = savedHallu;
}
return 0;
}
// C ref: wizcmds.c:wiz_level_change()
export async function wiz_level_change() {
if (!game.flags?.debug) return 0;
const raw = await getlin('To what experience level do you want to be set?', null, { logHookedLifecycle: true });
const buf = mungspaces(raw ?? '');
if (!buf) return 0;
if (!/^[+-]?\d+$/.test(buf)) {
await pline1(Never_mind);
return 0;
}
let newlevel = Number.parseInt(buf, 10);
const u = game.u;
if (newlevel === u.ulevel) {
await You('are already that experienced.');
} else if (newlevel < u.ulevel) {
if (u.ulevel === 1) {
await You('are already as inexperienced as you can get.');
return 0;
}
if (newlevel < 1) newlevel = 1;
while (u.ulevel > newlevel) {
await losexp('#levelchange');
}
} else {
if (u.ulevel >= MAXULEV) {
await You('are already as experienced as you can get.');
return 0;
}
if (newlevel > MAXULEV) newlevel = MAXULEV;
while (u.ulevel < newlevel) {
await pluslvl(false);
}
}
// C ref: wizcmds.c — freeze maximum level at current level.
u.ulevelmax = u.ulevel;
return 0;
}
// C ref: wizcmds.c:wiz_genesis()
export async function wiz_genesis() {
if (!game.flags?.debug) return 0;
const old = !!game.iflags?.debug_mongen;
game.iflags.debug_mongen = false;
try {
await create_particular();
} finally {
game.iflags.debug_mongen = old;
}
return 0;
}
// C ref: wizcmds.c:wiz_intrinsic()
export async function wiz_intrinsic() {
if (!game.flags?.debug) return 0;
const win = create_nhwindow_menu();
start_menu(win);
if (game.iflags?.cmdassist) {
add_menu_str(win,
`[Precede any selection with a count to increment by other than ${DEFAULT_TIMEOUT_INCR}.]`);
}
for (let i = 0; i < WIZ_INTRINSIC_PROPS.length; i++) {
const entry = WIZ_INTRINSIC_PROPS[i];
if (entry.prop === HALLUC_RES) continue;
if (entry.prop === FIRE_RES) add_menu_str(win, '--');
if (!game.u.uprops[entry.prop]) {
game.u.uprops[entry.prop] = { intrinsic: 0, extrinsic: 0, blocked: 0 };
}
const oldtimeout = game.u.uprops[entry.prop].intrinsic & TIMEOUT;
const line = oldtimeout
? `${entry.name.padEnd(27)} [${oldtimeout}]`
: entry.name;
add_menu(win, i + 1, 0, 0, ATR_NONE, NO_COLOR, line, 0);
}
end_menu(win, 'Which intrinsics?');
const picked = await select_menu(win, PICK_ANY);
destroy_nhwindow_menu(win);
const items = picked?.items || [];
for (const pick of items) {
const idx = Number(pick.identifier) - 1;
if (idx < 0 || idx >= WIZ_INTRINSIC_PROPS.length) continue;
const entry = WIZ_INTRINSIC_PROPS[idx];
const p = entry.prop;
if (!game.u.uprops[p]) game.u.uprops[p] = { intrinsic: 0, extrinsic: 0, blocked: 0 };
const oldtimeout = game.u.uprops[p].intrinsic & TIMEOUT;
const amt = (pick.count === -1) ? DEFAULT_TIMEOUT_INCR : Number(pick.count);
if (!Number.isFinite(amt) || amt <= 0) continue;
let newtimeout = oldtimeout + amt;
if ((p === SICK || p === SLIMED || p === STONED) && oldtimeout > 0 && newtimeout > oldtimeout) {
newtimeout = oldtimeout;
}
switch (p) {
case BLINDED:
await make_blinded(newtimeout, true);
break;
case DEAF:
await make_deaf(newtimeout, true);
break;
case HALLUC:
await make_hallucinated(newtimeout, true, 0);
break;
case SICK: {
const typ = (rn2(2) === 0) ? SICK_VOMITABLE : SICK_NONVOMITABLE;
await make_sick(newtimeout, '#wizintrinsic', true, typ);
break;
}
case SLIMED: {
const msg = `You are${!Slimed() ? '' : ' still'} turning into slime.`;
await make_slimed(newtimeout, msg);
break;
}
case STONED: {
const msg = `You are${!Stoned() ? '' : ' still'} turning into stone.`;
await make_stoned(newtimeout, msg, KILLED_BY, '#wizintrinsic');
break;
}
case STUNNED:
await make_stunned(newtimeout, true);
break;
case VOMITING: {
const msg = `You are${!(H(VOMITING) & TIMEOUT) ? '' : ' still'} vomiting.`;
await make_vomiting(newtimeout, false);
await pline1(msg);
break;
}
case WARN_OF_MON:
if (!H(WARN_OF_MON)) {
game.context.warntype = game.context.warntype || {};
game.context.warntype.speciesidx = PM_GRID_BUG;
game.context.warntype.species = mons[PM_GRID_BUG];
}
// falls through
case GLIB:
if (p === GLIB) {
make_glib(newtimeout);
} else {
incr_itimeout(p, amt);
}
setBotl('wiz_intrinsic');
await pline1(`Timeout for ${entry.name} ${oldtimeout ? 'increased by' : 'set to'} ${amt}.`);
break;
default:
incr_itimeout(p, amt);
setBotl('wiz_intrinsic');
await pline1(`Timeout for ${entry.name} ${oldtimeout ? 'increased by' : 'set to'} ${amt}.`);
break;
}
if (p === LEVITATION || p === FLYING) {
float_vs_flight();
}
}
await docrt();
return 0;
}
|