#ifndef WH_OBJ_H_6e168a5d_ #define WH_OBJ_H_6e168a5d_ /* * APIs exported by obj.c. */ #include #include "structs.h" /* * Format (to the FILE *) just the inventory letter for an xwi. */ extern void format_inv_letter(int, FILE *); /* * Format an INVOBJ (io) for display in an inventory list, writing the * result to f. */ extern void format_inv_line(INVOBJ *, FILE *); /* * Sort a list of INVOBJs based on a comparison function, returning the * new (sorted) list. * * (*cmp)(A,B) must return negative, zero, or positive according as A * must, may or may not, or must not come before B in the sorted list. */ extern INVOBJ *sort_inv(INVOBJ *, int (*)(INVOBJ *, INVOBJ *)); /* * Free up an OBJ. */ extern void objfree(OBJ *); /* * Free up an INVOBJ, including all the OBJs that make it up. */ extern void invobjfree(INVOBJ *); /* * Remove an INVOBJ from an INVENT. */ extern void inv_remove(INVENT *, INVOBJ *); /* * Return true if an object is present in an inventory, false if not. */ extern int inv_present(INVENT *, OBJ *); /* * Initialize an INVENT to be of a given type. The void * argument is * a backpointer: if t is IT_MON, the backpointer must be a MONST *; * if IT_LOC, a LOC *. */ extern void inv_init(INVENT *, INVTYPE, void *); /* * Split an inventory object. In * * inventory_split_n(io,newn,newxwi) * * if newn is positive, that many will remain in the old object, with * the new object getting the rest; if newn is negative, its absolute * value is how many go to the new object, with the rest remaining in * the old. The new INVOBJ is returned; the argument one is modified. */ extern INVOBJ *inventory_split_n(INVOBJ *, int, int); /* * Split a specific object out of an inventory object. In * * inventory_split_specific(io,o,newxwi) * * then o must be one of io's OBJs; it is split into its own INVOBJ. * This is used for, for example, picking a cursed weapon out of a * multi-weapon INVOBJ to force-wield it. The new INVOBJ, which will * contain nothing but o, is returned; the original INVOBJ is * modified. If the original INVOBJ would be empty after the split, * that is, if it contains no OBJs other than o, the call is an error. */ extern INVOBJ *inventory_split_specific(INVOBJ *, OBJ *, int); /* * An inventory interest function that selects everything. */ extern int invtest_all(INVOBJ *); /* * Show an inventory. The second arg is a prompt; the third, an * interest filter function; the fourth, an "if none" string, or nil * if nothing should be done if no items match. */ extern void show_inventory(INVENT *, const char *, int (*)(INVOBJ *), const char *); /* * Test to see whether an inventory has any objects in it satisfying a * filter predicate. Returns true if so or false if not. */ extern int test_inventory(INVENT *, int (*)(INVOBJ *)); /* * Pick an object from a filtered inventory, possibly with alternative * possible `exceptional' resposnes. The picked INVOBJ is returned * (still in its original place in the inventory), or nil if the * operation is aborted. * * The first arg is of course the inventory to ipck from. * * The second arg is a prompt string. * * The third arg is a callback; a user response keystroke which occurs * at a time such that it could be the first character of an inventory * item but which is not a possible inventory item keystroke will be * passed to this callback. If the callback returns false, nothing * special happens; if the callback returns true, the pick operation * is aborted immediately (presumably the callback will have set state * such that this is recognized). A nil callback operates as if it * always returns false and does nothing else. * * The fourth arg is a verb string for use in MEF_CONFUSION-generated * messages, eg "identify", "wield", "drop", etc. */ extern INVOBJ *pick_inventory(INVENT *, const char *, int (*)(INVOBJ *), int (*)(char), const char *); /* * Merge two inventories by moving all INVOBJs from one into the other. * The first arg is the inventory to be emptied; the second, the * inventory to have things added to it. After this, the first * inventory will be empty. */ extern void mergeinv(INVENT *, INVENT *); /* * This is just like mergeinv(), above, except that it makes callbacks. * Before anything else is done, an MWC_BEGIN call is made with a nil * INVOBJ pointer. The callback is called on each affected INVOBJ * with MWC_PRE, before the INVOBJ is moved, and with MWC_POST, after, * followed by an MWC_DONE call with a nil INVOBJ pointer. Finally, * after all the moving is done, an MWC_END call, also with a nil * INVOBJ pointer, is done - the BEGIN and END calls are done even if * no other calls are made. The void * callback argument is the last * arg to merge_with_cb(). * * Note that a PRE call may correspond to more than one POST call, * possibly with the same INVOBJ (because of multiple OBJs per * INVOBJ), and it is possible for POST calls for distinct PRE calls * to pass the same INVOBJ (because of merging in the target * inventory). However, every call fits the above sequence. * * The BEGIN and END callbacks may manipulate inventories and objects * arbitrarily (provided, for BEGIN, that the argument inventory * pointers remain valid); the others must not disturb the inventories * being manipulated. Objects are not promised to be anywhere in * particular for PRE and POST. Moved objects' moved methods are * called after the PRE calls and before any corresponding POST calls. */ typedef enum { MWC_BEGIN = 1, MWC_PRE, MWC_POST, MWC_DONE, MWC_END, } MWC_OP; extern void merge_with_cb(INVENT *, INVENT *, void (*)(MWC_OP, INVOBJ *, void *), void *); /* * Move a single INVOBJ (the second arg) from one inventory (the first * arg) to another (the third arg). The resulting INVOBJ is returned; * this will usually be the second arg, but may not if, for example, * the argument INVOBJ is collapsed into one already present. * * This may be called with both inventories being the same, in which * case it just operates to collapse the argument INVOBJ with anything * else it can collapse with in that inventory. */ extern INVOBJ *inv_move_1(INVENT *, INVOBJ *, INVENT *); /* * Find and return the lowest xwi value not currently in use by the * inventory. This is used for things like adding new objects to the * inventory. */ extern int find_xwi(INVENT *); /* * Initialize the object code. Called once, during startup. */ extern void initobj(void); /* * Destroy an inventory, including destroying everything in it. */ extern void destroy_inv(INVENT *); /* * Make a new object of a given type. This creates a singular object; * if a plural object is desired, the number must be set elsewhere. */ extern OBJ *obj_make(int type); /* * Add an OBJ to an inventory, including creating an INVOBJ for it if * necessary. The resulting INVOBJ, whether a new one or one the OBJ * got merged into, is returned. */ extern INVOBJ *add_obj_to_inv(OBJ *, INVENT *); /* * Split a plural OBJ. The OBJ * is the OBJ to split; the int is the * number to be split off. Returns a new OBJ holding that many of the * old OBJ's objects; the old OBJ holds the remainder. It is the * caller's responsibility to ensure that the number is strictly * between 0 and the object's number. */ extern OBJ *std_split(OBJ *, int); /* * Scan an inventory, looking for an object satisfying a predicate. * Returns the first one found, or nil if none of them match. */ extern INVOBJ *inv_scan(INVENT *, int (*)(INVOBJ *)); /* * Scan an inventory, looking for objects satisfying a predicate. * Returns the number of them found. */ extern int inv_count(INVENT *, int (*)(INVOBJ *)); /* * Inventory predicate that selects unidentified objects. */ extern int invtest_unidentified(INVOBJ *); /* * Identify an INVOBJ. If the second arg is true, report the result. */ extern void identify_it(INVOBJ *, int); /* * Remove one OBJ from an INVOBJ, the one whose index is given. It is * the caller's responsibility to ensure that the index is in range * for the INVOBJ. * * The OBJ is left detached from all INVOBJs. Its INVOBJ backpointer * is set to nil. */ extern OBJ *remove_obj_from_invobj(int, INVOBJ *); /* * Show a one-line inventory listing of a single INVOBJ. */ extern void pline_invobj(INVOBJ *); /* * A no-op object-type moved method. */ extern void noop_moved(INVOBJ *, INVENT *, INVENT *); /* * fmt_cond and fmt_spec methods which just panic, for object types * which should never call them. */ extern int panic_fmt_cond(char, INVOBJ *); extern void panic_fmt_spec(FILE *, char, INVOBJ *); /* * A no-op object-type new method, suitable for object types which have * no private data. */ extern OBJ *noop_new(int, OBJ *); /* * A no-op object-type old method, suitable for object types which have * no private data. */ extern void noop_old(OBJ *); /* * identified method for object types which are always fully identified. */ extern int always_identified(INVOBJ *); /* * identify method for object types which are always fully identified. */ extern INVOBJ *already_identify(INVOBJ *); /* * Inventory test function that selects ungateable objects. */ extern int invtest_ungateable(INVOBJ *); /* * Call a callback for every INVOBJ in an inventory. If any callback * call returns a negative number, that is immediately returned by * inv_map; otherwise, inv_map's return value is the sum of the return * values from all callbacks. (If the inventory is empty, the * callback is never called and the return value is 0.) */ extern int inv_map(INVENT *, int (*)(INVOBJ *)); /* * Register that the player has seen an object type. */ extern void see_type(int); /* * Test whether an object type is cursable, that is, whether it is * possible for an object of that type to be cursed. */ extern int obj_cursable(int); /* * Set whether an object is cursed. No-op for non-cursable objects. */ extern void obj_set_cursed(OBJ *, int); /* * An inuse method for objects which are never in use (eg, potions). */ extern int inuse_never(INVOBJ *); #endif