blob: 43735fedf59108abbd1476f08b890e9dddb28bfc [file] [log] [blame]
MG Mud User88f12472016-06-24 23:31:02 +02001/*OBJ*/
2/* 2013-Mai-23, Arathorn
3 Umfassend ueberarbeitet; setup(), init() und ReplaceWasser() entsorgt,
4 P_WEIGHT und P_LONG dynamisch gebaut, so dass das staendige Umsetzen
5 der Properties mittels setup() nach jedem Fuellen/Leeren entfaellt.
6 */
7
8/* Letzte Aenderung: 4.5.2004, Arathorn.
9 Zeile 149: cont_obj->remove() eingefuegt, damit das geclonte Objekt
10 nach dem Abfragen seines Namens wieder entfernt wird.
11 Update 6.6.2004, Arathorn. Habe um ein destruct() ergaenzt, weil das
12 trotz remove() hartnaeckig weitergebuggt hat. *fluch*
13 */
14
15/* Version 1.3 by Fraggle (17.1.1995) */
16
17 // PreventInsert: verhindert Fuellen wie std/container
18/* Version 1.2 by Fraggle (17.1.1995) */
19
20 // Flasche kann nun mittels environment(TP)->GetLiquid()
21 // etwas anderes als Wasser enthalten, sofern
22 // environment(TP)->QueryProp(P_WATER)==W_OTHER
23 // BUG: auch 1l Methan wiegt 1 Kg, aendere ich spaeter
24
25/* Version 1.1 by Fraggle (17.1.1995) */
26#pragma strong_types,rtt_checks
27#pragma no_clone
28
29inherit "/std/thing";
30#include <language.h>
31#include <properties.h>
32#include <items/flasche.h>
33#include <items/fishing/fishing.h>
34
35#define DEFAULT_LIQ "Wasser"
36#define TP this_player()
37
38private string co_filename;
39public string liquid_name=DEFAULT_LIQ;
40
41string dynamic_long();
42
43protected void create() {
44 ::create();
45
46 AddId(({"wasserbehaelter","behaelter","\nwater_source"}));
47 SetProp(P_NAME, "Wasserbehaelter");
48 SetProp(P_GENDER , MALE);
49 SetProp(P_ARTICLE, 1);
50 SetProp(P_SHORT, "Ein Standard-Wasserbehaelter");
51 SetProp(P_LONG,"none");
52 Set(P_LONG, #'dynamic_long, F_QUERY_METHOD);
53 SetProp(P_LONG_EMPTY,""); // Beschreibung fuer leeren Zustand
54 SetProp(P_LONG_FULL,""); // Beschreibung fuer gefuellten Zusand
55 SetProp(P_LIQUID,1000); // Fuellmenge = 1 Liter
56 SetProp(P_WATER,0); // Flasche ist defaultmaessig leer!
57 SetProp(P_VALUE,10);
58
59 // P_WEIGHT auf Leergewicht der Flasche setzen, QueryMethode liefert
60 // die Summe aus Leergewicht+Fuellung zurueck (Dichte = 1).
61 SetProp(P_WEIGHT,20);
62 Set(P_WEIGHT, function int () {
63 return ( Query(P_WEIGHT,F_VALUE)+
64 (QueryProp(P_WATER)?QueryProp(P_LIQUID):0) );
65 }, F_QUERY_METHOD);
66
67 AddCmd(({"fuell","fuelle"}),"cmd_fuelle");
68 AddCmd(({"leere", "entleere"}),"cmd_leere");
69}
70
71protected void create_super() {
72 set_next_reset(-1);
73}
74
75// Behaelter ist gefuellt, dann ist die Langbeschreibung entweder die
76// P_LONG_FULL, falls angegben, oder die P_LONG + Beschreibung der Fuellung.
77// Genauso, wenn sie leer ist.
78string dynamic_long() {
79 string l=Query(P_LONG,F_VALUE);
80 if ( QueryProp(P_WATER) ) {
81 string lf = QueryProp(P_LONG_FULL);
82 if ( stringp(lf) && sizeof(lf) )
83 l=lf;
84 else
85 l+=capitalize(QueryPronoun(WER))+" enthaelt "+liquid_name+".\n";
86 // Falls die Flasche mit etwas anderem als Wasser gefuellt wird, die
87 // Langbeschreibung fuer "volle Flasche" (P_LONG_FULL) aber nur fuer
88 // Wasser ausgelegt ist, wird "Wasser" durch den Inhalt von liquid_name
89 // ersetzt.
90 if ( liquid_name != DEFAULT_LIQ )
91 l=regreplace(l, DEFAULT_LIQ, liquid_name, 1);
92 } else {
93 string le = QueryProp(P_LONG_EMPTY);
94 if ( stringp(le) && sizeof(le) )
95 l=le;
96 else
97 l+=capitalize(QueryPronoun(WER))+" ist leer.\n";
98 }
99 return l;
100}
101
102// Zum Ueberschreiben! PreventInsert(object ob){return 0;} z.B.
103// macht die Flasche gasdicht.
104// Oder man kann die Flasche verschliessbar machen.
105int PreventInsert(object obj)
106{
107 if(obj->id("gas")) { //default: NICHT Gasdicht!
108 write(obj->Name(WER,1)+" entweicht sofort wieder!\n");
109 return 1;
110 }
111 return 0;
112}
113
114// Transferiert den Inhalt der Flasche an <dest>
115protected int transfer_to(object dest)
116{
117 int water=QueryProp(P_WATER);
118 if (!water)
119 {
120 write(Name(WER,1) + " ist schon leer!\n");
121 return 0; // War schon leer!
122 }
123 int contents=QueryProp(P_LIQUID);
124
125 if ( water&W_OTHER )
126 {
127 dest->PutLiquid(co_filename);
128 }
129 else
130 {
131 dest->AddWater(contents);
132 }
133 SetProp(P_WATER,0);
134 RemoveId(lower_case(liquid_name));
135 liquid_name=DEFAULT_LIQ;
136 return contents; //gib die ml an Umgebung ab :)
137}
138
139// Entleert die Flasche ins Environment der Flasche, allerdings nicht, wenn
140// dies ein Lebewesen ist, dann wird das Environment von dem genommen.
141// TODO: Eine Flasche in einem Paket leeren wurde dann in das paket entleeren.
142// Das waere an sich sogar richtig... Nur: gewollt? Alternative koennen wir
143// auch das aeusserste Environment nehmen, was nicht lebt.
144public int empty()
145{
146 if (environment())
147 {
148 // Environment des Benutzers finden.
149 object env = environment();
150 while (living(env))
151 env=environment(env);
152 return transfer_to(env);
153 }
154 return 0;
155}
156
157// Fuellt die Flasche aus <src>
158protected int fill_bottle(object src)
159{
160 int liquidtype = src->QueryProp(P_WATER);
161 if(liquidtype)
162 {
163 if(QueryProp(P_WATER)) {
164 write(Name(WER,1)+" ist bereits voll!\n");
165 return 1;
166 }
167 // Wasser von Umgebung abziehen!
168 // Man kann als Magier die Funktion AddWater(int n) dazu benuetzten,
169 // beispielsweise eine Pfuetze zu leeren, ...
170 src->AddWater(-QueryProp(P_LIQUID));
171 object cont_obj;
172 if(liquidtype&W_OTHER)
173 {
174 // Mittels GetLiquid() kann die Flasche mit was anderem als Wasser
175 // gefuellt werden.
176 co_filename=src->GetLiquid();
177 if (co_filename)
178 {
179 cont_obj=clone_object(co_filename);
180 if(PreventInsert(cont_obj))
181 {
182 // Hier passiert eigentlich das gleiche wie nach dem ifblock, aber
183 // auch noch Funktion beenden.
184 // TODO: Rueckgaenig machen von AddWater()?
185 // TODO: Die Meldung aus dem PreventInsert() muesste eigentlich
186 // _vorher_ noch mit einer Befuellmeldung begleitet werden.
187 cont_obj->remove(1);
188 if ( objectp(cont_obj) )
189 cont_obj->move("/room/muellraum",M_PUT);
190 cont_obj=0;
191 return 0;
192 }
193 else
194 liquid_name=cont_obj->name(WEN);
195 // In jedem Fall wird das Objekt wieder zerstoert - es wurde nur fuer
196 // das Ermitteln des liquid_name benutzt... Weia.
197 if ( cont_obj ) cont_obj->remove();
198 if ( cont_obj ) cont_obj->move("/room/muellraum",M_PUT);
199 }
200 }
201 SetProp(P_WATER,liquidtype);
202 AddId(lower_case(liquid_name));
203 //wie praktisch, 1 ml == 1 g :) // Aber nur fuer Wasser, du VOGEL! :-|
204 return 1;
205 }
206 else {
207 write("Du findest hier nichts, was Du in "+name(WEN,1)+
208 " fuellen koenntest!\n");
209 return 0;
210 }
211 return 0;
212}
213
214static int cmd_leere(string str)
215{
216 object dest;
217 notify_fail("Was willst Du denn (wo hinein) leeren?\n");
218 if (!str)
219 return 0;
220
221 string strbottle,strobj;
222 // leere flasche
223 if (id(str))
224 {
225 //NOOP
226 }
227 // leere flasche in xxx
228 else if (sscanf(str,"%s in %s",strbottle,strobj)==2)
229 {
230 if (!id(strbottle))
231 return 0;
232 dest = present(strobj, environment(this_player()))
233 || present(strobj, this_player());
234 if (!dest)
235 return 0;
236 }
237 else
238 return 0;
239 // Syntaxpruefung fertig.
240
241 if(!QueryProp(P_WATER))
242 {
243 write("Da ist kein "+liquid_name+" drin!\n");
244 return 1;
245 }
246
247 if (dest)
248 {
249 write(break_string("Du leerst "+name(WEN,1)+ " in "
250 + dest->name(WEN) + ".",78));
251 say(break_string(TP->name()+" leert "+name(WEN,0)
252 + " in " + dest->name(WEN) + ".",78),TP);
253 transfer_to(dest);
254 return 1;
255 }
256 write(break_string("Du leerst "+name(WEN,1)+".",78));
257 say(break_string(TP->name()+" leert "+name(WEN,0)+".",78),TP);
258 empty();
259 return 1;
260}
261
262public int cmd_fuelle(string str)
263{
264 string strbottle,strobj;
265
266 notify_fail("Was willst Du denn (womit) fuellen?\n");
267 if(!str)
268 return 0;
269
270 // fuelle flasche
271 if (id(str))
272 {
273 if (fill_bottle(environment(this_player())))
274 {
275 write(break_string("Du fuellst etwas "+liquid_name+" in "
276 +name(WEN,1)+".",78));
277 say(break_string(TP->Name(WER)+" fuellt etwas "
278 +liquid_name+" in "+name(WEN)+".",78), TP);
279 }
280 return 1;
281 }
282 // fuelle flasche aus xxx
283 // fuelle flasche mit xxx
284 // fuelle xxx in flasche
285 // fuelle flasche in xxx
286 // fuelle xxx aus flasche
287 // fuelle xxx mit flasche
288 else if (sscanf(str,"%s in %s",strobj,strbottle)==2
289 || sscanf(str,"%s mit %s",strbottle,strobj)==2
290 || sscanf(str,"%s aus %s",strbottle,strobj)==2)
291 {
292 object obj;
293 // Flasche befuellen?
294 if (id(strbottle)
295 && ( obj=present(strobj, environment(this_player()))
296 || present(strobj, this_player()) )
297 )
298 {
299 if (fill_bottle(obj))
300 {
301 write(break_string(
302 "Du fuellst etwas "+liquid_name+" aus " + obj->name(WEM,1)
303 + " in "+name(WEN,1)+".",78));
304 say(break_string(TP->Name(WER)+" fuellt etwas "+liquid_name+ " aus "
305 + obj->name(WEM,1) + " in "+name(WEN)+".",78), TP);
306 }
307 return 1;
308 }
309 // anderes Gefaess befuellen?
310 else if (id(strobj)
311 && ( obj=present(strbottle, environment(this_player()))
312 || present(strbottle, this_player()) )
313 )
314 {
315 if (transfer_to(obj))
316 {
317 write(break_string(
318 "Du fuellst etwas "+liquid_name+" aus " + name(WEM,1)
319 + " in "+obj->name(WEN,1)+".",78));
320 say(break_string(TP->Name(WER)+" fuellt etwas "+liquid_name+ " aus "
321 + name(WEM,1) + " in "+obj->name(WEN)+".",78), TP);
322 }
323 return 1;
324 }
325 }
326 // Syntax passt nicht.
327 return 0;
328}
329
330int IsBottle() {
331 return 1;
332}
333