117 lines
		
	
	
		
			5.0 KiB
		
	
	
	
		
			Plaintext
		
	
	
			
		
		
	
	
			117 lines
		
	
	
		
			5.0 KiB
		
	
	
	
		
			Plaintext
		
	
	
| This directory is for the object-type dependent code, in addition to also
 | |
| storing some generic methods for objects which an object-type may want to
 | |
| override.
 | |
| 
 | |
| ==Organization==
 | |
|  -Place object-type specific code in this directory either as "foobar.c" or in a
 | |
|   directory, as "foobar/*.c" with logical and clear individual file names. Use
 | |
|   your discretion on if the code for the type should be split across multiple
 | |
|   C files or not
 | |
|  -If multiple type numbers are the same in behavior (i.e. armor types, though
 | |
|   those should be fixed later), it is fine to put them in the same grouping of
 | |
|   code.
 | |
|  -Code used by multiple types, that is specific to an action controlled by this
 | |
|   subsystem is put in "common/*.c" under a logical filename. This includes
 | |
|   generic code for dropping, picking up, etc.
 | |
|  -Code for an action controlled by this system, but not yet split in to
 | |
|   type-specific segments may be stored in "legacy/*.c" for the moment. This will
 | |
|   obviously be removed after refactoring is complete.
 | |
| 
 | |
| ==API==
 | |
|  -The api for this system is in "server/ob_types.c" and "server/ob_methods.c" at
 | |
|   the top level. Read the comments in those files for more complete
 | |
|   documentation.
 | |
|  -The following types are initialized and defined in init_ob_methods(), which
 | |
|   you should edit to modify.
 | |
|    -The base_type is for defining default actions for all object types. It
 | |
|     inherits from legacy_type.
 | |
|    -legacy_type is for references to code in "legacy/*.c", and does not have a
 | |
|     fallback. It will be removed when the refactoring is complete.
 | |
|  -Functions:
 | |
|    -The function, init_ob_method_struct(ob_method *methods, ob_methods *fallback)
 | |
|     initializes an ob_method struct and sets it's fallback to fallback.
 | |
|    -All functions in the form of ob_foobar(object *ob, ...) are for calling object
 | |
|     methods. They search though fallbacks when the object's type.
 | |
|    -All functions named register_foobar(int ob_type, ...) are for registering a
 | |
|     callback with the array storing object methods for different types. Use this
 | |
|     to register object_type_specific callbacks
 | |
|  -Defined types:
 | |
|    -Always make sure your callback functions match the typedefs such as
 | |
|     apply_func, as defined in ob_methods.h
 | |
| 
 | |
| ==Adding new object methods==
 | |
| As a quick reference, here is a checklist for adding a new object method for use
 | |
| in this section of the code.
 | |
|  1) Define "foobar_func" in ob_methods.h
 | |
|  2) Add "foobar" to the "ob_methods" struct  in ob_methods.h
 | |
|  3) Add a line to set it to NULL in init_ob_method_struct() in ob_methods.c
 | |
|  4) Add the boring handler function, "ob_foobar(object *ob, ...)" in
 | |
|     ob_methods.c
 | |
|  5) Add the boring "register_foobar(int ob_type, foobar_func *methodptr)"
 | |
|     function in ob_types.c
 | |
|  6) Add handler functions for base_type and/or legacy_type if applicable.
 | |
|     Reference to in init_ob_methods() in ob_methods.c
 | |
|  7) Add type-specific methods and register them in an init function for the
 | |
|     type, using register_foobar(). Call this init function in init_ob_types() in
 | |
|     ob_types.c
 | |
| 
 | |
| ==Notes on refactoring into here==
 | |
|  -Always make a note in the ChangeLog file in this directory, but don't
 | |
|   neglect the top level ChangeLog either when making changes here.
 | |
|  -Try to refactor one whole object type at a time, adding whatever object
 | |
|   methods are required.
 | |
|  -Commit often, in fact, as often as you can so long as things don't break
 | |
|  -Try not to change in-game behavior here; unless it's a really obvious bug, try
 | |
|   to leave that for separate commits either before or after moving the code.
 | |
|  -When moving code here, always review it entirely, clean up the comments, and
 | |
|   code style.
 | |
| 
 | |
| ==Example==
 | |
| 
 | |
| /** @file example.c
 | |
|  * An example of how to define a type for the object 'method' system. This
 | |
|  * example is for a simple food type with no special behavoir except for when it
 | |
|  * is applied it gives the food value to the player. Do not use this for real code,
 | |
|  and just consider it an example of how to
 | |
|  */
 | |
| 
 | |
| /**
 | |
|  * Initialize the food object type. Call this from init_ob_types in
 | |
|  * server/ob_types.c
 | |
|  */
 | |
| void init_type_food() {
 | |
|     register_apply(FOOD, food_type_apply);
 | |
|     register_apply(FLESH, food_type_apply);
 | |
|     register_apply(DRINK, food_type_apply);
 | |
| }
 | |
| 
 | |
| /**
 | |
|  * ob_method handler for FOOD, FLESH and DRINK object types.
 | |
|  * @todo Handle cursed food
 | |
|  * @todo Add hook for dragon resistance gaining
 | |
|  * @todo Give special messages when full
 | |
|  * @note Remember this is just an example ;-)
 | |
|  */
 | |
| method_ret food_type_apply(ob_methods *context, object *ob, object *pl) {
 | |
|     method_ret can_apply;
 | |
| 
 | |
|     /*
 | |
|      * Call the 'can_apply' method for the player to check if the player can
 | |
|      * indeed apply it (checking if the player can reach it, etc).
 | |
|      */
 | |
|     can_apply = ob_can_apply(pl, ob);
 | |
|     if (can_apply == METHOD_OK) {
 | |
|         char name[MAX_BUF];
 | |
|         query_name(ob, name, MAX_BUF);
 | |
|         pl->stats.food += ob->stats.food;
 | |
|         if (pl->stats.food > 999)
 | |
|             pl->stats.food = 999;
 | |
|         draw_ext_info_format(NDI_UNIQUE, 0, pl, MSG_TYPE_APPLY, MSG_TYPE_APPLY_SUCCESS,
 | |
|              "You eat the %s!",
 | |
|              "You eat the %s!",
 | |
|              );
 | |
|         decrease_ob(ob);
 | |
|     }
 | |
|     return METHOD_OK;
 | |
| }
 |