static void _spoil_spell_book2(doc_ptr doc, int class1_idx, int class2_idx, int realm_idx, int book_idx) { int spell_idx; int k_idx = lookup_kind(realm2tval(realm_idx), book_idx); player_magic *magic1_ptr = &m_info[class1_idx]; player_magic *magic2_ptr = &m_info[class2_idx]; doc_printf(doc, "%-25.25s <color:G>%-12.12s</color> <color:R>%-12.12s</color>\n", "", get_class_aux(class1_idx, 0)->name, get_class_aux(class2_idx, 0)->name); doc_printf(doc, "<color:o>%-25.25s</color><color:G> Lvl Cst Fail</color> <color:R>Lvl Cst Fail</color>\n", k_name + k_info[k_idx].name); for (spell_idx = book_idx*8; spell_idx < (book_idx+1)*8; spell_idx++) { magic_type *spell1_ptr = &magic1_ptr->info[realm_idx - 1][spell_idx]; magic_type *spell2_ptr = &magic2_ptr->info[realm_idx - 1][spell_idx]; doc_printf(doc, "%-25.25s ", do_spell(realm_idx, spell_idx, SPELL_NAME)); if (1 <= spell1_ptr->slevel && spell1_ptr->slevel <= PY_MAX_LEVEL) doc_printf(doc, "%3d %3d %3d%% ", spell1_ptr->slevel, spell1_ptr->smana, spell1_ptr->sfail); else doc_insert(doc, "<color:D>Illegible</color> "); if (1 <= spell2_ptr->slevel && spell2_ptr->slevel <= PY_MAX_LEVEL) doc_printf(doc, "%3d %3d %3d%% ", spell2_ptr->slevel, spell2_ptr->smana, spell2_ptr->sfail); else doc_insert(doc, "<color:D>Illegible</color> "); doc_newline(doc); } doc_newline(doc); }
static void _doc_process_var(doc_ptr doc, cptr name) { if (strcmp(name, "version") == 0) { string_ptr s = string_alloc_format("%d.%d.%d", VER_MAJOR, VER_MINOR, VER_PATCH); doc_insert(doc, string_buffer(s)); string_free(s); } else if (strlen(name) > 3 && strncmp(name, "FF_", 3) == 0) { char buf[100]; int f_idx; sprintf(buf, "%s", name + 3); f_idx = f_tag_to_index(buf); if (0 <= f_idx && f_idx < max_f_idx) { string_ptr s = string_alloc(); feature_type *feat = &f_info[f_idx]; string_printf(s, "<color:%c>%c</color>", attr_to_attr_char(feat->d_attr[F_LIT_STANDARD]), feat->d_char[F_LIT_STANDARD]); doc_insert(doc, string_buffer(s)); string_free(s); } } }
static void _list_spells(doc_ptr doc, int options) { int i; doc_insert(doc, "<style:table>"); doc_printf(doc, "<color:G> %-20.20s Lvl SP Fail %-15.15s", "Name", "Desc"); if (options & _SHOW_STATS) doc_insert(doc, " Cast Fail"); doc_insert(doc, "</color>\n"); for (i = 0; i < _MAX_SLOTS; i++) { if (_spells[i].realm != REALM_NONE) _list_spell(doc, _spells[i].realm, _spells[i].spell, i, options); else { if (options & _ALLOW_EMPTY) doc_printf(doc, " %c) <color:D>(Empty)</color>\n", I2A(i)); else doc_printf(doc, " <color:D>%c) (Empty)</color>\n", I2A(i)); } } doc_insert(doc, "</style>"); if (_browse_choice != -1 && _spells[_browse_choice].realm != REALM_NONE) { doc_newline(doc); doc_printf(doc, " <indent>%s</indent>\n\n", do_spell(_spells[_browse_choice].realm, _spells[_browse_choice].spell, SPELL_DESC)); } }
doc_pos_t doc_read_file(doc_ptr doc, FILE *fp) { string_ptr s = string_read_file(fp); doc_insert(doc, string_buffer(s)); string_free(s); return doc->cursor; }
static void spoil_artifact_desc(void) { int i,j; doc_ptr doc = doc_alloc(80); spoiler_hack = TRUE; for (i = 0; group_artifact[i].tval; i++) { if (group_artifact[i].name) { if (i) doc_insert(doc, "</indent>\n"); doc_printf(doc, "<topic:%s><style:heading>%s</style>\n <indent>\n", group_artifact[i].name, group_artifact[i].name); } for (j = 1; j < max_a_idx; ++j) { artifact_type *a_ptr = &a_info[j]; object_type forge = {0}; if (a_ptr->tval != group_artifact[i].tval) continue; if (!make_fake_artifact(&forge, j)) continue; obj_identify_fully(&forge); obj_display_doc(&forge, doc); doc_newline(doc); } } doc_display(doc, "Artifact Spoilers", 0); doc_free(doc); spoiler_hack = FALSE; }
doc_pos_t doc_insert_text(doc_ptr doc, byte a, cptr text) { doc_style_ptr style = doc_current_style(doc); if (style->color != a) { doc_style_t copy = *style; copy.color = a; doc_push_style(doc, ©); doc_insert(doc, text); doc_pop_style(doc); } else doc_insert(doc, text); assert(0 <= doc->cursor.x && doc->cursor.x < doc->width); return doc->cursor; }
static void _display_spells_to_gain(object_type *o_ptr, rect_t r) { doc_ptr doc = doc_alloc(r.cx); int i; int realm = tval2realm(o_ptr->tval); int start_idx = o_ptr->sval * _SPELLS_PER_BOOK; doc_insert(doc, "<style:table>"); doc_printf(doc, "<color:G> %-20.20s Lvl SP Fail Desc</color>\n", "Name"); for (i = start_idx; i < start_idx + _SPELLS_PER_BOOK; i++) _list_spell(doc, realm, i, i - start_idx, _FROM_BOOK); doc_insert(doc, "</style>"); doc_sync_term(doc, doc_range_all(doc), doc_pos_create(r.x, r.y)); doc_free(doc); }
doc_pos_t doc_printf(doc_ptr doc, const char *fmt, ...) { string_ptr s = string_alloc(); va_list vp; va_start(vp, fmt); string_vprintf(s, fmt, vp); va_end(vp); doc_insert(doc, string_buffer(s)); string_free(s); return doc->cursor; }
static void _list_spell(doc_ptr doc, int realm, int spell, int choice, int options) { magic_type *spell_ptr = _get_spell_info(realm, spell); int cost = calculate_cost(spell_ptr->smana); int fail = calculate_fail_rate(spell_ptr->slevel, spell_ptr->sfail, p_ptr->stat_ind[A_INT]); if (cost > p_ptr->csp) doc_insert(doc, "<color:D>"); else if (choice == _browse_choice) doc_insert(doc, "<color:B>"); else if (spell_ptr->slevel > p_ptr->lev) { if (options & _FROM_BOOK) doc_insert(doc, "<color:D>"); else doc_insert(doc, "<color:y>"); } else doc_insert(doc, "<color:w>"); if (spell_ptr->slevel > p_ptr->lev) doc_printf(doc, " <color:D>%c)</color> ", I2A(choice)); else doc_printf(doc, " %c) ", I2A(choice)); doc_printf(doc, "%-20.20s ", do_spell(realm, spell, SPELL_NAME)); doc_printf(doc, "%3d %3d %3d%% ", spell_ptr->slevel, cost, fail); if (spell_ptr->slevel > p_ptr->lev) { if (options & _FROM_BOOK) doc_printf(doc, "%-15.15s", ""); else doc_printf(doc, "%-15.15s", "Forgotten"); } else if (options & _SHOW_INFO) doc_printf(doc, "%-15.15s", do_spell(realm, spell, SPELL_INFO)); if (options & _SHOW_STATS) { spell_stats_ptr stats = spell_stats_old(realm, spell); if (stats->ct_cast + stats->ct_fail) { doc_printf(doc, " %5d %4d %3d%%", stats->ct_cast, stats->ct_fail, spell_stats_fail(stats) ); } } doc_insert(doc, "</color>\n"); }
void monk_display_attack_info(doc_ptr doc, int hand) { _attack_t counts[MAX_MA]; int i; const int tot = 1000; int tot_dam = 0; /* Scaled by 10 */ int tot_mul = 0; int tot_to_d = 0; /* Scaled by 10 */ int blows = NUM_BLOWS(hand); /* Scaled by 100: 100 = 1.00 blows, 275 = 2.75 blows, etc */ int to_d = p_ptr->weapon_info[hand].to_d * 10; critical_t crit; doc_ptr cols[2] = {0}; cols[0] = doc_alloc(45); cols[1] = doc_alloc(35); /* First Column */ doc_printf(cols[0], "<color:G>%-14.14s %6s %5s %6s</color>\n", "Attack", "Dice", "Pct", "Dam"); _get_attack_counts(tot, counts, hand); for (i = 0; i < MAX_MA; i++) { martial_arts *ma_ptr = &ma_blows[i]; int dd = ma_ptr->dd + p_ptr->weapon_info[hand].to_dd; int ds = ma_ptr->ds + p_ptr->weapon_info[hand].to_ds; char tmp[20]; int dam = dd * (ds + 1) * 10 * counts[i].count / (2 * tot); if (counts[i].count == 0) continue; tot_dam += dam; tot_mul += counts[i].mul; tot_to_d += counts[i].to_d; sprintf(tmp, "%dd%d", dd, ds); doc_printf(cols[0], "%-14.14s %6s %3d.%1d%% %3d.%1d\n", ma_ptr->name, tmp, counts[i].count/10, counts[i].count%10, dam/10, dam%10); } doc_printf(cols[0], "<tab:8>%20s %3d.%1d\n", "Total:", tot_dam/10, tot_dam%10); crit.mul = tot_mul/tot; crit.to_d = tot_to_d*10/tot; doc_printf(cols[0], "<tab:8>%20s %3d.%02dx\n", "Criticals:", crit.mul/100, crit.mul%100); /* Account for criticals in all that follows ... */ tot_dam = tot_dam * crit.mul/100; to_d += crit.to_d; doc_printf(cols[0], "<tab:8>%20s %3d.%1d +%3d\n", "One Strike:", tot_dam/10, tot_dam%10, to_d/10); /* Second Column */ doc_insert(cols[1], "<color:y>Your Fists</color>\n"); doc_printf(cols[1], "Number of Blows: %d.%2.2d\n", blows/100, blows%100); doc_printf(cols[1], "To Hit: 0 50 100 150 200 (AC)\n"); doc_printf(cols[1], " %2d %2d %2d %2d %2d (%%)\n", hit_chance(0, 0, 0), hit_chance(0, 0, 50), hit_chance(0, 0, 100), hit_chance(0, 0, 150), hit_chance(0, 0, 200) ); doc_newline(cols[1]); doc_insert(cols[1], "<color:y>Average Damage:</color>\n"); doc_printf(cols[1], " One Strike: %d.%1d\n", (tot_dam + to_d)/10, (tot_dam + to_d)%10); /* Note: blows are scaled by 100. tot_dam and to_d by 10. So we divide by 1000 to recover the integer part ... */ doc_printf(cols[1], " One Attack: %d.%1d\n", blows*(tot_dam + to_d)/1000, ((blows*(tot_dam + to_d))/100)%10); if (display_weapon_mode == MYSTIC_ACID) { doc_printf(cols[1], " <color:r> Acid</color>: %d.%1d\n", blows*(tot_dam*20/10 + to_d + 50)/1000, ((blows*(tot_dam*20/10 + to_d + 50))/100)%10); } else if (have_flag(p_ptr->weapon_info[hand].flags, OF_BRAND_ACID)) { doc_printf(cols[1], " <color:r> Acid</color>: %d.%1d\n", blows*(tot_dam*17/10 + to_d)/1000, ((blows*(tot_dam*17/10 + to_d))/100)%10); } if (display_weapon_mode == MYSTIC_FIRE) { doc_printf(cols[1], " <color:r> Fire</color>: %d.%1d\n", blows*(tot_dam*17/10 + to_d + 30)/1000, ((blows*(tot_dam*17/10 + to_d + 30))/100)%10); } else if (have_flag(p_ptr->weapon_info[hand].flags, OF_BRAND_FIRE)) { doc_printf(cols[1], " <color:r> Fire</color>: %d.%1d\n", blows*(tot_dam*17/10 + to_d)/1000, ((blows*(tot_dam*17/10 + to_d))/100)%10); } if (display_weapon_mode == MYSTIC_COLD) { doc_printf(cols[1], " <color:r> Cold</color>: %d.%1d\n", blows*(tot_dam*17/10 + to_d + 30)/1000, ((blows*(tot_dam*17/10 + to_d + 30))/100)%10); } else if (have_flag(p_ptr->weapon_info[hand].flags, OF_BRAND_COLD)) { doc_printf(cols[1], " <color:r> Cold</color>: %d.%1d\n", blows*(tot_dam*17/10 + to_d)/1000, ((blows*(tot_dam*17/10 + to_d))/100)%10); } if (display_weapon_mode == MYSTIC_ELEC) { doc_printf(cols[1], " <color:r> Elec</color>: %d.%1d\n", blows*(tot_dam*25/10 + to_d + 70)/1000, ((blows*(tot_dam*25/10 + to_d + 70))/100)%10); } else if (have_flag(p_ptr->weapon_info[hand].flags, OF_BRAND_ELEC)) { doc_printf(cols[1], " <color:r> Elec</color>: %d.%1d\n", blows*(tot_dam*17/10 + to_d)/1000, ((blows*(tot_dam*17/10 + to_d))/100)%10); } if (display_weapon_mode == MYSTIC_POIS) { doc_printf(cols[1], " <color:r> Pois</color>: %d.%1d\n", blows*(tot_dam*17/10 + to_d + 30)/1000, ((blows*(tot_dam*17/10 + to_d + 30))/100)%10); } else if (have_flag(p_ptr->weapon_info[hand].flags, OF_BRAND_POIS)) { doc_printf(cols[1], " <color:r> Pois</color>: %d.%1d\n", blows*(tot_dam*17/10 + to_d)/1000, ((blows*(tot_dam*17/10 + to_d))/100)%10); } doc_insert_cols(doc, cols, 2, 0); doc_free(cols[0]); doc_free(cols[1]); }
static void _doc_process_tag(doc_ptr doc, doc_tag_ptr tag) { if ( tag->type == DOC_TAG_CLOSE_COLOR || tag->type == DOC_TAG_CLOSE_STYLE || tag->type == DOC_TAG_CLOSE_INDENT ) { doc_pop_style(doc); } else if (tag->type == DOC_TAG_COLOR) { assert(tag->arg); if (tag->arg_size == 1) { if (tag->arg[0] == '*') doc_pop_style(doc); else { doc_style_t style = *doc_current_style(doc); /* copy */ switch (tag->arg[0]) { case 'd': style.color = TERM_DARK; break; case 'w': style.color = TERM_WHITE; break; case 's': style.color = TERM_SLATE; break; case 'o': style.color = TERM_ORANGE; break; case 'r': style.color = TERM_RED; break; case 'g': style.color = TERM_GREEN; break; case 'b': style.color = TERM_BLUE; break; case 'u': style.color = TERM_UMBER; break; case 'D': style.color = TERM_L_DARK; break; case 'W': style.color = TERM_L_WHITE; break; case 'v': style.color = TERM_VIOLET; break; case 'y': style.color = TERM_YELLOW; break; case 'R': style.color = TERM_L_RED; break; case 'G': style.color = TERM_L_GREEN; break; case 'B': style.color = TERM_L_BLUE; break; case 'U': style.color = TERM_L_UMBER; break; } doc_push_style(doc, &style); } } else { string_ptr arg = string_copy_sn(tag->arg, tag->arg_size); doc_style_t style = *doc_current_style(doc); /* copy */ doc_style_f f = _get_doc_style_f(doc, string_buffer(arg)); if (f) f(&style); {/* We don't copy the named style, just its color. */ /* Also, we damn well better push a style or we'll be upset when the good little user pops! */ doc_style_t copy = *doc_current_style(doc); copy.color = style.color; doc_push_style(doc, ©); } string_free(arg); } } else if (tag->type == DOC_TAG_INDENT) { doc_style_t style = *doc_current_style(doc); style.left = doc->cursor.x; doc_push_style(doc, &style); } else { string_ptr arg = string_copy_sn(tag->arg, tag->arg_size); switch (tag->type) { case DOC_TAG_STYLE: if (tag->arg_size == 1 && tag->arg[0] == '*') doc_pop_style(doc); else {/* Better silently add one if name doesn't exist ... */ doc_style_t copy = *doc_current_style(doc); doc_style_f f = _get_doc_style_f(doc, string_buffer(arg)); if (f) f(©); doc_push_style(doc, ©); } break; case DOC_TAG_VAR: _doc_process_var(doc, string_buffer(arg)); break; case DOC_TAG_TAB: { int pos = atoi(string_buffer(arg)) + doc_current_style(doc)->left; if (pos > doc->cursor.x) doc_insert_space(doc, pos - doc->cursor.x); else doc_rollback(doc, doc_pos_create(pos, doc->cursor.y)); break; } case DOC_TAG_TOPIC: { doc_bookmark_ptr mark = malloc(sizeof(doc_bookmark_t)); mark->name = arg; /* steal ownership */ arg = NULL; mark->pos = doc->cursor; vec_add(doc->bookmarks, mark); break; } case DOC_TAG_LINK: { doc_link_ptr link = malloc(sizeof(doc_link_t)); int split = string_chr(arg, 0, '#'); int ch = 'a' + int_map_count(doc->links); if (split >= 0) { substring_t left = string_left(arg, split); substring_t right = string_right(arg, string_length(arg) - split - 1); link->file = substring_copy(&left); link->topic = substring_copy(&right); } else { link->file = arg; /* steal ownership */ arg = NULL; link->topic = NULL; } link->location.start = doc->cursor; int_map_add(doc->links, ch, link); { /* TODO: This is flawed. Here's a real world example: "(see below <link:birth.txt#PrimaryStats>)." Can you see the problem? We might line break after "[a]" right before ").". Instead, "[a])." should be treated as the current word. To fix this, we'll need a parser with a token queue that we can push onto, but this raises storage issues. */ string_ptr s = string_alloc_format("<style:link>[%c]</style>", ch); doc_insert(doc, string_buffer(s)); string_free(s); link->location.stop = doc->cursor; } break; } } string_free(arg); } }
void display_innate_attack_info(doc_ptr doc, int which) { innate_attack_ptr a = &p_ptr->innate_attacks[which]; int blows, min, max, min_base, max_base, min2, max2; int i; int to_h = p_ptr->to_h_m + a->to_h; int to_d = p_ptr->to_d_m + a->to_d; int dd = a->dd + p_ptr->innate_attack_info.to_dd; int mult; doc_ptr cols[2] = {0}; blows = a->blows; if (which == 0) blows += p_ptr->innate_attack_info.xtra_blow; cols[0] = doc_alloc(60); cols[1] = doc_alloc(10); /* First Column */ if (a->flags & INNATE_NO_DAM) doc_printf(cols[0], "<color:y> %-7.7s</color>: Your %s\n", "Attack", a->name); else doc_printf(cols[0], "<color:y> %-7.7s</color>: Your %s (%dd%d)\n", "Attack", a->name, dd, a->ds); if (a->weight && !(a->flags & INNATE_NO_DAM)) doc_printf(cols[0], " %-7.7s: %d.%d lbs\n", "Weight", a->weight/10, a->weight%10); { cptr name = skills_innate_calc_name(a); doc_printf(cols[0], " %-7.7s: %s (%+d To Hit)\n", "Profic", skills_innate_describe_current(name), skills_innate_calc_bonus(name)); } doc_printf(cols[0], " %-7.7s: %d + %d = %d\n", "To Hit", a->to_h, p_ptr->to_h_m, to_h); if (!(a->flags & INNATE_NO_DAM)) doc_printf(cols[0], " %-7.7s: %d + %d = %d\n", "To Dam", a->to_d, p_ptr->to_d_m, to_d); doc_printf(cols[0], " %-7.7s: %d.%2.2d\n", "Blows", blows/100, blows%100); mult = 100; if (!(a->flags & INNATE_NO_DAM)) { doc_printf(cols[0], "<color:G> %-7.7s</color>\n", "Damage"); if (a->flags & INNATE_VORPAL) { mult = mult * 11 / 9; doc_printf(cols[0], " %-7.7s: %d.%02dx\n", "Vorpal", mult/100, mult%100); } } if (!(a->flags & INNATE_NO_DAM)) { critical_t crit = {0}; const int ct = 10 * 1000; for (i = 0; i < ct; i++) { critical_t tmp = critical_norm(a->weight, to_h, 0, 0, HAND_NONE); if (tmp.desc) { crit.mul += tmp.mul; crit.to_d += tmp.to_d; } else crit.mul += 100; } crit.mul = crit.mul / ct; crit.to_d = crit.to_d * 100 / ct; if (crit.to_d) doc_printf(cols[0], " %-7.7s: %d.%02dx + %d.%02d\n", "Crits", crit.mul/100, crit.mul%100, crit.to_d/100, crit.to_d%100); else doc_printf(cols[0], " %-7.7s: %d.%02dx\n", "Crits", crit.mul/100, crit.mul%100); crit.to_d /= 100; mult = mult * crit.mul / 100; to_d = to_d + crit.to_d; } min_base = mult * dd / 100; min = min_base + to_d; min2 = 2*(min_base + a->to_d) + p_ptr->to_d_m; max_base = mult * dd * a->ds / 100; max = max_base + to_d; max2 = 2*(max_base + a->to_d) + p_ptr->to_d_m; if (a->effect[0] == GF_OLD_CONF) /* Hack for Umber Hulk ... */ { doc_insert(cols[0], "<tab:10><color:B>Confuses</color>\n"); } else if (!(a->flags & INNATE_NO_DAM)) { doc_printf(cols[0], " %-7.7s: %d (%d-%d)\n", _effect_name(a->effect[0]), blows * (min + max)/200, blows * min/100, blows * max/100 ); } for (i = 1; i < MAX_INNATE_EFFECTS; i++) { int p = a->effect_chance[i]; char xtra[255]; if (!a->effect[i]) continue; if (!p) sprintf(xtra, "%s", ""); else sprintf(xtra, " (%d%%)", p); switch (a->effect[i]) { case GF_STEAL: doc_printf(cols[0], "<tab:10><color:B>Steals%s</color>\n", xtra); break; case GF_OLD_SLOW: doc_printf(cols[0], "<tab:10><color:B>Slows%s</color>\n", xtra); break; case GF_OLD_CONF: doc_printf(cols[0], "<tab:10><color:B>Confuses%s</color>\n", xtra); break; case GF_OLD_SLEEP: doc_printf(cols[0], "<tab:10><color:B>Sleeps%s</color>\n", xtra); break; case GF_STASIS: case GF_PARALYSIS: doc_printf(cols[0], "<tab:10><color:B>Paralyzes%s</color>\n", xtra); break; case GF_DRAIN_MANA: doc_printf(cols[0], "<tab:10><color:B>Drains Mana%s</color>\n", xtra); break; case GF_STUN: doc_printf(cols[0], "<tab:10><color:B>Stuns%s</color>\n", xtra); break; case GF_TURN_ALL: doc_printf(cols[0], "<tab:10><color:r>Terrifies%s</color>\n", xtra); break; case GF_QUAKE: doc_printf(cols[0], "<tab:10><color:B>Shatters%s</color>\n", xtra); break; default: doc_printf(cols[0], "<color:r> %-7.7s</color>: %d (%d-%d)\n", _effect_name(a->effect[i]), blows * (min2 + max2)/200, blows * min2/100, blows * max2/100 ); } } /* Second Column */ doc_insert(cols[1], "<color:G>Accuracy</color>\n"); doc_insert(cols[1], " AC Hit\n"); doc_printf(cols[1], "%3d %2d%%\n", 25, hit_chance_innate(to_h, 25)); doc_printf(cols[1], "%3d %2d%%\n", 50, hit_chance_innate(to_h, 50)); doc_printf(cols[1], "%3d %2d%%\n", 75, hit_chance_innate(to_h, 75)); doc_printf(cols[1], "%3d %2d%%\n", 100, hit_chance_innate(to_h, 100)); doc_printf(cols[1], "%3d %2d%%\n", 125, hit_chance_innate(to_h, 125)); doc_printf(cols[1], "%3d %2d%%\n", 150, hit_chance_innate(to_h, 150)); doc_printf(cols[1], "%3d %2d%%\n", 175, hit_chance_innate(to_h, 175)); doc_printf(cols[1], "%3d %2d%%\n", 200, hit_chance_innate(to_h, 200)); doc_insert_cols(doc, cols, 2, 1); doc_free(cols[0]); doc_free(cols[1]); }
void display_weapon_info(doc_ptr doc, int hand) { object_type *o_ptr = equip_obj(p_ptr->weapon_info[hand].slot); char o_name[MAX_NLEN]; u32b flgs[TR_FLAG_SIZE]; int dd; int ds; int to_d = 0; int to_h = 0; int mult; critical_t crit = {0}; int crit_pct = 0; int num_blow = NUM_BLOWS(hand); bool force = FALSE; doc_ptr cols[2] = {0}; if (p_ptr->weapon_info[hand].wield_how == WIELD_NONE) return; if (!o_ptr) return; dd = o_ptr->dd + p_ptr->weapon_info[hand].to_dd; ds = o_ptr->ds + p_ptr->weapon_info[hand].to_ds; if (object_is_known(o_ptr)) { to_d = o_ptr->to_d; to_h = o_ptr->to_h; } switch (display_weapon_mode) { case MAULER_STUNNING_BLOW: case MAULER_CRITICAL_BLOW: case MAULER_CRUSHING_BLOW: case MAULER_KNOCKBACK: num_blow = 100; break; case MAULER_KNOCKOUT_BLOW: num_blow = 100; to_h -= 50; break; case PY_POWER_ATTACK: to_h += 10; to_d += p_ptr->lev / 2; break; } weapon_flags_known(hand, flgs); if ( (have_flag(flgs, TR_FORCE_WEAPON) || p_ptr->tim_force) && (p_ptr->csp > o_ptr->dd*o_ptr->ds/5) ) { force = TRUE; } if (weaponmaster_get_toggle() == TOGGLE_SHIELD_BASH && object_is_shield(o_ptr)) { dd = 3 + p_ptr->weapon_info[hand].to_dd; ds = o_ptr->ac + p_ptr->weapon_info[hand].to_ds; if (object_is_known(o_ptr)) { to_h = o_ptr->to_a; to_d = o_ptr->to_a; to_h += 2*o_ptr->to_h; to_d += 2*o_ptr->to_d; } } mult = 100; if (have_flag(flgs, TR_VORPAL2)) mult = mult * 5 / 3; else if (have_flag(flgs, TR_VORPAL)) mult = mult * 11 / 9; mult += mult * p_ptr->weapon_info[hand].to_mult / 100; if (display_weapon_mode == MAULER_CRUSHING_BLOW) { int d = p_ptr->lev/5; int n = 10*(1 + d)/2; /* scale by 10 */ mult = mult * (50 + n)/30; } if (!have_flag(flgs, TR_ORDER)) { const int attempts = 10 * 1000; int i; int crits = 0; /* Compute Average Effects of Criticals by sampling */ for (i = 0; i < attempts; i++) { critical_t tmp = critical_norm(o_ptr->weight, to_h, p_ptr->weapon_info[hand].to_h, display_weapon_mode, hand); if (tmp.desc) { crit.mul += tmp.mul; crit.to_d += tmp.to_d; crits++; } else crit.mul += 100; } crit.mul = crit.mul / attempts; crit.to_d = crit.to_d * 100 / attempts; crit_pct = crits * 1000 / attempts; } else crit.mul = 100; /* Display in 2 columns, side by side */ cols[0] = doc_alloc(60); cols[1] = doc_alloc(10); /* Column #1 */ object_desc(o_name, o_ptr, OD_COLOR_CODED | OD_NAME_AND_ENCHANT); if (prace_is_(RACE_MON_SWORD)) doc_printf(cols[0], "<color:y> You :</color> <indent><style:indent>%s</style></indent>\n", o_name); else doc_printf(cols[0], "<color:y> Hand #%d:</color> <indent><style:indent>%s</style></indent>\n", hand+1, o_name); doc_printf(cols[0], " %-7.7s: %d.%d lbs\n", "Weight", o_ptr->weight/10, o_ptr->weight%10); if (weaponmaster_get_toggle() == TOGGLE_SHIELD_BASH) { assert(o_ptr->tval == TV_SHIELD); doc_printf(cols[0], " %-7.7s: %dd%d (%+d,%+d)\n", "Bash", dd, ds, to_h, to_d); doc_printf(cols[0], " %-7.7s: %s (%+d To Hit)\n", "Profic", skills_shield_describe_current(o_ptr->sval), skills_shield_calc_bonus(o_ptr->sval)); } else { doc_printf(cols[0], " %-7.7s: %s (%+d To Hit)\n", "Profic", skills_weapon_describe_current(o_ptr->tval, o_ptr->sval), skills_weapon_calc_bonus(o_ptr->tval, o_ptr->sval)); } doc_printf(cols[0], " %-7.7s: %d + %d = %d\n", "To Hit", to_h, p_ptr->weapon_info[hand].to_h, to_h + p_ptr->weapon_info[hand].to_h); doc_printf(cols[0], " %-7.7s: %d + %d = %d\n", "To Dam", to_d, p_ptr->weapon_info[hand].to_d, to_d + p_ptr->weapon_info[hand].to_d); doc_printf(cols[0], " %-7.7s: %d.%2.2d\n", "Blows", num_blow/100, num_blow%100); if (p_ptr->weapon_info[hand].dual_wield_pct < 1000) { doc_printf(cols[0], " %-7.7s: %d.%d%%\n", "Skill", p_ptr->weapon_info[hand].dual_wield_pct/ 10, p_ptr->weapon_info[hand].dual_wield_pct % 10); } mult = mult * crit.mul / 100; to_d = to_d + crit.to_d/100 + p_ptr->weapon_info[hand].to_d; doc_printf(cols[0], "<color:G> %-7.7s</color>\n", "Damage"); if (!have_flag(flgs, TR_ORDER)) { if (crit.to_d) { doc_printf(cols[0], " %-7.7s: %d.%02dx + %d.%02d\n", "Crits", crit.mul/100, crit.mul%100, crit.to_d/100, crit.to_d%100); } else { doc_printf(cols[0], " %-7.7s: %d.%02dx (%d.%d%%)\n", "Crits", crit.mul/100, crit.mul%100, crit_pct / 10, crit_pct % 10); } } if (p_ptr->weapon_info[hand].to_mult) { int m = 100 + p_ptr->weapon_info[hand].to_mult; doc_printf(cols[0], " %-7.7s: %d.%02dx\n", "Mauler", m / 100, m % 100); } _display_weapon_slay(mult, 100, FALSE, num_blow, dd, ds, to_d, "Normal", TERM_WHITE, cols[0]); if (force) _display_weapon_slay(mult, 100, force, num_blow, dd, ds, to_d, "Force", TERM_L_BLUE, cols[0]); if (p_ptr->tim_slay_sentient) _display_weapon_slay(mult, 200, force, num_blow, dd, ds, to_d, "Sent.", TERM_YELLOW, cols[0]); if (have_flag(flgs, TR_KILL_ANIMAL)) _display_weapon_slay(mult, 400, force, num_blow, dd, ds, to_d, "Animals", TERM_YELLOW, cols[0]); else if (have_flag(flgs, TR_SLAY_ANIMAL)) _display_weapon_slay(mult, 250, force, num_blow, dd, ds, to_d, "Animals", TERM_YELLOW, cols[0]); if (have_flag(flgs, TR_KILL_EVIL)) _display_weapon_slay(mult, 350, force, num_blow, dd, ds, to_d, "Evil", TERM_YELLOW, cols[0]); else if (have_flag(flgs, TR_SLAY_EVIL)) _display_weapon_slay(mult, 200, force, num_blow, dd, ds, to_d, "Evil", TERM_YELLOW, cols[0]); if (have_flag(flgs, TR_SLAY_GOOD)) _display_weapon_slay(mult, 200, force, num_blow, dd, ds, to_d, "Good", TERM_YELLOW, cols[0]); if (have_flag(flgs, TR_SLAY_LIVING)) _display_weapon_slay(mult, 200, force, num_blow, dd, ds, to_d, "Living", TERM_YELLOW, cols[0]); if (have_flag(flgs, TR_KILL_HUMAN)) _display_weapon_slay(mult, 400, force, num_blow, dd, ds, to_d, "Human", TERM_YELLOW, cols[0]); else if (have_flag(flgs, TR_SLAY_HUMAN)) _display_weapon_slay(mult, 250, force, num_blow, dd, ds, to_d, "Human", TERM_YELLOW, cols[0]); if (have_flag(flgs, TR_KILL_UNDEAD)) _display_weapon_slay(mult, 500, force, num_blow, dd, ds, to_d, "Undead", TERM_YELLOW, cols[0]); else if (have_flag(flgs, TR_SLAY_UNDEAD)) _display_weapon_slay(mult, 300, force, num_blow, dd, ds, to_d, "Undead", TERM_YELLOW, cols[0]); if (have_flag(flgs, TR_KILL_DEMON)) _display_weapon_slay(mult, 500, force, num_blow, dd, ds, to_d, "Demons", TERM_YELLOW, cols[0]); else if (have_flag(flgs, TR_SLAY_DEMON)) _display_weapon_slay(mult, 300, force, num_blow, dd, ds, to_d, "Demons", TERM_YELLOW, cols[0]); if (have_flag(flgs, TR_KILL_ORC)) _display_weapon_slay(mult, 500, force, num_blow, dd, ds, to_d, "Orcs", TERM_YELLOW, cols[0]); else if (have_flag(flgs, TR_SLAY_ORC)) _display_weapon_slay(mult, 300, force, num_blow, dd, ds, to_d, "Orcs", TERM_YELLOW, cols[0]); if (have_flag(flgs, TR_KILL_TROLL)) _display_weapon_slay(mult, 500, force, num_blow, dd, ds, to_d, "Trolls", TERM_YELLOW, cols[0]); else if (have_flag(flgs, TR_SLAY_TROLL)) _display_weapon_slay(mult, 300, force, num_blow, dd, ds, to_d, "Trolls", TERM_YELLOW, cols[0]); if (have_flag(flgs, TR_KILL_GIANT)) _display_weapon_slay(mult, 500, force, num_blow, dd, ds, to_d, "Giants", TERM_YELLOW, cols[0]); else if (have_flag(flgs, TR_SLAY_GIANT)) _display_weapon_slay(mult, 300, force, num_blow, dd, ds, to_d, "Giants", TERM_YELLOW, cols[0]); if (have_flag(flgs, TR_KILL_DRAGON)) _display_weapon_slay(mult, 500, force, num_blow, dd, ds, to_d, "Dragons", TERM_YELLOW, cols[0]); else if (have_flag(flgs, TR_SLAY_DRAGON)) _display_weapon_slay(mult, 300, force, num_blow, dd, ds, to_d, "Dragons", TERM_YELLOW, cols[0]); if (have_flag(flgs, TR_BRAND_ACID)) _display_weapon_slay(mult, 250, force, num_blow, dd, ds, to_d, "Acid", TERM_RED, cols[0]); if (have_flag(flgs, TR_BRAND_ELEC)) _display_weapon_slay(mult, 250, force, num_blow, dd, ds, to_d, "Elec", TERM_RED, cols[0]); if (have_flag(flgs, TR_BRAND_FIRE)) _display_weapon_slay(mult, 250, force, num_blow, dd, ds, to_d, "Fire", TERM_RED, cols[0]); if (have_flag(flgs, TR_BRAND_COLD)) _display_weapon_slay(mult, 250, force, num_blow, dd, ds, to_d, "Cold", TERM_RED, cols[0]); if (have_flag(flgs, TR_BRAND_POIS)) _display_weapon_slay(mult, 250, force, num_blow, dd, ds, to_d, "Poison", TERM_RED, cols[0]); if (p_ptr->weapon_info[hand].wield_how == WIELD_TWO_HANDS) { if (p_ptr->weapon_info[hand].omoi) doc_insert(cols[0], " Your weapon requires two hands to wield properly.\n"); } if (p_ptr->weapon_info[hand].info) { byte a = p_ptr->weapon_info[hand].info_attr; if (!a) a = TERM_WHITE; /* uninitialized is TERM_DARK???! */ doc_printf(cols[0], " <color:%c>%s</color>\n", attr_to_attr_char(a), p_ptr->weapon_info[hand].info); } /* Column #1 */ doc_insert(cols[1], "<color:G>Accuracy</color>\n"); doc_insert(cols[1], " AC Hit\n"); doc_printf(cols[1], "%3d %2d%%\n", 25, hit_chance(hand, to_h, 25)); doc_printf(cols[1], "%3d %2d%%\n", 50, hit_chance(hand, to_h, 50)); doc_printf(cols[1], "%3d %2d%%\n", 75, hit_chance(hand, to_h, 75)); doc_printf(cols[1], "%3d %2d%%\n", 100, hit_chance(hand, to_h, 100)); doc_printf(cols[1], "%3d %2d%%\n", 125, hit_chance(hand, to_h, 125)); doc_printf(cols[1], "%3d %2d%%\n", 150, hit_chance(hand, to_h, 150)); doc_printf(cols[1], "%3d %2d%%\n", 175, hit_chance(hand, to_h, 175)); doc_printf(cols[1], "%3d %2d%%\n", 200, hit_chance(hand, to_h, 200)); /* Assemble the result */ doc_insert_cols(doc, cols, 2, 1); doc_free(cols[0]); doc_free(cols[1]); }
static void _shooter_info_aux(doc_ptr doc, object_type *bow, object_type *arrow, int ct) { char o_name[MAX_NLEN]; u32b flgs[TR_FLAG_SIZE]; int mult; int to_h = 0; int to_d = 0; int to_h_bow = 0; int to_d_bow = 0; int to_h_xtra = p_ptr->shooter_info.dis_to_h; int to_d_xtra = p_ptr->shooter_info.dis_to_d; int dd = arrow->dd; int ds = arrow->ds; critical_t crit = {0}; int num_fire = 0; doc_ptr cols[2] = {0}; cols[0] = doc_alloc(60); cols[1] = doc_alloc(10); missile_flags_known(arrow, flgs); mult = bow_mult(bow); if (object_is_artifact(arrow)) num_fire = 100; else if (p_ptr->shooter_info.num_fire) num_fire = p_ptr->shooter_info.num_fire * 100 * 100 / bow_energy(bow->sval); if (object_is_known(bow)) { to_h_bow = bow->to_h; to_d_bow = bow->to_d; if (weaponmaster_is_(WEAPONMASTER_CROSSBOWS) && p_ptr->lev >= 15) to_d_bow += 1 + p_ptr->lev/10; } if (object_is_known(arrow)) { to_h = arrow->to_h; to_d = arrow->to_d; } if (p_ptr->big_shot) dd *= 2; { const int ct = 10 * 1000; int i; /* Compute Average Effects of Criticals by sampling */ for (i = 0; i < ct; i++) { critical_t tmp = critical_shot(arrow->weight, arrow->to_h); if (tmp.desc) { crit.mul += tmp.mul; crit.to_d += tmp.to_d; } else crit.mul += 100; } crit.mul = crit.mul / ct; crit.to_d = crit.to_d * 100 / ct; } /* First Column */ object_desc(o_name, arrow, OD_OMIT_INSCRIPTION | OD_COLOR_CODED); doc_printf(cols[0], "<color:u> Ammo #%-2d</color>: <indent><style:indent>%s</style></indent>\n", ct, o_name); doc_printf(cols[0], " %-8.8s: %d.%d lbs\n", "Weight", arrow->weight/10, arrow->weight%10); doc_printf(cols[0], " %-8.8s: %d + %d = %d\n", "To Hit", to_h, to_h_bow + to_h_xtra, to_h + to_h_bow + to_h_xtra); doc_printf(cols[0], " %-8.8s: %d + %d = %d (%s)\n", "To Dam", to_d, to_d_bow, to_d + to_d_bow, "Multiplier Applies"); doc_printf(cols[0], " <color:G>%-8.8s</color>\n", "Damage"); if (crit.to_d) { doc_printf(cols[0], " %-8.8s: %d.%02dx + %d.%02d\n", "Crits", crit.mul/100, crit.mul%100, crit.to_d/100, crit.to_d%100); } else { doc_printf(cols[0], " %-8.8s: %d.%02dx\n", "Crits", crit.mul/100, crit.mul%100); } to_d = to_d + to_d_bow; mult = mult * crit.mul / 100; to_d_xtra = to_d_xtra + crit.to_d/100; _display_missile_slay(mult, 100, num_fire, dd, ds, to_d, to_d_xtra, "Normal", TERM_WHITE, cols[0]); if (p_ptr->tim_force && p_ptr->csp > (p_ptr->msp / 30)) { mult = mult * 3 / 2; _display_missile_slay(mult, 100, num_fire, dd, ds, to_d, to_d_xtra, "Force", TERM_L_BLUE, cols[0]); } if (have_flag(flgs, TR_KILL_ANIMAL)) _display_missile_slay(mult, 270, num_fire, dd, ds, to_d, to_d_xtra, "Animals", TERM_YELLOW, cols[0]); else if (have_flag(flgs, TR_SLAY_ANIMAL)) _display_missile_slay(mult, 170, num_fire, dd, ds, to_d, to_d_xtra, "Animals", TERM_YELLOW, cols[0]); if (have_flag(flgs, TR_KILL_EVIL)) _display_missile_slay(mult, 250, num_fire, dd, ds, to_d, to_d_xtra, "Evil", TERM_YELLOW, cols[0]); else if (have_flag(flgs, TR_SLAY_EVIL)) _display_missile_slay(mult, 150, num_fire, dd, ds, to_d, to_d_xtra, "Evil", TERM_YELLOW, cols[0]); if (have_flag(flgs, TR_KILL_HUMAN)) _display_missile_slay(mult, 270, num_fire, dd, ds, to_d, to_d_xtra, "Human", TERM_YELLOW, cols[0]); else if (have_flag(flgs, TR_SLAY_HUMAN)) _display_missile_slay(mult, 170, num_fire, dd, ds, to_d, to_d_xtra, "Human", TERM_YELLOW, cols[0]); if (have_flag(flgs, TR_KILL_UNDEAD)) _display_missile_slay(mult, 300, num_fire, dd, ds, to_d, to_d_xtra, "Undead", TERM_YELLOW, cols[0]); else if (have_flag(flgs, TR_SLAY_UNDEAD)) _display_missile_slay(mult, 200, num_fire, dd, ds, to_d, to_d_xtra, "Undead", TERM_YELLOW, cols[0]); if (have_flag(flgs, TR_KILL_DEMON)) _display_missile_slay(mult, 300, num_fire, dd, ds, to_d, to_d_xtra, "Demons", TERM_YELLOW, cols[0]); else if (have_flag(flgs, TR_SLAY_DEMON)) _display_missile_slay(mult, 200, num_fire, dd, ds, to_d, to_d_xtra, "Demons", TERM_YELLOW, cols[0]); if (have_flag(flgs, TR_KILL_ORC)) _display_missile_slay(mult, 300, num_fire, dd, ds, to_d, to_d_xtra, "Orcs", TERM_YELLOW, cols[0]); else if (have_flag(flgs, TR_SLAY_ORC)) _display_missile_slay(mult, 200, num_fire, dd, ds, to_d, to_d_xtra, "Orcs", TERM_YELLOW, cols[0]); if (have_flag(flgs, TR_KILL_TROLL)) _display_missile_slay(mult, 300, num_fire, dd, ds, to_d, to_d_xtra, "Trolls", TERM_YELLOW, cols[0]); else if (have_flag(flgs, TR_SLAY_TROLL)) _display_missile_slay(mult, 200, num_fire, dd, ds, to_d, to_d_xtra, "Trolls", TERM_YELLOW, cols[0]); if (have_flag(flgs, TR_KILL_GIANT)) _display_missile_slay(mult, 300, num_fire, dd, ds, to_d, to_d_xtra, "Giants", TERM_YELLOW, cols[0]); else if (have_flag(flgs, TR_SLAY_GIANT)) _display_missile_slay(mult, 200, num_fire, dd, ds, to_d, to_d_xtra, "Giants", TERM_YELLOW, cols[0]); if (have_flag(flgs, TR_KILL_DRAGON)) _display_missile_slay(mult, 300, num_fire, dd, ds, to_d, to_d_xtra, "Dragons", TERM_YELLOW, cols[0]); else if (have_flag(flgs, TR_SLAY_DRAGON)) _display_missile_slay(mult, 200, num_fire, dd, ds, to_d, to_d_xtra, "Dragons", TERM_YELLOW, cols[0]); if (have_flag(flgs, TR_BRAND_ACID)) _display_missile_slay(mult, 170, num_fire, dd, ds, to_d, to_d_xtra, "Acid", TERM_RED, cols[0]); if (have_flag(flgs, TR_BRAND_ELEC)) _display_missile_slay(mult, 170, num_fire, dd, ds, to_d, to_d_xtra, "Elec", TERM_RED, cols[0]); if (have_flag(flgs, TR_BRAND_FIRE)) _display_missile_slay(mult, 170, num_fire, dd, ds, to_d, to_d_xtra, "Fire", TERM_RED, cols[0]); if (have_flag(flgs, TR_BRAND_COLD)) _display_missile_slay(mult, 170, num_fire, dd, ds, to_d, to_d_xtra, "Cold", TERM_RED, cols[0]); if (have_flag(flgs, TR_BRAND_POIS)) _display_missile_slay(mult, 170, num_fire, dd, ds, to_d, to_d_xtra, "Poison", TERM_RED, cols[0]); /* Second Column */ to_h = to_h + to_h_bow + to_h_xtra; doc_insert(cols[1], " <color:G>AC Hit</color>\n"); doc_printf(cols[1], "%3d %2d%%\n", 25, bow_hit_chance(bow->sval, to_h, 25)); doc_printf(cols[1], "%3d %2d%%\n", 50, bow_hit_chance(bow->sval, to_h, 50)); doc_printf(cols[1], "%3d %2d%%\n", 100, bow_hit_chance(bow->sval, to_h, 100)); doc_printf(cols[1], "%3d %2d%%\n", 150, bow_hit_chance(bow->sval, to_h, 150)); doc_printf(cols[1], "%3d %2d%%\n", 175, bow_hit_chance(bow->sval, to_h, 175)); doc_printf(cols[1], "%3d %2d%%\n", 200, bow_hit_chance(bow->sval, to_h, 200)); doc_insert_cols(doc, cols, 2, 1); doc_free(cols[0]); doc_free(cols[1]); }
static void _spoil_table_aux(doc_ptr doc, cptr title, _obj_p pred, int options) { int i; vec_ptr entries = vec_alloc(free); int ct_std = 0, ct_rnd = 0, ct_ego = 0; int score_std = 0, score_rnd = 0, score_ego = 0; int max_score_std = 0, max_score_rnd = 0, max_score_ego = 0; if ((options & _SPOIL_ARTS) && !random_artifacts) { for (i = 1; i < max_a_idx; ++i) { object_type forge = {0}; _art_info_ptr entry; if (!p_ptr->wizard && (a_info[i].gen_flags & OFG_QUESTITEM)) continue; if (!create_named_art_aux(i, &forge)) continue; if ((options & _SPOIL_EGOS) && !a_info[i].found) continue; /* Hack */ if (pred && !pred(&forge)) continue; obj_identify_fully(&forge); entry = malloc(sizeof(_art_info_t)); entry->id = i; if (p_ptr->prace == RACE_ANDROID) { entry->score = android_obj_exp(&forge); if (!entry->score) entry->score = obj_value_real(&forge); } else entry->score = obj_value_real(&forge); object_desc(entry->name, &forge, OD_COLOR_CODED); entry->k_idx = forge.k_idx; vec_add(entries, entry); if (a_info[entry->id].found) { ct_std++; score_std += entry->score; if (entry->score > max_score_std) max_score_std = entry->score; } } } if (options & _SPOIL_RAND_ARTS) { vec_ptr v = stats_rand_arts(); for (i = 0; i < vec_length(v); i++) { object_type *o_ptr = vec_get(v, i); _art_info_ptr entry; if (pred && !pred(o_ptr)) continue; entry = malloc(sizeof(_art_info_t)); entry->id = ART_RANDOM; if (p_ptr->prace == RACE_ANDROID) { entry->score = android_obj_exp(o_ptr); if (!entry->score) entry->score = obj_value_real(o_ptr); } else entry->score = obj_value_real(o_ptr); object_desc(entry->name, o_ptr, OD_COLOR_CODED); entry->k_idx = o_ptr->k_idx; vec_add(entries, entry); ct_rnd++; score_rnd += entry->score; if (entry->score > max_score_rnd) max_score_rnd = entry->score; } } if (options & _SPOIL_EGOS) { vec_ptr v = stats_egos(); for (i = 0; i < vec_length(v); i++) { object_type *o_ptr = vec_get(v, i); _art_info_ptr entry; if (pred && !pred(o_ptr)) continue; entry = malloc(sizeof(_art_info_t)); entry->id = ART_EGO; if (p_ptr->prace == RACE_ANDROID) { entry->score = android_obj_exp(o_ptr); if (!entry->score) entry->score = obj_value_real(o_ptr); } else entry->score = obj_value_real(o_ptr); object_desc(entry->name, o_ptr, OD_COLOR_CODED); entry->k_idx = o_ptr->k_idx; vec_add(entries, entry); ct_ego++; score_ego += entry->score; if (entry->score > max_score_ego) max_score_ego = entry->score; } } if (vec_length(entries)) { vec_sort(entries, (vec_cmp_f)_art_score_cmp); doc_printf(doc, "<topic:%s><style:heading>%s</style>\n\n", title, title); doc_insert(doc, "<style:wide> <color:G> Score Lvl Rty Cts Object Description</color>\n"); for (i = 0; i < vec_length(entries); i++) { _art_info_ptr entry = vec_get(entries, i); if (entry->id == ART_RANDOM) { doc_printf(doc, "<color:v>%3d) %7d</color> %3d ", i+1, entry->score, k_info[entry->k_idx].counts.found); doc_printf(doc, "<indent><style:indent>%s</style></indent>\n", entry->name); } else if (entry->id == ART_EGO) { doc_printf(doc, "<color:B>%3d) %7d</color> %3d ", i+1, entry->score, k_info[entry->k_idx].counts.found); doc_printf(doc, "<indent><style:indent>%s</style></indent>\n", entry->name); } else { artifact_type *a_ptr = &a_info[entry->id]; doc_printf(doc, "<color:%c>%3d) %7d</color> %3d %3d ", (a_ptr->found) ? 'y' : 'w', i+1, entry->score, a_ptr->level, a_ptr->rarity); if (a_ptr->gen_flags & OFG_INSTA_ART) doc_insert(doc, " "); else doc_printf(doc, "%3d ", k_info[entry->k_idx].counts.found); doc_printf(doc, "<indent><style:indent>%s <color:D>#%d</color></style></indent>\n", entry->name, entry->id); } } if (ct_std || ct_rnd || ct_ego) { doc_printf(doc, "\n<color:G>%20.20s Ct Average Best</color>\n", ""); if (ct_std) { doc_printf(doc, "<color:B>%20.20s</color> %4d %7d %7d\n", "Stand Arts", ct_std, score_std/ct_std, max_score_std); } if (ct_rnd) { doc_printf(doc, "<color:B>%20.20s</color> %4d %7d %7d\n", "Rand Arts", ct_rnd, score_rnd/ct_rnd, max_score_rnd); } if (ct_ego) { doc_printf(doc, "<color:B>%20.20s</color> %4d %7d %7d\n", "Egos", ct_ego, score_ego/ct_ego, max_score_ego); } } doc_insert(doc, "</style>\n\n"); } vec_free(entries); }