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 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146
|
/*
* Crossfire -- cooperative multi-player graphical RPG and adventure game
*
* Copyright (c) 1999-2014 Mark Wedel and the Crossfire Development Team
* Copyright (c) 1992 Frank Tore Johansen
*
* Crossfire is free software and comes with ABSOLUTELY NO WARRANTY. You are
* welcome to redistribute it under certain conditions. For details, please
* see COPYING and LICENSE.
*
* The authors can be reached via e-mail at <crossfire@metalforge.org>.
*/
/**
* @file
* Those functions deal with the object/type system.
*/
#include <global.h>
#include <ob_methods.h>
#include <ob_types.h>
#include <sproto.h>
/*
* The following functions are meant for calling methods. No actual behavoir
* logic should be contained in this code. Code in the common/ directory should
* be used for logic common to all types, and should always be called by
* individual method code (i.e. all apply methods should call 'can_apply' from
* common/). Defaults for all types should not be put here either, as that code
* belongs in the common/ directory also, referenced to by base_type.
*/
/**
* Apply an object by running an event hook or an object method. Consider
* using apply_manual() instead of this function if the applier should check
* for apply restrictions.
* @param op The object to apply
* @param applier The object that executes the apply action
* @param aflags Special (always apply/unapply) flags
* @retval 0 A player or monster can't apply objects of that type
* @retval 1 has been applied, or there was an error applying the object
* @retval 2 objects of that type can't be applied if not in inventory
*/
method_ret ob_apply(object *op, object *applier, int aflags) {
method_ret ret;
ob_methods *methods;
/* Lauwenmark: Handle for plugin apply event */
if (execute_event(op, EVENT_APPLY, applier, NULL, NULL, SCRIPT_FIX_ALL) != 0)
return METHOD_OK;
for (methods = &type_methods[op->type]; methods; methods = methods->fallback) {
if (methods->apply) {
ret = methods->apply(methods, op, applier, aflags);
if (ret != METHOD_UNHANDLED)
return ret;
}
}
return METHOD_UNHANDLED;
}
/**
* Processes an object, giving it the opportunity to move or react.
* Note: The return value of ob_process doesn't seem to be used anymore.
* @param op The object to process
* @retval METHOD_UNHANDLED if the process method does not exist for that objec,
*/
method_ret ob_process(object *op) {
method_ret ret;
ob_methods *methods;
for (methods = &type_methods[op->type]; methods; methods = methods->fallback) {
if (methods->process) {
ret = methods->process(methods, op);
if (ret != METHOD_UNHANDLED)
return ret;
}
}
return METHOD_UNHANDLED;
}
/**
* Returns the description of an object, as seen by the given observer.
* @param op The object to describe
* @param observer The object to which the description is made
* @param use_media_tags whether to add media tags or not on the description
* @param buf Buffer that will contain the description
* @param size Size of buf
* @return
* buf.
*/
char *ob_describe(const object *op, const object *observer, int use_media_tags, char *buf, size_t size) {
ob_methods *methods;
for (methods = &type_methods[op->type]; methods; methods = methods->fallback) {
if (methods->describe) {
methods->describe(methods, op, observer, use_media_tags, buf, size);
return buf;
}
}
buf[0] = '\0';
return buf;
}
/**
* Makes an object move on top of another one.
* @param op The object over which to move
* @param victim The object moving over op
* @param originator The object that is the cause of the move
* @retval METHOD_UNHANDLED if the process method does not exist for that object
*/
method_ret ob_move_on(object *op, object *victim, object *originator) {
method_ret ret;
ob_methods *methods;
for (methods = &type_methods[op->type]; methods; methods = methods->fallback) {
if (methods->move_on) {
ret = methods->move_on(methods, op, victim, originator);
if (ret != METHOD_UNHANDLED)
return ret;
}
}
return METHOD_UNHANDLED;
}
/**
* An object is triggered by another one.
* @param op The object being triggered
* @param cause The object that is the cause of the trigger
* @param state trigger state, 0 for released, other for pushed
* @retval METHOD_UNHANDLED if the process method does not exist for that object
* @todo check the exact state values/meaning
*/
method_ret ob_trigger(object *op, object *cause, int state) {
method_ret ret;
ob_methods *methods;
for (methods = &type_methods[op->type]; methods; methods = methods->fallback) {
if (methods->trigger) {
ret = methods->trigger(methods, op, cause, state);
if (ret != METHOD_UNHANDLED)
return ret;
}
}
return METHOD_UNHANDLED;
}
|