/** * @brief Draws the tile image on a surface. * @param dst_surface the surface to draw * @param dst_position position where tile pattern should be drawn on dst_surface * @param tileset the tileset of this tile * @param viewport coordinates of the top-left corner of dst_surface relative * to the map (may be used for scrolling tiles) */ void SimpleTilePattern::draw(Surface& dst_surface, const Rectangle& dst_position, Tileset& tileset, const Rectangle& viewport) { Surface& tileset_image = tileset.get_tiles_image(); tileset_image.draw_region(position_in_tileset, dst_surface, dst_position); }
void Materials::createOtherTileset() { Tileset* others; Tileset* npc_tileset; if(tilesets["Others"] != NULL) { others = tilesets["Others"]; others->clear(); } else { others = newd Tileset(brushes, "Others"); tilesets["Others"] = others; } if(tilesets["NPCs"] != NULL) { npc_tileset = tilesets["NPCs"]; npc_tileset->clear(); } else { npc_tileset = newd Tileset(brushes, "NPCs"); tilesets["NPCs"] = npc_tileset; } // There should really be an iterator to do this for(int id = 0; id < item_db.getMaxID(); ++id) { ItemType& it = item_db[id]; if(it.id == 0) { continue; } if(it.isMetaItem() == false) { Brush* brush; if(it.in_other_tileset) { others->getCategory(TILESET_RAW)->brushlist.push_back(it.raw_brush); continue; } else if(it.raw_brush == NULL) { brush = it.raw_brush = newd RAWBrush(it.id); it.has_raw = true; brushes.addBrush(it.raw_brush); } else if(it.has_raw == false) { brush = it.raw_brush; } else continue; brush->flagAsVisible(); others->getCategory(TILESET_RAW)->brushlist.push_back(it.raw_brush); it.in_other_tileset = true; } } for(CreatureMap::iterator iter = creature_db.begin(); iter != creature_db.end(); ++iter) { CreatureType* type = iter->second; if(type->in_other_tileset) { if(type->isNpc) npc_tileset->getCategory(TILESET_CREATURE)->brushlist.push_back(type->brush); else others->getCategory(TILESET_CREATURE)->brushlist.push_back(type->brush); } else if(type->brush == NULL) { type->brush = newd CreatureBrush(type); brushes.addBrush(type->brush); type->brush->flagAsVisible(); type->in_other_tileset = true; if(type->isNpc) npc_tileset->getCategory(TILESET_CREATURE)->brushlist.push_back(type->brush); else others->getCategory(TILESET_CREATURE)->brushlist.push_back(type->brush); } } }
void MapEditor::calculate_light(bool pixel_precise) { if (wmap) { EditableMap::Lights& lights = wmap->get_light_sources(); if (!lights.size()) { show_messagebox(Gui::MessageBoxIconExclamation, "Light Sources", "No light sources found in this map."); return; } /* name set? */ if (!wmap->get_name().length()) { show_messagebox(Gui::MessageBoxIconExclamation, "No Map Name", "Please choose a map name in the map properties."); return; } /* trace all points */ Tileset *ts = wmap->get_tileset_ptr(); if (!ts) { show_messagebox(Gui::MessageBoxIconExclamation, "No Tileset", "Please select a tileset in the map properties."); return; } int vw = subsystem.get_view_width(); int vh = subsystem.get_view_height(); int ww = 127; int wh = 80; //60; win_compile = push_window(vw / 2 - ww / 2, vh / 2 - wh / 2, ww, wh, "Compiling"); lbl_compile = create_label(win_compile, Spc, Spc, "0%"); GuiButton *btn = add_close_button(win_compile, static_cancel_compilation_click); btn->set_caption("Cancel"); int mw = wmap->get_width(); int mh = wmap->get_height(); int tw = ts->get_tile_width(); int th = ts->get_tile_height(); lightmap_w = mw * tw; lightmap_h = mh * th; int mapw = mw * tw; int maph = mh * th; short **pdeco = wmap->get_decoration(); if (lightmap_w % LightMapSize) { lightmap_w = ((lightmap_w / LightMapSize) + 1) * LightMapSize; } if (lightmap_h % LightMapSize) { lightmap_h = ((lightmap_h / LightMapSize) + 1) * LightMapSize; } /* create whole lightmap */ lightmap = new unsigned char *[lightmap_h]; /* create thread */ if (pixel_precise) { for (int y = 0; y < lightmap_h; y++) { lightmap[y] = new unsigned char[lightmap_w * 4]; for (int x = 0; x < lightmap_w; x++) { lightmap[y][x * 4 + 0] = 0; lightmap[y][x * 4 + 1] = 0; lightmap[y][x * 4 + 2] = 0; if (x >= mapw || y >= maph) { lightmap[y][x * 4 + 3] = 0; } else { int index = pdeco[y / th][x / tw]; if (index < 0) { lightmap[y][x * 4 + 3] = 0; } else { TileGraphic *tg = ts->get_tile(index)->get_tilegraphic(); TileGraphicGL *tggl = static_cast<TileGraphicGL *>(tg); if (tggl->get_bytes_per_pixel(0) < 4) { lightmap[y][x * 4 + 3] = 255; } else { unsigned char *p = tggl->get_picture_array(0); p += (((y % th) * 4 * tw) + ((x % tw) * 4)); lightmap[y][x * 4 + 3] = p[3]; } } } } } compile_thread = new CompileThreadPixel(wmap, lightmap); } else { for (int y = 0; y < lightmap_h; y++) { lightmap[y] = new unsigned char[lightmap_w * 4]; for (int x = 0; x < lightmap_w; x++) { lightmap[y][x * 4 + 0] = 0; lightmap[y][x * 4 + 1] = 0; lightmap[y][x * 4 + 2] = 0; if (x >= mapw || y >= maph) { lightmap[y][x * 4 + 3] = 0; } else { if (pdeco[y / th][x / tw] < 0) { lightmap[y][x * 4 + 3] = 0; } else { lightmap[y][x * 4 + 3] = 255; } } } } compile_thread = new CompileThreadBlock(wmap, lightmap); } } }
void Map::ParseText(const string &text) { // Create a tiny xml document and use it to parse the text. TiXmlDocument doc; doc.Parse(text.c_str()); // Check for parsing errors. if (doc.Error()) { has_error = true; error_code = TMX_PARSING_ERROR; error_text = doc.ErrorDesc(); return; } TiXmlNode *mapNode = doc.FirstChild("map"); TiXmlElement* mapElem = mapNode->ToElement(); // Read the map attributes. mapElem->Attribute("version", &version); mapElem->Attribute("width", &width); mapElem->Attribute("height", &height); mapElem->Attribute("tilewidth", &tile_width); mapElem->Attribute("tileheight", &tile_height); // Read the orientation std::string orientationStr = mapElem->Attribute("orientation"); if (!orientationStr.compare("orthogonal")) { orientation = TMX_MO_ORTHOGONAL; } else if (!orientationStr.compare("isometric")) { orientation = TMX_MO_ISOMETRIC; } // Read the map properties. const TiXmlNode *propertiesNode = mapElem->FirstChild("properties"); if (propertiesNode) { properties.Parse(propertiesNode); } // Iterate through all of the tileset elements. const TiXmlNode *tilesetNode = mapNode->FirstChild("tileset"); while (tilesetNode) { // Allocate a new tileset and parse it. Tileset *tileset = new Tileset(); tileset->Parse(tilesetNode->ToElement(), file_path); if (tileset->HasError()) { has_error = true; error_code = 1; error_text = tileset->GetErrorText(); return; } // Add the tileset to the list. tilesets.push_back(tileset); tilesetNode = mapNode->IterateChildren("tileset", tilesetNode); } // Iterate through all of the layer elements. TiXmlNode *layerNode = mapNode->FirstChild("layer"); while (layerNode) { // Allocate a new layer and parse it. Layer *layer = new Layer(this); layer->Parse(layerNode); // Add the layer to the list. layers.push_back(layer); layerNode = mapNode->IterateChildren("layer", layerNode); } // Iterate through all of the objectgroup elements. TiXmlNode *objectGroupNode = mapNode->FirstChild("objectgroup"); while (objectGroupNode) { // Allocate a new object group and parse it. ObjectGroup *objectGroup = new ObjectGroup(); objectGroup->Parse(objectGroupNode); // Add the object group to the list. object_groups.push_back(objectGroup); objectGroupNode = mapNode->IterateChildren("objectgroup", objectGroupNode); } }
QModelIndex TerrainModel::index(Terrain *terrain, int column) const { Tileset *tileset = terrain->tileset(); int row = tileset->terrains().indexOf(terrain); return createIndex(row, column, tileset); }
void Map::ParseText(const string &text) { // Create a tiny xml document and use it to parse the text. TiXmlDocument doc; doc.Parse(text.c_str()); // Check for parsing errors. if (doc.Error()) { has_error = true; error_code = TMX_PARSING_ERROR; error_text = doc.ErrorDesc(); return; } TiXmlNode *mapNode = doc.FirstChild("map"); TiXmlElement* mapElem = mapNode->ToElement(); // Read the map attributes. mapElem->Attribute("version", &version); mapElem->Attribute("width", &width); mapElem->Attribute("height", &height); mapElem->Attribute("tilewidth", &tile_width); mapElem->Attribute("tileheight", &tile_height); // Read the orientation std::string orientationStr = mapElem->Attribute("orientation"); if (!orientationStr.compare("orthogonal")) { orientation = TMX_MO_ORTHOGONAL; } else if (!orientationStr.compare("isometric")) { orientation = TMX_MO_ISOMETRIC; } else if (!orientationStr.compare("staggered")) { orientation = TMX_MO_STAGGERED; } const TiXmlNode *node = mapElem->FirstChild(); int zOrder = 0; while( node ) { // Read the map properties. if( strcmp( node->Value(), "properties" ) == 0 ) { properties.Parse(node); } // Iterate through all of the tileset elements. if( strcmp( node->Value(), "tileset" ) == 0 ) { // Allocate a new tileset and parse it. Tileset *tileset = new Tileset(); tileset->Parse(node->ToElement()); // Add the tileset to the list. tilesets.push_back(tileset); } // Iterate through all of the layer elements. if( strcmp( node->Value(), "layer" ) == 0 ) { // Allocate a new layer and parse it. Layer *layer = new Layer(this); layer->Parse(node); layer->SetZOrder( zOrder ); ++zOrder; // Add the layer to the list. layers.push_back(layer); } // Iterate through all of the imagen layer elements. if( strcmp( node->Value(), "imagelayer" ) == 0 ) { // Allocate a new layer and parse it. ImageLayer *imageLayer = new ImageLayer(this); imageLayer->Parse(node); imageLayer->SetZOrder( zOrder ); ++zOrder; // Add the layer to the list. image_layers.push_back(imageLayer); } // Iterate through all of the objectgroup elements. if( strcmp( node->Value(), "objectgroup" ) == 0 ) { // Allocate a new object group and parse it. ObjectGroup *objectGroup = new ObjectGroup(); objectGroup->Parse(node); objectGroup->SetZOrder( zOrder ); ++zOrder; // Add the object group to the list. object_groups.push_back(objectGroup); } node = node->NextSibling(); } }
/** * @brief Displays the tile on a surface. * @param destination the destination surface * @param dst_position position of the tile pattern on the destination surface * @param tileset the tileset of this tile pattern */ void AnimatedTilePattern::display(Surface *destination, const Rectangle &dst_position, Tileset &tileset) { Surface *tileset_image = tileset.get_tiles_image(); tileset_image->blit(position_in_tileset[current_frames[sequence]], destination, dst_position); }
bool Level::Load(const std::string& filename) { Tmx::Map map; map.ParseFile(filename); if(map.HasError()) { Debug::logger->message("Error while loading level %s: %s\n", filename.c_str(), map.GetErrorText().c_str()); return false; } _width = map.GetWidth(); _height = map.GetHeight(); _tileWidth = map.GetTileWidth(); _tileHeight = map.GetTileHeight(); std::map<const Tmx::Tileset*, Tileset*> tilesetMap; for(int i = 0; i < map.GetNumTilesets(); i++) { const Tmx::Tileset* tmxTileset = map.GetTileset(i); Tileset* tileset = new Tileset(_tileWidth, _tileHeight); tileset->LoadImage(map.GetFilepath() + tmxTileset->GetImage()->GetSource()); _tilesets.push_back(tileset); tilesetMap.insert(std::pair<const Tmx::Tileset*, Tileset*>(tmxTileset, tileset)); } _collisions = new bool[_width * _height]; for(int i = 0; i < (_width * _height); i++) { _collisions[i] = false; } for(int i = 0; i < map.GetNumLayers(); i++) { const Tmx::Layer* tmxLayer = map.GetLayer(i); if(!strcasecmp(tmxLayer->GetName().c_str(), "collision")) { for(int x = 0; x < _width; x++) { for(int y = 0; y < _height; y++) { Tmx::MapTile tile = tmxLayer->GetTile(x, y); _collisions[y * _width + x] = tile.tilesetId > -1; } } continue; } else if(!strcasecmp(tmxLayer->GetName().c_str(), "middle")) { _middleLayer = i; } Layer* layer = new Layer( tmxLayer->GetWidth(), tmxLayer->GetHeight(), _tileWidth, _tileHeight); for(int x = 0; x < layer->GetWidth(); x++) { for(int y = 0; y < layer->GetHeight(); y++) { Tmx::MapTile tmxTile = tmxLayer->GetTile(x, y); MapTile tile; if(tmxTile.tilesetId != -1) { const Tmx::Tileset* tmxTileset = map.GetTileset(tmxTile.tilesetId); tile.id = tmxTile.id; tile.tileset = tilesetMap.find(tmxTileset)->second; } else { tile.id = 0; tile.tileset = NULL; } layer->SetTile(x, y, tile); } } _layers.push_back(layer); } if(_middleLayer == -1) { _middleLayer = int(floor(float(_layers.size()) / 2.0f)); // <-- nasty } for(int i = 0; i < map.GetNumObjectGroups(); i++) { const Tmx::ObjectGroup* tmxGroup = map.GetObjectGroup(i); for(int j = 0; j < tmxGroup->GetNumObjects(); j++) { const Tmx::Object* tmxObject = tmxGroup->GetObject(j); if(!strncasecmp(tmxObject->GetName().c_str(), "NPC", 3)) { NPC* npc = new NPC(this); npc->LoadSprites(tmxObject->GetProperties().GetLiteralProperty("image").c_str()); npc->SetXY(tmxObject->GetX(), tmxObject->GetY()); _npcs.push_back(npc); } else if(!strncasecmp(tmxObject->GetName().c_str(), "Warp", 4)) { Warp* warp = new Warp(); warp->SetXY(tmxObject->GetX(), tmxObject->GetY()); warp->SetWidthHeight(tmxObject->GetWidth(), tmxObject->GetHeight()); warp->SetTargetMap(tmxObject->GetProperties().GetLiteralProperty("map").c_str()); warp->SetTargetX(tmxObject->GetProperties().GetNumericProperty("x") * 32); warp->SetTargetY(tmxObject->GetProperties().GetNumericProperty("y") * 32); _warps.push_back(warp); } } } std::map<std::string, std::string> mapProps = map.GetProperties().GetList(); for(std::map<std::string, std::string>::iterator i = mapProps.begin(); i != mapProps.end(); ++i) { if(i->first == "BGM") { _bgm = musicManager.Load(i->second); } } return true; }
QModelIndex TilesetTerrainModel::index(Terrain *terrain) const { Tileset *tileset = terrain->tileset(); int row = tileset->terrains().indexOf(terrain); return index(row, 0); }
void TilesetEditor::addTiles(const QList<QUrl> &urls) { Tileset *tileset = currentTileset(); if (!tileset) return; Preferences *prefs = Preferences::instance(); struct LoadedFile { QUrl imageSource; QPixmap image; }; QVector<LoadedFile> loadedFiles; // If the tile is already in the tileset, warn user and confirm addition bool dontAskAgain = false; bool rememberOption = true; for (const QUrl &url : urls) { if (!(dontAskAgain && rememberOption) && hasTileInTileset(url, *tileset)) { if (dontAskAgain) continue; QCheckBox *checkBox = new QCheckBox(tr("Apply this action to all tiles")); QMessageBox warning(QMessageBox::Warning, tr("Add Tiles"), tr("Tile \"%1\" already exists in the tileset!").arg(url.toString()), QMessageBox::Yes | QMessageBox::No, mMainWindow->window()); warning.setDefaultButton(QMessageBox::Yes); warning.setInformativeText(tr("Add anyway?")); warning.setCheckBox(checkBox); int warningBoxChoice = warning.exec(); dontAskAgain = checkBox->checkState() == Qt::Checked; rememberOption = warningBoxChoice == QMessageBox::Yes; if (!rememberOption) continue; } const QPixmap image(url.toLocalFile()); if (!image.isNull()) { loadedFiles.append(LoadedFile { url, image }); } else { // todo: support lazy loading of selected remote files QMessageBox warning(QMessageBox::Warning, tr("Add Tiles"), tr("Could not load \"%1\"!").arg(url.toString()), QMessageBox::Ignore | QMessageBox::Cancel, mMainWindow->window()); warning.setDefaultButton(QMessageBox::Ignore); if (warning.exec() != QMessageBox::Ignore) return; } } if (loadedFiles.isEmpty()) return; const QString lastLocalFile = urls.last().toLocalFile(); if (!lastLocalFile.isEmpty()) prefs->setLastPath(Preferences::ImageFile, lastLocalFile); QList<Tile*> tiles; tiles.reserve(loadedFiles.size()); for (LoadedFile &loadedFile : loadedFiles) { Tile *newTile = new Tile(tileset->takeNextTileId(), tileset); newTile->setImage(loadedFile.image); newTile->setImageSource(loadedFile.imageSource); tiles.append(newTile); } mCurrentTilesetDocument->undoStack()->push(new AddTiles(mCurrentTilesetDocument, tiles)); }
void TilesetDock::exportTileset() { Tileset *tileset = currentTileset(); if (!tileset) return; if (tileset->isExternal()) return; int mapTilesetIndex = mMapDocument->map()->tilesets().indexOf(tileset->sharedPointer()); if (mapTilesetIndex == -1) return; // To export a tileset we clone it, since the tileset could now be used by // other maps. This ensures undo can take the map back to using an embedded // tileset, without affecting those other maps. SharedTileset externalTileset = tileset->clone(); FormatHelper<TilesetFormat> helper(FileFormat::ReadWrite); Preferences *prefs = Preferences::instance(); QString suggestedFileName = prefs->lastPath(Preferences::ExternalTileset); suggestedFileName += QLatin1Char('/'); suggestedFileName += externalTileset->name(); const QLatin1String extension(".tsx"); if (!suggestedFileName.endsWith(extension)) suggestedFileName.append(extension); // todo: remember last used filter QString selectedFilter = TsxTilesetFormat().nameFilter(); const QString fileName = QFileDialog::getSaveFileName(this, tr("Export Tileset"), suggestedFileName, helper.filter(), &selectedFilter); if (fileName.isEmpty()) return; prefs->setLastPath(Preferences::ExternalTileset, QFileInfo(fileName).path()); TilesetFormat *format = helper.formatByNameFilter(selectedFilter); if (!format) return; // can't happen if (!format->write(*externalTileset, fileName)) { QString error = format->errorString(); QMessageBox::critical(window(), tr("Export Tileset"), tr("Error saving tileset: %1").arg(error)); return; } externalTileset->setFileName(fileName); externalTileset->setFormat(format); QUndoCommand *command = new ReplaceTileset(mMapDocument, mapTilesetIndex, externalTileset); mMapDocument->undoStack()->push(command); // Make sure the external tileset is selected int externalTilesetIndex = mTilesets.indexOf(externalTileset); if (externalTilesetIndex != -1) mTabBar->setCurrentIndex(externalTilesetIndex); }
void MapperTilesetBox::draw(gcn::Graphics* graphics){ // draw components InfraellyWindow::draw(graphics); //draw selection overlay if( !tilesetList->empty() ){ Tileset *selectedTs = tilesetList->at( tilesetDropDown->getSelected() ); if( selectedTs != NULL ){ if( selectedTs->getImage() != NULL ){ //tile width and height int tileWidth = selectedTs->getTileWidth(); int tileHeight = selectedTs->getTileHeight(); //calculate amount of px off the screen int offsetX = tilesetImage->getX(); int offsetY = tilesetImage->getY(); // convert pixel values to row, width int offCol = offsetX/tileWidth; int offRow = offsetY/tileHeight; //get the row and col of the selected tile int trueCol = selectedTile.getCol(); int trueRow = selectedTile.getRow(); //to find out the reletive row/col to draw to // we must minus the offscreen tiles from the true tiles co-ords int drawCol = trueCol + offCol; int drawRow = trueRow + offRow; //calculate where to draw in pxs int drawX = (drawCol * tileWidth) + (tilesetImageScroller->getX() + getFrameSize()); int drawY = (drawRow * tileHeight) + (tilesetImageScroller->getY() + getTitleBarHeight()); //add offsets according to scroller drawX += offsetX%tileWidth; drawY += offsetY%tileHeight; //dimensions of the frame gcn::Rectangle d( drawX+selectedTs->getXOffset(), drawY+selectedTs->getYOffset(), tileWidth, tileHeight ); //only draw if within region if( ( d.x < tilesetImageScroller->getX()+tilesetImageScroller->getWidth() ) && ( d.x+d.width > tilesetImageScroller->getX() ) && ( d.y < tilesetImageScroller->getY()+tilesetImageScroller->getHeight()+getTitleBarHeight() ) && ( d.y+d.height > tilesetImageScroller->getY()+getTitleBarHeight() ) ){ //setcolour to blue graphics->setColor( gcn::Color( 0, 0, 255) ); //draw a frame graphics->drawRectangle( d ); //decrease the dimensions by one pixel ++d.x; ++d.y; d.width -= 2; d.height -= 2; //draw another frame (inside prev one) graphics->drawRectangle( d ); } else { //not in region, draw a bob //off the left if( (d.x+d.width) < tilesetImageScroller->getX() ){ d.x = tilesetImageScroller->getX(); d.y += (tileHeight/2)-5; }; //off the right if( d.x > (tilesetImageScroller->getWidth()+tilesetImageScroller->getX()) ){ d.x = tilesetImageScroller->getWidth()-10; d.y += (tileHeight/2)-5; }; //off the top if( (d.y+d.height) < tilesetImageScroller->getY() ){ d.y = tilesetImageScroller->getY()+getTitleBarHeight(); d.x += (tileWidth/2)-5; }; //off the bottom if( d.y > (tilesetImageScroller->getHeight()+tilesetImageScroller->getY()+getTitleBarHeight()) ){ d.y = tilesetImageScroller->getY()+tilesetImageScroller->getHeight()+getTitleBarHeight() - 10; d.x += (tileWidth/2)-5; }; //draw the bob (5x5px box) d.width = 10; d.height = 10; //setcolour to red graphics->setColor( gcn::Color( 255, 0, 0) ); graphics->fillRectangle( d ); } } } } }
void MapperTilesetBox::mouseClicked(gcn::MouseEvent& mouseEvent){ InfraellyWindow::mouseClicked(mouseEvent); if( mouseEvent.isConsumed() ){ return; }; //if click was from closeTilesetButton if( mouseEvent.getSource() == closeTilesetButton ){ //consume mouse event mouseEvent.consume(); //get the pointer to the tileset to remove Tileset *toRemove = tilesetList->at( tilesetDropDown->getSelected() ); //check if the user is trying to dlete teh nullTS if( toRemove != tilesetList->at(0) ){ //store number to remove int removeIndex = tilesetDropDown->getSelected(); //change the selected ts to the nullTS tilesetDropDown->setSelected(0); //delete the entry from teh list tilesetList->removeElementAt( removeIndex ); //if there is a map activley associated if( world != NULL ){ //stip dependency from map working on //if there IS dependency if( !world->empty() ){ //cycle through layers for( size_t i = 0; i < world->size(); ++i ){ //cycle thru tiles for( size_t j = 0; j < world->getLayer(i).getHeight() * world->getLayer(i).getWidth(); ++j){ if( world->getLayer(i).index(j).getTileset() == toRemove ){ world->getLayer(i).index(j).setTileset(NULL); } } } } } //dependency of tileset stripped //delete the tileset cache::tilesets.erase(toRemove); //remove from selected tile selectedTile.setSource(NULL,0,0); } } //click from the tilesetImage if( mouseEvent.getSource() == tilesetImage ){ //consume mouse event mouseEvent.consume(); if( !tilesetList->empty() ){ Tileset *selectedTs = selectedTile.getTileset(); if( selectedTs != NULL ){ // tileset select int tileWidth = selectedTs->getTileWidth(); int tileHeight = selectedTs->getTileHeight(); // get the x-y co-ords reletive to the tileset region int col = mouseEvent.getX() - (tilesetImage->getX()+selectedTs->getXOffset()); int row = mouseEvent.getY() - (tilesetImage->getY()+selectedTs->getYOffset()); // if its a multiple of tilewidth/height (ie in the barrier between) if( col % tileWidth == 0){ ++col; }; if( row % tileHeight == 0){ ++row; }; // turn co-ords into row/col col = col/tileWidth; row = row/tileHeight; // calculate the amount of tiles off the screen int trueCol = tilesetImage->getX(); int trueRow = tilesetImage->getY(); // if its a multiple of tilewidth/height (ie in the barrier between) if( trueCol % tileWidth == 0){ ++col; }; if( trueRow % tileHeight == 0){ ++row; }; // turn co-ords into row/col trueCol = trueCol/tileWidth; trueRow = trueRow/tileHeight; //add the on screen offset to the offsecreen tiles trueCol += col-1; trueRow += row-1; //store the tile's new row-col selectedTile.setSource( selectedTs, trueCol, trueRow); //store attribute if on atrib ts if( selectedTile.getTileset() == attribTs ){ selectedTile.setAttribute(attribGrid[trueCol][trueRow]); } }// end if null }//end if empty list }//end if event from drop down*/ }
QVariant MapToVariantConverter::toVariant(const Tileset &tileset, int firstGid) const { QVariantMap tilesetVariant; if (firstGid > 0) tilesetVariant[QLatin1String("firstgid")] = firstGid; else tilesetVariant[QLatin1String("version")] = 1.2; // external tileset const QString &fileName = tileset.fileName(); if (!fileName.isEmpty() && firstGid > 0) { QString source = mMapDir.relativeFilePath(fileName); tilesetVariant[QLatin1String("source")] = source; // Tileset is external, so no need to write any of the stuff below return tilesetVariant; } // Include a 'type' property if we are writing the tileset to its own file if (firstGid == 0) tilesetVariant[QLatin1String("type")] = QLatin1String("tileset"); tilesetVariant[QLatin1String("name")] = tileset.name(); tilesetVariant[QLatin1String("tilewidth")] = tileset.tileWidth(); tilesetVariant[QLatin1String("tileheight")] = tileset.tileHeight(); tilesetVariant[QLatin1String("spacing")] = tileset.tileSpacing(); tilesetVariant[QLatin1String("margin")] = tileset.margin(); tilesetVariant[QLatin1String("tilecount")] = tileset.tileCount(); tilesetVariant[QLatin1String("columns")] = tileset.columnCount(); const QColor bgColor = tileset.backgroundColor(); if (bgColor.isValid()) tilesetVariant[QLatin1String("backgroundcolor")] = colorToString(bgColor); addProperties(tilesetVariant, tileset.properties()); const QPoint offset = tileset.tileOffset(); if (!offset.isNull()) { QVariantMap tileOffset; tileOffset[QLatin1String("x")] = offset.x(); tileOffset[QLatin1String("y")] = offset.y(); tilesetVariant[QLatin1String("tileoffset")] = tileOffset; } if (tileset.orientation() != Tileset::Orthogonal || tileset.gridSize() != tileset.tileSize()) { QVariantMap grid; grid[QLatin1String("orientation")] = Tileset::orientationToString(tileset.orientation()); grid[QLatin1String("width")] = tileset.gridSize().width(); grid[QLatin1String("height")] = tileset.gridSize().height(); tilesetVariant[QLatin1String("grid")] = grid; } // Write the image element const QUrl &imageSource = tileset.imageSource(); if (!imageSource.isEmpty()) { const QString rel = toFileReference(imageSource, mMapDir); tilesetVariant[QLatin1String("image")] = rel; const QColor transColor = tileset.transparentColor(); if (transColor.isValid()) tilesetVariant[QLatin1String("transparentcolor")] = transColor.name(); tilesetVariant[QLatin1String("imagewidth")] = tileset.imageWidth(); tilesetVariant[QLatin1String("imageheight")] = tileset.imageHeight(); } // Write the properties, terrain, external image, object group and // animation for those tiles that have them. QVariantList tilesVariant; for (const Tile *tile : tileset.tiles()) { const Properties properties = tile->properties(); QVariantMap tileVariant; addProperties(tileVariant, properties); if (!tile->type().isEmpty()) tileVariant[QLatin1String("type")] = tile->type(); if (tile->terrain() != 0xFFFFFFFF) { QVariantList terrainIds; for (int j = 0; j < 4; ++j) terrainIds << QVariant(tile->cornerTerrainId(j)); tileVariant[QLatin1String("terrain")] = terrainIds; } if (tile->probability() != 1.0) tileVariant[QLatin1String("probability")] = tile->probability(); if (!tile->imageSource().isEmpty()) { const QString rel = toFileReference(tile->imageSource(), mMapDir); tileVariant[QLatin1String("image")] = rel; const QSize tileSize = tile->size(); if (!tileSize.isNull()) { tileVariant[QLatin1String("imagewidth")] = tileSize.width(); tileVariant[QLatin1String("imageheight")] = tileSize.height(); } } if (tile->objectGroup()) tileVariant[QLatin1String("objectgroup")] = toVariant(*tile->objectGroup()); if (tile->isAnimated()) { QVariantList frameVariants; for (const Frame &frame : tile->frames()) { QVariantMap frameVariant; frameVariant[QLatin1String("tileid")] = frame.tileId; frameVariant[QLatin1String("duration")] = frame.duration; frameVariants.append(frameVariant); } tileVariant[QLatin1String("animation")] = frameVariants; } if (!tileVariant.empty()) { tileVariant[QLatin1String("id")] = tile->id(); tilesVariant << tileVariant; } } if (!tilesVariant.empty()) tilesetVariant[QLatin1String("tiles")] = tilesVariant; // Write terrains if (tileset.terrainCount() > 0) { QVariantList terrainsVariant; for (int i = 0; i < tileset.terrainCount(); ++i) { Terrain *terrain = tileset.terrain(i); const Properties &properties = terrain->properties(); QVariantMap terrainVariant; terrainVariant[QLatin1String("name")] = terrain->name(); terrainVariant[QLatin1String("tile")] = terrain->imageTileId(); addProperties(terrainVariant, properties); terrainsVariant << terrainVariant; } tilesetVariant[QLatin1String("terrains")] = terrainsVariant; } return tilesetVariant; }
void CompileThreadPixel::thread() { EditableMap::Lights& lights = wmap->get_light_sources(); Tileset *ts = wmap->get_tileset_ptr(); size_t nlgt = lights.size(); int mw = wmap->get_width(); int mh = wmap->get_height(); int tw = ts->get_tile_width(); int th = ts->get_tile_height(); int w = mw * tw; int h = mh * th; short **pmap = wmap->get_map(); short **pdeco = wmap->get_decoration(); Point pr; for (size_t i = 0; i < nlgt; i++) { { ScopeMutex lock(mtx); finished_percent = 100 * (i + 1) / nlgt; } int r = lights[i]->radius; int lmaxsq = r * r; int lx = lights[i]->x; int ly = lights[i]->y; Point p2(static_cast<float>(lx * tw + (tw / 2)), static_cast<float>(ly * th + (th / 2))); int lsx = static_cast<int>(p2.x) - r; int lsy = static_cast<int>(p2.y) - r; int lex = static_cast<int>(p2.x) + r; int ley = static_cast<int>(p2.y) + r; if (lsx < 0) lsx = 0; if (lsy < 0) lsy = 0; if (lex > w) lex = w; if (ley > h) ley = h; int txs = lsx / tw; int txe = lex / tw; int tys = lsy / th; int tye = ley / th; for (int y = lsy; y < ley; y++) { for (int x = lsx; x < lex; x++) { int dindex = pdeco[y / th][x / tw]; if (dindex < 0) { lightmap[y][x * 4 + 3] = 0; } else { bool contact = false; Point p1(static_cast<float>(x), static_cast<float>(y)); float xd = p2.x - p1.x; float yd = p2.y - p1.y; float dist = xd * xd + yd * yd; if (dist < lmaxsq) { for (int tx = txs; tx < txe; tx++) { for (int ty = tys; ty < tye; ty++) { short index = pmap[ty][tx]; if (index >= 0) { if (ts->get_tile(index)->is_light_blocking()) { TileGraphic *tg = ts->get_tile(index)->get_tilegraphic(); TileGraphicGL *tggl = static_cast<TileGraphicGL *>(tg); if (tggl->get_bytes_per_pixel(0) < 4) { Point p1l(static_cast<float>(tx * tw), static_cast<float>(ty * th)); Point p2l(static_cast<float>(tx * tw), static_cast<float>((ty + 1) * th - 0.5f)); Point p1r(static_cast<float>((tx + 1) * tw - 0.5f), static_cast<float>(ty * th)); Point p2r(static_cast<float>((tx + 1) * tw - 0.5f), static_cast<float>((ty + 1) * th - 0.5f)); Point p1t(static_cast<float>(tx * tw), static_cast<float>(ty * th)); Point p2t(static_cast<float>((tx + 1) * tw - 0.5f), static_cast<float>(ty * th)); Point p1b(static_cast<float>(tx * tw), static_cast<float>((ty + 1) * th - 0.5f)); Point p2b(static_cast<float>((tx + 1) * tw - 0.5f), static_cast<float>((ty + 1) * th - 0.5f)); if (intersection(p1, p2, p1l, p2l, pr) || intersection(p1, p2, p1r, p2r, pr) || intersection(p1, p2, p1t, p2t, pr) || intersection(p1, p2, p1b, p2b, pr)) { contact = true; break; } } else { unsigned char *p = tggl->get_picture_array(0); for (int py = 0; py < th; py++) { for (int px = 0; px < tw; px++) { if (p[3] == 255) { Point p1v(static_cast<float>(tx * tw + px) + 0.5f, static_cast<float>(ty * th + py) - 0.5f); Point p2v(static_cast<float>(tx * tw + px) + 0.5f, static_cast<float>(ty * th + py) + 0.5f); Point p1h(static_cast<float>(tx * tw + px) - 0.5f, static_cast<float>(ty * th + py) + 0.5f); Point p2h(static_cast<float>(tx * tw + px) + 0.5f, static_cast<float>(ty * th + py) + 0.5f); if (intersection(p1, p2, p1v, p2v, pr) || intersection(p1, p2, p1h, p2h, pr)) { contact = true; break; } } p += 4; } if (contact) { break; } } if (contact) { break; } } } } } if (contact) { break; } } } else { contact = true; } if (!contact) { int v = static_cast<int>(sqrt(65025.0f * dist / lmaxsq)); if (v < lightmap[y][x * 4 + 3]) { lightmap[y][x * 4 + 3] = v; } } } } } } ScopeMutex lock(mtx); finished = true; }
void Map::ParseText(const string &text) { // Create a tiny xml document and use it to parse the text. tinyxml2::XMLDocument doc; doc.Parse(text.c_str()); // Check for parsing errors. if (doc.Error()) { has_error = true; error_code = TMX_PARSING_ERROR; error_text = doc.GetErrorStr1(); return; } tinyxml2::XMLNode *mapNode = doc.FirstChildElement("map"); tinyxml2::XMLElement* mapElem = mapNode->ToElement(); // Read the map attributes. version = mapElem->IntAttribute("version"); width = mapElem->IntAttribute("width"); height = mapElem->IntAttribute("height"); tile_width = mapElem->IntAttribute("tilewidth"); tile_height = mapElem->IntAttribute("tileheight"); next_object_id = mapElem->IntAttribute("nextobjectid"); if (mapElem->Attribute("backgroundcolor")) { background_color = mapElem->Attribute("backgroundcolor"); } // Read the orientation std::string orientationStr = mapElem->Attribute("orientation"); if (!orientationStr.compare("orthogonal")) { orientation = TMX_MO_ORTHOGONAL; } else if (!orientationStr.compare("isometric")) { orientation = TMX_MO_ISOMETRIC; } else if (!orientationStr.compare("staggered")) { orientation = TMX_MO_STAGGERED; } // Read the render order if (mapElem->Attribute("renderorder")) { std::string renderorderStr = mapElem->Attribute("renderorder"); if (!renderorderStr.compare("right-down")) { render_order = TMX_RIGHT_DOWN; } else if (!renderorderStr.compare("right-up")) { render_order = TMX_RIGHT_UP; } else if (!renderorderStr.compare("left-down")) { render_order = TMX_LEFT_DOWN; } else if (!renderorderStr.compare("left-down")) { render_order = TMX_LEFT_UP; } } const tinyxml2::XMLNode *node = mapElem->FirstChild(); while( node ) { // Read the map properties. if( strcmp( node->Value(), "properties" ) == 0 ) { properties.Parse(node); } // Iterate through all of the tileset elements. if( strcmp( node->Value(), "tileset" ) == 0 ) { // Allocate a new tileset and parse it. Tileset *tileset = new Tileset(); tileset->Parse(node->ToElement()); // Add the tileset to the list. tilesets.push_back(tileset); } // Iterate through all of the "layer" (tile layer) elements. if( strcmp( node->Value(), "layer" ) == 0 ) { // Allocate a new tile layer and parse it. TileLayer *tileLayer = new TileLayer(this); tileLayer->Parse(node); // Add the tile layer to the lists. tile_layers.push_back(tileLayer); layers.push_back(tileLayer); } // Iterate through all of the "imagelayer" (image layer) elements. if( strcmp( node->Value(), "imagelayer" ) == 0 ) { // Allocate a new image layer and parse it. ImageLayer *imageLayer = new ImageLayer(this); imageLayer->Parse(node); // Add the image layer to the lists. image_layers.push_back(imageLayer); layers.push_back(imageLayer); } // Iterate through all of the "objectgroup" (object layer) elements. if( strcmp( node->Value(), "objectgroup" ) == 0 ) { // Allocate a new object group and parse it. ObjectGroup *objectGroup = new ObjectGroup(this); objectGroup->Parse(node); // Add the object group to the lists. object_groups.push_back(objectGroup); layers.push_back(objectGroup); } node = node->NextSibling(); } }
void TileLayer::parseElement(tinyxml2::XMLElement* layerElement, Map* map) { // Get properties auto properties = layerElement->FirstChildElement("properties"); if(properties != 0) parseProperties(properties); m_name = layerElement->Attribute("name"); m_width = layerElement->UnsignedAttribute("width"); m_height = layerElement->UnsignedAttribute("height"); if (layerElement->Attribute("visible") != 0) { m_active = layerElement->IntAttribute("visible") == 0 ? false : true; } else m_active = true; // Parse data unsigned int x = 0; unsigned int y = 0; auto tile = layerElement->FirstChildElement("data")->FirstChildElement("tile"); while(tile != 0) { unsigned int gid = tile->UnsignedAttribute("gid"); // Go to the next "line" if (x >= map->GetWidth()) { x = 0; y++; } // Tile is "empty space" if (gid == 0) { x++; tile = tile->NextSiblingElement("tile"); continue; } // Read out the flags const bool flipped_horizontally = (gid & FLIPPED_HORIZONTALLY_FLAG) != 0; const bool flipped_vertically = (gid & FLIPPED_VERTICALLY_FLAG) != 0; const bool flipped_diagonally = (gid & FLIPPED_DIAGONALLY_FLAG) != 0; // Clear the flags gid &= ~(FLIPPED_HORIZONTALLY_FLAG | FLIPPED_VERTICALLY_FLAG | FLIPPED_DIAGONALLY_FLAG); // Find correct tileset for(int i = map->tilesets.size() - 1; i >= 0; --i) { Tileset* tileset = map->tilesets[i].get(); if (tileset->GetFirstGID() <= gid) { const pmath::Rect t(static_cast<float>(x * tileset->GetTileWidth()), static_cast<float>(y * tileset->GetTileHeight()), static_cast<float>(tileset->GetTileWidth()), static_cast<float>(tileset->GetTileHeight())); auto tile = new Tile(t); if (flipped_diagonally) { if (flipped_horizontally && flipped_vertically) { tile->transform.Rotate(90); tile->transform.SetScale(-1, tile->transform.GetScale().y); } else if (flipped_horizontally) { tile->transform.Rotate(90); } else if (flipped_vertically) { tile->transform.Rotate(-90); } else { tile->transform.Rotate(-90); tile->transform.SetScale(-1, tile->transform.GetScale().y); } } else { if (flipped_horizontally) tile->transform.SetScale(-1, tile->transform.GetScale().y); if (flipped_vertically) tile->transform.SetScale(tile->transform.GetScale().x, -1); } map->AddChild(tile); const pmath::Rect texCoords = tileset->GetTile(gid - tileset->GetFirstGID()); m_tiles.push_back(tile); m_spriteBatches.at(tileset->GetTexture())->AddSprite(&tile->transform, "", pmath::Vec4(1, 1, 1, 1), texCoords); x++; break; } } tile = tile->NextSiblingElement("tile"); } }