Example #1
0
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]);
}
Example #2
0
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]);
}