Пример #1
0
/*
 * Find the default paths to all of our important sub-directories.
 *
 * The purpose of each sub-directory is described in "variable.c".
 *
 * All of the sub-directories should, by default, be located inside
 * the main "lib" directory, whose location is very system dependant.
 *
 * This function takes a writable buffer, initially containing the
 * "path" to the "lib" directory, for example, "/pkg/lib/angband/",
 * or a system dependant string, for example, ":lib:".  The buffer
 * must be large enough to contain at least 32 more characters.
 *
 * Various command line options may allow some of the important
 * directories to be changed to user-specified directories, most
 * importantly, the "info" and "user" and "save" directories,
 * but this is done after this function, see "main.c".
 *
 * In general, the initial path should end in the appropriate "PATH_SEP"
 * string.  All of the "sub-directory" paths (created below or supplied
 * by the user) will NOT end in the "PATH_SEP" string, see the special
 * "path_build()" function in "util.c" for more information.
 *
 * Mega-Hack -- support fat raw files under NEXTSTEP, using special
 * "suffixed" directories for the "ANGBAND_DIR_DATA" directory, but
 * requiring the directories to be created by hand by the user.
 *
 * Hack -- first we free all the strings, since this is known
 * to succeed even if the strings have not been allocated yet,
 * as long as the variables start out as "NULL".  This allows
 * this function to be called multiple times, for example, to
 * try several base "path" values until a good one is found.
 */
void init_file_paths(char *path)
{
	char *tail;

#ifdef SET_UID
	char buf[1024];
#endif /* SET_UID */

	/*** Free everything ***/

	/* Free the main path */
	string_free(ANGBAND_DIR);

	/* Free the sub-paths */
	string_free(ANGBAND_DIR_APEX);
	string_free(ANGBAND_DIR_BONE);
	string_free(ANGBAND_DIR_DATA);
	string_free(ANGBAND_DIR_EDIT);
	string_free(ANGBAND_DIR_FILE);
	string_free(ANGBAND_DIR_HELP);
	string_free(ANGBAND_DIR_INFO);
	string_free(ANGBAND_DIR_SAVE);
	string_free(ANGBAND_DIR_PREF);
	string_free(ANGBAND_DIR_USER);
	string_free(ANGBAND_DIR_XTRA);


	/*** Prepare the "path" ***/

	/* Hack -- save the main directory */
	ANGBAND_DIR = string_make(path);

	/* Prepare to append to the Base Path */
	tail = path + strlen(path);


#ifdef VM


	/*** Use "flat" paths with VM/ESA ***/

	/* Use "blank" path names */
	ANGBAND_DIR_APEX = string_make("");
	ANGBAND_DIR_BONE = string_make("");
	ANGBAND_DIR_DATA = string_make("");
	ANGBAND_DIR_EDIT = string_make("");
	ANGBAND_DIR_FILE = string_make("");
	ANGBAND_DIR_HELP = string_make("");
	ANGBAND_DIR_INFO = string_make("");
	ANGBAND_DIR_SAVE = string_make("");
	ANGBAND_DIR_PREF = string_make("");
	ANGBAND_DIR_USER = string_make("");
	ANGBAND_DIR_XTRA = string_make("");


#else /* VM */


	/*** Build the sub-directory names ***/

	/* Build a path name */
	strcpy(tail, "apex");
	ANGBAND_DIR_APEX = string_make(path);

	/* Build a path name */
	strcpy(tail, "bone");
	ANGBAND_DIR_BONE = string_make(path);

	/* Build a path name */
	strcpy(tail, "data");
	ANGBAND_DIR_DATA = string_make(path);

	/* Build a path name */
	strcpy(tail, "edit");
	ANGBAND_DIR_EDIT = string_make(path);

	/* Build a path name */
	strcpy(tail, "file");
	ANGBAND_DIR_FILE = string_make(path);

	/* Build a path name */
	strcpy(tail, "help");
	ANGBAND_DIR_HELP = string_make(path);

	/* Build a path name */
	strcpy(tail, "info");
	ANGBAND_DIR_INFO = string_make(path);

	/* Build a path name */
	strcpy(tail, "save");
	ANGBAND_DIR_SAVE = string_make(path);

	/* Build a path name */
	strcpy(tail, "pref");
	ANGBAND_DIR_PREF = string_make(path);

#ifdef PRIVATE_USER_PATH

	/* Build the path to the user specific directory */
	path_build(buf, 1024, PRIVATE_USER_PATH, VERSION_NAME);

	/* Build a relative path name */
	ANGBAND_DIR_USER = string_make(buf);

#else /* PRIVATE_USER_PATH */

	/* Build a path name */
	strcpy(tail, "user");
	ANGBAND_DIR_USER = string_make(path);

#endif /* PRIVATE_USER_PATH */

	/* Build a path name */
	strcpy(tail, "xtra");
	ANGBAND_DIR_XTRA = string_make(path);

#endif /* VM */


#ifdef NeXT

	/* Allow "fat binary" usage with NeXT */
	if (TRUE)
	{
		cptr next = NULL;

# if defined(m68k)
		next = "m68k";
# endif

# if defined(i386)
		next = "i386";
# endif

# if defined(sparc)
		next = "sparc";
# endif

# if defined(hppa)
		next = "hppa";
# endif

		/* Use special directory */
		if (next)
		{
			/* Forget the old path name */
			string_free(ANGBAND_DIR_DATA);

			/* Build a new path name */
			sprintf(tail, "data-%s", next);
			ANGBAND_DIR_DATA = string_make(path);
		}
	}

#endif /* NeXT */

}
Пример #2
0
/**
 * This is the function called from wiz-debug.c.
 */
void stats_collect(void)
{
	static int simtype;
	static bool auto_flag;
	char buf[1024];

	/* Prompt the user for sim params */
	simtype = stats_prompt();

	/* Make sure the results are good! */
	if (!((simtype == 1) || (simtype == 2)))
		return; 

	/* Are we in diving or clearing mode */
	if (simtype == 2)
		clearing = TRUE;
	else
		clearing = FALSE;

	/* Open log file */
	path_build(buf, sizeof(buf), ANGBAND_DIR_USER, "stats.log");
	stats_log = file_open(buf, MODE_WRITE, FTYPE_TEXT);

	/* Logging didn't work */
	if (!stats_log) {
		msg("Error - can't open stats.log for writing.");
		exit(1);
	}

	/* Turn on auto-more.  This will clear prompts for items
	 * that drop under the player, or that can't fit on the 
	 * floor due to too many items.  This is a very small amount
	 * of items, even on deeper levels, so it's not worth worrying
	 * too much about.
	 */
	 auto_flag = FALSE;
	 
	 if (!OPT(auto_more)) {
		/* Remember that we turned off auto_more */
		auto_flag = TRUE;

		/* Turn on auto-more */
		option_set(option_name(OPT_auto_more),TRUE);
	}

	/* Print heading for the file */
	print_heading();

	/* Make sure all stats are 0 */
	init_stat_vals();

	/* Select diving option */
	if (!clearing) diving_stats();

	/* Select clearing option */
	if (clearing) clearing_stats();

	/* Turn auto-more back off */
	if (auto_flag) option_set(option_name(OPT_auto_more), FALSE);

	/* Close log file */
	if (!file_close(stats_log)) {
		msg("Error - can't close randart.log file.");
		exit(1);
	}
}
Пример #3
0
/*
 * Save a simple text screendump.
 */
static void do_cmd_save_screen_text(void)
{
	int y, x;

	byte a = 0;
	char c = ' ';

	ang_file *fff;

	char buf[1024];

	/* Build the filename */
	path_build(buf, 1024, ANGBAND_DIR_USER, "dump.txt");
	fff = file_open(buf, MODE_WRITE, FTYPE_TEXT);
	if (!fff) return;


	/* Save screen */
	screen_save();


	/* Dump the screen */
	for (y = 0; y < 24; y++)
	{
		/* Dump each row */
		for (x = 0; x < 79; x++)
		{
			/* Get the attr/char */
			(void)(Term_what(x, y, &a, &c));

			/* Dump it */
			buf[x] = c;
		}

		/* Terminate */
		buf[x] = '\0';

		/* End the row */
		file_putf(fff, "%s\n", buf);
	}

	/* Skip a line */
	file_putf(fff, "\n");


	/* Dump the screen */
	for (y = 0; y < 24; y++)
	{
		/* Dump each row */
		for (x = 0; x < 79; x++)
		{
			/* Get the attr/char */
			(void)(Term_what(x, y, &a, &c));

			/* Dump it */
			buf[x] = hack[a & 0x0F];
		}

		/* Terminate */
		buf[x] = '\0';

		/* End the row */
		file_putf(fff, "%s\n", buf);
	}

	/* Skip a line */
	file_putf(fff, "\n");


	/* Close it */
	file_close(fff);


	/* Message */
	msg("Screen dump saved.");
	message_flush();


	/* Load screen */
	screen_load();
}
Пример #4
0
/*
 * Create a spoiler file for monsters
 */
static void spoil_mon_desc(const char *fname)
{
	int i, n = 0;

	char buf[1024];

	char nam[80];
	char lev[80];
	char rar[80];
	char spd[80];
	char ac[80];
	char hp[80];
	char exp[80];

	u16b *who;

	/* We use either ascii or system-specific encoding */
 	int encoding = (OPT(xchars_to_file)) ? SYSTEM_SPECIFIC : ASCII;

	/* Build the filename */
	path_build(buf, sizeof(buf), ANGBAND_DIR_USER, fname);
	fh = file_open(buf, MODE_WRITE, FTYPE_TEXT);

	/* Oops */
	if (!fh)
	{
		msg("Cannot create spoiler file.");
		return;
	}

	/* Dump the header */
	x_file_putf(fh, encoding, "Monster Spoilers for %s\n", buildid);
	x_file_putf(fh, encoding, "------------------------------------------\n\n");

	/* Dump the header */
	x_file_putf(fh, encoding, "%-40.40s%4s%4s%6s%8s%4s  %11.11s\n",
	        "Name", "Lev", "Rar", "Spd", "Hp", "Ac", "Visual Info");
	x_file_putf(fh, encoding, "%-40.40s%4s%4s%6s%8s%4s  %11.11s\n",
	        "----", "---", "---", "---", "--", "--", "-----------");

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

	/* Scan the monsters (except the ghost) */
	for (i = 1; i < z_info->r_max - 1; i++)
	{
		monster_race *r_ptr = &r_info[i];

		/* Use that monster */
		if (r_ptr->name) who[n++] = (u16b)i;
	}

	/* Sort the array by dungeon depth of monsters */
	sort(who, n, sizeof(*who), cmp_monsters);

	/* Scan again */
	for (i = 0; i < n; i++)
	{
		monster_race *r_ptr = &r_info[who[i]];

		const char *name = r_ptr->name;

		/* Get the "name" */
		if (rf_has(r_ptr->flags, RF_QUESTOR))
		{
			strnfmt(nam, sizeof(nam), "[Q] %s", name);
		}
		else if (rf_has(r_ptr->flags, RF_UNIQUE))
		{
			strnfmt(nam, sizeof(nam), "[U] %s", name);
		}
		else
		{
			strnfmt(nam, sizeof(nam), "The %s", name);
		}


		/* Level */
		strnfmt(lev, sizeof(lev), "%d", r_ptr->level);

		/* Rarity */
		strnfmt(rar, sizeof(rar), "%d", r_ptr->rarity);

		/* Speed */
		if (r_ptr->speed >= 110)
			strnfmt(spd, sizeof(spd), "+%d", (r_ptr->speed - 110));
		else
			strnfmt(spd, sizeof(spd), "-%d", (110 - r_ptr->speed));

		/* Armor Class */
		strnfmt(ac, sizeof(ac), "%d", r_ptr->ac);

		/* Hitpoints */
		strnfmt(hp, sizeof(hp), "%d", r_ptr->avg_hp);


		/* Experience */
		strnfmt(exp, sizeof(exp), "%ld", (long)(r_ptr->mexp));

		/* Hack -- use visual instead */
		strnfmt(exp, sizeof(exp), "%s '%c'", attr_to_text(r_ptr->d_attr), r_ptr->d_char);

		/* Dump the info */
		x_file_putf(fh, encoding, "%-40.40s%4s%4s%6s%8s%4s  %11.11s\n",
		        nam, lev, rar, spd, hp, ac, exp);
	}

	/* End it */
	file_putf(fh, "\n");

	/* Free the "who" array */
	FREE(who);


	/* Check for errors */
	if (!file_close(fh))
	{
		msg("Cannot close spoiler file.");
		return;
	}

	/* Worked */
	msg("Successfully created a spoiler file.");
}
Пример #5
0
void
timestamp( 
	char	*target,
	time_t	*time )
{
	PATHNAME f1, f2;
	BINDING	binding, *b = &binding;
	string buf[1];

# ifdef DOWNSHIFT_PATHS
        string path; 
	char *p;

        string_copy( &path, target );
        p = path.value;

	do
            *p = tolower( *p );
	while( *p++ );

	target = path.value;
# endif
        string_new( buf );

	if( !bindhash )
	    bindhash = hashinit( sizeof( BINDING ), "bindings" );

	/* Quick path - is it there? */

	b->name = target;
	b->time = b->flags = 0;
	b->progress = BIND_INIT;

	if( hashenter( bindhash, (HASHDATA **)&b ) )
	    b->name = newstr( target );		/* never freed */

	if( b->progress != BIND_INIT )
	    goto afterscanning;

	b->progress = BIND_NOENTRY;

	/* Not found - have to scan for it */

	path_parse( target, &f1 );

	/* Scan directory if not already done so */

	{
	    BINDING binding, *b = &binding;

	    f2 = f1;
	    f2.f_grist.len = 0;
	    path_parent( &f2 );
	    path_build( &f2, buf, 0 );

	    b->name = buf->value;
	    b->time = b->flags = 0;
	    b->progress = BIND_INIT;

	    if( hashenter( bindhash, (HASHDATA **)&b ) )
		b->name = newstr( buf->value );	/* never freed */

	    if( !( b->flags & BIND_SCANNED ) )
	    {
		file_dirscan( buf->value, time_enter, bindhash );
		b->flags |= BIND_SCANNED;
	    }
	}

	/* Scan archive if not already done so */

	if( f1.f_member.len )
	{
	    BINDING binding, *b = &binding;

	    f2 = f1;
	    f2.f_grist.len = 0;
	    f2.f_member.len = 0;
            string_truncate( buf, 0 );
	    path_build( &f2, buf, 0 );

	    b->name = buf->value;
	    b->time = b->flags = 0;
	    b->progress = BIND_INIT;

	    if( hashenter( bindhash, (HASHDATA **)&b ) )
		b->name = newstr( buf->value );	/* never freed */

	    if( !( b->flags & BIND_SCANNED ) )
	    {
		file_archscan( buf->value, time_enter, bindhash );
		b->flags |= BIND_SCANNED;
	    }
	}

    afterscanning:

	if( b->progress == BIND_SPOTTED )
	{
	    if( file_time( b->name, &b->time ) < 0 )
		b->progress = BIND_MISSING;
	    else
		b->progress = BIND_FOUND;
	}

	*time = b->progress == BIND_FOUND ? b->time : 0;
        string_free( buf );
# ifdef DOWNSHIFT_PATHS
        string_free( &path );
#endif
}
Пример #6
0
/*!
 * @brief 現在のオプション設定をダンプ出力する /
 * Hack -- Dump option bits usage
 * @return なし
 */
static void do_cmd_dump_options(void)
{
	int  i, j;
	FILE *fff;
	char buf[1024];
	int  **exist;

	/* Build the filename */
	path_build(buf, sizeof buf, ANGBAND_DIR_USER, "opt_info.txt");

	/* File type is "TEXT" */
	FILE_TYPE(FILE_TYPE_TEXT);

	/* Open the file */
	fff = my_fopen(buf, "a");

	/* Oops */
	if (!fff)
	{
		msg_format(_("ファイル %s を開けませんでした。", "Failed to open file %s."), buf);
		msg_print(NULL);
		return;
	}

	/* Allocate the "exist" array (2-dimension) */
	C_MAKE(exist, NUM_O_SET, int *);
	C_MAKE(*exist, NUM_O_BIT * NUM_O_SET, int);
	for (i = 1; i < NUM_O_SET; i++) exist[i] = *exist + i * NUM_O_BIT;

	/* Check for exist option bits */
	for (i = 0; option_info[i].o_desc; i++)
	{
		const option_type *ot_ptr = &option_info[i];
		if (ot_ptr->o_var) exist[ot_ptr->o_set][ot_ptr->o_bit] = i + 1;
	}

	fprintf(fff, "[Option bits usage on Hengband %d.%d.%d]\n\n",
	        FAKE_VER_MAJOR - 10, FAKE_VER_MINOR, FAKE_VER_PATCH);

	fputs("Set - Bit (Page) Option Name\n", fff);
	fputs("------------------------------------------------\n", fff);
	/* Dump option bits usage */
	for (i = 0; i < NUM_O_SET; i++)
	{
		for (j = 0; j < NUM_O_BIT; j++)
		{
			if (exist[i][j])
			{
				const option_type *ot_ptr = &option_info[exist[i][j] - 1];
				fprintf(fff, "  %d -  %02d (%4d) %s\n",
				        i, j, ot_ptr->o_page, ot_ptr->o_text);
			}
			else
			{
				fprintf(fff, "  %d -  %02d\n", i, j);
			}
		}
		fputc('\n', fff);
	}

	/* Free the "exist" array (2-dimension) */
	C_KILL(*exist, NUM_O_BIT * NUM_O_SET, int);
	C_KILL(exist, NUM_O_SET, int *);

	/* Close it */
	my_fclose(fff);

	msg_format(_("オプションbit使用状況をファイル %s に書き出しました。", "Option bits usage dump saved to file %s."), buf);
}
Пример #7
0
/*
 * Create a spoiler file for items
 */
static void spoil_obj_desc(const char *fname)
{
	int i, k, s, t, n = 0;

	u16b who[200];

	char buf[1024];

	char wgt[80];
	char dam[80];

	const char *format = "%-51s  %7s%6s%4s%9s\n";

	/* We use either ascii or system-specific encoding */
 	int encoding = (OPT(xchars_to_file)) ? SYSTEM_SPECIFIC : ASCII;

	/* Open the file */
	path_build(buf, sizeof(buf), ANGBAND_DIR_USER, fname);
	fh = file_open(buf, MODE_WRITE, FTYPE_TEXT);

	/* Oops */
	if (!fh)
	{
		msg("Cannot create spoiler file.");
		return;
	}


	/* Header */
	file_putf(fh, "Spoiler File -- Basic Items (%s)\n\n\n", buildid);

	/* More Header */
	file_putf(fh, format, "Description", "Dam/AC", "Wgt", "Lev", "Cost");
	file_putf(fh, format, "----------------------------------------",
	        "------", "---", "---", "----");

	/* List the groups */
	for (i = 0; TRUE; i++)
	{
		/* Write out the group title */
		if (group_item[i].name)
		{
			/* Hack -- bubble-sort by cost and then level */
			for (s = 0; s < n - 1; s++)
			{
				for (t = 0; t < n - 1; t++)
				{
					int i1 = t;
					int i2 = t + 1;

					int e1;
					int e2;

					s32b t1;
					s32b t2;

					kind_info(NULL, 0, NULL, 0, NULL, 0, &e1, &t1, who[i1]);
					kind_info(NULL, 0, NULL, 0, NULL, 0, &e2, &t2, who[i2]);

					if ((t1 > t2) || ((t1 == t2) && (e1 > e2)))
					{
						int tmp = who[i1];
						who[i1] = who[i2];
						who[i2] = tmp;
					}
				}
			}

			/* Spoil each item */
			for (s = 0; s < n; s++)
			{
				int e;
				s32b v;

				/* Describe the kind */
				kind_info(buf, sizeof(buf), dam, sizeof(dam), wgt, sizeof(wgt), &e, &v, who[s]);

				/* Dump it */
				x_file_putf(fh, encoding, "  %-51s%7s%6s%4d%9ld\n",
				        buf, dam, wgt, e, (long)(v));
			}

			/* Start a new set */
			n = 0;

			/* Notice the end */
			if (!group_item[i].tval) break;

			/* Start a new set */
			x_file_putf(fh, encoding, "\n\n%s\n\n", group_item[i].name);
		}

		/* Get legal item types */
		for (k = 1; k < z_info->k_max; k++)
		{
			object_kind *k_ptr = &k_info[k];

			/* Skip wrong tval's */
			if (k_ptr->tval != group_item[i].tval) continue;

			/* Hack -- Skip instant-artifacts */
			if (of_has(k_ptr->flags, OF_INSTA_ART)) continue;

			/* Save the index */
			who[n++] = k;
		}
	}


	/* Check for errors */
	if (!file_close(fh))
	{
		msg("Cannot close spoiler file.");
		return;
	}

	/* Message */
	msg("Successfully created a spoiler file.");
}
Пример #8
0
/*used to check the power of artifacts.  Currently unused*/
void dump_artifact_power(void)
{
	int i;

	char buf[1024];

	int fd;
	FILE *fff = NULL;

	artifact_type *a_ptr;

	/* Build the filename */
	path_build(buf, 1024, ANGBAND_DIR_EDIT, "power.txt");

	/* Check for existing file */
	fd = fd_open(buf, O_RDONLY);

	/* Existing file */
	if (fd >= 0)
	{
		char out_val[160];

		/* Close the file */
		fd_close(fd);

		/* Build query */
		sprintf(out_val, "Replace existing file %s? ", buf);

		/* Ask */
		if (get_check(out_val)) fd = -1;
	}

	/* Open the non-existing file */
	if (fd < 0) fff = my_fopen(buf, "w");

	/* No output file - fail */
	if (!fff) return;

	/* Write a note */
	fprintf(fff, "# File: artifact_power.txt (autogenerated)\n\n");

	/* Read and print out all the objects */
	for (i = 1; i < z_info->art_norm_max; i++)
	{
		s32b power;
		char o_name[80];
		object_type *i_ptr;
		object_type object_type_body;

		/* Get local object */
		i_ptr = &object_type_body;

		/* Get the object */
		a_ptr = &a_info[i];

		/* Ignore unused objects */
		if (!strlen(a_ptr->name))
		{
			fprintf(fff, "## empty space (available for artifact) ##\n\n");
			continue;
		}

		/* Write the complete name of the artifact*/
		make_fake_artifact(i_ptr, i);

		/* Identify it */
		object_aware(i_ptr);
		object_known(i_ptr);
		i_ptr->ident |= (IDENT_MENTAL);

		/* Get a description to dump */
		object_desc(o_name, sizeof(o_name), i_ptr, TRUE, 0);

		power = artifact_power(i);

		/*dump the information*/
		fprintf(fff, "%9d is the power of %55s, tval is %6d \n", power, o_name, a_ptr->tval);

	}

	/* Done */
	fclose(fff);

}
Пример #9
0
/*
 * Use the monster racial information to a format easily parsed by a spreadsheet.
 *
 * Original function by -EB- (probably), revisions by -LM- & JG.
 */
void write_mon_power(void)
{
	int i;

	char buf[1024];

	int fd;
	FILE *fff = NULL;

	monster_race *r_ptr;

	/* Build the filename */
	path_build(buf, 1024, ANGBAND_DIR_EDIT, "mon_power_output.txt");

	/* Check for existing file */
	fd = fd_open(buf, O_RDONLY);

	/* Existing file */
	if (fd >= 0)
	{
		char out_val[160];

		/* Close the file */
		fd_close(fd);

		/* Build query */
		sprintf(out_val, "Replace existing file %s? ", buf);

		/* Ask */
		if (get_check(out_val)) fd = -1;
	}

	/* Open the non-existing file */
	if (fd < 0) fff = my_fopen(buf, "w");

	/* No output file - fail */
	if (!fff) return;

	/* Write a note */
	fprintf(fff, "# File: mon_power_output.txt (autogenerated)\n\n");

	/* Write a note */
	fprintf(fff, "##### The Player #####\n\n");

	/* Read and print out all the monsters */
	for (i = 0; i < z_info->r_max; i++)
	{

		/* Get the monster */
		r_ptr = &r_info[i];

		/* Ignore empty monsters */
		if (!strlen(r_name + r_ptr->name))
		{
			fprintf(fff, "## empty space (available for monsters) ##\n\n");
			continue;
		}

		/* Write New/Number/Name */
		fprintf(fff, "%3d:lvl: %3d power:%9d hp:%9d dam:%9d name: %s\n",
						i, r_ptr->level, r_ptr->mon_power, r_ptr->mon_eval_hp,
								r_ptr->mon_eval_dam,(r_name + r_ptr->name));

	}

	/*a few blank lines*/
	fprintf(fff, "\n\n");

	/*first clear the tables*/
	for (i = 0; i < MAX_DEPTH; i++)
	{
		/* Write New/Number/Name */
		fprintf(fff, "lvl: %3d unique_ave_power:%9d creature_ave_power:%9d \n", i,
					mon_power_ave[i][CREATURE_UNIQUE], mon_power_ave[i][CREATURE_NON_UNIQUE]);

	}

	/* Done */
	fclose(fff);
}
Пример #10
0
/**
 * Create a spoiler file for artifacts
 */
static void spoil_artifact(const char *fname)
{
	int i, j;
	char buf[1024];

	/* Build the filename */
	path_build(buf, sizeof(buf), ANGBAND_DIR_USER, fname);
	fh = file_open(buf, MODE_WRITE, FTYPE_TEXT);

	/* Oops */
	if (!fh) {
		msg("Cannot create spoiler file.");
		return;
	}

	/* Dump to the spoiler file */
	text_out_hook = text_out_to_file;
	text_out_file = fh;

	/* Dump the header */
	spoiler_underline(format("Artifact Spoilers for %s", buildid), '=');

	text_out("\n Randart seed is %u\n", seed_randart);

	/* List the artifacts by tval */
	for (i = 0; group_artifact[i].tval; i++) {
		/* Write out the group title */
		if (group_artifact[i].name) {
			spoiler_blanklines(2);
			spoiler_underline(group_artifact[i].name, '=');
			spoiler_blanklines(1);
		}

		/* Now search through all of the artifacts */
		for (j = 1; j < z_info->a_max; ++j) {
			struct artifact *art = &a_info[j];
			char buf2[80];
			char *temp;
			struct object *obj, *known_obj;

			/* We only want objects in the current group */
			if (art->tval != group_artifact[i].tval) continue;

			/* Get local object */
			obj = object_new();
			known_obj = object_new();

			/* Attempt to "forge" the artifact */
			if (!make_fake_artifact(obj, art)) {
				object_delete(&known_obj);
				object_delete(&obj);
				continue;
			}

			/* Grab artifact name */
			object_copy(known_obj, obj);
			obj->known = known_obj;
			object_desc(buf2, sizeof(buf2), obj, ODESC_PREFIX |
				ODESC_COMBAT | ODESC_EXTRA | ODESC_SPOIL);

			/* Print name and underline */
			spoiler_underline(buf2, '-');

			/* Temporarily blank the artifact flavour text - spoilers
			   spoil the mechanics, not the atmosphere. */
			temp = obj->artifact->text;
			obj->artifact->text = NULL;

			/* Write out the artifact description to the spoiler file */
			object_info_spoil(fh, obj, 80);

			/* Put back the flavour */
			obj->artifact->text = temp;

			/*
			 * Determine the minimum and maximum depths an
			 * artifact can appear, its rarity, its weight, and
			 * its power rating.
			 */
			text_out("\nMin Level %u, Max Level %u, Generation chance %u, Power %d, %d.%d lbs\n",
					 art->alloc_min, art->alloc_max, art->alloc_prob,
					 object_power(obj, false, NULL), (art->weight / 10),
					 (art->weight % 10));

			if (OPT(birth_randarts)) text_out("%s.\n", art->text);

			/* Terminate the entry */
			spoiler_blanklines(2);
			object_delete(&known_obj);
			object_delete(&obj);
		}
	}

	/* Check for errors */
	if (!file_close(fh)) {
		msg("Cannot close spoiler file.");
		return;
	}

	/* Message */
	msg("Successfully created a spoiler file.");
}
Пример #11
0
/**
 * Create a spoiler file for monsters (-SHAWN-)
 */
static void spoil_mon_info(const char *fname)
{
	char buf[1024];
	int i, n;
	u16b *who;
	int count = 0;
	textblock *tb = NULL;

	/* Open the file */
	path_build(buf, sizeof(buf), ANGBAND_DIR_USER, fname);
	fh = file_open(buf, MODE_WRITE, FTYPE_TEXT);

	if (!fh) {
		msg("Cannot create spoiler file.");
		return;
	}

	/* Dump the header */
	tb = textblock_new();
	textblock_append(tb, "Monster Spoilers for %s\n", buildid);
	textblock_append(tb, "------------------------------------------\n\n");
	textblock_to_file(tb, fh, 0, 75);
	textblock_free(tb);
	tb = NULL;

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

	/* Scan the monsters */
	for (i = 1; i < z_info->r_max; i++) {
		struct monster_race *race = &r_info[i];

		/* Use that monster */
		if (race->name) who[count++] = (u16b)i;
	}

	sort(who, count, sizeof(*who), cmp_monsters);

	/* List all monsters in order. */
	for (n = 0; n < count; n++) {
		int r_idx = who[n];
		const struct monster_race *race = &r_info[r_idx];
		const struct monster_lore *lore = &l_list[r_idx];
		tb = textblock_new();

		/* Line 1: prefix, name, color, and symbol */
		if (rf_has(race->flags, RF_QUESTOR))
			textblock_append(tb, "[Q] ");
		else if (rf_has(race->flags, RF_UNIQUE))
			textblock_append(tb, "[U] ");
		else
			textblock_append(tb, "The ");

		/* As of 3.5, race->name and race->text are stored as UTF-8 strings;
		 * there is no conversion from the source edit files. */
		textblock_append_utf8(tb, race->name);
		textblock_append(tb, "  (");	/* ---)--- */
		textblock_append(tb, attr_to_text(race->d_attr));
		textblock_append(tb, " '%c')\n", race->d_char);

		/* Line 2: number, level, rarity, speed, HP, AC, exp */
		textblock_append(tb, "=== ");
		textblock_append(tb, "Num:%d  ", r_idx);
		textblock_append(tb, "Lev:%d  ", race->level);
		textblock_append(tb, "Rar:%d  ", race->rarity);

		if (race->speed >= 110)
			textblock_append(tb, "Spd:+%d  ", (race->speed - 110));
		else
			textblock_append(tb, "Spd:-%d  ", (110 - race->speed));

		textblock_append(tb, "Hp:%d  ", race->avg_hp);
		textblock_append(tb, "Ac:%d  ", race->ac);
		textblock_append(tb, "Exp:%ld\n", (long)(race->mexp));

		/* Normal description (with automatic line breaks) */
		lore_description(tb, race, lore, true);
		textblock_append(tb, "\n");

		textblock_to_file(tb, fh, 0, 75);
		textblock_free(tb);
		tb = NULL;
	}

	/* Free the "who" array */
	mem_free(who);

	/* Check for errors */
	if (!file_close(fh)) {
		msg("Cannot close spoiler file.");
		return;
	}

	msg("Successfully created a spoiler file.");
}
Пример #12
0
/*
 * Initialization function for an "X11" module to Angband
 */
errr init_x11(int argc, char **argv)
{
	int i;

	cptr dpy_name = "";

	int num_term = 1;

#ifdef USE_GRAPHICS

	cptr bitmap_file = "";
	char filename[1024];

	int pict_wid = 0;
	int pict_hgt = 0;

	char *TmpData;

#endif /* USE_GRAPHICS */


	/* Parse args */
	for (i = 1; i < argc; i++)
	{
		if (prefix(argv[i], "-d"))
		{
			dpy_name = &argv[i][2];
			continue;
		}

#ifdef USE_GRAPHICS
		if (prefix(argv[i], "-s"))
		{
			smoothRescaling = FALSE;
			continue;
		}

		if (prefix(argv[i], "-o"))
		{
			arg_graphics = GRAPHICS_ORIGINAL;
			continue;
		}

		if (prefix(argv[i], "-a"))
		{
			arg_graphics = GRAPHICS_ADAM_BOLT;
			continue;
		}

		if (prefix(argv[i], "-g"))
		{
			smoothRescaling = FALSE;
			arg_graphics = GRAPHICS_DAVID_GERVAIS;
			continue;
		}

		if (prefix(argv[i], "-b"))
		{
			use_bigtile = TRUE;
			continue;
		}

#endif /* USE_GRAPHICS */

		if (prefix(argv[i], "-n"))
		{
			num_term = atoi(&argv[i][2]);
			if (num_term > MAX_TERM_DATA) num_term = MAX_TERM_DATA;
			else if (num_term < 1) num_term = 1;
			continue;
		}

		plog_fmt("Ignoring option: %s", argv[i]);
	}


	/* Init the Metadpy if possible */
	if (Metadpy_init_name(dpy_name)) return (-1);


	/* Prepare cursor color */
	MAKE(xor, infoclr);
	Infoclr_set(xor);
	Infoclr_init_ppn(Metadpy->fg, Metadpy->bg, "xor", 0);


	/* Prepare normal colors */
	for (i = 0; i < 256; ++i)
	{
		Pixell pixel;

		MAKE(clr[i], infoclr);

		Infoclr_set(clr[i]);

		/* Acquire Angband colors */
		color_table[i][0] = angband_color_table[i][0];
		color_table[i][1] = angband_color_table[i][1];
		color_table[i][2] = angband_color_table[i][2];
		color_table[i][3] = angband_color_table[i][3];

		/* Default to monochrome */
		pixel = ((i == 0) ? Metadpy->bg : Metadpy->fg);

		/* Handle color */
		if (Metadpy->color)
		{
			/* Create pixel */
			pixel = create_pixel(Metadpy->dpy,
			                     color_table[i][1],
			                     color_table[i][2],
			                     color_table[i][3]);
		}

		/* Initialize the color */
		Infoclr_init_ppn(pixel, Metadpy->bg, "cpy", 0);
	}


	/* Initialize the windows */
	for (i = 0; i < num_term; i++)
	{
		term_data *td = &data[i];

		/* Initialize the term_data */
		term_data_init(td, i);

		/* Save global entry */
		angband_term[i] = Term;
	}

	/* Raise the "Angband" window */
	Infowin_set(data[0].win);
	Infowin_raise();

	/* Activate the "Angband" window screen */
	Term_activate(&data[0].t);


#ifdef USE_GRAPHICS

	/* Try graphics */
	switch (arg_graphics)
	{
	case GRAPHICS_ADAM_BOLT:
		/* Use tile graphics of Adam Bolt */
		bitmap_file = "16x16.bmp";

		/* Try the "16x16.bmp" file */
		path_build(filename, sizeof(filename), ANGBAND_DIR_XTRA, format("graf/%s", bitmap_file));

		/* Use the "16x16.bmp" file if it exists */
		if (0 == fd_close(fd_open(filename, O_RDONLY)))
		{
			/* Use graphics */
			use_graphics = TRUE;
			use_transparency = TRUE;

			pict_wid = pict_hgt = 16;

			ANGBAND_GRAF = "new";

			break;
		}
		/* Fall through */

	case GRAPHICS_ORIGINAL:
		/* Use original tile graphics */
		bitmap_file = "8x8.bmp";

		/* Try the "8x8.bmp" file */
		path_build(filename, sizeof(filename), ANGBAND_DIR_XTRA, format("graf/%s", bitmap_file));

		/* Use the "8x8.bmp" file if it exists */
		if (0 == fd_close(fd_open(filename, O_RDONLY)))
		{
			/* Use graphics */
			use_graphics = TRUE;

			pict_wid = pict_hgt = 8;

			ANGBAND_GRAF = "old";
			break;
		}
		break;

	case GRAPHICS_DAVID_GERVAIS:
		/* Use tile graphics of David Gervais */
		bitmap_file = "32x32.bmp";

		/* Use graphics */
		use_graphics = TRUE;
		use_transparency = TRUE;

		pict_wid = pict_hgt = 32;

		ANGBAND_GRAF = "david";
		break;
	}

	/* Load graphics */
	if (use_graphics)
	{
		Display *dpy = Metadpy->dpy;

		XImage *tiles_raw;

		/* Initialize */
		for (i = 0; i < num_term; i++)
		{
			term_data *td = &data[i];
			td->tiles = NULL;
		}

		path_build(filename, sizeof(filename), ANGBAND_DIR_XTRA, format("graf/%s", bitmap_file));

		/* Load the graphical tiles */
		tiles_raw = ReadBMP(dpy, filename);

		if (tiles_raw)
		{
			/* Initialize the windows */
			for (i = 0; i < num_term; i++)
			{
				int j;
				bool same = FALSE;

				term_data *td = &data[i];
				term_data *o_td = NULL;

				term *t = &td->t;

				/* Graphics hook */
				t->pict_hook = Term_pict_x11;

				/* Use graphics sometimes */
				t->higher_pict = TRUE;

				/* Look for another term with same font size */
				for (j = 0; j < i; j++)
				{
					o_td = &data[j];

					if ((td->fnt->twid == o_td->fnt->twid) && (td->fnt->hgt == o_td->fnt->hgt))
					{
						same = TRUE;
						break;
					}
				}

				if (!same)
				{
					/* Resize tiles */
					td->tiles = ResizeImage(dpy, tiles_raw,
					                        pict_wid, pict_hgt,
					                        td->fnt->twid, td->fnt->hgt);
				}
				else
				{
					/* Use same graphics */
					td->tiles = o_td->tiles;
				}
			}

			/* Free tiles_raw */
			FREE(tiles_raw);
		}
                        
		/* Initialize the transparency masks */
		for (i = 0; i < num_term; i++)
		{
			term_data *td = &data[i];
			int ii, jj;
			int depth = DefaultDepth(dpy, DefaultScreen(dpy));
			Visual *visual = DefaultVisual(dpy, DefaultScreen(dpy));
			int total;


			/* Determine total bytes needed for image */
			ii = 1;
			jj = (depth - 1) >> 2;
			while (jj >>= 1) ii <<= 1;
			total = td->fnt->twid * td->fnt->hgt * ii;


			TmpData = (char *)malloc(total);

			td->TmpImage = XCreateImage(dpy,visual,depth,
				ZPixmap, 0, TmpData,
				td->fnt->twid, td->fnt->hgt, 32, 0);

		}
	}

#endif /* USE_GRAPHICS */


	/* Success */
	return (0);
}
Пример #13
0
/*
 * Actually place an entry into the high score file
 * Return the location (0 is best) or -1 on "failure"
 */
static void highscore_write(const high_score scores[], size_t sz)
{
	size_t n;

	ang_file *lok;
	ang_file *scorefile;

	char old_name[1024];
	char cur_name[1024];
	char new_name[1024];
	char lok_name[1024];

	path_build(old_name, sizeof(old_name), ANGBAND_DIR_APEX, "scores.old");
	path_build(cur_name, sizeof(cur_name), ANGBAND_DIR_APEX, "scores.raw");
	path_build(new_name, sizeof(new_name), ANGBAND_DIR_APEX, "scores.new");
	path_build(lok_name, sizeof(lok_name), ANGBAND_DIR_APEX, "scores.lok");


	/* Read in and add new score */
	n = highscore_count(scores, sz);


	/*** Lock scores ***/

	if (file_exists(lok_name))
	{
		msg("Lock file in place for scorefile; not writing.");
		return;
	}

	safe_setuid_grab();
	lok = file_open(lok_name, MODE_WRITE, FTYPE_RAW);
	file_lock(lok);
	safe_setuid_drop();

	if (!lok)
	{
		msg("Failed to create lock for scorefile; not writing.");
		return;
	}


	/*** Open the new file for writing ***/

	safe_setuid_grab();
	scorefile = file_open(new_name, MODE_WRITE, FTYPE_RAW);
	safe_setuid_drop();

	if (!scorefile)
	{
		msg("Failed to open new scorefile for writing.");

		file_close(lok);
		file_delete(lok_name);
		return;
	}

	file_write(scorefile, (const char *)scores, sizeof(high_score)*n);
	file_close(scorefile);

	/*** Now move things around ***/

	safe_setuid_grab();

	if (file_exists(old_name) && !file_delete(old_name))
		msg("Couldn't delete old scorefile");

	if (file_exists(cur_name) && !file_move(cur_name, old_name))
		msg("Couldn't move old scores.raw out of the way");

	if (!file_move(new_name, cur_name))
		msg("Couldn't rename new scorefile to scores.raw");

	/* Remove the lock */
	file_close(lok);
	file_delete(lok_name);

	safe_setuid_drop();
}
Пример #14
0
/*
 * Initialization function for an X Athena Widget module to Angband
 *
 * We should accept "-d<dpy>" requests in the "argv" array.  XXX XXX XXX
 */
errr init_xaw(int argc, char **argv)
{
	int i;
	Widget topLevel;
	Display *dpy;

	cptr dpy_name = "";


#ifdef USE_GRAPHICS

	cptr bitmap_file = "";
	char filename[1024];

	int pict_wid = 0;
	int pict_hgt = 0;

	char *TmpData;

#endif /* USE_GRAPHICS */

	/* Parse args */
	for (i = 1; i < argc; i++)
	{
		if (prefix(argv[i], "-d"))
		{
			dpy_name = &argv[i][2];
			continue;
		}

#ifdef USE_GRAPHICS
		if (prefix(argv[i], "-s"))
		{
			smoothRescaling = FALSE;
			continue;
		}

		if (prefix(argv[i], "-o"))
		{
			arg_graphics = GRAPHICS_ORIGINAL;
			continue;
		}

		if (prefix(argv[i], "-a"))
		{
			arg_graphics = GRAPHICS_ADAM_BOLT;
			continue;
		}

		if (prefix(argv[i], "-g"))
		{
			smoothRescaling = FALSE;
			arg_graphics = GRAPHICS_DAVID_GERVAIS;
			continue;
		}

		if (prefix(argv[i], "-b"))
		{
			use_bigtile = TRUE;
			continue;
		}

#endif /* USE_GRAPHICS */

		if (prefix(argv[i], "-n"))
		{
			num_term = atoi(&argv[i][2]);
			if (num_term > MAX_TERM_DATA) num_term = MAX_TERM_DATA;
			else if (num_term < 1) num_term = 1;
			continue;
		}

		plog_fmt("Ignoring option: %s", argv[i]);
	}


	/* Attempt to open the local display */
	dpy = XOpenDisplay(dpy_name);

	/* Failure -- assume no X11 available */
	if (!dpy) return (-1);

	/* Close the local display */
	XCloseDisplay(dpy);


#ifdef USE_XAW_LANG

	/* Support locale processing */
	XtSetLanguageProc(NULL, NULL, NULL);

#endif /* USE_XAW_LANG */


	/* Initialize the toolkit */
	topLevel = XtAppInitialize(&appcon, "Angband", NULL, 0, &argc, argv,
	                           fallback, NULL, 0);


	/* Initialize the windows */
	for (i = 0; i < num_term; i++)
	{
		term_data *td = &data[i];

		term_data_init(td, topLevel, 1024, termNames[i],
		               (i == 0) ? specialArgs : defaultArgs,
		               TERM_FALLBACKS, i);

		angband_term[i] = Term;
	}

	/* Activate the "Angband" window screen */
	Term_activate(&data[0].t);

	/* Raise the "Angband" window */
	term_raise(&data[0]);


#ifdef USE_GRAPHICS

	/* Try graphics */
	switch (arg_graphics)
	{
	case GRAPHICS_ADAM_BOLT:
		/* Use tile graphics of Adam Bolt */
		bitmap_file = "16x16.bmp";

		/* Try the "16x16.bmp" file */
		path_build(filename, sizeof(filename), ANGBAND_DIR_XTRA, format("graf/%s", bitmap_file));

		/* Use the "16x16.bmp" file if it exists */
		if (0 == fd_close(fd_open(filename, O_RDONLY)))
		{
			/* Use graphics */
			use_graphics = GRAPHICS_ADAM_BOLT;
			use_transparency = TRUE;

			pict_wid = pict_hgt = 16;

			ANGBAND_GRAF = "new";

			break;
		}
		/* Fall through */

	case GRAPHICS_ORIGINAL:
		/* Use original tile graphics */
		bitmap_file = "8x8.bmp";

		/* Try the "8x8.bmp" file */
		path_build(filename, sizeof(filename), ANGBAND_DIR_XTRA, format("graf/%s", bitmap_file));

		/* Use the "8x8.bmp" file if it exists */
		if (0 == fd_close(fd_open(filename, O_RDONLY)))
		{
			/* Use graphics */
			use_graphics = GRAPHICS_ORIGINAL;

			pict_wid = pict_hgt = 8;

			ANGBAND_GRAF = "old";
			break;
		}
		break;

	case GRAPHICS_DAVID_GERVAIS:
		/* Use tile graphics of David Gervais */
		bitmap_file = "32x32.bmp";

		/* Use graphics */
		use_graphics = GRAPHICS_DAVID_GERVAIS;
		use_transparency = TRUE;

		pict_wid = pict_hgt = 32;

		ANGBAND_GRAF = "david";
		break;
	}

	/* Load graphics */
	if (use_graphics)
	{
		/* Hack -- Get the Display */
		term_data *td = &data[0];
		Widget widget = (Widget)(td->widget);
		Display *dpy = XtDisplay(widget);

		XImage *tiles_raw;

		for (i = 0; i < num_term; i++)
		{
			term_data *td = &data[i];
			td->widget->angband.tiles = NULL;
		}

		path_build(filename, sizeof(filename), ANGBAND_DIR_XTRA, format("graf/%s", bitmap_file));

		/* Load the graphical tiles */
		tiles_raw = ReadBMP(dpy, filename);

		if (tiles_raw)
		{
			/* Initialize the windows */
			for (i = 0; i < num_term; i++)
			{
				int j;
				bool same = FALSE;

				term_data *td = &data[i];
				term_data *o_td = NULL;

				term *t = &td->t;

				t->pict_hook = Term_pict_xaw;

				t->higher_pict = TRUE;

				/* Look for another term with same font size */
				for (j = 0; j < i; j++)
				{
					o_td = &data[j];

					if ((td->widget->angband.tilewidth == o_td->widget->angband.tilewidth) &&
					    (td->widget->angband.fontheight == o_td->widget->angband.fontheight))
					{
						same = TRUE;
						break;
					}
				}

				if (!same)
				{
					/* Resize tiles */
					td->widget->angband.tiles = ResizeImage(dpy, tiles_raw,
					                                        pict_wid, pict_hgt,
					                                        td->widget->angband.tilewidth,
					                                        td->widget->angband.fontheight);
				}
				else
				{
					/* Use same graphics */
					td->widget->angband.tiles = o_td->widget->angband.tiles;
				}
			}

			/* Free tiles_raw */
			FREE(tiles_raw);
		}

		/* Initialize the transparency temp storage */
		for (i = 0; i < num_term; i++)
		{
			term_data *td = &data[i];
			int ii, jj;
			int depth = DefaultDepth(dpy, DefaultScreen(dpy));
			Visual *visual = DefaultVisual(dpy, DefaultScreen(dpy));
			int total;


			/* Determine total bytes needed for image */
			ii = 1;
			jj = (depth - 1) >> 2;
			while (jj >>= 1) ii <<= 1;
			total = td->widget->angband.tilewidth *
			        td->widget->angband.fontheight * ii;


			TmpData = (char *)malloc(total);

			td->widget->angband.TmpImage = XCreateImage(dpy,
				visual,depth,
				ZPixmap, 0, TmpData,
				td->widget->angband.tilewidth,
			        td->widget->angband.fontheight, 8, 0);
		}
	}

#endif /* USE_GRAPHICS */

	/* Success */
	return (0);
}
Пример #15
0
OBJECT *
search(
    OBJECT * target,
    time_t *time,
    OBJECT * * another_target,
    int file
)
{
    PATHNAME f[1];
    LIST   * varlist;
    string   buf[1];
    int      found = 0;
    /* Will be set to 1 if target location is specified via LOCATE. */
    int      explicitly_located = 0;
    OBJECT * boundname = 0;

    if ( another_target )
        *another_target = 0;

    if (! explicit_bindings )
        explicit_bindings = hashinit( sizeof(BINDING),
                                     "explicitly specified locations");

    string_new( buf );
    /* Parse the filename */

    path_parse( object_str( target ), f );

    f->f_grist.ptr = 0;
    f->f_grist.len = 0;

    varlist = var_get( root_module(), constant_LOCATE );
    if ( !list_empty( varlist ) )
    {
        OBJECT * key;
        f->f_root.ptr = object_str( list_front( varlist ) );
        f->f_root.len = strlen( object_str( list_front( varlist ) ) );

        path_build( f, buf, 1 );

        if ( DEBUG_SEARCH )
            printf( "locate %s: %s\n", object_str( target ), buf->value );

        explicitly_located = 1;

        key = object_new( buf->value );
        timestamp( key, time );
        object_free( key );
        found = 1;
    }
    else if ( varlist = var_get( root_module(), constant_SEARCH ), !list_empty( varlist ) )
    {
        LISTITER iter = list_begin( varlist ), end = list_end( varlist );
        for ( ; iter != end; iter = list_next( iter ) )
        {
            BINDING * ba;
            file_info_t *ff;
            OBJECT * key;
            OBJECT * test_path;

            f->f_root.ptr = object_str( list_item( iter ) );
            f->f_root.len = strlen( object_str( list_item( iter ) ) );

            string_truncate( buf, 0 );
            path_build( f, buf, 1 );

            if ( DEBUG_SEARCH )
                printf( "search %s: %s\n", object_str( target ), buf->value );

            test_path = object_new( buf->value );
            key = path_as_key( test_path );
            object_free( test_path );
            ff = file_query( key );
            timestamp( key, time );

            if ( ( ba = (BINDING *)hash_find( explicit_bindings, key ) ) )
            {
                if ( DEBUG_SEARCH )
                    printf(" search %s: found explicitly located target %s\n",
                           object_str( target ), object_str( ba->target ) );
                if ( another_target )
                    *another_target = ba->target;
                found = 1;
                object_free( key );
                break;
            }
            else if ( ff && ff->time )
            {
                if ( !file || ff->is_file )
                {
                    found = 1;
                    object_free( key );
                    break;
                }
            }
            object_free( key );
        }
    }

    if ( !found )
    {
        /* Look for the obvious */
        /* This is a questionable move.  Should we look in the */
        /* obvious place if SEARCH is set? */
        OBJECT * key;

        f->f_root.ptr = 0;
        f->f_root.len = 0;

        string_truncate( buf, 0 );
        path_build( f, buf, 1 );

        if ( DEBUG_SEARCH )
            printf( "search %s: %s\n", object_str( target ), buf->value );

        key = object_new( buf->value );
        timestamp( key, time );
        object_free( key );
    }

    boundname = object_new( buf->value );
    string_free( buf );

    if ( explicitly_located )
    {
        int found;
        BINDING * ba;
        OBJECT * key = path_as_key( boundname );
        /* CONSIDER: we probably should issue a warning is another file
           is explicitly bound to the same location. This might break
           compatibility, though. */
        ba = (BINDING *)hash_insert( explicit_bindings, key, &found );
        if ( !found )
        {
            ba->binding = key;
            ba->target = target;
        }
        else
        {
            object_free( key );
        }
    }

    /* prepare a call to BINDRULE if the variable is set */
    call_bind_rule( target, boundname );

    return boundname;
}
Пример #16
0
/*
 * Dump the object information a format easily parsed by a spreadsheet.
 *
 * Original function by -EB- (probably), revisions by -LM- & JG.
 */
void write_o_info_txt(void)
{
	int i, j, bc;
	int dlen;

	char buf[1024];

	int fd;
	FILE *fff = NULL;

	cptr desc;

	object_kind *k_ptr;

	/* We allow 75 characters on the line (plus 2) */
	u16b line_length = 75;

	/* Build the filename */
	path_build(buf, 1024, ANGBAND_DIR_EDIT, "o_output.txt");

	/* Check for existing file */
	fd = fd_open(buf, O_RDONLY);

	/* Existing file */
	if (fd >= 0)
	{
		char out_val[160];

		/* Close the file */
		fd_close(fd);

		/* Build query */
		sprintf(out_val, "Replace existing file %s? ", buf);

		/* Ask */
		if (get_check(out_val)) fd = -1;
	}

	/* Open the non-existing file */
	if (fd < 0) fff = my_fopen(buf, "w");

	/* No output file - fail */
	if (!fff) return;

	/* Write a note */
	fprintf(fff, "# File: o_info.txt (autogenerated)\n\n");

	/* Read and print out all the objects */
	for (i = 0; i < z_info->k_max; i++)
	{

		int counter = 1;

		cptr color_name;

		/* Get the object */
		k_ptr = &k_info[i];

		/* Ignore unused objects */
		if (!strlen((k_name + k_ptr->name)))
		{
			fprintf(fff, "## empty space (available for object) ##\n\n");
			continue;
		}

		/* Perform any translations */

		/* Write New/Number/Name */
		fprintf(fff, "N:%d:%s\n", i, k_name + k_ptr->name);

		/*get the color name*/
		color_name = get_ext_color_name(k_ptr->d_attr);

		/* Write G: line */
		fprintf(fff, "G:%d:%c:%s\n", i, k_ptr->d_char, color_name);

		/*don't do the rest for the pile symbol*/
		if (i == 0)
		{

			/* Write G: line */
			fprintf(fff, "\n\n\n");
			continue;
		}

		/* Write I: line */
		fprintf(fff, "I:%d:%d:%d:%d\n", i, k_ptr->tval, k_ptr->sval, k_ptr->pval);

		/* Write W: line */
		fprintf(fff, "W:%d:%d:%d:%d\n", i, k_ptr->k_level, k_ptr->weight, k_ptr->cost);

		/* Write P: line */
		fprintf(fff, "P:%d:%d:%d:d:%d:%d:%d:%d\n", i, k_ptr->ac, k_ptr->dd, k_ptr->ds,
						k_ptr->to_h, k_ptr->to_d, k_ptr->to_a);

		/* Write this A line */
		fprintf(fff, "A:%d:%d:%d:%d:%d:%d:%d\n", i,
				k_ptr->locale[0], k_ptr->chance[0],
				k_ptr->locale[1], k_ptr->chance[1],
				k_ptr->locale[2], k_ptr->chance[2]);

		/* Get the flags, store flag text in a format easily parsed by a
		 * database, but pretty much illegible to a person.
		 */
		dump_flags(fff, k_ptr->k_flags1, 1, i);
		dump_flags(fff, k_ptr->k_flags2, 2, i);
		dump_flags(fff, k_ptr->k_flags3, 3, i);
		dump_flags(fff, k_ptr->k_native, 4, i);

		/* Acquire the description */
		desc = k_text + k_ptr->text;
		dlen = strlen(desc);

		if (dlen < 1)
		{
			/* Space between entries */
			fprintf(fff, "\n\n\n");
			continue;
		}

		/* Write Description */
		for (j = 0; j < dlen;)
		{

			char buf[160], *t;

			/* Initialize */
			t = buf;
			bc = 0;

			/* Build this line */
			while (TRUE)
			{
				/* Insert this character, count it */
				*t++ = desc[j++];

				/* Oops.  Line is too long. */
				if (bc++ >= line_length)
				{
					/* Parse backwards until we find a space */
					while (!my_isspace(desc[j-1]) && (bc-- > 40))
					{
						j--;
						t--;
					}

					/* Time to end this line */
					*t++ = '\0';
					break;
				}

				/* All done */
				if (j >= dlen)
				{
					/* Time to end this line */
					*t++ = '\0';
					break;
				}
			}

			/* Done with this line; write it */
			fprintf(fff, "D-%d:%d:%s\n", counter, i, buf);

			counter++;
		}

		/*
		 * Print out empty lines, so all objects have
		 * an equal number of lines
		 * makes parsing and combining the description easier
		 */
		for (; counter <+ 9; counter++)
		{
			fprintf(fff, "D-%d:%d\n", counter, i);
		}

		/* Space between entries */
		fprintf(fff, "\n\n\n");

	}

	/* Done */
	fclose(fff);
}
Пример #17
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(const char *name, const char *what, int line, int mode)
{
	int i, k, n;

	struct keypress 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 */
	const char *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;
	
	/* TRUE if we are inside a RST block that should be skipped */
	bool skip_lines = FALSE;



	/* 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, FTYPE_TEXT);
	}

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

		path_build(path, sizeof(path), ANGBAND_DIR_HELP, name);
		fff = file_open(path, MODE_READ, FTYPE_TEXT);
	}

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

		path_build(path, sizeof(path), ANGBAND_DIR_INFO, name);
		fff = file_open(path, MODE_READ, FTYPE_TEXT);
	}

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

		/* Oops */
		return (TRUE);
	}


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

		/* Skip lines if we are inside a RST directive*/
		if(skip_lines){
			if(contains_only_spaces(buf))
				skip_lines=FALSE;
			continue;
		}

		/* Parse a very small subset of RST */
		/* TODO: should be more flexible */
		if (prefix(buf, ".. "))
		{
			/* parse ".. menu:: [x] filename.txt" (with exact spacing)*/
			if(prefix(buf+strlen(".. "), "menu:: [") && 
                           buf[strlen(".. menu:: [x")]==']')
			{
				/* This is a menu file */
				menu = TRUE;

				/* Extract the menu item */
				k = A2I(buf[strlen(".. menu:: [")]);

				/* Store the menu item (if valid) */
				if ((k >= 0) && (k < 26))
					my_strcpy(hook[k], buf + strlen(".. menu:: [x] "), sizeof(hook[0]));
			}
			/* parse ".. _some_hyperlink_target:" */
			else if (buf[strlen(".. ")] == '_')
			{
				if (tag)
				{
					/* Remove the closing '>' of the tag */
					buf[strlen(buf) - 1] = '\0';

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

			/* Skip this and enter skip mode*/
			skip_lines = TRUE;
			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;

		skip_lines = FALSE;
		/* 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, FTYPE_TEXT);
			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 lines if we are inside a RST directive*/
			if(skip_lines){
				if(contains_only_spaces(buf))
					skip_lines=FALSE;
				continue;
			}

			/* Skip RST directives */
			if (prefix(buf, ".. "))
			{
				skip_lines=TRUE;
				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;

			/* Skip lines if we are inside a RST directive*/
			if(skip_lines){
				if(contains_only_spaces(buf))
					skip_lines=FALSE;
				continue;
			}

			/* Skip RST directives */
			if (prefix(buf, ".. "))
			{
				skip_lines=TRUE;
				continue;
			}

			/* skip | characters */
			strskip(buf,'|');

			/* escape backslashes */
			strescape(buf,'\\');

			/* 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, COLOUR_WHITE, buf);

			/* Highlight "shower" */
			if (shower[0])
			{
				const char *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, COLOUR_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, Line %d-%d/%d]", buildid,
		           caption, line, line + hgt - 4, size), 0, 0);


		/* Prompt -- menu screen */
		if (menu)
		{
			/* Wait for it */
			prt("[Press a Letter, 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.code == '?') break;

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

		/* Try showing */
		if (ch.code == '&')
		{
			/* 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.code == '/')
		{
			/* 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.code == '#')
		{
			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.code == '%')
		{
			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.code = ESCAPE;
			}
		}

		switch (ch.code) {
			/* up a line */
			case ARROW_UP:
			case '8': line--; break;

			/* up a page */
			case KC_PGUP:
			case '9':
			case '-': line -= (hgt - 4); break;

			/* home */
			case KC_HOME:
			case '7': line = 0; break;

			/* down a line */
			case ARROW_DOWN:
			case '2':
			case KC_ENTER: line++; break;

			/* down a page */
			case KC_PGDOWN:
			case '3':
			case ' ': line += hgt - 4; break;

			/* end */
			case KC_END:
			case '1': line = size; break;
		}

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

			/* 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.code = ESCAPE;
			}
		}

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

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

	/* Done */
	return (ch.code != '?');
}
Пример #18
0
/*
 * Dump the ego-item information in a format easily parsed by a spreadsheet.
 *
 * Original function by -EB- (probably), revisions by -LM- & JG.
 */
void write_e_info_txt(void)
{
	int i, j, bc;
	int dlen;

	char buf[1024];

	int fd;
	FILE *fff = NULL;

	cptr desc;

	ego_item_type *e_ptr;

	/* We allow 75 characters on the line (plus 2) */
	u16b line_length = 75;

	/* Build the filename */
	path_build(buf, 1024, ANGBAND_DIR_EDIT, "e_output.txt");

	/* Check for existing file */
	fd = fd_open(buf, O_RDONLY);

	/* Existing file */
	if (fd >= 0)
	{
		char out_val[160];

		/* Close the file */
		fd_close(fd);

		/* Build query */
		sprintf(out_val, "Replace existing file %s? ", buf);

		/* Ask */
		if (get_check(out_val)) fd = -1;
	}

	/* Open the non-existing file */
	if (fd < 0) fff = my_fopen(buf, "w");

	/* No output file - fail */
	if (!fff) return;

	/* Write a note */
	fprintf(fff, "# File: e_info.txt (autogenerated)\n\n");

	/* Read and print out all the objects */
	for (i = 0; i < z_info->e_max; i++)
	{

		int counter = 1;

		/* Get the ego-item */
		e_ptr = &e_info[i];

		/* Ignore empty monsters */
		if (!strlen((e_name + e_ptr->name)))
		{
			fprintf(fff, "## empty space (available for ego-item) ##\n\n");
			continue;
		}

		/* Perform any translations */

		/* Write New/Number/Name */
		fprintf(fff, "N:%d:%s\n", i, e_name + e_ptr->name);

		/* Write X: line */
		fprintf(fff, "X:%d:%d:%d\n", i, e_ptr->rating, e_ptr->xtra);

		/* Write C: line */
		fprintf(fff, "C:%d:%d:%d:%d:%d\n", i, e_ptr->max_to_h, e_ptr->max_to_d,
										   e_ptr->max_to_a, e_ptr->max_pval);

		/* Write W: line */
		fprintf(fff, "W:%d:%d:%d:0:%d\n", i, e_ptr->level, e_ptr->rarity, e_ptr->cost);

		/* Write the T lines */
		fprintf(fff, "T:%d:%d:%d:%d:%d:%d:%d:%d:%d:%d\n", i,
				e_ptr->tval[0], e_ptr->min_sval[0], e_ptr->max_sval[0],
				e_ptr->tval[1], e_ptr->min_sval[1], e_ptr->max_sval[1],
				e_ptr->tval[2], e_ptr->min_sval[2], e_ptr->max_sval[2]);

		/* Get the flags, store flag text in a format easily parsed by a
		 * database, but pretty much illegible to a person.
		 */
		dump_flags(fff, e_ptr->flags1, 1, i);
		dump_flags(fff, e_ptr->flags2, 2, i);
		dump_flags(fff, e_ptr->flags3, 3, i);
		dump_flags(fff, e_ptr->e_native, 4, i);

		/* Acquire the description */
		desc = e_text + e_ptr->text;
		dlen = strlen(desc);

		if (dlen < 1)
		{
			/* Space between entries */
			fprintf(fff, "\n\n\n");
			continue;
		}

		/* Write Description */
		for (j = 0; j < dlen;)
		{

			char buf[160], *t;

			/* Initialize */
			t = buf;
			bc = 0;

			/* Build this line */
			while (TRUE)
			{
				/* Insert this character, count it */
				*t++ = desc[j++];

				/* Oops.  Line is too long. */
				if (bc++ >= line_length)
				{
					/* Parse backwards until we find a space */
					while (!my_isspace(desc[j-1]) && (bc-- > 40))
					{
						j--;
						t--;
					}

					/* Time to end this line */
					*t++ = '\0';
					break;
				}

				/* All done */
				if (j >= dlen)
				{
					/* Time to end this line */
					*t++ = '\0';
					break;
				}
			}

			/* Done with this line; write it */
			fprintf(fff, "D-%d:%d:%s\n", counter, i, buf);

			counter++;
		}

		/*
		 * Print out empty lines, so all objects have
		 * an equal number of lines
		 * makes parsing and combining the description easier
		 */
		for (; counter <+ 6; counter++)
		{
			fprintf(fff, "D-%d:%d\n", counter, i);
		}

		/* Space between entries */
		fprintf(fff, "\n\n\n");

	}

	/* Done */
	fclose(fff);
}
Пример #19
0
/*
 * Save a "bones" file for a dead character
 *
 * Should probably attempt some form of locking...
 */
void make_bones(void)
{
#if 0 /* DGDGDGDG */
	FILE *fp;

	int i;

	char str[1024];


	/* Ignore wizards and borgs */
	if (!(noscore & 0x00FF))
	{
		/* Ignore people who die in town */
		if (dun_level)
		{
			int level;
			char tmp[128];

			/* Slightly more tenacious saving routine. */
			for (i = 0; i < 5; i++)
			{
				/* Ghost hovers near level of death. */
				if (i == 0) level = dun_level;
				else level = dun_level + 5 - damroll(2, 4);
				if (level < 1) level = randint(4);

				/* XXX XXX XXX "Bones" name */
				sprintf(tmp, "bone%03d.%03d", dungeon_type, level);

				/* Build the filename */
				path_build(str, 1024, ANGBAND_DIR_BONE, tmp);

				/* Grab permission */
				safe_setuid_grab();

				/* Attempt to open the bones file */
				fp = my_fopen(str, "r");

				/* Drop permission */
				safe_setuid_drop();

				/* Close it right away */
				if (fp) my_fclose(fp);

				/* Do not over-write a previous ghost */
				if (fp) continue;

				/* If no file by that name exists, we can make a new one. */
				if (!(fp)) break;
			}


			/* File type is "TEXT" */
			FILE_TYPE(FILE_TYPE_TEXT);

			/* Grab permission */
			safe_setuid_grab();

			/* Try to write a new "Bones File" */
			fp = my_fopen(str, "w");

			/* Drop permission */
			safe_setuid_drop();

			/* Not allowed to write it?  Weird. */
			if (!fp) return;

			/* Save the info */
			fprintf(fp, "%s\n", player_name);
			fprintf(fp, "%d\n", p_ptr->mhp);
			fprintf(fp, "%d\n", p_ptr->prace);
			fprintf(fp, "%d\n", p_ptr->pclass);

			/* Close and save the Bones file */
			my_fclose(fp);
		}
	}
#endif
}
Пример #20
0
/*
 * Use the monster racial information to a format easily parsed by a spreadsheet.
 *
 * Original function by -EB- (probably), revisions by -LM- & JG.
 */
void write_r_info_txt(void)
{
	int i, j, bc;
	int dlen;

	char buf[1024];

	int fd;
	FILE *fff = NULL;

	cptr desc;

	monster_race *r_ptr;

	/* We allow 75 characters on the line (plus 2) */
	u16b line_length = 75;

	/* Build the filename */
	path_build(buf, 1024, ANGBAND_DIR_EDIT, "r_output.txt");

	/* Check for existing file */
	fd = fd_open(buf, O_RDONLY);

	/* Existing file */
	if (fd >= 0)
	{
		char out_val[160];

		/* Close the file */
		fd_close(fd);

		/* Build query */
		sprintf(out_val, "Replace existing file %s? ", buf);

		/* Ask */
		if (get_check(out_val)) fd = -1;
	}

	/* Open the non-existing file */
	if (fd < 0) fff = my_fopen(buf, "w");

	/* No output file - fail */
	if (!fff) return;

	/* Write a note */
	fprintf(fff, "# File: r_info.txt (autogenerated)\n\n");

	/* Write a note */
	fprintf(fff, "##### The Player #####\n\n");

	/* Read and print out all the monsters */
	for (i = 0; i < z_info->r_max; i++)
	{
		char what_char;

		cptr color_name;

		int counter = 1;

		/* Get the monster */
		r_ptr = &r_info[i];

		/* Ignore empty monsters */
		if (!strlen(r_name + r_ptr->name))
		{
			fprintf(fff, "## empty space (available for monsters) ##\n\n");
			continue;
		}

		/* Ignore useless monsters */
		if (i && !r_ptr->speed)
		{
			fprintf(fff, "## empty space (available for monsters) ##\n\n");
			continue;
		}

		/* Perform any translations */

		/* Write New/Number/Name */
		fprintf(fff, "N:%d:%d:%s\n", i, i, r_name + r_ptr->name);

		/*get the color name*/
		color_name = get_ext_color_name(r_ptr->d_attr);

		/* Write G: line */
		if (r_ptr->rarity) fprintf(fff, "G:%d:%c:%s \n",
			i, r_ptr->d_char, color_name);

		/*don't do rest for player*/
		if (i == 0)
		{
			/* Write a note */
			fprintf(fff, "\n\n ##### The Monsters #####\n\n");

			continue;
		}


		/* Write I: line */
		fprintf(fff, "I:%d:%d:%dd%d:%d:%d:%d\n", i,
		r_ptr->speed, r_ptr->hdice, r_ptr->hside,
		r_ptr->aaf, r_ptr->ac, r_ptr->sleep);

		/* Write W: line */
		fprintf(fff, "W:%d:%d::%d:%d:%ld\n", i, r_ptr->level, r_ptr->rarity,
		    r_ptr->mana, r_ptr->mexp);

		/* Write blows */
		for(j = 0; j < 4; j++)
		{

			/* Write this blow */
			fprintf(fff, format("B-%d:%d:%d:%d:%dd%d\n", j, i,
				r_ptr->blow[j].method, r_ptr->blow[j].effect,
				r_ptr->blow[j].d_dice, r_ptr->blow[j].d_side));
		}

		what_char = 'F';

		/* Get the flags, store flag text in a format easily parsed by a
		 * database, but pretty much illegible to a person.
		 */
		dump_flags(fff, r_ptr->flags1, 1, i);
		dump_flags(fff, r_ptr->flags2, 2, i);
		dump_flags(fff, r_ptr->flags3, 3, i);
		dump_flags(fff, r_ptr->flags4, 4, i);
		dump_flags(fff, r_ptr->flags5, 5, i);
		dump_flags(fff, r_ptr->flags6, 6, i);

		/* Write the terrain native flag. */
		what_char = 'T';

		dump_flags(fff, r_ptr->r_native, 8, i);

		fprintf(fff, "S:%d:%d:%d\n", i, r_ptr->freq_ranged, r_ptr->spell_power);

		/*now the summon flag*/
		what_char = 'S';

		dump_flags(fff, r_ptr->flags7, 7, i);


		/* Acquire the description */
		desc = r_text + r_ptr->text;
		dlen = strlen(desc);

		/* Write Description */
		for (j = 0; j < dlen;)
		{

			char buf[160], *t;

			/* Initialize */
			t = buf;
			bc = 0;

			/* Build this line */
			while (TRUE)
			{
				/* Insert this character, count it */
				*t++ = desc[j++];

				/* Oops.  Line is too long. */
				if (bc++ >= line_length)
				{
					/* Parse backwards until we find a space */
					while (!my_isspace(desc[j-1]) && (bc-- > 40))
					{
						j--;
						t--;
					}

					/* Time to end this line */
					*t++ = '\0';
					break;
				}

				/* All done */
				if (j >= dlen)
				{
					/* Time to end this line */
					*t++ = '\0';
					break;
				}
			}

			/* Done with this line; write it */
			fprintf(fff, "D-%d:%d:%s\n", counter, i, buf);

			counter++;
		}

		/*
		 * Print out empty lines, so all monsters have
		 * an equal number of lines
		 * makes parsing and combining the description easier
		 */
		for (; counter <+ 12; counter++)
		{
			fprintf(fff, "D-%d:%d\n", counter, i);
		}

		/* Space between entries */
		fprintf(fff, "\n\n\n");

	}

	/* Done */
	fclose(fff);
}
Пример #21
0
/*
 * Create a spoiler file for artifacts
 */
static void spoil_artifact(const char *fname)
{
	int i, j;

	object_type *i_ptr;
	object_type object_type_body;

	char buf[1024];


	/* Build the filename */
	path_build(buf, sizeof(buf), ANGBAND_DIR_USER, fname);
	fh = file_open(buf, MODE_WRITE, FTYPE_TEXT);

	/* Oops */
	if (!fh)
	{
		msg("Cannot create spoiler file.");
		return;
	}

	/* Dump to the spoiler file */
	text_out_hook = text_out_to_file;
	text_out_file = fh;

	/* Dump the header */
	spoiler_underline(format("Artifact Spoilers for %s", buildid), '=');

	/* List the artifacts by tval */
	for (i = 0; group_artifact[i].tval; i++)
	{
		/* Write out the group title */
		if (group_artifact[i].name)
		{
			spoiler_blanklines(2);
			spoiler_underline(group_artifact[i].name, '=');
			spoiler_blanklines(1);
		}

		/* Now search through all of the artifacts */
		for (j = 1; j < z_info->a_max; ++j)
		{
			artifact_type *a_ptr = &a_info[j];
			char buf[80];

			/* We only want objects in the current group */
			if (a_ptr->tval != group_artifact[i].tval) continue;

			/* Get local object */
			i_ptr = &object_type_body;

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

			/* Attempt to "forge" the artifact */
			if (!make_fake_artifact(i_ptr, a_ptr)) continue;

			/* Grab artifact name */
			object_desc(buf, sizeof(buf), i_ptr, ODESC_PREFIX |
				ODESC_COMBAT | ODESC_EXTRA | ODESC_SPOIL);

			/* Print name and underline */
			spoiler_underline(buf, '-');

			/* Write out the artifact description to the spoiler file */
			object_info_spoil(fh, i_ptr, 80);

			/*
			 * Determine the minimum and maximum depths an
			 * artifact can appear, its rarity, its weight, and
			 * its power rating.
			 */
			text_out("\nMin Level %u, Max Level %u, Generation chance %u, Power %d, %d.%d lbs\n",
				a_ptr->alloc_min, a_ptr->alloc_max,
				a_ptr->alloc_prob, object_power(i_ptr, FALSE,
				NULL, TRUE), (a_ptr->weight / 10),
				(a_ptr->weight % 10));

			/* Terminate the entry */
			spoiler_blanklines(2);
		}
	}

	/* Check for errors */
	if (!file_close(fh))
	{
		msg("Cannot close spoiler file.");
		return;
	}

	/* Message */
	msg("Successfully created a spoiler file.");
}
Пример #22
0
/*
 * Use the monster racial information to a format easily parsed by a spreadsheet.
 *
 * Original function by -EB- (probably), revisions by -LM- & JG.
 * Note: This function needs some updating as it is missing some fields.
 */
void write_f_info_txt(void)
{
	int i, j, bc, x;
	int dlen;

	char buf[1024];

	int fd;
	FILE *fff = NULL;

	cptr desc;

	feature_type *f_ptr;

	/* We allow 75 characters on the line (plus 2) */
	u16b line_length = 75;

	/* Build the filename */
	path_build(buf, 1024, ANGBAND_DIR_EDIT, "f_output.txt");

	/* Check for existing file */
	fd = fd_open(buf, O_RDONLY);

	/* Existing file */
	if (fd >= 0)
	{
		char out_val[160];

		/* Close the file */
		fd_close(fd);

		/* Build query */
		sprintf(out_val, "Replace existing file %s? ", buf);

		/* Ask */
		if (get_check(out_val)) fd = -1;
	}

	/* Open the non-existing file */
	if (fd < 0) fff = my_fopen(buf, "w");

	/* No output file - fail */
	if (!fff) return;

	/* Write a note */
	fprintf(fff, "# File: f_info.txt (autogenerated)\n\n");

	/* Read and print out all the features */
	for (i = 0; i < z_info->f_max; i++)
	{

		cptr color_name;

		int counter = 1;

		desc = NULL;

		/* Get the monster */
		f_ptr = &f_info[i];

		/* Ignore empty monsters */
		if (!strlen(f_name + f_ptr->name))
		{
			fprintf(fff, "## empty space (available for terrain) ##\n\n");
			continue;
		}

		/* Perform any translations */

		/* Write New/Number/Name */
		fprintf(fff, "N:%d:%d:%s\n", i, i, f_name + f_ptr->name);

		/* Write Mimic  */
		if (f_ptr->f_mimic > 0)
		{
			/*hack, switch to a new f_ptr- t outpit out the name*/
			f_ptr = &f_info[f_info[i].f_mimic];
			fprintf(fff, "M:%d:%s\n", i, f_name + f_ptr->name);
			/* Switch Back*/
			f_ptr = &f_info[i];
		}

		/* Write Edge  */
		if (f_ptr->f_edge > 0)
		{
			/*hack, switch to a new f_ptr- t outpit out the name*/
			f_ptr = &f_info[f_info[i].f_edge];
			fprintf(fff, "E:%d:%s\n", i, f_name + f_ptr->name);
			/* Switch Back*/
			f_ptr = &f_info[i];
		}

		/*get the color name*/
		color_name = get_ext_color_name(f_ptr->d_attr);

		/* Write G: line */
		fprintf(fff, "G:%d:%c:%s\n",i, f_ptr->d_char, color_name);

		if (f_ptr->f_edge > 0)
		{
			/*hack, switch to a new f_ptr- t outpit out the name*/
			f_ptr = &f_info[f_info[i].f_edge];
			desc = (f_name + f_ptr->name);
			/* Switch Back*/
			f_ptr = &f_info[i];

		}
		else desc = NULL;

		/* Write W: line */
		fprintf(fff, "W:%d:%d:%d:%d:%d:\n", i, f_ptr->f_level, f_ptr->f_rarity,
	    	f_ptr->priority, f_ptr->f_power);

		/* Write C: line */
		fprintf(fff, "C:%d:%d:%d:%d:%d:%d:%d:\n", i, f_ptr->dam_non_native, f_ptr->native_energy_move,
	   	 	f_ptr->non_native_energy_move, f_ptr->native_to_hit_adj,
			f_ptr->non_native_to_hit_adj, f_ptr->f_stealth_adj);


		/* Write X: line */
		fprintf(fff, "X:%d:%d:%d:%d:%d:%d:%d:%d:\n", i, f_ptr->f_level, f_ptr->f_rarity,
	   	 	f_ptr->f_power, f_ptr->x_damage, f_ptr->x_gf_type,
			f_ptr->x_timeout_set, f_ptr->x_timeout_rand);


		/* Get the flags, store flag text in a format easily parsed by a
		 * database, but pretty much illegible to a person.
		 */
		dump_flags(fff, f_ptr->f_flags1, 1, i);
		dump_flags(fff, f_ptr->f_flags2, 2, i);
		dump_flags(fff, f_ptr->f_flags3, 3, i);

		/*Drop the default*/
		fprintf(fff, "DEFAULT:%d:%d\n", i, f_ptr->defaults);

		/* Find the next empty state slot (if any) */
		for (x = 0; x < MAX_FEAT_STATES; x++)
		{

			if (f_ptr->state[x].fs_action != FS_FLAGS_END)
			{
				char action_desc[80];

				get_feature_name(action_desc, sizeof(action_desc),
											f_ptr->state[x].fs_action);

				if (f_ptr->state[x].fs_result > 0)
				{
					/*Get the name of terrain switching to*/
					f_ptr = &f_info[f_ptr->state[x].fs_result];
					desc = (f_name + f_ptr->name);
					/* Switch Back*/
					f_ptr = &f_info[i];

				}
				else desc = NULL;

				/*drop the "K" line*/
				fprintf(fff, "K%d:%d:%s:%s:%d\n", i, x, action_desc, desc, f_ptr->state[x].fs_power);
			}
		}

		/* Acquire the description */
		desc = f_text + f_ptr->f_text;
		dlen = strlen(desc);

		/* Write Description */
		for (j = 0; j < dlen;)
		{

			char buf[160], *t;

			/* Initialize */
			t = buf;
			bc = 0;

			/* Build this line */
			while (TRUE)
			{
				/* Insert this character, count it */
				*t++ = desc[j++];

				/* Oops.  Line is too long. */
				if (bc++ >= line_length)
				{
					/* Parse backwards until we find a space */
					while (!my_isspace(desc[j-1]) && (bc-- > 40))
					{
						j--;
						t--;
					}

					/* Time to end this line */
					*t++ = '\0';
					break;
				}

				/* All done */
				if (j >= dlen)
				{
					/* Time to end this line */
					*t++ = '\0';
					break;
				}
			}

			/* Done with this line; write it */
			fprintf(fff, "D-%d:%d:%s\n", counter, i, buf);

			counter++;
		}

		/*
		 * Print out empty lines, so all monsters have
		 * an equal number of lines
		 * makes parsing and combining the description easier
		 */
		for (; counter <+ 3; counter++)
		{
			fprintf(fff, "D-%d:%d\n", counter, i);
		}

		/* Space between entries */
		fprintf(fff, "\n\n\n");

	}

	/* Done */
	fclose(fff);
}
Пример #23
0
/*
 * Create a spoiler file for monsters (-SHAWN-)
 */
static void spoil_mon_info(const char *fname)
{
	char buf[1024];
	int i, n;
	u16b *who;
	int count = 0;


	/* Open the file */
	path_build(buf, sizeof(buf), ANGBAND_DIR_USER, fname);
	fh = file_open(buf, MODE_WRITE, FTYPE_TEXT);

	/* Oops */
	if (!fh)
	{
		msg("Cannot create spoiler file.");
		return;
	}

	/* Dump to the spoiler file */
	text_out_hook = text_out_to_file;
	text_out_file = fh;

	/* Dump the header */
	text_out("Monster Spoilers for %s\n", buildid);
	text_out("------------------------------------------\n\n");

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

	/* Scan the monsters */
	for (i = 1; i < z_info->r_max; i++)
	{
		monster_race *r_ptr = &r_info[i];

		/* Use that monster */
		if (r_ptr->name) who[count++] = (u16b)i;
	}

	sort(who, count, sizeof(*who), cmp_monsters);

	/*
	 * List all monsters in order (except the ghost).
	 */
	for (n = 0; n < count; n++)
	{
		int r_idx = who[n];
		monster_race *r_ptr = &r_info[r_idx];

		/* Prefix */
		if (rf_has(r_ptr->flags, RF_QUESTOR))
		{
			text_out("[Q] ");
		}
		else if (rf_has(r_ptr->flags, RF_UNIQUE))
		{
			text_out("[U] ");
		}
		else
		{
			text_out("The ");
		}

		/* Name */
		text_out("%s  (",  r_ptr->name);	/* ---)--- */

		/* Color */
		text_out(attr_to_text(r_ptr->d_attr));

		/* Symbol --(-- */
		text_out(" '%c')\n", r_ptr->d_char);


		/* Indent */
		text_out("=== ");

		/* Number */
		text_out("Num:%d  ", r_idx);

		/* Level */
		text_out("Lev:%d  ", r_ptr->level);

		/* Rarity */
		text_out("Rar:%d  ", r_ptr->rarity);

		/* Speed */
		if (r_ptr->speed >= 110)
		{
			text_out("Spd:+%d  ", (r_ptr->speed - 110));
		}
		else
		{
			text_out("Spd:-%d  ", (110 - r_ptr->speed));
		}

		/* Hitpoints */
		text_out("Hp:%d  ", r_ptr->avg_hp);

		/* Armor Class */
		text_out("Ac:%d  ", r_ptr->ac);

		/* Experience */
		text_out("Exp:%ld\n", (long)(r_ptr->mexp));

		/* Describe */
		describe_monster(r_idx, TRUE);

		/* Terminate the entry */
		text_out("\n");
	}

	/* Free the "who" array */
	FREE(who);

	/* Check for errors */
	if (!file_close(fh))
	{
		msg("Cannot close spoiler file.");
		return;
	}

	msg("Successfully created a spoiler file.");
}
Пример #24
0
/*
 * Dump the object information a format easily parsed by a spreadsheet.
 *
 * Original function by -EB- (probably), revisions by -LM- & JG.
 */
void write_a_info_txt(void)
{
	int i, j, bc;
	int dlen;

	char buf[1024];



	int fd;
	FILE *fff = NULL;

	cptr desc;

	artifact_type *a_ptr;

	/* We allow 75 characters on the line (plus 2) */
	u16b line_length = 75;

	/* Build the filename */
	path_build(buf, 1024, ANGBAND_DIR_EDIT, "a_output.txt");

	/* Check for existing file */
	fd = fd_open(buf, O_RDONLY);

	/* Existing file */
	if (fd >= 0)
	{
		char out_val[160];

		/* Close the file */
		fd_close(fd);

		/* Build query */
		sprintf(out_val, "Replace existing file %s? ", buf);

		/* Ask */
		if (get_check(out_val)) fd = -1;
	}

	/* Open the non-existing file */
	if (fd < 0) fff = my_fopen(buf, "w");

	/* No output file - fail */
	if (!fff) return;

	/* Write a note */
	fprintf(fff, "# File: a_info.txt (autogenerated)\n\n");

	/* Read and print out all the objects */
	for (i = 0; i < z_info->art_norm_max; i++)
	{

		int counter = 1;
		char o_name[80];
		object_type *i_ptr;
		object_type object_type_body;

		/* Get local object */
		i_ptr = &object_type_body;

		/* Get the object */
		a_ptr = &a_info[i];

		/* Ignore unused objects */
		if (!strlen(a_ptr->name))
		{
			fprintf(fff, "## empty space (available for artifact) ##\n\n");
			continue;
		}

		/* Perform any translations */

		/* Write New/Number/Name */
		fprintf(fff, "N:%d:%s\n", i, a_ptr->name);

		/* Write the complete name of the artifact*/
		make_fake_artifact(i_ptr, i);

		/*identify it*/
		/* Identify it */
		object_aware(i_ptr);
		object_known(i_ptr);
		i_ptr->ident |= (IDENT_MENTAL);

		/* Get a description to dump */
		object_desc(o_name, sizeof(o_name), i_ptr, TRUE, 0);

		/*dump the long name*/
		fprintf(fff, "desc:%d: # %s\n", i, o_name);

		/* Write I: line */
		fprintf(fff, "I:%d:%d:%d:%d\n", i, a_ptr->tval, a_ptr->sval, a_ptr->pval);

		/* Write W: line */
		fprintf(fff, "W:%d:%d:%d:%d:%d\n", i, a_ptr->a_level, a_ptr->a_rarity,
											a_ptr->weight, a_ptr->cost);

		/* Write P: line */
		fprintf(fff, "P:%d:%d:%d:d:%d:%d:%d:%d\n", i, a_ptr->ac, a_ptr->dd, a_ptr->ds,
						a_ptr->to_h, a_ptr->to_d, a_ptr->to_a);

		/* Get the flags, store flag text in a format easily parsed by a
		 * database, but pretty much illegible to a person.
		 */
		dump_flags(fff, a_ptr->a_flags1, 1, i);
		dump_flags(fff, a_ptr->a_flags2, 2, i);
		dump_flags(fff, a_ptr->a_flags3, 3, i);
		dump_flags(fff, a_ptr->a_native, 4, i);

		/* Write the A line */
		fprintf(fff, "A:%d:%d:%d:%d\n", i,
				a_ptr->activation, a_ptr->time, a_ptr->randtime);

		/* Acquire the description */
		desc = a_text + a_ptr->text;
		dlen = strlen(desc);

		if (dlen < 1)
		{
			/* Space between entries */
			fprintf(fff, "\n\n\n");
			continue;
		}

		/* Write Description */
		for (j = 0; j < dlen;)
		{

			char buf[160], *t;

			/* Initialize */
			t = buf;
			bc = 0;

			/* Build this line */
			while (TRUE)
			{
				/* Insert this character, count it */
				*t++ = desc[j++];

				/* Oops.  Line is too long. */
				if (bc++ >= line_length)
				{
					/* Parse backwards until we find a space */
					while (!my_isspace(desc[j-1]) && (bc-- > 40))
					{
						j--;
						t--;
					}

					/* Time to end this line */
					*t++ = '\0';
					break;
				}

				/* All done */
				if (j >= dlen)
				{
					/* Time to end this line */
					*t++ = '\0';
					break;
				}
			}

			/* Done with this line; write it */
			fprintf(fff, "D-%d:%d:%s\n", counter, i, buf);

			counter++;
		}

		/*
		 * Print out empty lines, so all objects have
		 * an equal number of lines
		 * makes parsing and combining the description easier
		 */
		for (; counter <+ 12; counter++)
		{
			fprintf(fff, "D-%d:%d\n", counter, i);
		}

		/* Space between entries */
		fprintf(fff, "\n\n\n");

	}

	/* Done */
	fclose(fff);
}
Пример #25
0
void file_dirscan( char * dir, scanback func, void * closure )
{
    PROFILE_ENTER( FILE_DIRSCAN );

    file_info_t * d = 0;

    d = file_query( dir );

    if ( !d || !d->is_dir )
    {
        PROFILE_EXIT( FILE_DIRSCAN );
        return;
    }

    if ( ! d->files )
    {
        LIST* files = L0;
        PATHNAME f;
        DIR *dd;
        STRUCT_DIRENT *dirent;
        string filename[1];

        /* First enter directory itself */

        memset( (char *)&f, '\0', sizeof( f ) );

        f.f_dir.ptr = dir;
        f.f_dir.len = strlen(dir);

        dir = *dir ? dir : ".";

        /* Now enter contents of directory. */

        if ( !( dd = opendir( dir ) ) )
        {
            PROFILE_EXIT( FILE_DIRSCAN );
            return;
        }

        if ( DEBUG_BINDSCAN )
            printf( "scan directory %s\n", dir );

        string_new( filename );
        while ( ( dirent = readdir( dd ) ) )
        {
            # ifdef old_sinix
            /* Broken structure definition on sinix. */
            f.f_base.ptr = dirent->d_name - 2;
            # else
            f.f_base.ptr = dirent->d_name;
            # endif
            f.f_base.len = strlen( f.f_base.ptr );

            string_truncate( filename, 0 );
            path_build( &f, filename, 0 );

            files = list_new( files, newstr(filename->value) );
            file_query( filename->value );
        }
        string_free( filename );

        closedir( dd );

        d->files = files;
    }

    /* Special case / : enter it */
    {
        unsigned long len = strlen(d->name);
        if ( ( len == 1 ) && ( d->name[0] == '/' ) )
            (*func)( closure, d->name, 1 /* stat()'ed */, d->time );
    }

    /* Now enter contents of directory */
    if ( d->files )
    {
        LIST * files = d->files;
        while ( files )
        {
            file_info_t * ff = file_info( files->string );
            (*func)( closure, ff->name, 1 /* stat()'ed */, ff->time );
            files = list_next( files );
        }
    }

    PROFILE_EXIT( FILE_DIRSCAN );
}
Пример #26
0
/**
 * Evaluate the whole monster list and write a new one.  power and scaled_power
 * are always adjusted, level, rarity and mexp only if requested.
 */
errr eval_monster_power(struct monster_race *racelist)
{
	int i, j, iteration;
	byte lvl;
	monster_race *r_ptr = NULL;
	ang_file *mon_fp;
	char buf[1024];
	bool dump = FALSE;

	/* Allocate arrays */
	power = mem_zalloc(z_info->r_max * sizeof(long));
	scaled_power = mem_zalloc(z_info->r_max * sizeof(long));
	final_hp = mem_zalloc(z_info->r_max * sizeof(long));
	final_melee_dam = mem_zalloc(z_info->r_max * sizeof(long));
	final_spell_dam = mem_zalloc(z_info->r_max * sizeof(long));
	highest_threat = mem_zalloc(z_info->r_max * sizeof(int));

	for (iteration = 0; iteration < 3; iteration ++) {
		long hp, av_hp, dam, av_dam;
		long *tot_hp = mem_zalloc(z_info->max_depth * sizeof(long));
		long *tot_dam = mem_zalloc(z_info->max_depth * sizeof(long));
		long *mon_count = mem_zalloc(z_info->max_depth * sizeof(long));

		/* Reset the sum of all monster power values */
		tot_mon_power = 0;

		/* Go through r_info and evaluate power ratings & flows. */
		for (i = 0; i < z_info->r_max; i++)	{

			/* Point at the "info" */
			r_ptr = &racelist[i];

			/* Set the current level */
			lvl = r_ptr->level;

			/* Maximum damage this monster can do in 10 game turns */
			dam = eval_max_dam(r_ptr, i);

			/* Adjust hit points based on resistances */
			hp = eval_hp_adjust(r_ptr);

			/* Hack -- set exp */
			if (lvl == 0)
				r_ptr->mexp = 0L;
			else {
				/* Compute depths of non-unique monsters */
				if (!rf_has(r_ptr->flags, RF_UNIQUE)) {
					long mexp = (hp * dam) / 25;
					long threat = highest_threat[i];

					/* Compute level algorithmically */
					for (j = 1; (mexp > j + 4) || (threat > j + 5);
						 mexp -= j * j, threat -= (j + 4), j++);

					/* Set level */
					lvl = MIN(( j > 250 ? 90 + (j - 250) / 20 : /* Level 90+ */
								(j > 130 ? 70 + (j - 130) / 6 :	/* Level 70+ */
								 (j > 40 ? 40 + (j - 40) / 3 :	/* Level 40+ */
								  j))), 99);

					/* Set level */
					if (arg_rebalance)
						r_ptr->level = lvl;
				}

				if (arg_rebalance) {
					/* Hack -- for Ungoliant */
					if (hp > 10000)
						r_ptr->mexp = (hp / 25) * (dam / lvl);
					else r_ptr->mexp = (hp * dam) / (lvl * 25);

					/* Round to 2 significant figures */
					if (r_ptr->mexp > 100) {
						if (r_ptr->mexp < 1000) {
							r_ptr->mexp = (r_ptr->mexp + 5) / 10;
							r_ptr->mexp *= 10;
						}
						else if (r_ptr->mexp < 10000) {
							r_ptr->mexp = (r_ptr->mexp + 50) / 100;
							r_ptr->mexp *= 100;
						}
						else if (r_ptr->mexp < 100000) {
							r_ptr->mexp = (r_ptr->mexp + 500) / 1000;
							r_ptr->mexp *= 1000;
						}
						else if (r_ptr->mexp < 1000000) {
							r_ptr->mexp = (r_ptr->mexp + 5000) / 10000;
							r_ptr->mexp *= 10000;
						}
						else if (r_ptr->mexp < 10000000) {
							r_ptr->mexp = (r_ptr->mexp + 50000) / 100000;
							r_ptr->mexp *= 100000;
						}
					}
				}
			}

			/* If we're rebalancing, this is a nop, if not, we restore the
			 * orig value */
			lvl = r_ptr->level;
			if ((lvl) && (r_ptr->mexp < 1L))
				r_ptr->mexp = 1L;

			/*
			 * Hack - We have to use an adjustment factor to prevent overflow.
			 * Try to scale evenly across all levels instead of scaling by level
			 */
			hp /= 2;
			if(hp < 1)
				hp = 1;
			final_hp[i] = hp;

			/* Define the power rating */
			power[i] = hp * dam;

			/* Adjust for group monsters, using somewhat arbitrary 
			 * multipliers for now */
			if (!rf_has(r_ptr->flags, RF_UNIQUE)) {
				if (r_ptr->friends)
					power[i] *= 3;
			}

			/* Adjust for escorts */
			if (r_ptr->friends_base) 
				power[i] *= 2;


			/* Adjust for multiplying monsters. This is modified by the speed,
			 * as fast multipliers are much worse than slow ones. We also
			 * adjust for ability to bypass walls or doors. */
			if (rf_has(r_ptr->flags, RF_MULTIPLY)) {
				int adj_power;

				if (flags_test(r_ptr->flags, RF_SIZE, RF_KILL_WALL,
							   RF_PASS_WALL, FLAG_END))
					adj_power = power[i] * adj_energy(r_ptr);
				else if (flags_test(r_ptr->flags, RF_SIZE, RF_OPEN_DOOR,
									RF_BASH_DOOR, FLAG_END))
					adj_power = power[i] * adj_energy(r_ptr) * 3 / 2;
				else
					adj_power = power[i] * adj_energy(r_ptr) / 2;

				power[i] = MAX(power[i], adj_power);
			}

			/* Update the running totals - these will be used as divisors later
			 * Total HP / dam / count for everything up to the current level */
			for (j = lvl; j < (lvl == 0 ? lvl + 1: z_info->max_depth); j++)	{
				int count = 10;

				/* Uniques don't count towards monster power on the level. */
				if (rf_has(r_ptr->flags, RF_UNIQUE)) continue;

				/* Specifically placed monsters don't count towards monster
				 * power on the level. */
				if (!(r_ptr->rarity)) continue;

				/* Hack -- provide adjustment factor to prevent overflow */
				if ((j == 90) && (r_ptr->level < 90)) {
					hp /= 10;
					dam /= 10;
				}

				if ((j == 65) && (r_ptr->level < 65)) {
					hp /= 10;
					dam /= 10;
				}

				if ((j == 40) && (r_ptr->level < 40)) {
					hp /= 10;
					dam /= 10;
				}

				/* Hack - if it's a group monster or multiplying monster, add
				 * several to the count so the averages don't get thrown off */

				if (r_ptr->friends || r_ptr->friends_base)
					count = 15;

				if (rf_has(r_ptr->flags, RF_MULTIPLY)) {
					int adj_energy_amt;

					if (flags_test(r_ptr->flags, RF_SIZE, RF_KILL_WALL,
								   RF_PASS_WALL, FLAG_END))
						adj_energy_amt = adj_energy(r_ptr);
					else if (flags_test(r_ptr->flags, RF_SIZE, RF_OPEN_DOOR,
										RF_BASH_DOOR, FLAG_END))
						adj_energy_amt = adj_energy(r_ptr) * 3 / 2;
					else
						adj_energy_amt = adj_energy(r_ptr) / 2;

					count = MAX(1, adj_energy_amt) * count;
				}

				/* Very rare monsters count less towards total monster power
				 * on the level. */
				if (r_ptr->rarity > count) {
					hp = hp * count / r_ptr->rarity;
					dam = dam * count / r_ptr->rarity;

					count = r_ptr->rarity;
				}

				tot_hp[j] += hp;
				tot_dam[j] += dam;

				mon_count[j] += count / r_ptr->rarity;
			}

		}

		/* Apply divisors now */
		for (i = 0; i < z_info->r_max; i++) {
			int new_power;

			/* Point at the "info" */
			r_ptr = &racelist[i];

			/* Extract level */
			lvl = r_ptr->level;

			/* Paranoia */
			if (tot_hp[lvl] != 0 && tot_dam[lvl] != 0) {
				scaled_power[i] = power[i];

				/* Divide by av HP and av damage for all in-level monsters */
				/* Note we have factored in the above 'adjustment factor' */
				av_hp = tot_hp[lvl] * 10 / mon_count[lvl];
				av_dam = tot_dam[lvl] * 10 / mon_count[lvl];

				/* Justifiable paranoia - avoid divide by zero errors */
				if (av_hp > 0)
					scaled_power[i] = scaled_power[i] / av_hp;
				if (av_dam > 0)
					scaled_power[i] = scaled_power[i] / av_dam;

				/* Never less than 1 */
				if (power[i] < 1)
					power[i] = 1;

				/* Set powers */
				if (arg_rebalance) {
					r_ptr->power = power[i];
					r_ptr->scaled_power = scaled_power[i];
				}

				/* Get power */
				new_power = power[i];

				/* Compute rarity algorithmically */
				for (j = 1; new_power > j; new_power -= j * j, j++);

				/* Set rarity */
				if (arg_rebalance)
					r_ptr->rarity = j;
			}
		}

		mem_free(mon_count);
		mem_free(tot_dam);
		mem_free(tot_hp);
	}

	/* Determine total monster power */
	for (i = 0; i < z_info->r_max; i++)
		tot_mon_power += r_info[i].scaled_power;

	if (dump) {
		/* Dump the power details */
		path_build(buf, sizeof(buf), ANGBAND_DIR_USER, "mon_power.txt");
		mon_fp = file_open(buf, MODE_WRITE, FTYPE_TEXT);

		file_putf(mon_fp, "ridx|level|rarity|d_char|name|pwr|scaled|melee|spell|hp\n");

		for (i = 0; i < z_info->r_max; i++) {
			char mbstr[MB_LEN_MAX + 1] = { 0 };
			r_ptr = &r_info[i];

			/* Don't print anything for nonexistent monsters */
			if (!r_ptr->name) continue;

			wctomb(mbstr, r_ptr->d_char);
			file_putf(mon_fp, "%d|%d|%d|%s|%s|%d|%d|%d|%d|%d\n", r_ptr->ridx,
				r_ptr->level, r_ptr->rarity, mbstr, r_ptr->name,
				power[i], scaled_power[i], final_melee_dam[i],
				final_spell_dam[i], final_hp[i]);
		}

		file_close(mon_fp);
	}

	/* Write to the user directory */
	path_build(buf, sizeof(buf), ANGBAND_DIR_USER, "new_monster.txt");

	if (text_lines_to_file(buf, write_monster_entries)) {
		msg("Failed to create file %s.new", buf);
		return -1;
	}

	/* Free power arrays */
	mem_free(highest_threat);
	mem_free(final_spell_dam);
	mem_free(final_melee_dam);
	mem_free(final_hp);
	mem_free(scaled_power);
	mem_free(power);

	/* Success */
	return 0;
}
Пример #27
0
/*
 * Hack -- load a screen dump from a file
 *
 * ToDo: Add support for loading/saving screen-dumps with graphics
 * and pseudo-graphics.  Allow the player to specify the filename
 * of the dump.
 */
void do_cmd_load_screen(void)
{
	int i, y, x;

	byte a = 0;
	char c = ' ';

	bool okay = TRUE;

	ang_file *fp;

	char buf[1024];


	/* Build the filename */
	path_build(buf, 1024, ANGBAND_DIR_USER, "dump.txt");
	fp = file_open(buf, MODE_READ, -1);
	if (!fp) return;


	/* Save screen */
	screen_save();


	/* Clear the screen */
	Term_clear();


	/* Load the screen */
	for (y = 0; okay && (y < 24); y++)
	{
		/* Get a line of data */
		if (!file_getl(fp, buf, sizeof(buf))) okay = FALSE;


		/* Show each row */
		for (x = 0; x < 79; x++)
		{
			/* Put the attr/char */
			Term_draw(x, y, TERM_WHITE, buf[x]);
		}
	}

	/* Get the blank line */
	if (!file_getl(fp, buf, sizeof(buf))) okay = FALSE;


	/* Dump the screen */
	for (y = 0; okay && (y < 24); y++)
	{
		/* Get a line of data */
		if (!file_getl(fp, buf, sizeof(buf))) okay = FALSE;

		/* Dump each row */
		for (x = 0; x < 79; x++)
		{
			/* Get the attr/char */
			(void)(Term_what(x, y, &a, &c));

			/* Look up the attr */
			for (i = 0; i < BASIC_COLORS; i++)
			{
				/* Use attr matches */
				if (hack[i] == buf[x]) a = i;
			}

			/* Put the attr/char */
			Term_draw(x, y, a, c);
		}
	}


	/* Close it */
	file_close(fp);


	/* Message */
	msg("Screen dump loaded.");
	message_flush();


	/* Load screen */
	screen_load();
}
Пример #28
0
static void describe_monster_desc(const monster_race *r_ptr)
{
	char buf[2048];

	char *s, *t;

	int match = (r_ptr->flags1 & (RF1_FEMALE)) ? 2 : 1;

	int state = 0;

#ifdef DELAY_LOAD_R_TEXT

	int fd;

	/* Build the filename */
	path_build(buf, 1024, ANGBAND_DIR_DATA, "monster.raw");

	/* Open the "raw" file */
	fd = fd_open(buf, O_RDONLY);

	/* Use file */
	if (fd >= 0)
	{
		long pos;

		/* Starting position */
		pos = r_ptr->text;

		/* Additional offsets */
		pos += r_head->head_size;
		pos += r_head->info_size;
		pos += r_head->name_size;

#if 0

		/* Maximal length */
		len = r_head->text_size - r_ptr->text;

		/* Actual length */
		for (i = r_idx+1; i < z_info->r_max; i++)
		{
			/* Actual length */
			if (r_info[i].text > r_ptr->text)
			{
				/* Extract length */
				len = r_info[i].text - r_ptr->text;

				/* Done */
				break;
			}
		}

		/* Maximal length */
		if (len > 2048) len = 2048;

#endif

		/* Seek */
		fd_seek(fd, pos);

		/* Read a chunk of data */
		fd_read(fd, buf, sizeof(buf));

		/* Close it */
		fd_close(fd);
	}

#else

	/* Simple method */
	my_strcpy(buf, r_text + r_ptr->text, sizeof(buf));

#endif

	/* Remove gender sensitivity */
	for (t = s = buf; *s; s++)
	{
		if (*s == '|')
		{
			state++;
			if (state == 3) state = 0;
		}
		else if (!state || (state == match))
		{
			*t++ = *s;
		}
	}

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

	/* Dump it */
	text_out(buf);

	if (strlen(buf)) text_out("  ");
}
Пример #29
0
TARGET* search_for_target ( char * name, LIST* search_path )
{
    PATHNAME f[1];
    string buf[1];
    LOCATED_TARGET lt, *lta = &lt;
    time_t time;
    int found = 0;
    TARGET* result;

    string_new( buf );

	path_parse( name, f );

    f->f_grist.ptr = 0;
    f->f_grist.len = 0;

    while( search_path )
    {
        f->f_root.ptr = search_path->string;
        f->f_root.len = strlen( search_path->string );

        string_truncate( buf, 0 );
        path_build( f, buf, 1 );

        lt.file_name = buf->value ;

        if (! located_targets )
            located_targets = hashinit( sizeof(LOCATED_TARGET),
                                        "located targets" );


        if ( hashcheck( located_targets, (HASHDATA **)&lta ) )
        {
            return lta->target;
        }

        timestamp( buf->value, &time );
        if (time)
        {
            found = 1;
            break;
        }

        search_path = list_next( search_path );
    }

    if ( ! found )
    {
        f->f_root.ptr = 0;
        f->f_root.len = 0;

        string_truncate( buf, 0 );
        path_build( f, buf, 1 );

        timestamp( buf->value, &time );        
    }

    result = bindtarget( name );
    result->boundname = newstr( buf->value );
    result->time = time;
    result->binding = time ? T_BIND_EXISTS : T_BIND_MISSING;

    call_bind_rule( result->name, result->boundname );
    
    string_free( buf );

    return result;

}
Пример #30
0
/*
 * Race Legends
 * -KMW-
 */
void race_score(int race_num)
{
    register int i = 0, j, m = 0;
    int pr, clev, lastlev;
    high_score the_score;
    char buf[1024], out_val[256], tmp_str[80];

    lastlev = 0;

    /* rr9: TODO - pluralize the race */
    sprintf(tmp_str,"The Greatest of all the %s", get_race_t_aux(race_num, 0)->name);

    prt(tmp_str, 5, 15);

    /* Build the filename */
    path_build(buf, sizeof(buf), ANGBAND_DIR_APEX, "scores.raw");

    highscore_fd = fd_open(buf, O_RDONLY);

    if (highscore_fd < 0)
    {
        msg_print("Score file unavailable.");

        msg_print(NULL);
        return;
    }

    if (highscore_seek(0)) return;

    for (i = 0; i < MAX_HISCORES; i++)
    {
        if (highscore_read(&the_score)) break;
    }

    m = 0;
    j = 0;

    while ((m < 10) || (j < MAX_HISCORES))
    {
        if (highscore_seek(j)) break;
        if (highscore_read(&the_score)) break;
        pr = atoi(the_score.p_r);
        clev = atoi(the_score.cur_lev);

        if (pr == race_num)
        {
            sprintf(out_val, "%3d) %s the %s (Level %3d)",
                (m + 1), the_score.who,
            get_race_t_aux(pr, 0)->name, clev);

            prt(out_val, (m + 7), 0);
            m++;
            lastlev = clev;
        }
        j++;
    }

    /* add player if qualified */
    if ((p_ptr->prace == race_num) && (p_ptr->lev >= lastlev))
    {
        sprintf(out_val, "You) %s the %s (Level %3d)",
            player_name, get_race_t_aux(p_ptr->prace, p_ptr->psubrace)->name, p_ptr->lev);

        prt(out_val, (m + 8), 0);
    }

    (void)fd_close(highscore_fd);
    highscore_fd = -1;
}