#include "IsoMiniMap.h" using namespace graphic; // base constructor, use a map to choose tiles IsoMiniMap::IsoMiniMap(IsoTilesMap * tm, IsoObjectsMap * om, TileSet * ts) : Map(tm->GetNumRows(), tm->GetNumCols()) { // Tile dimensions _tile_width = ts->GetTileW(); _tile_height = ts->GetTileH(); _square_side = _tile_height * SQRT2; int half_height = _tile_height / 2; // scale of the minimap _scale = tm->GetTileW() / _tile_width; // indexes int r , c; // temporary IntPoint for tiles IntPoint constr_p; // temporary tile pointer MiniTile * constr_tile; // set the image origin so that the [num_rows, 0] tile have x = 0 and the [0,0] // tile have y = 0 _graphic_origin.x = ((_num_rows - 1) * _tile_height); _graphic_origin.y = 0; // origin of the map _origin.x = _graphic_origin.x + _tile_height; _origin.y = _graphic_origin.y; // store IsoTilesMap pointer _tm = tm; // store IsoObjectsMap pointer _om = om; // store TileSet pointer _tile_set = ts; // dimensions of the map _width = (_num_cols + _num_rows) * _tile_height; _height = _width / 2; // number of used images _num_images = ts->GetNumImg(); // number of cells and objects _num_cells = _num_cols * _num_rows; _num_objects = _num_cells; for(r = 0; r < _num_rows; r++) { for(c = 0; c < _num_cols; c++) { // visible and walkable tile if(_tm->IsWalkable(r,c) && _tm->IsVisible(r,c) == VISIBLE) constr_tile = new MiniTile(ts->GetImage(IMG_VISIBLE)); // partially visible tile else if(_tm->IsVisible(r,c) == PARTIALLY_VISIBLE) constr_tile = new MiniTile(ts->GetImage(IMG_PARTIALLY_VISIBLE)); // visible but not walkable tile (ELEMENT) else if(_tm->IsVisible(r,c) == VISIBLE) { Element * el = (Element *) om->GetObject(r, c); //TODO These values should be set from a script or an xml file // scene element if(!el->GetType().compare("sceneelement") || !el->GetType().compare("terrainelement")) constr_tile = new MiniTile(ts->GetImage(IMG_ELEMENT)); // faction element else { int faction = (dynamic_cast (el))->GetFaction(); if(faction == F_MERCENARIES) constr_tile = new MiniTile(ts->GetImage(IMG_MERCENARIES)); else if(faction == F_NGG) constr_tile = new MiniTile(ts->GetImage(IMG_NGG)); else if(faction == F_SWA) constr_tile = new MiniTile(ts->GetImage(IMG_SWA)); else constr_tile = new MiniTile(ts->GetImage(IMG_NO_FACTION)); } } // not visible tile else constr_tile = new MiniTile(ts->GetImage(IMG_NOT_VISIBLE)); // set indexes of the new tile constr_tile->SetIndexes(r,c); // set tile isometric position constr_p.x = (c - r) * _tile_height + _graphic_origin.x; constr_p.y = (c + r) * half_height + _graphic_origin.y; constr_tile->SetPosition(constr_p); // store the tile into the tiles vector _objects.push_back(constr_tile); } } } // blit part of the layer on a surface, if the surface is NULL blit on screen void IsoMiniMap::BlitLayer(SDL_Rect limits_rect, Surface * dst_surf) { Sint16 l_limit = limits_rect.x ; Sint16 r_limit = limits_rect.x + limits_rect.w; Sint16 u_limit = limits_rect.y; Sint16 b_limit = limits_rect.y + limits_rect.h; // temporary IntPoint IntPoint p; Image * cur_img; MiniTile * cur_tile; FloatPoint * start, * end; int s_row, s_col, e_row, e_col; // compute start row => top, right corner start = iso2scr(r_limit, u_limit, _origin.x, _origin.y); s_row = (int)(start->y / _square_side) - 1; if(s_row < 0) s_row = 0; delete start; // compute start col => top, left corner start = iso2scr(l_limit, u_limit, _origin.x, _origin.y); s_col = (int)(start->x / _square_side) - 1; if(s_col < 0) s_col = 0; delete start; // compute end row => bottom, left corner end = iso2scr(l_limit, b_limit, _origin.x, _origin.y); // row and col of the end IntPoint e_row = (int)(end->y / _square_side) + 1; if(e_row > _num_rows) e_row = _num_rows; delete end; // compute end col => bottom, right corner end = iso2scr(r_limit, b_limit, _origin.x, _origin.y); e_col = (int)(end->x / _square_side) + 1; if(e_col > _num_cols) e_col = _num_cols; delete end; for(int r = s_row; r < e_row ; r++) { for(int c = s_col; c < e_col; c++) { cur_tile = (MiniTile *) _objects[(r * _num_cols) + c]; p.x = cur_tile->GetX(); p.y = cur_tile->GetY(); if( ((p.x + _tile_width >= l_limit) && (p.x <= r_limit) && (p.y + _tile_height >= u_limit) && (p.y <= b_limit))) { cur_img = cur_tile->GetImage(); //set blit position of the image cur_img->SetPosition(p.x - l_limit, p.y - u_limit); //blit blitter->Blit(cur_img, dst_surf); } } } } // blit part of the layer on a surface using dest_rect for the position, if the surface is NULL blit on screen void IsoMiniMap::BlitLayer(SDL_Rect limits_rect, SDL_Rect dest_rect, Surface * dst_surf) { Sint16 l_limit = limits_rect.x; Sint16 r_limit = limits_rect.x + limits_rect.w; Sint16 u_limit = limits_rect.y; Sint16 b_limit = limits_rect.y + limits_rect.h; // temporary IntPoint IntPoint p; Image * cur_img; MiniTile * cur_tile; FloatPoint * start, * end; int s_row, s_col, e_row, e_col; // compute start row => top, right corner start = iso2scr(r_limit, u_limit, _origin.x, _origin.y); s_row = (int)(start->y / _square_side) - 1; if(s_row < 0) s_row = 0; delete start; // compute start col => top, left corner start = iso2scr(l_limit, u_limit, _origin.x, _origin.y); s_col = (int)(start->x / _square_side) - 1; if(s_col < 0) s_col = 0; delete start; // compute end row => bottom, left corner end = iso2scr(l_limit, b_limit, _origin.x, _origin.y); // row and col of the end IntPoint e_row = (int)(end->y / _square_side) + 1; if(e_row > _num_rows) e_row = _num_rows; delete end; // compute end col => bottom, right corner end = iso2scr(r_limit, b_limit, _origin.x, _origin.y); e_col = (int)(end->x / _square_side) + 1; if(e_col > _num_cols) e_col = _num_cols; delete end; SDL_Rect part_r; bool blit_part; for(int r = s_row; r < e_row ; r++) { for(int c = s_col; c < e_col; c++) { cur_tile = (MiniTile *) _objects[(r * _num_cols) + c]; p.x = cur_tile->GetX(); p.y = cur_tile->GetY(); if( ((p.x + _tile_width >= l_limit) && (p.x <= r_limit) && (p.y + _tile_height >= u_limit) && (p.y <= b_limit))) { cur_img = cur_tile->GetImage(); //set blit position of the image cur_img->SetPosition(dest_rect.x + p.x - l_limit, dest_rect.y + p.y - u_limit); // part_r init - all the image part_r.x = 0; part_r.y = 0; part_r.w = cur_img->GetW(); part_r.h = cur_img->GetH(); blit_part = false; // img goes over left border if(cur_img->GetX() < dest_rect.x) { part_r.x = dest_rect.x - cur_img->GetX(); part_r.w = cur_img->GetW() - part_r.x; // set new starting blit X cur_img->SetX(dest_rect.x); blit_part = true; } // img goes over left border if((cur_img->GetX() + cur_img->GetW()) > (dest_rect.x + dest_rect.w)) { part_r.w = dest_rect.x + dest_rect.w - cur_img->GetX(); blit_part = true; } // img goes over upper border if(cur_img->GetY() < dest_rect.y) { part_r.y = dest_rect.y - cur_img->GetY(); part_r.h = cur_img->GetH() - part_r.y; // set new starting blit Y cur_img->SetY(dest_rect.y); blit_part = true; } // img goes over bottom border if((cur_img->GetY() + cur_img->GetH()) > (dest_rect.y + dest_rect.h)) { part_r.h = dest_rect.y + dest_rect.h - cur_img->GetY(); blit_part = true; } if(blit_part) blitter->BlitPart(cur_img, part_r, dst_surf); else blitter->Blit(cur_img, dst_surf); } } } } void IsoMiniMap::UpdateMap() { for(int r = 0; r < _num_rows; r++) { for(int c = 0; c < _num_cols; c++) { // visible and walkable tile if(_tm->IsWalkable(r,c) && _tm->IsVisible(r,c) == VISIBLE) ((MiniTile *) _objects[(r * _num_cols) + c])->SetImage(_tile_set->GetImage(IMG_VISIBLE)); // partially visible tile else if(_tm->IsVisible(r,c) == PARTIALLY_VISIBLE) ((MiniTile *) _objects[(r * _num_cols) + c])->SetImage(_tile_set->GetImage(IMG_PARTIALLY_VISIBLE)); // visible but not walkable tile (ELEMENT) else if(_tm->IsVisible(r,c) == VISIBLE) { Element * el = (Element *) _om->GetObject(r, c); //TODO These values should be set from a script or an xml file // scene element if(!el->GetType().compare("sceneelement") || !el->GetType().compare("terrainelement")) ((MiniTile *) _objects[(r * _num_cols) + c])->SetImage(_tile_set->GetImage(IMG_ELEMENT)); // faction element else { int faction = (dynamic_cast (el))->GetFaction(); if(faction == F_MERCENARIES) ((MiniTile *) _objects[(r * _num_cols) + c])->SetImage(_tile_set->GetImage(IMG_MERCENARIES)); else if(faction == F_NGG) ((MiniTile *) _objects[(r * _num_cols) + c])->SetImage(_tile_set->GetImage(IMG_NGG)); else if(faction == F_SWA) ((MiniTile *) _objects[(r * _num_cols) + c])->SetImage(_tile_set->GetImage(IMG_SWA)); else ((MiniTile *) _objects[(r * _num_cols) + c])->SetImage(_tile_set->GetImage(IMG_NO_FACTION)); } } // not visible tile else ((MiniTile *) _objects[(r * _num_cols) + c])->SetImage(_tile_set->GetImage(IMG_NOT_VISIBLE)); } } }