blob: 909eeadb1d406993aafa4faf3368fdf1651719b1 [file] [log] [blame]
MG Mud User88f12472016-06-24 23:31:02 +02001// (c) 2003 by Thomas Winheller (padreic@mg.mud.de)
2// Bei diesem File handelt es sich um einen universellen
3// Kessel zum Brauen von Traenken. Damit er sich in den
4// Raum entsprechend einpassen kann, ist er invis.
5
6// Ein Raum, in dem Traenke und Gift gebraut werden koennen
7// soll, braucht nichts weiter machen als:
8// - eine Moeglichkeit zu implementieren Wasser in den Kessel
9// zu fuellen. Hierzu muss dann mittels AddWater(3000)
10// insgesamt 3l Wasser eingefuellt werden. AddWater gibt die
11// Menge des tatsaechlich noch eingefuelltn Wassers zurueck.
12// Anmerkung: bisher enthaelt /obj/flasche noch keine Moeglichkeit
13// Fluessigkeiten von einem Fluessigkeitencontainer in
14// einen anderen zu schuetten, aber vielleicht aendert
15// das ja irgendwann mal wer - der Kessel kann dann
16// durch alle diese Flaschen befuellt werden!
17#pragma strong_types,rtt_checks
18
19inherit "/std/container";
20
21#include <defines.h>
22#include <properties.h>
23#include <moving.h>
24#include <fishing.h>
25#include <items/kraeuter/kraeuter.h>
26#include <items/flasche.h>
27
28#ifndef BS
29# define BS(x) break_string(x, 78)
30#endif
31
32private int wassermenge;
33
34// Aktueller Nutzer des Kessels in Form der Spieler-UID
35private string current_user;
36
37// Zeitpunkt, wann die Sperre endet.
38private int timeout;
39
40protected void create()
41{
42 ::create();
43 SetProp(P_SHORT, "Ein schwerer Kessel");
44 // \n werden in long() eingefuegt
45 SetProp(P_LONG,
46 "Ein kleiner, aber sehr schwerer Kessel, in dem die verschiedensten "
47 "Traenke gebraut werden koennen.");
48 SetProp(P_NAME, "Kessel");
49 SetProp(P_NAME_ADJ, "klein");
50 SetProp(P_MATERIAL, MAT_BRONCE);
51 SetProp(P_NOGET, "Der Kessel ist zu schwer, um ihn einfach mitnehmen "
52 "zu koennen.\n");
53 SetProp(P_MAX_WEIGHT, 100000); // ein _wirklich_ grosser Kessel ;o)
54 SetProp(P_WEIGHT, 50000);
55 SetProp(P_VALUE, 25000);
56 SetProp(P_MAX_OBJECTS, 9); // max. 8 Kraeuter + Wasser
57 SetProp(P_GENDER, MALE);
58 SetProp(P_LIQUID, 3000); // in den Kessel passen 3l :o)
59 AddId(({"kessel", KESSELID}));
60 AddAdjective(({"klein", "kleiner"}));
61 AddCmd("leer|leere&@ID&aus", "cmd_leeren",
62 "Was moechtest Du leeren?|Moechtest Du den Kessel etwa ausleeren?");
63 AddCmd(({"brau", "braue", "koch", "koche"}), "cmd_brauen");
64 AddCmd("fuell|fuelle&trank|heiltrank|ergebnis|kesselinhalt|inhalt&in&"
65 "@PRESENT", "cmd_fuellen",
66 "Was willst Du fuellen?|Willst Du etwas in etwas fuellen?|"
67 "Worein willst Du den Kesselinhalt fuellen?");
68 AddCmd(({"tauch", "tauche"}), "cmd_tauchen");
69}
70
71#define TRANKFERTIG "_lib_p_krauttrankfertig"
72
73private int check_busy(int useronly)
74{
75 if (useronly)
76 return current_user && current_user != getuid(PL);
77 // Timeout darf noch nicht abgelaufen sein. Wird beim Entleeren geprueft.
78 return current_user && timeout > time() && current_user != getuid(PL);
79}
80
81private void clear_kessel()
82{
83 all_inventory()->remove(1);
84 // gespeicherte Daten nullen
85 wassermenge = current_user = timeout = 0;
86 SetProp(P_WATER, 0);
87 SetProp(TRANKFERTIG, 0);
88}
89
90int AddWater(int menge)
91{
92 // Wenn ein User eingetragen ist, dieser nicht PL ist und die Sperre
93 // auch noch nicht abgelaufen ist, dann wird das Einfuellen von Wasser
94 // verhindert. Nutzer der Funktion muessen die Rueckgabewerte pruefen
95 // und entsprechende Meldungen ausgeben.
96 if (check_busy(1))
97 return -1;
98
99 int old = wassermenge;
100 wassermenge = min(wassermenge+menge, QueryProp(P_LIQUID));
101
102 if (wassermenge<=0)
103 {
104 wassermenge=0; // wasser entnahme
105 SetProp(P_WATER, 0);
106 }
107 else
108 SetProp(P_WATER, W_DEAD);
109 return wassermenge-old;
110}
111
112static int cmd_leeren(string str)
113{
114 if (!QueryProp(P_WATER) && !sizeof(all_inventory()))
115 {
116 write(BS("Im Kessel ist bisher noch nichts enthalten, was Du ausleeren "
117 "koenntest."));
118 }
119 // Es gibt einen aktuellen User, dieser ist nicht PL, und der Timeout
120 // ist auch noch nicht abgelaufen => Finger weg.
121 else if (check_busy(0))
122 {
123 tell_object(PL, BS(
124 "Der Inhalt des Kessels wurde erst kuerzlich von jemand anderem dort "
125 "hineingefuellt. Du solltest Dich nicht daran zu schaffen machen."));
126 }
127 write("Vorsichtig nimmst Du den Kessel und schuettest seinen Inhalt in den Abfluss.\n");
128 say(BS(PL->Name(WER)+" nimmt den Kessel und schuettet den Inhalt in den Abfluss."));
129 clear_kessel();
130 return 1;
131}
132
133/*#include "/d/erzmagier/boing/balance/balance.h"
134#include <wizlevels.h>
135#define TESTER (BTEAM+({"elendil","saray", "huraxprax"}))*/
136static int cmd_brauen(string str)
137{
138 /*if (!IS_ARCH(this_interactive())
139 && !member(TESTER, PL->query_real_name()))
140 return 0;*/
141
142 notify_fail("WAS moechtest Du brauen?\n");
143 if (!str) return 0;
144/* if (str=="zaubertrank") {
145 write("Ohne passendes Rezept duerfte dies schwierig werden...\n");
146 return 1;
147 }*/
148 if (member(({"trank","zaubertrank","kraeutertrank","tee","kraeutertee"}),
149 str)<0)
150 return 0;
151
152 if (check_busy(1)) {
153 tell_object(PL, BS(
154 "An dem Trank in dem Kessel arbeitet gerade noch "+
155 capitalize(current_user)+". Du kannst hoechstens in ein paar "
156 "Minuten versuchen, den Inhalt des Kessels auszuleeren. Selbst "
157 "Hand anzulegen, wuerde man Dir sicherlich uebelnehmen."));
158 }
159 else if (!QueryProp(P_WATER)) {
160 write("Vielleicht solltest Du zunaechst noch Wasser in den Kessel "
161 "fuellen...\n");
162 }
163 else if (wassermenge<QueryProp(P_LIQUID)) {
164 write("Vielleicht solltest Du zunaechst noch etwas mehr Wasser in "
165 "den Kessel\nfuellen...\n");
166 }
167 else if (sizeof(all_inventory())<3) {
168 write("Derzeit ist Dein Trank noch ein wenig waessrig.\n"
169 +"Mindestens drei Zutaten muessen in einen Trank schon hinein.\n");
170 }
171 else {
172 write(BS("Vorsichtig laesst Du den Kessel etwas naeher zur Feuerstelle "
173 "runter und wartest unter gelegentlichem Ruehren, bis er kocht. "
174 "Dein Trank sollte nun fertig sein und Du kannst ihn nun abfuellen. "
175 "Was er wohl fuer eine Wirkung haben wird?"));
176 say(BS(PL->Name()+" laesst den Kessel zur Feuerstelle herunter und "
177 "ruehrt langsam darin herum. Nach einer Weile kocht die Fluessigkeit "
178 "darin, und "+PL->Name(WER)+" stellt das Ruehren wieder ein."));
179 SetProp(TRANKFERTIG, 1);
180 }
181 return 1;
182}
183
184static int cmd_fuellen(string str,mixed* params)
185{
186/* if (!IS_ARCH(this_interactive())
187 && !member(TESTER, this_player()->query_real_name()))
188 return 0;*/
189
190 if ( !QueryProp(TRANKFERTIG) )
191 {
192 write("Im Kessel befindet sich aber gar kein Trank.\n");
193 }
194 // Abfuellen ist nur fuer den Spieler moeglich, der die Kraeuter
195 // reingetan hat.
196 else if (check_busy(1))
197 {
198 tell_object(PL, BS("Diesen Trank hast Du doch gar nicht selbst "
199 "gebraut! Du solltest noch eine Weile warten, ob "+
200 capitalize(current_user)+" ihn nicht doch noch selbst abfuellen "
201 "will. Wenn nicht, koenntest Du nur noch versuchen, den Kessel "
202 "auszuleeren - jedenfalls es erscheint Dir viel zu riskant, das "
203 "Gebraeu selbst zu trinken, das "+capitalize(current_user)+
204 " da zusammengeruehrt hat."));
205 }
206 else if (BLUE_NAME(params[2])==TRANKITEM)
207 {
208 int ret = params[2]->Fill(all_inventory());
209 switch( ret ) {
210 case -3:
211 case -1:
212 write(BS("Fehler beim Fuellen der Phiole. Bitte sag einem Magier "
213 "Bescheid und nenne den Fehlercode "+ret+"."));
214 break;
215 case -2:
216 write(BS("Die Phiole ist bereits gefuellt."));
217 break;
218 default:
219 write(BS("Du nimmst den Kessel und fuellst seinen konzentrierten "
220 "Inhalt in Deine Glasflasche. Hoffentlich ist Dir hier ein "
221 "toller Trank gelungen."));
222 say(BS(PL->Name(WER)+" nimmt den Kessel und fuellt dessen "
223 "konzentrierten Inhalt in eine kleine Glasflasche. Was "+
224 PL->QueryPronoun(WER)+" da wohl gebraut hat?"));
225 clear_kessel();
226 break;
227 }
228 }
229 else {
230 write("Darein kannst Du den Trank leider nicht fuellen.\n");
231 }
232 return 1;
233}
234
235varargs string long(int mode)
236{
237 string inv_desc = make_invlist(PL, all_inventory(ME));
238 if (inv_desc=="") {
239 if (QueryProp(P_WATER))
240 return BS(Query(P_LONG)+" Derzeit ist er lediglich mit Wasser "
241 "gefuellt.");
242 return BS(Query(P_LONG)+" Er ist im Moment leer.");
243 }
244 if (QueryProp(P_WATER))
245 return BS(Query(P_LONG)+" Er ist mit Wasser gefuellt, und Du siehst "
246 +"folgende Kraeuter in ihm schwimmen:")+inv_desc;
247 return BS(Query(P_LONG))+"Er enthaelt:\n"+inv_desc;
248}
249
250static int _query_invis()
251{
252 if (member(({"nimm", "nehm", "nehme", "leg", "lege",
253 "steck", "stecke"}), query_verb())!=-1) return 0;
254 return Query(P_INVIS, F_VALUE);
255}
256/*
257varargs string name(int casus, int demon)
258{
259 SetProp(P_INVIS, 0);
260 string ret=::name(casus, demon);
261 SetProp(P_INVIS, 1);
262 return ret;
263}
264*/
265varargs int PreventInsert(object ob)
266{
267 int plantid = ob->QueryPlantId();
268 int *inv = all_inventory(ME)->QueryPlantId();
269
270 // es koennen natuerlich nur echte Kraeuter in den Kessel gelegt werden
271 if ( plantid<=0 || !IS_PLANT(ob) )
272 return 1;
273
274 if (QueryProp(TRANKFERTIG))
275 {
276 tell_object(PL, break_string(
277 "Im Kessel ist ein fertiger Trank. Wenn Du etwas neues machen "
278 "willst, leere den Kessel oder fuelle den Trank ab."));
279 return 1;
280 }
281 // Reintun darf nur der aktuelle User, es sei denn, ein anderer Spieler
282 // faengt frisch an, wenn der Kessel gerade unbenutzt ist.
283 else if ( check_busy(1) )
284 {
285 tell_object(PL, BS("Dieser Kessel wurde bis gerade eben noch von "+
286 capitalize(current_user)+" genutzt. Warte besser, bis der Kessel "
287 "wieder frei ist."));
288 return 1;
289 }
290 else if ( !SECURE("krautmaster")->CanUseIngredient(PL, plantid) )
291 {
292 // mit Kraeutern ueber die man nichts weiss, kann man nicht brauen
293 tell_object(PL, BS("Ueber die Wirkungsweise von "+ob->name(WEM)+
294 " weisst Du bisher leider wirklich ueberhaupt nichts."));
295 return 1;
296 }
297 else if ( sizeof(inv) >= 8 )
298 {
299 tell_object(PL, BS("Mehr als acht Zutaten sollte man nie zu einem "
300 "Trank vereinigen, und es sind schon acht im Kessel."));
301 return 1;
302 }
303 else if (member(inv, plantid)>-1)
304 {
305 tell_object(PL, BS("Im Kessel befindet sich bereits "+ob->name(WER)+
306 ". Du kannst kein Kraut mehr als einmal verwenden."));
307 return 1;
308 }
309 current_user = getuid(PL);
310 timeout = time()+120;
311 return ::PreventInsert(ob);
312}
313
314int PreventLeave(object ob, mixed dest)
315{
316 if (QueryProp(P_WATER)) {
317 tell_object(PL, BS("Es befindet sich bereits Wasser im Kessel, die "
318 "einzelnen Zutaten kannst Du nun leider nicht mehr einzeln "
319 "rausholen, ohne den ganzen Kessel auszuleeren."));
320 return 1;
321 }
322 // Rausnehmen ist nur fuer den aktuellen User moeglich. Alle anderen
323 // koennen auch nach Ablauf der Zeitsperre nur ausleeren.
324 else if ( check_busy(1) ) {
325 tell_object(PL, BS("Du hast "+ob->name(WEN,1)+" nicht dort hineingetan, "
326 "also kannst Du "+ob->QueryPronoun(WEN)+" auch nicht herausnehmen. "
327 "Zumindest vorerst nicht. Sollte "+capitalize(current_user)+
328 "nicht innerhalb der naechsten paar Minuten weiterbrauen, kannst "
329 "Du den Kesselinhalt zumindest mit einem guten Schluck Wasser "
330 "rausspuelen."));
331 return 1;
332 }
333 return ::PreventLeave(ob, dest);
334}
335