static enum parser_error parse_quest_race(struct parser *p) { struct quest *q = parser_priv(p); const char *name = parser_getstr(p, "race"); assert(q); q->race = lookup_monster(name); if (!q->race) return PARSE_ERROR_INVALID_MONSTER; return PARSE_ERROR_NONE; }
static errr finish_parse_r(struct parser *p) { struct monster_race *r, *n; size_t i; /* scan the list for the max id */ z_info->r_max -= 1; /*z_info->r_max = 0; fails to load existing save file because of * too high value in old limits.txt. Change to this line when save file * compatibility changes and remove line from limits.txt */ r = parser_priv(p); while (r) { if (r->ridx > z_info->r_max) z_info->r_max = r->ridx; r = r->next; } /* allocate the direct access list and copy the data to it */ r_info = mem_zalloc((z_info->r_max+1) * sizeof(*r)); for (r = parser_priv(p); r; r = n) { memcpy(&r_info[r->ridx], r, sizeof(*r)); n = r->next; if (n) r_info[r->ridx].next = &r_info[n->ridx]; else r_info[r->ridx].next = NULL; mem_free(r); } z_info->r_max += 1; /* convert friend names into race pointers */ for (i = 0; i < z_info->r_max; i++) { struct monster_race *r = &r_info[i]; struct monster_friends *f; for (f = r->friends; f; f = f->next) { if (!my_stricmp(f->name, "same")) f->race = r; else f->race = lookup_monster(f->name); if (!f->race) quit_fmt("Monster '%s' has friend '%s' but I couldn't find any monster of that name", r->name, f->name); string_free(f->name); } } eval_r_power(r_info); parser_destroy(p); return 0; }
/** * Read monster memory. */ int rd_monster_memory(void) { u16b tmp16u; char buf[128]; int i; /* Monster temporary flags */ rd_byte(&mflag_size); /* Incompatible save files */ if (mflag_size > MFLAG_SIZE) { note(format("Too many (%u) monster temporary flags!", mflag_size)); return (-1); } /* Reset maximum numbers per level */ for (i = 1; z_info && i < z_info->r_max; i++) { struct monster_race *race = &r_info[i]; race->max_num = 100; if (rf_has(race->flags, RF_UNIQUE)) race->max_num = 1; } rd_string(buf, sizeof(buf)); while (!streq(buf, "No more monsters")) { struct monster_race *race = lookup_monster(buf); /* Get the kill count, skip if monster invalid */ rd_u16b(&tmp16u); if (!race) continue; /* Store the kill count, ensure dead uniques stay dead */ l_list[race->ridx].pkills = tmp16u; if (rf_has(race->flags, RF_UNIQUE) && tmp16u) race->max_num = 0; /* Look for the next monster */ rd_string(buf, sizeof(buf)); } return 0; }
/* * Ask for and parse a "debug command" * * The "p_ptr->command_arg" may have been set. */ void do_cmd_debug(void) { int py = p_ptr->py; int px = p_ptr->px; struct keypress cmd; const monster_race *r_ptr; /* Get a "debug command" */ if (!get_com("Debug Command: ", &cmd)) return; /* Analyze the command */ switch (cmd.code) { /* Ignore */ case ESCAPE: case ' ': case KC_ENTER: { break; } #ifdef ALLOW_SPOILERS /* Hack -- Generate Spoilers */ case '"': { do_cmd_spoilers(); break; } #endif /* Hack -- Help */ case '?': { do_cmd_wiz_help(); break; } /* Cure all maladies */ case 'a': { do_cmd_wiz_cure_all(); break; } /* Make the player powerful */ case 'A': { do_cmd_wiz_advance(); break; } /* Teleport to target */ case 'b': { do_cmd_wiz_bamf(); break; } /* Create any object */ case 'c': { wiz_create_item(); break; } /* Create an artifact */ case 'C': { if (p_ptr->command_arg > 0) { wiz_create_artifact(p_ptr->command_arg); } else { char name[80] = ""; int a_idx = -1; /* Avoid the prompt getting in the way */ screen_save(); /* Prompt */ prt("Create which artifact? ", 0, 0); /* Get the name */ if (askfor_aux(name, sizeof(name), NULL)) { /* See if an a_idx was entered */ a_idx = get_idx_from_name(name); /* If not, find the artifact with that name */ if (a_idx < 1) a_idx = lookup_artifact_name(name); /* Did we find a valid artifact? */ if (a_idx != -1) wiz_create_artifact(a_idx); else msg("No artifact found."); } /* Reload the screen */ screen_load(); } break; } /* Detect everything */ case 'd': { detect_all(TRUE); break; } /* Test for disconnected dungeon */ case 'D': { disconnect_stats(); break; } /* Edit character */ case 'e': { do_cmd_wiz_change(); break; } case 'f': { stats_collect(); break; } /* Good Objects */ case 'g': { if (p_ptr->command_arg <= 0) p_ptr->command_arg = 1; acquirement(py, px, p_ptr->depth, p_ptr->command_arg, FALSE); break; } /* GF demo */ case 'G': { wiz_gf_demo(); break; } /* Hitpoint rerating */ case 'h': { do_cmd_rerate(); break; } /* Identify */ case 'i': { (void)ident_spell(); break; } /* Go up or down in the dungeon */ case 'j': { do_cmd_wiz_jump(); break; } /* Learn about objects */ case 'l': { do_cmd_wiz_learn(); break; } case 'L': do_cmd_keylog(); break; /* Magic Mapping */ case 'm': { map_area(); break; } /* Summon Named Monster */ case 'n': { s16b r_idx = 0; if (p_ptr->command_arg > 0) { r_idx = p_ptr->command_arg; } else { char name[80] = ""; /* Avoid the prompt getting in the way */ screen_save(); /* Prompt */ prt("Summon which monster? ", 0, 0); /* Get the name */ if (askfor_aux(name, sizeof(name), NULL)) { /* See if a r_idx was entered */ r_idx = get_idx_from_name(name); /* If not, find the monster with that name */ if (r_idx < 1) r_idx = lookup_monster(name); p_ptr->redraw |= (PR_MAP | PR_MONLIST); /* Reload the screen */ screen_load(); } } if (r_idx > 0) do_cmd_wiz_named(r_idx, TRUE); else msg("No monster found."); break; } /* Object playing routines */ case 'o': { do_cmd_wiz_play(); break; } /* Phase Door */ case 'p': { teleport_player(10); break; } /* Monster pit stats */ case 'P': { pit_stats(); break; } /* Query the dungeon */ case 'q': { do_cmd_wiz_query(); break; } /* Get full recall for a monster */ case 'r': { s16b r_idx = 0; if (p_ptr->command_arg > 0) { r_idx = p_ptr->command_arg; } else { struct keypress sym; const char *prompt = "Full recall for [a]ll monsters or [s]pecific monster? "; if (!get_com(prompt, &sym)) return; if (sym.code == 'a' || sym.code == 'A') { int i; for (i = 1; i < z_info->r_max; i++) { r_ptr = &r_info[i]; cheat_monster_lore(r_ptr, &l_list[i]); } break; } else if (sym.code == 's' || sym.code == 'S') { char name[80] = ""; /* Avoid the prompt getting in the way */ screen_save(); /* Prompt */ prt("Which monster? ", 0, 0); /* Get the name */ if (askfor_aux(name, sizeof(name), NULL)) { /* See if a r_idx was entered */ r_idx = get_idx_from_name(name); /* If not, find the monster with that name */ if (r_idx < 1) r_idx = lookup_monster(name); } /* Reload the screen */ screen_load(); } else { /* Assume user aborts */ break; } } /* Did we find a valid monster? */ if (r_idx > 0) { r_ptr = &r_info[r_idx]; cheat_monster_lore(r_ptr, &l_list[r_idx]); } else msg("No monster found."); break; } /* Summon Random Monster(s) */ case 's': { if (p_ptr->command_arg <= 0) p_ptr->command_arg = 1; do_cmd_wiz_summon(p_ptr->command_arg); break; } /* Collect stats (S) */ case 'S': { stats_collect(); break; } /* Teleport */ case 't': { teleport_player(100); break; } /* Create a trap */ case 'T': { if (cave->feat[p_ptr->py][p_ptr->px] != FEAT_FLOOR) msg("You can't place a trap there!"); else if (p_ptr->depth == 0) msg("You can't place a trap in the town!"); else cave_set_feat(cave, p_ptr->py, p_ptr->px, FEAT_INVIS); break; } /* Un-hide all monsters */ case 'u': { detect_monsters_entire_level(); break; } /* Very Good Objects */ case 'v': { if (p_ptr->command_arg <= 0) p_ptr->command_arg = 1; acquirement(py, px, p_ptr->depth, p_ptr->command_arg, TRUE); break; } case 'V': { wiz_test_kind(p_ptr->command_arg); break; } /* Wizard Light the Level */ case 'w': { wiz_light(TRUE); break; } /* Wipe recall for a monster */ case 'W': { s16b r_idx = 0; if (p_ptr->command_arg > 0) { r_idx = p_ptr->command_arg; } else { struct keypress sym; const char *prompt = "Wipe recall for [a]ll monsters or [s]pecific monster? "; if (!get_com(prompt, &sym)) return; if (sym.code == 'a' || sym.code == 'A') { int i; for (i = 1; i < z_info->r_max; i++) { r_ptr = &r_info[i]; wipe_monster_lore(r_ptr, &l_list[i]); } break; } else if (sym.code == 's' || sym.code == 'S') { char name[80] = ""; /* Avoid the prompt getting in the way */ screen_save(); /* Prompt */ prt("Which monster? ", 0, 0); /* Get the name */ if (askfor_aux(name, sizeof(name), NULL)) { /* See if a r_idx was entered */ r_idx = get_idx_from_name(name); /* If not, find the monster with that name */ if (r_idx < 1) r_idx = lookup_monster(name); } /* Reload the screen */ screen_load(); } else { /* Assume user aborts */ break; } } /* Did we find a valid monster? */ if (r_idx > 0) { r_ptr = &r_info[r_idx]; wipe_monster_lore(r_ptr, &l_list[r_idx]); } else msg("No monster found."); break; } /* Increase Experience */ case 'x': { if (p_ptr->command_arg) { player_exp_gain(p_ptr, p_ptr->command_arg); } else { player_exp_gain(p_ptr, p_ptr->exp + 1); } break; } /* Zap Monsters (Banishment) */ case 'z': { if (p_ptr->command_arg <= 0) p_ptr->command_arg = MAX_SIGHT; do_cmd_wiz_zap(p_ptr->command_arg); break; } /* Hack */ case '_': { do_cmd_wiz_hack_ben(); break; } /* Oops */ default: { msg("That is not a valid debug command."); break; } } }
/* * Ask for and parse a "debug command" * * The "p_ptr->command_arg" may have been set. */ void do_cmd_debug(void) { int py = p_ptr->py; int px = p_ptr->px; char cmd; /* Get a "debug command" */ if (!get_com("Debug Command: ", &cmd)) return; /* Analyze the command */ switch (cmd) { /* Ignore */ case ESCAPE: case ' ': case '\n': case '\r': { break; } #ifdef ALLOW_SPOILERS /* Hack -- Generate Spoilers */ case '"': { do_cmd_spoilers(); break; } #endif /* Hack -- Help */ case '?': { do_cmd_wiz_help(); break; } /* Cure all maladies */ case 'a': { do_cmd_wiz_cure_all(); break; } /* Teleport to target */ case 'b': { do_cmd_wiz_bamf(); break; } /* Create any object */ case 'c': { wiz_create_item(); break; } /* Create an artifact */ case 'C': { if (p_ptr->command_arg > 0) { wiz_create_artifact(p_ptr->command_arg); } else { char name[80] = ""; int a_idx = -1; /* Avoid the prompt getting in the way */ screen_save(); /* Prompt */ prt("Create which artifact? ", 0, 0); /* Get the name */ if (askfor_aux(name, sizeof(name), NULL)) { /* See if an a_idx was entered */ a_idx = get_idx_from_name(name); /* If not, find the artifact with that name */ if (a_idx < 1) a_idx = lookup_artifact_name(name); /* Did we find a valid artifact? */ if (a_idx != -1) wiz_create_artifact(a_idx); } /* Reload the screen */ screen_load(); } break; } /* Detect everything */ case 'd': { detect_all(TRUE); break; } /* Edit character */ case 'e': { do_cmd_wiz_change(); break; } case 'f': { stats_collect(); break; } /* Good Objects */ case 'g': { if (p_ptr->command_arg <= 0) p_ptr->command_arg = 1; acquirement(py, px, p_ptr->depth, p_ptr->command_arg, FALSE); break; } /* Hitpoint rerating */ case 'h': { do_cmd_rerate(); break; } /* Identify */ case 'i': { (void)ident_spell(); break; } /* Go up or down in the dungeon */ case 'j': { do_cmd_wiz_jump(); break; } /* Learn about objects */ case 'l': { do_cmd_wiz_learn(); break; } /* Magic Mapping */ case 'm': { map_area(); break; } /* Summon Named Monster */ case 'n': { if (p_ptr->command_arg > 0) { do_cmd_wiz_named(p_ptr->command_arg, TRUE); } else { char name[80] = ""; s16b r_idx; /* Avoid the prompt getting in the way */ screen_save(); /* Prompt */ prt("Summon which monster? ", 0, 0); /* Get the name */ if (askfor_aux(name, sizeof(name), NULL)) { /* See if a r_idx was entered */ r_idx = get_idx_from_name(name); /* If not, find the monster with that name */ if (r_idx < 1) r_idx = lookup_monster(name); /* Did we find a valid monster? */ if (r_idx != -1) do_cmd_wiz_named(r_idx, TRUE); } p_ptr->redraw |= (PR_MAP | PR_MONLIST); /* Reload the screen */ screen_load(); } break; } /* Object playing routines */ case 'o': { do_cmd_wiz_play(); break; } /* Phase Door */ case 'p': { teleport_player(10); break; } /* Query the dungeon */ case 'q': { do_cmd_wiz_query(); break; } /* Summon Random Monster(s) */ case 's': { if (p_ptr->command_arg <= 0) p_ptr->command_arg = 1; do_cmd_wiz_summon(p_ptr->command_arg); break; } /* Teleport */ case 't': { teleport_player(100); break; } /* Create a trap */ case 'T': { cave_set_feat(p_ptr->py, p_ptr->px, FEAT_INVIS); break; } /* Un-hide all monsters */ case 'u': { if (p_ptr->command_arg <= 0) p_ptr->command_arg = 255; do_cmd_wiz_unhide(p_ptr->command_arg); break; } /* Very Good Objects */ case 'v': { if (p_ptr->command_arg <= 0) p_ptr->command_arg = 1; acquirement(py, px, p_ptr->depth, p_ptr->command_arg, TRUE); break; } case 'V': { wiz_test_kind(p_ptr->command_arg); break; } /* Wizard Light the Level */ case 'w': { wiz_light(); break; } /* Increase Experience */ case 'x': { if (p_ptr->command_arg) { gain_exp(p_ptr->command_arg); } else { gain_exp(p_ptr->exp + 1); } break; } /* Zap Monsters (Banishment) */ case 'z': { if (p_ptr->command_arg <= 0) p_ptr->command_arg = MAX_SIGHT; do_cmd_wiz_zap(p_ptr->command_arg); break; } /* Hack */ case '_': { do_cmd_wiz_hack_ben(); break; } /* Oops */ default: { msg_print("That is not a valid debug command."); break; } } }
/** * Read an object. */ static struct object *rd_item(void) { struct object *obj = object_new(); byte tmp8u; u16b tmp16u; byte effect; size_t i; char buf[128]; byte ver = 1; rd_u16b(&tmp16u); rd_byte(&ver); if (tmp16u != 0xffff) return NULL; rd_u16b(&obj->oidx); /* Location */ rd_byte(&obj->iy); rd_byte(&obj->ix); /* Type/Subtype */ rd_string(buf, sizeof(buf)); if (buf[0]) { obj->tval = tval_find_idx(buf); } rd_string(buf, sizeof(buf)); if (buf[0]) { obj->sval = lookup_sval(obj->tval, buf); } rd_s16b(&obj->pval); rd_byte(&obj->number); rd_s16b(&obj->weight); rd_string(buf, sizeof(buf)); if (buf[0]) { obj->artifact = lookup_artifact_name(buf); if (!obj->artifact) { note(format("Couldn't find artifact %s!", buf)); return NULL; } } rd_string(buf, sizeof(buf)); if (buf[0]) { obj->ego = lookup_ego_item(buf, obj->tval, obj->sval); if (!obj->ego) { note(format("Couldn't find ego item %s!", buf)); return NULL; } } rd_byte(&effect); rd_s16b(&obj->timeout); rd_s16b(&obj->to_h); rd_s16b(&obj->to_d); rd_s16b(&obj->to_a); rd_s16b(&obj->ac); rd_byte(&obj->dd); rd_byte(&obj->ds); rd_byte(&obj->origin); rd_byte(&obj->origin_depth); rd_string(buf, sizeof(buf)); if (buf[0]) { obj->origin_race = lookup_monster(buf); } rd_byte(&obj->notice); for (i = 0; i < of_size; i++) rd_byte(&obj->flags[i]); for (i = 0; i < obj_mod_max; i++) { rd_s16b(&obj->modifiers[i]); } /* Read brands */ rd_byte(&tmp8u); if (tmp8u) { obj->brands = mem_zalloc(z_info->brand_max * sizeof(bool)); for (i = 0; i < brand_max; i++) { rd_byte(&tmp8u); obj->brands[i] = tmp8u ? true : false; } } /* Read slays */ rd_byte(&tmp8u); if (tmp8u) { obj->slays = mem_zalloc(z_info->slay_max * sizeof(bool)); for (i = 0; i < slay_max; i++) { rd_byte(&tmp8u); obj->slays[i] = tmp8u ? true : false; } } /* Read curses */ rd_byte(&tmp8u); if (tmp8u) { obj->curses = mem_zalloc(z_info->curse_max * sizeof(struct curse_data)); for (i = 0; i < curse_max; i++) { rd_byte(&tmp8u); obj->curses[i].power = tmp8u; rd_u16b(&tmp16u); obj->curses[i].timeout = tmp16u; } } for (i = 0; i < elem_max; i++) { rd_s16b(&obj->el_info[i].res_level); rd_byte(&obj->el_info[i].flags); } /* Monster holding object */ rd_s16b(&obj->held_m_idx); rd_s16b(&obj->mimicking_m_idx); /* Activation */ rd_u16b(&tmp16u); if (tmp16u) obj->activation = &activations[tmp16u]; rd_u16b(&tmp16u); obj->time.base = tmp16u; rd_u16b(&tmp16u); obj->time.dice = tmp16u; rd_u16b(&tmp16u); obj->time.sides = tmp16u; /* Save the inscription */ rd_string(buf, sizeof(buf)); if (buf[0]) obj->note = quark_add(buf); /* Lookup item kind */ obj->kind = lookup_kind(obj->tval, obj->sval); /* Check we have a kind */ if ((!obj->tval && !obj->sval) || !obj->kind) { object_delete(&obj); return NULL; } /* Set effect */ if (effect && obj->ego) obj->effect = obj->ego->effect; if (effect && !obj->effect) obj->effect = obj->kind->effect; /* Success */ return obj; }
/** * Read a monster */ static bool rd_monster(struct chunk *c, struct monster *mon) { byte tmp8u; u16b tmp16u; char race_name[80]; size_t j; /* Read the monster race */ rd_string(race_name, sizeof(race_name)); mon->race = lookup_monster(race_name); if (!mon->race) { note(format("Monster race %s no longer exists!", race_name)); return (-1); } /* Read the other information */ rd_byte(&mon->fy); rd_byte(&mon->fx); rd_s16b(&mon->hp); rd_s16b(&mon->maxhp); rd_byte(&mon->mspeed); rd_byte(&mon->energy); rd_byte(&tmp8u); for (j = 0; j < tmp8u; j++) rd_s16b(&mon->m_timed[j]); /* Read and extract the flag */ for (j = 0; j < mflag_size; j++) rd_byte(&mon->mflag[j]); for (j = 0; j < of_size; j++) rd_byte(&mon->known_pstate.flags[j]); for (j = 0; j < elem_max; j++) rd_s16b(&mon->known_pstate.el_info[j].res_level); rd_u16b(&tmp16u); if (tmp16u) { /* Find and set the mimicked object */ struct object *square_obj = square_object(c, mon->fy, mon->fx); /* Try and find the mimicked object; if we fail, create a new one */ while (square_obj) { if (square_obj->mimicking_m_idx == tmp16u) break; square_obj = square_obj->next; } if (square_obj) { mon->mimicked_obj = square_obj; } else { mon_create_mimicked_object(c, mon, tmp16u); } } /* Read all the held objects (order is unimportant) */ while (true) { struct object *obj = rd_item(); if (!obj) break; pile_insert(&mon->held_obj, obj); assert(obj->oidx); assert(c->objects[obj->oidx] == NULL); c->objects[obj->oidx] = obj; } return true; }