/** * Adds an entry to the history ledger. */ bool history_add(struct player *p, const char *text, int type) { bitflag flags[HIST_SIZE]; hist_wipe(flags); hist_on(flags, type); return history_add_with_flags(p, text, flags, NULL); }
/** * Add an entry with text `event` to the history list, with type `type` * ("HIST_xxx" in player-history.h), and artifact number `id` (0 for * everything else). * * Return true on success. */ bool history_add(const char *event, int type, struct artifact *artifact) { bitflag h[HIST_SIZE]; hist_wipe(h); hist_on(h, type); return history_add_full(h, artifact, player->depth, player->lev, player->total_energy / 100, event); }
/** * Adding artifacts to the history list is trickier than other operations. * This is a wrapper function that gets some of the logic out of places * where it really doesn't belong. Call this to add an artifact to the history * list or make the history entry visible--history_add_artifact will make that * determination depending on what object_is_known returns for the artifact. */ bool history_add_artifact(struct artifact *artifact, bool known, bool found) { struct object body = { 0 }, known_body = { 0 }; struct object *fake = &body, *known_obj = &known_body; char o_name[80]; char buf[80]; assert(artifact); /* Make fake artifact for description purposes */ make_fake_artifact(fake, artifact); fake->known = known_obj; known_obj->artifact = (struct artifact *) 1; known_obj->kind = fake->kind; object_desc(o_name, sizeof(o_name), fake, ODESC_PREFIX | ODESC_BASE | ODESC_SPOIL); object_wipe(known_obj); object_wipe(fake); strnfmt(buf, sizeof(buf), (found)?"Found %s":"Missed %s", o_name); /* Known objects gets different treatment */ if (known) { /* Try revealing any existing artifact, otherwise log it */ if (history_is_artifact_logged(artifact)) history_know_artifact(artifact); else history_add(buf, HIST_ARTIFACT_KNOWN, artifact); } else { if (!history_is_artifact_logged(artifact)) { bitflag type[HIST_SIZE]; hist_wipe(type); hist_on(type, HIST_ARTIFACT_UNKNOWN); if (!found) hist_on(type, HIST_ARTIFACT_LOST); history_add_full(type, artifact, player->depth, player->lev, player->total_energy / 100, buf); } else { return false; } } return true; }
/** * Convert all ARTIFACT_UNKNOWN history items to HIST_ARTIFACT_KNOWN. * Use only after player retirement/death for the final character dump. */ void history_unmask_unknown(void) { size_t i = history_ctr; while (i--) { if (hist_has(history_list[i].type, HIST_ARTIFACT_UNKNOWN)) { hist_off(history_list[i].type, HIST_ARTIFACT_UNKNOWN); hist_on(history_list[i].type, HIST_ARTIFACT_KNOWN); } } }
/** * Convert all ARTIFACT_UNKNOWN history items to HIST_ARTIFACT_KNOWN. * Use only after player retirement/death for the final character dump. */ void history_unmask_unknown(struct player *p) { struct player_history *h = &p->hist; size_t i = h->next; while (i--) { if (hist_has(h->entries[i].type, HIST_ARTIFACT_UNKNOWN)) { hist_off(h->entries[i].type, HIST_ARTIFACT_UNKNOWN); hist_on(h->entries[i].type, HIST_ARTIFACT_KNOWN); } } }
/** * Mark artifact number `id` as lost forever. */ void history_lose_artifact(struct player *p, const struct artifact *artifact) { assert(artifact != NULL); /* Try to mark it as lost if it's already in history */ if (!history_mark_artifact_lost(&p->hist, artifact)) { /* Otherwise add a new entry */ char o_name[80]; char text[80]; get_artifact_name(o_name, sizeof(o_name), artifact); strnfmt(text, sizeof(text), "Missed %s", o_name); bitflag flags[HIST_SIZE]; hist_wipe(flags); hist_on(flags, HIST_ARTIFACT_UNKNOWN); hist_on(flags, HIST_ARTIFACT_LOST); history_add_with_flags(p, text, flags, artifact); } }
/** * Mark artifact number `id` as known. */ static bool history_know_artifact(struct artifact *artifact) { size_t i = history_ctr; assert(artifact); while (i--) { if (history_list[i].a_idx == artifact->aidx) { hist_wipe(history_list[i].type); hist_on(history_list[i].type, HIST_ARTIFACT_KNOWN); return true; } } return false; }
/** * Mark artifact as lost. */ static bool history_mark_artifact_lost(struct player_history *h, const struct artifact *artifact) { assert(artifact); size_t i = h->next; while (i--) { if (h->entries[i].a_idx == artifact->aidx) { hist_on(h->entries[i].type, HIST_ARTIFACT_LOST); return true; } } return false; }
/** * Mark artifact number `id` as lost forever, either due to leaving it on a * level, or due to a store purging its inventory after the player sold it. */ bool history_lose_artifact(struct artifact *artifact) { size_t i = history_ctr; assert(artifact); while (i--) { if (history_list[i].a_idx == artifact->aidx) { hist_on(history_list[i].type, HIST_ARTIFACT_LOST); return true; } } /* If we lost an artifact that didn't previously have a history, then we * missed it */ history_add_artifact(artifact, false, false); return false; }
/** * Add an artifact to the history log. * * Call this to add an artifact to the history list or make the history * entry visible. */ void history_find_artifact(struct player *p, const struct artifact *artifact) { assert(artifact != NULL); /* Try revealing any existing artifact, otherwise log it */ if (!history_mark_artifact_known(&p->hist, artifact)) { char o_name[80]; char text[80]; get_artifact_name(o_name, sizeof(o_name), artifact); strnfmt(text, sizeof(text), "Found %s", o_name); bitflag flags[HIST_SIZE]; hist_wipe(flags); hist_on(flags, HIST_ARTIFACT_KNOWN); history_add_with_flags(p, text, flags, artifact); } }