Example #1
0
File: skills.c Project: jcubic/ToME
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);
}
Example #2
0
/*
 * 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);
}
Example #3
0
File: skills.c Project: jcubic/ToME
/*
 * 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);
}