blob: e4b22458b3645397ba4307ce5eb4014334c81fcc [file] [log] [blame]
MG Mud User88f12472016-06-24 23:31:02 +02001// MorgenGrauen MUDlib
2//
3// lightsource.c -- standard light source
4//
5// $Id: lightsource.c 7806 2011-07-11 20:28:17Z Zesstra $
6
7// std/lightsource.c
8//
9// Original von Miril April '92
10// Neufassung von Sir Dezember '92 ( unter Boings Aegide :)
11// Version : 1.0
12//
13// Bugfixes von Sir Juni '93
14// Version : 1.2
15//
16// Wichtige Funktionen, die man in create() aufrufen sollte :
17//
18// Setzen der Brennstoffmenge :
19// SetProp( P_FUEL, int ) int gibt die Brennzeit in Sekunden an
20//
21// Setzen der Beschreibung wenn Objekt angezuendet( default : "brennend" ) :
22// SetProp( P_LIGHTDESC, string )
23//
24// Legt fest, ob ein Leuchtobjekt nach seinem Abbrennen destructed wird
25// SetProp( P_DO_DESTRUCT, int )
26//
27// Legt fest, wie hell die Fackel leuchtet.
28// SetProp( P_LIGHT, int )
29//
30// Ansonsten sind die Standardfuktionen wie z.B. SetProp( P_GENDER, MALE )
31// aufzurufen
32
33#pragma strict_types
34#pragma save_types
35#pragma no_clone
36#pragma pedantic
37#pragma range_check
38
39inherit "std/thing" ;
40
41#include <properties.h>
42#include <language.h>
43#include <defines.h>
44
45#define TRUE 1
46#define FALSE 0
47#define bool int
48
49#define DFLT_FUEL 20 // 20 Sekunden
50#define DFLT_LIGHTDESC "brennend"
51#define DFLT_LIGHT 2
52
53// So ergibt sich die Moeglichkeit sie wieder auzufuellen
54#define CALL_OUT_TIME 100
55
56#undef DEBUG
57
58// TODO: Private waer langfristig nett...
59nosave int fuel, max_fuel;
60nosave bool lighted ;
61nosave int call_time ;
62
63void create()
64{
65 thing::create() ;
66
67 SetProp( P_NAME, "Lichtquelle" ) ;
68 SetProp( P_SHORT, "Eine Lichtquelle" ) ;
69 SetProp( P_LONG, "Du siehst nichts besonderes.\n" ) ;
70 SetProp( P_GENDER, FEMALE ) ;
71 SetProp( P_FUEL, DFLT_FUEL ) ;
72 SetProp( P_LIGHTDESC, DFLT_LIGHTDESC ) ;
73 SetProp( P_LIGHT, DFLT_LIGHT );
74 SetProp( P_DO_DESTRUCT, TRUE ) ;
75 SetProp( P_VALUE, 5 ) ;
76
77 AddId( ({ "lichtquelle", "\nlichtquelle" }) ) ;
78 AddCmd( ({ "zuende", "zuend" }), "light" );
79 AddCmd( ({ "loesche", "loesch" }), "extinguish" );
80}
81
82void test_remove()
83{ if (QueryProp(P_DO_DESTRUCT)) remove(); }
84
85/*
86 * Lichtquelle anzuenden
87 */
88bool light(string str)
89{
90 string tmp ;
91 object env;
92
93 _notify_fail( "Zuende was an?\n" ) ;
94
95 if( (!str) || (!sscanf( str, "%s an", tmp )) || (!id( tmp )) )
96 return FALSE ;
97
98 if( environment() != PL ) // Player hat es nicht
99 {
100 _notify_fail( "Erstmal musst Du " + name( WEN, 0 ) + " haben.\n" ) ;
101 return FALSE ;
102 }
103
104 if( lighted )
105 {
106 _notify_fail( CAP( name( WER, 1 ) ) + " brennt schon.\n" ) ;
107 return FALSE ;
108 }
109
110 if( fuel <= 0 )
111 {
112 _notify_fail( CAP( name( WER, 1 ) ) + " ist abgebrannt.\n" ) ;
113 test_remove() ;
114 return FALSE ;
115 }
116
117 lighted = TRUE ;
118 env=this_object();
119 while (objectp(env=environment(env)))
120 // Ja. Man ruft die _set_xxx()-Funktionen eigentlich nicht direkt auf.
121 // Aber das Lichtsystem ist schon *so* rechenintensiv und gerade der
122 // P_LAST_CONTENT_CHANGE-Cache wird *so* oft benoetigt, dass es mir
123 // da um jedes bisschen Rechenzeit geht.
124 // Der Zweck heiligt ja bekanntlich die Mittel. ;-)
125 //
126 // Tiamak
127 env->_set_last_content_change();
128 call_time = (fuel < CALL_OUT_TIME)? fuel : CALL_OUT_TIME ;
129 call_out( "out_of_fuel", call_time ) ;
130 if( (int)PL->QueryProp(P_PLAYER_LIGHT) == 1 )
131 write( "Du kannst wieder etwas sehen.\n" ) ;
132 else write( "Ok.\n" ) ;
133 say((string)PL->Name(WER)
134 + " zuendet " + name( WEN, 0 ) + " an.\n" ) ;
135
136 return TRUE ;
137}
138
139bool extinguish(string str)
140{
141 int ti;
142 object env;
143
144 _notify_fail( "Welche Lichtquelle moechtest Du loeschen?\n" ) ;
145
146 if( (!str) || (!id( str )) )
147 return FALSE ;
148
149 if( !lighted )
150 {
151 _notify_fail( CAP( name( WER, 1 ) ) + " brennt gar nicht.\n" ) ;
152 return FALSE ;
153 }
154
155 if( environment() != PL )
156 {
157 _notify_fail( "Erstmal musst Du " + name( WEN, 0 ) + " haben.\n" ) ;
158 return FALSE ;
159 }
160
161 if( ( ti = remove_call_out( "out_of_fuel" ) ) == -1 )
162 ti = 0 ;
163
164 fuel -= (call_time - ti) ;
165 lighted = FALSE ;
166 env=this_object();
167 while (objectp(env=environment(env)))
168 // Ja. Man ruft die _set_xxx()-Funktionen eigentlich nicht direkt auf.
169 // Aber das Lichtsystem ist schon *so* rechenintensiv und gerade der
170 // P_LAST_CONTENT_CHANGE-Cache wird *so* oft benoetigt, dass es mir
171 // da um jedes bisschen Rechenzeit geht.
172 // Der Zweck heiligt ja bekanntlich die Mittel. ;-)
173 //
174 // Tiamak
175 env->_set_last_content_change();
176 if ( this_player()->QueryProp(P_PLAYER_LIGHT) == 0 )
177 {
178 write( "Es wird dunkel.\n" ) ;
179 say((string)PL->Name(WER)
180 + " macht das Licht aus.\n" ) ;
181 }
182 else
183 {
184 write( "Ok.\n" ) ;
185 say((string)PL->Name(WER)
186 + " loescht " + name( WEN, 0 ) + " aus.\n" ) ;
187 }
188
189 if( fuel <= 0 ) test_remove() ;
190 return TRUE ;
191}
192
193bool unlight()
194{
195 int ti;
196 object env;
197
198 if( !lighted )
199 return FALSE ;
200
201 if( ( ti = remove_call_out( "out_of_fuel" ) ) == -1 )
202 ti = 0 ;
203
204 fuel -= (call_time - ti) ;
205 lighted = FALSE ;
206 env=this_object();
207 while (objectp(env=environment(env)))
208 // Kommentar siehe oben ;^)
209 env->_set_last_content_change();
210 if( fuel <= 0 ) test_remove() ;
211 return TRUE ;
212}
213
214void out_of_fuel()
215{
216 int i;
217 object *inv, env;
218
219 fuel -= call_time ;
220
221 if (fuel>0) {
222 call_out( "out_of_fuel", call_time ) ;
223 return ;
224 }
225 lighted=FALSE;
226 env=this_object();
227 while (objectp(env=environment(env)))
228 // Immer noch nicht wirklich sauber. Aber Begruendung siehe oben.
229 env->_set_last_content_change();
230
231 if (environment())
232 {
233 if ( living(environment()) && environment(environment()) )
234 {
235 inv=(users() & all_inventory(environment(environment())))-({ environment() });
236 for (i=sizeof(inv)-1; i>=0; i--)
237 if (inv[i]->QueryProp(P_PLAYER_LIGHT)<=0)
238 tell_object(inv[i], "Es wird dunkel als " + environment()->name(WESSEN) +
239 " " + QueryProp(P_NAME) + " erlischt.\n" ) ;
240 else tell_object(inv[i], CAP( name( WER, 0 ) ) + " erlischt.\n" ) ;
241 if (environment()->QueryProp(P_PLAYER_LIGHT)<=0)
242 tell_object(environment(),
243 CAP( name( WER, 1 ) ) + " erlischt und es wird dunkel.\n" ) ;
244 else tell_object(environment(), CAP( name( WER, 1 ) ) + " erlischt.\n" ) ;
245 }
246 else
247 {
248 inv=(users() & all_inventory(environment()));
249 for (i=sizeof(inv)-1; i>=0; i--)
250 if (inv[i]->QueryProp(P_PLAYER_LIGHT)<=0)
251 tell_object(inv[i], "Es wird dunkel als " + name(WER,1)
252 + " erlischt.\n" ) ;
253 else tell_object(inv[i], CAP( name( WER, 0 ) ) + " erlischt.\n" ) ;
254 }
255 }
256 test_remove() ;
257}
258
259// Brennstoff nachfuellen
260void AddFuel(int f)
261{ fuel += f ; }
262
263// Property - Funktionen
264
265static void _set_lighted(bool l)
266{ lighted = l ; }
267
268bool _query_lighted()
269{ return lighted ; }
270
271static void _set_fuel(int f)
272{
273 if (f>max_fuel) max_fuel=f;
274 fuel = f ;
275}
276
277static int _query_fuel()
278{
279 int tmp;
280
281 if ((tmp=find_call_out("out_of_fuel"))>=0)
282 return fuel-call_time+tmp;
283 else return fuel;
284}
285
286static string _query_lightdesc()
287{
288 string *tmp;
289 int n,i;
290
291 tmp=Query(P_LIGHTDESC);
292 if (!pointerp(tmp)) return (string)tmp;
293 n=sizeof(tmp);
294 i=n*_query_fuel()/max_fuel;
295 if (i>=n) i=n-1;
296 return tmp[i];
297}
298
299static int _query_light()
300{ return (lighted ? Query(P_LIGHT) : 0); }
301
302/*
303 * short() ueberladen
304 */
305string short()
306{
307 string s;
308 string desc;
309
310 if(!(s=QueryProp(P_SHORT)))
311 return 0;
312 return s + ( (lighted)? (" ("+QueryProp( P_LIGHTDESC ) +").\n") : ".\n" );
313}