Пример #1
0
void get_spell_info(int tval, int spell, char *p, size_t len)
{
	/* Blank 'p' first */
	p[0] = '\0';

	/* Mage spells */
	if (tval == TV_MAGIC_BOOK)
	{
		int plev = p_ptr->lev;

		/* Analyze the spell */
		switch (spell)
		{
		case SPELL_MAGIC_MISSILE:
			strnfmt(p, len, " dam %dd4", 3 + ((plev - 1) / 5));
			break;
		case SPELL_PHASE_DOOR:
			strnfmt(p, len, " range 10");
			break;
		case SPELL_LIGHT_AREA:
			strnfmt(p, len, " dam 2d%d", (plev / 2));
			break; 
		case SPELL_CURE_LIGHT_WOUNDS:
			strnfmt(p, len, " heal 15%%");
			break;
		case SPELL_STINKING_CLOUD:
			strnfmt(p, len, " dam %d", 10 + (plev / 2));
			break;
		case SPELL_LIGHTNING_BOLT:
			strnfmt(p, len, " dam %dd6", (3 + ((plev - 5) / 6)));
			break;
		case SPELL_FROST_BOLT:
			strnfmt(p, len, " dam %dd8", (5 + ((plev - 5) / 4)));
			break;
		case SPELL_ACID_BOLT:
			strnfmt(p, len, " dam %dd8", (8 + ((plev - 5) / 4)));
			break;
		case SPELL_FIRE_BOLT:
			strnfmt(p, len, " dam %dd8", (6 + ((plev - 5) / 4)));
			break;
		case SPELL_SPEAR_OF_LIGHT:
			strnfmt(p, len, " dam 6d8");
			break;
		case SPELL_HEROISM:
			strnfmt(p, len, " dur 25+d25");
			break;
		case SPELL_BERSERKER:
			strnfmt(p, len, " dur 25+d25");
			break;
		case SPELL_HASTE_SELF:
			strnfmt(p, len, " dur %d+d20", plev);
			break;
		case SPELL_TELEPORT_SELF:
			strnfmt(p, len, " range %d", plev * 5);
			break;
		case SPELL_SHOCK_WAVE:
			strnfmt(p, len, " dam %d", 10 + plev);
			break;
		case SPELL_EXPLOSION:
			strnfmt(p, len, " dam %d", 20 + plev * 2);
			break;
		case SPELL_CLOUD_KILL:
			strnfmt(p, len, " dam %d", 40 + (plev / 2));
			break;
		case SPELL_REND_SOUL:
			strnfmt(p, len, " dam 11d%d", plev);
			break;
		case SPELL_CHAOS_STRIKE:
			strnfmt(p, len, " dam 13d%d", plev);
			break;
		case SPELL_RESIST_COLD:
			strnfmt(p, len, " dur 20+d20");
			break;
		case SPELL_RESIST_FIRE:
			strnfmt(p, len, " dur 20+d20");
			break;
		case SPELL_RESIST_POISON:
			strnfmt(p, len, " dur 20+d20");
			break;
		case SPELL_RESISTANCE:
			strnfmt(p, len, " dur 20+d20");
			break;
		case SPELL_SHIELD:
			strnfmt(p, len, " dur 30+d20");
			break;
		case SPELL_FROST_BALL:
			strnfmt(p, len, " dam %d", 30 + plev);
			break;
		case SPELL_ACID_BALL:
			strnfmt(p, len, " dam %d", 40 + plev);
			break;
		case SPELL_FIRE_BALL:
			strnfmt(p, len, " dam %d", 55 + plev);
			break;
		case SPELL_ICE_STORM:
			strnfmt(p, len, " dam %d", 50 + (plev * 2));
			break;
		case SPELL_METEOR_SWARM:
			strnfmt(p, len, " dam %dx%d", 30 + plev / 2, 2 + plev / 20);
			break;
		case SPELL_RIFT:
			strnfmt(p, len, " dam 40+%dd7", plev);
			break;
		case SPELL_MANA_STORM:
			strnfmt(p, len, " dam %d", 300 + plev * 2);
			break;
		}
	}

	/* Priest spells */
	if (tval == TV_PRAYER_BOOK)
	{
		int plev = p_ptr->lev;

		/* Analyze the spell */
		switch (spell)
		{
			case PRAYER_CURE_LIGHT_WOUNDS:
				my_strcpy(p, " heal 15%", len);
				break;
			case PRAYER_BLESS:
				my_strcpy(p, " dur 12+d12", len);
				break;
			case PRAYER_CALL_LIGHT:
				strnfmt(p, len, " dam 2d%d", (plev / 2));
				break; 
			case PRAYER_PORTAL:
				strnfmt(p, len, " range %d", 3 * plev);
				break;
			case PRAYER_CURE_SERIOUS_WOUNDS:
				my_strcpy(p, " heal 20%", len);
				break;
			case PRAYER_CHANT:
				my_strcpy(p, " dur 24+d24", len);
				break;
			case PRAYER_RESIST_HEAT_COLD:
				my_strcpy(p, " dur 10+d10", len);
				break;
			case PRAYER_ORB_OF_DRAINING:
				strnfmt(p, len, " %d+3d6", plev +
				        (player_has(PF_ZERO_FAIL) 
						? (plev / 2)
						: (plev / 4)));
				break;
			case PRAYER_CURE_CRITICAL_WOUNDS:
				my_strcpy(p, " heal 25%", len);
				break;
			case PRAYER_SENSE_INVISIBLE:
				my_strcpy(p, " dur 24+d24", len);
				break;
			case PRAYER_PROTECTION_FROM_EVIL:
				strnfmt(p, len, " dur %d+d25", 3 * plev);
				break;
			case PRAYER_CURE_MORTAL_WOUNDS:
				my_strcpy(p, " heal 30%", len);
				break;
			case PRAYER_PRAYER:
				my_strcpy(p, " dur 48+d48", len);
				break;
			case PRAYER_DISPEL_UNDEAD:
				strnfmt(p, len, " dam d%d", 3 * plev);
				break;
			case PRAYER_HEAL:
				my_strcpy(p, " heal 35%", len);
				break;
			case PRAYER_DISPEL_EVIL:
				strnfmt(p, len, " dam d%d", 3 * plev);
				break;
			case PRAYER_HOLY_WORD:
				my_strcpy(p, " heal 1000", len);
				break;
			case PRAYER_CURE_SERIOUS_WOUNDS2:
				my_strcpy(p, " heal 20%", len);
				break;
			case PRAYER_CURE_MORTAL_WOUNDS2:
				my_strcpy(p, " heal 30%", len);
				break;
			case PRAYER_HEALING:
				my_strcpy(p, " heal 2000", len);
				break;
			case PRAYER_DISPEL_UNDEAD2:
				strnfmt(p, len, " dam d%d", 4 * plev);
				break;
			case PRAYER_DISPEL_EVIL2:
				strnfmt(p, len, " dam d%d", 4 * plev);
				break;
			case PRAYER_ANNIHILATION:
				my_strcpy(p, " dam 200", len);
				break;
			case PRAYER_BLINK:
				my_strcpy(p, " range 10", len);
				break;
			case PRAYER_TELEPORT_SELF:
				strnfmt(p, len, " range %d", 8 * plev);
				break;
		}
	}

	return;
}
Пример #2
0
/*
 * Recursive file perusal.
 *
 * Return FALSE on "?", otherwise TRUE.
 *
 * This function could be made much more efficient with the use of "seek"
 * functionality, especially when moving backwards through a file, or
 * forwards through a file by less than a page at a time.  XXX XXX XXX
 */
bool show_file(cptr name, cptr what, int line, int mode)
{
	int i, k, n;

	char ch;

	/* Number of "real" lines passed by */
	int next = 0;

	/* Number of "real" lines in the file */
	int size;

	/* Backup value for "line" */
	int back = 0;

	/* This screen has sub-screens */
	bool menu = FALSE;

	/* Case sensitive search */
	bool case_sensitive = FALSE;

	/* Current help file */
	ang_file *fff = NULL;

	/* Find this string (if any) */
	char *find = NULL;

	/* Jump to this tag */
	cptr tag = NULL;

	/* Hold a string to find */
	char finder[80] = "";

	/* Hold a string to show */
	char shower[80] = "";

	/* Filename */
	char filename[1024];

	/* Describe this thing */
	char caption[128] = "";

	/* Path buffer */
	char path[1024];

	/* General buffer */
	char buf[1024];

	/* Lower case version of the buffer, for searching */
	char lc_buf[1024];

	/* Sub-menu information */
	char hook[26][32];

	int wid, hgt;



	/* Wipe the hooks */
	for (i = 0; i < 26; i++) hook[i][0] = '\0';

	/* Get size */
	Term_get_size(&wid, &hgt);

	/* Copy the filename */
	my_strcpy(filename, name, sizeof(filename));

	n = strlen(filename);

	/* Extract the tag from the filename */
	for (i = 0; i < n; i++)
	{
		if (filename[i] == '#')
		{
			filename[i] = '\0';
			tag = filename + i + 1;
			break;
		}
	}

	/* Redirect the name */
	name = filename;


	/* Hack XXX XXX XXX */
	if (what)
	{
		my_strcpy(caption, what, sizeof(caption));

		my_strcpy(path, name, sizeof(path));
		fff = file_open(path, MODE_READ, -1);
	}

	/* Look in "help" */
	if (!fff)
	{
		strnfmt(caption, sizeof(caption), "Help file '%s'", name);

		path_build(path, sizeof(path), reposband_DIR_HELP, name);
		fff = file_open(path, MODE_READ, -1);
	}

	/* Look in "info" */
	if (!fff)
	{
		strnfmt(caption, sizeof(caption), "Info file '%s'", name);

		path_build(path, sizeof(path), reposband_DIR_INFO, name);
		fff = file_open(path, MODE_READ, -1);
	}

	/* Oops */
	if (!fff)
	{
		/* Message */
		msg_format("Cannot open '%s'.", name);
		message_flush();

		/* Oops */
		return (TRUE);
	}


	/* Pre-Parse the file */
	while (TRUE)
	{
		/* Read a line or stop */
		if (!file_getl(fff, buf, sizeof(buf))) break;

		/* XXX Parse "menu" items */
		if (prefix(buf, "***** "))
		{
			char b1 = '[', b2 = ']';

			/* Notice "menu" requests */
			if ((buf[6] == b1) && isalpha((unsigned char)buf[7]) &&
			    (buf[8] == b2) && (buf[9] == ' '))
			{
				/* This is a menu file */
				menu = TRUE;

				/* Extract the menu item */
				k = A2I(buf[7]);

				/* Store the menu item (if valid) */
				if ((k >= 0) && (k < 26))
					my_strcpy(hook[k], buf + 10, sizeof(hook[0]));
			}
			/* Notice "tag" requests */
			else if (buf[6] == '<')
			{
				if (tag)
				{
					/* Remove the closing '>' of the tag */
					buf[strlen(buf) - 1] = '\0';

					/* Compare with the requested tag */
					if (streq(buf + 7, tag))
					{
						/* Remember the tagged line */
						line = next;
					}
				}
			}

			/* Skip this */
			continue;
		}

		/* Count the "real" lines */
		next++;
	}

	/* Save the number of "real" lines */
	size = next;



	/* Display the file */
	while (TRUE)
	{
		/* Clear screen */
		Term_clear();


		/* Restrict the visible range */
		if (line > (size - (hgt - 4))) line = size - (hgt - 4);
		if (line < 0) line = 0;


		/* Re-open the file if needed */
		if (next > line)
		{
			/* Close it */
			file_close(fff);

			/* Hack -- Re-Open the file */
			fff = file_open(path, MODE_READ, -1);
			if (!fff) return (TRUE);

			/* File has been restarted */
			next = 0;
		}


		/* Goto the selected line */
		while (next < line)
		{
			/* Get a line */
			if (!file_getl(fff, buf, sizeof(buf))) break;

			/* Skip tags/links */
			if (prefix(buf, "***** ")) continue;

			/* Count the lines */
			next++;
		}


		/* Dump the next lines of the file */
		for (i = 0; i < hgt - 4; )
		{
			/* Hack -- track the "first" line */
			if (!i) line = next;

			/* Get a line of the file or stop */
			if (!file_getl(fff, buf, sizeof(buf))) break;

			/* Hack -- skip "special" lines */
			if (prefix(buf, "***** ")) continue;

			/* Count the "real" lines */
			next++;

			/* Make a copy of the current line for searching */
			my_strcpy(lc_buf, buf, sizeof(lc_buf));

			/* Make the line lower case */
			if (!case_sensitive) string_lower(lc_buf);

			/* Hack -- keep searching */
			if (find && !i && !strstr(lc_buf, find)) continue;

			/* Hack -- stop searching */
			find = NULL;

			/* Dump the line */
			Term_putstr(0, i+2, -1, TERM_WHITE, buf);

			/* Highlight "shower" */
			if (shower[0])
			{
				cptr str = lc_buf;

				/* Display matches */
				while ((str = strstr(str, shower)) != NULL)
				{
					int len = strlen(shower);

					/* Display the match */
					Term_putstr(str-lc_buf, i+2, len, TERM_YELLOW, &buf[str-lc_buf]);

					/* Advance */
					str += len;
				}
			}

			/* Count the printed lines */
			i++;
		}

		/* Hack -- failed search */
		if (find)
		{
			bell("Search string not found!");
			line = back;
			find = NULL;
			continue;
		}


		/* Show a general "title" */
		prt(format("[%s %s, %s, Line %d-%d/%d]", VERSION_NAME, VERSION_STRING,
		           caption, line, line + hgt - 4, size), 0, 0);


		/* Prompt -- menu screen */
		if (menu)
		{
			/* Wait for it */
			prt("[Press a Number, or ESC to exit.]", hgt - 1, 0);
		}

		/* Prompt -- small files */
		else if (size <= hgt - 4)
		{
			/* Wait for it */
			prt("[Press ESC to exit.]", hgt - 1, 0);
		}

		/* Prompt -- large files */
		else
		{
			/* Wait for it */
			prt("[Press Space to advance, or ESC to exit.]", hgt - 1, 0);
		}

		/* Get a keypress */
		ch = inkey();

		/* Exit the help */
		if (ch == '?') break;

		/* Toggle case sensitive on/off */
		if (ch == '!')
		{
			case_sensitive = !case_sensitive;
		}

		/* Try showing */
		if (ch == '&')
		{
			/* Get "shower" */
			prt("Show: ", hgt - 1, 0);
			(void)askfor_aux(shower, sizeof(shower), NULL);

			/* Make the "shower" lowercase */
			if (!case_sensitive) string_lower(shower);
		}

		/* Try finding */
		if (ch == '/')
		{
			/* Get "finder" */
			prt("Find: ", hgt - 1, 0);
			if (askfor_aux(finder, sizeof(finder), NULL))
			{
				/* Find it */
				find = finder;
				back = line;
				line = line + 1;

				/* Make the "finder" lowercase */
				if (!case_sensitive) string_lower(finder);

				/* Show it */
				my_strcpy(shower, finder, sizeof(shower));
			}
		}

		/* Go to a specific line */
		if (ch == '#')
		{
			char tmp[80] = "0";

			prt("Goto Line: ", hgt - 1, 0);
			if (askfor_aux(tmp, sizeof(tmp), NULL))
				line = atoi(tmp);
		}

		/* Go to a specific file */
		if (ch == '%')
		{
			char ftmp[80] = "help.hlp";

			prt("Goto File: ", hgt - 1, 0);
			if (askfor_aux(ftmp, sizeof(ftmp), NULL))
			{
				if (!show_file(ftmp, NULL, 0, mode))
					ch = ESCAPE;
			}
		}

		/* Back up one line */
		if (ch == ARROW_UP || ch == '8')
		{
			line = line - 1;
		}

		/* Back up one full page */
		if ((ch == '9') || (ch == '-'))
		{
			line = line - (hgt - 4);
		}

		/* Back to the top */
		if (ch == '7')
		{
			line = 0;
		}

		/* Advance one line */
		if ((ch == ARROW_DOWN) || (ch == '2') || (ch == '\n') || (ch == '\r'))
		{
			line = line + 1;
		}

		/* Advance one full page */
		if ((ch == '3') || (ch == ' '))
		{
			line = line + (hgt - 4);
		}

		/* Advance to the bottom */
		if (ch == '1')
		{
			line = size;
		}

		/* Recurse on letters */
		if (menu && isalpha((unsigned char)ch))
		{
			/* Extract the requested menu item */
			k = A2I(ch);

			/* Verify the menu item */
			if ((k >= 0) && (k <= 25) && hook[k][0])
			{
				/* Recurse on that file */
				if (!show_file(hook[k], NULL, 0, mode)) ch = ESCAPE;
			}
		}

		/* Exit on escape */
		if (ch == ESCAPE) break;
	}

	/* Close the file */
	file_close(fff);

	/* Done */
	return (ch != '?');
}
Пример #3
0
/*
 * Apply special system-specific processing before dealing with a filename.
 */
static void path_parse(char *buf, size_t max, const char *file)
{
	/* Accept the filename */
	my_strcpy(buf, file, max);
}
Пример #4
0
/*
 * Identify a character, allow recall of monsters
 *
 * Several "special" responses recall "multiple" monsters:
 *   ^A (all monsters)
 *   ^U (all unique monsters)
 *   ^N (all non-unique monsters)
 *
 * The responses may be sorted in several ways, see below.
 *
 * Note that the player ghosts are ignored, since they do not exist.
 */
void do_cmd_query_symbol(void)
{
	int i, n, r_idx;
	char buf[128];

	struct keypress sym;
	struct keypress query;

	bool all = FALSE;
	bool uniq = FALSE;
	bool norm = FALSE;

	bool recall = FALSE;

	u16b *who;

	/* Get a character, or abort */
	if (!get_com("Enter character to be identified, or control+[ANU]: ", &sym))
		return;

	/* Describe */
	if (sym.code == KTRL('A'))
	{
		all = TRUE;
		my_strcpy(buf, "Full monster list.", sizeof(buf));
	}
	else if (sym.code == KTRL('U'))
	{
		all = uniq = TRUE;
		my_strcpy(buf, "Unique monster list.", sizeof(buf));
	}
	else if (sym.code == KTRL('N'))
	{
		all = norm = TRUE;
		my_strcpy(buf, "Non-unique monster list.", sizeof(buf));
	}
	else
	{
		lookup_symbol(sym, buf, sizeof(buf));
	}

	/* Display the result */
	prt(buf, 0, 0);

	/* Allocate the "who" array */
	who = C_ZNEW(z_info->r_max, u16b);

	/* Collect matching monsters */
	for (n = 0, i = 1; i < z_info->r_max - 1; i++)
	{
		monster_race *r_ptr = &r_info[i];
		monster_lore *l_ptr = &l_list[i];

		/* Nothing to recall */
		if (!OPT(cheat_know) && !l_ptr->sights) continue;

		/* Require non-unique monsters if needed */
		if (norm && rf_has(r_ptr->flags, RF_UNIQUE)) continue;

		/* Require unique monsters if needed */
		if (uniq && !rf_has(r_ptr->flags, RF_UNIQUE)) continue;

		/* Collect "appropriate" monsters */
		if (all || (r_ptr->d_char == (char)sym.code)) who[n++] = i;
	}

	/* Nothing to recall */
	if (!n)
	{
		/* XXX XXX Free the "who" array */
		FREE(who);

		return;
	}

	/* Buttons */
	button_add("[y]", 'y');
	button_add("[k]", 'k');
	/* Don't collide with the repeat button */
	button_add("[n]", 'q'); 
	redraw_stuff(p_ptr);

	/* Prompt */
	put_str("Recall details? (y/k/n): ", 0, 40);

	/* Query */
	query = inkey();

	/* Restore */
	prt(buf, 0, 0);

	/* Buttons */
	button_kill('y');
	button_kill('k');
	button_kill('q');
	redraw_stuff(p_ptr);

	/* Interpret the response */
	if (query.code == 'k')
	{
		/* Sort by kills (and level) */
		sort(who, n, sizeof(*who), cmp_pkill);
	}
	else if (query.code == 'y' || query.code == 'p')
	{
		/* Sort by level; accept 'p' as legacy */
		sort(who, n, sizeof(*who), cmp_level);
	}
	else
	{
		/* Any unsupported response is "nope, no history please" */
	
		/* XXX XXX Free the "who" array */
		FREE(who);

		return;
	}

	/* Start at the end */
	i = n - 1;

	/* Button */
	button_add("[r]", 'r');
	button_add("[-]", '-');
	button_add("[+]", '+');
	redraw_stuff(p_ptr);

	/* Scan the monster memory */
	while (1)
	{
		/* Extract a race */
		r_idx = who[i];

		/* Hack -- Auto-recall */
		monster_race_track(r_idx);

		/* Hack -- Handle stuff */
		handle_stuff(p_ptr);

		/* Hack -- Begin the prompt */
		roff_top(r_idx);

		/* Hack -- Complete the prompt */
		Term_addstr(-1, TERM_WHITE, " [(r)ecall, ESC]");

		/* Interact */
		while (1)
		{
			/* Recall */
			if (recall)
			{
				/* Save screen */
				screen_save();

				/* Recall on screen */
				screen_roff(who[i]);

				/* Hack -- Complete the prompt (again) */
				Term_addstr(-1, TERM_WHITE, " [(r)ecall, ESC]");
			}

			/* Command */
			query = inkey();

			/* Unrecall */
			if (recall)
			{
				/* Load screen */
				screen_load();
			}

			/* Normal commands */
			if (query.code != 'r') break;

			/* Toggle recall */
			recall = !recall;
		}

		/* Stop scanning */
		if (query.code == ESCAPE) break;

		/* Move to "prev" monster */
		if (query.code == '-')
		{
			if (++i == n)
				i = 0;
		}

		/* Move to "next" monster */
		else
		{
			if (i-- == 0)
				i = n - 1;
		}
	}

	/* Button */
	button_kill('r');
	button_kill('-');
	button_kill('+');
	redraw_stuff(p_ptr);

	/* Re-display the identity */
	prt(buf, 0, 0);

	/* Free the "who" array */
	FREE(who);
}
Пример #5
0
/*
 * Simple "main" function for multiple platforms.
 *
 * Note the special "--" option which terminates the processing of
 * standard options.  All non-standard options (if any) are passed
 * directly to the "init_xxx()" function.
 */
int main(int argc, char *argv[])
{
	int i;

	bool done = FALSE;

	const char *mstr = NULL;

	bool args = TRUE;


	/* Save the "program name" XXX XXX XXX */
	argv0 = argv[0];


#ifdef SET_UID

	/* Default permissions on files */
	(void)umask(022);

#endif /* SET_UID */


	/* Get the file paths */
	init_stuff();


#ifdef SET_UID

	/* Get the user id */
	player_uid = getuid();

	/* Save the effective GID for later recall */
	player_egid = getegid();

#endif /* SET_UID */


	/* Drop permissions */
	safe_setuid_drop();


#ifdef SET_UID

	/* Get the "user name" as a default player name */
	user_name(op_ptr->full_name, sizeof(op_ptr->full_name), player_uid);

	/* Create any missing directories */
	create_needed_dirs();

#endif /* SET_UID */


	/* Process the command line arguments */
	for (i = 1; args && (i < argc); i++)
	{
		cptr arg = argv[i];

		/* Require proper options */
		if (*arg++ != '-') goto usage;

		/* Analyze option */
		switch (*arg++)
		{
			case 'N':
			case 'n':
			{
				new_game = TRUE;
				break;
			}

			case 'W':
			case 'w':
			{
				arg_wizard = TRUE;
				break;
			}

			case 'R':
			case 'r':
			{
				arg_rebalance = TRUE;
				break;
			}

			case 'G':
			case 'g':
			{
				/* Default graphics tile */
				arg_graphics = GRAPHICS_ADAM_BOLT;
				break;
			}

			case 'u':
			case 'U':
			{
				if (!*arg) goto usage;

				/* Get the savefile name */
				my_strcpy(op_ptr->full_name, arg, sizeof(op_ptr->full_name));
				continue;
			}

			case 'm':
			case 'M':
			{
				if (!*arg) goto usage;
				mstr = arg;
				continue;
			}

			case 'd':
			case 'D':
			{
				change_path(arg);
				continue;
			}

			case '-':
			{
				argv[i] = argv[0];
				argc = argc - i;
				argv = argv + i;
				args = FALSE;
				break;
			}

			default:
			usage:
			{
				/* Dump usage information */
				puts("Usage: angband [options] [-- subopts]");
				puts("  -n             Start a new character");
				puts("  -L             Load a new-format save file");
				puts("  -w             Resurrect dead character (marks savefile)");
				puts("  -r             Rebalance monsters if monster.raw is absent");
				puts("  -g             Request graphics mode");
				puts("  -u<who>        Use your <who> savefile");
				puts("  -d<path>       Store pref files and screendumps in <path>");
				puts("  -m<sys>        Use module <sys>, where <sys> can be:");

				/* Print the name and help for each available module */
				for (i = 0; i < (int)N_ELEMENTS(modules); i++)
				{
					printf("     %s   %s\n",
					       modules[i].name, modules[i].help);
				}

				/* Actually abort the process */
				quit(NULL);
			}
		}
		if (*arg) goto usage;
	}

	/* Hack -- Forget standard args */
	if (args)
	{
		argc = 1;
		argv[1] = NULL;
	}


	/* Try the modules in the order specified by modules[] */
	for (i = 0; i < (int)N_ELEMENTS(modules); i++)
	{
		/* User requested a specific module? */
		if (!mstr || (streq(mstr, modules[i].name)))
		{
			if (0 == modules[i].init(argc, argv))
			{
				ANGBAND_SYS = modules[i].name;
				done = TRUE;
				break;
			}
		}
	}

	/* Make sure we have a display! */
	if (!done) quit("Unable to prepare any 'display module'!");


	/* Process the player name */
	process_player_name(TRUE);

	/* Install "quit" hook */
	quit_aux = quit_hook;

#ifdef USE_SOUND

	/* Try the modules in the order specified by sound_modules[] */
	for (i = 0; i < (int)N_ELEMENTS(sound_modules) - 1; i++)
	{
		if (0 == sound_modules[i].init(argc, argv))
			break;
	}

#endif


	/* Catch nasty signals */
	signals_init();

	/* Set up the command hook */
	cmd_get_hook = default_get_cmd;

	/* Set up the display handlers and things. */
	init_display();

	/* Play the game */
	play_game();

	/* Free resources */
	cleanup_angband();

	/* Quit */
	quit(NULL);

	/* Exit */
	return (0);
}
Пример #6
0
void dir_test(){
    struct inode* root_inode;
    struct inode *rip;
    char string[DIRSIZ];
    int number;
    int * inode_num = & number;
    int r;

    root_inode = get_inode(1);
    if(root_inode == NIL_INODE){
        printf("root_inode is a null inode\n");
        return;
    }
    /* printf("root_inode size is %d\n", root_inode->i_size); */
    /* delete_dir(root_inode, 0); */
    /* empty_inode_space(root_inode); */
    /* put_inode(root_inode); */
    /* return; */

    /* my_strcpy(string, "usr"); */
    /* if( r = search_dir(root_inode, string, inode_num, LOOK_UP) != OK){ */
        /* printf("LOOK_UP a usr error: %s\n", strerror(r)); */
        /* put_inode(root_inode); */
        /* return; */
    /* } */
    /* printf("this time i node size is %d\n", root_inode->i_size); */
    /* put_inode(root_inode); */
    /* return; */

    my_strcpy(string, "..");
    *inode_num = root_inode->i_num;
    if (r = search_dir(root_inode, string, inode_num, ENTER) != OK){
        printf("enter a item error: %s\n", strerror(r));
        put_inode(root_inode);
        return;
    }
    my_strcpy(string, ".");
    *inode_num = root_inode->i_num;
    if (r = search_dir(root_inode, string, inode_num, ENTER) != OK){
        printf("enter a item error: %s\n", strerror(r));
        put_inode(root_inode);
        return;
    }
    root_inode->i_dirt = DIRTY;
    put_inode(root_inode);
    show_file_list();
    /* return; */
    printf("\n");

    my_strcpy(string, ".");
    root_inode = get_inode(1);
    *inode_num = 0;
    if (r = search_dir(root_inode, string, inode_num, LOOK_UP) != OK){
        printf("find a item error: %s\n", strerror(r));
        put_inode(root_inode);
        return;
    }
    if(*inode_num != root_inode->i_num){
        printf("can't find . in the root directory!!!\n");
        put_inode(root_inode);
        return;
    }
    put_inode(root_inode);

    my_mkdir("./usr");
    my_mkdir("src");
    my_mkdir("../root");
    show_file_list();
    printf("\n");

    root_inode = last_dir("./../usr", string);
    if(root_inode == NIL_INODE){
        printf("last_dir error: can't find root dir\n");
        return;
    }
    if(root_inode->i_num != 1){
        printf("this time last dir is not root_inode, it's i_num is %d\n", root_inode->i_num);
        put_inode(root_inode);
        return;
    }
    printf("string remain is %s\n", string);
    show_file_list();
    printf("\n");
    rip = advance(root_inode, string);
    if(rip == NIL_INODE){
        printf("advance error: can't find usr dir\n");
        return;
    }
    show_file_list();
    printf("\n");
    put_inode(rip);
    put_inode(root_inode);

    if(my_rmdir("/src") != OK){
        printf("can't remove dir src\n");
        return;
    }
    show_file_list();
}
Пример #7
0
/**
 * Hack -- change name
 */
void do_cmd_change_name(void)
{
  ui_event ke;
  
  int col = 0;
  int last_line = 0;
  int top_line = 0;

  const char *p;

  /* Prompt */
  p = "['c' change name, 'f' to file, scroll, or ESC]";
  
  /* Save screen */
  screen_save();

  /* Adjust the buttons */
  button_backup_all();
  button_kill_all();
  button_add("ESC", ESCAPE);
  button_add("Spc", ' ');
  button_add("-", '-');
  button_add("c", 'c');
  button_add("f", 'f');
  button_add("->", ARROW_RIGHT);
  button_add("<-", ARROW_LEFT);
  p_ptr->redraw |= PR_BUTTONS;

  /* Make the array of lines */
  C_WIPE(dumpline, DUMP_MAX_LINES, char_attr_line);
  last_line = make_dump(dumpline, 2);

  /* Forever */
  while (1)
    {
      /* Display the player */
      display_dump(dumpline, top_line, top_line + Term->hgt - 1, col);

      redraw_stuff(p_ptr);

      /* Clear the bottom line */
      prt("", Term->hgt - 1, 0);
      
      /* Prompt */
      Term_putstr(0, Term->hgt - 1, -1, TERM_WHITE, p);
     
      /* Query */
      ke = inkey_ex();
      
      /* Exit */
      if (ke.key.code == ESCAPE) break;
      
      /* Change name */
      if (ke.key.code == 'c')
        {
	  char namebuf[32] = "";

	  if (get_name(namebuf, sizeof namebuf))
	  {
	      /* Set player name */
	      my_strcpy(op_ptr->full_name, namebuf,
			sizeof(op_ptr->full_name));
	      
	      /* Don't change savefile name. */
	      process_player_name(FALSE);
	  }
	  //(void) get_name(namebuf, sizeof namebuf);
	  (void) make_dump(dumpline, 2);
        }
      
      /* File dump */
      else if (ke.key.code == 'f')
	{
	  char ftmp[80];
	  
	  strnfmt(ftmp, sizeof ftmp, "%s.txt", op_ptr->base_name);
	  
	  if (get_string("File name: ", ftmp, 80))
	    {
	      if (ftmp[0] && (ftmp[0] != ' '))
		{
		  if (file_character(ftmp, dumpline, last_line))
		    msg("Character dump failed!");
		  else
		    msg("Character dump successful.");
		}
	    }
	}
      
      /* Scroll down */
      else if (ke.key.code == ARROW_DOWN)
	{
	  if (top_line + Term->hgt - 2 < last_line)
	    top_line++;
	}
      
      /* Page down */
      else if (ke.key.code == ' ')
	{
	  top_line = MIN(last_line - Term->hgt + 2, 
			 top_line + (Term->hgt - 2));
	}
      
      /* Scroll up */
      else if (ke.key.code == ARROW_UP)
	{
	  if (top_line)
	    top_line--;
	}
      
      /* Page up */
      else if (ke.key.code == '-')
	{
	  top_line -= (Term->hgt - 2) / 2;
	  if (top_line < 0) top_line = 0;
	}
      
      /* Scroll left */
      else if (ke.key.code == ARROW_LEFT)
	{
	  if (col)
	    col--;
	}
      
      /* Scroll right */
      else if (ke.key.code == ARROW_RIGHT)
	{
	  if (col < 32)
	    col++;
	}
      
      
      /* Oops */
      else
	{
	  bell(NULL);
	}
      
      /* Flush messages */
      message_flush();
    }

  /* Adjust the buttons */
  button_restore();

  /* Load screen */
  screen_load();
}
Пример #8
0
/* 
 * Build the object list.  Note that only the equipment has first non-zero. 
 */
static void build_obj_list(int first, int last, const int *floor_list, 
			   olist_detail_t mode)
{
    int i;
    object_type *o_ptr;
    bool in_term = (mode & OLIST_WINDOW) ? TRUE : FALSE;

    need_spacer = FALSE;
    offset = 0;
    num_obj = 0;

    /* Clear the existing contents */
    for (i = 0; i < 50; i++)
    {
	items[i].object = NULL;
	items[i].index = 0;
	items[i].key = '\0';
	my_strcpy(items[i].label, "", sizeof(items[i].label));
    }

    /* Leave top line clear for inventory subwindow */
    if (!first && !floor_list && in_term) 
	offset = 1;
    
    for (i = first; i <= last; i++)
    {
	if (floor_list)
	    o_ptr = &o_list[floor_list[i]];
	else
	    o_ptr = &p_ptr->inventory[i];

	/* May need a blank line to separate equipment and quiver */
	if ((i == INVEN_TOTAL) && (first))
	{
	    int j;
	    
	    /* Scan the rest of the items for acceptable entries */
	    for (j = i; j <= last; j++)
	    {
		o_ptr = &p_ptr->inventory[j];
		if (item_tester_okay(o_ptr)) need_spacer = TRUE;
	    }

	    continue;
	}

	/* Tester always skips gold. When gold should be displayed,
	 * only test items that are not gold.
	 */
	if (((o_ptr->tval == TV_GOLD) && (mode & OLIST_GOLD)) ||
	    item_tester_okay(o_ptr)) 
	    strnfmt(items[num_obj].label, sizeof(items[num_obj].label), "%c) ", 
		    index_to_label(i));
		
	/* Unacceptable carried items are still displayed in term windows */
	else if ((in_term) && (!floor_list))
	    my_strcpy(items[num_obj].label, "   ", 
		      sizeof(items[num_obj].label));

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

	/* Special labels for equipment */
	if (first){
	    char tmp_val[80];

	    /* Show full slot labels */
	    if (OPT(show_labels))
	    {
		strnfmt(tmp_val, sizeof(tmp_val), "%-14s: ", mention_use(i));
		my_strcat(items[num_obj].label, tmp_val, 
			  sizeof(items[num_obj].label));
	    }

	    /* Otherwise only show short quiver labels */
	    else if (i >= QUIVER_START)
	    {
		strnfmt(tmp_val, sizeof(tmp_val), "[f%d]: ", i - QUIVER_START);
		my_strcat(items[num_obj].label, tmp_val, 
			  sizeof(items[num_obj].label));
	    }
	}

	/* Save the object */
	items[num_obj].object = o_ptr;
	items[num_obj].index = i;
	items[num_obj].key = (items[num_obj].label)[0];
	num_obj++;
    }
}
Пример #9
0
/*
 * Display an object.  Each object may be prefixed with a label.
 * Used by show_inven(), show_equip(), and show_floor().  Mode flags are
 * documented in object.h
 */
static void show_obj(int onum, size_t max_len, char label[80],
		     const object_type *object, bool cursor,
		     olist_detail_t mode)
{
    int row = 0, col = 0;
    int ex_width = 0, ex_offset, ex_offset_ctr;

    object_type *o_ptr = (object_type *) object;
    char o_name[160];
    char tmp_val[80];

    bool in_term;
    byte attr = proc_list_color_hack(o_ptr);

    /* Highlight */
    if (cursor) attr = get_color(attr, ATTR_HIGH, 1);

    in_term = (mode & OLIST_WINDOW) ? TRUE : FALSE;

    /* Object name */
    object_desc(o_name, sizeof(o_name), o_ptr, ODESC_PREFIX | ODESC_FULL);

    /* Width of extra fields */
    if (mode & OLIST_WEIGHT)
	ex_width += 9;
    if (mode & OLIST_PRICE)
	ex_width += 9;
    if (mode & OLIST_FAIL)
	ex_width += 10;

    /* Determine beginning row and column */
    if (in_term) 
    {
	/* Term window */
	row = offset;
	col = 0;
    } 
    else 
    {
	/* Main window */
	row = 1;
	col = Term->wid - 3 - max_len - ex_width;
	col = MIN(col, 20);

	if (col < 3)
	    col = 0;
    }

    /* Column offset of the first extra field */
    ex_offset = MIN(max_len, (size_t) (Term->wid - 1 - ex_width - col));

    /* Clear the line */
    prt("", row + onum, MAX(col - 2, 0));

    /* Print the label */
    put_str(label, row + onum, col);

    /* Print the object */
    if (o_ptr != NULL) {
	/* Limit object name */
	if (strlen(label) + strlen(o_name) > (size_t) ex_offset) {
	    int truncate = ex_offset - strlen(label);

	    if (truncate < 0)
		truncate = 0;
	    if ((size_t) truncate > sizeof(o_name) - 1)
		truncate = sizeof(o_name) - 1;

	    o_name[truncate] = '\0';
	}

	/* Object name */
	c_put_str(attr, o_name, row + onum, col + strlen(label));

	/* Extra fields */
	ex_offset_ctr = ex_offset;

	if (mode & OLIST_FAIL) {
	    int fail = (9 + get_use_device_chance(o_ptr)) / 10;
	    if (object_aware_p(o_ptr))
		strnfmt(tmp_val, sizeof(tmp_val), "%4d%% fail", fail);
	    else
		my_strcpy(tmp_val, "    ? fail", sizeof(tmp_val));
	    put_str(tmp_val, row + onum, col + ex_offset_ctr);
	    ex_offset_ctr += 10;
	}

	if (mode & OLIST_WEIGHT) {
	    int weight = o_ptr->weight * o_ptr->number;
	    strnfmt(tmp_val, sizeof(tmp_val), "%4d.%1d lb", weight / 10,
		    weight % 10);
	    put_str(tmp_val, row + onum, col + ex_offset_ctr);
	    ex_offset_ctr += 9;
	}
    }
}
Пример #10
0
/**
 * Handle signals -- simple (interrupt and quit)
 *
 * This function was causing a *huge* number of problems, so it has
 * been simplified greatly.  We keep a global variable which counts
 * the number of times the user attempts to kill the process, and
 * we commit suicide if the user does this a certain number of times.
 *
 * We attempt to give "feedback" to the user as he approaches the
 * suicide thresh-hold, but without penalizing accidental keypresses.
 *
 * To prevent messy accidents, we should reset this global variable
 * whenever the user enters a keypress, or something like that.
 */
static void handle_signal_simple(int sig)
{
	/* Protect errno from library calls in signal handler */
	int save_errno = errno;

	/* Disable handler */
	(void)(*signal_aux)(sig, SIG_IGN);

	/* Nothing to save, just quit */
	if (!character_generated || character_saved) quit(NULL);

	/* Count the signals */
	signal_count++;

	/* Terminate dead characters, suicide from interrupts (after warnings) */
	if (player->is_dead) {
		/* Mark the savefile */
		my_strcpy(player->died_from, "Abortion", sizeof(player->died_from));

		close_game();

		/* Quit */
		quit("interrupt");
	} else if (signal_count >= 5) {
		/* Cause of "death" */
		my_strcpy(player->died_from, "Interrupting", sizeof(player->died_from));

		/* Commit suicide */
		player->is_dead = TRUE;

		/* Stop playing */
		player->upkeep->playing = FALSE;

		/* Close stuff */
		close_game();

		/* Quit */
		quit("interrupt");
	} else if (signal_count >= 4) {
		/* Make a noise */
		Term_xtra(TERM_XTRA_NOISE, 0);

		/* Clear the top line */
		Term_erase(0, 0, 255);

		/* Display the cause */
		Term_putstr(0, 0, -1, COLOUR_WHITE, "Contemplating suicide!");

		/* Flush */
		Term_fresh();
	} else if (signal_count >= 2) {
		/* Make a noise */
		Term_xtra(TERM_XTRA_NOISE, 0);
	}

	/* Restore handler */
	(void)(*signal_aux)(sig, handle_signal_simple);

	/* Restore errno */
	errno = save_errno;
}
Пример #11
0
static void channels_report(int idx, int details)
{
  struct chanset_t *chan;
  int i;
  char s[1024], s2[100];
  struct flag_record fr = {FR_CHAN | FR_GLOBAL, 0, 0, 0, 0, 0};

  chan = chanset;
  while (chan != NULL) {
    if (idx != DP_STDOUT)
      get_user_flagrec(dcc[idx].user, &fr, chan->dname);
    if ((idx == DP_STDOUT) || glob_master(fr) || chan_master(fr)) {
      s[0] = 0;
      if (channel_greet(chan))
	strcat(s, "greet, ");
      if (channel_autoop(chan))
	strcat(s, "auto-op, ");
      if (channel_bitch(chan))
	strcat(s, "bitch, ");
      if (s[0])
	s[strlen(s) - 2] = 0;
      if (!s[0])
	strcpy(s, MISC_LURKING);
      get_mode_protect(chan, s2);
      if (!channel_inactive(chan)) {
	if (channel_active(chan)) {
	  /* If it's a !chan, we want to display it's unique name too <cybah> */
	  if (chan->dname[0]=='!') {
	    dprintf(idx, "    %-10s: %2d member%s enforcing \"%s\" (%s), "
	            "unique name %s\n", chan->dname, chan->channel.members,
	            (chan->channel.members==1) ? "," : "s,", s2, s, chan->name);
	  } else {
	    dprintf(idx, "    %-10s: %2d member%s enforcing \"%s\" (%s)\n",
	            chan->dname, chan->channel.members,
	            chan->channel.members == 1 ? "," : "s,", s2, s);
	  }
	} else {
	  dprintf(idx, "    %-10s: (%s), enforcing \"%s\"  (%s)\n", chan->dname,
		  channel_pending(chan) ? "pending" : "inactive", s2, s);
	}
      } else {
	dprintf(idx, "    %-10s: no IRC support for this channel\n",
		chan->dname);
      }
      if (details) {
	s[0] = 0;
	i = 0;
	if (channel_clearbans(chan))
	  i += my_strcpy(s + i, "clear-bans ");
	if (channel_enforcebans(chan))
	  i += my_strcpy(s + i, "enforce-bans ");
	if (channel_dynamicbans(chan))
	  i += my_strcpy(s + i, "dynamic-bans ");
	if (channel_nouserbans(chan))
	  i += my_strcpy(s + i, "forbid-user-bans ");
	if (channel_autoop(chan))
	  i += my_strcpy(s + i, "op-on-join ");
	if (channel_bitch(chan))
	  i += my_strcpy(s + i, "bitch ");
	if (channel_greet(chan))
	  i += my_strcpy(s + i, "greet ");
	if (channel_protectops(chan))
	  i += my_strcpy(s + i, "protect-ops ");
        if (channel_protectfriends(chan))
          i += my_strcpy(s + i, "protect-friends ");
	if (channel_dontkickops(chan))
	  i += my_strcpy(s + i, "dont-kick-ops ");
	if (channel_logstatus(chan))
	  i += my_strcpy(s + i, "log-status ");
	if (channel_revenge(chan))
	  i += my_strcpy(s + i, "revenge ");
	if (channel_secret(chan))
	  i += my_strcpy(s + i, "secret ");
	if (channel_shared(chan))
	  i += my_strcpy(s + i, "shared ");
	if (!channel_static(chan))
	  i += my_strcpy(s + i, "dynamic ");
	if (channel_autovoice(chan))
	  i += my_strcpy(s + i, "autovoice ");
	if (channel_cycle(chan))
	  i += my_strcpy(s + i, "cycle ");
	if (channel_seen(chan))
	  i += my_strcpy(s + i, "seen ");
	if (channel_dynamicexempts(chan))
	  i += my_strcpy(s + i, "dynamic-exempts ");
	if (channel_nouserexempts(chan))
	  i += my_strcpy(s + i, "forbid-user-exempts ");
	if (channel_dynamicinvites(chan))
	  i += my_strcpy(s + i, "dynamic-invites ");
	if (channel_nouserinvites(chan))
	  i += my_strcpy(s + i, "forbid-user-invites ");
	if (channel_inactive(chan))
	  i += my_strcpy(s + i, "inactive ");
	if (channel_nodesynch(chan))
	  i += my_strcpy(s + i, "nodesynch ");
	dprintf(idx, "      Options: %s\n", s);
	if (chan->need_op[0])
	  dprintf(idx, "      To get ops I do: %s\n", chan->need_op);
	if (chan->need_invite[0])
	  dprintf(idx, "      To get invited I do: %s\n", chan->need_invite);
	if (chan->need_limit[0])
	  dprintf(idx, "      To get the channel limit up'd I do: %s\n",
		  chan->need_limit);
	if (chan->need_unban[0])
	  dprintf(idx, "      To get unbanned I do: %s\n", chan->need_unban);
	if (chan->need_key[0])
	  dprintf(idx, "      To get the channel key I do: %s\n",
		  chan->need_key);
	if (chan->idle_kick)
	  dprintf(idx, "      Kicking idle users after %d min\n",
		  chan->idle_kick);
	if (chan->stopnethack_mode)
	  dprintf(idx, "      stopnethack-mode %d\n",
		  chan->stopnethack_mode);
      }
    }
    chan = chan->next;
  }
  if (details) {
    dprintf(idx, "    Bans last %d mins.\n", ban_time);
    dprintf(idx, "    Exemptions last %d mins.\n", exempt_time);
    dprintf(idx, "    Invitations last %d mins.\n", invite_time);
  }
}
Пример #12
0
int main( int argc, char *argv[] )
{
    char x[300];
    char y[300];

    CYG_TEST_INIT();

    CYG_TEST_INFO("Starting tests from testcase " __FILE__ " for C library "
                  "memcmp() function");
    CYG_TEST_INFO("This testcase provides simple basic tests");

    // Check 1
    my_strcpy(x, "I have become, comfortably numb");
    my_strcpy(y, "I have become, comfortably numb");
    CYG_TEST_PASS_FAIL( (memcmp(x, y, my_strlen(x)) == 0), "Simple compare");


    // Check 2
    my_strcpy(x, "");
    my_strcpy(y, "");
    CYG_TEST_PASS_FAIL( (memcmp(x, y, 0) == 0), "Simple empty string compare");


    // Check 3
    my_strcpy(x, "..shall snuff it. And the Lord did grin");
    my_strcpy(y, "..shall snuff it. And the Lord did grio");
    CYG_TEST_PASS_FAIL( (memcmp(x, y, my_strlen(x)) < 0),
                        "Memory less than #1" );


    // Check 4
    my_strcpy(x, "A reading from the Book of Armaments, Chapter 4, "
                  "Verses 16 to 20:");
    my_strcpy(y, "Bless this, O Lord, that with it thou mayst blow thine "
                 "enemies to tiny bits, in thy mercy.");
    CYG_TEST_PASS_FAIL( (memcmp(x, y, my_strlen(x)) < 0),
                        "Memory less than #2");

    // Check 5
    my_strcpy(x, "Lobeth this thy holy hand grenade at thy foe");
    my_strcpy(y, "Lobeth this thy holy hand grenade at thy fod");
    CYG_TEST_PASS_FAIL( (memcmp(x, y, my_strlen(x)) > 0),
                        "Memory greater than #1" );


    // Check 6
    my_strcpy(y, "Three shall be the number of the counting and the");
    my_strcpy(x, "number of the counting shall be three");
    CYG_TEST_PASS_FAIL( (memcmp(x, y, my_strlen(x)) > 0),
                        "Memory greater than #2" );

//    CYG_TEST_NA("Testing is not applicable to this configuration");

    CYG_TEST_FINISH("Finished tests from testcase " __FILE__ " for C library "
                    "memcmp() function");
} // main()
Пример #13
0
/**
 * This is a helper function used by do_cmd_throw and do_cmd_fire.
 *
 * It abstracts out the projectile path, display code, identify and clean up
 * logic, while using the 'attack' parameter to do work particular to each
 * kind of attack.
 */
static void ranged_helper(struct object *obj, int dir, int range, int shots,
						  ranged_attack attack)
{
	int i, j;

	char o_name[80];

	int path_n;
	struct loc path_g[256];

	/* Start at the player */
	int x = player->px;
	int y = player->py;

	/* Predict the "target" location */
	int ty = y + 99 * ddy[dir];
	int tx = x + 99 * ddx[dir];

	bool hit_target = FALSE;

	struct object *missile;

	/* Check for target validity */
	if ((dir == 5) && target_okay()) {
		int taim;
		target_get(&tx, &ty);
		taim = distance(y, x, ty, tx);
		if (taim > range) {
			char msg[80];
			strnfmt(msg, sizeof(msg),
					"Target out of range by %d squares. Fire anyway? ",
				taim - range);
			if (!get_check(msg)) return;
		}
	}

	/* Sound */
	sound(MSG_SHOOT);

	/* Describe the object */
	object_desc(o_name, sizeof(o_name), obj, ODESC_FULL | ODESC_SINGULAR);

	/* Actually "fire" the object -- Take a partial turn */
	player->upkeep->energy_use = (z_info->move_energy / shots);

	/* Calculate the path */
	path_n = project_path(path_g, range, y, x, ty, tx, 0);

	/* Hack -- Handle stuff */
	handle_stuff(player->upkeep);

	/* Start at the player */
	x = player->px;
	y = player->py;

	/* Project along the path */
	for (i = 0; i < path_n; ++i) {
		int ny = path_g[i].y;
		int nx = path_g[i].x;
		bool see = square_isseen(cave, ny, nx);

		/* Stop before hitting walls */
		if (!(square_ispassable(cave, ny, nx)) &&
			!(square_isprojectable(cave, ny, nx)))
			break;

		/* Advance */
		x = nx;
		y = ny;

		/* Tell the UI to display the missile */
		event_signal_missile(EVENT_MISSILE, obj, see, y, x);

		/* Try the attack on the monster at (x, y) if any */
		if (cave->squares[y][x].mon > 0) {
			monster_type *m_ptr = square_monster(cave, y, x);
			int visible = mflag_has(m_ptr->mflag, MFLAG_VISIBLE);

			bool fear = FALSE;
			const char *note_dies = monster_is_unusual(m_ptr->race) ? 
				" is destroyed." : " dies.";

			struct attack_result result = attack(obj, y, x);
			int dmg = result.dmg;
			u32b msg_type = result.msg_type;
			char hit_verb[20];
			my_strcpy(hit_verb, result.hit_verb, sizeof(hit_verb));
			mem_free(result.hit_verb);

			if (result.success) {
				hit_target = TRUE;

				object_notice_attack_plusses(obj);

				/* Learn by use for other equipped items */
				equip_notice_to_hit_on_attack(player);

				/* No negative damage; change verb if no damage done */
				if (dmg <= 0) {
					dmg = 0;
					msg_type = MSG_MISS;
					my_strcpy(hit_verb, "fails to harm", sizeof(hit_verb));
				}

				if (!visible) {
					/* Invisible monster */
					msgt(MSG_SHOOT_HIT, "The %s finds a mark.", o_name);
				} else {
					for (j = 0; j < (int)N_ELEMENTS(ranged_hit_types); j++) {
						char m_name[80];
						const char *dmg_text = "";

						if (msg_type != ranged_hit_types[j].msg)
							continue;

						if (OPT(show_damage))
							dmg_text = format(" (%d)", dmg);

						monster_desc(m_name, sizeof(m_name), m_ptr, MDESC_OBJE);

						if (ranged_hit_types[j].text)
							msgt(msg_type, "Your %s %s %s%s. %s", o_name, 
								 hit_verb, m_name, dmg_text, 
								 ranged_hit_types[j].text);
						else
							msgt(msg_type, "Your %s %s %s%s.", o_name, hit_verb,
								 m_name, dmg_text);
					}
					
					/* Track this monster */
					if (mflag_has(m_ptr->mflag, MFLAG_VISIBLE)) {
						monster_race_track(player->upkeep, m_ptr->race);
						health_track(player->upkeep, m_ptr);
					}
				}

				/* Hit the monster, check for death */
				if (!mon_take_hit(m_ptr, dmg, &fear, note_dies)) {
					message_pain(m_ptr, dmg);
					if (fear && mflag_has(m_ptr->mflag, MFLAG_VISIBLE)) {
						char m_name[80];
						monster_desc(m_name, sizeof(m_name), m_ptr, 
									 MDESC_DEFAULT);
						add_monster_message(m_name, m_ptr, 
											MON_MSG_FLEE_IN_TERROR, TRUE);
					}
				}
			}
			/* Stop the missile */
			break;
		}

		/* Stop if non-projectable but passable */
		if (!(square_isprojectable(cave, ny, nx))) 
			break;
	}

	/* Get the missile */
	if (object_is_carried(player, obj))
		missile = gear_object_for_use(obj, 1, TRUE);
	else
		missile = floor_object_for_use(obj, 1, TRUE);

	/* Drop (or break) near that location */
	drop_near(cave, missile, breakage_chance(missile, hit_target), y, x, TRUE);
}
Пример #14
0
/**
 * Attack the monster at the given location with a single blow.
 */
static bool py_attack_real(int y, int x, bool *fear)
{
	size_t i;

	/* Information about the target of the attack */
	struct monster *mon = square_monster(cave, y, x);
	char m_name[80];
	bool stop = FALSE;

	/* The weapon used */
	struct object *obj = equipped_item_by_slot_name(player, "weapon");

	/* Information about the attack */
	int chance = py_attack_hit_chance(obj);
	bool do_quake = FALSE;
	bool success = FALSE;

	/* Default to punching for one damage */
	char verb[20];
	int dmg = 1;
	u32b msg_type = MSG_HIT;

	/* Default to punching for one damage */
	my_strcpy(verb, "punch", sizeof(verb));

	/* Extract monster name (or "it") */
	monster_desc(m_name, sizeof(m_name), mon, 
				 MDESC_OBJE | MDESC_IND_HID | MDESC_PRO_HID);

	/* Auto-Recall if possible and visible */
	if (mflag_has(mon->mflag, MFLAG_VISIBLE))
		monster_race_track(player->upkeep, mon->race);

	/* Track a new monster */
	if (mflag_has(mon->mflag, MFLAG_VISIBLE))
		health_track(player->upkeep, mon);

	/* Handle player fear (only for invisible monsters) */
	if (player_of_has(player, OF_AFRAID)) {
		msgt(MSG_AFRAID, "You are too afraid to attack %s!", m_name);
		return FALSE;
	}

	/* Disturb the monster */
	mon_clear_timed(mon, MON_TMD_SLEEP, MON_TMD_FLG_NOMESSAGE, FALSE);

	/* See if the player hit */
	success = test_hit(chance, mon->race->ac,
					   mflag_has(mon->mflag, MFLAG_VISIBLE));

	/* If a miss, skip this hit */
	if (!success) {
		msgt(MSG_MISS, "You miss %s.", m_name);
		return FALSE;
	}

	/* Handle normal weapon */
	if (obj) {
		int j;
		const struct brand *b = NULL;
		const struct slay *s = NULL;

		my_strcpy(verb, "hit", sizeof(verb));

		/* Get the best attack from all slays or
		 * brands on all non-launcher equipment */
		for (j = 2; j < player->body.count; j++) {
			struct object *obj = slot_object(player, j);
			if (obj)
				improve_attack_modifier(obj, mon, &b, &s, verb, FALSE, TRUE,
										FALSE);
		}

		improve_attack_modifier(obj, mon, &b, &s, verb, FALSE, TRUE, FALSE);

		dmg = melee_damage(obj, b, s);
		dmg = critical_norm(obj->weight, obj->to_h, dmg, &msg_type);

		/* Learn by use for the weapon */
		object_notice_attack_plusses(obj);

		if (player_of_has(player, OF_IMPACT) && dmg > 50) {
			do_quake = TRUE;
			equip_notice_flag(player, OF_IMPACT);
		}
	}

	/* Learn by use for other equipped items */
	equip_notice_on_attack(player);

	/* Apply the player damage bonuses */
	dmg += player_damage_bonus(&player->state);

	/* No negative damage; change verb if no damage done */
	if (dmg <= 0) {
		dmg = 0;
		msg_type = MSG_MISS;
		my_strcpy(verb, "fail to harm", sizeof(verb));
	}

	for (i = 0; i < N_ELEMENTS(melee_hit_types); i++) {
		const char *dmg_text = "";

		if (msg_type != melee_hit_types[i].msg)
			continue;

		if (OPT(show_damage))
			dmg_text = format(" (%d)", dmg);

		if (melee_hit_types[i].text)
			msgt(msg_type, "You %s %s%s. %s", verb, m_name, dmg_text,
					melee_hit_types[i].text);
		else
			msgt(msg_type, "You %s %s%s.", verb, m_name, dmg_text);
	}

	/* Pre-damage side effects */
	blow_side_effects(player, mon);

	/* Damage, check for fear and death */
	stop = mon_take_hit(mon, dmg, fear, NULL);

	if (stop)
		(*fear) = FALSE;

	/* Post-damage effects */
	if (blow_after_effects(y, x, do_quake))
		stop = TRUE;

	return stop;
}
Пример #15
0
/*
 * Inscribe an object with a comment
 */
void do_cmd_inscribe(void)
{
	int item;

	object_type *o_ptr;

	char o_name[80];

	char tmp[80];

	cptr q, s;

	/* Get an item */
	q = "Inscribe which item? ";
	s = "You have nothing to inscribe.";
	if (!get_item(&item, q, s, (USE_EQUIP | USE_INVEN | USE_FLOOR))) return;

	/* Get the item (in the pack) */
	if (item >= 0)
	{
		o_ptr = &inventory[item];
	}

	/* Get the item (on the floor) */
	else
	{
		o_ptr = &o_list[0 - item];
	}

	/* Describe the activity */
	object_desc(o_name, sizeof(o_name), o_ptr, TRUE, 3);

	/* Message */
	msg_format("Inscribing %s.", o_name);
	message_flush();

	/* Start with nothing */
	my_strcpy(tmp, "", sizeof(tmp));

	/* Use old inscription */
	if (o_ptr->obj_note)
	{
		/* Start with the old inscription */
		strnfmt(tmp, sizeof(tmp), "%s", quark_str(o_ptr->obj_note));
	}

	/* Get a new inscription (possibly empty) */
	if (term_get_string("Inscription: ", tmp, sizeof(tmp)))
	{
		char tmp_val[160];
		char o_name2[80];

		/*make a fake object so we can give a proper message*/
		object_type *i_ptr;
		object_type object_type_body;

		// if given an empty inscription, then uninscribe instead
		if (strlen(tmp) == 0)
		{
			uninscribe(o_ptr);
			return;
		}
		
		/* Save the inscription */
		o_ptr->obj_note = quark_add(tmp);

		/* Add an autoinscription? */
		// Sil-y: removed restriction to known items (through 'object_aware')
		if (!(k_info[o_ptr->k_idx].flags3 & (TR3_INSTA_ART)))
		{
			/* Get local object */
			i_ptr = &object_type_body;

			/* Wipe the object */
			object_wipe(i_ptr);

			/* Create the object */
			object_prep(i_ptr, o_ptr->k_idx);

			/*make it plural*/
			i_ptr->number = 2;

			/*now describe with correct amount*/
			object_desc(o_name2, sizeof(o_name2), i_ptr, FALSE, 0);

			/* Prompt */
			strnfmt(tmp_val, sizeof(tmp_val), "Automatically inscribe all %s with '%s'? ",
					o_name2, tmp);

			/* Auto-Inscribe if they want that */
			if (get_check(tmp_val)) add_autoinscription(o_ptr->k_idx, tmp);
		}

		/* Combine the pack */
		p_ptr->notice |= (PN_COMBINE);

		/* Window stuff */
		p_ptr->window |= (PW_INVEN | PW_EQUIP);
	}
}
Пример #16
0
int main(int argc, char *argv[])
{
   // if(testme())
     //   return 0;
    if (argc == 2 && (strcmp(argv[0], "-h") == 0 || strcmp(argv[0], "--help") == 0)) 
	{
	    printUsage(argv[0]);
	    return EXIT_SUCCESS;
	}

    if (argc != 3) {
	printUsage(argv[0]);
	return EXIT_FAILURE;
    }

    FILE * f;
    if ((f = fopen(argv[2], "r")) == NULL) {
	printf("Unable to open file '%s', aborting!\n", argv[2]);
	return EXIT_FAILURE;
    }
    FILE * fptrout = stdout;

    int line_count = 0;
    char line_buffer[LINE_SIZE];
    while (fgets(line_buffer, LINE_SIZE, f) != NULL) 
	{
	    line_count++;
	}
    int file_length = ftell(f);
    rewind(f);
    
    char * * src = malloc(sizeof(char *) * line_count);
    char * * copy = malloc(sizeof(char *) * line_count);
    int i;
    for (i = 0; i < line_count; i++) 
	{
	    if (feof(f)) 
		{
		    printf("Not enough lines in file!\n");
		    fclose(f);
		    return EXIT_FAILURE;
		}
	    copy[i] = malloc(sizeof(char) * LINE_SIZE);
	    fgets(copy[i], LINE_SIZE, f);
	    trim(copy[i]);
	    src[i] = strdup(copy[i]);
	}
    fclose(f);

    char * buffer = malloc(sizeof(char) * file_length);
    buffer[0] = '\0';
    //Partitioning outputs
    const char * command = argv[1];

    if (strcmp(command, "my_strlen") == 0) {
	for (i = 0; i < line_count; i++) {
	    fprintf(fptrout, "length: %d\n", my_strlen(copy[i]));
	}
    } else if (strcmp(command, "my_countchar") == 0) {
	for (i = 0; i < line_count; i++) {
	    fprintf(fptrout, "count(%c): %d\n", copy[i][0], my_countchar(copy[i], copy[i][0]));
	}
    } else if (strcmp(command, "my_strupper") == 0) {
	for (i = 0; i < line_count; i++) {
	    my_strupper(copy[i]);
	    fprintf(fptrout, "uppercase: %s\n", copy[i]);
	}
    } else if (strcmp(command, "my_strlower") == 0) {
	for (i = 0; i < line_count; i++) {
	    my_strlower(copy[i]);
	    fprintf(fptrout, "lowercase: %s\n", copy[i]);
	}
    } else if (strcmp(command, "my_strcat") == 0) {
	for (i = 0; i < line_count; i++) {
	    my_strcat(copy[i], " ");
	    my_strcat(copy[i], src[i]);
	    fprintf(fptrout, "%s\n", copy[i]);
	}
    } else if (strcmp(command, "my_strncat") == 0) {
	for (i = 0; i < line_count; i++) {
	    my_strncat(copy[i], "   ", 2);
	    my_strncat(copy[i], "........", 1);
	    fprintf(fptrout, "%s\n", copy[i]);
	}
    } else if (strcmp(command, "my_strcpy") == 0) {
	for (i = 0; i < line_count; i++) {
	    my_strcpy(copy[i], "Copying this String.");
	    fprintf(fptrout, "%s\n", copy[i]);
	}
    } else if (strcmp(command, "my_strncpy") == 0) {
	for (i = 0; i < line_count; i++) {
	    my_strncpy(copy[i], src[i], 5);
	    fprintf(fptrout, "%s\n", copy[i]);
	}
    } else if (strcmp(command, "my_strstr") == 0) {
	for (i = 0; i < line_count; i++) {
	    fprintf(fptrout, "%d\n", my_strstr(copy[i], src[i]) != NULL);
	}
    } else if (strcmp(command, "my_strinsert") == 0) {
	for (i = 0; i < line_count; i++) {
	    my_strinsert(buffer, "\n", 0);
	    my_strinsert(buffer, src[i], 0);
	}
	fprintf(fptrout, "[%s]\n", buffer);
    } else if (strcmp(command, "my_strdelete") == 0) {
	for (i = 0; i < line_count; i++) {
	    my_strinsert(buffer, "\n", 0);
	    my_strinsert(buffer, src[i], 0);
	    my_strdelete(buffer, 0, 10);
	}
	fprintf(fptrout, "[%s]\n", buffer);
    }

    for (i = 0; i < line_count; i++) {
	free(copy[i]);
	free(src[i]);
    }
    free(src);
    free(copy);
    free(buffer);
    fclose(fptrout);
    return EXIT_SUCCESS;
}
Пример #17
0
/*
 * Identify a character, allow recall of monsters
 *
 * Several "special" responses recall "multiple" monsters:
 *   ^A (all monsters)
 *   ^U (all unique monsters)
 *   ^N (all non-unique monsters)
 *
 * The responses may be sorted in several ways, see below.
 *
 *
 */
void do_cmd_query_symbol(void)
{
	int i, n, r_idx;
	char sym, query;
	char buf[128];

	bool all = FALSE;
	bool uniq = FALSE;
	bool norm = FALSE;

	bool recall = FALSE;

	u16b why = 0;
	u16b *who;


	/* Get a character, or abort */
	if (!get_com("Enter character to be identified: ", &sym)) return;

	/* Find that character info, and describe it */
	for (i = 0; ident_info[i]; ++i)
	{
		if (sym == ident_info[i][0]) break;
	}

	/* Describe */
	if (sym == KTRL('A'))
	{
		all = TRUE;
		my_strcpy(buf, "Full monster list.", sizeof (buf));
	}
	else if (sym == KTRL('U'))
	{
		all = uniq = TRUE;
		my_strcpy(buf, "Unique monster list.", sizeof (buf));
	}
	else if (sym == KTRL('N'))
	{
		all = norm = TRUE;
		my_strcpy(buf, "Non-unique monster list.", sizeof (buf));
	}
	else if (ident_info[i])
	{
		strnfmt(buf, sizeof(buf), "%c - %s.", sym, ident_info[i] + 2);
	}
	else
	{
		strnfmt(buf, sizeof(buf), "%c - %s.", sym, "Unknown Symbol");
	}

	/* Display the result */
	prt(buf, 0, 0);

	/* Allocate the "who" array */
	C_MAKE(who, z_info->r_max, u16b);

	/* Collect matching monsters */
	for (n = 0, i = 1; i < z_info->r_max - 1; i++)
	{
		monster_race *r_ptr = &r_info[i];
		monster_lore *l_ptr = &l_list[i];

		/* Nothing to recall */
		if (!cheat_know && !l_ptr->tsights && !p_ptr->active_ability[S_PER][PER_LORE2]) continue;

		/* Require non-unique monsters if needed */
		if (norm && (r_ptr->flags1 & (RF1_UNIQUE))) continue;

		/* Require unique monsters if needed */
		if (uniq && !(r_ptr->flags1 & (RF1_UNIQUE))) continue;

		// Ignore monsters that can't be generated
		if (r_ptr->level > 25) continue;

		/* Collect "appropriate" monsters */
		if (all || (r_ptr->d_char == sym)) who[n++] = i;
	}

	/* Nothing to recall */
	if (!n)
	{
		/* XXX XXX Free the "who" array */
		FREE(who);

		return;
	}


	/* Prompt */
	put_str("Recall details? (k/p/y/n): ", 0, 40);

	/* Query */
	query = inkey();

	/* Restore */
	prt(buf, 0, 0);


	/* Sort by kills (and level) */
	if (query == 'k')
	{
		why = 4;
		query = 'y';
	}

	/* Sort by level */
	if (query == 'p')
	{
		why = 2;
		query = 'y';
	}

	/* Catch "escape" */
	if (query != 'y')
	{
		/* XXX XXX Free the "who" array */
		FREE(who);

		return;
	}

	/* Sort if needed */
	if (why)
	{
		/* Select the sort method */
		ang_sort_comp = ang_sort_comp_hook;
		ang_sort_swap = ang_sort_swap_hook;

		/* Sort the array */
		ang_sort(who, &why, n);
	}


	/* Start at the end */
	i = n - 1;

	/* Scan the monster memory */
	while (1)
	{
		/* Extract a race */
		r_idx = who[i];

		/* Hack -- Auto-recall */
		monster_race_track(r_idx);

		/* Hack -- Handle stuff */
		handle_stuff();

		/* Hack -- Begin the prompt */
		roff_top(r_idx);

		/* Hack -- Complete the prompt */
		Term_addstr(-1, TERM_WHITE, " [(r)ecall, ESC]");

		/* Interact */
		while (1)
		{
			/* Recall (raging players don't get recall) */
			if (recall)
			{
				/* Save screen */
				screen_save();

				/* Recall on screen */
				screen_roff(who[i]);

				/* Hack -- Complete the prompt (again) */
				Term_addstr(-1, TERM_WHITE, " [(r)ecall, ESC]");
			}

			/* Command */
			query = inkey();

			/* Unrecall */
			if (recall)
			{
				/* Load screen */
				screen_load();
			}

			/* Normal commands */
			if (query != 'r') break;

			/* Toggle recall */
			recall = !recall;
		}

		/* Stop scanning */
		if (query == ESCAPE) break;

		/* Move to "prev" monster */
		if (query == '-')
		{
			if (++i == n)
			{
				i = 0;
			}
		}

		/* Move to "next" monster */
		else
		{
			if (i-- == 0)
			{
				i = n - 1;
			}
		}
	}


	/* Re-display the identity */
	prt(buf, 0, 0);

	/* Free the "who" array */
	FREE(who);
}
Пример #18
0
/*
 * Creates a description of the item "o_ptr", and stores it in "out_val".
 *
 * One can choose the "verbosity" of the description, including whether
 * or not the "number" of items should be described, and how much detail
 * should be used when describing the item.
 *
 * The given "buf" must be MAX_NLEN chars long to hold the longest possible
 * description, which can get pretty long, including incriptions, such as:
 * "no more Maces of Disruption (Defender) (+10,+10) [+5] (+3 to stealth)".
 * Note that the inscription will be clipped to keep the total description
 * under MAX_NLEN-1 chars (plus a terminator).
 *
 * Note the use of "object_desc_num()" and "object_desc_int()" as hyper-efficient,
 * portable, versions of some common "sprintf()" commands.
 *
 * Note that all ego-items (when known) append an "Ego-Item Name", unless
 * the item is also an artifact, which should NEVER happen.
 *
 * Note that all artifacts (when known) append an "Artifact Name", so we
 * have special processing for "Specials" (artifact Lites, Rings, Amulets).
 * The "Specials" never use "modifiers" if they are "known", since they
 * have special "descriptions", such as "The Necklace of the Dwarves".
 *
 * Special Lite's use the "k_info" base-name (Phial, Star, or Arkenstone),
 * plus the artifact name, just like any other artifact, if known.
 *
 * Special Ring's and Amulet's, if not "aware", use the same code as normal
 * rings and amulets, and if "aware", use the "k_info" base-name (Ring or
 * Amulet or Necklace).  They will NEVER "append" the "k_info" name.  But,
 * they will append the artifact name, just like any artifact, if known.
 *
 * Hack -- Display "The One Ring" as "a Plain Gold Ring" until aware.
 *
 * Mode:
 *   OD_NAME_ONLY        : The Cloak of Death
 *   OD_NAME_AND_ENCHANT : The Cloak of Death [1,+3]
 *   OD_OMIT_INSCRIPTION : The Cloak of Death [1,+3] (+2 to Stealth)
 *   0                   : The Cloak of Death [1,+3] (+2 to Stealth) {nifty}
 *
 *   OD_OMIT_PREFIX      : Forbidden numeric prefix
 *   OD_NO_PLURAL        : Forbidden use of plural 
 *   OD_STORE            : Assume to be aware and known
 *   OD_NO_FLAVOR        : Allow to hidden flavor
 *   OD_FORCE_FLAVOR     : Get un-shuffled flavor name
 */
void object_desc(char *buf, const object_type *o_ptr, u32b mode)
{
	/* Extract object kind name */
	cptr            kindname = get_object_name(o_ptr);

	/* Extract default "base" string */
	cptr            basenm = kindname;

	/* Assume no "modifier" string */
	cptr            modstr = "";

	int             power;

	bool            aware = FALSE;
	bool            known = FALSE;
	bool            flavor = TRUE;

	bool            show_weapon = FALSE;
	bool            show_armour = FALSE;

	cptr            s, s0;
	char            *t;

	char            p1 = '(', p2 = ')';
	char            b1 = '[', b2 = ']';
	char            c1 = '{', c2 = '}';

	char            tmp_val[MAX_NLEN+160];
	char            tmp_val2[MAX_NLEN+10];
	char            fake_insc_buf[30];

	u32b            f1, f2, f3;
	bool            fullname = FALSE;

	object_type *bow_ptr;

	object_kind *k_ptr = &k_info[o_ptr->k_idx];
	object_kind *flavor_k_ptr = &k_info[k_ptr->flavor];

	/* Extract some flags */
	object_flags(o_ptr, &f1, &f2, &f3);

	/* See if the object is "aware" */
	if (object_aware_p(o_ptr)) aware = TRUE;

	/* See if the object is "known" */
	if (object_known_p(o_ptr)) known = TRUE;

	/* Allow flavors to be hidden when aware */
	if (aware && ((mode & OD_NO_FLAVOR) || plain_descriptions)) flavor = FALSE;

	/* Object is in the inventory of a store or spoiler */
	if ((mode & OD_STORE) || (o_ptr->ident & IDENT_STORE))
	{
		/* Don't show flavors */
		flavor = FALSE;

		/* Pretend known and aware */
		aware = TRUE;
		known = TRUE;
	}

	/* Force to be flavor name only */
	if (mode & OD_FORCE_FLAVOR)
	{
		aware = FALSE;
		flavor = TRUE;
		known = FALSE;

		/* Cancel shuffling */
		flavor_k_ptr = k_ptr;
	}

	/* Analyze the object */
	switch (o_ptr->tval)
	{
		/* Some objects are easy to describe */
		case TV_SKELETON:
		case TV_BOTTLE:
		case TV_JUNK:
		case TV_SPIKE:
		case TV_FLASK:
		case TV_CHEST:
		case TV_FOOD:
		{
			break;
		}

		/* Figurines/Statues */
		case TV_FIGURINE:
		case TV_STATUE:
		{
			monster_race *r_ptr = &r_info[o_ptr->pval];

#ifdef JP
			modstr = r_name + r_ptr->name;
#else
			cptr t = r_name + r_ptr->name;

			if (!(r_ptr->flags1 & RF1_UNIQUE))
			{
				sprintf(tmp_val2, "%s%s", (is_a_vowel(*t) ? "an " : "a "), t);

				modstr = tmp_val2;
			}
			else
			{
				modstr = t;
			}
#endif


			break;
		}

		/* Corpses */
		case TV_CORPSE:
		{
			monster_race *r_ptr = &r_info[o_ptr->pval];

			modstr = r_name + r_ptr->name;

#ifdef JP
			basenm = "#%";
#else
			if (r_ptr->flags1 & RF1_UNIQUE)
				basenm = "& % of #";
			else
				basenm = "& # %";
#endif

			break;
		}

		/* Missiles/ Bows/ Weapons */
		case TV_SHOT:
		case TV_BOLT:
		case TV_ARROW:
		case TV_BOW:
		case TV_HAFTED:
		case TV_POLEARM:
		case TV_SWORD:
		case TV_DIGGING:
		{
			show_weapon = TRUE;
			break;
		}

		/* Armour */
		case TV_BOOTS:
		case TV_GLOVES:
		case TV_CLOAK:
		case TV_CROWN:
		case TV_HELM:
		case TV_SHIELD:
		case TV_SOFT_ARMOR:
		case TV_HARD_ARMOR:
		case TV_DRAG_ARMOR:
		{
			show_armour = TRUE;
			break;
		}

		/* Lites (including a few "Specials") */
		case TV_LITE:
		{
			break;
		}

		/* Amulets (including a few "Specials") */
		case TV_AMULET:
		{
			/* Known artifacts */
			if (aware)
			{
				if (artifact_p(o_ptr)) break;
				if (k_ptr->gen_flags & TRG_INSTA_ART) break;
			}

			/* Color the object */
			modstr = k_name + flavor_k_ptr->flavor_name;

#ifdef JP
			if (!flavor)    basenm = "%のアミュレット";
			else if (aware) basenm = "%の#アミュレット";
			else            basenm = "#アミュレット";
#else
			if (!flavor)    basenm = "& Amulet~ of %";
			else if (aware) basenm = "& # Amulet~ of %";
			else            basenm = "& # Amulet~";
#endif

			break;
		}

		/* Rings (including a few "Specials") */
		case TV_RING:
		{
			/* Known artifacts */
			if (aware)
			{
				if (artifact_p(o_ptr)) break;
				if (k_ptr->gen_flags & TRG_INSTA_ART) break;
			}

			/* Color the object */
			modstr = k_name + flavor_k_ptr->flavor_name;

#ifdef JP
			if (!flavor)    basenm = "%の指輪";
			else if (aware) basenm = "%の#指輪";
			else            basenm = "#指輪";
#else
			if (!flavor)    basenm = "& Ring~ of %";
			else if (aware) basenm = "& # Ring~ of %";
			else            basenm = "& # Ring~";
#endif

			if (!k_ptr->to_h && !k_ptr->to_d && (o_ptr->to_h || o_ptr->to_d)) show_weapon = TRUE;

			break;
		}

		case TV_STAFF:
		{
			/* Color the object */
			modstr = k_name + flavor_k_ptr->flavor_name;

#ifdef JP
			if (!flavor)    basenm = "%のスタッフ";
			else if (aware) basenm = "%の#スタッフ";
			else            basenm = "#スタッフ";
#else
			if (!flavor)    basenm = "& Staff~ of %";
			else if (aware) basenm = "& # Staff~ of %";
			else            basenm = "& # Staff~";
#endif

			break;
		}

		case TV_WAND:
		{
			/* Color the object */
			modstr = k_name + flavor_k_ptr->flavor_name;

#ifdef JP
			if (!flavor)    basenm = "%のワンド";
			else if (aware) basenm = "%の#ワンド";
			else            basenm = "#ワンド";
#else
			if (!flavor)    basenm = "& Wand~ of %";
			else if (aware) basenm = "& # Wand~ of %";
			else            basenm = "& # Wand~";
#endif

			break;
		}

		case TV_ROD:
		{
			/* Color the object */
			modstr = k_name + flavor_k_ptr->flavor_name;

#ifdef JP
			if (!flavor)    basenm = "%のロッド";
			else if (aware) basenm = "%の#ロッド";
			else            basenm = "#ロッド";
#else
			if (!flavor)    basenm = "& Rod~ of %";
			else if (aware) basenm = "& # Rod~ of %";
			else            basenm = "& # Rod~";
#endif

			break;
		}

		case TV_SCROLL:
		{
			/* Color the object */
			modstr = k_name + flavor_k_ptr->flavor_name;

#ifdef JP
			if (!flavor)    basenm = "%の巻物";
			else if (aware) basenm = "\"#\"と書かれた%の巻物";
			else            basenm = "\"#\"と書かれた巻物";
#else
			if (!flavor)    basenm = "& Scroll~ of %";
			else if (aware) basenm = "& Scroll~ titled \"#\" of %";
			else            basenm = "& Scroll~ titled \"#\"";
#endif

			break;
		}

		case TV_POTION:
		{
			/* Color the object */
			modstr = k_name + flavor_k_ptr->flavor_name;

#ifdef JP
			if (!flavor)    basenm = "%の薬";
			else if (aware) basenm = "%の#薬";
			else            basenm = "#薬";
#else
			if (!flavor)    basenm = "& Potion~ of %";
			else if (aware) basenm = "& # Potion~ of %";
			else            basenm = "& # Potion~";
#endif

			break;
		}

		/* Magic Books */
		case TV_LIFE_BOOK:
		{
#ifdef JP
			basenm = "生命の魔法書%";
#else
			if (mp_ptr->spell_type == ST_PRAYER)
				basenm = "& Book~ of Life Magic %";
			else
				basenm = "& Life Spellbook~ %";
#endif

			break;
		}

		case TV_SORCERY_BOOK:
		{
#ifdef JP
			basenm = "仙術の魔法書%";
#else
			if (mp_ptr->spell_type == ST_PRAYER)
				basenm = "& Book~ of Sorcery %";
			else
				basenm = "& Sorcery Spellbook~ %";
#endif

			break;
		}

		/* Hack -- Gold/Gems */
		case TV_GOLD:
		{
			strcpy(buf, basenm);
			return;
		}

		/* Used in the "inventory" routine */
		default:
		{
#ifdef JP
			strcpy(buf, "(なし)");
#else
			strcpy(buf, "(nothing)");
#endif

			return;
		}
	}

	/* Use full name from a_info */
	if (known && o_ptr->name1)
	{
		artifact_type *a_ptr = &a_info[o_ptr->name1];
		if (prefix(a_name + a_ptr->name, "$"))
		{
			basenm = a_name + a_info[o_ptr->name1].name + 1;
			fullname = TRUE;
		}
	}

	/* Start dumping the result */
	t = tmp_val;

#ifdef JP
	if (basenm[0] == '&')
		s = basenm + 2;
	else
		s = basenm;

	/* No prefix */
	if (mode & OD_OMIT_PREFIX)
	{
		/* Nothing */
	}
	else if (o_ptr->number > 1)
	{
		t = object_desc_kosuu(t, o_ptr);
		t = object_desc_str(t, "の ");
	}

	/* 英語の場合アーティファクトは The が付くので分かるが
	 * 日本語では分からないのでマークをつける 
	 */
	if (known)
	{
		if (artifact_p(o_ptr)) t = object_desc_str(t, "★");
		else if (o_ptr->art_name) t = object_desc_str(t, "☆");
	}

#else

	/* The object "expects" a "number" */
	if (basenm[0] == '&')
	{
		/* Skip the ampersand (and space) */
		s = basenm + 2;

		/* No prefix */
		if (mode & OD_OMIT_PREFIX)
		{
			/* Nothing */
		}

		/* Hack -- None left */
		else if (o_ptr->number <= 0)
		{
			t = object_desc_str(t, "no more ");
		}

		/* Extract the number */
		else if (o_ptr->number > 1)
		{
			t = object_desc_num(t, o_ptr->number);
			t = object_desc_chr(t, ' ');
		}

		/* Hack -- The only one of its kind */
		else if ((known && (artifact_p(o_ptr) || o_ptr->art_name)) ||
		         ((o_ptr->tval == TV_CORPSE) &&
		          (r_info[o_ptr->pval].flags1 & RF1_UNIQUE)))
		{
			t = object_desc_str(t, "The ");
		}

		/* A single one */
		else
		{
			bool vowel;

			switch (*s)
			{
			case '#': vowel = is_a_vowel(modstr[0]); break;
			case '%': vowel = is_a_vowel(*kindname); break;
			default:  vowel = is_a_vowel(*s); break;
			}

			if (vowel)
			{
				/* A single one, with a vowel */
				t = object_desc_str(t, "an ");
			}
			else
			{
				/* A single one, without a vowel */
				t = object_desc_str(t, "a ");
			}
		}
	}

	/* Hack -- objects that "never" take an article */
	else
	{
		/* No ampersand */
		s = basenm;

		/* No pref */
		if (mode & OD_OMIT_PREFIX)
		{
			/* Nothing */
		}

		/* Hack -- all gone */
		else if (o_ptr->number <= 0)
		{
			t = object_desc_str(t, "no more ");
		}

		/* Prefix a number if required */
		else if (o_ptr->number > 1)
		{
			t = object_desc_num(t, o_ptr->number);
			t = object_desc_chr(t, ' ');
		}

		/* Hack -- The only one of its kind */
		else if (known && (artifact_p(o_ptr) || o_ptr->art_name))
		{
			t = object_desc_str(t, "The ");
		}

		/* Hack -- single items get no prefix */
		else
		{
			/* Nothing */
		}
	}
#endif

	/* Paranoia -- skip illegal tildes */
	/* while (*s == '~') s++; */

#ifdef JP
	/* 伝説のアイテム、名のあるアイテムの名前を付加する */
	if (known)
	{
		/* ランダム・アーティファクト */
		if (o_ptr->art_name)
		{
			cptr temp = quark_str(o_ptr->art_name);

			/* '『' から始まらない伝説のアイテムの名前は最初に付加する */
			/* 英語版のセーブファイルから来た 'of XXX' は,「XXXの」と表示する */
			if (strncmp(temp, "of ", 3) == 0)
			{
				t = object_desc_str(t, &temp[3]);
				t = object_desc_str(t, "の");
			}
			else if ((strncmp(temp, "『", 2) != 0) && (temp[0] != '\''))
				t = object_desc_str(t, temp);
		}
		/* 伝説のアイテム */
		else if (o_ptr->name1 && !fullname)
		{
			artifact_type *a_ptr = &a_info[o_ptr->name1];
			/* '『' から始まらない伝説のアイテムの名前は最初に付加する */
			if (strncmp(a_name + a_ptr->name, "『", 2) != 0)
			{
				t = object_desc_str(t, a_name + a_ptr->name);
			}
		}
		/* 名のあるアイテム */
		else if (o_ptr->name2)
		{
			ego_item_type *e_ptr = &e_info[o_ptr->name2];
			t = object_desc_str(t, e_name + e_ptr->name);
		}
	}
#endif

	/* Copy the string */
	for (s0 = NULL; *s || s0; )
	{
		/* The end of the flavour/kind string. */
		if (!*s)
		{
			s = s0 + 1;
			s0 = NULL;
		}

		/* Begin to append the modifier (flavor) */
		else if ((*s == '#') && !s0)
		{
			s0 = s;
			s = modstr;

			/* Paranoia -- Never append multiple modstrs */
			modstr = "";
		}

		/* Begin to append the kind name */
		else if ((*s == '%') && !s0)
		{
			s0 = s;
			s = kindname;

			/* Paranoia -- Never append multiple kindnames */
			kindname = "";
		}

#ifndef JP
		/* Pluralizer */
		else if (*s == '~')
		{
			/* Add a plural if needed */
			if (!(mode & OD_NO_PLURAL) && (o_ptr->number != 1))
			{
				char k = t[-1];

				/* XXX XXX XXX Mega-Hack */

				/* Hack -- "Cutlass-es" and "Torch-es" */
				if ((k == 's') || (k == 'h')) *t++ = 'e';

				/* Add an 's' */
				*t++ = 's';
			}
			s++;
		}
#endif

		/* Normal */
		else
		{
			/* Copy */
			*t++ = *s++;
		}
	}

	/* Terminate */
	*t = '\0';


#ifdef JP
	/* '『'から始まる伝説のアイテムの名前は最後に付加する */
	if (known)
	{
		/* ランダムアーティファクトの名前はセーブファイルに記録
		   されるので、英語版の名前もそれらしく変換する */
		if (o_ptr->art_name)
		{
			char temp[256];
			int itemp;
			strcpy(temp, quark_str(o_ptr->art_name));
			/* MEGA HACK by ita */
			if (strncmp(temp, "『", 2) == 0) t = object_desc_str(t, temp);
			else if (temp[0] == '\'')
			{
				itemp = strlen(temp);
				temp[itemp - 1] = 0;
				t = object_desc_str(t, "『");
				t = object_desc_str(t, &temp[1]);
				t = object_desc_str(t, "』");
			}
		}
		else if (o_ptr->name1)
		{
			artifact_type *a_ptr = &a_info[o_ptr->name1];
			if (strncmp(a_name + a_ptr->name, "『", 2) == 0)
			{
				t = object_desc_str(t, a_name + a_ptr->name);
			}
		}
		else if (o_ptr->ego_name)
		{
			t = object_desc_str(t, quark_str(o_ptr->ego_name));
		}
		else if (o_ptr->inscription)
		{
			cptr str = quark_str(o_ptr->inscription);

			while(*str)
			{
				if (iskanji(*str))
				{
					str += 2;
					continue;
				}
				if (*str == '#') break;
				str++;
			}
			if (*str)
			{
				/* Find the '#' */
				cptr str = my_strchr(quark_str(o_ptr->inscription), '#');

				/* Add the false name */
				t = object_desc_str(t,"『");
				t = object_desc_str(t, &str[1]);
				t = object_desc_str(t,"』");
			}
		}
	}
#else
	/* Hack -- Append "Artifact" or "Special" names */
	if (known && !fullname)
	{
		/* Is it a new random artifact ? */
		if (o_ptr->art_name)
		{
			t = object_desc_chr(t, ' ');
			t = object_desc_str(t, quark_str(o_ptr->art_name));
		}

		/* Grab any artifact name */
		else if (o_ptr->name1)
		{
			artifact_type *a_ptr = &a_info[o_ptr->name1];

			t = object_desc_chr(t, ' ');
			t = object_desc_str(t, a_name + a_ptr->name);
		}

		/* Grab any ego-item name */
		else
		{
			if (o_ptr->name2)
			{
				ego_item_type *e_ptr = &e_info[o_ptr->name2];

				t = object_desc_chr(t, ' ');
				t = object_desc_str(t, e_name + e_ptr->name);
			}

			if (o_ptr->ego_name)
			{
				t = object_desc_chr(t, ' ');
				t = object_desc_str(t, quark_str(o_ptr->ego_name));
			}
			else if (o_ptr->inscription && my_strchr(quark_str(o_ptr->inscription), '#'))
			{
				/* Find the '#' */
				cptr str = my_strchr(quark_str(o_ptr->inscription), '#');

				/* Add the false name */
				t = object_desc_chr(t, ' ');
				t = object_desc_str(t, &str[1]);
			}
		}
	}
#endif


	/* No more details wanted */
	if (mode & OD_NAME_ONLY) goto object_desc_done;

	/* Hack -- Chests must be described in detail */
	if (o_ptr->tval == TV_CHEST)
	{
		/* Not searched yet */
		if (!known)
		{
			/* Nothing */
		}

		/* May be "empty" */
		else if (!o_ptr->pval)
		{
#ifdef JP
			t = object_desc_str(t, "(空)");
#else
			t = object_desc_str(t, " (empty)");
#endif
		}

		/* May be "disarmed" */
		else if (o_ptr->pval < 0)
		{
			if (chest_traps[0 - o_ptr->pval])
			{
#ifdef JP
				t = object_desc_str(t, "(解除済)");
#else
				t = object_desc_str(t, " (disarmed)");
#endif
			}
			else
			{
#ifdef JP
				t = object_desc_str(t, "(非施錠)");
#else
				t = object_desc_str(t, " (unlocked)");
#endif
			}
		}

		/* Describe the traps, if any */
		else
		{
			/* Describe the traps */
			switch (chest_traps[o_ptr->pval])
			{
				case 0:
				{
#ifdef JP
					t = object_desc_str(t, "(施錠)");
#else
					t = object_desc_str(t, " (Locked)");
#endif
					break;
				}
				case CHEST_LOSE_STR:
				{
#ifdef JP
					t = object_desc_str(t, "(毒針)");
#else
					t = object_desc_str(t, " (Poison Needle)");
#endif
					break;
				}
				case CHEST_LOSE_CON:
				{
#ifdef JP
					t = object_desc_str(t, "(毒針)");
#else
					t = object_desc_str(t, " (Poison Needle)");
#endif
					break;
				}
				case CHEST_POISON:
				{
#ifdef JP
					t = object_desc_str(t, "(ガス・トラップ)");
#else
					t = object_desc_str(t, " (Gas Trap)");
#endif
					break;
				}
				case CHEST_PARALYZE:
				{
#ifdef JP
					t = object_desc_str(t, "(ガス・トラップ)");
#else
					t = object_desc_str(t, " (Gas Trap)");
#endif
					break;
				}
				case CHEST_EXPLODE:
				{
#ifdef JP
					t = object_desc_str(t, "(爆発装置)");
#else
					t = object_desc_str(t, " (Explosion Device)");
#endif
					break;
				}
				case CHEST_SUMMON:
				{
#ifdef JP
					t = object_desc_str(t, "(召喚のルーン)");
#else
					t = object_desc_str(t, " (Summoning Runes)");
#endif
					break;
				}
				default:
				{
#ifdef JP
					t = object_desc_str(t, "(マルチ・トラップ)");
#else
					t = object_desc_str(t, " (Multiple Traps)");
#endif
					break;
				}
			}
		}
	}


	/* Display the item like a weapon */
	if (f3 & TR3_SHOW_MODS) show_weapon = TRUE;

	/* Display the item like a weapon */
	if (o_ptr->to_h && o_ptr->to_d) show_weapon = TRUE;

	/* Display the item like armour */
	if (o_ptr->ac) show_armour = TRUE;


	/* Dump base weapon info */
	switch (o_ptr->tval)
	{
		/* Missiles and Weapons */
		case TV_SHOT:
		case TV_BOLT:
		case TV_ARROW:
		case TV_HAFTED:
		case TV_POLEARM:
		case TV_SWORD:
		case TV_DIGGING:

		/* Append a "damage" string */
		t = object_desc_chr(t, ' ');
		t = object_desc_chr(t, p1);
		t = object_desc_num(t, o_ptr->dd);
		t = object_desc_chr(t, 'd');
		t = object_desc_num(t, o_ptr->ds);
		t = object_desc_chr(t, p2);

		/* All done */
		break;


		/* Bows get a special "damage string" */
		case TV_BOW:

		/* Mega-Hack -- Extract the "base power" */
		power = bow_tmul(o_ptr->sval);

		/* Apply the "Extra Might" flag */
		if (f3 & TR3_XTRA_MIGHT) power++;

		/* Append a special "damage" string */
		t = object_desc_chr(t, ' ');
		t = object_desc_chr(t, p1);
		t = object_desc_chr(t, 'x');
		t = object_desc_num(t, power);
		t = object_desc_chr(t, p2);

		/* All done */
		break;
	}


	/* Add the weapon bonuses */
	if (known)
	{
		/* Show the tohit/todam on request */
		if (show_weapon)
		{
			t = object_desc_chr(t, ' ');
			t = object_desc_chr(t, p1);
			t = object_desc_int(t, o_ptr->to_h);
			t = object_desc_chr(t, ',');
			t = object_desc_int(t, o_ptr->to_d);
			t = object_desc_chr(t, p2);
		}

		/* Show the tohit if needed */
		else if (o_ptr->to_h)
		{
			t = object_desc_chr(t, ' ');
			t = object_desc_chr(t, p1);
			t = object_desc_int(t, o_ptr->to_h);
			t = object_desc_chr(t, p2);
		}

		/* Show the todam if needed */
		else if (o_ptr->to_d)
		{
			t = object_desc_chr(t, ' ');
			t = object_desc_chr(t, p1);
			t = object_desc_int(t, o_ptr->to_d);
			t = object_desc_chr(t, p2);
		}
	}

	bow_ptr = &inventory[INVEN_BOW];

	/* If have a firing weapon + ammo matches bow */
	if (bow_ptr->k_idx && (o_ptr->tval == p_ptr->tval_ammo))
	{
		int avgdam = o_ptr->dd * (o_ptr->ds + 1) * 10 / 2;
		int tmul = bow_tmul(bow_ptr->sval);
		s16b energy_fire = bow_energy(bow_ptr->sval);

		/* See if the bow is "known" - then set damage bonus */
		if (object_known_p(bow_ptr)) avgdam += (bow_ptr->to_d * 10);

		/* Effect of ammo */
		if (known) avgdam += (o_ptr->to_d * 10);

		/* Get extra "power" from "extra might" */
		if (p_ptr->xtra_might) tmul++;

		tmul = tmul * (100 + (int)(adj_str_td[p_ptr->stat_ind[A_STR]]) - 128);

		/* Launcher multiplier */
		avgdam *= tmul;
		avgdam /= (100 * 10);
	
		if (avgdam < 0) avgdam = 0;

		/* Display (shot damage/ avg damage) */
		t = object_desc_chr(t, ' ');
		t = object_desc_chr(t, p1);
		t = object_desc_num(t, avgdam);
		t = object_desc_chr(t, '/');

		if (p_ptr->num_fire == 0)
		{
			t = object_desc_chr(t, '0');
		}
		else
		{
			/* Calc effects of energy */
			avgdam *= (p_ptr->num_fire * 100);
			avgdam /= energy_fire * 100;
			t = object_desc_num(t, avgdam);
		}

		t = object_desc_chr(t, p2);
	}

	/* Add the armor bonuses */
	if (known)
	{
		/* Show the armor class info */
		if (show_armour)
		{
			t = object_desc_chr(t, ' ');
			t = object_desc_chr(t, b1);
			t = object_desc_num(t, o_ptr->ac);
			t = object_desc_chr(t, ',');
			t = object_desc_int(t, o_ptr->to_a);
			t = object_desc_chr(t, b2);
		}

		/* No base armor, but does increase armor */
		else if (o_ptr->to_a)
		{
			t = object_desc_chr(t, ' ');
			t = object_desc_chr(t, b1);
			t = object_desc_int(t, o_ptr->to_a);
			t = object_desc_chr(t, b2);
		}
	}

	/* Hack -- always show base armor */
	else if (show_armour)
	{
		t = object_desc_chr(t, ' ');
		t = object_desc_chr(t, b1);
		t = object_desc_num(t, o_ptr->ac);
		t = object_desc_chr(t, b2);
	}


	/* No more details wanted */
	if (mode & OD_NAME_AND_ENCHANT) goto object_desc_done;


	if (known) /* Known item only */
	{
		/*
		 * Hack -- Wands and Staffs have charges.  Make certain how many charges
		 * a stack of staffs really has is clear. -LM-
		 */
		if (((o_ptr->tval == TV_STAFF) || (o_ptr->tval == TV_WAND)))
		{
			/* Dump " (N charges)" */
			t = object_desc_chr(t, ' ');
			t = object_desc_chr(t, p1);

			/* Clear explaination for staffs. */
			if ((o_ptr->tval == TV_STAFF) && (o_ptr->number > 1))
			{
				t = object_desc_num(t, o_ptr->number);
				t = object_desc_str(t, "x ");
			}
			t = object_desc_num(t, o_ptr->pval);
#ifdef JP
			t = object_desc_str(t, "回分");
#else
			t = object_desc_str(t, " charge");
			if (o_ptr->pval != 1) t = object_desc_chr(t, 's');
#endif

			t = object_desc_chr(t, p2);
		}
		/* Hack -- Rods have a "charging" indicator.  Now that stacks of rods may
		 * be in any state of charge or discharge, this now includes a number. -LM-
		 */
		else if (o_ptr->tval == TV_ROD)
		{
			/* Hack -- Dump " (# charging)" if relevant */
			if (o_ptr->timeout)
			{
				/* Stacks of rods display an exact count of charging rods. */
				if (o_ptr->number > 1)
				{
					/* Paranoia. */
					if (k_ptr->pval == 0) k_ptr->pval = 1;

					/* Find out how many rods are charging, by dividing
					 * current timeout by each rod's maximum timeout.
					 * Ensure that any remainder is rounded up.  Display
					 * very discharged stacks as merely fully discharged.
					 */
					power = (o_ptr->timeout + (k_ptr->pval - 1)) / k_ptr->pval;
					if (power > o_ptr->number) power = o_ptr->number;

					/* Display prettily. */
					t = object_desc_str(t, " (");
					t = object_desc_num(t, power);
#ifdef JP
					t = object_desc_str(t, "本 充填中)");
#else
					t = object_desc_str(t, " charging)");
#endif
				}

				/* "one Rod of Perception (1 charging)" would look tacky. */
				else
				{
#ifdef JP
					t = object_desc_str(t, "(充填中)");
#else
					t = object_desc_str(t, " (charging)");
#endif
				}
			}
		}

		/* Dump "pval" flags for wearable items */
		if (f1 & TR1_PVAL_MASK)
		{
			/* Start the display */
			t = object_desc_chr(t, ' ');
			t = object_desc_chr(t, p1);

			/* Dump the "pval" itself */
			t = object_desc_int(t, o_ptr->pval);

			/* Do not display the "pval" flags */
			if (f3 & TR3_HIDE_TYPE)
			{
				/* Nothing */
			}

			/* Speed */
			else if (f1 & TR1_SPEED)
			{
				/* Dump " to speed" */
#ifdef JP
				t = object_desc_str(t, "加速");
#else
				t = object_desc_str(t, " to speed");
#endif
			}

			/* Attack speed */
			else if (f1 & TR1_BLOWS)
			{
				/* Add " attack" */
#ifdef JP
				t = object_desc_str(t, "攻撃");
#else
				t = object_desc_str(t, " attack");

				/* Add "attacks" */
				if (ABS(o_ptr->pval) != 1) t = object_desc_chr(t, 's');
#endif
			}

			/* Stealth */
			else if (f1 & TR1_STEALTH)
			{
				/* Dump " to stealth" */
#ifdef JP
				t = object_desc_str(t, "隠密");
#else
				t = object_desc_str(t, " to stealth");
#endif
			}

			/* Search */
			else if (f1 & TR1_SEARCH)
			{
				/* Dump " to searching" */
#ifdef JP
				t = object_desc_str(t, "探索");
#else
				t = object_desc_str(t, " to searching");
#endif
			}

			/* Infravision */
			else if (f1 & TR1_INFRA)
			{
				/* Dump " to infravision" */
#ifdef JP
				t = object_desc_str(t, "赤外線視力");
#else
				t = object_desc_str(t, " to infravision");
#endif
			}

			/* Finish the display */
			t = object_desc_chr(t, p2);
		}

		/* Hack -- Process Lanterns/Torches */
		if ((o_ptr->tval == TV_LITE) && ((o_ptr->sval == SV_LITE_TORCH) || (o_ptr->sval == SV_LITE_LANTERN)))
		{
			/* Hack -- Turns of light for normal lites */
#ifdef JP
			t = object_desc_chr(t, '(');
#else
			t = object_desc_str(t, " (with ");
#endif
			t = object_desc_num(t, o_ptr->xtra3);
#ifdef JP
			t = object_desc_str(t, "ターンの寿命)");
#else
			t = object_desc_str(t, " turns of light)");
#endif
		}

		/* Indicate charging objects, but not rods. */
		if (o_ptr->timeout && (o_ptr->tval != TV_ROD))
		{
			/* Hack -- Dump " (charging)" if relevant */
#ifdef JP
			t = object_desc_str(t, "(充填中)");
#else
			t = object_desc_str(t, " (charging)");
#endif
		}
	}


	/* No more details wanted */
	if (mode & OD_OMIT_INSCRIPTION) goto object_desc_done;


	/* Prepare real inscriptions in a buffer */
	tmp_val2[0] = '\0';

	/* Auto abbreviation inscribe */
	if ((abbrev_extra || abbrev_all) && (o_ptr->ident & IDENT_MENTAL))
	{
		if (!o_ptr->inscription || !my_strchr(quark_str(o_ptr->inscription), '%'))
		{
			bool kanji, all;

#ifdef JP
			kanji = TRUE;
#else
			kanji = FALSE;
#endif
			all = abbrev_all;

			get_ability_abbreviation(tmp_val2, o_ptr, kanji, all, FALSE);
		}
	}

	/* Use the standard inscription if available */
	if (o_ptr->inscription)
	{
		char buff[1024];

		if (tmp_val2[0]) strcat(tmp_val2, ", ");

		/* Get inscription and convert {%} */
		get_inscription(buff, o_ptr);

		/* strcat with correct treating of kanji */
		my_strcat(tmp_val2, buff, sizeof(tmp_val2));
	}


	/* No fake inscription yet */
	fake_insc_buf[0] = '\0';

	/* Use the game-generated "feeling" otherwise, if available */
	if (o_ptr->feeling)
	{
		strcpy(fake_insc_buf, game_inscriptions[o_ptr->feeling]);
	}

	/* Note "cursed" if the item is known to be cursed */
	else if (cursed_p(o_ptr) && (known || (o_ptr->ident & IDENT_SENSE)))
	{
#ifdef JP
		strcpy(fake_insc_buf, "呪われている");
#else
		strcpy(fake_insc_buf, "cursed");
#endif
	}

	/* Note "unidentified" if the item is unidentified */
	else if (((o_ptr->tval == TV_RING) || (o_ptr->tval == TV_AMULET)
		   || (o_ptr->tval == TV_LITE) || (o_ptr->tval == TV_FIGURINE))
		 && aware && !known
		 && !(o_ptr->ident & IDENT_SENSE))
	{
#ifdef JP
		strcpy(fake_insc_buf, "未鑑定");
#else
		strcpy(fake_insc_buf, "unidentified");
#endif
	}

	/* Mega-Hack -- note empty wands/staffs */
	else if (!known && (o_ptr->ident & IDENT_EMPTY))
	{
#ifdef JP
		strcpy(fake_insc_buf, "空");
#else
		strcpy(fake_insc_buf, "empty");
#endif
	}

	/* Note "tried" if the object has been tested unsuccessfully */
	else if (!aware && object_tried_p(o_ptr))
	{
#ifdef JP
		strcpy(fake_insc_buf, "未判明");
#else
		strcpy(fake_insc_buf, "tried");
#endif
	}

	/* Note the discount, if any */
	if (o_ptr->discount)
	{
		/* Hidden by real inscription unless in a store */
		if (!tmp_val2[0] || (o_ptr->ident & IDENT_STORE))
		{
			char discount_num_buf[4];

			/* Append to other fake inscriptions if any */
			if (fake_insc_buf[0]) strcat(fake_insc_buf, ", ");

			(void)object_desc_num(discount_num_buf, o_ptr->discount);
			strcat(fake_insc_buf, discount_num_buf);
#ifdef JP
			strcat(fake_insc_buf, "%引き");
#else
			strcat(fake_insc_buf, "% off");
#endif
		}
	}


	/* Append the inscription, if any */
	if (fake_insc_buf[0] || tmp_val2[0])
	{
		/* Append the inscription */
		t = object_desc_chr(t, ' ');
		t = object_desc_chr(t, c1);

		/* Append fake inscriptions */
		if (fake_insc_buf[0])
		{
			t = object_desc_str(t, fake_insc_buf);
		}

		/* Append a separater */
		if (fake_insc_buf[0] && tmp_val2[0])
		{
			t = object_desc_chr(t, ',');
			t = object_desc_chr(t, ' ');
		}

		/* Append real inscriptions */
		if (tmp_val2[0])
		{
			t = object_desc_str(t, tmp_val2);
		}

		t = object_desc_chr(t, c2);
	}

object_desc_done:
	my_strcpy(buf, tmp_val, MAX_NLEN);
}
Пример #19
0
void private_chat(Link msg, int new_fd)
{    
    int target_sfd = link_search_name(msg);

    Node msg2;

    memset(&msg2, 0, sizeof(Node));
    if(target_sfd != -1)
    {
        msg2.action = msg->action;
	msg2.online_sfd = msg->online_sfd;

        my_strcpy(msg2.name, msg->name);
        my_strcpy(msg2.target_user, msg->target_user);
        my_strcpy(msg2.message, msg->message);

        char filename[50];

        FILE *file;


	memset(filename, 0, sizeof(filename));

	sprintf(filename, "chathistory/chat%s.txt", msg->id);
            
	if((file = fopen(filename, "a")) == NULL)
        {
            perror_exit1("open error!");
        }

        chathistory_write1(&file, msg);

        if(fclose(file) != 0)
        {
            perror_exit1("close error!");
        }
        
	memset(filename, 0, sizeof(filename));


	sprintf(filename, "chathistory/chat%s.txt", link_search_id2(msg));
            
	if((file = fopen(filename, "a")) == NULL)
        {
            perror_exit1("open error!");
        }

        chathistory_write2(&file, msg);

        if(fclose(file) != 0)
        {
            perror_exit1("close error!");
        }

        write(target_sfd, &msg2, sizeof(Node));
    }
    else
    {
        char str[9];

        char sql[1024];
        char *errmsg;

        sqlite3 *db;
        
	memset(str, 0, sizeof(str));
	my_strcpy(str, msg->id);

        msg->action = FAILED_NOBODY;

        printf("%s %s\n",msg->id,msg->password);
        printf("aaa\n");

        sqlite3_open("users.db", &db);
        sprintf(sql, "select id from user where name='%s'", msg->target_user);

        sqlite3_exec(db, sql, chat_callback, msg, &errmsg);

	if(msg->action == SUCCESS_OFFLINE)
	{
	    char filename[50];

            FILE *file;
	    
	    memset(filename, 0, sizeof(filename));

	    sprintf(filename, "chathistory/chat%s.txt", str);
            
	    if((file = fopen(filename, "a")) == NULL)
            {
                perror_exit1("open error!");
            }

            chathistory_write3(&file, msg);

            if(fclose(file) != 0)
            {
                perror_exit1("close error!");
            }
         

	    memset(filename, 0, sizeof(filename));

	    sprintf(filename, "chathistory/chat%s.txt", msg->id);
            
	    if((file = fopen(filename, "a")) == NULL)
            {
                perror_exit1("open error!");
            }

            chathistory_write4(&file, msg);

            if(fclose(file) != 0)
            {
                perror_exit1("close error!");
            }


	    memset(filename, 0, sizeof(filename));

	    sprintf(filename, "offmsg/msg%s.txt", msg->id);
            
	    if((file = fopen(filename, "a")) == NULL)
            {
                perror_exit1("open error!");
            }

            file_write(&file, msg);

            if(fclose(file) != 0)
            {
                perror_exit1("close error!");
            }
	}

	write(new_fd, msg, sizeof(Node));
    }
}
Пример #20
0
int main(int argc, char * * argv)
{
    printf("Welcome to PA02.\n"
	   "\n"
	   "You are encouraged to edit this file in order to test\n"
	   "the behavior of the functions you write in answer02.c\n"
	   "\n"
	   "This file will not be marked, and should not be\n"
	   "submitted.\n"
	   "\n"
	   "Don't forget to post questions on blackboard, and ask\n"
	   "the TAs and your classmates for help.\n"
	   "\n");

    const char * s1 = "Hello World!";
    const char * s2 = "";
    const char * s3 = "foo";

    // -- my_strlen, should be: 12, 0, and 3
    printf("my_strlen(\"%s\") = %d\n", s1, (int) my_strlen(s1));
    printf("my_strlen(\"%s\") = %d\n", s2, (int) my_strlen(s2));
    printf("my_strlen(\"%s\") = %d\n", s3, (int) my_strlen(s3));
    printf("\n");

    // -- my_countchar, should be: 3, 0, and 2
    printf("my_countchar(\"%s\", 'l') = %d\n", s1, (int) my_countchar(s1, 'l'));
    printf("my_countchar(\"%s\", 'o') = %d\n", s2, (int) my_countchar(s2, 'o'));
    printf("my_countchar(\"%s\", 'o') = %d\n", s3, (int) my_countchar(s3, 'o'));
    printf("\n");
    
    // -- my_strchr, should be: "llo World!", "(null)", and ""
    printf("my_strchr(\"%s\", 'l') = %s\n", s1, my_strchr(s1, 'l'));
    printf("my_strchr(\"%s\", 'o') = %s\n", s2, my_strchr(s2, 'o'));
    printf("my_strchr(\"%s\", '\\0') = %s\n", s3, my_strchr(s3, '\0'));
    printf("\n");

    // -- my_strrchr, should be: "ld!", "(null)", and ""
    printf("my_strrchr(\"%s\", 'l') = %s\n", s1, my_strrchr(s1, 'l'));
    printf("my_strrchr(\"%s\", 'o') = %s\n", s2, my_strrchr(s2, 'o'));
    printf("my_strrchr(\"%s\", '\\0') = %s\n", s3, my_strrchr(s3, '\0'));
    printf("my_strrchr(\"\", '\\0') = %s\n", my_strrchr("", '\0'));
    printf("my_strrchr(\"Find First 'F' from right\", 'F') = %s\n", my_strrchr("Find First 'F' from right", 'F'));
    printf("my_strrchr(\"Find first char\", 'F') = %s\n", my_strrchr("Find first char", 'F'));
    printf("my_strrchr(\"!Find last char!\", '!') = %s\n", my_strrchr("!Find last char!", '!'));
    printf("\n");

    // -- my_strstr, should be: "World!", "Hello World!", "(null)"
    printf("my_strstr(\"%s\", \"World\") = %s\n", s1, my_strstr(s1, "World"));
    printf("my_strstr(\"%s\", \"\") = %s\n", s1, my_strstr(s1, ""));
    printf("my_strstr(\"%s\", \"hello\") = %s\n", s1, my_strstr(s1, "hello"));
    printf("\n");

    // -- my_strcpy. For this function you need a buffer where you
    // copy the string to. 
    char buffer[BUFFER_LEN];
    my_strcpy(buffer, s1);
    printf("my_strcpy(buffer, \"%s\"), buffer = \"%s\"\n", s1, buffer);
    my_strcpy(buffer, s2);
    printf("my_strcpy(buffer, \"%s\"), buffer = \"%s\"\n", s2, buffer);
    my_strcpy(buffer, s3);
    printf("my_strcpy(buffer, \"%s\"), buffer = \"%s\"\n", s3, buffer);
    printf("\n");

    // -- my_strcat. You will have to do this yourself... just
    // look at my_strcpy for an example, and go from there.
    char dest[BUFFER_LEN];
    char src[BUFFER_LEN];
    my_strcpy(dest, "Hello ");
    my_strcpy(src, "Zippy!");
    printf("my_strcat(\"Hello \", \"%s\") = \"%s\"\n", src,  my_strcat(dest, src));
    my_strcpy(dest, "");
    my_strcpy(src, "Hi!");
    printf("my_strcat(\"\", \"%s\") = \"%s\"\n", src,  my_strcat(dest, src));
    printf("\n");
    
    // -- my_isspace. You will have to do this for yourself.
    printf("my_isspace(' ') = %d\n", my_isspace(' '));
    printf("my_isspace('\\t') = %d\n", my_isspace('\t'));
    printf("my_isspace('\\v') = %d\n", my_isspace('\v'));
    printf("my_isspace('\\f') = %d\n", my_isspace('\f'));
    printf("my_isspace('\\n') = %d\n", my_isspace('\n'));
    printf("my_isspace('\\r') = %d\n", my_isspace('\r'));
    printf("\n");

    // -- my_atoi. You will have to do this for yourself.
    printf("my_atoi(\"%s\") = %d\n", s1, my_atoi(s1));
    printf("my_atoi(\"32 students got an F\") = %d\n", my_atoi("32 students got an F"));
    printf("my_atoi(\"\\n\\t\\v -273\") = %d\n", my_atoi("\n\t\v -273"));
    printf("\n");
    return EXIT_SUCCESS;
}
Пример #21
0
/**
 * Show previous messages to the user
 *
 * The screen format uses line 0 and 23 for headers and prompts,
 * skips line 1 and 22, and uses line 2 thru 21 for old messages.
 *
 * This command shows you which commands you are viewing, and allows
 * you to "search" for strings in the recall.
 *
 * Note that messages may be longer than 80 characters, but they are
 * displayed using "infinite" length, with a special sub-command to
 * "slide" the virtual display to the left or right.
 *
 * Attempt to only hilight the matching portions of the string.
 */
void do_cmd_messages(void)
{
  ui_event ke;
  
  int i, j, n, q;
  int wid, hgt;
  
  char shower[80];
  char finder[80];
  char p[80];  
  
  /* Wipe finder */
  my_strcpy(finder, "", sizeof(shower));
  
  /* Wipe shower */
  my_strcpy(shower, "", sizeof(finder));
  
  
  /* Total messages */
  n = messages_num();
  
  /* Start on first message */
  i = 0;
  
  /* Start at leftmost edge */
  q = 0;
  
  /* Get size */
  Term_get_size(&wid, &hgt);
  
  /* Prompt */
  strncpy(p, "[Press 'p' for older, 'n' for newer, ..., or ESCAPE]", 80);

  /* Save screen */
  screen_save();
  
  /* Adjust the buttons */
  button_backup_all();
  button_kill_all();
  button_add("ESC", ESCAPE);
  button_add("-", '-');
  button_add("=", '=');
  button_add("/", '/');
  button_add("p", 'p');
  button_add("n", 'n');
  button_add("+", '+');
  button_add("->", '6');
  button_add("<-", '4');
  p_ptr->redraw |= (PR_BUTTONS);

  /* Process requests until done */
  while (1)
    {
      /* Clear screen */
      Term_clear();
      
      /* Dump messages */
      for (j = 0; (j < hgt - 4) && (i + j < n); j++)
	{
	  const char *msg = message_str((s16b)(i+j));
	  byte attr = message_color((s16b)(i+j));
	  
	  /* Apply horizontal scroll */
	  msg = ((int)strlen(msg) >= q) ? (msg + q) : "";
	  
	  /* Dump the messages, bottom to top */
	  Term_putstr(0, hgt - 3 - j, -1, attr, msg);
	  
	  /* Hilight "shower" */
	  if (shower[0])
	    {
	      const char *str = msg;
	      
	      /* Display matches */
	      while ((str = strstr(str, shower)) != NULL)
		{
		  int len = strlen(shower);
		  
		  /* Display the match */
		  Term_putstr(str-msg, hgt - 3 - j, len, TERM_YELLOW, shower);
		  
		  /* Advance */
		  str += len;
		}
	    }
	}
      
      /* Display header XXX XXX XXX */
      prt(format("Message Recall (%d-%d of %d), Offset %d",
		 i, i + j - 1, n, q), 0, 0);
      
      /* Display prompt (not very informative) */
      prt(p, hgt - 1, 0);
      redraw_stuff(p_ptr);
      
      /* Get a command */
      ke = inkey_ex();
      
      /* Exit on Escape */
      if (ke.key.code == ESCAPE) break;
      
      /* Hack -- Save the old index */
      j = i;
      
      /* Horizontal scroll */
      if (ke.key.code == '4')
	{
	  /* Scroll left */
	  q = (q >= wid / 2) ? (q - wid / 2) : 0;
	  
	  /* Success */
	  continue;
	}
      
      /* Horizontal scroll */
      if (ke.key.code == '6')
	{
	  /* Scroll right */
	  q = q + wid / 2;
	  
	  /* Success */
	  continue;
	}
      
      /* Hack -- handle show */
      if (ke.key.code == '=')
	{
	  /* Prompt */
	  prt("Show: ", hgt - 1, 0);
	  
	  /* Get a "shower" string, or continue */
	  if (!askfor_aux(shower, sizeof shower, NULL)) continue;
	  
	  /* Okay */
	  continue;
	}
      
      /* Hack -- handle find */
      if (ke.key.code == '/')
	{
	  s16b z;
	  
	  /* Prompt */
	  prt("Find: ", hgt - 1, 0);
	  
	  /* Get a "finder" string, or continue */
	  if (!askfor_aux(finder, sizeof finder, NULL)) continue;
	  
	  /* Show it */
	  my_strcpy(shower, finder, sizeof(shower));
	  
	  /* Scan messages */
	  for (z = i + 1; z < n; z++)
	    {
	      const char *msg = message_str(z);
	      
	      /* Search for it */
	      if (strstr(msg, finder))
		{
		  /* New location */
		  i = z;
		  
		  /* Done */
		  break;
		}
	    }
	}
      
      /* Recall 20 older messages */
      if ((ke.key.code == 'p') || (ke.key.code == KTRL('P')) || (ke.key.code == ' '))
	{
	  /* Go older if legal */
	  if (i + 20 < n) i += 20;
	}
      
      /* Recall 10 older messages */
      if (ke.key.code == '+')
	{
	  /* Go older if legal */
	  if (i + 10 < n) i += 10;
	}
      
      /* Recall 1 older message */
      if ((ke.key.code == '8') || (ke.key.code == '\n') || (ke.key.code == '\r'))
	{
	  /* Go older if legal */
	  if (i + 1 < n) i += 1;
	}
      
      /* Recall 20 newer messages */
      if ((ke.key.code == 'n') || (ke.key.code == KTRL('N')))
	{
	  /* Go newer (if able) */
	  i = (i >= 20) ? (i - 20) : 0;
	}
      
      /* Recall 10 newer messages */
      if (ke.key.code == '-')
	{
	  /* Go newer (if able) */
	  i = (i >= 10) ? (i - 10) : 0;
	}
      
      /* Recall 1 newer messages */
      if (ke.key.code == '2')
	{
	  /* Go newer (if able) */
	  i = (i >= 1) ? (i - 1) : 0;
	}
      
      /* Scroll forwards or backwards using mouse clicks */
      if (ke.mouse.button)
      {
	  if (ke.mouse.y <= hgt / 2)
	  {
	      /* Go older if legal */
	      if (i + 20 < n) i += 20;
	  }
	  else
	  {
	      /* Go newer (if able) */
	      i = (i >= 20) ? (i - 20) : 0;
	  }
      }
      
      /* Hack -- Error of some kind */
      if (i == j) bell(NULL);
    }
  
  /* Adjust the buttons */
  button_restore();

  /* Load screen */
  screen_load();
}
Пример #22
0
void read_message(void *arg)
{
    int fd = *((int *)arg);
    int to_fd;
    int count;
    int result;  
    int temp;

    struct message msg;
    struct online *p;
    struct online *q;
    struct online *m;

    while(1)
    {
         if((count = read(fd,&msg,sizeof(msg))) != 0)  //读取客户端传来的信息
	 {
             //printf("aaaaaaaaaaaaa%d\n",msg.action);
	     if(msg.action == log)
	     {
	         p = (struct online*)malloc(sizeof(struct online));
		 p->fd = fd;
		 p->ID = msg.ID;
		 strcpy(p->passwd,msg.passwd);
		
		 if(find_id(msg.ID) == 0)       //找到已经登录的ID号,返回have_log,防止重复登录
		 {
		     msg.action = have_log;

		     write(fd,&msg,sizeof(msg));
		 }
                 else
		 {
	             result = server_log(p);  //去数据库中核实登录信息和注册信息是否一致
                 
                 //printf("bbbbbbbbbbbbb%d\n",result);

                     strcpy(msg.name,p->name);

		     if(result == log_ok)
		     {
		         msg.action = log_ok;

		         insert_online(p);    //登录成功后,插入链表,用来显示在线的用户

		         write(fd,&msg,sizeof(msg));

		         sleep(8);

		         read_unlog_msg(msg.name,fd);    //读保存在服务器里的离线消息
		     }

		     if(result == admin_log_ok)
		     {
		         msg.action = admin_log_ok;

		         insert_online(p);
		         write(fd,&msg,sizeof(msg));

		         sleep(8);
		     
		         read_unlog_msg(msg.name,fd);
		     }

		 
		 
		     if(result == passwd_error)
		     {
		         msg.action = passwd_error;
       		         write(fd,&msg,sizeof(msg));
		     }
		     
		     if(result == ID_error)
		     {
		         msg.action = ID_error;
	                 write(fd,&msg,sizeof(msg));
		     }
		 
                 }
             }

	     if(msg.action == reg)
	     {
	         p = (struct online*)malloc(sizeof(struct online)); //给结构体p分配空间

                 p->fd = fd;                                        //为写入数据库作准备
		 strcpy(p->name,msg.name);
		 strcpy(p->passwd,msg.passwd);

		 //result = insert_online(p);

		 //if(result == insert_ok)
                 srand(time(0));  //防止随机数重复
		 temp = rand();   //生成随机数
		 p->ID = temp;
		 msg.ID = p->ID;         //返回给客户端的ID和reg_ok
		 msg.action = reg_ok;    //通知客户端“注册成功”的标志
            
		 my_sqlite(p);         //注册时的信息写入数据库
		 write(fd,&msg,sizeof(msg));//把生成的id号传给客户端
	     }

	     if(msg.action == say)
	     {
                 if(find_ban(fd) == ban)
		 {
		     msg.action = ban;
		     write(fd,&msg,sizeof(msg));

		     msg.action = -2;                  //防止和谁聊天,谁被禁言
		 }
	        
		 else
		 {
	             to_fd = find_fd(msg.toname);//聊天通过寻找对方的fd,找不到返回-1,找到返回对方的fd
		 
		     if(to_fd == -1)
		     {
		         msg.action = to_fd;

                         reserve_unlog_msg(&msg);

			 reserve_chat_msg(&msg);

		         write(fd,&msg,sizeof(msg));//没找到客户2,就返回客户1的fd
		     }
		     else
		     {
		         
			 reserve_chat_msg(&msg);
			 
			 write(to_fd,&msg,sizeof(msg));//找到了客户2,就返回客户2的fd
		     }
		 }
	     }
	     
	     if(msg.action == say_all)
	     {
                 if(find_ban(fd) == ban)
		 {
		     msg.action = ban;
		     write(fd,&msg,sizeof(msg));

		     msg.action = -2;
		 }
	         else
		 {
	             struct online *temp = head;     //遍历链表,传送每一个fd
		 
	             reserve_chat_msg(&msg);
		     
		     while(temp != NULL)
		     {    
			 write(temp->fd,&msg,sizeof(msg));
		         temp = temp->next;
		     }
		 }
	     }

	     if(msg.action == send_face)
	     {
                 if(find_ban(fd) == ban)
		 {
		     msg.action = ban;
		     write(fd,&msg,sizeof(msg));

		     msg.action = -2;                  //防止和谁聊天,谁被禁言
		 }
		 else
		 {
                     to_fd = find_fd(msg.toname);
		 
		     if(to_fd == -1)
		     {
		         msg.action = to_fd;        

		         write(fd,&msg,sizeof(msg));
		     }
		     else
		     {   
			 write(to_fd,&msg,sizeof(msg));
		     }
		 }
	     }

	     if(msg.action == change)
	     {   
	         struct online *temp = head;           //通过查找ID,替换昵称和密码
	         
		 q = (struct online*)malloc(sizeof(struct online));
		 
		 while(temp->fd == fd)
		 {   
		     q->ID = msg.ID;
		     strcpy(q->passwd,msg.passwd);
		     strcpy(q->name,msg.name);

		     //printf("aaaaaaaaaa%ldaaaaaaa%saaaaaaa%s\n",q->ID,q->passwd,q->name);
		 
	             result = server_change(q);
                      
                     //printf("cccccccccccccccckui zi shi sha bi!\n");

		     if(result == change_ok)
		     {
		         msg.action = change_ok;
                         write(fd,&msg,sizeof(msg));
			 break;
		     }

		     else
		     {
		         msg.action = change_error;
		         write(fd,&msg,sizeof(msg));
			 break;
		     }

		     temp = temp->next;
		 }
	     }

	     if(msg.action == show)
	     {      
	         struct online *temp = head;     //遍历链表,传送每一个fd
		 while(temp != NULL)
		 {
		     msg.ID = temp->ID;             //错误:这两句话要加,不然信息是同一个人的
		     my_strcpy(msg.name,temp->name);
		     write(fd,&msg,sizeof(msg)); //错误:这里是fd,是在发过来的客户的界面显示
		     temp = temp->next;
		 }
	     }

	     if(msg.action == quit)
	     {
		 //printf("aaaaaaaaaaaaa%ld\n",msg.ID);
	         m = (struct online*)malloc(sizeof(struct online));
		 m->fd = fd;
		 //m->ID = msg.ID;
		 //my_strcpy(m->passwd,msg.passwd);
		 //my_strcpy(m->name,msg.name);
		 
		 //printf("aaaaaaaaaaaaa%ld\n",msg.ID);

	         delete_online(m);      //链表中不显示该用户
		 
		 msg.action = quit_ok;
		 
		 write(fd,&msg,sizeof(msg));

                 /*
		 if(result == delete_error)
		 {
		     msg.action = quit_error;
		     write(fd,&msg,sizeof(msg));
		 }
		 */
	     }

	     if(msg.action == kick)
	     {	
		 to_fd = find_fd(msg.toname);
	         //fd = find_fd(msg.name);
                 if(to_fd == -1 || my_strcmp(msg.name,msg.toname) == 0)
		 {
		     msg.action = -1;

		     write(fd,&msg,sizeof(msg));
		 }
		 
		 else
		 {
		     m = (struct online*)malloc(sizeof(struct online));
		 
		     m->fd = to_fd;
	         
		     delete_online(m);      //链表中不显示该用户
		 
		     msg.action = kick_ok;
		  
		     write(fd,&msg,sizeof(msg));
		 
		     write(to_fd,&msg,sizeof(msg));
		 }
	     }

             if(msg.action == ban)
	     {
	         //printf("nnnnnnn%s\n",msg.toname);

	         to_fd = find_fd(msg.toname);

		 struct online *temp;
		 struct online *str = head;

		 temp = (struct online*)malloc(sizeof(struct online));

		 while(str != NULL)
		 {
                     msg.action = ban_tell_all;  //不能写在后面,找到了就要发过去

                     write(str->fd,&msg,sizeof(msg));

		     if(str->fd == to_fd)
		     {
		         temp->fd = to_fd;
			 temp->ID = str->ID;
			 my_strcpy(temp->name,str->name);

			 //insert_online(temp);   错误:不能插入head中,那是显示在线链表的
			 insert_ban(temp);   //建立一个禁言链表
		     }
		     
		     str = str->next;        
		 }
	     }

	     if(msg.action == solve_ban)
	     {
	        
		 to_fd = find_fd(msg.toname);

	     
		 if((find_ban(to_fd)) == -1)
		 {
	        //printf("aaaaaaaaaaaaaaaaaa\n"); 
		     msg.action = solve_error;

		     write(fd,&msg,sizeof(msg));
	        //printf("aaaaaaaaaaaaaaaaaa\n"); 
		 }
	         
		 else
		 {
		     m = (struct online*)malloc(sizeof(struct online));
		 
		     m->fd = to_fd;
	         
		     delete_ban(m);  //删除禁言链表中该用户名字

		     msg.action = solve_ban;

		     struct online *temp = head;

		     while(temp != NULL)          //通知所有人,该用户被解禁了
                     {
		         write(temp->fd,&msg,sizeof(msg));
		         temp = temp->next;
		     }
		 }
	     }

	     if(msg.action == see_record)
	     {

	         //printf("cccccccccccccccccccccccccc\n");
		 read_chat_msg(msg.name,fd);

		 write(fd,&msg,sizeof(msg));
	     }
	 }

	 else              //客户端ctrl+c之后,将在线的用户删除掉,show的时候少掉这个异常退出的用户
	 {
             struct online *m = (struct online*)malloc(sizeof(struct online));
		 
	     m->fd = fd;
	         
	     delete_online(m);   
	 }
    }
}