blob: a249b6c7f53592fe8d8feaa0fb3242e0f6b262cf [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
Bugfix98ea85e2021-01-23 14:30:33 +010017protected void create()
18{
19 Set(P_HELPER_OBJECTS,([
20 HELPER_TYPE_AQUATIC:({}),
21 HELPER_TYPE_AERIAL:({})]), F_VALUE);
22}
23
MG Mud User88f12472016-06-24 23:31:02 +020024public int RegisterHelperObject(object helper, int type,
25 string|closure callback)
26{
27 // cb: closure auf die Callback-Funktion in previous_object()
28 closure cb;
29 // helpers: Mapping aller eingetragenen Helfer-Objekte
30 mapping helpers;
31
32 // Kein positiver Integerwert als Helfertyp uebergeben?
33 if ( !intp(type) || type < 1 )
34 raise_error(sprintf( "Wrong argument 1 to RegisterHelperObject(). "
35 "Expected positive <int>, got %O.\n", type));
36 // Kein Objekt vorhanden, an dem die Callback-Funktion gerufen werden soll?
37 if ( !objectp(helper) )
38 return HELPER_NO_CALLBACK_OBJECT;
39
40 // Funktionsname zum Zweck des Callbacks uebergeben?
41 if ( stringp(callback) ) {
42 // Dann Closure davon erstellen.
43 cb = symbol_function(callback, helper);
44 // Wenn das nicht klappt (zB weil die Funktion private ist), dann
45 // Fehler werfen und abbrechen.
46 if ( !closurep(cb) )
47 raise_error(sprintf("Error in RegisterHelperObject(): Unable to call "
48 "function %s in object %O.\n", callback, helper));
49 }
50 // Wenn schon eine Closure uebergeben wurde, dann diese direkt speichern.
51 else if ( closurep(callback) ) {
52 cb = callback;
53 }
54 // Weder Funktionsname, noch Closure, dann Fehler werfen und abbrechen.
55 else
56 raise_error(sprintf("Wrong argument 2 to RegisterHelperObject(). "
57 "Expected <string/closure>, got %O.\n",callback));
58
59 // Property auslesen und zwischenspeichern
60 helpers = QueryProp(P_HELPER_OBJECTS);
MG Mud User88f12472016-06-24 23:31:02 +020061
62 // Closure eintragen, wenn noch nicht vorhanden
63 if ( member(helpers[type], cb)==-1 ) {
64 helpers[type] = helpers[type]+({cb});
65 SetProp(P_HELPER_OBJECTS, helpers);
66 return HELPER_SUCCESS;
67 }
68 else
69 return HELPER_ALREADY_LISTED;
70}
71
72public int UnregisterHelperObject(object helper, int type) {
73 if ( !intp(type) || type < 1 )
74 raise_error(sprintf( "Wrong argument 2 to UnregisterHelperObject(). "
75 "Expected positive <int>, got %O.\n", type));
76 if ( !objectp(helper) )
77 return HELPER_NO_CALLBACK_OBJECT;
78
79 mapping helpers = Query(P_HELPER_OBJECTS, F_VALUE);
80
Bugfix98ea85e2021-01-23 14:30:33 +010081 foreach(closure cl: helpers[type]) {
82 if ( get_type_info(cl,2) == helper ) {
83 helpers[type] = helpers[type]-({cl});
84 return HELPER_SUCCESS;
MG Mud User88f12472016-06-24 23:31:02 +020085 }
86 }
87 return HELPER_NOTHING_TO_UNREGISTER;
88}
89
90// Querymethode fuer P_AQUATIC_HELPERS
91public mapping _query_lib_p_aquatic_helpers() {
92 mapping ret = ([]);
93 // eingetragene Callback-Closures auslesen
Bugfix98ea85e2021-01-23 14:30:33 +010094 closure *helpers = Query(P_HELPER_OBJECTS, F_VALUE)[HELPER_TYPE_AQUATIC];
MG Mud User88f12472016-06-24 23:31:02 +020095
96 // Nullelement substrahieren
97 helpers -= ({0});
98
99 if ( sizeof(helpers) ) {
100 // Mapping erstellen: Keys sind die Objekte, deren Closures eingetragen
101 // sind. Values sind die Rueckgabewerte der Closures,
102 // die dabei das Spielerobjekt und das abfragende Objekt uebergeben
103 // bekommen.
104 object *keys = map(helpers, #'get_type_info, 2);
105 int *vals = map(helpers, #'funcall, this_object(), previous_object(1));
106 ret = mkmapping(keys,vals);
107 }
108 return ret;
109}
110
111// Querymethode fuer P_AERIAL_HELPERS
112public mapping _query_lib_p_aerial_helpers() {
113 mapping ret = ([]);
114 // eingetragene Callback-Closures auslesen
Bugfix98ea85e2021-01-23 14:30:33 +0100115 closure *helpers = Query(P_HELPER_OBJECTS, F_VALUE)[HELPER_TYPE_AERIAL];
MG Mud User88f12472016-06-24 23:31:02 +0200116
MG Mud User88f12472016-06-24 23:31:02 +0200117 // Nullelement substrahieren
118 helpers -= ({0});
119
120 if ( sizeof(helpers) ) {
121 // Mapping erstellen: Keys sind die Objekte, deren Closures eingetragen
122 // sind. Values sind die Rueckgabewerte der Closures,
123 // die dabei das Spielerobjekt und das abfragende Objekt uebergeben
124 // bekommen.
125 object *keys = map(helpers,#'get_type_info, 2);
126 int *vals = map(helpers, #'funcall, this_object(), previous_object(1));
127 ret = mkmapping(keys,vals);
128 }
129 return ret;
130}
131
132// Querymethode fuer P_HELPER_OBJECTS
133public mapping _query_lib_p_helper_objects() {
134 return deep_copy(Query(P_HELPER_OBJECTS,F_VALUE));
135}
136
Zesstra1a4cb172018-03-09 21:43:26 +0100137public varargs object GetHelperObject(int type, int|closure strength,
138 varargs mixed* extra)
heull0013d7ea4a2018-02-27 18:33:35 +0100139{
140 object ob;
Zesstra1a4cb172018-03-09 21:43:26 +0100141 // Wenn kein Wert uebergeben wird ist strength 0, in dem Fall duerfte aber
142 // mehrheitlich 1 gemeint sein. Daher auf 1 setzen, wenn 0 uebergeben wurde.
143 strength ||= 1;
144
145 if (intp(strength))
heull0013d7ea4a2018-02-27 18:33:35 +0100146 {
Zesstra1a4cb172018-03-09 21:43:26 +0100147 foreach(closure cl : Query(P_HELPER_OBJECTS)[type]-({0}))
heull0013d7ea4a2018-02-27 18:33:35 +0100148 {
Zesstra1a4cb172018-03-09 21:43:26 +0100149 if(funcall(cl, this_object(), previous_object()) >= strength)
150 {
151 return get_type_info(cl,2);
152 }
heull0013d7ea4a2018-02-27 18:33:35 +0100153 }
154 }
Zesstra1a4cb172018-03-09 21:43:26 +0100155 else
156 {
157 foreach(closure cl : Query(P_HELPER_OBJECTS)[type]-({0}))
158 {
159 ob=get_type_info(cl,2);
160 if(apply(strength, ob, funcall(cl, this_object(), previous_object()),
161 extra) )
162 {
163 return ob;
164 }
165 }
166 }
167
168 return 0;
heull0013d7ea4a2018-02-27 18:33:35 +0100169}