예제 #1
0
파일: options.c 프로젝트: FredrIQ/nhfourk
boolean
set_option(const char *name, union nh_optvalue value,
           struct newgame_options *ngo)
{
    struct nh_option_desc *option = NULL, *options = new_opt_struct();
    boolean ret = FALSE;

    /* can't change options for other players */
    if (program_state.followmode != FM_PLAY)
        goto free;

    if (options)
        option = nhlib_find_option(options, name);

    if (!option || (option->birth_option && program_state.game_running))
        goto free;

    if (!nhlib_option_value_ok(option, value))
        goto free;

    nhlib_copy_option_value(option, value);

    if (option->type == OPTTYPE_BOOL) {
        boolean *bvar = nhlib_find_boolopt(boolopt_map, option->name);

        if (!bvar) {
            impossible("no boolean for option '%s'", option->name);
            goto free;
        }
        *bvar = option->value.b;

        ret = TRUE;
        goto free;
    } else if (!strcmp("disclose", option->name)) {
        flags.end_disclose = option->value.e;
    } else if (!strcmp("fruit", option->name)) {
        strncpy(gamestate.fruits.curname, option->value.s, PL_FSIZ-1);
        gamestate.fruits.curname[PL_FSIZ - 1] = '\0';
        if (objects)    /* don't do fruitadd before the game is running */
            fruitadd(gamestate.fruits.curname);
    } else if (!strcmp("menustyle", option->name)) {
        flags.menu_style = option->value.e;
    } else if (!strcmp("movecommand", option->name)) {
        flags.interaction_mode = option->value.e;
    } else if (!strcmp("packorder", option->name)) {
        if (!change_inv_order(option->value.s))
            goto free;
    } else if (!strcmp("pickup_burden", option->name)) {
        flags.pickup_burden = option->value.e;
    } else if (!strcmp("autopickup_rules", option->name)) {
        if (flags.ap_rules) {
            free(flags.ap_rules->rules);
            free(flags.ap_rules);
            flags.ap_rules = NULL;
        }
        flags.ap_rules = nhlib_copy_autopickup_rules(option->value.ar);
    }
    /* birth options */
    else if (!strcmp("mode", option->name)) {
        flags.debug = (option->value.e == MODE_WIZARD);
        flags.explore = (option->value.e == MODE_EXPLORE);
        flags.challenge = (option->value.e == MODE_CHALLENGE);
    } else if (!strcmp("align", option->name)) {
        u.initalign = option->value.e;
    } else if (!strcmp("gender", option->name)) {
        u.initgend = option->value.e;
    } else if (!strcmp("race", option->name)) {
        u.initrace = option->value.e;
    } else if (!strcmp("role", option->name)) {
        u.initrole = option->value.e;
    }

    else if (!strcmp("name", option->name)) {
        strncpy(u.uplname, option->value.s, PL_NSIZ-1);
        (u.uplname)[PL_NSIZ - 1] = '\0';
    } else if (!strcmp("seed", option->name)) {
        /* note: does not NUL-terminate a max-length string, this is
           intentional */
        strncpy(flags.setseed, option->value.s, RNG_SEED_SIZE_BASE64);
    } else if (!strcmp("catname", option->name)) {
        if (!ngo)
            panic("catname set outside newgame sequence");
        strncpy(ngo->catname, option->value.s, PL_PSIZ-1);
        ngo->catname[PL_PSIZ - 1] = '\0';
    } else if (!strcmp("dogname", option->name)) {
        if (!ngo)
            panic("dogname set outside newgame sequence");
        strncpy(ngo->dogname, option->value.s, PL_PSIZ-1);
        ngo->dogname[PL_PSIZ - 1] = '\0';
    } else if (!strcmp("horsename", option->name)) {
        if (!ngo)
            panic("horsename set outside newgame sequence");
        strncpy(ngo->horsename, option->value.s, PL_PSIZ-1);
        ngo->horsename[PL_PSIZ - 1] = '\0';
    } else if (!strcmp("pettype", option->name)) {
        if (!ngo)
            panic("preferred_pet set outside newgame sequence");
        ngo->preferred_pet = (char)option->value.e;
    } else if (!strcmp("timezone", option->name)) {
        flags.timezone = option->value.e;
    } else if (!strcmp("polyinit", option->name)) {
        flags.polyinit_mnum = option->value.e;
    }

    else
        /* unrecognized option */
        goto free;

    /* assume that any recognized option has been handled. */
    ret = TRUE;

free:
    nhlib_free_optlist(options);

    return ret;
}
예제 #2
0
파일: options.c 프로젝트: FredrIQ/nhfourk
struct nh_option_desc *
nh_get_options(void)
{
    struct nh_option_desc *options = new_opt_struct();

    /* Outside of a game, don't attempt to recover options from state; all
       options should have default values. */
    if (!program_state.game_running)
        return options;

    struct nh_option_desc *option;
    for (option = options; option->name; ++option) {
        if (option->type == OPTTYPE_BOOL) {
            boolean *bvar = nhlib_find_boolopt(boolopt_map, option->name);

            if (!bvar) {
                impossible("no boolean for option '%s'", option->name);
                continue;
            }

            option->value.b = *bvar;
        }

        else if (!strcmp("disclose", option->name)) {
            option->value.e = flags.end_disclose;
        } else if (!strcmp("fruit", option->name)) {
            if (option->value.s)
                free(option->value.s);
            option->value.s = malloc(PL_FSIZ);

            strncpy(option->value.s, gamestate.fruits.curname, PL_FSIZ-1);
            option->value.s[PL_FSIZ - 1] = '\0';

        } else if (!strcmp("menustyle", option->name)) {
            option->value.e = flags.menu_style;
        } else if (!strcmp("movecommand", option->name)) {
            option->value.e = flags.interaction_mode;
        } else if (!strcmp("packorder", option->name)) {

            int i;

            if (option->value.s)
                free(option->value.s);

            option->value.s = malloc(MAXOCLASSES + 1);
            for (i = 0; i < MAXOCLASSES; ++i)
                option->value.s[i] = def_oc_syms[(int)flags.inv_order[i]];

            option->value.s[MAXOCLASSES] = '\0';

        } else if (!strcmp("pickup_burden", option->name)) {
            option->value.e = flags.pickup_burden;
        } else if (!strcmp("autopickup_rules", option->name)) {
            if (option->value.ar) {
                free(option->value.ar->rules);
                free(option->value.ar);
            }
            option->value.ar = nhlib_copy_autopickup_rules(flags.ap_rules);
        } else if (!strcmp("mode", option->name)) {
            option->value.e =
                flags.debug ? MODE_WIZARD :
                flags.explore ? MODE_EXPLORE :
                flags.challenge ? MODE_CHALLENGE : MODE_NORMAL;
        } else if (!strcmp("timezone", option->name)) {
            option->value.e = flags.timezone;
        } else if (!strcmp("polyinit", option->name)) {
            option->value.e = flags.polyinit_mnum;
        } else if (!strcmp("align", option->name)) {
            option->value.e = u.initalign;
        } else if (!strcmp("gender", option->name)) {
            option->value.e = u.initgend;
        } else if (!strcmp("race", option->name)) {
            option->value.e = u.initrace;
        } else if (!strcmp("role", option->name)) {
            option->value.e = u.initrole;
        } else if (!strcmp("name", option->name)) {

            if (option->value.s)
                free(option->value.s);
            option->value.s = malloc(PL_NSIZ);

            strncpy(option->value.s, u.uplname, PL_NSIZ-1);
            option->value.s[PL_NSIZ - 1] = '\0';

        } else if (!strcmp("seed", option->name)) {

            if (option->value.s)
                free(option->value.s);
            option->value.s = malloc(RNG_SEED_SIZE_BASE64 + 1);

            strncpy(option->value.s, flags.setseed, RNG_SEED_SIZE_BASE64);
            option->value.s[RNG_SEED_SIZE_BASE64] = '\0';

        } else if (!strcmp("catname", option->name) ||
                   !strcmp("dogname", option->name) ||
                   !strcmp("horsename", option->name)) {
            /* The client shouldn't be doing this, but we can't crash in
               response because that would be exploitable. Send it a null
               string instead. */
            if (option->value.s)
                free(option->value.s);
            option->value.s = malloc(1);
            option->value.s[0] = '\0';
        } else if (!strcmp("pettype", option->name)) {
            /* As the previous case, just we want an enum not a string. */
            option->value.e = 0;
        } else {
            impossible("unknown option '%s'", option->name);
            memset(&option->value, 0, sizeof option->value);
        }
    }

    return options;
}
예제 #3
0
nh_bool
curses_set_option(const char *name, union nh_optvalue value)
{
    nh_bool game_option = FALSE;
    struct nh_option_desc *option = nhlib_find_option(curses_options, name);

    if (!option) {
        if (game_is_running)
            return nh_set_option(name, value);

        /* If the game is not running, update our local copy of options. */
        if (!nh_options || !(option = nhlib_find_option(nh_options, name))) {
            return FALSE;
        }
        game_option = TRUE;
    }

    if ((int)option->type == OPTTYPE_KEYMAP) {
        return FALSE;
    }

    if (!nhlib_option_value_ok(option, value))
        return FALSE;

    nhlib_copy_option_value(option, value);

    if (game_option)
        return TRUE;

    /* In case the option affects graphics; this is pretty cheap if we don't do
       it every turn */
    mark_mapwin_for_full_refresh();

    if (option->type == OPTTYPE_BOOL) {
        nh_bool *var = nhlib_find_boolopt(boolopt_map, option->name);
        if (!var) {
            curses_impossible("missing boolean option");
            return FALSE;
        }

        *var = value.b;

        if (!strcmp(option->name, "status3")) {
            rebuild_ui();
        } else if (!strcmp(option->name, "darkgray")) {
            set_darkgray();
            draw_map(player.x, player.y);
        } else if (!strcmp(option->name, "mouse")) {
            uncursed_enable_mouse(option->value.b);
        }
    } else if (!strcmp(option->name, "comment")) {
        /* do nothing */
    } else if (!strcmp(option->name, "tileset")) {
        if (settings.tileset)
            free(settings.tileset);
        settings.tileset = malloc(strlen(option->value.s) + 1);
        strcpy(settings.tileset, option->value.s);
        rebuild_ui();
    } else if (!strcmp(option->name, "border")) {
        settings.whichframes = option->value.e;
        rebuild_ui();
    } else if (!strcmp(option->name, "menu_headings")) {
        settings.menu_headings = option->value.e;
    } else if (!strcmp(option->name, "palette")) {
        settings.palette = option->value.e;
        setup_palette();

        if (ui_flags.initialized) {
            /*
             * - We don't want to install a palette as a result of the default
             *   setting of "palette", because some terminals cannot handle a
             *   palette reset, and thus we need to ensure that we've loaded
             *   the user's palette setting before palette initialization.
             *
             * - Besides, clear() will crash with an uninitialized libuncursed.
             *   So we have to delay this anyway.
             */
            clear();
            refresh();
            rebuild_ui();
        }
    } else if (!strcmp(option->name, "animation")) {
        settings.animation = option->value.e;
    } else if (!strcmp(option->name, "sidebar")) {
        settings.sidebar = option->value.e;
        rebuild_ui();
    } else if (!strcmp(option->name, "scores_top")) {
        settings.end_top = option->value.i;
    } else if (!strcmp(option->name, "scores_around")) {
        settings.end_around = option->value.i;
    } else if (!strcmp(option->name, "networkmotd")) {
        settings.show_motd = option->value.e;
    } else if (!strcmp(option->name, "menupaging")) {
        settings.menupaging = option->value.e;
    } else if (!strcmp(option->name, "optstyle")) {
        settings.optstyle = option->value.e;
    } else if (!strcmp(option->name, "msgheight")) {
        settings.msgheight = option->value.i;
        rebuild_ui();
    } else if (!strcmp(option->name, "msghistory")) {
        settings.msghistory = option->value.i;
        alloc_hist_array();
    }
    else
        return FALSE;

    return TRUE;
}