static void show_autopickup_menu(struct nh_option_desc *opt) { struct nh_menuitem *items; int i, j, n, icount, size, menusize, parts, selected[1], id; struct nh_autopickup_rule *r; char buf[BUFSZ]; struct nh_autopickup_rule *rule; union nh_optvalue value; /* clone autopickup rules */ value.ar = malloc(sizeof(struct nh_autopickup_rules)); value.ar->num_rules = 0; value.ar->rules = NULL; if (opt->value.ar){ value.ar->num_rules = opt->value.ar->num_rules; size = value.ar->num_rules * sizeof(struct nh_autopickup_rule); value.ar->rules = malloc(size); memcpy(value.ar->rules, opt->value.ar->rules, size); } menusize = value.ar->num_rules + 4; items = malloc(sizeof(struct nh_menuitem) * menusize); selected[0] = 0; do { icount = 0; add_menu_txt(items, menusize, icount, "Pos\tRule\tAction", MI_HEADING); /* list the rules in human-readable form */ for (i = 0; i < value.ar->num_rules; i++) { r = &value.ar->rules[i]; parts = 0; sprintf(buf, "%2d.\tIF ", i+1); if (strlen(r->pattern)) { parts++; sprintf(buf + strlen(buf), "name matches \"%s\"", r->pattern); } if (r->oclass != OCLASS_ANY) { char *classname = NULL; for (j = 0; j < opt->a.numclasses && !classname; j++) if (opt->a.classes[j].id == r->oclass) classname = opt->a.classes[j].caption; if (parts++) strcat(buf, " AND "); sprintf(buf + strlen(buf), "type is \"%s\"", classname); } if (r->buc != B_DONT_CARE) { if (parts++) strcat(buf, " AND "); sprintf(buf + strlen(buf), "beatitude is %s", bucnames[r->buc]); } if (!parts) sprintf(buf, "%2d.\teverything", i+1); if (r->action == AP_GRAB) sprintf(buf + strlen(buf), ":\t< GRAB"); else sprintf(buf + strlen(buf), ":\t LEAVE >"); add_menu_item(items, menusize, icount, i+1, buf, 0, 0); } add_menu_txt(items, menusize, icount, "", MI_TEXT); add_menu_item(items, menusize, icount, -1, "add a new rule", '!', 0); add_menu_item(items, menusize, icount, -2, "help", '?', 0); /* If the previous selection was to add a rule, scroll to the bottom now * so that the player can see it. */ if (selected[0] == -1) { n = curses_display_menu_bottom(items, icount, "Autopickup rules:", PICK_ONE, selected); } else { n = curses_display_menu(items, icount, "Autopickup rules:", PICK_ONE, selected); } if (n <= 0) break; /* add or edit a rule */ id = selected[0]; if (id == -1) { /* create a new rule */ id = value.ar->num_rules; value.ar->num_rules++; size = value.ar->num_rules * sizeof(struct nh_autopickup_rule); value.ar->rules = realloc(value.ar->rules, size); rule = &value.ar->rules[id]; rule->pattern[0] = '\0'; rule->oclass = OCLASS_ANY; rule->buc = B_DONT_CARE; rule->action = AP_GRAB; } else if (id == -2) { autopickup_rules_help(); continue; } else id--; edit_ap_rule(&opt->a, value.ar, id); } while (n > 0); nh_set_option(opt->name, value, FALSE); free(value.ar->rules); free(value.ar); free(items); }
static void show_autopickup_menu(struct nh_option_desc *opt) { struct nh_menulist menu; int i, j, parts, selected[1], id; struct nh_autopickup_rule *r; char buf[BUFSZ]; struct nh_autopickup_rule *rule; union nh_optvalue value; /* clone autopickup rules */ value.ar = malloc(sizeof (struct nh_autopickup_rules)); value.ar->num_rules = 0; value.ar->rules = NULL; if (opt->value.ar) { int size; value.ar->num_rules = opt->value.ar->num_rules; size = value.ar->num_rules * sizeof (struct nh_autopickup_rule); value.ar->rules = malloc(size); memcpy(value.ar->rules, opt->value.ar->rules, size); } do { init_menulist(&menu); add_menu_txt(&menu, "Pos\tRule\tAction", MI_HEADING); /* list the rules in human-readable form */ for (i = 0; i < value.ar->num_rules; i++) { r = &value.ar->rules[i]; parts = 0; snprintf(buf, ARRAY_SIZE(buf), "%2d.\tIF ", i + 1); if (strlen(r->pattern)) { parts++; sprintf(buf + strlen(buf), "name matches \"%s\"", r->pattern); } if (r->oclass != OCLASS_ANY) { const char *classname = NULL; for (j = 0; j < opt->a.numclasses && !classname; j++) if (opt->a.classes[j].id == r->oclass) classname = opt->a.classes[j].caption; if (parts++) strcat(buf, " AND "); sprintf(buf + strlen(buf), "type is \"%s\"", classname); } if (r->buc != B_DONT_CARE) { if (parts++) strcat(buf, " AND "); sprintf(buf + strlen(buf), "beatitude is %s", bucnames[r->buc]); } if (!parts) snprintf(buf, ARRAY_SIZE(buf), "%2d.\teverything", i + 1); if (r->action == AP_GRAB) sprintf(buf + strlen(buf), ":\t< GRAB"); else sprintf(buf + strlen(buf), ":\t LEAVE >"); add_menu_item(&menu, i + 1, buf, 0, 0); } add_menu_txt(&menu, "", MI_TEXT); add_menu_item(&menu, -1, "add a new rule", '!', 0); add_menu_item(&menu, -2, "help", '?', 0); /* TODO */ curses_display_menu(&menu, "Autopickup rules:", PICK_ONE, PLHINT_RIGHT, selected, curses_menu_callback); if (*selected == CURSES_MENU_CANCELLED) break; /* add or edit a rule */ id = selected[0]; if (id == -1) { int size; /* create a new rule */ id = value.ar->num_rules; value.ar->num_rules++; size = value.ar->num_rules * sizeof (struct nh_autopickup_rule); value.ar->rules = realloc(value.ar->rules, size); rule = &value.ar->rules[id]; memset(rule->pattern, 0, sizeof(rule->pattern)); rule->oclass = OCLASS_ANY; rule->buc = B_DONT_CARE; rule->action = AP_GRAB; } else if (id == -2) { autopickup_rules_help(); continue; } else id--; edit_ap_rule(&opt->a, value.ar, id); } while (1); curses_set_option(opt->name, value); free(value.ar->rules); free(value.ar); }