void player_bump(int dir, int x, int y) { int bump_x = player_entity.x; int bump_y = player_entity.y; switch(dir) { case LEFT: bump_x--; break; case RIGHT: bump_x++; break; case UP: bump_y--; break; case DOWN: bump_y++; break; case UP_LEFT: bump_x--; bump_y--; break; case UP_RIGHT: bump_x++; bump_y--; break; case DOWN_LEFT: bump_x--; bump_y++; break; case DOWN_RIGHT: bump_x++; bump_y++; break; default: break; } u32 meta = map_get_meta(LAYER_MIDDLE, bump_x, bump_y); if(meta & (TILE_ITEM | TILE_WEAPON)) { u16 item = map_get_tile(LAYER_MIDDLE, bump_x, bump_y); map_set_tile(LAYER_MIDDLE, bump_x, bump_y, TILE_NONE); item_select_prompt(bump_x, bump_y, item); } else { iact_set_trigger(IACT_TRIG_BumpTile, 3, bump_x, bump_y, map_get_tile(LAYER_MIDDLE, bump_x, bump_y)); } }
void map_draw(map* p_map, SDL_Renderer* renderer){ int x_from = -(p_map->o_camera.x); int x_to = (p_map->width * p_map->tile_width) + x_from; int y_from = -(p_map->o_camera.y); int y_to = (p_map->height * p_map->tile_height) + y_from; int tile_y_index = 0; for (int y=y_from;y<y_to;y+=p_map->tile_height/2){ int tile_x_index = 0; for (int x=x_from;x<x_to;x+=p_map->tile_width/2){ //get the tile in the map tiles tile* p_tile = map_get_tile(p_map, tile_x_index, tile_y_index); //draw the tile map_draw_tile(p_map, p_tile, x, y, renderer); //increment the tile index and check if it's in the map size rang if(++tile_x_index >= p_map->width)break; } //increment the tile index and check if it's in the map size rang if(++tile_y_index >= p_map->height)break; } #ifdef DEBUG debug_map(p_map, renderer, x_from, x_to, y_from, y_to, p_map->o_camera.x / p_map->tile_width*8, p_map->o_camera.y / p_map->tile_height*8); #endif }
bool player_collides(int dir, int x, int y) { switch(dir) { case LEFT: if(((!(map_get_meta(LAYER_MIDDLE, player_entity.x-1,player_entity.y) & (TILE_MIDDLE_LAYER_COLLIDING | TILE_GAME_OBJECT)) || map_get_tile(LAYER_MIDDLE, player_entity.x-1, player_entity.y) == TILE_NONE)) && player_entity.x != 0) return false; break; case RIGHT: if(((!(map_get_meta(LAYER_MIDDLE,player_entity.x+1, player_entity.y) & (TILE_MIDDLE_LAYER_COLLIDING | TILE_GAME_OBJECT)) || map_get_tile(LAYER_MIDDLE,player_entity.x+1, player_entity.y) == TILE_NONE)) && player_entity.x != map_get_width()-1) return false; break; case UP: if(((!(map_get_meta(LAYER_MIDDLE,player_entity.x, player_entity.y-1) & (TILE_MIDDLE_LAYER_COLLIDING | TILE_GAME_OBJECT)) || map_get_tile(LAYER_MIDDLE,player_entity.x, player_entity.y-1) == TILE_NONE)) ) return false; break; case DOWN: if(((!(map_get_meta(LAYER_MIDDLE,player_entity.x, player_entity.y+1) & (TILE_MIDDLE_LAYER_COLLIDING | TILE_GAME_OBJECT)) || map_get_tile(LAYER_MIDDLE,player_entity.x, player_entity.y+1) == TILE_NONE)) && player_entity.y != map_get_height()-1) return false; break; case UP_LEFT: if(((!(map_get_meta(LAYER_MIDDLE, player_entity.x-1,player_entity.y-1) & (TILE_MIDDLE_LAYER_COLLIDING | TILE_GAME_OBJECT)) || map_get_tile(LAYER_MIDDLE, player_entity.x-1, player_entity.y-1) == TILE_NONE)) && (player_entity.x != 0 && player_entity.y != 0)) return false; break; case UP_RIGHT: if(((!(map_get_meta(LAYER_MIDDLE,player_entity.x+1, player_entity.y-1) & (TILE_MIDDLE_LAYER_COLLIDING | TILE_GAME_OBJECT)) || map_get_tile(LAYER_MIDDLE,player_entity.x+1, player_entity.y-1) == TILE_NONE)) && (player_entity.x != map_get_width()-1 && player_entity.y != 0)) return false; break; case DOWN_LEFT: if(((!(map_get_meta(LAYER_MIDDLE, player_entity.x-1,player_entity.y+1) & (TILE_MIDDLE_LAYER_COLLIDING | TILE_GAME_OBJECT)) || map_get_tile(LAYER_MIDDLE, player_entity.x-1, player_entity.y+1) == TILE_NONE)) && (player_entity.x != 0&& player_entity.y != map_get_height()-1)) return false; break; case DOWN_RIGHT: if(((!(map_get_meta(LAYER_MIDDLE,player_entity.x+1, player_entity.y+1) & (TILE_MIDDLE_LAYER_COLLIDING | TILE_GAME_OBJECT)) || map_get_tile(LAYER_MIDDLE,player_entity.x+1, player_entity.y+1) == TILE_NONE)) && (player_entity.x != map_get_width()-1 && player_entity.y != map_get_height()-1)) return false; break; } return true; }
/**************************************************************** ... *****************************************************************/ void city_dialog_update_present_units(struct city_dialog *pdialog, int unitid) { int i; struct genlist_iterator myiter; struct unit *punit; if(unitid) { for(i=0; i<NO_UNITS_SHOWN; i++) if(pdialog->present_unit_ids[i]==unitid) break; if(i==NO_UNITS_SHOWN) unitid=0; } genlist_iterator_init(&myiter, &map_get_tile(pdialog->pcity->x, pdialog->pcity->y)->units.list, 0); for(i=0; ITERATOR_PTR(myiter); ITERATOR_NEXT(myiter), i++) { punit=(struct unit*)ITERATOR_PTR(myiter); if(unitid && punit->id!=unitid) continue; put_unit_pixmap(punit, XawPixcommPixmap(pdialog->present_unit_pixcomms[i]), 0, 0); put_unit_pixmap_city_overlays(punit, XawPixcommPixmap(pdialog->present_unit_pixcomms[i]), 0,0); xaw_expose_now(pdialog->present_unit_pixcomms[i]); pdialog->present_unit_ids[i]=punit->id; XtRemoveAllCallbacks(pdialog->present_unit_pixcomms[i], XtNcallback); XtAddCallback(pdialog->present_unit_pixcomms[i], XtNcallback, present_units_callback, (XtPointer)punit->id); XtSetSensitive(pdialog->present_unit_pixcomms[i], TRUE); } for(; i<NO_UNITS_SHOWN; i++) { XawPixcommClear(pdialog->present_unit_pixcomms[i]); pdialog->present_unit_ids[i]=0; XtSetSensitive(pdialog->present_unit_pixcomms[i], FALSE); } }
/************************************************************************** ... **************************************************************************/ void handle_tile_info(struct packet_tile_info *packet) { int old_known, old_special; struct tile *ptile=map_get_tile(packet->x, packet->y); old_known=ptile->known; old_special=ptile->special; ptile->terrain=packet->type; ptile->special=packet->special; ptile->known=packet->known; if(client_state==CLIENT_GAME_RUNNING_STATE && packet->known>=TILE_KNOWN) { refresh_tile_mapcanvas(packet->x, packet->y, 1); if(old_known<TILE_KNOWN) { int known; known=tile_is_known(packet->x-1, packet->y); if(known>=TILE_KNOWN && known!=ptile->known) refresh_tile_mapcanvas(packet->x-1, packet->y, 1); known=tile_is_known(packet->x+1, packet->y); if(known>=TILE_KNOWN && known!=ptile->known) refresh_tile_mapcanvas(packet->x+1, packet->y, 1); known=tile_is_known(packet->x, packet->y-1); if(known>=TILE_KNOWN && known!=ptile->known) refresh_tile_mapcanvas(packet->x, packet->y-1, 1); known=tile_is_known(packet->x, packet->y+1); if(known>=TILE_KNOWN && known!=ptile->known) refresh_tile_mapcanvas(packet->x, packet->y+1, 1); } else { /* happens so seldom(new roads etc) so refresh'em all */ refresh_tile_mapcanvas(packet->x-1, packet->y, 1); refresh_tile_mapcanvas(packet->x+1, packet->y, 1); refresh_tile_mapcanvas(packet->x, packet->y-1, 1); refresh_tile_mapcanvas(packet->x, packet->y+1, 1); } } }
/************************************************************************** ... **************************************************************************/ void handle_map_info(struct packet_map_info *pinfo) { int x, y; map.xsize=pinfo->xsize; map.ysize=pinfo->ysize; map.is_earth=pinfo->is_earth; if(!(map.tiles=(struct tile*)malloc(map.xsize*map.ysize* sizeof(struct tile)))) { log(LOG_FATAL, "malloc failed in handle_map_info"); exit(1); } for(y=0; y<map.ysize; y++) for(x=0; x<map.xsize; x++) tile_init(map_get_tile(x, y)); set_overview_dimensions(map.xsize, map.ysize); }
void map_tile_click(map* p_map, int x, int y, Uint8 button){ //offset the map to draw the chipset int x_offset = p_map->p_chipset->width; int y_offset = p_map->p_chipset->height; if(x < x_offset && y < y_offset){ //the click was on the chipset part //set the chipset tile p_map->chipset_tile_x_index = x / p_map->tile_width; p_map->chipset_tile_y_index = y / p_map->tile_height; } else{ //the clic was on the map part //change the clicked tile with the selected tile //iso to cartesian coord SDL_Point iso_cam = cart_to_iso_i(p_map->o_camera.x, p_map->o_camera.y); SDL_Point cart = iso_to_cart_i(x + iso_cam.x, y + iso_cam.y); int clicked_tile_x_index = cart.x / (p_map->tile_width / 2); int clicked_tile_y_index = cart.y / (p_map->tile_height / 2); #ifdef DEBUG printf("click at index %d %d\n", clicked_tile_x_index, clicked_tile_y_index); #endif //check if the index is in the map boundaries if(clicked_tile_x_index >= 0 && clicked_tile_x_index < p_map->width && clicked_tile_y_index >= 0 && clicked_tile_y_index < p_map->height){ tile* p_tile = map_get_tile(p_map, clicked_tile_x_index, clicked_tile_y_index); p_tile->x = p_map->chipset_tile_x_index; p_tile->y = p_map->chipset_tile_y_index; } } }
bool player_do_pull(int dir) { if(BUTTON_PUSH_STATE) { switch(dir) { case LEFT: if((map_get_meta(LAYER_MIDDLE, player_entity.x+1,player_entity.y) & (TILE_PUSH_PULL_BLOCK)) && player_entity.x != 0 && map_get_tile(LAYER_MIDDLE, player_entity.x+1,player_entity.y) != TILE_NONE) { map_set_tile(LAYER_MIDDLE, player_entity.x, player_entity.y, map_get_tile(LAYER_MIDDLE, player_entity.x+1,player_entity.y)); int object_index = 0; while(1) { obj_info *object = map_get_object(object_index++, player_entity.x+1, player_entity.y); if (object == NULL) break; if(!object->visible) continue; if(object->type == OBJ_ITEM || object->type == OBJ_WEAPON) { object->visible = false; map_set_tile(LAYER_MIDDLE, player_entity.x+1, player_entity.y, object->arg); return true; } } map_set_tile(LAYER_MIDDLE, player_entity.x+1, player_entity.y, TILE_NONE); return true; } break; case RIGHT: if((map_get_meta(LAYER_MIDDLE, player_entity.x-1,player_entity.y) & (TILE_PUSH_PULL_BLOCK)) && player_entity.x != map_get_width()-1 && map_get_tile(LAYER_MIDDLE, player_entity.x-1,player_entity.y) != TILE_NONE) { map_set_tile(LAYER_MIDDLE, player_entity.x, player_entity.y, map_get_tile(LAYER_MIDDLE, player_entity.x-1,player_entity.y)); int object_index = 0; while(1) { obj_info *object = map_get_object(object_index++, player_entity.x-1, player_entity.y); if (object == NULL) break; if(!object->visible) continue; if(object->type == OBJ_ITEM || object->type == OBJ_WEAPON) { object->visible = false; map_set_tile(LAYER_MIDDLE, player_entity.x-1, player_entity.y, object->arg); return true; } } map_set_tile(LAYER_MIDDLE, player_entity.x-1, player_entity.y, TILE_NONE); return true; } break; case UP: if((map_get_meta(LAYER_MIDDLE,player_entity.x, player_entity.y+1) & (TILE_PUSH_PULL_BLOCK)) && player_entity.y != 0 && map_get_tile(LAYER_MIDDLE, player_entity.x,player_entity.y+1) != TILE_NONE) { map_set_tile(LAYER_MIDDLE, player_entity.x, player_entity.y, map_get_tile(LAYER_MIDDLE, player_entity.x,player_entity.y+1)); int object_index = 0; while(1) { obj_info *object = map_get_object(object_index++, player_entity.x, player_entity.y+1); if (object == NULL) break; if(!object->visible) continue; if(object->type == OBJ_ITEM || object->type == OBJ_WEAPON) { object->visible = false; map_set_tile(LAYER_MIDDLE, player_entity.x, player_entity.y+1, object->arg); return true; } } map_set_tile(LAYER_MIDDLE, player_entity.x, player_entity.y+1, TILE_NONE); return true; } break; case DOWN: if((map_get_meta(LAYER_MIDDLE,player_entity.x, player_entity.y-1) & (TILE_PUSH_PULL_BLOCK)) && player_entity.y != map_get_height()-1 && map_get_tile(LAYER_MIDDLE, player_entity.x,player_entity.y-1) != TILE_NONE) { map_set_tile(LAYER_MIDDLE, player_entity.x, player_entity.y, map_get_tile(LAYER_MIDDLE, player_entity.x,player_entity.y-1)); int object_index = 0; while(1) { obj_info *object = map_get_object(object_index++, player_entity.x, player_entity.y-1); if (object == NULL) break; if(!object->visible) continue; if(object->type == OBJ_ITEM || object->type == OBJ_WEAPON) { object->visible = false; map_set_tile(LAYER_MIDDLE, player_entity.x, player_entity.y-1, object->arg); return true; } } map_set_tile(LAYER_MIDDLE, player_entity.x, player_entity.y-1, TILE_NONE); return true; } break; } } return false; }
/************************************************************************** ... **************************************************************************/ void handle_unit_info(struct packet_unit_info *packet) { struct city *pcity; struct unit *punit; int repaint_unit; int repaint_city; repaint_unit=0; repaint_city=0; punit=unit_list_find(&game.players[packet->owner].units, packet->id); if(punit) { if(punit->activity!=packet->activity) { /* change activity */ punit->activity=packet->activity; repaint_unit=1; /* refresh_tile_mapcanvas(punit->x, punit->y, 1); update_unit_pix_label(punit); refresh_unit_city_dialogs(punit); update_unit_focus(); */ } if(punit->homecity!=packet->homecity) { /* change homecity */ struct city *pcity; if((pcity=game_find_city_by_id(punit->homecity))) { unit_list_unlink(&pcity->units_supported, punit); refresh_city_dialog(pcity); } punit->homecity=packet->homecity; if((pcity=game_find_city_by_id(punit->homecity))) { unit_list_insert(&pcity->units_supported, punit); refresh_city_dialog(pcity); } } if(punit->hp!=packet->hp) { /* hp changed */ punit->hp=packet->hp; repaint_unit=1; } if(punit->attacks_left!=packet->attacksleft) { /* #attacks changed */ punit->attacks_left=packet->attacksleft; repaint_unit=1; } if(punit->x!=packet->x || punit->y!=packet->y) { /* change position */ struct city *pcity; pcity=map_get_city(punit->x, punit->y); if(tile_is_known(packet->x, packet->y)) { do_move_unit(punit, packet); update_unit_focus(); } else { unit_list_unlink(&game.players[packet->owner].units, punit); unit_list_unlink(&map_get_tile(punit->x, punit->y)->units, punit); refresh_tile_mapcanvas(punit->x, punit->y, 1); free(punit); } if(pcity) refresh_city_dialog(pcity); if((pcity=map_get_city(punit->x, punit->y))) refresh_city_dialog(pcity); repaint_unit=0; } if (punit->unhappiness!=packet->unhappiness) { punit->unhappiness=packet->unhappiness; repaint_city=1; } if (punit->upkeep!=packet->upkeep) { punit->upkeep=packet->upkeep; repaint_city=1; } if (repaint_city) { if((pcity=game_find_city_by_id(punit->homecity))) { refresh_city_dialog(pcity); } } punit->moves_left=packet->movesleft; punit->bribe_cost=packet->bribe_cost; } else { /* create new unit */ punit=(struct unit *)malloc(sizeof(struct unit)); punit->id=packet->id; punit->owner=packet->owner; punit->x=packet->x; punit->y=packet->y; punit->veteran=packet->veteran; punit->homecity=packet->homecity; punit->type=packet->type; punit->attacks_left=packet->attacksleft; punit->moves_left=packet->movesleft; punit->hp=packet->hp; punit->unhappiness=0; punit->activity=packet->activity; punit->upkeep=0; punit->hp=packet->hp; punit->bribe_cost=packet->bribe_cost; unit_list_insert(&game.players[packet->owner].units, punit); unit_list_insert(&map_get_tile(punit->x, punit->y)->units, punit); if((pcity=game_find_city_by_id(punit->homecity))) unit_list_insert(&pcity->units_supported, punit); /* this is ugly - prevent unit from being drawn if it's moved into * screen by a transporter - only works for ground_units.. yak */ if(!is_ground_unit(punit) || map_get_terrain(punit->x, punit->y)!=T_OCEAN) repaint_unit=1; else repaint_unit=0; } if(punit && punit==get_unit_in_focus()) update_unit_info_label(punit); if(repaint_unit) refresh_tile_mapcanvas(punit->x, punit->y, 1); update_unit_focus(); }
/** Display a menu to resize the map enter the new map size for width, height and depth. TODO if the value entered is lower than the current map size ask if the tiles to delete are at front or at rear TODO if the value entered is higher than the current map size ask if the tile to create are at front or a rear and select in the chipset which tile to fill */ game_status state_resize_menu(SDL_Renderer *renderer, game* p_game){ bool done=false; char text[BUFSIZ] = {'\0'}; map *p_map = p_game->p_map; int new_width, new_height, new_depth; //flush the keys input which triggered this game state SDL_FlushEvent(SDL_TEXTINPUT); SDL_StartTextInput(); while (!done){ //draw SDL_RenderClear(renderer); SDL_SetRenderDrawColor(renderer, 0x22, 0x22, 0x42, 0x4F); SDL_Rect r = {.x=0, .y=0, .w=SCREEN_WIDTH, .h=SCREEN_HEIGHT}; SDL_RenderFillRect(renderer, &r); fontmap_printf(p_game->p_fontmap, 0, p_game->p_fontmap->size, renderer, "CURRENT MAP SIZE WIDTH %d HEIGHT %d DEPTH %d\n\ ENTER NEW SIZE WITH FORMAT %d-%d-%d ", p_map->width, p_map->height, p_map->depth, p_map->width, p_map->height, p_map->depth); //print back to the user the entered text fontmap_printf(p_game->p_fontmap, 0, p_game->p_fontmap->size*3, renderer, text); //render SDL_RenderPresent(renderer); //input SDL_Event event; while (SDL_PollEvent(&event)){ if(event.type == SDL_QUIT){ exit(EXIT_SUCCESS); } switch ( event.type ) { case SDL_KEYDOWN: switch (event.key.keysym.sym) { case SDLK_q: done=true; break; case SDLK_RETURN: //assign integers from the formated input sscanf(text, "%d-%d-%d", &new_width, &new_height, &new_depth); //allocate memory tile *tiles = calloc(new_width*new_height*new_depth, sizeof(tile)); //copy the current map tile into the new tiles memmove(tiles, p_map->tiles, p_map->height*p_map->width*p_map->depth); //free map tiles free(p_map->tiles); //allocate new tiles p_map->tiles = tiles; p_map->width = new_width; p_map->height = new_height; p_map->depth = new_depth; break; case SDLK_BACKSPACE: //remove the last character by replacing it by the EOS char text[strlen(text)-1] = '\0'; break; } break; case SDL_TEXTINPUT: strcat(text, event.text.text); break; } } } SDL_StopTextInput(); return STAY; } void game_tile_click(game* p_game, int x, int y, Uint8 button){ map *p_map = p_game->p_map; int x_offset = p_map->p_chipset->width; int y_offset = p_map->p_chipset->height; if(x < x_offset && y < y_offset){ //the click was on the chipset part //set the chipset tile p_map->chipset_tile_x_index = x / p_map->tile_width; p_map->chipset_tile_y_index = y / p_map->tile_height; } else{ //the clic was on the map part //change the clicked map tile with the selected chipset tile //check if the index is in the map boundaries if(p_map->map_tile_x_index >= 0 && p_map->map_tile_x_index < p_map->width && p_map->map_tile_y_index >= 0 && p_map->map_tile_y_index < p_map->height){ tile* p_tile = map_get_tile(p_map, p_map->map_tile_x_index, p_map->map_tile_y_index, p_map->map_tile_z_index); switch(p_game->tile_mode){ default: case TILE: tile_set_coord(p_tile, p_map->chipset_tile_x_index, p_map->chipset_tile_y_index); break; case LINE: if(p_game->tile_from_x < 0 || p_game->tile_from_y < 0 || p_game->tile_from_z < 0){ //set the tile to draw from p_game->tile_from_x = p_map->map_tile_x_index; p_game->tile_from_y = p_map->map_tile_y_index; p_game->tile_from_z = p_map->map_tile_z_index; } else{ //set the tile to draw to //the tile to draw to is always superior to the tile to draw from if(p_map->map_tile_x_index < p_game->tile_from_x){ p_game->tile_to_x = p_game->tile_from_x; p_game->tile_from_x = p_map->map_tile_x_index; } else{ p_game->tile_to_x = p_map->map_tile_x_index; } if(p_map->map_tile_y_index < p_game->tile_from_y){ p_game->tile_to_y = p_game->tile_from_y; p_game->tile_from_y = p_map->map_tile_y_index; } else{ p_game->tile_to_y = p_map->map_tile_y_index; } if(p_map->map_tile_z_index < p_game->tile_from_z){ p_game->tile_to_z = p_game->tile_from_z; p_game->tile_from_z = p_map->map_tile_z_index; } else{ p_game->tile_to_z = p_map->map_tile_z_index; } for(int x=p_game->tile_from_x;x<=p_game->tile_to_x;x++){ for(int y=p_game->tile_from_y;y<=p_game->tile_to_y;y++){ for(int z=p_game->tile_from_z;z<=p_game->tile_to_z;z++){ p_tile = map_get_tile(p_map, x, y, z); tile_set_coord(p_tile, p_map->chipset_tile_x_index, p_map->chipset_tile_y_index); } } } p_game->tile_from_x = -1; p_game->tile_from_y = -1; p_game->tile_from_z = -1; p_game->tile_to_x = -1; p_game->tile_to_y = -1; p_game->tile_to_z = -1; } break; } } } #ifdef DEBUG printf("map clicked at index %d %d %d\n", p_map->map_tile_x_index, p_map->map_tile_y_index, p_map->map_tile_z_index); #endif }
tile_t client_get_tile(map_t *map, s32 x, s32 y) { client_load_chunk(map, x, y); return map_get_tile(map, x, y); }
void map_draw(map* p_map, SDL_Renderer* renderer){ //offset the map drawing to the left in order to display the chipset const int x_offset = p_map->x_offset; const int x_from = -(p_map->o_camera.x % p_map->tile_width) + x_offset; const int x_to = x_from + SCREEN_WIDTH + (x_from == 0 ? 0 : p_map->tile_width) + x_offset; const int y_from = -(p_map->o_camera.y % p_map->tile_height); const int y_to = y_from + SCREEN_HEIGHT + (y_from == 0 ? 0 : p_map->tile_height); int tile_y_index = p_map->o_camera.y / p_map->tile_height; for (int y=y_from;y<y_to;y+=p_map->tile_height){ int tile_x_index = p_map->o_camera.x / p_map->tile_width; for (int x=x_from;x<x_to;x+=p_map->tile_width){ //get the tile in the map tiles tile* p_tile = map_get_tile(p_map, tile_x_index, tile_y_index); //draw the tile map_draw_tile(p_map, p_tile, x, y, renderer); //draw a horizontal grid line SDL_RenderDrawLine(renderer, 0, y, SCREEN_WIDTH, y); //draw a vertical grid line SDL_RenderDrawLine(renderer, x, 0, x, SCREEN_HEIGHT); //increment the tile index and check if it's in the map size rang if(++tile_x_index >= p_map->width)break; } //increment the tile index and check if it's in the map size rang if(++tile_y_index >= p_map->height)break; } //draw a rectangle on the selected map tile SDL_Rect rect = {.x= p_map->map_tile_x_index * p_map->tile_width, .y= p_map->map_tile_y_index * p_map->tile_height + y_from, .w= p_map->tile_width, .h= p_map->tile_height}; SDL_SetRenderDrawColor(renderer, 0xFF, 0x0, 0x0, 0xFF); SDL_RenderDrawRect(renderer, &rect); #ifdef DEBUG //Draw the debug menu debug_map(p_map, renderer, x_from, x_to, y_from, y_to, p_map->o_camera.x / p_map->tile_width, p_map->o_camera.y / p_map->tile_height); #endif } void map_mouse_move(map* p_map, SDL_Renderer* renderer, int x, int y){ const int x_from = p_map->o_camera.x % p_map->tile_width; const int y_from = p_map->o_camera.y % p_map->tile_height; int map_tile_x_index = (x + x_from) / p_map->tile_width; int map_tile_y_index = (y + y_from) / p_map->tile_height; p_map->map_tile_x_index = map_tile_x_index; p_map->map_tile_y_index = map_tile_y_index; } void map_tile_click(map* p_map, int x, int y, Uint8 button){ int x_offset = p_map->x_offset; if(x < x_offset){ //the click was on the chipset part //set the selected tile in the chipset p_map->chipset_tile_x_index = x / p_map->tile_width; p_map->chipset_tile_y_index = y / p_map->tile_height; } else{ //the clic was on the map part //change the clicked tile with the selected tile int clicked_tile_x_index = (x + p_map->o_camera.x - x_offset) / p_map->tile_width; int clicked_tile_y_index = (y + p_map->o_camera.y) / p_map->tile_height; #ifdef DEBUG printf("click at index %d %d\n", clicked_tile_x_index, clicked_tile_y_index); #endif //check if the index is in the map boundaries if(clicked_tile_x_index >= 0 && clicked_tile_x_index < p_map->width && clicked_tile_y_index >= 0 && clicked_tile_y_index < p_map->height){ tile* p_tile = map_get_tile(p_map, clicked_tile_x_index, clicked_tile_y_index); p_tile->x = p_map->chipset_tile_x_index; p_tile->y = p_map->chipset_tile_y_index; } } }