blob: 91c480f6085df6adc844a8f03c1c632b3b9c7aca [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
MG Mud User88f12472016-06-24 23:31:02 +020011
12#include <living/helpers.h>
13#define NEED_PROTOTYPES
14#include <thing/properties.h>
15#undef NEED_PROTOTYPES
16
17public int RegisterHelperObject(object helper, int type,
18 string|closure callback)
19{
20 // cb: closure auf die Callback-Funktion in previous_object()
21 closure cb;
22 // helpers: Mapping aller eingetragenen Helfer-Objekte
23 mapping helpers;
24
25 // Kein positiver Integerwert als Helfertyp uebergeben?
26 if ( !intp(type) || type < 1 )
27 raise_error(sprintf( "Wrong argument 1 to RegisterHelperObject(). "
28 "Expected positive <int>, got %O.\n", type));
29 // Kein Objekt vorhanden, an dem die Callback-Funktion gerufen werden soll?
30 if ( !objectp(helper) )
31 return HELPER_NO_CALLBACK_OBJECT;
32
33 // Funktionsname zum Zweck des Callbacks uebergeben?
34 if ( stringp(callback) ) {
35 // Dann Closure davon erstellen.
36 cb = symbol_function(callback, helper);
37 // Wenn das nicht klappt (zB weil die Funktion private ist), dann
38 // Fehler werfen und abbrechen.
39 if ( !closurep(cb) )
40 raise_error(sprintf("Error in RegisterHelperObject(): Unable to call "
41 "function %s in object %O.\n", callback, helper));
42 }
43 // Wenn schon eine Closure uebergeben wurde, dann diese direkt speichern.
44 else if ( closurep(callback) ) {
45 cb = callback;
46 }
47 // Weder Funktionsname, noch Closure, dann Fehler werfen und abbrechen.
48 else
49 raise_error(sprintf("Wrong argument 2 to RegisterHelperObject(). "
50 "Expected <string/closure>, got %O.\n",callback));
51
52 // Property auslesen und zwischenspeichern
53 helpers = QueryProp(P_HELPER_OBJECTS);
54 // Wenn die Prop leer ist, hier initialisieren
55 if ( !helpers ) {
56 helpers = ([type:({})]);
57 }
58 // Wenn der Typ noch nicht existiert, hier nachtragen.
59 else if ( !pointerp(helpers[type]) ) {
60 helpers[type] = ({});
61 }
62
63 // Closure eintragen, wenn noch nicht vorhanden
64 if ( member(helpers[type], cb)==-1 ) {
65 helpers[type] = helpers[type]+({cb});
66 SetProp(P_HELPER_OBJECTS, helpers);
67 return HELPER_SUCCESS;
68 }
69 else
70 return HELPER_ALREADY_LISTED;
71}
72
73public int UnregisterHelperObject(object helper, int type) {
74 if ( !intp(type) || type < 1 )
75 raise_error(sprintf( "Wrong argument 2 to UnregisterHelperObject(). "
76 "Expected positive <int>, got %O.\n", type));
77 if ( !objectp(helper) )
78 return HELPER_NO_CALLBACK_OBJECT;
79
80 mapping helpers = Query(P_HELPER_OBJECTS, F_VALUE);
81
82 if ( mappingp(helpers) ) {
83 foreach(closure cl: helpers[type]) {
84 if ( get_type_info(cl,2) == helper ) {
85 helpers[type] = helpers[type]-({cl});
86 return HELPER_SUCCESS;
87 }
88 }
89 }
90 return HELPER_NOTHING_TO_UNREGISTER;
91}
92
93// Querymethode fuer P_AQUATIC_HELPERS
94public mapping _query_lib_p_aquatic_helpers() {
95 mapping ret = ([]);
96 // eingetragene Callback-Closures auslesen
97 closure *helpers =
98 ( Query(P_HELPER_OBJECTS, F_VALUE) || ([]) )[HELPER_TYPE_AQUATIC];
99 // Es sind gar keine Werte eingetragen? Dann gleich rausspringen.
100 if ( !pointerp(helpers) )
101 return ret;
102
103 // Nullelement substrahieren
104 helpers -= ({0});
105
106 if ( sizeof(helpers) ) {
107 // Mapping erstellen: Keys sind die Objekte, deren Closures eingetragen
108 // sind. Values sind die Rueckgabewerte der Closures,
109 // die dabei das Spielerobjekt und das abfragende Objekt uebergeben
110 // bekommen.
111 object *keys = map(helpers, #'get_type_info, 2);
112 int *vals = map(helpers, #'funcall, this_object(), previous_object(1));
113 ret = mkmapping(keys,vals);
114 }
115 return ret;
116}
117
118// Querymethode fuer P_AERIAL_HELPERS
119public mapping _query_lib_p_aerial_helpers() {
120 mapping ret = ([]);
121 // eingetragene Callback-Closures auslesen
122 closure *helpers =
123 ( Query(P_HELPER_OBJECTS, F_VALUE) || ([]) )[HELPER_TYPE_AERIAL];
124
125 // Es sind gar keine Werte eingetragen? Dann gleich rausspringen.
126 if ( !pointerp(helpers) )
127 return ret;
128
129 // Nullelement substrahieren
130 helpers -= ({0});
131
132 if ( sizeof(helpers) ) {
133 // Mapping erstellen: Keys sind die Objekte, deren Closures eingetragen
134 // sind. Values sind die Rueckgabewerte der Closures,
135 // die dabei das Spielerobjekt und das abfragende Objekt uebergeben
136 // bekommen.
137 object *keys = map(helpers,#'get_type_info, 2);
138 int *vals = map(helpers, #'funcall, this_object(), previous_object(1));
139 ret = mkmapping(keys,vals);
140 }
141 return ret;
142}
143
144// Querymethode fuer P_HELPER_OBJECTS
145public mapping _query_lib_p_helper_objects() {
146 return deep_copy(Query(P_HELPER_OBJECTS,F_VALUE));
147}
148
Zesstra1a4cb172018-03-09 21:43:26 +0100149public varargs object GetHelperObject(int type, int|closure strength,
150 varargs mixed* extra)
heull0013d7ea4a2018-02-27 18:33:35 +0100151{
152 object ob;
Zesstra1a4cb172018-03-09 21:43:26 +0100153 // Wenn kein Wert uebergeben wird ist strength 0, in dem Fall duerfte aber
154 // mehrheitlich 1 gemeint sein. Daher auf 1 setzen, wenn 0 uebergeben wurde.
155 strength ||= 1;
156
157 if (intp(strength))
heull0013d7ea4a2018-02-27 18:33:35 +0100158 {
Zesstra1a4cb172018-03-09 21:43:26 +0100159 foreach(closure cl : Query(P_HELPER_OBJECTS)[type]-({0}))
heull0013d7ea4a2018-02-27 18:33:35 +0100160 {
Zesstra1a4cb172018-03-09 21:43:26 +0100161 if(funcall(cl, this_object(), previous_object()) >= strength)
162 {
163 return get_type_info(cl,2);
164 }
heull0013d7ea4a2018-02-27 18:33:35 +0100165 }
166 }
Zesstra1a4cb172018-03-09 21:43:26 +0100167 else
168 {
169 foreach(closure cl : Query(P_HELPER_OBJECTS)[type]-({0}))
170 {
171 ob=get_type_info(cl,2);
172 if(apply(strength, ob, funcall(cl, this_object(), previous_object()),
173 extra) )
174 {
175 return ob;
176 }
177 }
178 }
179
180 return 0;
heull0013d7ea4a2018-02-27 18:33:35 +0100181}