File: README

package info (click to toggle)
crossfire 1.75.0-9
  • links: PTS, VCS
  • area: main
  • in suites: forky, sid
  • size: 24,168 kB
  • sloc: ansic: 83,169; sh: 4,659; perl: 1,736; lex: 1,443; makefile: 1,199; python: 43
file content (116 lines) | stat: -rw-r--r-- 5,150 bytes parent folder | download | duplicates (4)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
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 > MAX_FOOD)
            pl->stats.food = MAX_FOOD;
        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;
}