Objects are one of the main structures in Crossfire. They represent every item the player can interact with, including skills, experience, spells and their effects, monsters, walls...
Objects in Crossfire are represented by the obj structure. One important field is object::type, which defines the object type (wall, monster, exit, ...). Another important field is object::flags "the flags", that indicate some special properties of the object.
- link to types, flags, ...
This structure should not be created directly, but managed through suitable functions (see Object manipulation functions
An object can exist in the following states:
- freed, with its FLAG_FREED set. Such an object should never be manipulated
- removed, with its FLAG_REMOVED set. The object is in an indeterminate state, between insertion in a map or in another object and destruction
- in another object, in which case its object::env field points to the containing object
- on a map, in which case the object::map, object::x and object::x fields specify where it is located.
Objects are managed on lists, one object can be on different lists.
The following global object lists are defined, the object::next and object::prev fields are used to link to the other objects:
- a freed object list, containing all objects once used and now unused. Items on this list can be recycled and reused later. The pointer to the first item is free_objects
- an allocated object list, containing all objects currently used, on a map or in another object. The pointer to the first item is objects
- an active object list, containing all objects that change over time (with object::speed not 0). The pointer to the first item is active_objects. Fields used to specify next and previous items are object::active_next and object::active_prev.
The following local object lists are defined:
- write :)
Most of the object manipulation functions are defined in the object.c
An object can be obtained:
An object will be freed, thus become invalid:
When you manipulate an object that interacts with a player, thus with a remote client, the client needs to be informed of changes to the manipulated object.
The general object manipulation functions like remove_ob(), insert_ob_in_ob() and such will automatically update the client's status if needed when used with such an obecjt.
If you change some fields of the objets that the client knows about (name, weight, cursed status, ...), you need to call esrv_update_item() with the correct flags. See this section for fields the client knows about.
Various functions exist to manipulate objects. They should be used instead of modifying the field directly, because the field has side-effects.
- update_ob_speed() should be called when changing the speed from 0 to a non 0 value or vice-versa
- add_weight() and sub_weight() should be called when an object changes weight. Containers can reduce the weight of items they contain, thus there is a need for full weight update of containers
- fix_object() will reset an object to its archetype values and apply all modifiers from items in inventory. This is mostly called for living things (players and monsters).
There are special objects that, even if they use the obj
structure, should not be manipulated through the usual functions.
Archetypes have a archetype::clone field that is an obj structure. This object is never on any list, even if active.
Artifacts have a malloc()'d artifact::item object structure, that isn't on any list either. Those objects should never be manipulated directly.