/** * Cheat -- describe a created object for the user */ static void object_mention(object_type * o_ptr) { char o_name[120]; /* Describe */ object_desc(o_name, sizeof(o_name), o_ptr, ODESC_BASE | ODESC_SPOIL); /* Artifact */ if (artifact_p(o_ptr)) { /* Silly message */ msg("Artifact (%s)", o_name); } /* Ego-item */ else if (ego_item_p(o_ptr)) { /* Silly message */ msg("Ego-item (%s)", o_name); } /* Normal item */ else { /* Silly message */ msg("Object (%s)", o_name); } }
static size_t obj_desc_inscrip(const object_type *o_ptr, char *buf, size_t max, size_t end) { const char *u[4] = { 0, 0, 0, 0 }; int n = 0; int feel = object_pseudo(o_ptr); bitflag flags_known[OF_SIZE]; object_flags_known(o_ptr, flags_known); /* Get inscription */ if (o_ptr->note) u[n++] = quark_str(o_ptr->note); /* Use special inscription, if any */ if (!object_is_known(o_ptr) && feel) { /* cannot tell excellent vs strange vs splendid until wield */ if (!object_was_worn(o_ptr) && ego_item_p(o_ptr)) u[n++] = "ego"; else u[n++] = inscrip_text[feel]; } else if ((o_ptr->ident & IDENT_EMPTY) && !object_is_known(o_ptr)) u[n++] = "empty"; else if (!object_is_known(o_ptr) && object_was_worn(o_ptr)) { if (wield_slot(o_ptr) == INVEN_WIELD || wield_slot(o_ptr) == INVEN_BOW) u[n++] = "wielded"; else u[n++] = "worn"; } else if (!object_is_known(o_ptr) && object_was_fired(o_ptr)) u[n++] = "fired"; else if (!object_flavor_is_aware(o_ptr) && object_flavor_was_tried(o_ptr)) u[n++] = "tried"; /* Note curses */ if (flags_test(flags_known, OF_SIZE, OF_CURSE_MASK, FLAG_END)) u[n++] = "cursed"; /* Note squelch */ if (squelch_item_ok(o_ptr)) u[n++] = "squelch"; if (n) { int i; for (i = 0; i < n; i++) { if (i == 0) strnfcat(buf, max, &end, " {"); strnfcat(buf, max, &end, "%s", u[i]); if (i < n-1) strnfcat(buf, max, &end, ", "); } strnfcat(buf, max, &end, "}"); } return end; }
/* * Cheat -- describe a created object for the user */ static void object_mention(object_type *o_ptr) { char o_name[80]; /* Describe */ object_desc_store(o_name, o_ptr, FALSE, 0); /* Artifact */ if (artifact_p(o_ptr)) { /* Silly message */ msg_format("Artifact (%s)", o_name); } /* Random Artifact */ else if (o_ptr->art_name) { msg_print("Random artifact"); } /* Ego-item */ else if (ego_item_p(o_ptr)) { /* Silly message */ msg_format("Ego-item (%s)", o_name); } /* Normal item */ else { /* Silly message */ msg_format("Object (%s)", o_name); } }
/* * Checks for additional knowledge implied by what the player already knows. * * \param o_ptr is the object to check * * returns whether it calls object_notice_everyting */ bool object_check_for_ident(object_type *o_ptr) { bitflag flags[OF_SIZE], known_flags[OF_SIZE]; object_flags(o_ptr, flags); object_flags_known(o_ptr, known_flags); /* Some flags are irrelevant or never learned or too hard to learn */ flags_clear(flags, OF_SIZE, OF_OBJ_ONLY_MASK, FLAG_END); flags_clear(known_flags, OF_SIZE, OF_OBJ_ONLY_MASK, FLAG_END); if (!of_is_equal(flags, known_flags)) return FALSE; /* If we know attack bonuses, and defence bonuses, and effect, then * we effectively know everything, so mark as such */ if ((object_attack_plusses_are_visible(o_ptr) || (object_was_sensed(o_ptr) && o_ptr->to_h == 0 && o_ptr->to_d == 0)) && (object_defence_plusses_are_visible(o_ptr) || (object_was_sensed(o_ptr) && o_ptr->to_a == 0)) && (object_effect_is_known(o_ptr) || !object_effect(o_ptr))) { object_notice_everything(o_ptr); return TRUE; } /* We still know all the flags, so we still know if it's an ego */ else if (ego_item_p(o_ptr)) { /* require worn status so you don't learn launcher of accuracy or gloves of slaying before wield */ if (object_was_worn(o_ptr)) object_notice_ego(o_ptr); } return FALSE; }
/** * \returns whether both the object is both an ego and the player knows it is */ bool object_ego_is_visible(const object_type *o_ptr) { if (!ego_item_p(o_ptr)) return FALSE; if (o_ptr->tval == TV_LIGHT) return TRUE; if ((o_ptr->ident & IDENT_NAME) || (o_ptr->ident & IDENT_STORE)) return TRUE; else return FALSE; }
/** * Return a "feeling" (or FEEL_NONE) about an item. Method 1 (Heavy). */ int value_check_aux1(object_type * o_ptr) { int slot = wield_slot(o_ptr); /* Wieldable? */ if (slot < 0) return FEEL_NONE; /* No pseudo for lights */ if (slot == INVEN_LIGHT) return FEEL_NONE; /* Artifacts */ if (artifact_p(o_ptr)) { /* All return special now */ return FEEL_SPECIAL; } /* Ego-Items */ if (ego_item_p(o_ptr)) { /* Dubious egos (including jewellery) */ if (item_dubious(o_ptr, TRUE)) return FEEL_PERILOUS; /* Normal */ o_ptr->ident |= (IDENT_UNCURSED | IDENT_KNOW_CURSES); return FEEL_EXCELLENT; } /* Dubious items */ if (item_dubious(o_ptr, TRUE)) return FEEL_DUBIOUS_STRONG; /* Known not cursed now */ o_ptr->ident |= (IDENT_UNCURSED | IDENT_KNOW_CURSES); /* No average jewellery */ if ((slot >= INVEN_LEFT) && (slot <= INVEN_NECK)) return FEEL_GOOD_STRONG; /* Good "armor" bonus */ if (o_ptr->to_a > 0) return FEEL_GOOD_STRONG; /* Good "weapon" bonus */ if (o_ptr->to_h + o_ptr->to_d > 0) return FEEL_GOOD_STRONG; /* Default to "average" */ return FEEL_AVERAGE; }
/* * Cheat -- describe a created object for the user */ static void object_mention(const object_type *o_ptr) { char o_name[80]; /* Describe */ object_desc(o_name, sizeof(o_name), o_ptr, ODESC_BASE | ODESC_SPOIL); /* Provide a silly message */ if (artifact_p(o_ptr)) msg_format("Artifact (%s)", o_name); else if (ego_item_p(o_ptr)) msg_format("Ego-item (%s)", o_name); else msg_format("Object (%s)", o_name); }
/** * Return a "feeling" (or FEEL_NONE) about an item. Method 2 (Light). */ int value_check_aux2(object_type * o_ptr) { int slot = wield_slot(o_ptr); /* Wieldable? */ if (slot < 0) return FEEL_NONE; /* No pseudo for lights */ if (slot == INVEN_LIGHT) return FEEL_NONE; /* Dubious items (all of them) */ if (item_dubious(o_ptr, TRUE)) return FEEL_DUBIOUS_WEAK; /* Known not cursed now */ o_ptr->ident |= (IDENT_UNCURSED | IDENT_KNOW_CURSES); /* Artifacts -- except dubious ones */ if (artifact_p(o_ptr)) return FEEL_GOOD_WEAK; /* Ego-Items -- except dubious ones */ if (ego_item_p(o_ptr)) return FEEL_GOOD_WEAK; /* Good armor bonus */ if (o_ptr->to_a > 0) return FEEL_GOOD_WEAK; /* Good weapon bonuses */ if (o_ptr->to_h + o_ptr->to_d > 0) return FEEL_GOOD_WEAK; /* SJGU */ /* Default to "average" */ return FEEL_AVERAGE; }
/* * Return a "feeling" (or NULL) about an item. Method 1 (Heavy). */ static int value_check_aux1(object_type *o_ptr) { /* Artifacts */ if (artifact_p(o_ptr)) { /* Cursed/Broken */ if (cursed_p(o_ptr) || broken_p(o_ptr)) return (FEEL_TERRIBLE); /* Normal */ return (FEEL_SPECIAL); } /* Ego-Items */ if (ego_item_p(o_ptr)) { /* Cursed/Broken */ if (cursed_p(o_ptr) || broken_p(o_ptr)) return (FEEL_WORTHLESS); /* Normal */ return (FEEL_EXCELLENT); } /* Cursed items */ if (cursed_p(o_ptr)) return (FEEL_CURSED); /* Broken items */ if (broken_p(o_ptr)) return (FEEL_BROKEN); /* Good "armor" bonus */ if (o_ptr->to_a > 0) return (FEEL_GOOD); /* Good "weapon" bonus */ if (o_ptr->to_h + o_ptr->to_d > 0) return (FEEL_GOOD); /* Default to "average" */ return (FEEL_AVERAGE); }
/* * Determine if an item can "absorb" a second item * * See "object_absorb()" for the actual "absorption" code. * * If permitted, we allow wands/staffs (if they are known to have equal * charges) and rods (if fully charged) to combine. They will unstack * (if necessary) when they are used. * * If permitted, we allow weapons/armor to stack, if fully "known". * * Missiles will combine if both stacks have the same "known" status. * This is done to make unidentified stacks of missiles useful. * * Food, potions, scrolls, and "easy know" items always stack. * * Chests, and activatable items, never stack (for various reasons). */ bool object_similar(object_type *o_ptr, object_type *j_ptr) { s32b i; s32b total = o_ptr->number + j_ptr->number; s32b similar = TRUE; /* Require identical object types */ if (o_ptr->k_idx != j_ptr->k_idx) similar = FALSE; /* Only identified objects can stack */ /* even this is not enough to stop the user being surprised by * (e.g.) ego items which might have random powers being * different although they look the same. This is in fact * fairly unlikely (having *exactly* the same plusses etc) */ if (!object_known_p(o_ptr) || !object_known_p(j_ptr)) similar = FALSE; /* Beware artifatcs should not combibne with "lesser" thing */ /* perhaps they should not combine at all? */ if (artifact_p(o_ptr) != artifact_p(j_ptr)) similar = FALSE; /* Do not combine different ego or normal ones */ if (ego_item_p(o_ptr) != ego_item_p(j_ptr)) similar = FALSE; /* stuff to implement in ToME lua hooks * instruments don't stack * check stack option setting for certain kinds of items */ /* Require identical "turns of light" */ if (o_ptr->timeout != j_ptr->timeout) similar = FALSE; /* Require identical "bonuses" */ if (o_ptr->to_h != j_ptr->to_h) similar = FALSE; if (o_ptr->to_d != j_ptr->to_d) similar = FALSE; if (o_ptr->to_a != j_ptr->to_a) similar = FALSE; /* Require identical exploding status code */ if (get_flag(o_ptr, FLAG_EXPLODE) != get_flag(j_ptr, FLAG_EXPLODE)) similar = FALSE; /* Require identical "artifact" names */ if (o_ptr->artifact_id != j_ptr->artifact_id) similar = FALSE; /* Random artifacts never stack */ /* I don't see why these shouldn't stack. -- wilh */ if (o_ptr->art_name || j_ptr->art_name) similar = FALSE; /* Require identical "ego-item" names */ for (i = 0; i < MAX_EGO_PER_OBJ; i++) if (o_ptr->ego_id[i] != j_ptr->ego_id[i]) similar = FALSE; /* Hack -- Never stack "powerful" items */ /* Why?! -- wilh */ if (o_ptr->xtra1 || j_ptr->xtra1) similar = FALSE; /* Require identical "values" */ if (o_ptr->ac != j_ptr->ac) similar = FALSE; if (o_ptr->dd != j_ptr->dd) similar = FALSE; if (o_ptr->ds != j_ptr->ds) similar = FALSE; /* Identical flags! */ if (!flag_equal(&o_ptr->flags, &j_ptr->flags)) similar = FALSE; /* Hack -- Require identical "cursed" status */ if ((o_ptr->ident & (IDENT_CURSED)) != (j_ptr->ident & (IDENT_CURSED))) similar = FALSE; /* Hack -- require semi-matching "inscriptions" */ if (o_ptr->note && j_ptr->note && (o_ptr->note != j_ptr->note)) similar = FALSE; /* move the next two checks into game/tome/scripts/objects.lua ? */ /* Hack -- normally require matching "inscriptions" */ if (!stack_force_notes && (o_ptr->note != j_ptr->note)) similar = FALSE; /* Hack -- normally require matching "discounts" */ if (!stack_force_costs && (o_ptr->discount != j_ptr->discount)) similar = FALSE; /* Maximal "stacking" limit */ if (total >= MAX_STACK_SIZE) similar = FALSE; if (process_hooks_ret(HOOK_OBJECT_SIMILAR, "d", "(O,O,d)", o_ptr, j_ptr, similar)) return process_hooks_return[0].num; return similar; }
/* XXX Eddie should messages be adhoc all over the place? perhaps the main * loop should check for change in inventory/wieldeds and all messages be * printed from one place */ void object_notice_on_wield(object_type *o_ptr) { bitflag f[OF_SIZE], obvious_mask[OF_SIZE]; bool obvious = FALSE; const slay_t *s_ptr; flags_init(obvious_mask, OF_SIZE, OF_OBVIOUS_MASK, FLAG_END); /* Save time of wield for later */ object_last_wield = turn; /* Only deal with un-ID'd items */ if (object_is_known(o_ptr)) return; /* Wear it */ object_flavor_tried(o_ptr); if (object_add_ident_flags(o_ptr, IDENT_WORN)) object_check_for_ident(o_ptr); if (obj_is_light(o_ptr) && ego_item_p(o_ptr)) object_notice_ego(o_ptr); if (object_flavor_is_aware(o_ptr) && easy_know(o_ptr)) { object_notice_everything(o_ptr); return; } /* Automatically sense artifacts upon wield */ object_sense_artifact(o_ptr); /* Note artifacts when found */ if (artifact_p(o_ptr)) history_add_artifact(o_ptr->name1, object_is_known(o_ptr), TRUE); /* special case FA, needed at least for mages wielding gloves */ if (object_FA_would_be_obvious(o_ptr)) of_on(obvious_mask, OF_FREE_ACT); /* Learn about obvious flags */ of_union(o_ptr->known_flags, obvious_mask); /* Extract the flags */ object_flags(o_ptr, f); /* Find obvious things (disregarding curses) */ flags_clear(obvious_mask, OF_SIZE, OF_CURSE_MASK, FLAG_END); if (of_is_inter(f, obvious_mask)) obvious = TRUE; flags_init(obvious_mask, OF_SIZE, OF_OBVIOUS_MASK, FLAG_END); /* XXX Eddie should these next NOT call object_check_for_ident due to worries about repairing? */ /* XXX Eddie this is a small hack, but jewelry with anything noticeable really is obvious */ /* XXX Eddie learn =soulkeeping vs =bodykeeping when notice sustain_str */ if (object_is_jewelry(o_ptr)) { /* Learn the flavor of jewelry with obvious flags */ if (EASY_LEARN && obvious) object_flavor_aware(o_ptr); /* Learn all flags on any aware non-artifact jewelry */ if (object_flavor_is_aware(o_ptr) && !artifact_p(o_ptr)) object_know_all_flags(o_ptr); } object_check_for_ident(o_ptr); if (!obvious) return; /* Messages */ for (s_ptr = slay_table; s_ptr->slay_flag; s_ptr++) { if (of_has(f, s_ptr->slay_flag) && s_ptr->brand) { char o_name[40]; object_desc(o_name, sizeof(o_name), o_ptr, ODESC_BASE); msg_format("Your %s %s!", o_name, s_ptr->active_verb); } } /* XXX Eddie need to add stealth here, also need to assert/double-check everything is covered */ if (of_has(f, OF_STR)) msg_format("You feel %s!", o_ptr->pval > 0 ? "stronger" : "weaker"); if (of_has(f, OF_INT)) msg_format("You feel %s!", o_ptr->pval > 0 ? "smarter" : "more stupid"); if (of_has(f, OF_WIS)) msg_format("You feel %s!", o_ptr->pval > 0 ? "wiser" : "more naive"); if (of_has(f, OF_DEX)) msg_format("You feel %s!", o_ptr->pval > 0 ? "more dextrous" : "clumsier"); if (of_has(f, OF_CON)) msg_format("You feel %s!", o_ptr->pval > 0 ? "healthier" : "sicklier"); if (of_has(f, OF_CHR)) msg_format("You feel %s!", o_ptr->pval > 0 ? "cuter" : "uglier"); if (of_has(f, OF_SPEED)) msg_format("You feel strangely %s.", o_ptr->pval > 0 ? "quick" : "sluggish"); if (flags_test(f, OF_SIZE, OF_BLOWS, OF_SHOTS, FLAG_END)) msg_format("Your hands %s", o_ptr->pval > 0 ? "tingle!" : "ache."); if (of_has(f, OF_INFRA)) msg_format("Your eyes tingle."); if (of_has(f, OF_LIGHT)) msg_print("It glows!"); if (of_has(f, OF_TELEPATHY)) msg_print("Your mind feels strangely sharper!"); /* WARNING -- masking f by obvious mask -- this should be at the end of this function */ flags_mask(f, OF_SIZE, OF_OBVIOUS_MASK, FLAG_END); /* learn the ego on any obvious brand or slay */ if (EASY_LEARN && ego_item_p(o_ptr) && obvious && flags_test(f, OF_SIZE, OF_ALL_SLAY_MASK, FLAG_END)) object_notice_ego(o_ptr); /* Remember the flags */ object_notice_sensing(o_ptr); /* XXX Eddie should we check_for_ident here? */ }
/* * Given an object, return a short identifier which gives some idea of what * the item is. */ obj_pseudo_t object_pseudo(const object_type *o_ptr) { object_kind *k_ptr = &k_info[o_ptr->k_idx]; bitflag flags[OF_SIZE]; /* Get the known and obvious flags on the object, * not including curses or properties of the kind */ object_flags_known(o_ptr, flags); /* MEGA-hack : there needs to be a table of what is obvious in each slot perhaps for each class */ /* FA on gloves is obvious to mage casters */ if (object_FA_would_be_obvious(o_ptr)) flags_mask(flags, OF_SIZE, OF_OBVIOUS_MASK, OF_FREE_ACT, FLAG_END); else flags_mask(flags, OF_SIZE, OF_OBVIOUS_MASK, FLAG_END); flags_clear(flags, OF_SIZE, OF_CURSE_MASK, FLAG_END); of_diff(flags, k_ptr->flags); if (o_ptr->ident & IDENT_INDESTRUCT) return INSCRIP_SPECIAL; if ((object_was_sensed(o_ptr) || object_was_worn(o_ptr)) && artifact_p(o_ptr)) return INSCRIP_SPECIAL; /* jewelry does not pseudo */ if (object_is_jewelry(o_ptr)) return INSCRIP_NULL; /* XXX Eddie should also check for flags with pvals where the pval exceeds * the base pval for things like picks of digging, though for now acid brand gets those */ if (!of_is_empty(flags)) return INSCRIP_SPLENDID; if (!object_is_known(o_ptr) && !object_was_sensed(o_ptr)) return INSCRIP_NULL; if (ego_item_p(o_ptr)) { /* uncursed bad egos are not excellent */ if (flags_test(e_info[o_ptr->name2].flags, OF_SIZE, OF_CURSE_MASK, FLAG_END)) return INSCRIP_STRANGE; /* XXX Eddie need something worse */ else return INSCRIP_EXCELLENT; } if (o_ptr->to_a == randcalc(k_ptr->to_a, 0, MINIMISE) && o_ptr->to_h == randcalc(k_ptr->to_h, 0, MINIMISE) && o_ptr->to_d == randcalc(k_ptr->to_d, 0, MINIMISE)) return INSCRIP_AVERAGE; if (o_ptr->to_a >= randcalc(k_ptr->to_a, 0, MINIMISE) && o_ptr->to_h >= randcalc(k_ptr->to_h, 0, MINIMISE) && o_ptr->to_d >= randcalc(k_ptr->to_d, 0, MINIMISE)) return INSCRIP_MAGICAL; if (o_ptr->to_a <= randcalc(k_ptr->to_a, 0, MINIMISE) && o_ptr->to_h <= randcalc(k_ptr->to_h, 0, MINIMISE) && o_ptr->to_d <= randcalc(k_ptr->to_d, 0, MINIMISE)) return INSCRIP_MAGICAL; return INSCRIP_STRANGE; }