#include <sys/types.h> #include <ctype.h> #include <stdio.h> #include <string.h> #include "mud.h" RESTORE_DATA * first_restore; RESTORE_DATA * last_restore; RESTORE_DATA *get_restore( char *name ) { RESTORE_DATA *restore; for ( restore = first_restore; restore; restore = restore->next ) if ( !str_cmp( name, restore->type ) ) return restore; for ( restore = first_restore; restore; restore = restore->next ) if ( nifty_is_name( name, restore->type ) ) return restore; for ( restore = first_restore; restore; restore = restore->next ) if ( !str_prefix( name, restore->type ) ) return restore; for ( restore = first_restore; restore; restore = restore->next ) if ( nifty_is_name_prefix( name, restore->type ) ) return restore; return NULL; } #if defined(KEY) #undef KEY #endif #define KEY( literal, field, value ) \ if ( !str_cmp( word, literal ) ) \ { \ field = value; \ fMatch = TRUE; \ break; \ } /* Online editing of restore added by Gavin 5-26-2000 */ /* Read in an individual restoretype */ void fread_restore( RESTORE_DATA *restore, FILE *fp ) { char buf[MAX_STRING_LENGTH]; char *word; bool fMatch; for ( ; ; ) { word = feof( fp ) ? "End" : fread_word( fp ); fMatch = FALSE; switch ( UPPER(word[0]) ) { case '*': fMatch = TRUE; fread_to_eol( fp ); break; case 'B': KEY( "Boost", restore->boost, fread_number( fp ) ); break; case 'C': KEY( "Cmessage", restore->cmsg, fread_string( fp ) ); KEY( "Color", restore->color, fread_number( fp ) ); break; case 'E': if ( !str_cmp( word, "End" ) ) { if (!restore->owner) restore->owner = STRALLOC( "Any" ); if (!restore->boost) restore->boost = 1; return; } break; case 'O': KEY( "Owner", restore->owner, fread_string( fp ) ); break; case 'R': KEY( "Rmessage", restore->rmsg, fread_string( fp ) ); break; case 'T': KEY( "Type", restore->type, fread_string( fp ) ); break; case 'V': KEY( "Vmessage", restore->vmsg, fread_string( fp ) ); break; } if ( !fMatch ) { sprintf( buf, "Fread_restore: no match: %s", word ); bug( buf, 0 ); } } } /* Load the restore file */ void load_restores() { char filename[256]; RESTORE_DATA *restore; FILE *fp; int restorecount; first_restore = NULL; last_restore = NULL; sprintf( filename, "%s%s", SYSTEM_DIR, RESTORE_FILE ); if ( ( fp = fopen( filename, "r" ) ) != NULL ) { restorecount = 0; for ( ; ; ) { char letter; char *word; letter = fread_letter( fp ); if ( letter == '*' ) { fread_to_eol( fp ); continue; } if ( letter != '#' ) { bug( "Load_restore_file: # not found.", 0 ); break; } word = fread_word( fp ); if ( !str_cmp( word, "RESTORE" ) ) { if ( restorecount >= MAX_RESTORE_TYPES ) { bug( "load_restores: more restoretypes than MAX_RESTORE_TYPES %d", MAX_RESTORE_TYPES ); FCLOSE( fp ); return; } CREATE( restore, RESTORE_DATA, 1 ); fread_restore( restore, fp ); restorecount++; LINK(restore, first_restore, last_restore, next, prev); continue; } else if ( !str_cmp( word, "END" ) ) break; else { char buf[MAX_STRING_LENGTH]; sprintf( buf, "Load_restore_file: bad section: %s.", word ); bug( buf, 0 ); continue; } } FCLOSE( fp ); } return; } /* Online restore editing, save the restore table to disk - Gavin 5-26-2000 */ void save_restores() { RESTORE_DATA *trestore; FILE *fp; char filename[256]; sprintf( filename, "%s%s", SYSTEM_DIR, RESTORE_FILE ); FCLOSE( fpReserve ); if ( ( fp = fopen( filename, "w" ) ) == NULL ) { bug( "save_restore: fopen", 0 ); perror( filename ); } else { for ( trestore = first_restore; trestore; trestore = trestore->next ) { fprintf( fp, "#RESTORE\n" ); fprintf( fp, "Type %s~\n", trestore->type ); fprintf( fp, "Owner %s~\n", trestore->owner ); fprintf( fp, "Cmessage %s~\n", trestore->cmsg ); fprintf( fp, "Vmessage %s~\n", trestore->vmsg ); fprintf( fp, "Rmessage %s~\n", trestore->rmsg ); fprintf( fp, "Color %d\n", trestore->color ); fprintf( fp, "Boost %f\n", trestore->boost ); fprintf( fp, "End\n\n" ); } fprintf( fp, "#END\n" ); FCLOSE(fp); } fpReserve = fopen ( NULL_FILE, "r" ); return; } /** Function: do_restore * Descr : Restores (heals) a player, optionally sending one of several * predefined "restore option" messages to those involved. * Returns : (void) * Syntax : restore (who/all) [option] * Written : v1.0 May/2000 * Author : Gavin <ur_gavin@hotmail.com> */ void do_restore( CHAR_DATA *ch, char *argument ) { RESTORE_DATA *restore; char type[MAX_INPUT_LENGTH]; char who[MAX_INPUT_LENGTH]; int color = AT_IMMORT; bool found = FALSE; CHAR_DATA *victim; if ( IS_NPC(ch) ) { send_to_char( "Mobs can't use the restore command.\n\r", ch ); return; } set_char_color( AT_IMMORT, ch ); argument = one_argument( argument, who ); argument = one_argument( argument, type ); if ( !str_prefix( who, "list" ) || who == NULL ) { set_char_color( AT_GREEN, ch ); send_to_char( "Syntax: restore <victim/all> [type]\n\r", ch ); send_to_char( "Where type is one of the above...\n\r", ch); send_to_pager_color( "&YRestore &ROwner\n\r", ch ); send_to_pager_color( "&g-------------------------+---------------\n\r", ch ); for ( restore = first_restore; restore; restore = restore->next ) pager_printf( ch, "&G%-14s &g%13s\n\r", restore->type, restore->owner ); send_to_char( "\n\rTyping just 'restore <player>' will work too...\n\r",ch ); return; } if ( !str_cmp( who, "all" ) ) { CHAR_DATA *vch; CHAR_DATA *vch_next; if ( !ch->pcdata ) return; if ( get_trust( ch ) < LEVEL_NEOPHYTE ) { if ( IS_NPC( ch ) ) { send_to_char( "You can't do that.\n\r", ch ); return; } else { /* Check if the player did a restore all within the last 18 hours. */ if ( current_time - last_restore_all_time < RESTORE_INTERVAL ) { send_to_char( "Sorry, you can't do a restore all yet.\n\r", ch ); do_restoretime( ch, "" ); return; } } } last_restore_all_time = current_time; ch->pcdata->restore_time = current_time; save_char_obj( ch ); send_to_char( "Beginning 'restore all' ...\n\r", ch); for ( vch = first_char; vch; vch = vch_next ) { vch_next = vch->next; if ( !IS_NPC( vch ) && !IS_IMMORTAL( vch ) ) { if ( type[0] == '\0' ) { act( AT_IMMORT, "$n has restored you.", ch, NULL, vch, TO_VICT ); vch->hit = vch->max_hit; vch->mana = vch->max_mana; vch->move = vch->max_move; update_pos (vch); found = TRUE; } else { for ( restore = first_restore; restore; restore = restore->next ) { if ( ( !str_cmp(type,restore->type) && !str_cmp("Any",restore->owner) ) || ( !str_cmp(restore->owner,ch->name) && !str_cmp(type,restore->type) ) || ( get_trust(ch) == MAX_LEVEL && !str_cmp(type,restore->type) ) ) { found = TRUE; color = restore->color; act( AT_WHITE, restore->vmsg , ch, NULL, vch, TO_VICT); if ( restore->boost != 0 ) vch->hit = vch->max_hit * restore->boost; else vch->hit = vch->max_hit; vch->mana = vch->max_mana; vch->move = vch->max_move; update_pos (vch); /*return;*/ } } } if (!found) send_to_char( "&RRestore type not defined, or not owned by you. Type \"restore list\" for a complete listing of types available to you.\n\r", ch ); } } send_to_char( "Restored.\n\r", ch ); } else { if ( ( victim = get_char_world( ch, who ) ) == NULL ) { send_to_char( "They aren't here.\n\r", ch ); return; } if ( type[0] == '\0' ) { act( AT_IMMORT, "You restore $N!", ch, NULL, victim, TO_CHAR ); act( AT_IMMORT, "$n has restored you.", ch, NULL, victim, TO_VICT ); act( AT_IMMORT, "$n restores $N!", ch, NULL, victim, TO_NOTVICT ); victim->hit = victim->max_hit; victim->mana = victim->max_mana; victim->move = victim->max_move; update_pos( victim ); return; } else { for ( restore = first_restore; restore; restore = restore->next ) { if ( ( !str_cmp(type,restore->type) && !str_cmp("Any",restore->owner) ) || ( !str_cmp(restore->owner,ch->name) && !str_cmp(type,restore->type) ) || ( get_trust(ch) == MAX_LEVEL && !str_cmp(type,restore->type) ) ) { found = TRUE; color = restore->color; act( AT_WHITE , restore->cmsg, ch, NULL, victim, TO_CHAR ); act( AT_WHITE , restore->vmsg, ch, NULL, victim, TO_VICT ); act( AT_WHITE , restore->rmsg, ch, NULL, victim, TO_NOTVICT ); if ( restore->boost != 0 ) victim->hit = victim->max_hit * restore->boost; else victim->hit = victim->max_hit; victim->mana = victim->max_mana; victim->move = victim->max_move; update_pos (victim); return; } } } if (!found) send_to_char( "&RRestore type not defined, or not owned by you. Type \"restore list\" for a complete listing of types available to you.\n\r", ch ); send_to_char( "Restored.\n\r", ch ); return; } } /* Create a restoretype online - Gavin 5-26-2000 */ void do_makerestore( CHAR_DATA *ch, char *argument ) { RESTORE_DATA *restore; if ( IS_NPC( ch ) ) { send_to_char( "Huh?\n\r", ch ); return; } if ( !argument || argument[0] == '\0' ) { send_to_char( "Usage: makerestore <restoretype>\n\r", ch ); return; } if( ( restore = get_restore( argument ) ) != NULL ) { send_to_char( "That restore type already exists.\n\r", ch ); return; } CREATE( restore, RESTORE_DATA, 1 ); LINK( restore, first_restore, last_restore, next, prev ); restore->type = STRALLOC( argument ); restore->owner = STRALLOC( "Any" ); restore->color = AT_IMMORT; restore->boost = 1; restore->cmsg = STRALLOC( "You restore $N!" ); restore->vmsg = STRALLOC( "$n has restored you" ); restore->rmsg = STRALLOC( "$n restores $N!" ); ch_printf( ch, "New restoretype %s added. Set to default values.\n\r", restore->type ); return; } /* Set restore values online - Gavin 5-26-2000 */ void do_setrestore( CHAR_DATA *ch, char *argument ) { char arg1[MAX_INPUT_LENGTH]; char arg2[MAX_INPUT_LENGTH]; RESTORE_DATA *restore; if ( IS_NPC( ch ) ) { send_to_char( "Huh?\n\r", ch ); return; } switch( ch->substate ) { default: break; case SUB_RESTRICTED: send_to_char( "You cannot do this while in another command.\n\r", ch ); return; case SUB_SLAYCMSG: restore = ch->dest_buf; STRFREE( restore->cmsg ); restore->cmsg = copy_buffer( ch ); stop_editing( ch ); ch->substate = ch->tempnum; return; case SUB_SLAYVMSG: restore = ch->dest_buf; STRFREE( restore->vmsg ); restore->vmsg = copy_buffer( ch ); stop_editing( ch ); ch->substate = ch->tempnum; return; case SUB_SLAYRMSG: restore = ch->dest_buf; STRFREE( restore->rmsg ); restore->rmsg = copy_buffer( ch ); stop_editing( ch ); ch->substate = ch->tempnum; return; } argument = one_argument( argument, arg1 ); argument = one_argument( argument, arg2 ); if ( arg1[0] == '\0' ) { send_to_char( "Usage: setrestore <restoretype> <field> <value>\n\r", ch ); send_to_char( "Usage: setrestore save\n\r", ch ); send_to_char( "\n\rField being one of:\n\r", ch ); send_to_char( "owner cmsg vmsg rmsg\n\r", ch ); return; } if ( !str_cmp( arg1, "save" ) ) { save_restores(); send_to_char( "Restore table saved.\n\r", ch ); return; } if( ( restore = get_restore( arg1 ) ) == NULL ) { send_to_char( "No such restoretype.\n\r", ch ); return; } if ( !str_cmp( arg2, "owner" ) ) { STRFREE( restore->owner ); restore->owner = STRALLOC( argument ); send_to_char( "New owner set.\n\r", ch ); return; } if ( !str_cmp( arg2, "cmsg" ) ) { if ( ch->substate == SUB_REPEATCMD ) ch->tempnum = SUB_REPEATCMD; else ch->tempnum = SUB_NONE; ch->substate = SUB_SLAYCMSG; ch->dest_buf = restore; start_editing( ch, restore->cmsg ); #ifdef SOLANCODE set_editor_desc( ch, "A custom restore message." ); #endif return; } if ( !str_cmp( arg2, "vmsg" ) ) { if ( ch->substate == SUB_REPEATCMD ) ch->tempnum = SUB_REPEATCMD; else ch->tempnum = SUB_NONE; ch->substate = SUB_SLAYVMSG; ch->dest_buf = restore; start_editing( ch, restore->vmsg ); #ifdef SOLANCODE set_editor_desc( ch, "A custom restore message." ); #endif return; } if ( !str_cmp( arg2, "rmsg" ) ) { if ( ch->substate == SUB_REPEATCMD ) ch->tempnum = SUB_REPEATCMD; else ch->tempnum = SUB_NONE; ch->substate = SUB_SLAYRMSG; ch->dest_buf = restore; start_editing( ch, restore->rmsg ); #ifdef SOLANCODE set_editor_desc( ch, "A custom restore message." ); #endif return; } if ( !str_cmp( arg2, "color" ) ) { if ( atoi(argument) < 0 ) { send_to_char("Please Enter A Number greater then 0\n\r",ch); return; } restore->color = atoi( argument ); send_to_char( "Restore color set.\n\r", ch ); return; } if ( !str_cmp(arg2, "boost" ) ) { if ( get_trust(ch) <= ( MAX_LEVEL - 2 ) ) { send_to_char("Your not able to set this, ask a higher imm\n\r",ch); return; } if ( atoi(argument) < 0 ) { send_to_char("Please Enter A Number greater then 0\n\r",ch); return; } restore->boost = atof(argument); send_to_char( "Restore boost set.\n\r", ch); return; } do_setrestore( ch, "" ); return; } /* Online restore editor, show details of a restoretype - Gavin 5-26-2000 */ void do_showrestore( CHAR_DATA *ch, char *argument ) { RESTORE_DATA *restore; if ( IS_NPC( ch ) ) { send_to_char( "Huh?\n\r", ch ); return; } if ( argument[0] == '\0' ) { send_to_char( "Usage: showrestore <slaytype>\n\r", ch ); return; } if( ( restore = get_restore( argument ) ) == NULL ) { send_to_char( "No such restoretype.\n\r", ch ); return; } ch_printf( ch, "\n\rRestoretype: %s\n\r", restore->type ); ch_printf( ch, "Owner:\t%s\n\r", restore->owner ); ch_printf( ch, "Color:\t%d\n\r", restore->color ); ch_printf( ch, "Boost:\t%f\n\r", restore->boost ); ch_printf( ch, "&RCmessage: \n\r%s\n\r", restore->cmsg ); ch_printf( ch, "&YVmessage: \n\r%s\n\r", restore->vmsg ); ch_printf( ch, "&GRmessage: \n\r%s\n\r", restore->rmsg ); return; } /* Of course, to create means you need to be able to destroy as well :P - Gavin 5-26-2000 */ void do_destroyrestore( CHAR_DATA *ch, char *argument ) { char arg[MAX_INPUT_LENGTH]; RESTORE_DATA *prestore; if ( IS_NPC(ch) ) { send_to_char( "Huh?\n\r", ch ); return; } one_argument( argument, arg ); if ( arg[0] == '\0' ) { send_to_char( "Destroy which restoretype?\n\r", ch ); return; } for ( prestore = first_restore; prestore; prestore = prestore->next ) { if ( !str_cmp( arg, prestore->type ) ) { UNLINK( prestore, first_restore, last_restore, next, prev ); STRFREE( prestore->owner ); STRFREE( prestore->type ); STRFREE( prestore->cmsg ); STRFREE( prestore->vmsg ); STRFREE( prestore->rmsg ); ch_printf( ch,"Restoretype \"%s\" has beed deleted. Be sure to save the restore table.\n\r", arg ); return; } } send_to_char( "No such restoretype.\n\r", ch ); return; }