예제 #1
0
파일: rungame.c 프로젝트: neonKow/DynaHack
static void game_ended(int status, fnchar *filename)
{
    fnchar fncopy[1024], logname[1024], savedir[BUFSZ], *bp, *fname;

    if (status != GAME_OVER)
        return;

    show_topten(player.plname, settings.end_top, settings.end_around,
                settings.end_own);

    /*
     * The game ended terminally. Now it would be nice to move the saved game
     * out of the save/ dir and into the log/ dir, since it's only use now is as
     * a tropy.
     */
#if !defined(WIN32)
    /* dirname and basename may modify the input string, depending on the system */
    strncpy(fncopy, filename, sizeof(fncopy));
    bp = dirname(fncopy);

    get_gamedir(SAVE_DIR, savedir);
    savedir[strlen(savedir)-1] = '\0'; /* remove the trailing '/' */
    if (strcmp(bp, savedir) != 0)
        return; /* file was not in savedir, so don't touch it */

    get_gamedir(LOG_DIR, logname);
    strncpy(fncopy, filename, sizeof(fncopy));
    fname = basename(fncopy);
    strncat(logname, fname, sizeof(logname)-1);

    /* don't care about errors: rename is nice to have, not essential */
    rename(filename, logname);
#else
    bp = wcsrchr(filename, L'\\');
    get_gamedir(SAVE_DIR, savedir);
    if (!bp || wcsncmp(filename, savedir, wcslen(savedir)))
        return;

    get_gamedir(LOG_DIR, logname);
    wcsncat(logname, bp+1, 1024);

    /* don't care about errors: rename is nice to have, not essential */
    _wrename(filename, logname);
#endif
}
예제 #2
0
파일: rungame.c 프로젝트: neonKow/DynaHack
void rungame(void)
{
    int ret, role = initrole, race = initrace, gend = initgend, align = initalign;
    int fd = -1;
    char plname[BUFSZ];
    fnchar filename[1024];
    fnchar savedir[BUFSZ];
    long t;

    if (!get_gamedir(SAVE_DIR, savedir)) {
        curses_raw_print("Could not find where to put the logfile for a new game.");
        return;
    }

    if (!player_selection(&role, &race, &gend, &align, random_player))
        return;

    strncpy(plname, settings.plname, PL_NSIZ);
    /* The player name is set to "wizard" (again) in nh_start_game, so setting
     * it here just prevents wizmode player from being asked for a name. */
    if (ui_flags.playmode == MODE_WIZARD)
        strcpy(plname, "wizard");

    while (!plname[0])
        curses_getline("what is your name?", plname);
    if (plname[0] == '\033') /* canceled */
        return;

    t = (long)time(NULL);
#if defined(WIN32)
    snwprintf(filename, 1024, L"%ls%ld_%hs.nhgame", savedir, t, plname);
#else
    snprintf(filename, 1024, "%s%ld_%s.nhgame", savedir, t, plname);
#endif
    fd = sys_open(filename, O_TRUNC | O_CREAT | O_RDWR, FILE_OPEN_MASK);
    if (fd == -1) {
        curses_raw_print("Could not create the logfile.");
        return;
    }

    create_game_windows();
    if (!nh_start_game(fd, plname, role, race, gend, align, ui_flags.playmode)) {
        destroy_game_windows();
        close(fd);
        return;
    }

    load_keymap(); /* need to load the keymap after the game has been started */
    ret = commandloop();
    free_keymap();
    close(fd);

    destroy_game_windows();
    cleanup_messages();
    game_ended(ret, filename);
}
예제 #3
0
/* determine the correct filename for the config file */
static int
get_config_name(fnchar * buf, nh_bool ui)
{
    buf[0] = '\0';

    /* If running in connection-only mode, we can't get the options until we're
       already logged into the server. */
    if (ui_flags.connection_only && !*ui_flags.username)
        return 0;

#if defined(UNIX)
    char *envval;

    if (!ui) {
        /* check for env override first */
        envval = getenv("NETHACK4OPTIONS");
        if (envval) {
            strncpy(buf, envval, BUFSZ);
            return 1;
        }
    }
#endif

    /* look in regular location */
    if (!get_gamedir(CONFIG_DIR, buf))
        return 0;

#ifdef WIN32
    wchar_t usernamew[BUFSZ];
    int i = 0;

    while (i < BUFSZ - 2 && ui_flags.username[i]) {
        usernamew[i] = ui_flags.username[i];
        i++;
    }
    usernamew[i] = 0;
#else
    /* This is to avoid putting a directive inside the arguments to fnncat,
     * which is a macro. */
    char *usernamew = ui_flags.username;
#endif

    fnncat(buf, ui_flags.connection_only ? usernamew :
                ui ? FN("curses.conf") :
                FN("NetHack4.conf"),
           BUFSZ - fnlen(buf) - 1);
    if (ui_flags.connection_only)
        fnncat(buf, ui ? FN(".curses.rc") : FN(".NetHack4.rc"),
               BUFSZ - fnlen(buf) - 1);

    return 1;
}
예제 #4
0
/* determine the correct filename for the config file */
static void get_config_name(fnchar *buf, nh_bool ui)
{
    buf[0] = '\0';

#if defined(UNIX)
    char *envval;
    if (!ui) {
	/* check for env override first */
	envval = getenv("DYNAHACKOPTIONS");
	if (envval) {
	    strncpy(buf, envval, BUFSZ);
	    return;
	}
    }
#endif
    
    /* look in regular location */
    if (!get_gamedir(CONFIG_DIR, buf))
	return;

    fnncat(buf, ui ? FN("curses.conf") : FN("DynaHack.conf"), BUFSZ);
}
예제 #5
0
void
replay(void)
{
    char buf[BUFSZ];
    fnchar logdir[BUFSZ], savedir[BUFSZ], filename[1024], *dir, **files;
    struct nh_menuitem *items;
    int i, n, fd, icount, size, filecount, pick[1];
    enum nh_log_status status;
    struct nh_game_info gi;

    if (!get_gamedir(LOG_DIR, logdir))
        logdir[0] = '\0';
    if (!get_gamedir(SAVE_DIR, savedir))
        savedir[0] = '\0';

    if (*logdir)
        dir = logdir;
    else if (*savedir)
        dir = savedir;
    else {
        curses_msgwin("There are no games to replay.");
        return;
    }

    while (1) {
        filename[0] = '\0';
        files = list_gamefiles(dir, &filecount);
        /* make sure there are some files to show */
        if (!filecount) {
            if (dir == savedir) {
                curses_msgwin("There are no saved games to replay.");
                savedir[0] = '\0';
            } else {
                curses_msgwin("There are no completed games to replay.");
                logdir[0] = '\0';
            }

            dir = (dir == savedir) ? logdir : savedir;
            if (!*dir)
                return;
            continue;
        }

        icount = 0;
        size = filecount + 2;
        items = malloc(size * sizeof (struct nh_menuitem));

        /* add all the files to the menu */
        for (i = 0; i < filecount; i++) {
            fd = sys_open(files[i], O_RDWR, 0660);
            status = nh_get_savegame_status(fd, &gi);
            close(fd);

            describe_game(buf, status, &gi);
            add_menu_item(items, size, icount,
                          (status == LS_IN_PROGRESS) ? 0 : icount + 1, buf, 0,
                          FALSE);
        }

        if (dir == logdir && *savedir) {
            add_menu_txt(items, size, icount, "", MI_NORMAL);
            add_menu_item(items, size, icount, -1, "View saved games instead",
                          '!', FALSE);
        } else if (dir == savedir && *logdir) {
            add_menu_txt(items, size, icount, "", MI_NORMAL);
            add_menu_item(items, size, icount, -1, "View saved games instead",
                          '!', FALSE);
        }

        n = curses_display_menu(items, icount, "Pick a game to view", PICK_ONE,
                                PLHINT_ANYWHERE, pick);
        free(items);
        filename[0] = '\0';
        if (n > 0 && pick[0] != -1)
            fnncat(filename, files[pick[0] - 1],
                   sizeof (filename) / sizeof (fnchar) - 1);

        for (i = 0; i < filecount; i++)
            free(files[i]);
        free(files);

        if (n <= 0)
            return;

        if (pick[0] == -1) {
            dir = (dir == savedir) ? logdir : savedir;
            continue;
        }

        /* we have a valid filename */
        break;
    }

    fd = sys_open(filename, O_RDWR, 0660);
    replay_commandloop(fd);
    close(fd);
}
예제 #6
0
/*
====================================================================
Load terrain types, weather information and hex tile icons.
====================================================================
*/
int terrain_load( char *fname )
{
    int i, j, k;
    PData *pd, *sub, *subsub, *subsubsub;
    List *entries, *flags;
    char path[512];
    char *flag, *str;
    char *domain = 0;
    int count;
    /* log info */
    int  log_dot_limit = 40; /* maximum of dots */
    char log_str[128];
    sprintf( path, "%s/maps/%s", get_gamedir(), fname );
    if ( ( pd = parser_read_file( fname, path ) ) == 0 ) goto parser_failure;
    domain = determine_domain(pd, fname);
    locale_load_domain(domain, 0/*FIXME*/);
    /* get weather */
    if ( !parser_get_entries( pd, "weather", &entries ) ) goto parser_failure;
    weather_type_count = entries->count;
    weather_types = calloc( weather_type_count, sizeof( Weather_Type ) );
    list_reset( entries ); i = 0;
    while ( ( sub = list_next( entries ) ) ) {
        weather_types[i].id = strdup( sub->name );
        if ( !parser_get_localized_string( sub, "name", domain, &weather_types[i].name ) ) goto parser_failure;
        if ( !parser_get_values( sub, "flags", &flags ) ) goto parser_failure;
        list_reset( flags );
        while ( ( flag = list_next( flags ) ) )
            weather_types[i].flags |= check_flag( flag, fct_terrain );
        i++;
    }
    /* hex tile geometry */
    if ( !parser_get_int( pd, "hex_width", &hex_w ) ) goto parser_failure;
    if ( !parser_get_int( pd, "hex_height", &hex_h ) ) goto parser_failure;
    if ( !parser_get_int( pd, "hex_x_offset", &hex_x_offset ) ) goto parser_failure;
    if ( !parser_get_int( pd, "hex_y_offset", &hex_y_offset ) ) goto parser_failure;
    /* terrain icons */
    terrain_icons = calloc( 1, sizeof( Terrain_Icons ) );
    if ( !parser_get_value( pd, "fog", &str, 0 ) ) goto parser_failure;
    sprintf( path, "terrain/%s", str );
    if ( ( terrain_icons->fog = load_surf( path, SDL_SWSURFACE ) ) == 0 ) goto failure;
    if ( !parser_get_value( pd, "danger", &str, 0 ) ) goto parser_failure;
    sprintf( path, "terrain/%s", str );
    if ( ( terrain_icons->danger = load_surf( path, SDL_SWSURFACE ) ) == 0 ) goto failure;
    if ( !parser_get_value( pd, "grid", &str, 0 ) ) goto parser_failure;
    sprintf( path, "terrain/%s", str );
    if ( ( terrain_icons->grid = load_surf( path, SDL_SWSURFACE ) ) == 0 ) goto failure;
    if ( !parser_get_value( pd, "frame", &str, 0 ) ) goto parser_failure;
    sprintf( path, "terrain/%s", str );
    if ( ( terrain_icons->select = load_surf( path, SDL_SWSURFACE ) ) == 0 ) goto failure;
    if ( !parser_get_value( pd, "crosshair", &str, 0 ) ) goto parser_failure;
    sprintf( path, "terrain/%s", str );
    if ( ( terrain_icons->cross = anim_create( load_surf( path, SDL_SWSURFACE ), 1000/config.anim_speed, hex_w, hex_h, sdl.screen, 0, 0 ) ) == 0 )
        goto failure;
    anim_hide( terrain_icons->cross, 1 );
    if ( !parser_get_value( pd, "explosion", &str, 0 ) ) goto parser_failure;
    sprintf( path, "terrain/%s", str );
    if ( ( terrain_icons->expl1 = anim_create( load_surf( path, SDL_SWSURFACE ), 50/config.anim_speed, hex_w, hex_h, sdl.screen, 0, 0 ) ) == 0 )
        goto failure;
    anim_hide( terrain_icons->expl1, 1 );
    if ( ( terrain_icons->expl2 = anim_create( load_surf( path, SDL_SWSURFACE ), 50/config.anim_speed, hex_w, hex_h, sdl.screen, 0, 0 ) ) == 0 )
        goto failure;
    anim_hide( terrain_icons->expl2, 1 );
    /* terrain sounds */
#ifdef WITH_SOUND    
    if ( parser_get_value( pd, "explosion_sound", &str, 0 ) )
        terrain_icons->wav_expl = wav_load( str, 2 );
    if ( parser_get_value( pd, "select_sound", &str, 0 ) )
        terrain_icons->wav_select = wav_load( str, 1 );
#endif
    /* terrain types */
    if ( !parser_get_entries( pd, "terrain", &entries ) ) goto parser_failure;
    terrain_type_count = entries->count;
    terrain_types = calloc( terrain_type_count, sizeof( Terrain_Type ) );
    list_reset( entries ); i = 0;
    while ( ( sub = list_next( entries ) ) ) {
        /* id */
        terrain_types[i].id = sub->name[0];
        /* name */
        if ( !parser_get_localized_string( sub, "name", domain, &terrain_types[i].name ) ) goto parser_failure;
        /* each weather type got its own image -- if it's named 'default' we
           point towards the image of weather_type 0 */
        terrain_types[i].images = calloc( weather_type_count, sizeof( SDL_Surface* ) );
        for ( j = 0; j < weather_type_count; j++ ) {
            sprintf( path, "image/%s", weather_types[j].id );
            if ( !parser_get_value( sub, path, &str, 0 ) ) goto parser_failure;
            if ( STRCMP( "default", str ) && j > 0 ) {
                /* just a pointer */
                terrain_types[i].images[j] = terrain_types[i].images[0];
            }
            else {
                sprintf( path, "terrain/%s", str );
                if ( ( terrain_types[i].images[j] = load_surf( path, SDL_SWSURFACE ) ) == 0 ) goto parser_failure;
                SDL_SetColorKey( terrain_types[i].images[j], SDL_SRCCOLORKEY, 
                                 get_pixel( terrain_types[i].images[j], 0, 0 ) );
            }
        }
        /* fog image */
        terrain_types[i].images_fogged = calloc( weather_type_count, sizeof( SDL_Surface* ) );
        for ( j = 0; j < weather_type_count; j++ ) {
            if ( terrain_types[i].images[j] == terrain_types[i].images[0] && j > 0 ) {
                /* just a pointer */
                terrain_types[i].images_fogged[j] = terrain_types[i].images_fogged[0];
            }
            else {
                terrain_types[i].images_fogged[j] = create_surf( terrain_types[i].images[j]->w, terrain_types[i].images[j]->h, SDL_SWSURFACE );
                FULL_DEST( terrain_types[i].images_fogged[j]  );
                FULL_SOURCE( terrain_types[i].images[j] );
                blit_surf();
                count =  terrain_types[i].images[j]->w /  hex_w;
                for ( k = 0; k < count; k++ ) {
                    DEST( terrain_types[i].images_fogged[j], k * hex_w, 0,  hex_w, hex_h );
                    SOURCE(  terrain_icons->fog, 0, 0 );
                    alpha_blit_surf( FOG_ALPHA );
                }
                SDL_SetColorKey( terrain_types[i].images_fogged[j], SDL_SRCCOLORKEY, get_pixel( terrain_types[i].images[j], 0, 0 ) );
            }
        }
        /* spot cost */
        terrain_types[i].spt = calloc( weather_type_count, sizeof( int ) );
        if ( !parser_get_pdata( sub, "spot_cost",  &subsub ) ) goto parser_failure;
        for ( j = 0; j < weather_type_count; j++ )
            if ( !parser_get_int( subsub, weather_types[j].id, &terrain_types[i].spt[j] ) ) goto parser_failure;
        /* mov cost */
        terrain_types[i].mov = calloc( mov_type_count * weather_type_count, sizeof( int ) );
        if ( !parser_get_pdata( sub, "move_cost",  &subsub ) ) goto parser_failure;
        for ( k = 0; k < mov_type_count; k++ ) {
            if ( !parser_get_pdata( subsub, mov_types[k].id,  &subsubsub ) ) goto parser_failure;
            for ( j = 0; j < weather_type_count; j++ ) {
                if ( !parser_get_value( subsubsub, weather_types[j].id, &str, 0 ) ) goto parser_failure;
                if ( str[0] == 'X' )
                    terrain_types[i].mov[j + k * weather_type_count] = 0; /* impassable */
                else
                    if ( str[0] == 'A' )
                        terrain_types[i].mov[j + k * weather_type_count] = -1; /* costs all */
                    else
                        terrain_types[i].mov[j + k * weather_type_count] = atoi( str ); /* normal cost */
            }
        }
        /* entrenchment */
        if ( !parser_get_int( sub, "min_entr",  &terrain_types[i].min_entr ) ) goto parser_failure;
        if ( !parser_get_int( sub, "max_entr",  &terrain_types[i].max_entr ) ) goto parser_failure;
        /* initiative modification */
        if ( !parser_get_int( sub, "max_init",  &terrain_types[i].max_ini ) ) goto parser_failure;
        /* flags */
        terrain_types[i].flags = calloc( weather_type_count, sizeof( int ) );
        if ( !parser_get_pdata( sub, "flags",  &subsub ) ) goto parser_failure;
        for ( j = 0; j < weather_type_count; j++ ) {
            if ( !parser_get_values( subsub, weather_types[j].id, &flags ) ) goto parser_failure;
            list_reset( flags );
            while ( ( flag = list_next( flags ) ) )
                terrain_types[i].flags[j] |= check_flag( flag, fct_terrain );
        }
        /* next terrain */
        i++;
        /* LOG */
        strcpy( log_str, "  [                                        ]" );
        for ( k = 0; k < i * log_dot_limit / entries->count; k++ )
            log_str[3 + k] = '*';
        write_text( log_font, sdl.screen, log_x, log_y, log_str, 255 );
        SDL_UpdateRect( sdl.screen, log_font->last_x, log_font->last_y, log_font->last_width, log_font->last_height );
    }
    parser_free( &pd );
    /* LOG */
    write_line( sdl.screen, log_font, log_str, log_x, &log_y ); refresh_screen( 0, 0, 0, 0 );
    free(domain);
    return 1;
parser_failure:        
    fprintf( stderr, "%s\n", parser_get_error() );
failure:
    terrain_delete();
    if ( pd ) parser_free( &pd );
    free(domain);
    printf(tr("If data seems to be missing, please re-run the converter lgc-pg.\n"));
    return 0;
}
예제 #7
0
파일: rungame.c 프로젝트: neonKow/DynaHack
nh_bool loadgame(void)
{
    char buf[BUFSZ];
    fnchar savedir[BUFSZ], filename[1024], **files;
    struct nh_menuitem *items;
    int size, icount, fd, i, n, ret, pick[1];
    enum nh_log_status status;
    struct nh_game_info gi;

    if (!get_gamedir(SAVE_DIR, savedir)) {
        curses_raw_print("Could not find or create the save directory.");
        return FALSE;
    }

    files = list_gamefiles(savedir, &size);
    if (!size) {
        curses_msgwin("No saved games found.");
        return FALSE;
    }

    icount = 0;
    items = malloc(size * sizeof(struct nh_menuitem));

    for (i = 0; i < size; i++) {
        fd = sys_open(files[i], O_RDWR, FILE_OPEN_MASK);
        status = nh_get_savegame_status(fd, &gi);
        close(fd);

        describe_game(buf, status, &gi);
        add_menu_item(items, size, icount, (status == LS_IN_PROGRESS) ? 0 : icount + 1,
                      buf, 0, FALSE);
    }

    n = curses_display_menu(items, icount, "saved games", PICK_ONE, pick);
    free(items);
    filename[0] = '\0';
    if (n > 0)
        fnncat(filename, files[pick[0]-1], sizeof(filename)/sizeof(fnchar)-1);

    for (i = 0; i < icount; i++)
        free(files[i]);
    free(files);
    if (n <= 0)
        return FALSE;

    fd = sys_open(filename, O_RDWR, FILE_OPEN_MASK);
    create_game_windows();
    if (nh_restore_game(fd, NULL, FALSE) != GAME_RESTORED) {
        destroy_game_windows();
        close(fd);
        if (curses_yn_function("Failed to load the save. Do you wish to delete the file?", "yn", 'n') == 'y')
            unlink(filename);
        return FALSE;
    }

    load_keymap(); /* need to load the keymap after the game has been started */
    ret = commandloop();
    free_keymap();
    close(fd);

    destroy_game_windows();
    cleanup_messages();
    game_ended(ret, filename);

    return TRUE;
}