MG Mud User | 88f1247 | 2016-06-24 23:31:02 +0200 | [diff] [blame^] | 1 | // 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 | |
| 39 | inherit "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... |
| 59 | nosave int fuel, max_fuel; |
| 60 | nosave bool lighted ; |
| 61 | nosave int call_time ; |
| 62 | |
| 63 | void 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 | |
| 82 | void test_remove() |
| 83 | { if (QueryProp(P_DO_DESTRUCT)) remove(); } |
| 84 | |
| 85 | /* |
| 86 | * Lichtquelle anzuenden |
| 87 | */ |
| 88 | bool 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 | |
| 139 | bool 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 | |
| 193 | bool 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 | |
| 214 | void 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 |
| 260 | void AddFuel(int f) |
| 261 | { fuel += f ; } |
| 262 | |
| 263 | // Property - Funktionen |
| 264 | |
| 265 | static void _set_lighted(bool l) |
| 266 | { lighted = l ; } |
| 267 | |
| 268 | bool _query_lighted() |
| 269 | { return lighted ; } |
| 270 | |
| 271 | static void _set_fuel(int f) |
| 272 | { |
| 273 | if (f>max_fuel) max_fuel=f; |
| 274 | fuel = f ; |
| 275 | } |
| 276 | |
| 277 | static 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 | |
| 286 | static 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 | |
| 299 | static int _query_light() |
| 300 | { return (lighted ? Query(P_LIGHT) : 0); } |
| 301 | |
| 302 | /* |
| 303 | * short() ueberladen |
| 304 | */ |
| 305 | string 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 | } |