Example #1
0
void Messages::add_msg_string(const std::string &s, game_message_type type)
{
    if (s.length() == 0) {
        return;
    }
    if (!player_messages.messages.empty() &&
        int(player_messages.messages.back().turn) + 3 >= int(calendar::turn) &&
        s == player_messages.messages.back().message) {
        player_messages.messages.back().count++;
        player_messages.messages.back().turn = calendar::turn;
        player_messages.messages.back().type = type;
        return;
    }

    while( size() >= 256 ) {
        player_messages.messages.erase(player_messages.messages.begin());
    }

    player_messages.messages.push_back(game_message(calendar::turn, s, type));
}
Example #2
0
File: map.c Project: ralight/ggz
int map_save(combat_game * map)
{
	unsigned int hash;
	char filename[128];
	char options[20];
	char *map_data;
	int handle, a;
	hash = _generate_hash((char*)combat_options_string_write(map, 1));
	snprintf(filename, sizeof(filename), "%s/%s.%u", GLOBAL_MAPS, map->name, hash);
	handle = ggz_conf_parse(filename, GGZ_CONF_RDWR | GGZ_CONF_CREATE);
	if (handle < 0) {
		snprintf(filename, sizeof(filename), "%s/.ggz/combat/maps/%s.%u",
			getenv("HOME"), map->name, hash);
		handle =
		    ggz_conf_parse(filename,
				   GGZ_CONF_RDWR | GGZ_CONF_CREATE);
		if (handle < 0) {
			snprintf(filename, sizeof(filename), "%s/.ggz", getenv("HOME"));
			mkdir(filename, S_IRWXU | S_IRGRP | S_IXGRP);

			snprintf(filename, sizeof(filename), "%s/.ggz/combat",
				getenv("HOME"));
			mkdir(filename, S_IRWXU | S_IRGRP | S_IXGRP);

			snprintf(filename, sizeof(filename), "%s/.ggz/combat/maps",
				getenv("HOME"));
			mkdir(filename, S_IRWXU | S_IRGRP | S_IXGRP);

			snprintf(filename, sizeof(filename), "%s/.ggz/combat/maps/%s.%u",
				getenv("HOME"), map->name, hash);
			handle =
			    ggz_conf_parse(filename,
					   GGZ_CONF_RDWR |
					   GGZ_CONF_CREATE);
			if (handle < 0) {
				// Give up
				game_message
				    ("I couldn't write the map to disk");
				return -1;
			}
		}
	}
	// Width/height
	ggz_conf_write_int(handle, "map", "width", map->width);
	ggz_conf_write_int(handle, "map", "height", map->height);
	// Army data
	for (a = 0; a < 12; a++)
		ggz_conf_write_int(handle, "army", file_unit_name[a],
				   map->army[map->number][a]);
	// Map data
	map_data = (char *)ggz_malloc(map->width * map->height + 1);
	for (a = 0; a < map->width * map->height; a++) {
		if (GET_OWNER(map->map[a].type) >= 0) {
			// Intial position!
			map_data[a] = GET_OWNER(map->map[a].type) + 49;
		} else {
			// Get's terrain
			switch (LAST(map->map[a].type)) {
			case T_OPEN:
				map_data[a] = 'O';
				break;
			case T_NULL:
				map_data[a] = 'N';
				break;
			case T_LAKE:
				map_data[a] = 'L';
				break;
			}
		}
	}
	map_data[map->width * map->height] = 0;
	ggz_conf_write_string(handle, "map", "data", map_data);
	// Options
	snprintf(options, sizeof(filename), "%lX", map->options);
	ggz_conf_write_string(handle, "options", "bin1", options);
	ggz_conf_commit(handle);
	return 0;
}
Example #3
0
/*Fonction jeu
*Gere le jeu en lui-meme
*Deplacement des monstres en fonctions du temps
*Deplacement du joueur et traitement de son deplacement
*/
void jeu(t_case matrice[N][M], int level){
	//declaration ncurses
	int nb_col, col, row;
	int ch = 0;
	getmaxyx(stdscr,row,col); /* get the number of rows and columns */
	nb_col= col/2;
	//declaration
	int dx, dy;
	int i,j;
	t_coord pos_sortie;
	t_coord perso_position;
	int niveau_termine=0;

	//position de la sortie à 3cases du coffre mais invisible
	for(i=0;i<N;i++){
		for(j=0;j<M;j++){
			if(matrice[i][j]==coffre){
				pos_sortie.x=i;
				pos_sortie.y=j-3;
			}
		}
	}

	//traitement
	if(level>=1){
		sauvegarde_map(matrice,level);
		//tant que la vie > 0 et niveau en cours et qu'on appuye pas sur echap
		while(valeur_PV_personnage()>0 && niveau_termine==0 && ch != 27){ 
			//Deplacment des monstres en fonction du temps
			while (!kbhit() && valeur_PV_personnage()>0 ){//tant que l'on n'appuie sur aucune touche, kbhit fais boucler
				//si personnage meurt, 3 coups pour se sauver car les monstres sont inactifs
				if(valeur_invi_personnage()==0)
					generation_mob_suivante(matrice,perso_position);

				else{
					if(valeur_invi_personnage()<=3) modif_invi_personnage(valeur_invi_personnage()+1);						
					else modif_invi_personnage(0);
				}
				//affichage du jeu avec uen temporisation de 1,5s, avec la touche p pour mettre le jeu en pause
				afficher_ecran(matrice,level);
				usleep(150000);
				while(ch == 'p') ch = getch();
			}
			//choix de deplacement (deplacement possible avec les touches zqsd, ZQSD ou les fleches directives)
			ch = getch();
			switch(ch){
				
				case 'z':
				case 'Z':
				case KEY_UP:
					dx=-1;
					dy=0;
					break;
				
				case 'q':
				case 'Q':
				case KEY_LEFT:
					dx=0;
					dy=-1;
					break;
				
				case 's':
				case 'S':
				case KEY_DOWN:
					dx=1;
					dy=0;
					break;
				
				case 'd':
				case 'D':
				case KEY_RIGHT:
					dx=0;
					dy=1;
					break;
				
				default:
					dx=0;
					dy=0;
					break;
			}
			//si deplacement choisi, traitement de la case
			if(dx != 0 || dy != 0){
				valeur_position_personnage(&perso_position);

				if(matrice[perso_position.x+dx][perso_position.y+dy]!=mur_contour && matrice[perso_position.x+dx][perso_position.y+dy]!=mur){
					perso_position.x=perso_position.x+dx;
					perso_position.y=perso_position.y+dy;
					//action en fonction de la nouvelle case

					switch(matrice[perso_position.x][perso_position.y]){
						case vide:
							matrice[perso_position.x-dx][perso_position.y-dy]=vide;
							matrice[perso_position.x][perso_position.y]=hero;
							break;
						case couloir:
							matrice[perso_position.x-dx][perso_position.y-dy]=vide;
							matrice[perso_position.x][perso_position.y]=hero;
							break;
						case porte:
							matrice[perso_position.x-dx][perso_position.y-dy]=vide;
							perso_position.x=perso_position.x+dx;
							perso_position.y=perso_position.y+dy;
							matrice[perso_position.x][perso_position.y]=hero;
							break;
						case cle:
							matrice[perso_position.x-dx][perso_position.y-dy]=vide;
							modif_cle_personnage(1);
							mvprintw(41, nb_col-5,"cle prise");
							matrice[perso_position.x][perso_position.y]=hero;
							break;
						case coffre:
							if(valeur_cle_personnage()==0){	//s'il n'a pas la cle
								perso_position.x=perso_position.x-dx; //personnage ne bouge pas
								perso_position.y=perso_position.y-dy;
								mvprintw(41, nb_col-12,"veuillez prendre la cle");
							}
							else{
								matrice[perso_position.x-dx][perso_position.y-dy]=vide;
								mvprintw(42, nb_col-6,"coffre pris");
								matrice[perso_position.x][perso_position.y]=hero;
								//creation piece sortie pour finir le niveau
								matrice[pos_sortie.x][pos_sortie.y]=sortie;
								matrice[pos_sortie.x-2][pos_sortie.y]=porte;
								matrice[pos_sortie.x-2][pos_sortie.y-1]=mur_contour;
								matrice[pos_sortie.x-2][pos_sortie.y+1]=mur_contour;
								matrice[pos_sortie.x-1][pos_sortie.y]=vide;
								matrice[pos_sortie.x-1][pos_sortie.y-1]=mur_contour;
								matrice[pos_sortie.x-1][pos_sortie.y+1]=mur_contour;
								matrice[pos_sortie.x][pos_sortie.y-1]=mur_contour;
								matrice[pos_sortie.x][pos_sortie.y+1]=mur_contour;
							}
							break;
						case bonus:
							matrice[perso_position.x-dx][perso_position.y-dy]=vide;
							if(rand()%3==0){//une chance sur 3 d'avoir un point d'armure
								gain_armure_personnage(1);
							}
							else{
								gain_bonus_personnage(20); //le bonus vaut 20points
							}
							matrice[perso_position.x][perso_position.y]=hero;
							break;
						case piege:
							degat_personnage();//perd un point de vie
							perso_position.x=perso_position.x-dx; //personnage ne bouge pas
							perso_position.y=perso_position.y-dy;
							break;
						case monstre_agressif:
						case monstre_defensif:
						case monstre_inactif:
							if(position_mob(perso_position)){
								mob_perte_PV(matrice,1);
							}
							perso_position.x=perso_position.x-dx; //personnage ne bouge pas
							perso_position.y=perso_position.y-dy;

							break;
						case sortie:
							niveau_termine=1;
							break;
						default:
							break;
					}
					modif_position_personnage(perso_position);
					afficher_ecran(matrice,level);
				}
			}
		}
		if(niveau_termine==0){
			game_message(matrice,niveau_termine,level); //defaite
		}
		else{
			level++;
			//generation niveau superieur
			if(level<=5){
				init_etage_personnage();
				generation_level(matrice, level);
				jeu(matrice,level);
			}
			//si niveau 5 termine, victoire
			else game_message(matrice,niveau_termine,level);
		}
	}
}
Example #4
0
void on_show_game_options_activate(void)
{
	if (cbt_game.army && cbt_game.map)
		game_message(combat_options_describe(&cbt_game, 0));
}
Example #5
0
File: game.c Project: ralight/ggz
/* Events:
 * CHESS_EVENT_INIT -> NULL
 * CHESS_EVENT_SEAT -> arg[0] = (char)SEAT
 *                     arg[1] = (char)VERSION
 * CHESS_EVENT_PLAYERS arg[0] = (char)ASSIGN1
 *                     arg[1-17] = (string)NAME1
 *                     arg[20] = (char)ASSIGN2
 *                     arg[21-37] = (string)NAME2
 * CHESS_EVENT_TIME_REQUEST -> NULL
 * CHESS_EVENT_TIME_OPTION -> time option
 * CHESS_EVENT_START -> NULL
 * CHESS_EVENT_MOVE_END -> arg = (str)MOVE
 * CHESS_EVENT_MOVE -> arg = (str)MOVE
 * CHESS_EVENT_GAMEOVER -> arg[0] = (char)OVER_CODE
 * CHESS_EVENT_UPDATE_TIME -> arg[0] = (int)TIME_1
 *                            arg[1] = (int)TIME_2
 *
 */
void game_update(int event, void *arg)
{
	char move[6];
	/*int diff[2]; */
	int retval = 0;
	switch (event) {
	case CHESS_EVENT_INIT:
		if (game_info.state != CHESS_STATE_INIT)
			break;
		game_init();
		game_info.state = CHESS_STATE_WAIT;
		break;
	case CHESS_EVENT_SEAT:
		if (game_info.state != CHESS_STATE_WAIT)
			break;
		/* Update the game info structure */
		game_info.seat = ((char *)arg)[0];
		game_info.version = ((char *)arg)[1];
		if (game_info.version != PROTOCOL_VERSION)
			game_popup
			    ("Incompatible version. The game may not run as expected");
		break;
	case CHESS_EVENT_PLAYERS:
		if (game_info.state != CHESS_STATE_WAIT)
			break;
		/* Update the game info structure */
		game_info.assign[0] = *(char *)arg;
		game_info.assign[1] = *(((char *)arg) + 20);
		if (game_info.assign[0] != GGZ_SEAT_OPEN)
			strcpy(game_info.name[0], (char *)arg + 1);
		if (game_info.assign[1] != GGZ_SEAT_OPEN)
			strcpy(game_info.name[1], (char *)arg + 21);
		board_info_update();
		free(arg);
		break;
	case CHESS_EVENT_TIME_REQUEST:
		if (game_info.state != CHESS_STATE_WAIT)
			break;
		/* FIXME: Should ask the user for the time */
		gtk_widget_show(create_clock_dialog());
		break;
	case CHESS_EVENT_TIME_OPTION:
		if (game_info.state != CHESS_STATE_WAIT)
			break;
		game_info.clock_type = (*((int *)arg)) >> 24;
		game_info.seconds[0] = (*((int *)arg)) & 0xFFFFFF;
		game_info.seconds[1] = (*((int *)arg)) & 0xFFFFFF;
		game_info.t_seconds[0] = (*((int *)arg)) & 0xFFFFFF;
		game_info.t_seconds[1] = (*((int *)arg)) & 0xFFFFFF;
		switch (game_info.clock_type) {
		case CHESS_CLOCK_NOCLOCK:
			game_popup("This game won't have a time limit.");
			break;
		case CHESS_CLOCK_CLIENT:
			game_popup
			    ("This game will use a client clock.\nThis option should only be used when playing against people you trust, as it relies much in the client program, that can be cheated.\nSo, if the time behaves very strangely (like your oponnent time never wearing out), he may be running a cheated client.\n\nEach player will have %d min : %d sec to win the game.",
			     game_info.seconds[0] / 60,
			     game_info.seconds[0] % 60);
			break;
		case CHESS_CLOCK_SERVER:
			game_popup
			    ("This game will use a server clock.\nIt is very difficult to cheat when using this type of clock, and you should use it if you suspect your oponnent may have a cheated client or if you don't trust him.\nHowever, if either your connection or your opponent's is deeply lagged, it will have a deep effect on the time count as well.\n\nEach player will have %d min : %d sec to win the game.",
			     game_info.seconds[0] / 60,
			     game_info.seconds[0] % 60);
			break;
		case CHESS_CLOCK_SERVERLAG:
			game_popup
			    ("This game will use a server clock with lag support.\nIn this option, we will use a server clock, but using a lag meter to compensate for any lag due to Internet connection. Although it's possible to cheat with this option, it is much more difficult then cheating with the client clock.\nBesides, the lag of either connect won't have a so deep effect on the time of the players.\n\nEach player will have %d min : %d sec to win the game.",
			     game_info.seconds[0] / 60,
			     game_info.seconds[0] % 60);
			break;
		default:
			game_popup("Clock type is %d and time is %d",
				   game_info.clock_type,
				   game_info.seconds[0]);
			break;
		}
		board_info_update();
		break;
	case CHESS_EVENT_START:
		if (game_info.state != CHESS_STATE_WAIT)
			break;
		game_info.state = CHESS_STATE_PLAYING;
		if (game_info.clock_type != CHESS_CLOCK_NOCLOCK)
			g_timeout_add(1000, game_timer, NULL);
		game_message("The game has started!");
		break;
	case CHESS_EVENT_MOVE_END:
		if (game_info.state != CHESS_STATE_PLAYING)
			break;
		ggz_debug("main", "Sending move... %s", (char *)arg);
		if (game_info.clock_type != CHESS_CLOCK_CLIENT
		    || game_info.turn == 0)
			/* Client clock is only tracked if we're using that
			 * clock system, and the first turn is never timed. */
			net_send_move(arg, -1);
		else {
			g_source_remove(timeout_id);
			if (game_info.turn == 0 || game_info.turn == 1)
				net_send_move(arg, 0);
			else
				net_send_move(arg,
					      g_timer_elapsed(game_info.
							      timer,
							      NULL));
			g_timer_stop(game_info.timer);
			g_timer_reset(game_info.timer);
		}
		game_message("Sending move to server...");
		break;
	case CHESS_EVENT_MOVE:
		if (game_info.state != CHESS_STATE_PLAYING)
			break;
		if (!arg) {
			game_message("Invalid move!");
			break;
		}
		strncpy(move, arg, 6);
		game_message("Making move %s", move);
		game_info.check = FALSE;
		retval = cgc_make_move(game, move);
		if (retval == CHECK || retval == MATE) {
			if ((game_info.turn % 2 != game_info.seat)) {
				game_info.check = TRUE;
				game_message("You are in check!");
			} else {
				game_message("Your opponent is in check!");
			}
		}
		/* Now update the time, if that's the case */
		if (game_info.clock_type != CHESS_CLOCK_NOCLOCK) {
			game_info.seconds[game_info.turn % 2] -=
			    *((gint32 *) arg + 2);
			/* Ok, adjust the timer clocks */
			game_info.t_seconds[0] = game_info.seconds[0];
			game_info.t_seconds[1] = game_info.seconds[1];
		}
		game_info.turn++;
		/* Check if it's my turn now and we have CLIENT_CLOCK */
		if (game_info.clock_type == CHESS_CLOCK_CLIENT
		    && game_info.turn % 2 == game_info.seat) {
			/* Starts the timer ! */
			g_timer_start(game_info.timer);
			/* Starts the timeout for MSG_UPDATE */
			timeout_id =
			    g_timeout_add(15000, game_update_server, NULL);
		}
		board_info_update();
		board_info_add_move(move);
		board_draw();
		break;
	case CHESS_EVENT_UPDATE_TIME:
		game_info.seconds[0] = *((int *)arg);
		game_info.seconds[1] = *((int *)arg + 1);
		game_info.t_seconds[0] = game_info.seconds[0];
		game_info.t_seconds[1] = game_info.seconds[1];
		board_info_update();
		break;
	case CHESS_EVENT_GAMEOVER:
		switch (*(char *)arg) {
		case CHESS_GAMEOVER_DRAW_AGREEMENT:
			game_message
			    ("Game is over! Both players agred on a draw");
			break;
		case CHESS_GAMEOVER_DRAW_STALEMATE:
			game_message("Game is over! We have a stalemate");
			break;
		case CHESS_GAMEOVER_DRAW_POSREP:
			game_message
			    ("Game is over! Too much repetition of positions");
			break;
		case CHESS_GAMEOVER_DRAW_MATERIAL:
			game_message
			    ("Game is over! Neither of the players has material for a mate");
			break;
		case CHESS_GAMEOVER_DRAW_MOVECOUNT:
			game_message
			    ("Game is over! The maximum movecount was reached");
			break;
		case CHESS_GAMEOVER_DRAW_TIMEMATERIAL:
			game_message
			    ("Gams is over! Time is out and the remaining player doesn't have enough material for a mate");
			break;
		case CHESS_GAMEOVER_WIN_1_MATE:
			game_message("Game is over! %s wins by a mate",
				     game_info.name[0]);
			break;
		case CHESS_GAMEOVER_WIN_1_RESIGN:
			game_message
			    ("Game is over! %s wins, %s has resigned",
			     game_info.name[0], game_info.name[1]);
			break;
		case CHESS_GAMEOVER_WIN_1_FLAG:
			game_message
			    ("Game is over! %s wins, %s has run out of time",
			     game_info.name[0], game_info.name[1]);
			break;
		case CHESS_GAMEOVER_WIN_2_MATE:
			game_message("Game is over! %s wins by a mate",
				     game_info.name[1]);
			break;
		case CHESS_GAMEOVER_WIN_2_RESIGN:
			game_message
			    ("Game is over! %s wins, %s has resigned",
			     game_info.name[1], game_info.name[0]);
			break;
		case CHESS_GAMEOVER_WIN_2_FLAG:
			game_message
			    ("Game is over! %s wins, %s has run out of time",
			     game_info.name[1], game_info.name[0]);
			break;
		default:
			game_message
			    ("The game should be over, but I don't know why");
		}
		game_info.state = CHESS_STATE_DONE;
		break;
	case CHESS_EVENT_DRAW:
		gtk_widget_show(create_draw_dialog());
		break;
	default:
		game_message("Unknown event! %d", event);
		break;
	}
}