Beispiel #1
0
/**
 * Find a default user name from the system.
 */
static void user_name(char *buf, size_t len, int id)
{
	struct passwd *pw = getpwuid(id);

	/* Default to PLAYER */
	if (!pw || !pw->pw_name || !pw->pw_name[0] ) {
		my_strcpy(buf, "PLAYER", len);
		return;
	}

	/* Copy and capitalise */
	my_strcpy(buf, pw->pw_name, len);
	my_strcap(buf);
}
Beispiel #2
0
/**
 * Build the object list.
 */
static void build_obj_list(int last, struct object **list, item_tester tester,
						   olist_detail_t mode)
{
	int i;
	struct object *obj;
	char buf[80];
	bool gold_ok = (mode & OLIST_GOLD) ? TRUE : FALSE;
	bool in_term = (mode & OLIST_WINDOW) ? TRUE : FALSE;
	bool show_empty = (mode & OLIST_SEMPTY) ? TRUE : FALSE;
	bool equip = list ? FALSE : TRUE;

	/* Build the object list */
	for (i = 0; i <= last; i++) {
		obj = equip ? slot_object(player, i) : list[i];

		/* Acceptable items get a label */
		if (object_test(tester, obj) ||	(obj && tval_is_money(obj) && gold_ok))
			strnfmt(items[num_obj].label, sizeof(items[num_obj].label), "%c) ",
					I2A(i));

		/* Unacceptable items are still sometimes shown */
		else if ((!obj && show_empty) || in_term)
			my_strcpy(items[num_obj].label, "   ",
					  sizeof(items[num_obj].label));

		/* Unacceptable items are skipped in the main window */
		else continue;

		/* Show full slot labels for equipment (or quiver in subwindow) */
		if (equip) {
			strnfmt(buf, sizeof(buf), "%-14s: ", equip_mention(player, i));
			my_strcap(buf);
			my_strcpy(items[num_obj].equip_label, buf,
					  sizeof(items[num_obj].equip_label));
		} else if (in_term && (list == player->upkeep->quiver)) {
			strnfmt(buf, sizeof(buf), "Slot %-9d: ", i);
			my_strcpy(items[num_obj].equip_label, buf,
					  sizeof(items[num_obj].equip_label));
		} else {
			strnfmt(items[num_obj].equip_label,
					sizeof(items[num_obj].equip_label), "");
		}

		/* Save the object */
		items[num_obj].object = obj;
		items[num_obj].key = (items[num_obj].label)[0];
		num_obj++;
	}
}
Beispiel #3
0
int main(int argc, char *argv[])
{
	int i;
	char name[256];

	Rand_value = time(NULL);

	for (i = 0; i < 20; i++) {
		randname_make(RANDNAME_TOLKIEN, 5, 9, name, 256, name_sections);
		my_strcap(name);
		printf("%s\n", name);
	}

	return 0;
}
Beispiel #4
0
/**
 * Get a spell from the player.
 */
int textui_get_spell(const char *verb, item_tester book_filter,
					 cmd_code cmd, const char *error,
					 bool (*spell_filter)(int spell_index))
{
	char prompt[1024];
	struct object *book;

	/* Create prompt */
	strnfmt(prompt, sizeof prompt, "%s which book?", verb);
	my_strcap(prompt);

	if (!get_item(&book, prompt, error,
				  cmd, book_filter, (USE_INVEN | USE_FLOOR)))
		return -1;

	return textui_get_spell_from_book(verb, book, error, spell_filter);
}
Beispiel #5
0
/**
 * Run the spell menu to select a spell.
 */
static int spell_menu_select(struct menu *m, const char *noun, const char *verb)
{
	struct spell_menu_data *d = menu_priv(m);
	char buf[80];

	screen_save();
	region_erase_bordered(&m->active);

	/* Format, capitalise and display */
	strnfmt(buf, sizeof buf, "%s which %s? ('?' to toggle description)",
			verb, noun);
	my_strcap(buf);
	prt(buf, 0, 0);

	menu_select(m, 0, TRUE);
	screen_load();

	return d->selected_spell;
}
Beispiel #6
0
/**
 * Show spell long description when browsing
 */
static void curse_menu_browser(int oid, void *data, const region *loc)
{
	struct curse_menu_data *choice = data;
	char buf[80];

	/* Redirect output to the screen */
	text_out_hook = text_out_to_screen;
	text_out_wrap = 0;
	text_out_indent = loc->col - 1;
	text_out_pad = 1;

	Term_gotoxy(loc->col, loc->row + loc->page_rows);
	my_strcpy(buf, curses[choice[oid].index].desc, sizeof(buf));
	my_strcap(buf);
	text_out(" %s.\n", buf);

	/* XXX */
	text_out_pad = 0;
	text_out_indent = 0;
}
Beispiel #7
0
/*
 * A "keypress" handling function for askfor_aux, that handles the special
 * case of '*' for a new random "name" and passes any other "keypress"
 * through to the default "editing" handler.
 */
static bool get_name_keypress(char *buf, size_t buflen, size_t *curs, size_t *len, struct keypress keypress, bool firsttime)
{
	bool result;

	switch (keypress.code)
	{
		case '*':
		{
			*len = randname_make(RANDNAME_TOLKIEN, 4, 8, buf, buflen, name_sections);
			my_strcap(buf);
			*curs = 0;
			result = FALSE;
			break;
		}

		default:
		{
			result = askfor_aux_keypress(buf, buflen, curs, len, keypress, firsttime);
			break;
		}
	}

	return result;
}
Beispiel #8
0
/**
 * Decreases a monster's hit points by `dam` and handle monster death.
 *
 * Hack -- we "delay" fear messages by passing around a "fear" flag.
 *
 * We announce monster death (using an optional "death message" (`note`)
 * if given, and a otherwise a generic killed/destroyed message).
 * 
 * Returns TRUE if the monster has been killed (and deleted).
 *
 * TODO: Consider decreasing monster experience over time, say, by using
 * "(m_exp * m_lev * (m_lev)) / (p_lev * (m_lev + n_killed))" instead
 * of simply "(m_exp * m_lev) / (p_lev)", to make the first monster
 * worth more than subsequent monsters.  This would also need to
 * induce changes in the monster recall code.  XXX XXX XXX
 **/
bool mon_take_hit(struct monster *m_ptr, int dam, bool *fear, const char *note)
{
	s32b div, new_exp, new_exp_frac;
	monster_lore *l_ptr = get_lore(m_ptr->race);


	/* Redraw (later) if needed */
	if (p_ptr->health_who == m_ptr) p_ptr->redraw |= (PR_HEALTH);

	/* Wake it up */
	mon_clear_timed(m_ptr, MON_TMD_SLEEP, MON_TMD_FLG_NOMESSAGE, FALSE);

	/* Become aware of its presence */
	if (m_ptr->unaware)
		become_aware(m_ptr);

	/* Hurt it */
	m_ptr->hp -= dam;

	/* It is dead now */
	if (m_ptr->hp < 0) {
		char m_name[80];
		char buf[80];

		/* Assume normal death sound */
		int soundfx = MSG_KILL;

		/* Play a special sound if the monster was unique */
		if (rf_has(m_ptr->race->flags, RF_UNIQUE)) {
			if (m_ptr->race->base == lookup_monster_base("Morgoth"))
				soundfx = MSG_KILL_KING;
			else
				soundfx = MSG_KILL_UNIQUE;
		}

		/* Extract monster name */
		monster_desc(m_name, sizeof(m_name), m_ptr, 0);

		/* Death by Missile/Spell attack */
		if (note) {
			/* Hack -- allow message suppression */
			if (strlen(note) <= 1) {
				/* Be silent */
			} else {
				char *str = format("%s%s", m_name, note);
				my_strcap(str);
				msgt(soundfx, "%s", str);
			}
		}

		/* Death by physical attack -- invisible monster */
		else if (!m_ptr->ml)
			msgt(soundfx, "You have killed %s.", m_name);

		/* Death by Physical attack -- non-living monster */
		else if (monster_is_unusual(m_ptr->race))
			msgt(soundfx, "You have destroyed %s.", m_name);

		/* Death by Physical attack -- living monster */
		else
			msgt(soundfx, "You have slain %s.", m_name);

		/* Player level */
		div = p_ptr->lev;

		/* Give some experience for the kill */
		new_exp = ((long)m_ptr->race->mexp * m_ptr->race->level) / div;

		/* Handle fractional experience */
		new_exp_frac = ((((long)m_ptr->race->mexp * m_ptr->race->level) % div)
		                * 0x10000L / div) + p_ptr->exp_frac;

		/* Keep track of experience */
		if (new_exp_frac >= 0x10000L) {
			new_exp++;
			p_ptr->exp_frac = (u16b)(new_exp_frac - 0x10000L);
		}
		else
			p_ptr->exp_frac = (u16b)new_exp_frac;

		/* When the player kills a Unique, it stays dead */
		if (rf_has(m_ptr->race->flags, RF_UNIQUE)) {
			char unique_name[80];
			m_ptr->race->max_num = 0;

			/* 
			 * This gets the correct name if we slay an invisible 
			 * unique and don't have See Invisible.
			 */
			monster_desc(unique_name, sizeof(unique_name), m_ptr, 
					MDESC_SHOW | MDESC_IND2);

			/* Log the slaying of a unique */
			strnfmt(buf, sizeof(buf), "Killed %s", unique_name);
			history_add(buf, HISTORY_SLAY_UNIQUE, 0);
		}

		/* Gain experience */
		player_exp_gain(p_ptr, new_exp);

		/* Generate treasure */
		monster_death(m_ptr, FALSE);

		/* Recall even invisible uniques or winners */
		if (m_ptr->ml || rf_has(m_ptr->race->flags, RF_UNIQUE)) {
			/* Count kills this life */
			if (l_ptr->pkills < MAX_SHORT) l_ptr->pkills++;

			/* Count kills in all lives */
			if (l_ptr->tkills < MAX_SHORT) l_ptr->tkills++;

			/* Hack -- Auto-recall */
			monster_race_track(m_ptr->race);
		}

		/* Delete the monster */
		delete_monster_idx(m_ptr->midx);

		/* Not afraid */
		(*fear) = FALSE;

		/* Monster is dead */
		return (TRUE);
	}


	/* Mega-Hack -- Pain cancels fear */
	if (!(*fear) && m_ptr->m_timed[MON_TMD_FEAR] && (dam > 0)) {
		int tmp = randint1(dam);

		/* Cure a little fear */
		if (tmp < m_ptr->m_timed[MON_TMD_FEAR]) {
			/* Reduce fear */
			mon_dec_timed(m_ptr, MON_TMD_FEAR, tmp, MON_TMD_FLG_NOMESSAGE,
				FALSE);
		}

		/* Cure all the fear */
		else {
			/* Cure fear */
			mon_clear_timed(m_ptr, MON_TMD_FEAR, MON_TMD_FLG_NOMESSAGE, FALSE);

			/* No more fear */
			(*fear) = FALSE;
		}
	}

	/* Sometimes a monster gets scared by damage */
	if (!m_ptr->m_timed[MON_TMD_FEAR] && !rf_has(m_ptr->race->flags, RF_NO_FEAR) &&
		dam > 0) {
		int percentage;

		/* Percentage of fully healthy */
		percentage = (100L * m_ptr->hp) / m_ptr->maxhp;

		/*
		 * Run (sometimes) if at 10% or less of max hit points,
		 * or (usually) when hit for half its current hit points
		 */
		if ((randint1(10) >= percentage) ||
		    ((dam >= m_ptr->hp) && (randint0(100) < 80)))
		{
			int timer = randint1(10) + (((dam >= m_ptr->hp) && (percentage > 7)) ?
	                   20 : ((11 - percentage) * 5));

			/* Hack -- note fear */
			(*fear) = TRUE;

			mon_inc_timed(m_ptr, MON_TMD_FEAR, timer,
					MON_TMD_FLG_NOMESSAGE | MON_TMD_FLG_NOFAIL, FALSE);
		}
	}


	/* Not dead yet */
	return (FALSE);
}
Beispiel #9
0
/**
 * Builds a string describing a monster in some way.
 *
 * We can correctly describe monsters based on their visibility.
 * We can force all monsters to be treated as visible or invisible.
 * We can build nominatives, objectives, possessives, or reflexives.
 * We can selectively pronominalize hidden, visible, or all monsters.
 * We can use definite or indefinite descriptions for hidden monsters.
 * We can use definite or indefinite descriptions for visible monsters.
 *
 * Pronominalization involves the gender whenever possible and allowed,
 * so that by cleverly requesting pronominalization / visibility, you
 * can get messages like "You hit someone.  She screams in agony!".
 *
 * Reflexives are acquired by requesting Objective plus Possessive.
 *
 * I am assuming that no monster name is more than 65 characters long,
 * so that "char desc[80];" is sufficiently large for any result, even
 * when the "offscreen" notation is added.
 *
 * Note that the "possessive" for certain unique monsters will look
 * really silly, as in "Morgoth, King of Darkness's".  We should
 * perhaps add a flag to "remove" any "descriptives" in the name.
 *
 * Note that "offscreen" monsters will get a special "(offscreen)"
 * notation in their name if they are visible but offscreen.  This
 * may look silly with possessives, as in "the rat's (offscreen)".
 * Perhaps the "offscreen" descriptor should be abbreviated.
 *
 * Mode Flags:
 *   0x01 --> Objective (or Reflexive)
 *   0x02 --> Possessive (or Reflexive)
 *   0x04 --> Use indefinites for hidden monsters ("something")
 *   0x08 --> Use indefinites for visible monsters ("a kobold")
 *   0x10 --> Pronominalize hidden monsters
 *   0x20 --> Pronominalize visible monsters
 *   0x40 --> Assume the monster is hidden
 *   0x80 --> Assume the monster is visible
 *  0x100 --> Capitalise monster name
 *
 * Useful Modes:
 *   0x00 --> Full nominative name ("the kobold") or "it"
 *   0x04 --> Full nominative name ("the kobold") or "something"
 *   0x80 --> Banishment resistance name ("the kobold")
 *   0x88 --> Killing name ("a kobold")
 *   0x22 --> Possessive, genderized if visable ("his") or "its"
 *   0x23 --> Reflexive, genderized if visable ("himself") or "itself"
 */
void monster_desc(char *desc, size_t max, const struct monster *mon, int mode)
{
	const char *choice;
	bool seen, use_pronoun;

	assert(mon);


	/* Can we "see" it (forced, or not hidden + visible) */
	seen = ((mode & (MDESC_SHOW)) || (!(mode & (MDESC_HIDE)) &&
									  mflag_has(mon->mflag, MFLAG_VISIBLE)));

	/* Sexed Pronouns (seen and forced, or unseen and allowed) */
	use_pronoun = ((seen && (mode & (MDESC_PRO_VIS))) ||
				   (!seen && (mode & (MDESC_PRO_HID))));


	/* First, try using pronouns, or describing hidden monsters */
	if (!seen || use_pronoun) {
		/* an encoding of the monster "sex" */
		int msex = 0x00;

		/* Extract the gender (if applicable) */
		if (rf_has(mon->race->flags, RF_FEMALE)) msex = 0x20;
		else if (rf_has(mon->race->flags, RF_MALE)) msex = 0x10;

		/* Ignore the gender (if desired) */
		if (!mon || !use_pronoun) msex = 0x00;


		/* Assume simple result */
		choice = "it";

		/* Brute force: split on the possibilities */
		switch (msex + (mode & 0x07)) {
			/* Neuter, or unknown */
			case 0x00: choice = "it"; break;
			case 0x01: choice = "it"; break;
			case 0x02: choice = "its"; break;
			case 0x03: choice = "itself"; break;
			case 0x04: choice = "something"; break;
			case 0x05: choice = "something"; break;
			case 0x06: choice = "something's"; break;
			case 0x07: choice = "itself"; break;

			/* Male (assume human if vague) */
			case 0x10: choice = "he"; break;
			case 0x11: choice = "him"; break;
			case 0x12: choice = "his"; break;
			case 0x13: choice = "himself"; break;
			case 0x14: choice = "someone"; break;
			case 0x15: choice = "someone"; break;
			case 0x16: choice = "someone's"; break;
			case 0x17: choice = "himself"; break;

			/* Female (assume human if vague) */
			case 0x20: choice = "she"; break;
			case 0x21: choice = "her"; break;
			case 0x22: choice = "her"; break;
			case 0x23: choice = "herself"; break;
			case 0x24: choice = "someone"; break;
			case 0x25: choice = "someone"; break;
			case 0x26: choice = "someone's"; break;
			case 0x27: choice = "herself"; break;
		}

		/* Copy the result */
		my_strcpy(desc, choice, max);
	} else if ((mode & MDESC_POSS) && (mode & MDESC_OBJE)) {
		/* The monster is visible, so use its gender */
		if (rf_has(mon->race->flags, RF_FEMALE))
			my_strcpy(desc, "herself", max);
		else if (rf_has(mon->race->flags, RF_MALE))
			my_strcpy(desc, "himself", max);
		else
			my_strcpy(desc, "itself", max);
	} else {
		/* Unique, indefinite or definite */
		if (rf_has(mon->race->flags, RF_UNIQUE)) {
			/* Start with the name (thus nominative and objective) */
			my_strcpy(desc, mon->race->name, max);
		} else if (mode & MDESC_IND_VIS) {
			/* XXX Check plurality for "some" */

			/* Indefinite monsters need an indefinite article */
			my_strcpy(desc, is_a_vowel(mon->race->name[0]) ? "an " : "a ", max);
			my_strcat(desc, mon->race->name, max);
		} else {
			/* Definite monsters need a definite article */
			my_strcpy(desc, "the ", max);
			my_strcat(desc, mon->race->name, max);
		}

		/* Handle the Possessive as a special afterthought */
		if (mode & MDESC_POSS) {
			/* XXX Check for trailing "s" */

			/* Simply append "apostrophe" and "s" */
			my_strcat(desc, "'s", max);
		}

		/* Mention "offscreen" monsters XXX XXX */
		if (!panel_contains(mon->fy, mon->fx)) {
			/* Append special notation */
			my_strcat(desc, " (offscreen)", max);
		}
	}

	if (mode & MDESC_CAPITAL)
		my_strcap(desc);
}