Ejemplo n.º 1
0
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;
}
Ejemplo n.º 2
0
static boolean
set_option(const char *name, union nh_optvalue value, boolean isstring)
{
    boolean is_ui = FALSE;
    struct nh_option_desc *option = NULL;

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

    if (!option && !program_state.game_running && birth_options)
        option = find_option(birth_options, name);

    if (!option && ui_options) {
        option = find_option(ui_options, name);
        is_ui = TRUE;
    }

    if (!option)
        return FALSE;

    /* if this option change affects game options (!is_ui) and happens during a 
       replay (program_state.viewing) and the change isn't triggered by the
       replay (!program_state.restoring) */
    if (!is_ui && program_state.viewing && !program_state.restoring)
        return FALSE;   /* Nope, sorry. That would mess up the replay */

    if (isstring)
        value = string_to_optvalue(option, value.s);

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

    if (copy_option_value(option, value) && !is_ui)
        log_option(option);     /* prev value != new value */

    if (option->type == OPTTYPE_BOOL) {
        int i;
        boolean *bvar = NULL;
        const struct nh_boolopt_map *boolmap = boolopt_map;

        if (is_ui)
            boolmap = ui_boolopt_map;

        for (i = 0; boolmap[i].optname && !bvar; i++)
            if (!strcmp(option->name, boolmap[i].optname))
                bvar = boolmap[i].addr;

        if (!bvar)
            /* shouldn't happen */
            return FALSE;

        *bvar = option->value.b;
        if (is_ui && ui_option_callback)
            /* allow the ui to "see" changes to booleans, but the return value
               doesn't mattter as the option was set here. */
            ui_option_callback(option);
        return TRUE;
    } else if (is_ui)
        return ui_option_callback(option);
    /* regular non-boolean options */
    else if (!strcmp("comment", option->name)) {
        /* do nothing */
    } else if (!strcmp("disclose", option->name)) {
        flags.end_disclose = option->value.e;
    } else if (!strcmp("fruit", option->name)) {
        strncpy(pl_fruit, option->value.s, PL_FSIZ);
        if (objects)    /* don't do fruitadd before the game is running */
            fruitadd(pl_fruit);
    } else if (!strcmp("menustyle", option->name)) {
        flags.menu_style = option->value.e;
    } else if (!strcmp("packorder", option->name)) {
        if (!change_inv_order(option->value.s))
            return FALSE;
    } else if (!strcmp("pickup_burden", option->name)) {
        flags.pickup_burden = option->value.e;
    } else if (!strcmp("runmode", option->name)) {
        iflags.runmode = option->value.e;
    } else if (!strcmp("autopickup_rules", option->name)) {
        if (iflags.ap_rules) {
            free(iflags.ap_rules->rules);
            free(iflags.ap_rules);
            iflags.ap_rules = NULL;
        }
        iflags.ap_rules = copy_autopickup_rules(option->value.ar);
    }
    /* birth options */
    else if (!strcmp("align", option->name)) {
        flags.init_align = option->value.e;
    } else if (!strcmp("gender", option->name)) {
        flags.init_gend = option->value.e;
    } else if (!strcmp("race", option->name)) {
        flags.init_race = option->value.e;
    } else if (!strcmp("role", option->name)) {
        flags.init_role = option->value.e;
    }

    else if (!strcmp("catname", option->name)) {
        strncpy(catname, option->value.s, PL_PSIZ);
    } else if (!strcmp("dogname", option->name)) {
        strncpy(dogname, option->value.s, PL_PSIZ);
    } else if (!strcmp("horsename", option->name)) {
        strncpy(horsename, option->value.s, PL_PSIZ);
    } else if (!strcmp("pettype", option->name)) {
        preferred_pet = (char)option->value.e;
    }

    else
        /* unrecognized option */
        return FALSE;

    /* assume that any recognized option has been handled. */
    return TRUE;
}