Exemplo n.º 1
0
Arquivo: event.c Projeto: Zoxc/gltron
int crashTestPlayers(int i, const segment2 *movement) {
	int j, k;
	int crash = 0;
	Data *data = game->player[i].data;
	segment2 *current = data->trails + data->trailOffset;
	// debug: only test player0 against himself
	// j = 0; 
	// if(i == 0) { 
	for(j = 0; j < game->players; j++) {
		int crash = 0;

		if(game->player[j].data->trail_height < TRAIL_HEIGHT)
			continue;

		for(k = 0; k < game->player[j].data->trailOffset + 1; k++) {
			segment2 *wall;
			vec2 v;
			float t1, t2;
						
			if(j == i && k >= game->player[j].data->trailOffset - 1)
				break;

			wall = game->player[j].data->trails + k;
						
			if(segment2_Intersect(&v, &t1, &t2, movement, wall)) {
#if 0
				printf("(%.2f, %.2f), (%.2f, %.2f), %.2f, %.2f\n",
							 data->posx, data->posy,
							 v.v[0], v.v[1],
							 t1, t2); 
#endif
				if(t1 >= 0 && t1 <= 1 && t2 >= 0 && t2 <= 1) {
					current->vDirection.v[0] = v.v[0] - current->vStart.v[0];
					current->vDirection.v[1] = v.v[1] - current->vStart.v[1];
					createEvent(i, EVENT_CRASH);
					crash = 1;
					break;
				}
			}
		}
		if(crash)
			break;
	}
	return crash;
}
Exemplo n.º 2
0
Arquivo: event.c Projeto: Zoxc/gltron
int crashTestWalls(int i, const segment2 *movement) {
	int j;
	vec2 v;
	float t1, t2;
	int crash = 0;

	Data *data = game->player[i].data;
	segment2 *current = data->trails + data->trailOffset;
	
	for(j = 0; j < 4; j++) {
		if(segment2_Intersect(&v, &t1, &t2, current, walls + j)) {
			if(t1 >= 0 && t1 < 1 && t2 >= 0 && t2 < 1) {
				current->vDirection.v[0] = v.v[0] - current->vStart.v[0];
				current->vDirection.v[1] = v.v[1] - current->vStart.v[1];
				createEvent(i, EVENT_CRASH);
				crash = 1;
				break;
			}
		}
	}
	return crash;
}
Exemplo n.º 3
0
Arquivo: event.c Projeto: Zoxc/gltron
int applyWallAcceleration(int player, int dt) {
	// find distance to enemy walls left & right
	enum { eLeft, eRight, eMax };
	segment2 segments[eMax];

	Data *data = game->player[player].data;
	int dirLeft = (data->dir + 3) % 4;
	int dirRight = (data->dir + 1) % 4;

	float left, right;

	float x, y;
	vec2 vPos;

	int i, j;

	getPositionFromIndex(&x, &y, player);
	vPos.v[0] = x;
	vPos.v[1] = y;

	for(i = 0; i < eMax; i++) {
		vec2Copy(&segments[i].vStart, &vPos);
	}

	segments[eLeft].vDirection.v[0] = dirsX[dirLeft];
	segments[eLeft].vDirection.v[1] = dirsY[dirLeft];
	segments[eRight].vDirection.v[0] = dirsX[dirRight];
	segments[eRight].vDirection.v[1] = dirsY[dirRight];

	left = FLT_MAX;
	right = FLT_MAX;

	for(i = 0; i < game->players; i++) {
		segment2 *wall = game->player[i].data->trails;

		if(i == player)
			continue;
		if(game->player[i].data->trail_height < TRAIL_HEIGHT)
			continue;
		
		for(j = 0; j < game->player[i].data->trailOffset + 1; j++) {
			float t1, t2;
			vec2 v;
			if(segment2_Intersect(&v, &t1, &t2, segments + eLeft, wall) &&
				 t1 > 0 && t1 < left && t2 >= 0 && t2 <= 1)
				left = t1;
			if(segment2_Intersect(&v, &t1, &t2, segments + eRight, wall) &&
				 t1 > 0 && t1 < right && t2 >= 0 && t2 <= 1)
				right = t1;
			wall++;
		}
	}

	{
		float accell_limit = getSettingf("wall_accel_limit");
		if(left < accell_limit || right < accell_limit) {
			float boost = getSettingf("wall_accel_use") * dt / 1000.0f;
			data->speed += boost;
			return 1;
		} else {
			return 0;
		}
	}
}
void ai_getDistances(int player, AI_Distances *distances) {
	enum { eFront = 0, eLeft, eRight, eBackleft, eMax };
	segment2 segments[eMax];
	vec2 v, vPos;
	Data *data = game->player[player].data;
	int dirLeft = (data->dir + 3) % 4;
	int dirRight = (data->dir + 1) % 4;
	int i, j;
	float *front = &distances->front;
	float *right = &distances->right;
	float *left = &distances->left;
	float *backleft = &distances->backleft;

	getPositionFromIndex(vPos.v + 0, vPos.v + 1, player);

	for(i = 0; i < eMax; i++) {
		vec2_Copy(&segments[i].vStart, &vPos);
	}

	segments[eFront].vDirection.v[0] = (float) dirsX[data->dir];
	segments[eFront].vDirection.v[1] = (float) dirsY[data->dir];
	segments[eLeft].vDirection.v[0] = (float) dirsX[dirLeft];
	segments[eLeft].vDirection.v[1] = (float) dirsY[dirLeft];
	segments[eRight].vDirection.v[0] = (float) dirsX[dirRight];
	segments[eRight].vDirection.v[1] = (float) dirsY[dirRight];
	segments[eBackleft].vDirection.v[0] = (float) dirsX[dirLeft] - dirsX[data->dir];
	segments[eBackleft].vDirection.v[1] = (float) dirsY[dirLeft] - dirsY[data->dir];
	vec2_Normalize(&segments[eBackleft].vDirection,
								&segments[eBackleft].vDirection);
	*front = FLT_MAX;
	*left = FLT_MAX;
	*right = FLT_MAX;
	*backleft = FLT_MAX;

	// loop over all segment
	for(i = 0; i < game->players; i++) {
		segment2 *wall = game->player[i].data->trails;
		if(game->player[i].data->trail_height < TRAIL_HEIGHT)
			continue;

		for(j = 0; j < game->player[i].data->trailOffset + 1; j++) {
			float t1, t2;
			if(i == player && j == game->player[i].data->trailOffset)
				break;
			if(segment2_Intersect(&v, &t1, &t2, segments + eFront, wall) &&
				 t1 > 0 && t1 < *front && t2 >= 0 && t2 <= 1)
				*front = t1;
			if(segment2_Intersect(&v, &t1, &t2, segments + eLeft, wall) &&
				 t1 > 0 && t1 < *left && t2 >= 0 && t2 <= 1)
				*left = t1;
			if(segment2_Intersect(&v, &t1, &t2, segments + eRight, wall) &&
				 t1 > 0 && t1 < *right && t2 >= 0 && t2 <= 1)
				*right = t1;
			if(segment2_Intersect(&v, &t1, &t2, segments + eBackleft, wall) &&
				 t1 > 0 && t1 < *backleft && t2 >= 0 && t2 <= 1)
				*backleft = t1;
			wall++;
		}
	}
	for(i = 0; i < game2->level->nBoundaries; i++) {
		float t1, t2;
		segment2* wall = game2->level->boundaries + i;
		if(segment2_Intersect(&v, &t1, &t2, segments + eFront, wall) &&
			 t1 > 0 && t1 < *front && t2 >= 0 && t2 <= 1)
			*front = t1;
		if(segment2_Intersect(&v, &t1, &t2, segments + eLeft, wall) &&
			 t1 > 0 && t1 < *left && t2 >= 0 && t2 <= 1)
			*left = t1;
		if(segment2_Intersect(&v, &t1, &t2, segments + eRight, wall) &&
			 t1 > 0 && t1 < *right && t2 >= 0 && t2 <= 1)
			*right = t1;
		if(segment2_Intersect(&v, &t1, &t2, segments + eBackleft, wall) &&
			 t1 > 0 && t1 < *backleft && t2 >= 0 && t2 <= 1)
			*backleft = t1;
	}
	
	// update debug render segments
	{
		AI *ai = game->player[player].ai;
		vec2_Copy(&ai->front.vStart, &vPos);
		vec2_Copy(&ai->left.vStart, &vPos);
		vec2_Copy(&ai->right.vStart, &vPos);
		vec2_Copy(&ai->backleft.vStart, &vPos);
		
		ai->front.vDirection.v[0] = *front * dirsX[data->dir];
		ai->front.vDirection.v[1] = *front * dirsY[data->dir];
		ai->left.vDirection.v[0] = *left * dirsX[dirLeft];
		ai->left.vDirection.v[1] = *left * dirsY[dirLeft];
		ai->right.vDirection.v[0] = *right * dirsX[dirRight];
		ai->right.vDirection.v[1] = *right * dirsY[dirRight];
		ai->backleft.vDirection.v[0] = (float) (dirsX[dirLeft] - dirsX[data->dir]);
		ai->backleft.vDirection.v[1] = (float) (dirsY[dirLeft] - dirsY[data->dir]);
		vec2_Normalize(&ai->backleft.vDirection,
									&ai->backleft.vDirection);
		vec2_Scale(&ai->backleft.vDirection, 
							&ai->backleft.vDirection,
							*backleft);
	}
		
	// printf("%.2f, %.2f, %.2f\n", *front, *right, *left);
	return;
}
void ai_getConfig(int player, int target,
										AI_Configuration *config) {

	Data *data;
	
	getPositionFromIndex(config->player.vStart.v + 0,
											 config->player.vStart.v + 1,
											 player);
	getPositionFromIndex(config->opponent.vStart.v + 0,
											 config->opponent.vStart.v + 1,
											 target);
	
	data = game->player[player].data;
	config->player.vDirection.v[0] = dirsX[ data->dir ] * data->speed;
	config->player.vDirection.v[1] = dirsY[ data->dir ] * data->speed;

	data = game->player[target].data;
	config->opponent.vDirection.v[0] = dirsX[ data->dir ] * data->speed;
	config->opponent.vDirection.v[1] = dirsY[ data->dir ] * data->speed;
	
	// compute sector
	{
		vec2 diff;
		vec3 v1, v2, v3;
		vec3 up = { { 0, 0, 1 } };
		float cosphi;
		float phi;
		int i;

		vec2_Sub(&diff, &config->player.vStart, &config->opponent.vStart);
		v1.v[0] = diff.v[0];
		v1.v[1] = diff.v[1];
		v1.v[2] = 0;

		v2.v[0] = config->opponent.vDirection.v[0];
		v2.v[1] = config->opponent.vDirection.v[1];
		v2.v[2] = 0;

		vec3_Normalize(&v1, &v1);
		vec3_Normalize(&v2, &v2);

		vec3_Cross(&v3, &v1, &v2);
		vec3_Normalize(&v3, &v3);
	
		cosphi = vec3_Dot(&v1, &v2);
		nebu_Clamp(&cosphi, -1, 1);
		phi = (float) acos(cosphi);
		if(vec3_Dot(&v3, &up) > 0)
			phi = 2 * (float) M_PI - phi;
	
		for(i = 0; i < 8; i++) {
			phi -= (float) M_PI / 4;
			if(phi < 0) {
				config->location = i;
				break;
			}
		}
	}
	// compute intersection
	{
		segment2 seg1;
		segment2 seg2;
		seg1.vStart = config->opponent.vStart;
		seg1.vDirection = config->opponent.vDirection;
		seg2.vStart = config->player.vStart;
		vec2_Orthogonal( &seg2.vDirection, &config->opponent.vDirection );
		vec2_Normalize( &seg2.vDirection, &seg2.vDirection );
		vec2_Scale( &seg2.vDirection, 
							 &seg2.vDirection,
							 vec2_Length( &config->player.vDirection )
							 );
							 
		segment2_Intersect( &config->intersection, 
												&config->t_opponent, &config->t_player,
												&seg1, &seg2 );
		if(config->t_player < 0)
			config->t_player *= -1;
	}
	
}