blob: 812ea6f3f0f58f77dfd17833d427b888cf7da0f8 [file] [log] [blame]
MG Mud User88f12472016-06-24 23:31:02 +02001// MorgenGrauen MUDlib
2//
3// living/comm.c -- communiction module for livings
4//
5// $Id$
6
7#pragma strong_types,save_types
8#pragma no_clone
MG Mud User88f12472016-06-24 23:31:02 +02009#pragma range_check
10
11#include <defines.h>
Bugfixb1d9b4d2021-09-14 20:07:04 +020012#include <thing/language.h>
13#define NEED_PROTOTYPES
MG Mud User88f12472016-06-24 23:31:02 +020014#include <living/comm.h>
Bugfixb1d9b4d2021-09-14 20:07:04 +020015#undef NEED_PROTOTYPES
MG Mud User88f12472016-06-24 23:31:02 +020016
17void create_super()
18{
19 set_next_reset(-1);
20}
21
22protected string comm_guess_action() {
23 string cmd;
24 string action = query_verb();
25 // Die Aktionen sind intern in der Regel nach den haeufigsten Kommandoverben
26 // dieser Aktion benannt. Bei einigen Aktionen sind mehrere Kommandoverben
27 // ueblich, die sollen hier noch abgehandelt werden.
28 switch(action) {
29 case "nehme":
30 // MA_TAKE == nimm
31 action = MA_TAKE;
32 break;
33
Bugfix1450fbd2022-10-05 23:03:44 +020034 case "gebe":
35 // MA_GIVE == "gib"
36 action = MA_GIVE;
37 break;
38
MG Mud User88f12472016-06-24 23:31:02 +020039 case "norden":
40 case "nordosten":
41 case "osten":
42 case "suedosten":
43 case "sueden":
44 case "suedwesten":
45 case "westen":
46 case "nordwesten":
47 case "oben":
48 case "unten":
49 case "betrete":
50 case "verlasse":
51 case "teleport":
52 case "teleportiere":
53 action = MA_MOVE;
54 break;
55
56 case "unt":
57 action = MA_LOOK;
58 break;
59
60 case "wirf":
61 if (strstr(query_command(), " weg") > -1)
62 action = MA_PUT;
63 break;
64
65 case "stecke":
66 cmd = query_command();
67 if (strstr(cmd, " weg") > -1)
68 action = MA_UNWIELD;
69 else if (strstr(cmd," in ") > -1)
70 action = MA_PUT;
71 break;
72
73 case "ziehe":
74 cmd = query_command();
75 if (strstr(cmd, " an") > -1)
76 action = MA_WEAR;
77 else if (strstr(cmd, " aus") > -1)
78 action = MA_UNWEAR;
79 break;
80
81 case "esse":
82 case "friss":
83 action = MA_EAT;
84 break;
85
86 case "saufe":
87 action = MA_DRINK;
88 break;
89
90 case "hoere":
91 //MA_LISTEN == lausche
92 action = MA_LISTEN;
93 break;
94 case "lese":
95 action = MA_READ;
96 break;
97
98 case ":":
99 case ";":
100 action = MA_EMOTE;
101 break;
102
103 case "zerbreche":
104 case "zerstoere":
105 case "verbrenne":
106 case "entsorge":
107 action = MA_REMOVE;
108 break;
109 }
110 return action;
111}
112
113protected int comm_guess_message_type(string action, mixed origin) {
114 // everything not mentioned in the switch becomes MT_LOOK.
115 switch(action) {
116 case MA_FIGHT:
117 // Kampf kann man meisten sowohl sehen als auch hoeren.
118 return MT_LOOK | MT_LISTEN;
119 case MA_LISTEN:
120 case MA_SAY:
121 return MT_LISTEN;
122 case MA_FEEL:
123 return MT_FEEL;
124 case MA_SMELL:
125 return MT_SMELL;
126 case MA_CHANNEL:
127 return MT_COMM | MT_FAR;
128 case MA_EMOTE:
129 if (objectp(origin)
130 && environment(origin) == environment())
131 return MT_COMM;
132 else
133 return MT_COMM | MT_FAR;
134 case MA_SHOUT:
135 return MT_LISTEN | MT_FAR;
136 }
137 // die meisten Aktionen sind zumindest sichtbar...
138 return MT_LOOK;
139}
140
Zesstra71ae7422023-12-30 20:13:12 +0100141// ReceiveMsg() wird in <player/comm.c> und <npc/comm.c> implementiert und ist
142// hier nicht erforderlich (Cross-Defintion von LPC sei Dank).
143//public varargs int ReceiveMsg(string msg, int msg_type, string msg_action,
144// string msg_prefix, object origin)
145//{}
146
147
Bugfixb1d9b4d2021-09-14 20:07:04 +0200148// Wrapper fuer ReceiveMsg()
Bugfixb1d9b4d2021-09-14 20:07:04 +0200149
Zesstra71ae7422023-12-30 20:13:12 +0100150// Bekommt ein wave_s oder davon geerbte Struct uebergeben, welche daher
151// mindestens Nachricht, Typ und Prefix enthaelt. Ist ansonsten
152// funktionsgleich zu ReceiveMsg().
153public int ReceiveWave(struct wave_s wave, string msg_action, object origin)
154{
155 if (!wave) return MSG_FAILED;
156 return ReceiveMsg(wave.msg, wave.type, msg_action, wave.prefix,
157 origin);
158}
159
160// Bekommt ein wave_s oder davon geerbte Struct uebergeben, welche daher
161// mindestens Nachricht, Typ und Prefix enthaelt. Wird ein wave_dyn_s
162// uebergeben und ist das <cl>-Element eine Closure, wird diese ausgewertet
163// und kann Nachricht, Typ und Prefix veraendern. Ansonsten ist diese Funktion
164// funktionsgleich zu ReceiveWave().
165public int ReceiveDynWave(struct wave_s wave, string msg_action, object origin)
166{
167 if (!wave) return MSG_FAILED;
168 // Falls ein wave_dyn_s uebergeben wurde, ist ein Element cl enthalten und
169 // -> gibt das zurueck. ( . funktioniert nicht, weil der Compiler von einem
170 // wave_s ausgeht.
171 if (closurep(wave->cl))
172 wave = funcall(wave->cl, wave);
173 return ReceiveMsg(wave.msg, wave.type, msg_action, wave.prefix,
174 origin);
175}
176
Bugfixb1d9b4d2021-09-14 20:07:04 +0200177public int ReceiveNotify(string msg, string action)
178{
179 // Da MT_NOTIFICATION immer zugestellt wird, ist keine Fehlerbehandlung
180 // notwendig.
181 return ReceiveMsg(
182 msg,
183 // MSG_DONT_IGNORE waere wegen MT_NOTIFICATION inhaltlich nicht noetig,
184 // spart aber ein paar Ticks.
185 MT_NOTIFICATION | MSG_BS_LEAVE_LFS | MSG_DONT_IGNORE,
186 action);
187}
188
189public int ReceiveTeilemit(string msg)
190{
191 // Blockierte Sinne sind hier kein Problem, ergo keine Fehlerbehandlung.
192 return ReceiveMsg(
193 replace_personal(msg, ({previous_object(), this_player()}) - ({0}), 1),
194 MT_COMM | MT_FAR | MSG_BS_LEAVE_LFS | MSG_DONT_STORE,
195 MA_TELL,
196 previous_object().Name(WER, 1) + "teilt Dir mit: ");
197}
198
Zesstra77b32572022-09-21 23:27:23 +0200199public int ReceiveMultiSense(struct wave_s *msgs,
Zesstra24c1f902023-12-30 20:09:12 +0100200 string action = comm_guess_action(), int commontypes = 0)
Bugfixb1d9b4d2021-09-14 20:07:04 +0200201{
Zesstra77b32572022-09-21 23:27:23 +0200202 int res;
203 foreach(struct wave_s wave : msgs)
Bugfixb1d9b4d2021-09-14 20:07:04 +0200204 {
Zesstra77b32572022-09-21 23:27:23 +0200205 // Pruefung auf != MSG_SENSE_BLOCK statt Erfolg, weil ein anderer Fehler
206 // (insb. aufgrund ignoriere) fuer alle Alternativen ebenso auftritt.
207 res = ReceiveMsg(
208 replace_personal(wave.msg, ({previous_object(), this_player()}),1),
209 wave.type | MSG_BS_LEAVE_LFS | commontypes, action, wave.prefix);
210 if (res != MSG_SENSE_BLOCK)
Bugfixb1d9b4d2021-09-14 20:07:04 +0200211 {
Bugfixb1d9b4d2021-09-14 20:07:04 +0200212 break;
213 }
214 }
215 return res;
216}
Zesstra77b32572022-09-21 23:27:23 +0200217
218public int ReceiveSay(string msg,
219 string prefix = previous_object().Name(WER, 1) + " sagt: ",
220 struct wave_s *alt =
221 ({(<wave_s>
222 msg: "@WER1 bewegt die Lippen, Du hoerst jedoch nichts.",
223 type: MT_LOOK)})
224 )
225{
226 // Nachricht in struct konvertieren, ans Anfang vom Array stellen
227 alt = ({(<wave_s> msg: msg, prefix: prefix, type: MT_LISTEN)}) + alt;
228 // Rest macht ReceiveMultiSense()
229 return ReceiveMultiSense(alt, MA_SAY, MSG_BS_LEAVE_LFS);
230}
231