/** * Get the object element info the player should know about for the given * object/viewing mode combination. */ static void get_known_elements(const struct object *obj, const oinfo_detail_t mode, struct element_info el_info[]) { size_t i; /* Grab the element info */ for (i = 0; i < N_ELEMENTS(elements); i++) { /* Report fake egos or known element info */ if ((mode & OINFO_EGO) || object_element_is_known(obj, i)) { el_info[i].res_level = obj->el_info[i].res_level; el_info[i].flags = obj->el_info[i].flags; } else { el_info[i].res_level = 0; el_info[i].flags = 0; } /* Ignoring an element: */ if (obj->el_info[i].flags & EL_INFO_IGNORE) { /* If the object is usually destroyed, mention the ignoring; */ if (obj->el_info[i].flags & EL_INFO_HATES) el_info[i].flags &= ~(EL_INFO_HATES); /* Otherwise, don't say anything */ else el_info[i].flags &= ~(EL_INFO_IGNORE); } /* Don't include hates flag when terse */ if (mode & OINFO_TERSE) el_info[i].flags &= ~(EL_INFO_HATES); } }
/** * Add power for elemental properties */ static int element_power(const object_type *obj, int p, bool known) { size_t i, j; int q; /* Zero the set counts */ for (i = 0; i < N_ELEMENTS(element_sets); i++) element_sets[i].count = 0; /* Analyse each element for ignore, vulnerability, resistance or immunity */ for (i = 0; i < N_ELEMENTS(el_powers); i++) { if (!known && !object_element_is_known(obj, i)) continue; if (obj->el_info[i].flags & EL_INFO_IGNORE) { if (el_powers[i].ignore_power != 0) { q = (el_powers[i].ignore_power); p += q; log_obj(format("Add %d power for ignoring %s, total is %d\n", q, el_powers[i].name, p)); } } if (obj->el_info[i].res_level == -1) { if (el_powers[i].vuln_power != 0) { q = (el_powers[i].vuln_power); p += q; log_obj(format("Add %d power for vulnerability to %s, total is %d\n", q, el_powers[i].name, p)); } } else if (obj->el_info[i].res_level == 1) { if (el_powers[i].res_power != 0) { q = (el_powers[i].res_power); p += q; log_obj(format("Add %d power for resistance to %s, total is %d\n", q, el_powers[i].name, p)); } } else if (obj->el_info[i].res_level == 3) { if (el_powers[i].im_power != 0) { q = (el_powers[i].im_power + el_powers[i].res_power); p += q; log_obj(format("Add %d power for immunity to %s, total is %d\n", q, el_powers[i].name, p)); } } /* Track combinations of element properties */ for (j = 0; j < N_ELEMENTS(element_sets); j++) if ((element_sets[j].type == el_powers[i].type) && (element_sets[j].res_level <= obj->el_info[i].res_level)) element_sets[j].count++; } /* Add extra power for multiple flags of the same type */ for (i = 0; i < N_ELEMENTS(element_sets); i++) { if (element_sets[i].count > 1) { q = (element_sets[i].factor * element_sets[i].count * element_sets[i].count); p += q; log_obj(format("Add %d power for multiple %s, total is %d\n", q, element_sets[i].desc, p)); } /* Add bonus if item has a full set of these flags */ if (element_sets[i].count == element_sets[i].size) { q = element_sets[i].bonus; p += q; log_obj(format("Add %d power for full set of %s, total is %d\n", q, element_sets[i].desc, p)); } } return p; }
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); }
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); }