void do_get_new_skill() { char *items[4]; s32b skl[4]; s32b val[4], mod[4]; bool *used; s32b *available_skills; s32b max = 0, max_a = 0, res, i; C_MAKE(used, max_s_idx, bool); C_MAKE(available_skills, max_s_idx, s32b); /* Check if some skills didn't influence other stuff */ recalc_skills(TRUE); /* Grab the ones we can gain */ max = 0; for (i = 0; i < max_s_idx; i++) { if (has_flag(&s_info[i], FLAG_RANDOM_GAIN)) available_skills[max++] = i; } available_skills[max++] = -1; /* Init */ for (max = 0; max < max_s_idx; max++) { used[max] = FALSE; } /* Count the number of available skills */ while (available_skills[max_a] != -1) max_a++; /* Get 4 skills */ for (max = 0; max < 4; max++) { s32b i; skill_type *s_ptr; /* Get an non used skill */ do { i = rand_int(max_a); /* Does it pass the check? */ if (!magik(get_flag(&s_info[i], FLAG_RANDOM_GAIN))) continue; } while (used[available_skills[i]]); s_ptr = &s_info[available_skills[i]]; used[available_skills[i]] = TRUE; if (s_ptr->mod) { if (s_ptr->mod < 500) { val[max] = s_ptr->mod * 1; mod[max] = 100; if (mod[max] + s_ptr->mod > 500) mod[max] = 500 - s_ptr->mod; } else { val[max] = s_ptr->mod * 3; mod[max] = 0; } } else { mod[max] = 300; val[max] = 1000; } if (s_ptr->value + val[max] > SKILL_MAX) val[max] = SKILL_MAX - s_ptr->value; skl[max] = available_skills[i]; items[max] = (char *)string_make(format("%-40s: +%02ld.%03ld value, +%01d.%03d modifier", s_ptr->name, val[max] / SKILL_STEP, val[max] % SKILL_STEP, mod[max] / SKILL_STEP, mod[max] % SKILL_STEP)); } while (TRUE) { res = ask_menu("Choose a skill to learn(a-d to choose, ESC to cancel)?", (char **)items, 4); /* Ok ? lets learn ! */ if (res > -1) { skill_type *s_ptr; bool oppose = FALSE; s32b oppose_skill = -1; /* Check we don't oppose an existing skill */ for (i = 0; i < max_s_idx; i++) { if ((flag_get(&s_info[i].action, skl[res]) == SKILL_EXCLUSIVE) && (s_info[i].value != 0)) { oppose = TRUE; oppose_skill = i; break; } } /* Ok we oppose, so be sure */ if (oppose) { cptr msg; /* * Because this is SO critical a question, we must flush * input to prevent killing character off -- pelpel */ flush(); /* Prepare prompt */ msg = format("This skill is mutually exclusive with " "at least %s, continue?", s_info[oppose_skill].name); /* The player rejected the choice */ if (!get_check(msg)) continue; } s_ptr = &s_info[skl[res]]; s_ptr->value += val[res]; s_ptr->mod += mod[res]; if (mod[res]) { msg_format("You can now learn the %s skill.", s_ptr->name); } else { msg_format("Your knowledge of the %s skill increases.", s_ptr->name); } break; } } /* Free them ! */ for (max = 0; max < 4; max++) { string_free(items[max]); } /* Check if some skills didn't influence other stuff */ recalc_skills(FALSE); C_FREE(used, max_s_idx, bool); C_FREE(available_skills, max_s_idx, s32b); }
/* * Interreact with skills */ void do_cmd_skill() { int sel = 0, start = 0, max; char c; int table[MAX_SKILLS][2]; int i; int wid, hgt; s16b skill_points_save; s32b *skill_values_save; s32b *skill_mods_save; s16b *skill_rates_save; s16b *skill_invest; s32b *skill_bonus; recalc_skills(TRUE); /* Save the screen */ screen_save(); /* Allocate arrays to save skill values */ C_MAKE(skill_values_save, MAX_SKILLS, s32b); C_MAKE(skill_mods_save, MAX_SKILLS, s32b); C_MAKE(skill_rates_save, MAX_SKILLS, s16b); C_MAKE(skill_invest, MAX_SKILLS, s16b); C_MAKE(skill_bonus, MAX_SKILLS, s32b); /* Save skill points */ skill_points_save = p_ptr->skill_points; /* Save skill values */ for (i = 0; i < max_s_idx; i++) { skill_type *s_ptr = &s_info[i]; skill_values_save[i] = s_ptr->value; skill_mods_save[i] = s_ptr->mod; skill_rates_save[i] = s_ptr->rate; skill_invest[i] = 0; } /* Clear the screen */ Term_clear(); /* Initialise the skill list */ init_table(table, &max, FALSE); while (TRUE) { Term_get_size(&wid, &hgt); /* Display list of skills */ recalc_skills_theory(skill_invest, skill_values_save, skill_mods_save, skill_bonus); print_skills(table, max, sel, start); /* Wait for user input */ c = inkey(); /* Leave the skill screen */ if (c == ESCAPE) break; /* Expand / collapse list of skills */ else if (c == '\r') { if (s_info[table[sel][0]].dev) s_info[table[sel][0]].dev = FALSE; else s_info[table[sel][0]].dev = TRUE; init_table(table, &max, FALSE); } /* Next page */ else if (c == 'n') { sel += (hgt - 7); if (sel >= max) sel = max - 1; } /* Previous page */ else if (c == 'p') { sel -= (hgt - 7); if (sel < 0) sel = 0; } /* Select / increase a skill */ else { int dir; /* Allow use of numpad / arrow keys / roguelike keys */ dir = get_keymap_dir(c); /* Move cursor down */ if (dir == 2) sel++; /* Move cursor up */ if (dir == 8) sel--; /* Miscellaneous skills cannot be increased/decreased as a group */ if (table[sel][0] == SKILL_MISC) continue; /* Increase the current skill */ if (dir == 6) increase_skill(table[sel][0], skill_invest); /* Decrease the current skill */ if (dir == 4) decrease_skill(table[sel][0], skill_invest); /* XXX XXX XXX Wizard mode commands outside of wizard2.c */ /* Increase the skill */ if (wizard && (c == '+')) skill_bonus[table[sel][0]] += SKILL_STEP; /* Decrease the skill */ if (wizard && (c == '-')) skill_bonus[table[sel][0]] -= SKILL_STEP; /* Contextual help */ if (c == '?') exec_lua(format("ingame_help('select_context', 'skill', '%s')", s_info[table[sel][0]].name + s_name)); ; /* Handle boundaries and scrolling */ if (sel < 0) sel = max - 1; if (sel >= max) sel = 0; if (sel < start) start = sel; if (sel >= start + (hgt - 7)) start = sel - (hgt - 7) + 1; } } /* Some skill points are spent */ if (p_ptr->skill_points != skill_points_save) { /* Flush input as we ask an important and irreversible question */ flush(); /* Ask we can commit the change */ if (msg_box("Save and use these skill values? (y/n)", (int)(hgt / 2), (int)(wid / 2)) != 'y') { /* User declines -- restore the skill values before exiting */ /* Restore skill points */ p_ptr->skill_points = skill_points_save; /* Restore skill values */ for (i = 0; i < max_s_idx; i++) { skill_type *s_ptr = &s_info[i]; s_ptr->value = skill_values_save[i]; s_ptr->mod = skill_mods_save[i]; s_ptr->rate = skill_rates_save[i]; } } } /* Free arrays to save skill values */ C_FREE(skill_values_save, MAX_SKILLS, s32b); C_FREE(skill_mods_save, MAX_SKILLS, s32b); C_FREE(skill_rates_save, MAX_SKILLS, s16b); C_FREE(skill_invest, MAX_SKILLS, s16b); C_FREE(skill_bonus, MAX_SKILLS, s32b); /* Load the screen */ screen_load(); recalc_skills(FALSE); }
/* * Interreact with skills */ void do_cmd_skill() { s32b sel = 0, start = 0, max, max_ab = 0; s32b c; s32b **table, *table_ab; s32b i; s32b wid, hgt; s16b skill_points_save; s32b *skill_values_save; s32b *skill_mods_save; s16b *skill_rates_save; s16b *skill_invest; s32b *skill_bonus; bool *ab_learned; recalc_skills(TRUE); /* Save the screen */ screen_save(); /* Allocate arrays to save skill values */ C_MAKE(table, max_s_idx, s32b*); for (i = 0; i < max_s_idx; i++) C_MAKE(table[i], 2, s32b); C_MAKE(skill_values_save, max_s_idx, s32b); C_MAKE(skill_mods_save, max_s_idx, s32b); C_MAKE(skill_rates_save, max_s_idx, s16b); C_MAKE(skill_invest, max_s_idx, s16b); C_MAKE(skill_bonus, max_s_idx, s32b); /* Initialise the abilities list */ C_MAKE(ab_learned, max_ab_idx, s32b); C_MAKE(table_ab, max_ab_idx, s32b); for (i = 0; i < max_ab_idx; i++) { ab_learned[i] = ab_info[i].acquired; if (ab_info[i].name && (wizard || (!ab_info[i].hidden && show_ability(i)))) add_sorted_ability(table_ab, &max_ab, i); } /* Save skill points */ skill_points_save = p_ptr->skill_points; /* Save skill values */ for (i = 0; i < max_s_idx; i++) { skill_type *s_ptr = &s_info[i]; skill_values_save[i] = s_ptr->value; skill_mods_save[i] = s_ptr->mod; skill_rates_save[i] = s_ptr->rate; skill_invest[i] = 0; } /* Clear the screen */ Term_clear(); /* Initialise the skill list */ init_table(table, &max, FALSE); if (max) max++; if (max_ab) max_ab++; if (max > 1) sel = 1; while (TRUE) { Term_get_size(&wid, &hgt); /* Display list of skills */ recalc_skills_theory(skill_invest, skill_values_save, skill_mods_save, skill_bonus); print_all(table, max, table_ab, max_ab, sel, start); /* Wait for user input */ c = inkey(); /* Leave the skill screen */ if (c == ESCAPE) break; /* Expand / collapse list of skills */ else if ((sel < max) && (sel != 0) && (c == '\r')) { if (s_info[table[sel-1][0]].dev) s_info[table[sel-1][0]].dev = FALSE; else s_info[table[sel-1][0]].dev = TRUE; init_table(table, &max, FALSE); max++; } /* Next page */ else if (c == 'n') { sel += (hgt - 7); if (sel >= max + max_ab) sel = max + max_ab - 1; } /* Previous page */ else if (c == 'p') { sel -= (hgt - 7); if (sel < 0) sel = 0; } /* Select / increase a skill */ else { s32b dir; /* Allow use of numpad / arrow keys / roguelike keys */ dir = get_keymap_dir(c); /* Move cursor down */ if (dir == 2) sel++; /* Move cursor up */ if (dir == 8) sel--; if (sel == 0 || sel == max) { // Nothing } else if (sel < max) { /* Increase the current skill */ if (dir == 6) increase_skill(table[sel-1][0], skill_invest); /* Decrease the current skill */ if (dir == 4) decrease_skill(table[sel-1][0], skill_invest); /* XXX XXX XXX Wizard mode commands outside of wizard2.c */ /* Increase the skill */ if (wizard && (c == '+')) skill_bonus[table[sel-1][0]] += SKILL_STEP; /* Decrease the skill */ if (wizard && (c == '-')) skill_bonus[table[sel-1][0]] -= SKILL_STEP; /* Contextual help */ if (c == '?') exec_lua(format("ingame_help('select_context', 'skill', '%s')", s_info[table[sel-1][0]].name)); } else { /* Gain ability */ if (dir == 6) gain_ability(table_ab[sel-1 - max]); if (dir == 4) ungain_ability(table_ab[sel-1 - max], ab_learned[table_ab[sel-1 - max]]); /* XXX XXX XXX Wizard mode commands outside of wizard2.c */ if (wizard && (c == '+')) ab_info[table_ab[sel-1 - max]].acquired = TRUE; if (wizard && (c == '-')) ab_info[table_ab[sel-1 - max]].acquired = FALSE; /* Contextual help */ if (c == '?') exec_lua(format("ingame_help('select_context', 'ability', '%s')", ab_info[table_ab[sel-1 - max]].name)); } /* Handle boundaries and scrolling */ if (sel < 0) sel = max + max_ab - 1; /* Just in case the skill and ability list is empty */ if (sel < 0) sel = 0; if (sel >= max + max_ab) sel = 0; if (sel < start) start = sel; if (sel >= start + (hgt - 7)) start = sel - (hgt - 7) + 1; } } /* Some skill points are spent */ if (p_ptr->skill_points != skill_points_save) { /* Flush input as we ask an important and irreversible question */ flush(); /* Ask we can commit the change */ if (msg_box("Save and use these skill values? (y/n)", (s32b)(hgt / 2), (s32b)(wid / 2)) != 'y') { /* User declines -- restore the skill values before exiting */ /* Restore skill points */ p_ptr->skill_points = skill_points_save; /* Restore skill values */ for (i = 0; i < max_s_idx; i++) { skill_type *s_ptr = &s_info[i]; s_ptr->value = skill_values_save[i]; s_ptr->mod = skill_mods_save[i]; s_ptr->rate = skill_rates_save[i]; } /* Restore abilities */ for (i = 0; i < max_ab_idx; i++) { ab_info[i].acquired = ab_learned[i]; } } } /* Free arrays to save skill values */ C_FREE(skill_values_save, max_s_idx, s32b); C_FREE(skill_mods_save, max_s_idx, s32b); C_FREE(skill_rates_save, max_s_idx, s16b); C_FREE(skill_invest, max_s_idx, s16b); C_FREE(skill_bonus, max_s_idx, s32b); for (i = 0; i < max_s_idx; i++) C_FREE(table[i], 2, s32b); C_FREE(table, max_s_idx, s32b*); C_FREE(ab_learned, max_ab_idx, s32b); C_FREE(table_ab, max_ab_idx, s32b); /* Load the screen */ screen_load(); recalc_skills(FALSE); }