/* ** This beast of a thing does a conversion between a list ** of objects in the players inventory into a list of ** strings which can be saved, and vice versa. ** ** Optimised, Newstyle, 03/02/94 ** reported DW auto_load to get delayed loading stuff, Bannor 1-APR-94 */ /* ** Format of the autoload string: ** ** ({ cloned, filename, ({ static_load, dynamic_load }), ** cloned, filename, ({ auto_load, 0 }), ... }) ** ** Where clone = <0/1>, filename excludes any #nnnn, and ** no entries are given for object with no autoload, or ** neither of static_load and dynamic load. */ #define CLONER "/global/cloner" #define FILE_NAME1 file_name( arg[ 0 ] ) #define FILE_NAME2 file_name( arg[ 2 ] ) string *auto_load; string *fragile_auto_str_ob( object ob ) { /* this function was added by Ember 30-Oct-93 */ /* it is a copy of auto_str_ob below, with all the catches taken out */ /* it is intended for the newer style of saving/loading with receipts */ string s, s1, s3; int j; object sh; mixed *sh_junk; s = (string)ob->query_auto_load(); if( !s ) { s = (string)ob->query_static_auto_load(); s3 = (string)ob->query_dynamic_auto_load(); if( !s && !s3 ) return({ }); } else s3 = 0; sh_junk = ({ }); if( sh = shadow( ob, 0 ) ) { while( sh ) { /* * We pass the shadow object to the query so they know we are talking * to them. */ s = (string)sh->query_shadow_auto_load( sh ); if( s ) { sh_junk += ({ file_name( sh ), s }); } sh = shadow( sh, 0 ); } } if( sscanf( file_name( ob ), "%s#%d", s1, j ) == 2 ) return({ 1, s1, ({ s, s3, sh_junk }) }); else return({ 0, file_name( ob ), ({ s, s3, sh_junk }) }); } /* fragile_auto_str_ob() */ string *auto_str_ob( object ob ) { string s, s1, s3; int j; object sh; mixed * sh_junk; if( !catch( s = (string)ob->query_auto_load() ) && !s ) { catch( s = (string)ob->query_static_auto_load() ); catch( s3 = (string)ob->query_dynamic_auto_load() ); if( !s && !s3 ) return({ }); } else if( !s ) return({ }); else s3 = 0; sh_junk = ({ }); if( sh = shadow( ob, 0 ) ) { while( sh ) { /* * We pass the shadow object to the query so they know we are talking * to them. */ catch( s = (string)sh->query_shadow_auto_load( sh ) ); if( s ) { sh_junk += ({ file_name( sh ), s }); } sh = shadow( sh, 0 ); } } if( sscanf( file_name( ob ), "%s#%d", s1, j ) == 2 ) return({ 1, s1, ({ s, s3, sh_junk }) }); else return({ 0, file_name( ob ), ({ s, s3, sh_junk }) }); } /* auto_str_ob() */ string *create_auto_load( object *obs, int into_array ) { int j, i; string *tmp, *al_tmp; if( into_array ) auto_load = ({ }); else tmp = ({ }); for( i = 0; i < sizeof( obs ); i++ ) { reset_eval_cost(); if( !catch( al_tmp = auto_str_ob( obs[ i ] ) ) ) { if( into_array ) auto_load += al_tmp; else tmp += al_tmp; } } return tmp; } /* create_auto_load() */ void birthday_gifts() { int day; string month, s1, s2; if( !sizeof( find_match( "birthday card", this_object() ) ) ) if( this_object()->query_is_birthday_today() ) if( !catch( call_other( "/obj/b_day/card", "??" ) ) && !catch( call_other( "/obj/b_day/demon", "??" ) ) ) { call_out( "card_arrives", 5 ); } #ifdef 0 /* commented out until such time as NM needs it */ sscanf( ctime( time() ), "%s %s %d %s", s1, month, day, s2 ); switch( month ) { /* Special day processing */ case "Feb": switch( day ) { case 17: break; } break; case "Mar": switch( day ) { case 8: write( "\n\n%^BLUE%^Happy International Womens day! Be free! Live well!\n" + "But most of all... Don't explode.%^RESET%^\n\n" ); this_object()->set_womens_day( 1 ); break; } break; case "Sep": switch( day ) { case 10: "/global/special_day/beard_day"->startup_player( this_object() ); break; } break; } #endif } /* birthday_gifts() */ void card_arrives() { object card; card = (object)"/global/cloner"->clone( "/obj/b_day/card" ); card->move( this_object() ); tell_room( environment(), "You hear a rumbling in the distance. " + "Then, suddenly, a malformed goblin wizzes past you, " + "frantically pedalling a fire-engine red tricycle!\n" ); write( "You feel something thrust into your hand by a greener, " + "wartier one.\n" ); } /* card_arrives() */ object *load_auto_load( string *auto_string, object dest ) { object ob, card, *obs; string name, args; int i; obs = ({ }); if( stringp( auto_string ) ) return({ }); if( !auto_string || !sizeof( auto_string ) ) return({ }); for( i = 0; i < sizeof( auto_string ); i += 3 ) { reset_eval_cost(); if( auto_string[ i ] ) { if( !catch( call_other( auto_string[ i + 1 ], "??" ) ) ) { catch( ob = (object)"/global/cloner"->clone( auto_string[ i + 1 ] ) ); if( ob ) { call_out( "auto_clone", 0, ({ ob, auto_string[ i + 2 ], dest }) ); obs += ({ ob }); } } } else if( !find_object( auto_string[ i + 1 ] ) && !catch( call_other( auto_string[ i + 1 ], "??" ) ) ) { ob = find_object( auto_string[ i + 1 ] ); call_out( "auto_clone", 0, ({ ob, auto_string[ i + 2 ], dest }) ); obs += ({ ob }); } } return obs; } /* load_auto_load() */ void load_auto_load_alt( mixed *auto_string, object dest, object tell ) { int i; object thing; if( !auto_string || !sizeof( auto_string ) ) return; if( stringp( auto_string ) ) return; if( sizeof( auto_string ) > 3 ) { for( i = 0; i < sizeof( auto_string ); i += 3 ) call_out( "load_auto_load_alt", i, auto_string[ i..i + 2 ], dest, tell ); return; } if( auto_string[ 0 ] ) if( !catch( call_other( auto_string[ 1 ], "??" ) ) ) { catch( thing = (object)CLONER->clone( auto_string[ 1 ] ) ); if( thing ) call_out( "auto_clone_alt", 1, ({ thing, auto_string[ 2 ], dest, tell }) ); else { tell_object( tell, "Could not clone " + auto_string[ 1 ] + ".\n" ); thing = clone_object( "/obj/misc/al_receipt" ); thing->set_object( auto_string[ 1 ] ); thing->move( dest ); } } else { tell_object( tell, "Error in loading " + auto_string[ 1 ] + ".\n" ); thing = clone_object( "/obj/misc/al_receipt" ); thing->set_object( auto_string[ 1 ] ); thing->move( dest ); } else if( !find_object( auto_load[ 1 ] ) ) if( !catch( call_other( auto_string[ 1 ], "??" ) ) ) { catch( thing = find_object( auto_string[ 1 ] ) ); if( thing ) call_out( "auto_clone_alt", 1, ({ thing, auto_string[ 2 ], dest, tell }) ); else tell_object( tell, "Could not load " + auto_string[ 1 ] + ".\n" ); } else tell_object( tell, "Error in loading " + auto_string[ 1 ] + ".\n" ); else tell_object( tell, "Object " + auto_string[ 1 ] + " exists.\n" ); } /* load_auto_load_alt() */ void auto_clone( mixed arg ) { object wombat; int i; /* This should stop containers which too long eval on loading... * (Yes, I have seen this happen). From dieing completely and put * them into the inventory, it will have a side effect of putting * broken objects into the players inventory too... */ if( arg[ 0 ]->move( arg[ 2 ] ) ) if( environment( arg[ 2 ] ) ) { if( arg[ 0 ]->move( environment( arg[ 2 ] ) ) ) return( void ) arg[ 0 ]->dest_me(); } else return( void ) arg[ 0 ]->dest_me(); if( sizeof( arg[ 1 ] ) == 1 || !arg[ 1 ][ 1 ] ) { arg[ 0 ]->init_arg( arg[ 1 ][ 0 ] ); } else { reset_eval_cost(); catch( arg[ 0 ]->init_static_arg( arg[ 1 ][ 0 ] ) ); catch( arg[ 0 ]->init_dynamic_arg( arg[ 1 ][ 1 ] ) ); if( sizeof( arg[ 1 ] ) >= 3 ) { for( i = 0; i < sizeof( arg[ 1 ][ 2 ] ); i += 2 ) { catch( wombat = clone_object( arg[ 1 ][ 2 ][ i ] ) ); printf( "WOmbat: %O\n", wombat, arg[ 1 ][ 2 ][ i ] ); catch( wombat->init_shadow_arg( arg[ 0 ], arg[ 1 ][ 2 ][ i + 1 ] ) ); } } } } /* auto_clone() */ void auto_clone_alt( mixed arg ) { int i; object shadow; if( (i = remove_call_out( "check_auto_load_over" )) != -1 ) call_out( "check_auto_load_over", ( i + 3 ), arg[ 3 ] ); else call_out( "check_auto_load_over", 3, arg[ 3 ] ); if( arg[ 0 ]->move( arg[ 2 ] ) ) { tell_object( arg[ 3 ], "Can't move " + FILE_NAME1 + " into " + FILE_NAME2 + ".\n" ); if( environment( arg[ 2 ] ) ) if( arg[ 0 ]->move( environment( arg[ 2 ] ) ) ) { tell_object( arg[ 3 ], "Can't move " + FILE_NAME1 + " into the " + "environment of " + FILE_NAME2 + ". Moving it into the room for " + "broken objects.\n" ); "/room/broken"->force_load(); arg[ 0 ]->move( "/room/broken" ); } else { tell_object( arg[ 3 ], FILE_NAME2 + " does not have an environment. " + "Moving " + FILE_NAME1 + " into the room for broken objects.\n" ); "/room/broken"->force_load(); arg[ 0 ]->move( "/room/broken" ); } } if( sizeof( arg[ 1 ] ) == 1 ) catch( arg[ 0 ]->init_arg( arg[ 1 ][ 0 ] ) ); else if( !arg[ 1 ][ 1 ] ) catch( arg[ 0 ]->init_arg( arg[ 1 ][ 0 ] ) ); else { reset_eval_cost(); catch( arg[ 0 ]->init_static_arg( arg[ 1 ][ 0 ] ) ); catch( arg[ 0 ]->set_player( arg[ 3 ] ) ); catch( arg[ 0 ]->init_dynamic_arg( arg[ 1 ][ 1 ] ) ); } if( sizeof( arg[ 1 ] ) > 2 ) for( i = 0; i < sizeof( arg[ 1 ][ 2 ] ); i += 2 ) { catch( shadow = (object)CLONER->clone( arg[ 1 ][ 2 ][ i ] ) ); if( shadow ) catch( shadow->init_shadow_arg( arg[ 0 ], arg[ 1 ][ 2 ][ i + 1 ] ) ); } } /* auto_clone_alt() */ void check_auto_load_over( object thing ) { if( find_call_out( "auto_clone_alt" ) == -1 ) if( find_call_out( "load_auto_load_alt" ) == -1 ) tell_object( thing, "\n%^CYAN%^Inventory regeneration complete." + "%^RESET%^\n" ); } /* check_auto_load_over() */