/** * This function takes a pointer to a grid info struct describing the * contents of a grid location (as obtained through the function map_info) * and fills in the character and attr pairs for display. * * ap and cp are filled with the attr/char pair for the monster, object or * floor tile that is at the "top" of the grid (monsters covering objects, * which cover floor, assuming all are present). * * tap and tcp are filled with the attr/char pair for the floor, regardless * of what is on it. This can be used by graphical displays with * transparency to place an object onto a floor tile, is desired. * * Any lighting effects are also applied to these pairs, clear monsters allow * the underlying colour or feature to show through (ATTR_CLEAR and * CHAR_CLEAR), multi-hued colour-changing (ATTR_MULTI) is applied, and so on. * Technically, the flag "CHAR_MULTI" is supposed to indicate that a monster * looks strange when examined, but this flag is currently ignored. * * NOTES: * This is called pretty frequently, whenever a grid on the map display * needs updating, so don't overcomplicate it. * * The "zero" entry in the feature/object/monster arrays are * used to provide "special" attr/char codes, with "monster zero" being * used for the player attr/char, "object zero" being used for the "pile" * attr/char, and "feature zero" being used for the "darkness" attr/char. * * TODO: * The transformations for tile colors, or brightness for the 16x16 * tiles should be handled differently. One possibility would be to * extend feature_type with attr/char definitions for the different states. * This will probably be done outside of the current text->graphics mappings * though. */ void grid_data_as_text(struct grid_data *g, int *ap, wchar_t *cp, int *tap, wchar_t *tcp) { struct feature *feat = &f_info[g->f_idx]; int a = feat_x_attr[g->lighting][feat->fidx]; wchar_t c = feat_x_char[g->lighting][feat->fidx]; bool skip_objects = false; /* Get the colour for ASCII */ if (use_graphics == GRAPHICS_NONE) grid_get_attr(g, &a); /* Save the terrain info for the transparency effects */ (*tap) = a; (*tcp) = c; /* There is a trap in this grid, and we are not hallucinating */ if (g->trap && (!g->hallucinate)) { /* Change graphics to indicate visible traps, skip objects if a web */ skip_objects = get_trap_graphics(cave, g, &a, &c); } if (!skip_objects) { /* If there's an object, deal with that. */ if (g->unseen_money) { /* $$$ gets an orange star*/ a = object_kind_attr(unknown_gold_kind); c = object_kind_char(unknown_gold_kind); } else if (g->unseen_object) { /* Everything else gets a red star */ a = object_kind_attr(unknown_item_kind); c = object_kind_char(unknown_item_kind); } else if (g->first_kind) { if (g->hallucinate) { /* Just pick a random object to display. */ hallucinatory_object(&a, &c); } else if (g->multiple_objects) { /* Get the "pile" feature instead */ a = object_kind_attr(pile_kind); c = object_kind_char(pile_kind); } else { /* Normal attr and char */ a = object_kind_attr(g->first_kind); c = object_kind_char(g->first_kind); } } } /* Handle monsters, the player and trap borders */ if (g->m_idx > 0) { if (g->hallucinate) { /* Just pick a random monster to display. */ hallucinatory_monster(&a, &c); } else if (!monster_is_mimicking(cave_monster(cave, g->m_idx))) { struct monster *mon = cave_monster(cave, g->m_idx); byte da; wchar_t dc; /* Desired attr & char */ da = monster_x_attr[mon->race->ridx]; dc = monster_x_char[mon->race->ridx]; /* Special handling of attrs and/or chars */ if (da & 0x80) { /* Special attr/char codes */ a = da; c = dc; } else if (OPT(player, purple_uniques) && rf_has(mon->race->flags, RF_UNIQUE)) { /* Turn uniques purple if desired (violet, actually) */ a = COLOUR_VIOLET; c = dc; } else if (rf_has(mon->race->flags, RF_ATTR_MULTI) || rf_has(mon->race->flags, RF_ATTR_FLICKER) || rf_has(mon->race->flags, RF_ATTR_RAND)) { /* Multi-hued monster */ a = mon->attr ? mon->attr : da; c = dc; } else if (!flags_test(mon->race->flags, RF_SIZE, RF_ATTR_CLEAR, RF_CHAR_CLEAR, FLAG_END)) { /* Normal monster (not "clear" in any way) */ a = da; /* Desired attr & char. da is not used, should a be set to it?*/ /*da = monster_x_attr[mon->race->ridx];*/ dc = monster_x_char[mon->race->ridx]; c = dc; } else if (a & 0x80) { /* Hack -- Bizarre grid under monster */ a = da; c = dc; } else if (!rf_has(mon->race->flags, RF_CHAR_CLEAR)) { /* Normal char, Clear attr, monster */ c = dc; } else if (!rf_has(mon->race->flags, RF_ATTR_CLEAR)) { /* Normal attr, Clear char, monster */ a = da; } /* Store the drawing attr so we can use it elsewhere */ mon->attr = a; } } else if (g->is_player) { struct monster_race *race = &r_info[0]; /* Get the "player" attr */ a = monster_x_attr[race->ridx]; if ((OPT(player, hp_changes_color)) && !(a & 0x80)) { switch(player->chp * 10 / player->mhp) { case 10: case 9: { a = COLOUR_WHITE; break; } case 8: case 7: { a = COLOUR_YELLOW; break; } case 6: case 5: { a = COLOUR_ORANGE; break; } case 4: case 3: { a = COLOUR_L_RED; break; } case 2: case 1: case 0: { a = COLOUR_RED; break; } default: { a = COLOUR_WHITE; break; } } } /* Get the "player" char */ c = monster_x_char[race->ridx]; } /* Result */ (*ap) = a; (*cp) = c; }
/** * This function takes a pointer to a grid info struct describing the * contents of a grid location (as obtained through the function map_info) * and fills in the character and attr pairs for display. * * ap and cp are filled with the attr/char pair for the monster, object or * floor tile that is at the "top" of the grid (monsters covering objects, * which cover floor, assuming all are present). * * tap and tcp are filled with the attr/char pair for the floor, regardless * of what is on it. This can be used by graphical displays with * transparency to place an object onto a floor tile, is desired. * * Any lighting effects are also applied to these pairs, clear monsters allow * the underlying colour or feature to show through (ATTR_CLEAR and * CHAR_CLEAR), multi-hued colour-changing (ATTR_MULTI) is applied, and so on. * Technically, the flag "CHAR_MULTI" is supposed to indicate that a monster * looks strange when examined, but this flag is currently ignored. * * NOTES: * This is called pretty frequently, whenever a grid on the map display * needs updating, so don't overcomplicate it. * * The "zero" entry in the feature/object/monster arrays are * used to provide "special" attr/char codes, with "monster zero" being * used for the player attr/char, "object zero" being used for the "pile" * attr/char, and "feature zero" being used for the "darkness" attr/char. * * TODO: * The transformations for tile colors, or brightness for the 16x16 * tiles should be handled differently. One possibility would be to * extend feature_type with attr/char definitions for the different states. * This will probably be done outside of the current text->graphics mappings * though. */ void grid_data_as_text(grid_data *g, int *ap, wchar_t *cp, int *tap, wchar_t *tcp) { feature_type *f_ptr = &f_info[g->f_idx]; int a = feat_x_attr[g->lighting][f_ptr->fidx]; wchar_t c = feat_x_char[g->lighting][f_ptr->fidx]; /* Check for trap detection boundaries */ if (use_graphics == GRAPHICS_NONE) grid_get_attr(g, &a); else if (g->trapborder && tf_has(f_ptr->flags, TF_FLOOR) && (g->m_idx || g->first_kind)) { /* if there is an object or monster here, and this is a plain floor * display the border here rather than an overlay below */ a = feat_x_attr[g->lighting][FEAT_DTRAP_FLOOR]; c = feat_x_char[g->lighting][FEAT_DTRAP_FLOOR]; } /* Save the terrain info for the transparency effects */ (*tap) = a; (*tcp) = c; /* There is a trap in this grid, and we are not hallucinating */ if (g->trap && (!g->hallucinate)) /* Change graphics to indicate a trap (if visible) */ get_trap_graphics(cave, g, &a, &c); /* If there's an object, deal with that. */ if (g->unseen_money) { /* $$$ gets an orange star*/ a = object_kind_attr(&k_info[7]); c = object_kind_char(&k_info[7]); } else if (g->unseen_object) { /* Everything else gets a red star */ a = object_kind_attr(&k_info[6]); c = object_kind_char(&k_info[6]); } else if (g->first_kind) { if (g->hallucinate) { /* Just pick a random object to display. */ hallucinatory_object(&a, &c); } else if (g->multiple_objects) { /* Get the "pile" feature instead */ a = object_kind_attr(&k_info[0]); c = object_kind_char(&k_info[0]); } else { /* Normal attr and char */ a = object_kind_attr(g->first_kind); c = object_kind_char(g->first_kind); } } /* Handle monsters, the player and trap borders */ if (g->m_idx > 0) { if (g->hallucinate) { /* Just pick a random monster to display. */ hallucinatory_monster(&a, &c); } else if (!is_mimicking(cave_monster(cave, g->m_idx))) { monster_type *m_ptr = cave_monster(cave, g->m_idx); byte da; wchar_t dc; /* Desired attr & char */ da = monster_x_attr[m_ptr->race->ridx]; dc = monster_x_char[m_ptr->race->ridx]; /* Special handling of attrs and/or chars */ if (da & 0x80) { /* Special attr/char codes */ a = da; c = dc; } else if (OPT(purple_uniques) && rf_has(m_ptr->race->flags, RF_UNIQUE)) { /* Turn uniques purple if desired (violet, actually) */ a = COLOUR_VIOLET; c = dc; } else if (rf_has(m_ptr->race->flags, RF_ATTR_MULTI) || rf_has(m_ptr->race->flags, RF_ATTR_FLICKER) || rf_has(m_ptr->race->flags, RF_ATTR_RAND)) { /* Multi-hued monster */ a = m_ptr->attr ? m_ptr->attr : da; c = dc; } else if (!flags_test(m_ptr->race->flags, RF_SIZE, RF_ATTR_CLEAR, RF_CHAR_CLEAR, FLAG_END)) { /* Normal monster (not "clear" in any way) */ a = da; /* Desired attr & char. da is not used, should a be set to it?*/ /*da = monster_x_attr[m_ptr->race->ridx];*/ dc = monster_x_char[m_ptr->race->ridx]; c = dc; } else if (a & 0x80) { /* Hack -- Bizarre grid under monster */ a = da; c = dc; } else if (!rf_has(m_ptr->race->flags, RF_CHAR_CLEAR)) { /* Normal char, Clear attr, monster */ c = dc; } else if (!rf_has(m_ptr->race->flags, RF_ATTR_CLEAR)) { /* Normal attr, Clear char, monster */ a = da; } /* Store the drawing attr so we can use it elsewhere */ m_ptr->attr = a; } } else if (g->is_player) { monster_race *r_ptr = &r_info[0]; /* Get the "player" attr */ a = monster_x_attr[r_ptr->ridx]; if ((OPT(hp_changes_color)) && !(a & 0x80)) { switch(player->chp * 10 / player->mhp) { case 10: case 9: { a = COLOUR_WHITE; break; } case 8: case 7: { a = COLOUR_YELLOW; break; } case 6: case 5: { a = COLOUR_ORANGE; break; } case 4: case 3: { a = COLOUR_L_RED; break; } case 2: case 1: case 0: { a = COLOUR_RED; break; } default: { a = COLOUR_WHITE; break; } } } /* Get the "player" char */ c = monster_x_char[r_ptr->ridx]; } else if (g->trapborder && (g->f_idx) && !(g->first_kind) && (use_graphics != GRAPHICS_NONE)) { /* No overlay is used, so we can use the trap border overlay */ a = feat_x_attr[g->lighting][FEAT_DTRAP_WALL]; c = feat_x_char[g->lighting][FEAT_DTRAP_WALL]; } /* Result */ (*ap) = a; (*cp) = c; }