Exemplo n.º 1
0
// inits ncurses so we can use wclear() and so on
void init_ncurs()
{
	// locale needs to be initialized for ncurses
	// "" sets "native" locale
	// TODO should we force some locale (UTF-8)
	// telnetd gives us "posix" locale
	char *locale = setlocale(LC_ALL, "");
	if (locale == NULL)
	{
		syslog(LOG_WARNING, "setlocale failed, continuing anyways");
	}

	/* ncurses init stuff */
	initscr();
	cbreak();
	noecho();
	keypad(stdscr, TRUE);	/* Function Keys  - problems with some terminals */
	curs_set(0); 		/* 0 = invisible, 1 = normal, 2 = really visible */
	refresh();

	/* checks that terminal size is big enough */
	getmaxyx(stdscr, y_size, x_size);
	if (y_size < 24 || x_size < 80)
	{
		printw("This program needs 80x24 characters of screen 	size to run.\n");
		printw("You currently have: %dx%d\n", x_size, y_size);
		printw("Enlarge your screen and press a key or this program might segfault.\n");
		refresh();
		todd_getchar(NULL);
	}

	/* checks that terminal supports color */

	if (has_colors() == FALSE)
	{
		printw("Your terminal does not seem to support color!\n");
		printw("The game will try to use color whenever possible\n");
		printw("You might experience problems\n");
		printw("Press a key to continue\n");
		refresh();
		todd_getchar(NULL);
	}

	/*
	// OLD CODE FOR COLOR STUFF, NOT USED AT THE MOMENT
	start_color();
	init_pair(1, COLOR_RED, COLOR_BLACK);
	init_pair(2, COLOR_GREEN, COLOR_BLACK);
	init_pair(3, COLOR_BLUE, COLOR_BLACK);
	syntax for color usage:
	attron(COLOR_PAIR(1));
	wprintw(stdscr, "color");
	attroff(COLOR_PAIR(1));
	*/



}
Exemplo n.º 2
0
/* Prints a message to game window
 * Waits user to press a key */
void ncurs_modal_msg(const char *fmt, ...)
{
	/* this function has a getch(). Clear the command window so people won't get frustrated */
	werase(command_win);
	wrefresh(command_win);
	// TODO do we want to clear the window first?
	va_list argp;
	va_start(argp, fmt);
	vwprintw(game_win, fmt, argp);
	va_end(argp);
	wprintw(game_win, "\n\n%s\n", _("Continue..."));
	wrefresh(game_win);
	todd_getchar(NULL);
	set_player_location(player.location); /* after getch, redraw command_win */
}
Exemplo n.º 3
0
/* Prints a list of items to game window
 * returns the index of the item that player chooses
 * or -1 if player cancels or error occures 
 * Parameters:
 * first_item - Pointer to the description of first item
 * stride     - Memory offset between items
 * price_offset - Offset from first_item to integer price
 *                or < 1 if no prices should be printed
 * count      - number of items */
int ncurs_listselect(char **first_item, size_t stride, int price_offset, size_t count)
{
	werase(command_win);
	wrefresh(command_win);

	for (size_t i = 0; i < count; i++)
	{
		// pointer is cast to void and back to calculate the position of next string
		void *base = first_item;
		base += stride*i;
		wprintw(game_win, "%c) %s", i+'a', *(char**)base);
		if (price_offset > 0)
		{
			base += price_offset;
			wprintw(game_win, "\t%d\n", *(int*)base);
		}
		else
		{
			wprintw(game_win, "\n");
		}
	}
	// "Nevermind)
	wprintw(game_win, "x) %s\n", _("Nevermind"));
	wrefresh(game_win);

	unsigned char ch;
	while (true)
	{
		if (!todd_getchar(&ch))
		{
			return -1;
		}

		if (ch == 'x')  
		{
			/* "Nevermind */
			return -1;
		}

		/* only accept numbers between 0 and count */
		if (ch >= 'a' && ch < (char)(('a' + count)&0xFF))
		{
			return ch - 'a';
		}
	}
	return -1; /* control should never reach this point */
}
Exemplo n.º 4
0
int fight_check_dead()
{
	/* TODO: figure out the order of checking deaths: attacks are simultaneous. Iniative? */
	// TODO enemy and player codes are almost identical, refactor into a function
	// bool check_chr_dead(Character *chr); or something

	bool enemy_dead;
	bool enemy_dead_elements;
	// loop through all enemies in combat

	for (int i = 0; i <= 2; i++)
		{
		enemy_dead = false;
		enemy_dead_elements = false;

			if (enemy_party.characters[i]->incombat)
				{
					/* check if enemy dies */
					for (size_t j = 0; j < ELEM_COUNT; j++)
						{
							if (enemy_party.characters[i]->elements[j] <= 0) 
							{
								enemy_dead = true;
								enemy_dead_elements = true;
							}
						}
					if (enemy_party.characters[i]->health <= 0)
						enemy_dead = true;
			
				// the current enemy is dead (characters[i])
				if (enemy_dead)	
					{
						enemy_party.characters[i]->incombat = false;
						// TODO: would it look better to display "DEAD" instead of erasing the box?
						werase(fight_stat_win[3+i]);
						wrefresh(fight_stat_win[3+i]);

						int money = 7;
						player.money += money;
				
						if (enemy_dead_elements)
							ncurs_log_sysmsg(_("%s has caused an elemental imbalance in %s"), player.name, enemy_party.characters[i]->name);
					
						ncurs_log_sysmsg(_("%s has killed %s!"), player.name, enemy_party.characters[i]->name);
						// TODO: share money from a kill someway
						ncurs_log_sysmsg(_("%s found %d coins from the body"), player.name, money);

					// if there's no more enemies left, return to dungeons. 
					int alldead = 1;
 					for (int i = 0; i <= 2; i++)
						if (enemy_party.characters[i]->incombat)
 							alldead = 0;

					// if all enemies are dead, the battle is over
					if (alldead)
						{
						player.incombat = false; // don't return to combat any more
						ncurs_log_sysmsg(_("All enemies are slain! The battle is over"));
						return 1;					
						}
					// If there's enemies left, the battle continues (i.e. do nothing)
					}
				}
			}

	/* check if player dies as well */
	// TODO: loop through all players, not just yourself
	bool player_dead = false;
	bool player_dead_elements = false;
	for (size_t i = 0; i < 5; i++)
	{
		if (player.elements[i] <= 0) {
			player_dead = true;
			player_dead_elements = true;
		}
	}
	if (player.health <= 0)
		player_dead = true;

	if (player_dead)
	{
		wclear (game_win);
		if (player_dead_elements) // elements below 0, don't die but faint only
		{
			db_player_location(LOC_FAINTED);
			// TODO: which enemy..
			ncurs_log_sysmsg(_("%s has caused an elemental imbalance in %s"), enemy_party.characters[0]->name, player.name);
			mvwprintw(game_win, 6, 0, _("The world around you starts to spin.\nYou sense a great imbalance inside you."));

			wattron(game_win, A_BOLD);
			wattron(game_win, A_UNDERLINE);
			mvwprintw(game_win, 8, 0, _("You faint. TODO: \"come back in 8 hours??\""));
			wattroff(game_win, A_BOLD);
			wattroff(game_win, A_UNDERLINE);
		}
		else // PERMADEATH
		{
			/* first, set the player location to "DEAD" */
			db_player_location(LOC_DEAD);
			// TODO: which enemy
			ncurs_log_sysmsg(_("%s has killed %s!"), enemy_party.characters[0]->name, player.name);
			mvwprintw(game_win, 6, 0, _("The world fades around you as you fall to the ground, \nbleeding."));
			wattron(game_win, A_BOLD);
			wattron(game_win, A_UNDERLINE);
			mvwprintw(game_win, 8, 0, _("You are dead."));
			wattroff(game_win, A_BOLD);
			wattroff(game_win, A_UNDERLINE);
		}

		// common stuff to death // elemental imbalance
		wrefresh(game_win);
		todd_getchar(NULL);
		playing = false;
	}

	if (enemy_dead || player_dead)
		return 1; /* if enemy / player is dead, don't redraw combat stuff anymore */
	else
		return 0; // redraw combat stuff
}
Exemplo n.º 5
0
// WINDOW *echowindow points to the window that processes the input
// basically it's input_win during the game and stdscr before the game screen is loaded
bool todd_getline(char **line, size_t *len, WINDOW *echowindow)
{
	// curs_set displays a nice cursor for user convenience
	curs_set(1);
	chat_typing = 1;
	bool ret = false;
	size_t buf_len = 20;
	*line = malloc(buf_len);
	*len = 0;
	unsigned char c;
	do
	{
		bool rc = todd_getchar(&c);
		if (!rc || c == '\t')	
		{
		// pressing TAB (\t) when in input mode is supposed to toggle chat
		//
		// however, pressing TAB when logging in (typing name or password)
		// would cause the program to quit
		// -> don't accept TAB when logging in

		// echowindow == input_win either when 
		//	todd_getline is called with input_win
		// OR   they are both NULL (when logging in)
		//	therefore, those two cases can't be true at the same time
		if (echowindow == input_win && input_win != NULL)
			{		
				free(*line);
				*line = NULL;
				*len = 0;
				goto cleanup;
	
			}
		continue;	// don't accept TAB unless in input_win, just skip it

		}
		if (c == '\b') // it's a backspace, go back a character
		{
			// if echowindow is NULL it means we're asking for the password
			// in this case, make backspace work
			int password = 0;
			if (echowindow == NULL)
				{
				password = 1;
				echowindow = stdscr;
				}

			// don't backspace on an empty string or the pointer will cause a segfault
			if ((*len) != 0) 
			{
				// if it's a multibyte (scandic letters, § and so on)
				// len -1 and len -2 have negative values
				int multibyte = 0;
				if ((*line)[*len - 1] < 0)
					multibyte = 1;

				int y,x;
				// get current position of cursor to y and x
				getyx(echowindow,y,x);
				// move the cursor left by one
				wmove(echowindow, y,x-1);
				// blank it from screen and from buffer
				wechochar(echowindow, ' ');
				(*line)[*len] = '\0';
				(*len)--;
				if (multibyte) // there's two chars in buffer, not one
				{
				(*line)[*len] = '\0';
				(*len)--;
				}

				// by calling wechochar, the cursor moves right. move it back
				wmove(echowindow, y,x-1);
				wrefresh(echowindow);

			// if this was in the password field, change echowindow back to original value
			if (password)
				echowindow = NULL;
			}
		}
		else	// it's just a normal character
		{
			if (buf_len <= *len)
			{
				buf_len += 20;
				*line = realloc(*line, buf_len);
			}

			(*line)[*len] = c;
			(*len)++;
			// echo the character, except when echowindow is NULL echo a * to stdscr
			// this is a hack: echowindow is NULL only when asking for a password
			// also, don't echo a \r
			if (echowindow == NULL && c != '\r')
				wechochar(stdscr, '*');
			else
			if (c != '\r')	// without this, todd_getline would eat the "Halt! who goes there" -message 
					// when asking for player name
				wechochar(echowindow, c);
		}

	} while (c != '\r');

	(*len)--; // strip trailing newline
	(*line)[*len] = '\0'; // insert null terminator

	curs_set(0);

	if (*len == 0) // it's an empty string..
		return false;
	// else, return true
	ret = true;

cleanup:
	if (echowindow == input_win)
		{
		werase(echowindow);
		wrefresh(echowindow);
		}

	chat_typing = 0;
	curs_set(0);

	return ret;
}
Exemplo n.º 6
0
int fight_check_dead()
{
	/* TODO: figure out the order of checking deaths: attacks are simultaneous. Iniative? */
	// TODO enemy and player codes are almost identical, refactor into a function
	// bool check_chr_dead(Character *chr); or something

	/* check if enemy dies */
	bool enemy_dead = false;
	bool enemy_dead_elements = false;
	for (size_t i = 0; i < ELEM_COUNT; i++)
	{
		if (enemy.elements[i] <= 0) {
			enemy_dead = true;
			enemy_dead_elements = true;
		}
	}
	if (enemy.health <= 0)
		enemy_dead = true;
	if (enemy_dead)
	{
		int money = 7;
		int exp = 10;
		player.money += money;
		player.experience += exp;
		werase(game_win);
		if (enemy_dead_elements)
			ncurs_log_sysmsg(_("%s has caused an elemental imbalance in %s"), player.name, enemy.name);
		ncurs_log_sysmsg(_("%s has killed %s!"), player.name, enemy.name);
		ncurs_log_sysmsg(_("%s received %d coins and %d XP"), player.name, money, exp);
		ncurs_modal_msg(
				_("%s is slain!\n\nYou find %d coins on the corpse, and gain %d experience\n"),
				enemy.name, money, exp);
		ac_dungeons();
	}

	/* check if player dies as well */
	bool player_dead = false;
	bool player_dead_elements = false;
	for (size_t i = 0; i < 5; i++)
	{
		if (player.elements[i] <= 0) {
			player_dead = true;
			player_dead_elements = true;
		}
	}
	if (player.health <= 0)
		player_dead = true;

	if (player_dead)
	{
	
		wclear (game_win);

		if (player_dead_elements) // elements below 0, don't die but faint only
		{
			db_player_location(LOC_FAINTED);
			ncurs_log_sysmsg(_("%s has caused an elemental imbalance in %s"), enemy.name, player.name);
			mvwprintw(game_win, 6, 0, _("The world around you starts to spin.\nYou sense a great imbalance inside you."));

			wattron(game_win, A_BOLD);
			wattron(game_win, A_UNDERLINE);
			mvwprintw(game_win, 8, 0, _("You faint. TODO: \"come back in 8 hours??\""));
			wattroff(game_win, A_BOLD);
			wattroff(game_win, A_UNDERLINE);
		}
		else // PERMADEATH
		{
			/* first, set the player location to "DEAD" */
			db_player_location(LOC_DEAD);
		
			ncurs_log_sysmsg(_("%s has killed %s!"), enemy.name, player.name);
			mvwprintw(game_win, 6, 0, _("The world fades around you as you fall to the ground, \nbleeding."));
			wattron(game_win, A_BOLD);
			wattron(game_win, A_UNDERLINE);
			mvwprintw(game_win, 8, 0, _("You are dead."));
			wattroff(game_win, A_BOLD);
			wattroff(game_win, A_UNDERLINE);
		}

		// common stuff to death // elemental imbalance
		wrefresh(game_win);
		todd_getchar(NULL);
		playing = false;
	}

	if (enemy_dead || player_dead)
		return 1; /* if enemy / player is dead, don't redraw combat stuff anymore */
	else
		return 0; // redraw combat stuff
}