blob: 3d292c0adb33422a58e7bdb22e260da2313a139f [file] [log] [blame]
MG Mud User88f12472016-06-24 23:31:02 +02001// MorgenGrauen MUDlib
2//
3// living/helpers.c -- (Query)Methoden fuer Hilfsobjekte, z.B. zum Tauchen
4//
5// $Id: moneyhandler.h,v 3.1 1997/02/12 13:29:09 Wargon Exp %
6
7#pragma strong_types
8#pragma save_types
9#pragma range_check
10#pragma no_clone
11#pragma pedantic
12
13#include <living/helpers.h>
14#define NEED_PROTOTYPES
15#include <thing/properties.h>
16#undef NEED_PROTOTYPES
17
18public int RegisterHelperObject(object helper, int type,
19 string|closure callback)
20{
21 // cb: closure auf die Callback-Funktion in previous_object()
22 closure cb;
23 // helpers: Mapping aller eingetragenen Helfer-Objekte
24 mapping helpers;
25
26 // Kein positiver Integerwert als Helfertyp uebergeben?
27 if ( !intp(type) || type < 1 )
28 raise_error(sprintf( "Wrong argument 1 to RegisterHelperObject(). "
29 "Expected positive <int>, got %O.\n", type));
30 // Kein Objekt vorhanden, an dem die Callback-Funktion gerufen werden soll?
31 if ( !objectp(helper) )
32 return HELPER_NO_CALLBACK_OBJECT;
33
34 // Funktionsname zum Zweck des Callbacks uebergeben?
35 if ( stringp(callback) ) {
36 // Dann Closure davon erstellen.
37 cb = symbol_function(callback, helper);
38 // Wenn das nicht klappt (zB weil die Funktion private ist), dann
39 // Fehler werfen und abbrechen.
40 if ( !closurep(cb) )
41 raise_error(sprintf("Error in RegisterHelperObject(): Unable to call "
42 "function %s in object %O.\n", callback, helper));
43 }
44 // Wenn schon eine Closure uebergeben wurde, dann diese direkt speichern.
45 else if ( closurep(callback) ) {
46 cb = callback;
47 }
48 // Weder Funktionsname, noch Closure, dann Fehler werfen und abbrechen.
49 else
50 raise_error(sprintf("Wrong argument 2 to RegisterHelperObject(). "
51 "Expected <string/closure>, got %O.\n",callback));
52
53 // Property auslesen und zwischenspeichern
54 helpers = QueryProp(P_HELPER_OBJECTS);
55 // Wenn die Prop leer ist, hier initialisieren
56 if ( !helpers ) {
57 helpers = ([type:({})]);
58 }
59 // Wenn der Typ noch nicht existiert, hier nachtragen.
60 else if ( !pointerp(helpers[type]) ) {
61 helpers[type] = ({});
62 }
63
64 // Closure eintragen, wenn noch nicht vorhanden
65 if ( member(helpers[type], cb)==-1 ) {
66 helpers[type] = helpers[type]+({cb});
67 SetProp(P_HELPER_OBJECTS, helpers);
68 return HELPER_SUCCESS;
69 }
70 else
71 return HELPER_ALREADY_LISTED;
72}
73
74public int UnregisterHelperObject(object helper, int type) {
75 if ( !intp(type) || type < 1 )
76 raise_error(sprintf( "Wrong argument 2 to UnregisterHelperObject(). "
77 "Expected positive <int>, got %O.\n", type));
78 if ( !objectp(helper) )
79 return HELPER_NO_CALLBACK_OBJECT;
80
81 mapping helpers = Query(P_HELPER_OBJECTS, F_VALUE);
82
83 if ( mappingp(helpers) ) {
84 foreach(closure cl: helpers[type]) {
85 if ( get_type_info(cl,2) == helper ) {
86 helpers[type] = helpers[type]-({cl});
87 return HELPER_SUCCESS;
88 }
89 }
90 }
91 return HELPER_NOTHING_TO_UNREGISTER;
92}
93
94// Querymethode fuer P_AQUATIC_HELPERS
95public mapping _query_lib_p_aquatic_helpers() {
96 mapping ret = ([]);
97 // eingetragene Callback-Closures auslesen
98 closure *helpers =
99 ( Query(P_HELPER_OBJECTS, F_VALUE) || ([]) )[HELPER_TYPE_AQUATIC];
100 // Es sind gar keine Werte eingetragen? Dann gleich rausspringen.
101 if ( !pointerp(helpers) )
102 return ret;
103
104 // Nullelement substrahieren
105 helpers -= ({0});
106
107 if ( sizeof(helpers) ) {
108 // Mapping erstellen: Keys sind die Objekte, deren Closures eingetragen
109 // sind. Values sind die Rueckgabewerte der Closures,
110 // die dabei das Spielerobjekt und das abfragende Objekt uebergeben
111 // bekommen.
112 object *keys = map(helpers, #'get_type_info, 2);
113 int *vals = map(helpers, #'funcall, this_object(), previous_object(1));
114 ret = mkmapping(keys,vals);
115 }
116 return ret;
117}
118
119// Querymethode fuer P_AERIAL_HELPERS
120public mapping _query_lib_p_aerial_helpers() {
121 mapping ret = ([]);
122 // eingetragene Callback-Closures auslesen
123 closure *helpers =
124 ( Query(P_HELPER_OBJECTS, F_VALUE) || ([]) )[HELPER_TYPE_AERIAL];
125
126 // Es sind gar keine Werte eingetragen? Dann gleich rausspringen.
127 if ( !pointerp(helpers) )
128 return ret;
129
130 // Nullelement substrahieren
131 helpers -= ({0});
132
133 if ( sizeof(helpers) ) {
134 // Mapping erstellen: Keys sind die Objekte, deren Closures eingetragen
135 // sind. Values sind die Rueckgabewerte der Closures,
136 // die dabei das Spielerobjekt und das abfragende Objekt uebergeben
137 // bekommen.
138 object *keys = map(helpers,#'get_type_info, 2);
139 int *vals = map(helpers, #'funcall, this_object(), previous_object(1));
140 ret = mkmapping(keys,vals);
141 }
142 return ret;
143}
144
145// Querymethode fuer P_HELPER_OBJECTS
146public mapping _query_lib_p_helper_objects() {
147 return deep_copy(Query(P_HELPER_OBJECTS,F_VALUE));
148}
149