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;
|
|
}
|