Esempio n. 1
0
File: map.c Progetto: jdp/psionrl
/* Generate some ruins */
void generate_ruins(map_t *map) {
    /* Start off with a cave */
    generate_cave(map);

    /* Special room wall tiles */
    tile_t room_wall = tileset[TILE_WALL];
    room_wall.glyph = '%';
    room_wall.fg_lit = C_BROWN;

    /* Put some random rooms onto the map */
    int room, rooms = rand() % 5 + 3;
    int room_x, room_y, room_width, room_height;

    /* Build each room */
    for (room = 0; room < rooms; room++) {
        room_width = rand() % 8 + 4;
        room_height = rand() % 6 + 4;
        room_x = rand() % (map->width - room_width);
        room_y = rand() % (map->height - room_height);
        map_fill_rect(map, room_wall, room_x, room_y, room_width, room_height);
        map_fill_rect(map, tileset[TILE_FLOOR], room_x+1, room_y+1,
                      room_width-2, room_height-2);
    }
}
Esempio n. 2
0
File: game.c Progetto: jdp/psionrl
/* The main game loop */
void play(void) {
	int playing = 1;
	int x, y, vpx, vpy;
	
	/* A messy way to do the map, works for now */
	map_t *map = map_new(50, 50);
	generate_cave(map);
	map_fov_build(map);
	
	/* Set up the offscreen consoles */
	map_layer = TCOD_console_new(ui_viewport_width, ui_viewport_height);
	psion_layer = TCOD_console_new(ui_viewport_width, ui_viewport_height);
	TCOD_console_set_key_color(psion_layer, C_KEY);
	bgcolor(psion_layer, C_KEY);
	
	/* Set up the player */
	init_player();
	rename_player("Gu the Cabeboy");
	blink_player(map);
	
	/* Initialize the inventory */
	
	
	/* Enter the main game loop! */
	while (playing) {
	
		/* Prepare the screen for drawing */
		clear(NULL);
		
		/* Calculate the position of the viewport */
		vpx = player->x - ui_viewport_width/2 > 0 ?
			  player->x - ui_viewport_width/2 : 0;
		vpy = player->y - ui_viewport_height/2 > 0 ?
			  player->y - ui_viewport_height/2 : 0;
		if ((vpx + ui_viewport_width) > map->width) {
			vpx = map->width - ui_viewport_width;
		}
		if ((vpy + ui_viewport_height) > map->height) {
			vpy = map->height - ui_viewport_height;
		}
		if (ui_viewport_width > map->width) {
			vpx = 0;
		}
		if (ui_viewport_height > map->height) {
			vpy = 0;
		}
			
		/* Calculate the field of view */
		map_fov_do(map, player->x, player->y);
		
		/* Only display the part of the map inside the viewport */
		for (y = 0; y < ui_viewport_height; y++) {
			for (x = 0; x < ui_viewport_width; x++) {
				if (((vpy+y) < map->height) && ((vpx+x) < map->width)) {
					tile_t *tile = tile_at(map, vpx+x, vpy+y);
					if (TCOD_map_is_in_fov(map->fov, vpx+x, vpy+y)) {
						fgcolor(map_layer, tile->fg_lit);
					}
					else {
						fgcolor(map_layer, tile->fg_dark);
					}
					putch(map_layer, x, y, tile->glyph);
				}
			}
		}
		
		TCOD_console_blit(map_layer, 0, 0, ui_viewport_width,
		                  ui_viewport_height, NULL, ui_viewport_x,
		                  ui_viewport_y, 255);
		
		/* Draw the player and status */
		fgcolor(NULL, C_WHITE);
		putch(NULL, ui_viewport_x+player->x-vpx, ui_viewport_y+player->y-vpy, '@');
		fgcolor(NULL, C_MSG);
		putstr(NULL, 1, 23, player->name);
		
		/* Redraw the screen */
		update();
		
		/* Handle keypress */
		TCOD_key_t k = getkey();
		if (k.c == 0) {
			switch (k.vk) {
				/* Move around */
				case TCODK_KP7: /* up left */
					attempt_move(map, player->x-1, player->y-1);
					break;
					
				case TCODK_KP8: /* up */
				case TCODK_UP:
					attempt_move(map, player->x, player->y-1);
					break;
					
				case TCODK_KP9: /* up right */
					attempt_move(map, player->x+1, player->y-1);
					break;
					
				case TCODK_KP1: /* down left */
					attempt_move(map, player->x-1, player->y+1);
					break;
				
				case TCODK_KP2: /* down */
				case TCODK_DOWN:
					attempt_move(map, player->x, player->y+1);
					break;
					
				case TCODK_KP3: /* down right */
					attempt_move(map, player->x+1, player->y+1);
					break;
				
				case TCODK_KP4: /* left */
				case TCODK_LEFT:
					attempt_move(map, player->x-1, player->y);
					break;
				
				case TCODK_KP6: /* right */
				case TCODK_RIGHT:
					attempt_move(map, player->x+1, player->y);
					break;
				
				/* View character summary */
				case TCODK_TAB:
					character();
					break;
				
				default:
					printf("%d %d\n", TCODK_TAB, k.vk);
					break;
			}
		}
		else {
			switch (k.c) {
				
				/* Quit the game */
				case 'Q':
					playing = quit();
					break;
				
				/* Open up the inventory */
				case 'i':
					inventory();
					break;
				
				/* View character summary */
				case 'c':
					character();
					break;
					
				/* Use scan ability */
				case 's':
					psion_scan(map);
					break;
				
				default:
					break;
			}
		}
	}
	
	/* Clean up, the game is over */
	map_destroy(map);
}
Esempio n. 3
0
/*!
 * @brief フロアの切り替え処理 / Enter new floor.
 * @return なし
 * @details
 * If the floor is an old saved floor, it will be\n
 * restored from the temporal file.  If the floor is new one, new cave\n
 * will be generated.\n
 */
void change_floor(void)
{
	saved_floor_type *sf_ptr;
	bool loaded = FALSE;

	/* The dungeon is not ready */
	character_dungeon = FALSE;

	/* No longer in the trap detecteded region */
	p_ptr->dtrap = FALSE;

	/* Mega-Hack -- no panel yet */
	panel_row_min = 0;
	panel_row_max = 0;
	panel_col_min = 0;
	panel_col_max = 0;

	/* Mega-Hack -- not ambushed on the wildness? */
	ambush_flag = FALSE;

	/* No saved floors (On the surface etc.) */
	if (!(change_floor_mode & CFM_SAVE_FLOORS) &&
	    !(change_floor_mode & CFM_FIRST_FLOOR))
	{
		/* Create cave */
		generate_cave();

		/* Paranoia -- No new saved floor */
		new_floor_id = 0;
	}

	/* In the dungeon */
	else
	{
		/* No floor_id yet */
		if (!new_floor_id)
		{
			/* Get new id */
			new_floor_id = get_new_floor_id();
		}

		/* Pointer for infomations of new floor */
		sf_ptr = get_sf_ptr(new_floor_id);

		/* Try to restore old floor */
		if (sf_ptr->last_visit)
		{
			/* Old saved floor is exist */
			if (load_floor(sf_ptr, 0))
			{
				loaded = TRUE;

				/* Forbid return stairs */
				if (change_floor_mode & CFM_NO_RETURN)
				{
					cave_type *c_ptr = &cave[p_ptr->y][p_ptr->x];

					if (!feat_uses_special(c_ptr->feat))
					{
						if (change_floor_mode & (CFM_DOWN | CFM_UP))
						{
							/* Reset to floor */
							c_ptr->feat = floor_type[randint0(100)];
						}

						c_ptr->special = 0;
					}
				}
			}
		}

		/*
		 * Set lower/upper_floor_id of new floor when the new
		 * floor is right-above/right-under the current floor.
		 *
		 * Stair creation/Teleport level/Trap door will take
		 * you the same floor when you used it later again.
		 */
		if (p_ptr->floor_id)
		{
			saved_floor_type *cur_sf_ptr = get_sf_ptr(p_ptr->floor_id);

			if (change_floor_mode & CFM_UP)
			{
				/* New floor is right-above */
				if (cur_sf_ptr->upper_floor_id == new_floor_id)
					sf_ptr->lower_floor_id = p_ptr->floor_id;
			}
			else if (change_floor_mode & CFM_DOWN)
			{
				/* New floor is right-under */
				if (cur_sf_ptr->lower_floor_id == new_floor_id)
					sf_ptr->upper_floor_id = p_ptr->floor_id;
			}
		}

		/* Break connection to killed floor */
		else
		{
			if (change_floor_mode & CFM_UP)
				sf_ptr->lower_floor_id = 0;
			else if (change_floor_mode & CFM_DOWN)
				sf_ptr->upper_floor_id = 0;
		}

		/* Maintain monsters and artifacts */
		if (loaded)
		{
			IDX i;
			s32b tmp_last_visit = sf_ptr->last_visit;
			s32b absence_ticks;
			int alloc_chance = d_info[dungeon_type].max_m_alloc_chance;
			int alloc_times;

			while (tmp_last_visit > turn) tmp_last_visit -= TURNS_PER_TICK * TOWN_DAWN;
			absence_ticks = (turn - tmp_last_visit) / TURNS_PER_TICK;

			/* Maintain monsters */
			for (i = 1; i < m_max; i++)
			{
				monster_race *r_ptr;
				monster_type *m_ptr = &m_list[i];

				/* Skip dead monsters */
				if (!m_ptr->r_idx) continue;

				if (!is_pet(m_ptr))
				{
					/* Restore HP */
					m_ptr->hp = m_ptr->maxhp = m_ptr->max_maxhp;

					/* Remove timed status (except MTIMED_CSLEEP) */
					(void)set_monster_fast(i, 0);
					(void)set_monster_slow(i, 0);
					(void)set_monster_stunned(i, 0);
					(void)set_monster_confused(i, 0);
					(void)set_monster_monfear(i, 0);
					(void)set_monster_invulner(i, 0, FALSE);
				}

				/* Extract real monster race */
				r_ptr = real_r_ptr(m_ptr);

				/* Ignore non-unique */
				if (!(r_ptr->flags1 & RF1_UNIQUE) &&
				    !(r_ptr->flags7 & RF7_NAZGUL)) continue;

				/* Appear at a different floor? */
				if (r_ptr->floor_id != new_floor_id)
				{
					/* Disapper from here */
					delete_monster_idx(i);
				}
			}

			/* Maintain artifatcs */
			for (i = 1; i < o_max; i++)
			{
				object_type *o_ptr = &o_list[i];

				/* Skip dead objects */
				if (!o_ptr->k_idx) continue;

				/* Ignore non-artifact */
				if (!object_is_fixed_artifact(o_ptr)) continue;

				/* Appear at a different floor? */
				if (a_info[o_ptr->name1].floor_id != new_floor_id)
				{
					/* Disappear from here */
					delete_object_idx(i);
				}
				else
				{
					/* Cancel preserve */
					a_info[o_ptr->name1].cur_num = 1;
				}
			}

			(void)place_quest_monsters();

			/* Place some random monsters */
			alloc_times = absence_ticks / alloc_chance;

			if (randint0(alloc_chance) < (absence_ticks % alloc_chance))
				alloc_times++;

			for (i = 0; i < alloc_times; i++)
			{
				/* Make a (group of) new monster */
				(void)alloc_monster(0, 0);
			}

		}

		/* New floor_id or failed to restore */
		else /* if (!loaded) */
		{
			if (sf_ptr->last_visit)
			{
				/* Temporal file is broken? */
#ifdef JP
				msg_print("階段は行き止まりだった。");
#else
				msg_print("The staircases come to a dead end...");
#endif

				/* Create simple dead end */
				build_dead_end();

				/* Break connection */
				if (change_floor_mode & CFM_UP)
				{
					sf_ptr->upper_floor_id = 0;
				}
				else if (change_floor_mode & CFM_DOWN)
				{
					sf_ptr->lower_floor_id = 0;
				}
			}
			else
			{
				/* Newly create cave */
				generate_cave();
			}

			/* Record last visit turn */
			sf_ptr->last_visit = turn;

			/* Set correct dun_level value */
			sf_ptr->dun_level = dun_level;

			/* Create connected stairs */
			if (!(change_floor_mode & CFM_NO_RETURN))
			{
				/* Extract stair position */
				cave_type *c_ptr = &cave[p_ptr->y][p_ptr->x];

				/*** Create connected stairs ***/

				/* No stairs down from Quest */
				if ((change_floor_mode & CFM_UP) && !quest_number(dun_level))
				{
					c_ptr->feat = (change_floor_mode & CFM_SHAFT) ? feat_state(feat_down_stair, FF_SHAFT) : feat_down_stair;
				}

				/* No stairs up when ironman_downward */
				else if ((change_floor_mode & CFM_DOWN) && !ironman_downward)
				{
					c_ptr->feat = (change_floor_mode & CFM_SHAFT) ? feat_state(feat_up_stair, FF_SHAFT) : feat_up_stair;
				}

				/* Paranoia -- Clear mimic */
				c_ptr->mimic = 0;

				/* Connect to previous floor */
				c_ptr->special = p_ptr->floor_id;
			}
		}

		/* Arrive at random grid */
		if (change_floor_mode & (CFM_RAND_PLACE))
		{
			(void)new_player_spot();
		}

		/* You see stairs blocked */
		else if ((change_floor_mode & CFM_NO_RETURN) &&
			 (change_floor_mode & (CFM_DOWN | CFM_UP)))
		{
			if (!p_ptr->blind)
			{
#ifdef JP
				msg_print("突然階段が塞がれてしまった。");
#else
				msg_print("Suddenly the stairs is blocked!");
#endif
			}
			else
			{
#ifdef JP
				msg_print("ゴトゴトと何か音がした。");
#else
				msg_print("You hear some noises.");
#endif
			}
		}

		/*
		 * Update visit mark
		 *
		 * The "turn" is not always different number because
		 * the level teleport doesn't take any turn.  Use
		 * visit mark instead of last visit turn to find the
		 * oldest saved floor.
		 */
		sf_ptr->visit_mark = latest_visit_mark++;
	}

	/* Place preserved pet monsters */
	place_pet();

	/* Reset travel target place */
	forget_travel_flow();

	/* Hack -- maintain unique and artifacts */
	update_unique_artifact(new_floor_id);

	/* Now the player is in new floor */
	p_ptr->floor_id = new_floor_id;

	/* The dungeon is ready */
	character_dungeon = TRUE;

	/* Hack -- Munchkin characters always get whole map */
	if (p_ptr->pseikaku == SEIKAKU_MUNCHKIN)
		wiz_lite((bool)(p_ptr->pclass == CLASS_NINJA));

	/* Remember when this level was "created" */
	old_turn = turn;

	/* No dungeon feeling yet */
	p_ptr->feeling_turn = old_turn;
	p_ptr->feeling = 0;

	/* Clear all flags */
	change_floor_mode = 0L;

	select_floor_music();
}
Esempio n. 4
0
/*
 * This is the entry point for generation statistics.
 */
static void stats_collect_level(void)
{
	static bool first = TRUE;
	size_t i, x, y;

	memset(o_count, 0, sizeof(o_count));
	memset(gold_count, 0, sizeof(gold_count));

	mon_gold = 0.0;
	mon_drop = 0.0;

	results_reset();
	result_add("level", format("%d", p_ptr->depth));


	for (i = 0; i < TRIES; i++)
	{
		generate_cave();

		/* Get stats on objects */
		for (y = 1; y < DUNGEON_HGT - 1; y++)
		{
			for (x = 1; x < DUNGEON_WID - 1; x++)
			{
				const object_type *obj = get_first_object(y, x);

				if (obj) do
				{
					if (obj->tval == TV_GOLD) gold_count[i] += obj->pval;
					else o_count[i]++;
				}
				while ((obj = get_next_object(obj)));
			}
		}

		/* Get stats on monsters */
		for (y = 1; y < DUNGEON_HGT - 1; y++)
		{
			for (x = 1; x < DUNGEON_WID - 1; x++)
			{
				if (cave_m_idx[y][x])
					stats_monster(&mon_list[cave_m_idx[y][x]]);
			}
		}
	}

	stats_print_o();
	stats_print_m();

	if (first)
	{
		/* printf("level,mon-drops"); */
		results_print_csv_titles();
		first = FALSE;
	}

	/* results_print_csv_pair("level", "mon-drops"); */
	results_print_csv();

	do_cmd_redraw();
}