static void _spoil_spell_book(doc_ptr doc, int class_idx, int realm_idx, int book_idx) { int spell_idx; int k_idx = lookup_kind(realm2tval(realm_idx), book_idx); player_magic *magic_ptr = &m_info[class_idx]; doc_printf(doc, "<color:o>%-25.25s</color><color:G> 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 *spell_ptr = NULL; if (is_magic(realm_idx)) spell_ptr = &magic_ptr->info[realm_idx - 1][spell_idx]; else spell_ptr = &technic_info[realm_idx - MIN_TECHNIC][spell_idx]; if (0 < spell_ptr->slevel && spell_ptr->slevel <= PY_MAX_LEVEL) { doc_printf(doc, "%-25.25s %3d %3d %3d%%\n", do_spell(realm_idx, spell_idx, SPELL_NAME), spell_ptr->slevel, spell_ptr->smana, spell_ptr->sfail ); } else { doc_printf(doc, "<color:D>%-26.26s</color>\n", "Illegible"); } } doc_newline(doc); }
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)); } }
static void _display_missile_slay(int base_mult, int slay_mult, int shots, int dd, int ds, int to_d, int to_d_xtra, cptr name, int color, doc_ptr doc) { int mult, min, max; mult = slay_mult; mult = mult * base_mult / 100; if (p_ptr->concent) { min = shots * (boost_concentration_damage(mult*(dd + to_d)/100) + to_d_xtra) / 100; max = shots * (boost_concentration_damage(mult*(dd*ds + to_d)/100) + to_d_xtra) / 100; } else { min = shots * (mult*(dd + to_d)/100 + to_d_xtra) / 100; max = shots * (mult*(dd*ds + to_d)/100 + to_d_xtra) / 100; } doc_printf(doc, " <color:%c>%-8.8s</color>", attr_to_attr_char(color), name); doc_printf(doc, ": %d (%d-%d) [%d.%02dx]\n", (min + max)/2, min, max, mult/100, mult%100); }
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); }
void spellbook_character_dump(doc_ptr doc) { doc_printf(doc, "<topic:Spells>==================================== <color:keypress>S</color>pells ===================================\n\n"); if (p_ptr->pclass == CLASS_RED_MAGE || p_ptr->pclass == CLASS_SORCERER) { int realm; for (realm = REALM_LIFE; realm <= MAX_MAGIC; realm++) _dump_realm(doc, realm); } else { if (p_ptr->realm1) _dump_realm(doc, p_ptr->realm1); if (p_ptr->realm2) _dump_realm(doc, p_ptr->realm2); } if (p_ptr->old_realm) { int i; for (i = 0; i < MAX_MAGIC; i++) { if (!(p_ptr->old_realm & 1L << i)) continue; doc_printf(doc, " You were able to use %s magic before.\n", realm_names[i+1]); } doc_newline(doc); } }
static void spoil_spells_by_class(void) { int i, realm_idx; doc_ptr doc = doc_alloc(80); vec_ptr vec = vec_alloc(NULL); for (i = 0; i < MAX_CLASS; i++) vec_add_int(vec, i); vec_sort(vec, (vec_cmp_f)_cmp_class_name); for (i = 0; i < vec_length(vec); i++) { int class_idx = vec_get_int(vec, i); class_t *class_ptr = get_class_aux(class_idx, 0); bool class_heading = FALSE; if (class_idx == CLASS_RAGE_MAGE) continue; /* broken */ for (realm_idx = REALM_LIFE; realm_idx <= MAX_REALM; realm_idx++) { if (_check_realm(class_idx, realm_idx)) { doc_ptr cols[2]; cols[0] = doc_alloc(40); cols[1] = doc_alloc(40); _spoil_spell_book(cols[0], class_idx, realm_idx, 0); _spoil_spell_book(cols[1], class_idx, realm_idx, 1); if (class_idx != CLASS_RED_MAGE || realm_idx == REALM_ARCANE) { _spoil_spell_book(cols[0], class_idx, realm_idx, 2); _spoil_spell_book(cols[1], class_idx, realm_idx, 3); } if (!class_heading) { doc_printf(doc, "<topic:%s><color:r>%s</color>\n", class_ptr->name, class_ptr->name); doc_printf(doc, "%s\n\n", class_ptr->desc); class_heading = TRUE; } doc_printf(doc, "<color:B>%s</color>\n", realm_names[realm_idx]); doc_insert_cols(doc, cols, 2, 0); doc_free(cols[0]); doc_free(cols[1]); } } } doc_display(doc, "Spells by Class", 0); doc_free(doc); vec_free(vec); }
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; }
static void _dump_realm(doc_ptr doc, int realm) { int i; bool first = TRUE; for (i = 0; i < 4; i++) { bool dump = FALSE; /* Red Mages only learn from first 2 books (except for Arcane) */ if (p_ptr->pclass == CLASS_RED_MAGE && realm != REALM_ARCANE && i > 1) break; /* Necromancy probably should be a technique ... Too late now :( */ if (p_ptr->pclass == CLASS_RED_MAGE && realm == REALM_NECROMANCY) break; /* Red Mages and Sorcerers don't learn spells, so make sure the user actually has the book in their pack (otherwise we spoil ... ) */ if (p_ptr->pclass == CLASS_RED_MAGE || p_ptr->pclass == CLASS_SORCERER) dump = _has_book(realm, i); else dump = _has_spells(realm, i) || _has_book(realm, i); if (dump) { if (first) { doc_printf(doc, "<color:r>Realm:</color> <color:B>%s</color>\n\n", realm_names[realm]); first = FALSE; } _dump_book(doc, realm, i); } } }
static void spoil_mon_info() { int i; vec_ptr v = vec_alloc(NULL); doc_ptr doc = doc_alloc(80); spoiler_hack = TRUE; for (i = 1; i < max_r_idx; i++) { monster_race *r_ptr = &r_info[i]; if (!r_ptr->name) continue; if (r_ptr->id == MON_MONKEY_CLONE) continue; if (r_ptr->id == MON_KAGE) continue; vec_add(v, r_ptr); } vec_sort(v, (vec_cmp_f)_compare_r_level_desc); for (i = 0; i < vec_length(v); i++) { monster_race *r_ptr = vec_get(v, i); doc_printf(doc, "<topic:%s><color:r>=====================================================================</color>\n", r_name + r_ptr->name); mon_display_doc(r_ptr, doc); doc_newline(doc); } vec_free(v); doc_display(doc, "Monster Spoilers", 0); doc_free(doc); spoiler_hack = FALSE; }
static void _character_dump(doc_ptr doc) { int i; spell_info spells[MAX_SPELLS]; int ct = _get_spells_imp(spells, MAX_SPELLS, 0, _MAX_TALENTS - 1); for (i = 0; i < ct; i++) { spell_info* current = &spells[i]; current->cost += get_spell_cost_extra(current->fn); current->fail = MAX(current->fail, get_spell_fail_min(current->fn)); } if (ct > 0) { int i; variant name, info; var_init(&name); var_init(&info); doc_printf(doc, "<topic:WildTalent>================================= <color:keypress>W</color>ild Talents ================================\n\n"); doc_printf(doc, "<color:G>%-23.23s Lv Stat Cost Fail Info</color>\n", ""); for (i = 0; i < ct; ++i) { spell_info *spell = &spells[i]; (spell->fn)(SPELL_NAME, &name); (spell->fn)(SPELL_INFO, &info); doc_printf(doc, "%-23.23s %2d %4.4s %4d %3d%% %s\n", var_get_string(&name), spell->level, stat_abbrev_true[_which_stat(i)], spell->cost, spell->fail, var_get_string(&info)); } var_clear(&name); var_clear(&info); doc_newline(doc); } }
/********************************************************************** * Display Weapon Information to the Player **********************************************************************/ static void _display_weapon_slay(int base_mult, int slay_mult, bool force, int blows, int dd, int ds, int to_d, cptr name, int color, doc_ptr doc) { int mult, min, max; mult = slay_mult; if (force) mult = mult * 3/2 + 150; mult = mult * base_mult / 100; min = blows * (mult*dd/100 + to_d) / 100; max = blows * (mult*dd*ds/100 + to_d) / 100; doc_printf(doc, "<color:%c> %-7.7s</color>", attr_to_attr_char(color), name); doc_printf(doc, ": %d (%d-%d) [%d.%02dx]\n", (min + max)/2, min, max, mult/100, mult%100); }
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 _character_dump(doc_ptr doc) { int i; bool first = TRUE; for (i = 0; i < _MAX_FORMS; i++) { if (_forms[i]) { if (first) { doc_printf(doc, "<topic:LearnedForms>================================ <color:keypress>L</color>earned Forms ================================\n\n"); first = FALSE; } doc_printf(doc, " %s\n", r_name + r_info[_forms[i]].name); } } doc_newline(doc); possessor_character_dump(doc); }
void display_shooter_info(doc_ptr doc) { object_type *bow_ptr = NULL; int slot = equip_find_object(TV_BOW, SV_ANY); char o_name[MAX_NLEN]; int mult; int num_fire = 0; int to_h = 0; int to_d = 0; int i, j; if (!slot || prace_is_(RACE_MON_JELLY) || p_ptr->shooter_info.tval_ammo == TV_NO_AMMO) return; bow_ptr = equip_obj(slot); assert(bow_ptr); mult = bow_mult(bow_ptr); if (p_ptr->shooter_info.num_fire) num_fire = p_ptr->shooter_info.num_fire * 100 * 100 / bow_energy(bow_ptr->sval); if (object_is_known(bow_ptr)) { to_h = bow_ptr->to_h; to_d = bow_ptr->to_d; if (weaponmaster_is_(WEAPONMASTER_CROSSBOWS) && p_ptr->lev >= 15) to_d += 1 + p_ptr->lev/10; } /* Shooter */ object_desc(o_name, bow_ptr, OD_OMIT_INSCRIPTION | OD_COLOR_CODED); doc_printf(doc, " <color:y>Shooting</color>: <indent><style:indent>%s</style></indent>\n", o_name); doc_printf(doc, " %-8.8s: %d'\n", "Range", (bow_range(bow_ptr) + 1) * 10); doc_printf(doc, " %-8.8s: %d.%02d\n", "Shots", num_fire/100, num_fire%100); doc_printf(doc, " %-8.8s: %d.%02dx\n", "Mult", mult/100, mult%100); doc_printf(doc, " %-8.8s: %d + %d = %d\n", "To Hit", to_h, p_ptr->shooter_info.dis_to_h, to_h + p_ptr->shooter_info.dis_to_h); doc_printf(doc, " %-8.8s: %d (%s)\n", "To Dam", to_d, "Multiplier Applies"); doc_printf(doc, " %-8.8s: %d (%s)\n", "Xtra Dam", p_ptr->shooter_info.dis_to_d, "Multiplier Does Not Apply"); doc_newline(doc); /* Ammo */ j = 0; for (i = 0; i < INVEN_PACK; i++) { if (inventory[i].tval == p_ptr->shooter_info.tval_ammo) _shooter_info_aux(doc, bow_ptr, &inventory[i], ++j); } }
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); }
static void _dump_book(doc_ptr doc, int realm, int book) { int k_idx = lookup_kind(realm2tval(realm), book); int i, increment = 64; caster_info *caster_ptr = get_caster_info(); if ((p_ptr->pclass == CLASS_SORCERER) || (p_ptr->pclass == CLASS_RED_MAGE)) increment = 0; else if (realm == p_ptr->realm1) increment = 0; else if (realm == p_ptr->realm2) increment = 32; if (realm == REALM_HISSATSU) { doc_printf(doc, "<color:G> %-25.25s Lvl SP %-15.15s Cast</color>\n", k_name + k_info[k_idx].name, "Desc"); } else { if (caster_ptr && (caster_ptr->options & CASTER_USE_HP)) doc_printf(doc, "<color:G> %-23.23s Profic Lvl HP Fail %-15.15s Cast Fail</color>\n", k_name + k_info[k_idx].name, "Desc"); else doc_printf(doc, "<color:G> %-23.23s Profic Lvl SP Fail %-15.15s Cast Fail</color>\n", k_name + k_info[k_idx].name, "Desc"); } for (i = 0; i < 8; i++) { int s_idx = book * 8 + i; magic_type *s_ptr; int cost; bool max = FALSE; char proficiency[10]; char info[80]; cptr comment; char line[160]; char color = 'w'; if (is_magic(realm)) s_ptr = &mp_ptr->info[realm - 1][s_idx]; else s_ptr = &technic_info[realm - MIN_TECHNIC][s_idx]; if (s_ptr->slevel >= 99) continue; if (realm == REALM_HISSATSU) cost = s_ptr->smana; else { s16b exp = experience_of_spell(s_idx, realm); int exp_level = spell_exp_level(exp); cost = mod_need_mana(s_ptr->smana, s_idx, realm); max = FALSE; if (!increment && (exp_level == EXP_LEVEL_MASTER)) max = TRUE; else if ((increment == 32) && (exp_level >= EXP_LEVEL_EXPERT)) max = TRUE; else if ((p_ptr->pclass == CLASS_RED_MAGE) && (exp_level >= EXP_LEVEL_SKILLED)) max = TRUE; strncpy(proficiency, exp_level_str[exp_level], 4); proficiency[3] = ']'; proficiency[4] = '\0'; } strcpy(info, do_spell(realm, s_idx, SPELL_INFO)); comment = info; if (p_ptr->pclass == CLASS_SORCERER || p_ptr->pclass == CLASS_RED_MAGE) { if (s_ptr->slevel > p_ptr->max_plv) { comment = "unknown"; color = 'D'; } else if (s_ptr->slevel > p_ptr->lev) { comment = "forgotten"; color = 'y'; } } else if ((realm == p_ptr->realm1) ? ((p_ptr->spell_forgotten1 & (1L << s_idx))) : ((p_ptr->spell_forgotten2 & (1L << s_idx)))) { comment = "forgotten"; color = 'y'; } else if (!((realm == p_ptr->realm1) ? (p_ptr->spell_learned1 & (1L << s_idx)) : (p_ptr->spell_learned2 & (1L << s_idx)))) { comment = "unknown"; if (s_ptr->slevel > p_ptr->lev) color = 'D'; else color = 'B'; } else if (!((realm == p_ptr->realm1) ? (p_ptr->spell_worked1 & (1L << s_idx)) : (p_ptr->spell_worked2 & (1L << s_idx)))) { comment = "untried"; } sprintf(line, " %c) ", I2A(i)); if (realm == REALM_HISSATSU) { spell_stats_ptr stats = spell_stats_old(realm, s_idx); strcat( line, format( "<color:%c>%-25s %3d %3d %-15.15s %5d</color>", color, do_spell(realm, s_idx, SPELL_NAME), s_ptr->slevel, cost, comment, stats->ct_cast ) ); } else { spell_stats_ptr stats = spell_stats_old(realm, s_idx); strcat( line, format( "<color:%c>%-25s%c%-4s %3d %3d %3d%% %-15.15s %5d %4d %3d%%</color>", color, do_spell(realm, s_idx, SPELL_NAME), (max ? '!' : ' '), proficiency, s_ptr->slevel, cost, spell_chance(s_idx, realm), comment, stats->ct_cast, stats->ct_fail, spell_stats_fail(stats) ) ); } doc_printf(doc, "%s\n", line); } doc_newline(doc); }
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); }
/********************************************************************** * Private Helpers **********************************************************************/ static void _character_dump(doc_ptr doc) { doc_printf(doc, "<topic:Spells>==================================== <color:keypress>S</color>pells ===================================\n\n"); _list_spells(doc, _SHOW_INFO | _SHOW_STATS); doc_newline(doc); }
static void _character_dump(doc_ptr doc) { int ct = _count_open_terrain(); bool disrupt = heavy_armor(); if (!disrupt && p_ptr->lev >= 5) { spell_info spells[MAX_SPELLS]; int ct = _get_spells(spells, MAX_SPELLS); py_display_spells(doc, spells, ct); } doc_printf(doc, "<topic:Abilities>================================== <color:keypress>A</color>bilities ==================================\n\n"); /* Hack: Heavy Armor negates advantages of being in the open, and actually incurs penalties for being entrenched! */ if (disrupt) { doc_printf(doc, " * Your talents are disrupted by the weight of your armor.\n"); ct = 0; } else { if (ct >= 6) doc_printf(doc, " * You are out in the open (%d adjacent open squares).\n", ct); else if (ct >= 3) doc_printf(doc, " * You are somewhat confined (%d adjacent open squares).\n", ct); else doc_printf(doc, " * You are very confined (%d adjacent open squares).\n", ct); } /* Unfettered Body */ if (p_ptr->lev >= 1) { int amt = _unfettered_body(ct); if (amt > 0) doc_printf(doc, " * You gain %+d to your AC being out in the open.\n", amt); else if (amt < 0) doc_printf(doc, " * You lose %+d to your AC being so confined.\n", amt); } /* Unfettered Mind */ if (p_ptr->lev >= 1) { int amt = _unfettered_mind(ct); if (amt > 0) doc_printf(doc, " * You gain %+d to your Saving Throws being out in the open.\n", amt); else if (amt < 0) doc_printf(doc, " * You lose %+d to your Saving Throws being so confined.\n", amt); } if (!disrupt && p_ptr->lev >= 20) doc_printf(doc, " * You ambush sleeping monsters for extra damage.\n"); if (!disrupt && p_ptr->lev >= 50) doc_printf(doc, " * You have Peerless Stealth and will never aggravate monsters.\n"); doc_newline(doc); }
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]); }
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]); }
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]); }
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]); }