/* * Create a spoiler file for monsters (-SHAWN-) */ static void spoil_mon_info(void) { int n, x, y; bool breath, magic; u32b flags1, flags2, flags3, flags4, flags5, flags6; const bool old_spoil_mon = spoil_mon; byte a; char c, c2; byte old_moncol[MAX_MONCOL]; /* Give full information. */ spoil_mon = TRUE; for (n = 0; n < MAX_MONCOL; n++) old_moncol[n] = moncol[n].gfx.xa; /* Hack - hide some information. */ moncol[0].gfx.xa = moncol[8].gfx.xa = moncol[18].gfx.xa = TERM_DARK; /* Dump the header */ spoil_out("Monster Spoilers for %s Version %s\n", GAME_NAME, GAME_VERSION); spoil_out("------------------------------------------\n\n"); /* * List all monsters in order (except the ghost). */ for (n = 1; n < MAX_R_IDX; n++) { monster_race *r_ptr = &r_info[n]; /* Skip "fake" monsters. */ if (is_fake_monster(r_ptr)) continue; /* Extract the flags */ flags1 = r_ptr->flags1; flags2 = r_ptr->flags2; flags3 = r_ptr->flags3; flags4 = r_ptr->flags4; flags5 = r_ptr->flags5; flags6 = r_ptr->flags6; breath = FALSE; magic = FALSE; /* Prefix */ if (flags1 & (RF1_GUARDIAN)) { spoil_out("[G] "); } else if (flags1 & (RF1_UNIQUE)) { spoil_out("[U] "); } else { spoil_out("The "); } /* Name */ spoil_out("%v (", monster_desc_aux_f3, r_ptr, 1, 0); /* Color */ spoil_out(attr_to_text(r_ptr->gfx.da)); /* Symbol --(-- */ spoil_out(" '%c')\n", r_ptr->gfx.dc); /* Indent */ spoil_out("=== "); /* Number */ spoil_out("Num:%d ", n); /* Level */ spoil_out("Lev:%d ", r_ptr->level); /* Rarity */ spoil_out("Rar:%d ", r_ptr->rarity); /* Speed */ spoil_out("Spd:%+d ", (r_ptr->speed - 110)); /* Hitpoints */ if ((flags1 & (RF1_FORCE_MAXHP)) || (r_ptr->hside == 1)) { spoil_out("Hp:%d ", r_ptr->hdice * r_ptr->hside); } else { spoil_out("Hp:%dd%d ", r_ptr->hdice, r_ptr->hside); } /* Armor Class */ spoil_out("Ac:%d ", r_ptr->ac); /* Power */ spoil_out("Power:%ld\n", (long)(r_ptr->mexp)); /* Clear the screen before every monster. */ Term_clear(); /* Display the monster on screen. */ screen_roff(n); /* Dump the on-screen display (excluding the title). */ for (c2 = 0, y = 1; y < Term->hgt; y++) { for (x = 0; x < Term->wid; x++) { /* Check the character. */ Term_what(x, y, &a, &c); /* Ignore blanked text. */ if (a == TERM_DARK) continue; /* Ignore repeated spaces. */ if (c == ' ' && c2 == ' ') continue; /* Dump the character. */ spoil_out("%c", c); /* Remember the character. */ c2 = c; } /* Put a space at the end of every line. */ if (c2 != ' ') spoil_out(" "); } spoil_out(NULL); } /* Restore spoil_mon. */ spoil_mon = old_spoil_mon; /* Restore moncol[]. */ for (n = 0; n < MAX_MONCOL; n++) moncol[n].gfx.xa = old_moncol[n]; /* Don't leave a monster display lying around. */ Term_clear(); }
/* * Print monsters' evolution information to file */ static void spoil_mon_evol(cptr fname) { char buf[1024]; monster_race *r_ptr; int **evol_tree, i, j, n, r_idx; int *evol_tree_zero; /* For C_KILL() */ /* Build the filename */ path_build(buf, sizeof buf, ANGBAND_DIR_USER, fname); /* File type is "TEXT" */ FILE_TYPE(FILE_TYPE_TEXT); /* Open the file */ fff = my_fopen(buf, "w"); /* Oops */ if (!fff) { msg_print("Cannot create spoiler file."); return; } /* Dump the header */ sprintf(buf, "Monster Spoilers for PosChengband Version %d.%d.%d\n", VER_MAJOR, VER_MINOR, VER_PATCH); spoil_out(buf); spoil_out("------------------------------------------\n\n"); /* Allocate the "evol_tree" array (2-dimension) */ C_MAKE(evol_tree, max_r_idx, int *); C_MAKE(*evol_tree, max_r_idx * (MAX_EVOL_DEPTH + 1), int); for (i = 1; i < max_r_idx; i++) evol_tree[i] = *evol_tree + i * (MAX_EVOL_DEPTH + 1); evol_tree_zero = *evol_tree; /* Step 1: Build the evolution tree */ for (i = 1; i < max_r_idx; i++) { r_ptr = &r_info[i]; /* No evolution */ if (!r_ptr->next_exp) continue; /* Trace evolution */ n = 0; evol_tree[i][n++] = i; do { evol_tree[i][n++] = r_ptr->next_r_idx; r_ptr = &r_info[r_ptr->next_r_idx]; } while (r_ptr->next_exp && (n < MAX_EVOL_DEPTH)); } /* Step 2: Scan the evolution trees and remove "partial tree" */ for (i = 1; i < max_r_idx; i++) { /* Not evolution tree */ if (!evol_tree[i][0]) continue; for (j = 1; j < max_r_idx; j++) { /* Same tree */ if (i == j) continue; /* Not evolution tree */ if (!evol_tree[j][0]) continue; /* Is evolution tree[i] is part of [j]? */ if (is_partial_tree(evol_tree[j], evol_tree[i])) { /* Remove this evolution tree */ evol_tree[i][0] = 0; break; } } } /* Step 3: Sort the evolution trees */ /* Select the sort method */ ang_sort_comp = ang_sort_comp_evol_tree; ang_sort_swap = ang_sort_swap_evol_tree; /* Sort the array */ ang_sort(evol_tree, NULL, max_r_idx); /* Step 4: Print the evolution trees */ for (i = 0; i < max_r_idx; i++) { r_idx = evol_tree[i][0]; /* No evolution or removed evolution tree */ if (!r_idx) continue; /* Trace the evolution tree */ r_ptr = &r_info[r_idx]; fprintf(fff, "[%d]: %s (Level %d, '%c')\n", r_idx, r_name + r_ptr->name, r_ptr->level, r_ptr->d_char); for (n = 1; r_ptr->next_exp; n++) { fprintf(fff, "%*s-(%d)-> ", n * 2, "", r_ptr->next_exp); fprintf(fff, "[%d]: ", r_ptr->next_r_idx); r_ptr = &r_info[r_ptr->next_r_idx]; fprintf(fff, "%s (Level %d, '%c')\n", r_name + r_ptr->name, r_ptr->level, r_ptr->d_char); } /* End of evolution tree */ fputc('\n', fff); } /* Free the "evol_tree" array (2-dimension) */ C_KILL(evol_tree_zero, max_r_idx * (MAX_EVOL_DEPTH + 1), int); C_KILL(evol_tree, max_r_idx, int *); /* Check for errors */ if (ferror(fff) || my_fclose(fff)) { msg_print("Cannot close spoiler file."); return; } /* Message */ msg_print("Successfully created a spoiler file."); }