/* Check if the given artifact idx is something we should "Know" about */ static bool artifact_is_known(int a_idx) { object_type *o_ptr; if (!a_info[a_idx].name) return FALSE; if (p_ptr->wizard) return TRUE; if (!a_info[a_idx].created) return FALSE; /* Check all objects to see if it exists but hasn't been IDed */ o_ptr = find_artifact(&a_info[a_idx]); if (o_ptr && !object_is_known_artifact(o_ptr)) return FALSE; return TRUE; }
static int rd_artifacts(void) { int i; u16b tmp16u; /* Load the Artifacts */ rd_u16b(&tmp16u); /* Incompatible save files */ if (tmp16u > z_info->a_max) { note(format("Too many (%u) artifacts!", tmp16u)); return (-1); } /* Read the artifact flags */ for (i = 0; i < tmp16u; i++) { byte tmp8u; rd_byte(&tmp8u); a_info[i].created = tmp8u; rd_byte(&tmp8u); rd_byte(&tmp8u); rd_byte(&tmp8u); } /* For old versions, we need to go through objects and update */ { size_t i; object_type *o_ptr = NULL; bool *anywhere; anywhere = C_ZNEW(z_info->a_max, bool); /* All inventory/home artifacts need to be marked as seen */ for (i = 0; i < INVEN_TOTAL; i++) { o_ptr = &o_list[i]; if (object_is_known_artifact(o_ptr)) artifact_of(o_ptr)->seen = TRUE; anywhere[o_ptr->name1] = TRUE; } for (i = 0; i < (size_t)o_max; i++) { o_ptr = &o_list[i]; if (object_is_known_artifact(o_ptr)) artifact_of(o_ptr)->seen = TRUE; anywhere[o_ptr->name1] = TRUE; } for (i = 0; i < MAX_STORES; i++) { int j = 0; for (j = 0; j < store[i].stock_num; j++) { o_ptr = &store[i].stock[j]; if (object_is_known_artifact(o_ptr)) artifact_of(o_ptr)->seen = TRUE; anywhere[o_ptr->name1] = TRUE; } } /* Now update the seen flags correctly */ for (i = 0; i < z_info->a_max; i++) { artifact_type *a_ptr = &a_info[i]; /* If it isn't present anywhere, but has been created, * then it has been lost, and thus seen */ if (a_ptr->created && !anywhere[i]) a_ptr->seen = TRUE; } FREE(anywhere); } return 0; }
/** * Format the object name so that the prefix is right aligned to a common * column. * * This uses the default logic of object_desc() in order to handle flavors, * artifacts, vowels and so on. It was easier to do this and then use strtok() * to break it up than to do anything else. * * \param entry is the object list entry that has a name to be formatted. * \param line_buffer is the buffer to format into. * \param size is the size of line_buffer. */ void object_list_format_name(const object_list_entry_t *entry, char *line_buffer, size_t size) { char name[80]; const char *chunk; char *source; bool has_singular_prefix; bool los = false; int field; byte old_number; struct loc pgrid = player->grid; struct object *base_obj; struct loc grid; bool object_is_recognized_artifact; if (entry == NULL || entry->object == NULL || entry->object->kind == NULL) return; base_obj = cave->objects[entry->object->oidx]; grid = entry->object->grid; object_is_recognized_artifact = object_is_known_artifact(base_obj); /* Hack - these don't have a prefix when there is only one, so just pad * with a space. */ switch (entry->object->kind->tval) { case TV_SOFT_ARMOR: if (object_is_recognized_artifact) has_singular_prefix = true; else if (base_obj->kind->sval == lookup_sval(TV_SOFT_ARMOR, "Robe")) has_singular_prefix = true; else has_singular_prefix = false; break; case TV_HARD_ARMOR: case TV_DRAG_ARMOR: if (object_is_recognized_artifact) has_singular_prefix = true; else has_singular_prefix = false; break; default: has_singular_prefix = true; break; } if (entry->object->kind != base_obj->kind) has_singular_prefix = true; /* Work out if the object is in view */ los = projectable(cave, pgrid, grid, PROJECT_NONE) || loc_eq(grid, pgrid); field = los ? OBJECT_LIST_SECTION_LOS : OBJECT_LIST_SECTION_NO_LOS; /* * Because each entry points to a specific object and not something more * general, the number of similar objects we counted has to be swapped in. * This isn't an ideal way to do this, but it's the easiest way until * object_desc is more flexible. */ old_number = entry->object->number; entry->object->number = entry->count[field]; object_desc(name, sizeof(name), base_obj, ODESC_PREFIX | ODESC_FULL); entry->object->number = old_number; /* The source string for strtok() needs to be set properly, depending on * when we use it. */ if (!has_singular_prefix && entry->count[field] == 1) { chunk = " "; source = name; } else { chunk = strtok(name, " "); source = NULL; } /* Right alight the prefix and clip. */ strnfmt(line_buffer, size, "%3.3s ", chunk); /* Get the rest of the name and clip it to fit the max width. */ chunk = strtok(source, "\0"); my_strcat(line_buffer, chunk, size); }