#include #ifdef MAP_EDITOR2 #include "../map_editor2/global.h" #else #include "global.h" #endif #define HIGHLIGHT_MARKER_LIFESPAN (500) #define NUMBER_OF_HIGHLIGHT_MARKERS (10) typedef struct { short x; short y; int timeleft; int type; int active; } highlight_marker; highlight_marker markers[NUMBER_OF_HIGHLIGHT_MARKERS]; int highlighting_enabled = 1; highlight_marker *get_free_highlight_marker(short x, short y) { int i; //first try to find one that already occupies this tile for(i = 0; i < NUMBER_OF_HIGHLIGHT_MARKERS; i++) { if (markers[i].active && markers[i].x == x && markers[i].y == y) { return &markers[i]; } } //otherwise, find the first free slot for(i = 0; i < NUMBER_OF_HIGHLIGHT_MARKERS; i++) { if (!markers[i].active) { return &markers[i]; } } return NULL; } void add_highlight(short x, short y, int type) { highlight_marker *m = get_free_highlight_marker(x, y); if (m == NULL) return; m->x = x; m->y = y; m->type = type; m->timeleft = HIGHLIGHT_MARKER_LIFESPAN; m->active = 1; } float get_tile_height(short x, short y) { if (x < 0 || x >= tile_map_size_x * 6) return 0; if (y < 0 || y >= tile_map_size_x * 6) return 0; return height_map[y * tile_map_size_x * 6 + x]; } float get_tile_display_height(short x, short y) { int i = 0; float f = get_tile_height(x, y); float f2; if (f == 0) { //if the tile is non-walkable, we get the average height from the // surrounding tiles. f += f2 = get_tile_height(x - 1, y - 1); if (f2 != 0) i++; f += f2 = get_tile_height(x , y - 1); if (f2 != 0) i++; f += f2 = get_tile_height(x + 1, y - 1); if (f2 != 0) i++; f += f2 = get_tile_height(x - 1, y ); if (f2 != 0) i++; f += f2 = get_tile_height(x + 1, y - 1); if (f2 != 0) i++; f += f2 = get_tile_height(x - 1, y + 1); if (f2 != 0) i++; f += f2 = get_tile_height(x , y + 1); if (f2 != 0) i++; f += f2 = get_tile_height(x - 1, y + 1); if (f2 != 0) i++; f /= i; } return -2.2f+f*0.2f; } void display_highlight_marker(const highlight_marker *marker) { // (a) varies from 1..0 depending on the age of this marker const float a = ((float)marker->timeleft) / HIGHLIGHT_MARKER_LIFESPAN; float z = get_tile_display_height(marker->x, marker->y); float x = (float)marker->x/2; float y = (float)marker->y/2; /* The highlighting marker is four polygons like the one below rotated with C as center. A---B---+ | | | D---+---+ | | | +---+---C (polygon is A->B->C->D->A) where C is supposed to be the center of the highlighted tile (offset by center_offset_x, center_offset_y though). Distance A->B is (dx), distance A->D is (dy) */ const float dx = (TILESIZE_X / 6); const float dy = (TILESIZE_Y / 6); //Move the offset of the C point closer to the actual center of the tile depending // on how "old" this marker is. We want the highlighting marker to shrink close to // the center as the marker gets older, and we also want the shrinking to be faster // when the marker is large, and slower as it gets to the center, hence the (a*a) // instead of just (a). const float center_offset_x = ((TILESIZE_X / 2) * (a*a)); const float center_offset_y = ((TILESIZE_X / 2) * (a*a)); //we want the marker to start a bit above ground and move itself closer to the // ground as it gets older. z += a*0.3f; // place x,y in the center of the highlighting tile x += (TILESIZE_X / 2); y += (TILESIZE_Y / 2); switch (marker->type) { case HIGHLIGHT_TYPE_WALKING_DESTINATION: glColor4f(0.0f, 1.0f, 0.0f, a); break; } glBegin(GL_POLYGON); glVertex3f(x - 2*dx - center_offset_x, y - 2*dy - center_offset_y, z); glVertex3f(x - 1*dx - center_offset_x, y - 2*dy - center_offset_y, z); glVertex3f(x - 0*dx - center_offset_x, y - 0*dy - center_offset_y, z); glVertex3f(x - 2*dx - center_offset_x, y - 1*dy - center_offset_y, z); glVertex3f(x - 2*dx - center_offset_x, y - 2*dy - center_offset_y, z); glEnd(); glBegin(GL_POLYGON); glVertex3f(x + 2*dx + center_offset_x, y - 2*dy - center_offset_y, z); glVertex3f(x + 1*dx + center_offset_x, y - 2*dy - center_offset_y, z); glVertex3f(x + 0*dx + center_offset_x, y - 0*dy - center_offset_y, z); glVertex3f(x + 2*dx + center_offset_x, y - 1*dy - center_offset_y, z); glVertex3f(x + 2*dx + center_offset_x, y - 2*dy - center_offset_y, z); glEnd(); glBegin(GL_POLYGON); glVertex3f(x + 2*dx + center_offset_x, y + 2*dy + center_offset_y, z); glVertex3f(x + 1*dx + center_offset_x, y + 2*dy + center_offset_y, z); glVertex3f(x + 0*dx + center_offset_x, y + 0*dy + center_offset_y, z); glVertex3f(x + 2*dx + center_offset_x, y + 1*dy + center_offset_y, z); glVertex3f(x + 2*dx + center_offset_x, y + 2*dy + center_offset_y, z); glEnd(); glBegin(GL_POLYGON); glVertex3f(x - 2*dx - center_offset_x, y + 2*dy + center_offset_y, z); glVertex3f(x - 1*dx - center_offset_x, y + 2*dy + center_offset_y, z); glVertex3f(x - 0*dx - center_offset_x, y + 0*dy + center_offset_y, z); glVertex3f(x - 2*dx - center_offset_x, y + 1*dy + center_offset_y, z); glVertex3f(x - 2*dx - center_offset_x, y + 2*dy + center_offset_y, z); glEnd(); } void display_highlight_markers() { int i; if (!highlighting_enabled) return; glDisable(GL_TEXTURE_2D); glDisable(GL_LIGHTING); glEnable(GL_BLEND); glBlendFunc(GL_SRC_ALPHA, GL_ONE); glEnable(GL_ALPHA_TEST); for(i = 0; i < NUMBER_OF_HIGHLIGHT_MARKERS; i++) { if (markers[i].active) { markers[i].timeleft -= (cur_time - last_time); if (markers[i].timeleft > 0) { display_highlight_marker(&markers[i]); } else { // This marker has lived long enough now. markers[i].active = 0; } } } glDisable(GL_ALPHA_TEST); glEnable(GL_LIGHTING); glDisable(GL_BLEND); #ifdef OPENGL_TRACE CHECK_GL_ERRORS(); #endif //OPENGL_TRACE }