/** * Special display, part 2c * * How to print out the modifications and sustains. * Positive mods with no sustain will be light green. * Positive mods with a sustain will be dark green. * Sustains (with no modification) will be a dark green 's'. * Negative mods (from a curse) will be red. * Huge mods (>9), like from MICoMorgoth, will be a '*' * No mod, no sustain, will be a slate '.' */ static void display_player_sust_info(void) { int i, row, col, stat; struct object *obj; bitflag f[OF_SIZE]; byte a; char c; /* Row */ row = 2; /* Column */ col = 26; /* Header */ c_put_str(COLOUR_WHITE, "abcdefghijkl@", row-1, col); /* Process equipment */ for (i = 0; i < player->body.count; ++i) { /* Get the object */ obj = slot_object(player, i); if (!obj) { col++; continue; } /* Get the "known" flags */ object_flags_known(obj, f); /* Initialize color based on sign of modifier. */ for (stat = OBJ_MOD_MIN_STAT; stat < OBJ_MOD_MIN_STAT + STAT_MAX; stat++) { /* Default */ a = COLOUR_SLATE; c = '.'; /* Boosted or reduced */ if (obj->modifiers[stat] > 0) { /* Good */ a = COLOUR_L_GREEN; /* Label boost */ if (obj->modifiers[stat] < 10) c = I2D(obj->modifiers[stat]); } else if (obj->modifiers[stat] < 0) { /* Bad */ a = COLOUR_RED; /* Label boost */ if (obj->modifiers[stat] > -10) c = I2D(-(obj->modifiers[stat])); } /* Sustain */ if (of_has(f, sustain_flag(stat))) { /* Dark green */ a = COLOUR_GREEN; /* Convert '.' to 's' */ if (c == '.') c = 's'; } if ((c == '.') && obj && !object_flag_is_known(obj, sustain_flag(stat))) c = '?'; /* Dump proper character */ Term_putch(col, row+stat, a, c); } /* Advance */ col++; } /* Player flags */ player_flags(player, f); /* Check stats */ for (stat = 0; stat < STAT_MAX; ++stat) { /* Default */ a = COLOUR_SLATE; c = '.'; /* Sustain */ if (of_has(f, sustain_flag(stat))) { /* Dark green "s" */ a = COLOUR_GREEN; c = 's'; } /* Dump */ Term_putch(col, row+stat, a, c); } /* Column */ col = 26; /* Footer */ c_put_str(COLOUR_WHITE, "abcdefghijkl@", row+6, col); /* Equippy */ display_player_equippy(row+7, col); }
static void display_resistance_panel(const struct player_flag_record *rec, size_t size, const region *bounds) { size_t i; int j; int col = bounds->col; int row = bounds->row; int res_cols = 5 + 2 + player->body.count; Term_putstr(col, row++, res_cols, COLOUR_WHITE, " abcdefghijkl@"); for (i = 0; i < size - 3; i++, row++) { byte name_attr = COLOUR_WHITE; Term_gotoxy(col + 6, row); /* Repeated extraction of flags is inefficient but more natural */ for (j = 0; j <= player->body.count; j++) { struct object *obj; bitflag f[OF_SIZE]; byte attr = COLOUR_WHITE | (j % 2) * 8; /* alternating columns */ char sym = '.'; bool res = false, imm = false, vul = false, rune = false; bool timed = false; bool known = false; /* Wipe flagset */ of_wipe(f); /* Get the object or player info */ obj = j < player->body.count ? slot_object(player, j) : NULL; if (j < player->body.count && obj) { /* Get known properties */ object_flags_known(obj, f); if (rec[i].element != -1) known = object_element_is_known(obj, rec[i].element); else if (rec[i].flag != -1) known = object_flag_is_known(obj, rec[i].flag); else known = true; } else if (j == player->body.count) { player_flags(player, f); known = true; /* Timed flags only in the player column */ if (rec[i].tmd_flag >= 0) { timed = player->timed[rec[i].tmd_flag] ? true : false; /* There has to be one special case... */ if ((rec[i].tmd_flag == TMD_AFRAID) && (player->timed[TMD_TERROR])) timed = true; } } /* Set which (if any) symbol and color are used */ if (rec[i].mod != -1) { if (j != player->body.count) res = (obj && (obj->modifiers[rec[i].mod] != 0)); else { /* Messy special cases */ if (rec[i].mod == OBJ_MOD_INFRA) res = (player->race->infra > 0); if (rec[i].mod == OBJ_MOD_TUNNEL) res = (player->race->r_skills[SKILL_DIGGING] > 0); } rune = (player->obj_k->modifiers[rec[i].mod] == 1); } else if (rec[i].flag != -1) { res = of_has(f, rec[i].flag); rune = of_has(player->obj_k->flags, rec[i].flag); } else if (rec[i].element != -1) { if (j != player->body.count) { imm = obj && known && (obj->el_info[rec[i].element].res_level == 3); res = obj && known && (obj->el_info[rec[i].element].res_level == 1); vul = obj && known && (obj->el_info[rec[i].element].res_level == -1); } else { imm = player->race->el_info[rec[i].element].res_level == 3; res = player->race->el_info[rec[i].element].res_level == 1; vul = player->race->el_info[rec[i].element].res_level == -1; } rune = (player->obj_k->el_info[rec[i].element].res_level == 1); } /* Set the symbols and print them */ if (imm) name_attr = COLOUR_GREEN; else if (!rune) name_attr = COLOUR_SLATE; else if (res && (name_attr != COLOUR_GREEN)) name_attr = COLOUR_L_BLUE; if (vul) sym = '-'; else if (imm) sym = '*'; else if (res) sym = '+'; else if (timed) { sym = '!'; attr = COLOUR_L_GREEN; } else if ((j < player->body.count) && obj && !known && !rune) sym = '?'; Term_addch(attr, sym); } Term_putstr(col, row, 6, name_attr, format("%5s:", rec[i].name)); } Term_putstr(col, row++, res_cols, COLOUR_WHITE, " abcdefghijkl@"); /* Equippy */ display_player_equippy(row++, col + 6); }
static void display_resistance_panel(const struct player_flag_record *rec, size_t size, const region *bounds) { size_t i; int j; int col = bounds->col; int row = bounds->row; int res_cols = 5 + 2 + player->body.count; Term_putstr(col, row++, res_cols, COLOUR_WHITE, " abcdefghijkl@"); for (i = 0; i < size - 3; i++, row++) { byte name_attr = COLOUR_WHITE; Term_gotoxy(col + 6, row); /* Repeated extraction of flags is inefficient but more natural */ for (j = 0; j <= player->body.count; j++) { bitflag f[OF_SIZE]; byte attr = COLOUR_WHITE | (j % 2) * 8; /* alternating columns */ char sym = '.'; bool res = false, imm = false, vul = false, rune = false; bool timed = false; bool known = false; /* Object or player info? */ if (j < player->body.count) { int index = 0; struct object *obj = slot_object(player, j); struct curse_data *curse = obj ? obj->curses : NULL; while (obj) { /* Wipe flagset */ of_wipe(f); /* Get known properties */ object_flags_known(obj, f); if (rec[i].element != -1) { known = object_element_is_known(obj, rec[i].element); } else if (rec[i].flag != -1) { known = object_flag_is_known(obj, rec[i].flag); } else { known = true; } /* Get resistance, immunity and vulnerability info */ if (rec[i].mod != -1) { if (obj->modifiers[rec[i].mod] != 0) { res = true; } rune = (player->obj_k->modifiers[rec[i].mod] == 1); } else if (rec[i].flag != -1) { if (of_has(f, rec[i].flag)) { res = true; } rune = of_has(player->obj_k->flags, rec[i].flag); } else if (rec[i].element != -1) { if (known) { if (obj->el_info[rec[i].element].res_level == 3) { imm = true; } if (obj->el_info[rec[i].element].res_level == 1) { res = true; } if (obj->el_info[rec[i].element].res_level == -1) { vul = true; } } rune = (player->obj_k->el_info[rec[i].element].res_level == 1); } /* Move to any unprocessed curse object */ if (curse) { index++; obj = NULL; while (index < z_info->curse_max) { if (curse[index].power) { obj = curses[index].obj; break; } else { index++; } } } else { obj = NULL; } } } else { player_flags(player, f); known = true; /* Timed flags only in the player column */ if (rec[i].tmd_flag >= 0) { timed = player->timed[rec[i].tmd_flag] ? true : false; /* There has to be one special case... */ if ((rec[i].tmd_flag == TMD_AFRAID) && (player->timed[TMD_TERROR])) timed = true; } /* Set which (if any) symbol and color are used */ if (rec[i].mod != -1) { int k; /* Shape modifiers */ for (k = 0; k < OBJ_MOD_MAX; k++) { res = (player->shape->modifiers[i] > 0); vul = (player->shape->modifiers[i] > 0); } /* Messy special cases */ if (rec[i].mod == OBJ_MOD_INFRA) res |= (player->race->infra > 0); if (rec[i].mod == OBJ_MOD_TUNNEL) res |= (player->race->r_skills[SKILL_DIGGING] > 0); } else if (rec[i].flag != -1) { res = of_has(f, rec[i].flag); res |= (of_has(player->shape->flags, rec[i].flag) && of_has(player->obj_k->flags, rec[i].flag)); } else if (rec[i].element != -1) { int el = rec[i].element; imm = (player->race->el_info[el].res_level == 3) || ((player->shape->el_info[el].res_level == 3) && (player->obj_k->el_info[el].res_level)); res = (player->race->el_info[el].res_level == 1) || ((player->shape->el_info[el].res_level == 1) && (player->obj_k->el_info[el].res_level)); vul = (player->race->el_info[el].res_level == -1) || ((player->shape->el_info[el].res_level == -1) && (player->obj_k->el_info[el].res_level)); } } /* Colour the name appropriately */ if (imm) { name_attr = COLOUR_GREEN; } else if (res && (name_attr != COLOUR_GREEN)) { name_attr = COLOUR_L_BLUE; } else if (vul && (name_attr != COLOUR_GREEN)) { name_attr = COLOUR_RED; } /* Set the symbols and print them */ if (vul) { sym = '-'; } else if (imm) { sym = '*'; } else if (res) { sym = '+'; } else if (timed) { sym = '!'; attr = COLOUR_L_GREEN; } else if ((j < player->body.count) && slot_object(player, j) && !known && !rune) { sym = '?'; } Term_addch(attr, sym); } /* Check if the rune is known */ if (((rec[i].mod >= 0) && (player->obj_k->modifiers[rec[i].mod] == 0)) || ((rec[i].flag >= 0) && !of_has(player->obj_k->flags, rec[i].flag)) || ((rec[i].element >= 0) && (player->obj_k->el_info[rec[i].element].res_level == 0))) { name_attr = COLOUR_SLATE; } Term_putstr(col, row, 6, name_attr, format("%5s:", rec[i].name)); } Term_putstr(col, row++, res_cols, COLOUR_WHITE, " abcdefghijkl@"); /* Equippy */ display_player_equippy(row++, col + 6); }
/* * Special display, part 2c * * How to print out the modifications and sustains. * Positive mods with no sustain will be light green. * Positive mods with a sustain will be dark green. * Sustains (with no modification) will be a dark green 's'. * Negative mods (from a curse) will be red. * Huge mods (>9), like from MICoMorgoth, will be a '*' * No mod, no sustain, will be a slate '.' */ static void display_player_sust_info(void) { int i, j, row, col, stat; object_type *o_ptr; bitflag f[OF_SIZE]; int stat_flags[A_MAX]; int sustain_flags[A_MAX]; byte a; char c; /* Row */ row = 2; /* Column */ col = 26; /* Build the stat flags tables */ stat_flags[A_STR] = OF_STR; stat_flags[A_INT] = OF_INT; stat_flags[A_WIS] = OF_WIS; stat_flags[A_DEX] = OF_DEX; stat_flags[A_CON] = OF_CON; sustain_flags[A_STR] = OF_SUST_STR; sustain_flags[A_INT] = OF_SUST_INT; sustain_flags[A_WIS] = OF_SUST_WIS; sustain_flags[A_DEX] = OF_SUST_DEX; sustain_flags[A_CON] = OF_SUST_CON; /* Header */ c_put_str(TERM_WHITE, "abcdefghijkl@", row-1, col); /* Process equipment */ for (i = INVEN_WIELD; i < INVEN_TOTAL; ++i) { /* Get the object */ o_ptr = &p_ptr->inventory[i]; if (!o_ptr->kind) { col++; continue; } /* Get the "known" flags */ object_flags_known(o_ptr, f); /* Initialize color based of sign of pval. */ for (stat = 0; stat < A_MAX; stat++) { /* Default */ a = TERM_SLATE; c = '.'; /* Boost */ if (of_has(f, stat_flags[stat])) { /* Default */ c = '*'; /* Work out which pval we're talking about */ j = which_pval(o_ptr, stat_flags[stat]); /* Good */ if (o_ptr->pval[j] > 0) { /* Good */ a = TERM_L_GREEN; /* Label boost */ if (o_ptr->pval[j] < 10) c = I2D(o_ptr->pval[j]); } /* Bad */ if (o_ptr->pval[j] < 0) { /* Bad */ a = TERM_RED; /* Label boost */ if (o_ptr->pval[j] > -10) c = I2D(-(o_ptr->pval[j])); } } /* Sustain */ if (of_has(f, sustain_flags[stat])) { /* Dark green */ a = TERM_GREEN; /* Convert '.' to 's' */ if (c == '.') c = 's'; } if ((c == '.') && o_ptr->kind && !object_flag_is_known(o_ptr, sustain_flags[stat])) c = '?'; /* Dump proper character */ Term_putch(col, row+stat, a, c); } /* Advance */ col++; } /* Player flags */ player_flags(f); /* Check stats */ for (stat = 0; stat < A_MAX; ++stat) { /* Default */ a = TERM_SLATE; c = '.'; /* Sustain */ if (of_has(f, sustain_flags[stat])) { /* Dark green "s" */ a = TERM_GREEN; c = 's'; } /* Dump */ Term_putch(col, row+stat, a, c); } /* Column */ col = 26; /* Footer */ c_put_str(TERM_WHITE, "abcdefghijkl@", row+6, col); /* Equippy */ display_player_equippy(row+7, col); }
static void display_resistance_panel(const struct player_flag_record *resists, size_t size, const region *bounds) { size_t i, j; int col = bounds->col; int row = bounds->row; Term_putstr(col, row++, RES_COLS, TERM_WHITE, " abcdefghijkl@"); for (i = 0; i < size-3; i++, row++) { byte name_attr = TERM_WHITE; Term_gotoxy(col+6, row); /* repeated extraction of flags is inefficient but more natural */ for (j = INVEN_WIELD; j <= INVEN_TOTAL; j++) { object_type *o_ptr = &p_ptr->inventory[j]; bitflag f[OF_SIZE]; byte attr = TERM_WHITE | (j % 2) * 8; /* alternating columns */ char sym = '.'; bool res, imm, vuln; /* Wipe flagset */ of_wipe(f); if (j < INVEN_TOTAL && o_ptr->kind) { object_flags_known(o_ptr, f); } else if (j == INVEN_TOTAL) { player_flags(f); /* If the race has innate infravision/digging, force the corresponding flag here. If we set it in player_flags(), then all callers of that function will think the infravision is caused by equipment. */ if (p_ptr->race->infra > 0) of_on(f, OF_INFRA); if (p_ptr->race->r_skills[SKILL_DIGGING] > 0) of_on(f, OF_TUNNEL); } res = of_has(f, resists[i].res_flag); imm = of_has(f, resists[i].im_flag); vuln = of_has(f, resists[i].vuln_flag); if (imm) name_attr = TERM_GREEN; else if (res && name_attr == TERM_WHITE) name_attr = TERM_L_BLUE; if (vuln) sym = '-'; else if (imm) sym = '*'; else if (res) sym = '+'; else if ((j < INVEN_TOTAL) && o_ptr->kind && !object_flag_is_known(o_ptr, resists[i].res_flag)) sym = '?'; Term_addch(attr, sym); } Term_putstr(col, row, 6, name_attr, format("%5s:", resists[i].name)); } Term_putstr(col, row++, RES_COLS, TERM_WHITE, " abcdefghijkl@"); /* Equippy */ display_player_equippy(row++, col+6); }
/* * Calculate the players current "state", taking into account * not only race/class intrinsics, but also objects being worn * and temporary spell effects. * * See also calc_mana() and calc_hitpoints(). * * Take note of the new "speed code", in particular, a very strong * player will start slowing down as soon as he reaches 150 pounds, * but not until he reaches 450 pounds will he be half as fast as * a normal kobold. This both hurts and helps the player, hurts * because in the old days a player could just avoid 300 pounds, * and helps because now carrying 300 pounds is not very painful. * * The "weapon" and "bow" do *not* add to the bonuses to hit or to * damage, since that would affect non-combat things. These values * are actually added in later, at the appropriate place. * * If id_only is true, calc_bonuses() will only use the known * information of objects; thus it returns what the player _knows_ * the character state to be. */ void calc_bonuses(object_type inventory[], player_state *state, bool id_only) { int i, j, hold; int extra_blows = 0; int extra_shots = 0; int extra_might = 0; object_type *o_ptr; bitflag f[OF_SIZE]; bitflag collect_f[OF_SIZE]; /*** Reset ***/ memset(state, 0, sizeof *state); /* Set various defaults */ state->speed = 110; state->num_blow = 1; /*** Extract race/class info ***/ /* Base infravision (purely racial) */ state->see_infra = rp_ptr->infra; /* Base skills */ for (i = 0; i < SKILL_MAX; i++) state->skills[i] = rp_ptr->r_skills[i] + cp_ptr->c_skills[i]; /*** Analyze player ***/ /* Extract the player flags */ player_flags(collect_f); /*** Analyze equipment ***/ /* Scan the equipment */ for (i = INVEN_WIELD; i < INVEN_TOTAL; i++) { o_ptr = &inventory[i]; /* Skip non-objects */ if (!o_ptr->k_idx) continue; /* Extract the item flags */ if (id_only) object_flags_known(o_ptr, f); else object_flags(o_ptr, f); of_union(collect_f, f); /* Affect stats */ if (of_has(f, OF_STR)) state->stat_add[A_STR] += o_ptr->pval; if (of_has(f, OF_INT)) state->stat_add[A_INT] += o_ptr->pval; if (of_has(f, OF_WIS)) state->stat_add[A_WIS] += o_ptr->pval; if (of_has(f, OF_DEX)) state->stat_add[A_DEX] += o_ptr->pval; if (of_has(f, OF_CON)) state->stat_add[A_CON] += o_ptr->pval; if (of_has(f, OF_CHR)) state->stat_add[A_CHR] += o_ptr->pval; /* Affect stealth */ if (of_has(f, OF_STEALTH)) state->skills[SKILL_STEALTH] += o_ptr->pval; /* Affect searching ability (factor of five) */ if (of_has(f, OF_SEARCH)) state->skills[SKILL_SEARCH] += (o_ptr->pval * 5); /* Affect searching frequency (factor of five) */ if (of_has(f, OF_SEARCH)) state->skills[SKILL_SEARCH_FREQUENCY] += (o_ptr->pval * 5); /* Affect infravision */ if (of_has(f, OF_INFRA)) state->see_infra += o_ptr->pval; /* Affect digging (factor of 20) */ if (of_has(f, OF_TUNNEL)) state->skills[SKILL_DIGGING] += (o_ptr->pval * 20); /* Affect speed */ if (of_has(f, OF_SPEED)) state->speed += o_ptr->pval; /* Affect blows */ if (of_has(f, OF_BLOWS)) extra_blows += o_ptr->pval; /* Affect shots */ if (of_has(f, OF_SHOTS)) extra_shots += o_ptr->pval; /* Affect Might */ if (of_has(f, OF_MIGHT)) extra_might += o_ptr->pval; /* Modify the base armor class */ state->ac += o_ptr->ac; /* The base armor class is always known */ state->dis_ac += o_ptr->ac; /* Apply the bonuses to armor class */ if (!id_only || object_is_known(o_ptr)) state->to_a += o_ptr->to_a; /* Apply the mental bonuses to armor class, if known */ if (object_defence_plusses_are_visible(o_ptr)) state->dis_to_a += o_ptr->to_a; /* Hack -- do not apply "weapon" bonuses */ if (i == INVEN_WIELD) continue; /* Hack -- do not apply "bow" bonuses */ if (i == INVEN_BOW) continue; /* Apply the bonuses to hit/damage */ if (!id_only || object_is_known(o_ptr)) { state->to_h += o_ptr->to_h; state->to_d += o_ptr->to_d; } /* Apply the mental bonuses tp hit/damage, if known */ if (object_attack_plusses_are_visible(o_ptr)) { state->dis_to_h += o_ptr->to_h; state->dis_to_d += o_ptr->to_d; } } /*** Update all flags ***/ /* Good flags */ if (of_has(collect_f, OF_SLOW_DIGEST)) state->slow_digest = TRUE; if (of_has(collect_f, OF_FEATHER)) state->ffall = TRUE; if (of_has(collect_f, OF_REGEN)) state->regenerate = TRUE; if (of_has(collect_f, OF_TELEPATHY)) state->telepathy = TRUE; if (of_has(collect_f, OF_SEE_INVIS)) state->see_inv = TRUE; if (of_has(collect_f, OF_FREE_ACT)) state->free_act = TRUE; if (of_has(collect_f, OF_HOLD_LIFE)) state->hold_life = TRUE; /* Weird flags */ if (of_has(collect_f, OF_BLESSED)) state->bless_blade = TRUE; /* Bad flags */ if (of_has(collect_f, OF_IMPACT)) state->impact = TRUE; if (of_has(collect_f, OF_AGGRAVATE)) state->aggravate = TRUE; if (of_has(collect_f, OF_TELEPORT)) state->teleport = TRUE; if (of_has(collect_f, OF_DRAIN_EXP)) state->exp_drain = TRUE; if (of_has(collect_f, OF_IMPAIR_HP)) state->impair_hp = TRUE; if (of_has(collect_f, OF_IMPAIR_MANA)) state->impair_mana = TRUE; if (of_has(collect_f, OF_AFRAID)) state->afraid = TRUE; /* Vulnerability flags */ if (of_has(collect_f, OF_VULN_FIRE)) state->vuln_fire = TRUE; if (of_has(collect_f, OF_VULN_ACID)) state->vuln_acid = TRUE; if (of_has(collect_f, OF_VULN_COLD)) state->vuln_cold = TRUE; if (of_has(collect_f, OF_VULN_ELEC)) state->vuln_elec = TRUE; /* Immunity flags */ if (of_has(collect_f, OF_IM_FIRE)) state->immune_fire = TRUE; if (of_has(collect_f, OF_IM_ACID)) state->immune_acid = TRUE; if (of_has(collect_f, OF_IM_COLD)) state->immune_cold = TRUE; if (of_has(collect_f, OF_IM_ELEC)) state->immune_elec = TRUE; /* Resistance flags */ if (of_has(collect_f, OF_RES_ACID)) state->resist_acid = TRUE; if (of_has(collect_f, OF_RES_ELEC)) state->resist_elec = TRUE; if (of_has(collect_f, OF_RES_FIRE)) state->resist_fire = TRUE; if (of_has(collect_f, OF_RES_COLD)) state->resist_cold = TRUE; if (of_has(collect_f, OF_RES_POIS)) state->resist_pois = TRUE; if (of_has(collect_f, OF_RES_FEAR)) state->resist_fear = TRUE; if (of_has(collect_f, OF_RES_LIGHT)) state->resist_light = TRUE; if (of_has(collect_f, OF_RES_DARK)) state->resist_dark = TRUE; if (of_has(collect_f, OF_RES_BLIND)) state->resist_blind = TRUE; if (of_has(collect_f, OF_RES_CONFU)) state->resist_confu = TRUE; if (of_has(collect_f, OF_RES_SOUND)) state->resist_sound = TRUE; if (of_has(collect_f, OF_RES_SHARD)) state->resist_shard = TRUE; if (of_has(collect_f, OF_RES_NEXUS)) state->resist_nexus = TRUE; if (of_has(collect_f, OF_RES_NETHR)) state->resist_nethr = TRUE; if (of_has(collect_f, OF_RES_CHAOS)) state->resist_chaos = TRUE; if (of_has(collect_f, OF_RES_DISEN)) state->resist_disen = TRUE; /* Sustain flags */ if (of_has(collect_f, OF_SUST_STR)) state->sustain_str = TRUE; if (of_has(collect_f, OF_SUST_INT)) state->sustain_int = TRUE; if (of_has(collect_f, OF_SUST_WIS)) state->sustain_wis = TRUE; if (of_has(collect_f, OF_SUST_DEX)) state->sustain_dex = TRUE; if (of_has(collect_f, OF_SUST_CON)) state->sustain_con = TRUE; if (of_has(collect_f, OF_SUST_CHR)) state->sustain_chr = TRUE; /*** Handle stats ***/ /* Calculate stats */ for (i = 0; i < A_MAX; i++) { int add, top, use, ind; /* Extract modifier */ add = state->stat_add[i]; /* Maximize mode */ if (OPT(adult_maximize)) { /* Modify the stats for race/class */ add += (rp_ptr->r_adj[i] + cp_ptr->c_adj[i]); } /* Extract the new "stat_top" value for the stat */ top = modify_stat_value(p_ptr->stat_max[i], add); /* Save the new value */ state->stat_top[i] = top; /* Extract the new "stat_use" value for the stat */ use = modify_stat_value(p_ptr->stat_cur[i], add); /* Save the new value */ state->stat_use[i] = use; /* Values: n/a */ if (use <= 3) ind = 0; /* Values: 3, 4, ..., 18 */ else if (use <= 18) ind = (use - 3); /* Ranges: 18/00-18/09, ..., 18/210-18/219 */ else if (use <= 18+219) ind = (15 + (use - 18) / 10); /* Range: 18/220+ */ else ind = (37); assert((0 <= ind) && (ind < STAT_RANGE)); /* Save the new index */ state->stat_ind[i] = ind; } /*** Temporary flags ***/ /* Apply temporary "stun" */ if (p_ptr->timed[TMD_STUN] > 50) { state->to_h -= 20; state->dis_to_h -= 20; state->to_d -= 20; state->dis_to_d -= 20; state->skills[SKILL_DEVICE] = state->skills[SKILL_DEVICE] * 8 / 10; } else if (p_ptr->timed[TMD_STUN]) { state->to_h -= 5; state->dis_to_h -= 5; state->to_d -= 5; state->dis_to_d -= 5; state->skills[SKILL_DEVICE] = state->skills[SKILL_DEVICE] * 9 / 10; } /* Invulnerability */ if (p_ptr->timed[TMD_INVULN]) { state->to_a += 100; state->dis_to_a += 100; } /* Temporary blessing */ if (p_ptr->timed[TMD_BLESSED]) { state->to_a += 5; state->dis_to_a += 5; state->to_h += 10; state->dis_to_h += 10; state->skills[SKILL_DEVICE] = state->skills[SKILL_DEVICE] * 105 / 100; } /* Temporary shield */ if (p_ptr->timed[TMD_SHIELD]) { state->to_a += 50; state->dis_to_a += 50; } /* Temporary stoneskin */ if (p_ptr->timed[TMD_STONESKIN]) { state->to_a += 40; state->dis_to_a += 40; state->speed -= 5; } /* Temporary "Hero" */ if (p_ptr->timed[TMD_HERO]) { state->to_h += 12; state->dis_to_h += 12; state->resist_fear = TRUE; state->skills[SKILL_DEVICE] = state->skills[SKILL_DEVICE] * 105 / 100; } /* Temporary "Berserk" */ if (p_ptr->timed[TMD_SHERO]) { state->to_h += 24; state->dis_to_h += 24; state->to_a -= 10; state->dis_to_a -= 10; state->resist_fear = TRUE; state->skills[SKILL_DEVICE] = state->skills[SKILL_DEVICE] * 9 / 10; } /* Temporary "fast" */ if (p_ptr->timed[TMD_FAST] || p_ptr->timed[TMD_SPRINT]) state->speed += 10; /* Temporary "slow" */ if (p_ptr->timed[TMD_SLOW]) state->speed -= 10; /* Temporary see invisible */ if (p_ptr->timed[TMD_SINVIS]) state->see_inv = TRUE; /* Temporary infravision boost */ if (p_ptr->timed[TMD_SINFRA]) state->see_infra += 5; /* Temporary telepathy */ if (p_ptr->timed[TMD_TELEPATHY]) state->telepathy = TRUE; /* Temporary resist confusion */ if (p_ptr->timed[TMD_OPP_CONF]) state->resist_confu = TRUE; /* Fear */ if (p_ptr->timed[TMD_AFRAID] || p_ptr->timed[TMD_TERROR]) state->afraid = TRUE; if (p_ptr->timed[TMD_TERROR]) state->speed += 5; /* Fear can come from item flags too */ if (state->afraid) { state->to_h -= 20; state->dis_to_h -= 20; state->to_a += 8; state->dis_to_a += 8; state->skills[SKILL_DEVICE] = state->skills[SKILL_DEVICE] * 95 / 100; } /* Confusion */ if (p_ptr->timed[TMD_CONFUSED]) state->skills[SKILL_DEVICE] = state->skills[SKILL_DEVICE] * 75 / 100; /* Amnesia */ if (p_ptr->timed[TMD_AMNESIA]) state->skills[SKILL_DEVICE] = state->skills[SKILL_DEVICE] * 8 / 10; /* Poison */ if (p_ptr->timed[TMD_POISONED]) state->skills[SKILL_DEVICE] = state->skills[SKILL_DEVICE] * 95 / 100; /* Hallucination */ if (p_ptr->timed[TMD_IMAGE]) state->skills[SKILL_DEVICE] = state->skills[SKILL_DEVICE] * 8 / 10; /*** Analyze weight ***/ /* Extract the current weight (in tenth pounds) */ j = p_ptr->total_weight; /* Extract the "weight limit" (in tenth pounds) */ i = weight_limit(state); /* Apply "encumbrance" from weight */ if (j > i / 2) state->speed -= ((j - (i / 2)) / (i / 10)); /* Bloating slows the player down (a little) */ if (p_ptr->food >= PY_FOOD_MAX) state->speed -= 10; /* Searching slows the player down */ if (p_ptr->searching) state->speed -= 10; /* Sanity check on extreme speeds */ if (state->speed < 0) state->speed = 0; if (state->speed > 199) state->speed = 199; /*** Apply modifier bonuses ***/ /* Actual Modifier Bonuses (Un-inflate stat bonuses) */ state->to_a += ((int)(adj_dex_ta[state->stat_ind[A_DEX]]) - 128); state->to_d += ((int)(adj_str_td[state->stat_ind[A_STR]]) - 128); state->to_h += ((int)(adj_dex_th[state->stat_ind[A_DEX]]) - 128); state->to_h += ((int)(adj_str_th[state->stat_ind[A_STR]]) - 128); /* Displayed Modifier Bonuses (Un-inflate stat bonuses) */ state->dis_to_a += ((int)(adj_dex_ta[state->stat_ind[A_DEX]]) - 128); state->dis_to_d += ((int)(adj_str_td[state->stat_ind[A_STR]]) - 128); state->dis_to_h += ((int)(adj_dex_th[state->stat_ind[A_DEX]]) - 128); state->dis_to_h += ((int)(adj_str_th[state->stat_ind[A_STR]]) - 128); /*** Modify skills ***/ /* Affect Skill -- stealth (bonus one) */ state->skills[SKILL_STEALTH] += 1; /* Affect Skill -- disarming (DEX and INT) */ state->skills[SKILL_DISARM] += adj_dex_dis[state->stat_ind[A_DEX]]; state->skills[SKILL_DISARM] += adj_int_dis[state->stat_ind[A_INT]]; /* Affect Skill -- magic devices (INT) */ state->skills[SKILL_DEVICE] += adj_int_dev[state->stat_ind[A_INT]]; /* Affect Skill -- saving throw (WIS) */ state->skills[SKILL_SAVE] += adj_wis_sav[state->stat_ind[A_WIS]]; /* Affect Skill -- digging (STR) */ state->skills[SKILL_DIGGING] += adj_str_dig[state->stat_ind[A_STR]]; /* Affect Skills (Level, by Class) */ for (i = 0; i < SKILL_MAX; i++) state->skills[i] += (cp_ptr->x_skills[i] * p_ptr->lev / 10); /* Limit Skill -- digging from 1 up */ if (state->skills[SKILL_DIGGING] < 1) state->skills[SKILL_DIGGING] = 1; /* Limit Skill -- stealth from 0 to 30 */ if (state->skills[SKILL_STEALTH] > 30) state->skills[SKILL_STEALTH] = 30; if (state->skills[SKILL_STEALTH] < 0) state->skills[SKILL_STEALTH] = 0; /* Apply Skill -- Extract noise from stealth */ state->noise = (1L << (30 - state->skills[SKILL_STEALTH])); /* Obtain the "hold" value */ hold = adj_str_hold[state->stat_ind[A_STR]]; /*** Analyze current bow ***/ /* Examine the "current bow" */ o_ptr = &inventory[INVEN_BOW]; /* Assume not heavy */ state->heavy_shoot = FALSE; /* It is hard to carholdry a heavy bow */ if (hold < o_ptr->weight / 10) { /* Hard to wield a heavy bow */ state->to_h += 2 * (hold - o_ptr->weight / 10); state->dis_to_h += 2 * (hold - o_ptr->weight / 10); /* Heavy Bow */ state->heavy_shoot = TRUE; } /* Analyze launcher */ if (o_ptr->k_idx) { /* Get to shoot */ state->num_fire = 1; /* Analyze the launcher */ switch (o_ptr->sval) { /* Sling and ammo */ case SV_SLING: { state->ammo_tval = TV_SHOT; state->ammo_mult = 2; break; } /* Short Bow and Arrow */ case SV_SHORT_BOW: { state->ammo_tval = TV_ARROW; state->ammo_mult = 2; break; } /* Long Bow and Arrow */ case SV_LONG_BOW: { state->ammo_tval = TV_ARROW; state->ammo_mult = 3; break; } /* Light Crossbow and Bolt */ case SV_LIGHT_XBOW: { state->ammo_tval = TV_BOLT; state->ammo_mult = 3; break; } /* Heavy Crossbow and Bolt */ case SV_HEAVY_XBOW: { state->ammo_tval = TV_BOLT; state->ammo_mult = 4; break; } } /* Apply special flags */ if (o_ptr->k_idx && !state->heavy_shoot) { /* Extra shots */ state->num_fire += extra_shots; /* Extra might */ state->ammo_mult += extra_might; /* Hack -- Rangers love Bows */ if (player_has(PF_EXTRA_SHOT) && (state->ammo_tval == TV_ARROW)) { /* Extra shot at level 20 */ if (p_ptr->lev >= 20) state->num_fire++; /* Extra shot at level 40 */ if (p_ptr->lev >= 40) state->num_fire++; } } /* Require at least one shot */ if (state->num_fire < 1) state->num_fire = 1; } /*** Analyze weapon ***/ /* Examine the "current weapon" */ o_ptr = &inventory[INVEN_WIELD]; /* Assume not heavy */ state->heavy_wield = FALSE; /* It is hard to hold a heavy weapon */ if (hold < o_ptr->weight / 10) { /* Hard to wield a heavy weapon */ state->to_h += 2 * (hold - o_ptr->weight / 10); state->dis_to_h += 2 * (hold - o_ptr->weight / 10); /* Heavy weapon */ state->heavy_wield = TRUE; } /* Non-object means barehanded attacks */ if (!o_ptr->k_idx) assert(o_ptr->weight == 0); /* Normal weapons */ if (!state->heavy_wield) { /* Calculate number of blows */ state->num_blow = calc_blows(o_ptr, state) + extra_blows; /* Boost digging skill by weapon weight */ state->skills[SKILL_DIGGING] += (o_ptr->weight / 10); } /* Assume okay */ state->icky_wield = FALSE; /* Priest weapon penalty for non-blessed edged weapons */ if (player_has(PF_BLESS_WEAPON) && (!state->bless_blade) && ((o_ptr->tval == TV_SWORD) || (o_ptr->tval == TV_POLEARM))) { /* Reduce the real bonuses */ state->to_h -= 2; state->to_d -= 2; /* Reduce the mental bonuses */ state->dis_to_h -= 2; state->dis_to_d -= 2; /* Icky weapon */ state->icky_wield = TRUE; } return; }
/* * Special display, part 2c * * How to print out the modifications and sustains. * Positive mods with no sustain will be light green. * Positive mods with a sustain will be dark green. * Sustains (with no modification) will be a dark green 's'. * Negative mods (from a curse) will be red. * Huge mods (>9), like from MICoMorgoth, will be a '*' * No mod, no sustain, will be a slate '.' */ static void display_player_sust_info(void) { int i, row, col, stat; object_type *o_ptr; bitflag f[OF_SIZE]; int stat_flags[A_MAX]; int sustain_flags[A_MAX]; byte a; char c; /* Row */ row = 2; /* Column */ col = 26; /* Build the stat flags tables */ stat_flags[A_STR] = OF_STR; stat_flags[A_INT] = OF_INT; stat_flags[A_WIS] = OF_WIS; stat_flags[A_DEX] = OF_DEX; stat_flags[A_CON] = OF_CON; stat_flags[A_CHR] = OF_CHR; sustain_flags[A_STR] = OF_SUST_STR; sustain_flags[A_INT] = OF_SUST_INT; sustain_flags[A_WIS] = OF_SUST_WIS; sustain_flags[A_DEX] = OF_SUST_DEX; sustain_flags[A_CON] = OF_SUST_CON; sustain_flags[A_CHR] = OF_SUST_CHR; /* Header */ c_put_str(TERM_WHITE, "@abcdefghijklmnopqrstuvwxyz{|}", row-1, col); /* Process equipment */ for (i = INVEN_WIELD - 1; i < INVEN_TOTAL; ++i) { if (((i >= INVEN_WIELD) && (i < INVEN_WIELD + rp_ptr->melee_slots)) || ((i >= INVEN_BOW) && (i < INVEN_BOW + rp_ptr->range_slots)) || ((i >= INVEN_FINGER) && (i < INVEN_FINGER + rp_ptr->ring_slots)) || ((i >= INVEN_NECK) && (i < INVEN_NECK + rp_ptr->amulet_slots)) || ((i >= INVEN_LIGHT) && (i < INVEN_LIGHT + rp_ptr->light_slots)) || ((i >= INVEN_BODY) && (i < INVEN_BODY + rp_ptr->body_slots)) || ((i >= INVEN_OUTER) && (i < INVEN_OUTER + rp_ptr->cloak_slots)) || ((i >= INVEN_ARM) && (i < INVEN_ARM + rp_ptr->shield_slots)) || ((i >= INVEN_HEAD) && (i < INVEN_HEAD + rp_ptr->helm_slots)) || ((i >= INVEN_HANDS) && (i < INVEN_HANDS + rp_ptr->glove_slots)) || ((i >= INVEN_FEET) && (i < INVEN_FEET + rp_ptr->boot_slots)) || (i == INVEN_WIELD - 1)) { /* Player flags */ if (i < INVEN_WIELD) { player_flags(f); o_ptr = NULL; } else { /* Get the object */ o_ptr = &p_ptr->inventory[i]; /* Get the "known" flags */ object_flags_known(o_ptr, f); } /* Initialize color based of sign of pval. */ for (stat = 0; stat < A_MAX; stat++) { /* Default */ a = TERM_SLATE; c = '.'; /* Boost */ if (of_has(f, stat_flags[stat]) && (o_ptr != NULL)) { /* Default */ c = '*'; /* Good */ if (o_ptr->pval > 0) { /* Good */ a = TERM_L_GREEN; /* Label boost */ if (o_ptr->pval < 10) c = I2D(o_ptr->pval); } /* Bad */ if (o_ptr->pval < 0) { /* Bad */ a = TERM_RED; /* Label boost */ if (o_ptr->pval > -10) c = I2D(-(o_ptr->pval)); } } /* Sustain */ if (of_has(f, sustain_flags[stat])) { /* Dark green */ a = TERM_GREEN; /* Convert '.' to 's' */ if (c == '.') c = 's'; } if ((c == '.') && (o_ptr != NULL) && o_ptr->k_idx && !object_flag_is_known(o_ptr, sustain_flags[stat])) c = '?'; /* Dump proper character */ Term_putch(col, row+stat, a, c); } /* Advance */ col++; } } /* Check stats */ for (stat = 0; stat < A_MAX; ++stat) { /* Default */ a = TERM_SLATE; c = '.'; /* Sustain */ if (of_has(f, sustain_flags[stat])) { /* Dark green "s" */ a = TERM_GREEN; c = 's'; } /* Dump */ Term_putch(col, row+stat, a, c); } /* Column */ col = 26; /* Footer */ c_put_str(TERM_WHITE, "@abcdefghijklmnopqrstuvwxyz{|}", row+6, col); /* Equippy */ display_player_equippy(row+7, col+1); }
static void display_resistance_panel(const struct player_flag_record *resists, size_t size, const region *bounds) { size_t i; int j; int col = bounds->col; int row = bounds->row; Term_putstr(col, row++, RES_COLS, TERM_WHITE, " @abcdefghijklmnopqrstuvwxyz{|}"); for (i = 0; i < size-3; i++, row++) { byte name_attr = TERM_WHITE; Term_gotoxy(col+6, row); /* repeated extraction of flags is inefficient but more natural */ for (j = INVEN_WIELD - 1; j < INVEN_TOTAL; j++) { if (((j >= INVEN_WIELD) && (j < INVEN_WIELD + rp_ptr->melee_slots)) || ((j >= INVEN_BOW) && (j < INVEN_BOW + rp_ptr->range_slots)) || ((j >= INVEN_FINGER) && (j < INVEN_FINGER + rp_ptr->ring_slots)) || ((j >= INVEN_NECK) && (j < INVEN_NECK + rp_ptr->amulet_slots)) || ((j >= INVEN_LIGHT) && (j < INVEN_LIGHT + rp_ptr->light_slots)) || ((j >= INVEN_BODY) && (j < INVEN_BODY + rp_ptr->body_slots)) || ((j >= INVEN_OUTER) && (j < INVEN_OUTER + rp_ptr->cloak_slots)) || ((j >= INVEN_ARM) && (j < INVEN_ARM + rp_ptr->shield_slots)) || ((j >= INVEN_HEAD) && (j < INVEN_HEAD + rp_ptr->helm_slots)) || ((j >= INVEN_HANDS) && (j < INVEN_HANDS + rp_ptr->glove_slots)) || ((j >= INVEN_FEET) && (j < INVEN_FEET + rp_ptr->boot_slots)) || (j == INVEN_WIELD - 1)) { object_type *o_ptr = &p_ptr->inventory[j]; bitflag f[OF_SIZE]; byte attr = TERM_WHITE | (j % 2) * 8; /* alternating columns */ char sym = '.'; bool res, imm, vuln; /* Wipe flagset */ of_wipe(f); if (j < INVEN_WIELD) { player_flags(f); /* If the race has innate infravision/digging, force the corresponding flag here. If we set it in player_flags(), then all callers of that function will think the infravision is caused by equipment. */ if (rp_ptr->infra > 0) of_on(f, OF_INFRA); if (rp_ptr->r_skills[SKILL_DIGGING] > 0) of_on(f, OF_TUNNEL); } else if (j < INVEN_TOTAL && o_ptr->k_idx) { object_flags_known(o_ptr, f); } res = of_has(f, resists[i].res_flag); imm = of_has(f, resists[i].im_flag); vuln = of_has(f, resists[i].vuln_flag); if (imm) name_attr = TERM_GREEN; else if (res && name_attr == TERM_WHITE) name_attr = TERM_L_BLUE; if (vuln) sym = '-'; else if (imm) sym = '*'; else if (res) sym = '+'; else if ((j < INVEN_TOTAL) && o_ptr->k_idx && !object_flag_is_known(o_ptr, resists[i].res_flag)) sym = '?'; Term_addch(attr, sym); } } Term_putstr(col, row, 6, name_attr, format("%5s:", resists[i].name)); } Term_putstr(col, row++, RES_COLS, TERM_WHITE, " @abcdefghijklmnopqrstuvwxyz{|}"); /* Equippy */ display_player_equippy(row++, col+7); }