/* QuickTextureOverlay3d::applyTexture * Applies the current texture to all selected walls/flats *******************************************************************/ void QuickTextureOverlay3d::applyTexture() { // Check editor is associated if (!editor) return; // Get selection/hilight auto& selection = editor->selection(); // Go through items if (!selection.empty()) { for (unsigned a = 0; a < selection.size(); a++) { // Thing (skip) if (selection[a].type == MapEditor::ItemType::Thing) continue; // Floor else if (selection[a].type == MapEditor::ItemType::Floor && (sel_type == 0 || sel_type == 2)) { MapSector* sector = editor->map().getSector(selection[a].index); if (sector) sector->setStringProperty("texturefloor", textures[current_index].name); } // Ceiling else if (selection[a].type == MapEditor::ItemType::Ceiling && (sel_type == 0 || sel_type == 2)) { MapSector* sector = editor->map().getSector(selection[a].index); if (sector) sector->setStringProperty("textureceiling", textures[current_index].name); } // Wall else if (sel_type > 0) { MapSide* side = editor->map().getSide(selection[a].index); if (side) { // Upper if (selection[a].type == MapEditor::ItemType::WallTop) side->setStringProperty("texturetop", textures[current_index].name); // Middle else if (selection[a].type == MapEditor::ItemType::WallMiddle) side->setStringProperty("texturemiddle", textures[current_index].name); // Lower else if (selection[a].type == MapEditor::ItemType::WallBottom) side->setStringProperty("texturebottom", textures[current_index].name); } } } } }
/* MapArchClipboardItem::addLines * Copies [lines] and all related map structures *******************************************************************/ void MapArchClipboardItem::addLines(vector<MapLine*> lines) { // Get sectors and sides to copy vector<MapSector*> copy_sectors; vector<MapSide*> copy_sides; for (unsigned a = 0; a < lines.size(); a++) { MapSide* s1 = lines[a]->s1(); MapSide* s2 = lines[a]->s2(); // Front side if (s1) { copy_sides.push_back(s1); if (std::find(copy_sectors.begin(), copy_sectors.end(), s1->getSector()) == copy_sectors.end()) copy_sectors.push_back(s1->getSector()); } // Back side if (s2) { copy_sides.push_back(s2); if (std::find(copy_sectors.begin(), copy_sectors.end(), s2->getSector()) == copy_sectors.end()) copy_sectors.push_back(s2->getSector()); } } // Copy sectors for (unsigned a = 0; a < copy_sectors.size(); a++) { MapSector* copy = new MapSector(NULL); copy->copy(copy_sectors[a]); sectors.push_back(copy); } // Copy sides for (unsigned a = 0; a < copy_sides.size(); a++) { MapSide* copy = new MapSide(); copy->copy(copy_sides[a]); // Set relative sector for (unsigned b = 0; b < copy_sectors.size(); b++) { if (copy_sides[a]->getSector() == copy_sectors[b]) { copy->setSector(sectors[b]); break; } } sides.push_back(copy); } // Get vertices to copy (and determine midpoint) double min_x = 9999999; double max_x = -9999999; double min_y = 9999999; double max_y = -9999999; vector<MapVertex*> copy_verts; for (unsigned a = 0; a < lines.size(); a++) { MapVertex* v1 = lines[a]->v1(); MapVertex* v2 = lines[a]->v2(); // Add vertices to copy list if (std::find(copy_verts.begin(), copy_verts.end(), v1) == copy_verts.end()) copy_verts.push_back(v1); if (std::find(copy_verts.begin(), copy_verts.end(), v2) == copy_verts.end()) copy_verts.push_back(v2); // Update min/max if (v1->xPos() < min_x) min_x = v1->xPos(); if (v1->xPos() > max_x) max_x = v1->xPos(); if (v1->yPos() < min_y) min_y = v1->yPos(); if (v1->yPos() > max_y) max_y = v1->yPos(); if (v2->xPos() < min_x) min_x = v2->xPos(); if (v2->xPos() > max_x) max_x = v2->xPos(); if (v2->yPos() < min_y) min_y = v2->yPos(); if (v2->yPos() > max_y) max_y = v2->yPos(); } // Determine midpoint double mid_x = min_x + ((max_x - min_x) * 0.5); double mid_y = min_y + ((max_y - min_y) * 0.5); this->midpoint.set(mid_x, mid_y); // Copy vertices for (unsigned a = 0; a < copy_verts.size(); a++) { MapVertex* copy = new MapVertex(copy_verts[a]->xPos() - mid_x, copy_verts[a]->yPos() - mid_y); copy->copy(copy_verts[a]); vertices.push_back(copy); } // Copy lines for (unsigned a = 0; a < lines.size(); a++) { // Get relative sides MapSide* s1 = NULL; MapSide* s2 = NULL; bool s1_found = false; bool s2_found = !(lines[a]->s2()); for (unsigned b = 0; b < copy_sides.size(); b++) { if (lines[a]->s1() == copy_sides[b]) { s1 = sides[b]; s1_found = true; } if (lines[a]->s2() == copy_sides[b]) { s2 = sides[b]; s2_found = true; } if (s1_found && s2_found) break; } // Get relative vertices MapVertex* v1 = NULL; MapVertex* v2 = NULL; for (unsigned b = 0; b < copy_verts.size(); b++) { if (lines[a]->v1() == copy_verts[b]) v1 = vertices[b]; if (lines[a]->v2() == copy_verts[b]) v2 = vertices[b]; if (v1 && v2) break; } // Copy line MapLine* copy = new MapLine(v1, v2, s1, s2); copy->copy(lines[a]); this->lines.push_back(copy); } }
/* InfoOverlay3D::update * Updates the info text for the object of [item_type] at [item_index] * in [map] *******************************************************************/ void InfoOverlay3D::update(int item_index, int item_type, SLADEMap* map) { // Clear current info info.clear(); info2.clear(); // Setup variables current_type = item_type; texname = ""; texture = NULL; thing_icon = false; int map_format = theMapEditor->currentMapDesc().format; // Wall if (item_type == MapEditor::SEL_SIDE_BOTTOM || item_type == MapEditor::SEL_SIDE_MIDDLE || item_type == MapEditor::SEL_SIDE_TOP) { // Get line and side MapSide* side = map->getSide(item_index); if (!side) return; MapLine* line = side->getParentLine(); if (!line) return; object = side; // --- Line/side info --- info.push_back(S_FMT("Line #%d", line->getIndex())); if (side == line->s1()) info.push_back(S_FMT("Front Side #%d", side->getIndex())); else info.push_back(S_FMT("Back Side #%d", side->getIndex())); // Relevant flags string flags = ""; if (theGameConfiguration->lineBasicFlagSet("dontpegtop", line, map_format)) flags += "Upper Unpegged, "; if (theGameConfiguration->lineBasicFlagSet("dontpegbottom", line, map_format)) flags += "Lower Unpegged, "; if (theGameConfiguration->lineBasicFlagSet("blocking", line, map_format)) flags += "Blocking, "; if (!flags.IsEmpty()) flags.RemoveLast(2); info.push_back(flags); info.push_back(S_FMT("Length: %d", (int)line->getLength())); // Other potential info: special, sector# // --- Wall part info --- // Part if (item_type == MapEditor::SEL_SIDE_BOTTOM) info2.push_back("Lower Texture"); else if (item_type == MapEditor::SEL_SIDE_MIDDLE) info2.push_back("Middle Texture"); else info2.push_back("Upper Texture"); // Offsets if (theGameConfiguration->udmfNamespace() == "zdoom") { // Get x offset info int xoff = side->intProperty("offsetx"); double xoff_part = 0; if (item_type == MapEditor::SEL_SIDE_BOTTOM) xoff_part = side->floatProperty("offsetx_bottom"); else if (item_type == MapEditor::SEL_SIDE_MIDDLE) xoff_part = side->floatProperty("offsetx_mid"); else xoff_part = side->floatProperty("offsetx_top"); // Add x offset string string xoff_info; if (xoff_part == 0) xoff_info = S_FMT("%d", xoff); else if (xoff_part > 0) xoff_info = S_FMT("%1.2f (%d+%1.2f)", (double)xoff+xoff_part, xoff, xoff_part); else xoff_info = S_FMT("%1.2f (%d-%1.2f)", (double)xoff+xoff_part, xoff, -xoff_part); // Get y offset info int yoff = side->intProperty("offsety"); double yoff_part = 0; if (item_type == MapEditor::SEL_SIDE_BOTTOM) yoff_part = side->floatProperty("offsety_bottom"); else if (item_type == MapEditor::SEL_SIDE_MIDDLE) yoff_part = side->floatProperty("offsety_mid"); else yoff_part = side->floatProperty("offsety_top"); // Add y offset string string yoff_info; if (yoff_part == 0) yoff_info = S_FMT("%d", yoff); else if (yoff_part > 0) yoff_info = S_FMT("%1.2f (%d+%1.2f)", (double)yoff+yoff_part, yoff, yoff_part); else yoff_info = S_FMT("%1.2f (%d-%1.2f)", (double)yoff+yoff_part, yoff, -yoff_part); info2.push_back(S_FMT("Offsets: %s, %s", xoff_info, yoff_info)); } else { // Basic offsets info2.push_back(S_FMT("Offsets: %d, %d", side->intProperty("offsetx"), side->intProperty("offsety"))); } // ZDoom UDMF extras if (theGameConfiguration->udmfNamespace() == "zdoom") { // Scale double xscale, yscale; if (item_type == MapEditor::SEL_SIDE_BOTTOM) { xscale = side->floatProperty("scalex_bottom"); yscale = side->floatProperty("scaley_bottom"); } else if (item_type == MapEditor::SEL_SIDE_MIDDLE) { xscale = side->floatProperty("scalex_mid"); yscale = side->floatProperty("scaley_mid"); } else { xscale = side->floatProperty("scalex_top"); yscale = side->floatProperty("scaley_top"); } info2.push_back(S_FMT("Scale: %1.2fx, %1.2fx", xscale, yscale)); } else { info2.push_back(""); } // Height of this section of the wall // TODO this is wrong in the case of slopes, but slope support only // exists in the 3.1.1 branch fpoint2_t left_point, right_point; MapSide* other_side; if (side == line->s1()) { left_point = line->v1()->getPoint(0); right_point = line->v2()->getPoint(0); other_side = line->s2(); } else { left_point = line->v2()->getPoint(0); right_point = line->v1()->getPoint(0); other_side = line->s1(); } MapSector* this_sector = side->getSector(); MapSector* other_sector = NULL; if (other_side) other_sector = other_side->getSector(); double left_height, right_height; if (item_type == MapEditor::SEL_SIDE_MIDDLE && other_sector) { // A two-sided line's middle area is the smallest distance between // both sides' floors and ceilings, which is more complicated with // slopes. plane_t floor1 = this_sector->getFloorPlane(); plane_t floor2 = other_sector->getFloorPlane(); plane_t ceiling1 = this_sector->getCeilingPlane(); plane_t ceiling2 = other_sector->getCeilingPlane(); left_height = min(ceiling1.height_at(left_point), ceiling2.height_at(left_point)) - max(floor1.height_at(left_point), floor2.height_at(left_point)); right_height = min(ceiling1.height_at(right_point), ceiling2.height_at(right_point)) - max(floor1.height_at(right_point), floor2.height_at(right_point)); } else { plane_t top_plane, bottom_plane; if (item_type == MapEditor::SEL_SIDE_MIDDLE) { top_plane = this_sector->getCeilingPlane(); bottom_plane = this_sector->getFloorPlane(); } else { if (!other_sector) return; if (item_type == MapEditor::SEL_SIDE_TOP) { top_plane = this_sector->getCeilingPlane(); bottom_plane = other_sector->getCeilingPlane(); } else { top_plane = other_sector->getFloorPlane(); bottom_plane = this_sector->getFloorPlane(); } } left_height = top_plane.height_at(left_point) - bottom_plane.height_at(left_point); right_height = top_plane.height_at(right_point) - bottom_plane.height_at(right_point); } if (fabs(left_height - right_height) < 0.001) info2.push_back(S_FMT("Height: %d", (int)left_height)); else info2.push_back(S_FMT("Height: %d ~ %d", (int)left_height, (int)right_height)); // Texture if (item_type == MapEditor::SEL_SIDE_BOTTOM) texname = side->getTexLower(); else if (item_type == MapEditor::SEL_SIDE_MIDDLE) texname = side->getTexMiddle(); else texname = side->getTexUpper(); texture = theMapEditor->textureManager().getTexture(texname, theGameConfiguration->mixTexFlats()); } // Floor else if (item_type == MapEditor::SEL_FLOOR || item_type == MapEditor::SEL_CEILING) { // Get sector MapSector* sector = map->getSector(item_index); if (!sector) return; object = sector; // Get basic info int fheight = sector->intProperty("heightfloor"); int cheight = sector->intProperty("heightceiling"); // --- Sector info --- // Sector index info.push_back(S_FMT("Sector #%d", item_index)); // Sector height info.push_back(S_FMT("Total Height: %d", cheight - fheight)); // ZDoom UDMF extras /* if (theGameConfiguration->udmfNamespace() == "zdoom") { // Sector colour rgba_t col = sector->getColour(0, true); info.push_back(S_FMT("Colour: R%d, G%d, B%d", col.r, col.g, col.b)); } */ // --- Flat info --- // Height if (item_type == MapEditor::SEL_FLOOR) info2.push_back(S_FMT("Floor Height: %d", fheight)); else info2.push_back(S_FMT("Ceiling Height: %d", cheight)); // Light int light = sector->intProperty("lightlevel"); if (theGameConfiguration->udmfNamespace() == "zdoom") { // Get extra light info int fl = 0; bool abs = false; if (item_type == MapEditor::SEL_FLOOR) { fl = sector->intProperty("lightfloor"); abs = sector->boolProperty("lightfloorabsolute"); } else { fl = sector->intProperty("lightceiling"); abs = sector->boolProperty("lightceilingabsolute"); } // Set if absolute if (abs) { light = fl; fl = 0; } // Add info string if (fl == 0) info2.push_back(S_FMT("Light: %d", light)); else if (fl > 0) info2.push_back(S_FMT("Light: %d (%d+%d)", light+fl, light, fl)); else info2.push_back(S_FMT("Light: %d (%d-%d)", light+fl, light, -fl)); } else info2.push_back(S_FMT("Light: %d", light)); // ZDoom UDMF extras if (theGameConfiguration->udmfNamespace() == "zdoom") { // Offsets double xoff, yoff; if (item_type == MapEditor::SEL_FLOOR) { xoff = sector->floatProperty("xpanningfloor"); yoff = sector->floatProperty("ypanningfloor"); } else { xoff = sector->floatProperty("xpanningceiling"); yoff = sector->floatProperty("ypanningceiling"); } info2.push_back(S_FMT("Offsets: %1.2f, %1.2f", xoff, yoff)); // Scaling double xscale, yscale; if (item_type == MapEditor::SEL_FLOOR) { xscale = sector->floatProperty("xscalefloor"); yscale = sector->floatProperty("yscalefloor"); } else { xscale = sector->floatProperty("xscaleceiling"); yscale = sector->floatProperty("yscaleceiling"); } info2.push_back(S_FMT("Scale: %1.2fx, %1.2fx", xscale, yscale)); } // Texture if (item_type == MapEditor::SEL_FLOOR) texname = sector->getFloorTex(); else texname = sector->getCeilingTex(); texture = theMapEditor->textureManager().getFlat(texname, theGameConfiguration->mixTexFlats()); } // Thing else if (item_type == MapEditor::SEL_THING) { // index, type, position, sector, zpos, height?, radius? // Get thing MapThing* thing = map->getThing(item_index); if (!thing) return; object = thing; // Index info.push_back(S_FMT("Thing #%d", item_index)); // Position if (theMapEditor->currentMapDesc().format == MAP_HEXEN || theMapEditor->currentMapDesc().format == MAP_UDMF) info.push_back(S_FMT("Position: %d, %d, %d", (int)thing->xPos(), (int)thing->yPos(), (int)thing->floatProperty("height"))); else info.push_back(S_FMT("Position: %d, %d", (int)thing->xPos(), (int)thing->yPos())); // Type ThingType* tt = theGameConfiguration->thingType(thing->getType()); if (tt->getName() == "Unknown") info2.push_back(S_FMT("Type: %d", thing->getType())); else info2.push_back(S_FMT("Type: %s", tt->getName())); // Args if (theMapEditor->currentMapDesc().format == MAP_HEXEN || (theMapEditor->currentMapDesc().format == MAP_UDMF && theGameConfiguration->getUDMFProperty("arg0", MOBJ_THING))) { // Get thing args int args[5]; args[0] = thing->intProperty("arg0"); args[1] = thing->intProperty("arg1"); args[2] = thing->intProperty("arg2"); args[3] = thing->intProperty("arg3"); args[4] = thing->intProperty("arg4"); string argstr = tt->getArgsString(args); if (argstr.IsEmpty()) info2.push_back("No Args"); else info2.push_back(argstr); } // Sector int sector = map->sectorAt(thing->point()); if (sector >= 0) info2.push_back(S_FMT("In Sector #%d", sector)); else info2.push_back("No Sector"); // Texture texture = theMapEditor->textureManager().getSprite(tt->getSprite(), tt->getTranslation(), tt->getPalette()); if (!texture) { if (use_zeth_icons && tt->getZeth() >= 0) texture = theMapEditor->textureManager().getEditorImage(S_FMT("zethicons/zeth%02d", tt->getZeth())); if (!texture) texture = theMapEditor->textureManager().getEditorImage(S_FMT("thing/%s", tt->getIcon())); thing_icon = true; } texname = ""; } last_update = theApp->runTimer(); }
/* MapEditContext::paste3d * Pastes previously copied wall/flat/thing info to selection *******************************************************************/ void Edit3D::paste(CopyType type) { // Begin undo step string ptype = "Paste Properties"; if (type == CopyType::TexType) ptype = "Paste Texture/Type"; undo_manager_->beginRecord(ptype); // Go through items auto& selection = context_.selection(); for (auto& item : selection.selectionOrHilight()) { // Wall if (MapEditor::baseItemType(item.type) == ItemType::Side) { MapSide* side = context_.map().getSide(item.index); undo_manager_->recordUndoStep(new MapEditor::PropertyChangeUS(side)); // Upper wall if (item.type == ItemType::WallTop) { // Texture if (type == CopyType::TexType) side->setStringProperty("texturetop", copy_texture_); } // Middle wall else if (item.type == ItemType::WallMiddle) { // Texture if (type == CopyType::TexType) side->setStringProperty("texturemiddle", copy_texture_); } // Lower wall else if (item.type == ItemType::WallBottom) { // Texture if (type == CopyType::TexType) side->setStringProperty("texturebottom", copy_texture_); } } // Flat else if (item.type == ItemType::Floor || item.type == ItemType::Ceiling) { MapSector* sector = context_.map().getSector(item.index); undo_manager_->recordUndoStep(new MapEditor::PropertyChangeUS(sector)); // Floor if (item.type == ItemType::Floor) { // Texture if (type == CopyType::TexType) sector->setStringProperty("texturefloor", copy_texture_); } // Ceiling if (item.type == ItemType::Ceiling) { // Texture if (type == CopyType::TexType) sector->setStringProperty("textureceiling", copy_texture_); } } // Thing else if (item.type == ItemType::Thing) { MapThing* thing = context_.map().getThing(item.index); undo_manager_->recordUndoStep(new MapEditor::PropertyChangeUS(thing)); // Type if (type == CopyType::TexType) thing->setIntProperty("type", copy_thing_.getType()); } } // Editor message if (type == CopyType::TexType) { if (selection.hilight().type == ItemType::Thing) context_.addEditorMessage("Pasted Thing Type"); else context_.addEditorMessage("Pasted Texture"); } undo_manager_->endRecord(true); }
/* Edit3D::changeOffset * Changes the offset of selected walls by [amount]. X axis if [x] is * true, otherwise Y axis *******************************************************************/ void Edit3D::changeOffset(int amount, bool x) const { // Get items to process vector<MapEditor::Item> items; auto& selection_3d = context_.selection(); auto hilight_3d = context_.hilightItem(); if (selection_3d.empty()) { if (hilight_3d.index >= 0 && hilight_3d.type != ItemType::Thing) items.push_back(hilight_3d); } else { for (unsigned a = 0; a < selection_3d.size(); a++) { if (selection_3d[a].type != ItemType::Thing) items.push_back(selection_3d[a]); } } if (items.empty()) return; // Begin undo level context_.beginUndoRecordLocked("Change Offset", true, false, false); // Go through items vector<int> done; bool changed = false; for (unsigned a = 0; a < items.size(); a++) { // Wall if (items[a].type >= ItemType::WallTop && items[a].type <= ItemType::WallBottom) { MapSide* side = context_.map().getSide(items[a].index); // If offsets are linked, just change the whole side offset if (link_offset_) { // Check we haven't processed this side already if (VECTOR_EXISTS(done, items[a].index)) continue; // Change the appropriate offset if (x) { int offset = side->intProperty("offsetx"); side->setIntProperty("offsetx", offset + amount); } else { int offset = side->intProperty("offsety"); side->setIntProperty("offsety", offset + amount); } // Add to done list done.push_back(items[a].index); } // Unlinked offsets else { // Build property string (offset[x/y]_[top/mid/bottom]) string ofs = "offsetx"; if (!x) ofs = "offsety"; if (items[a].type == ItemType::WallBottom) ofs += "_bottom"; else if (items[a].type == ItemType::WallTop) ofs += "_top"; else ofs += "_mid"; // Change the offset int offset = side->floatProperty(ofs); side->setFloatProperty(ofs, offset + amount); } changed = true; } // Flat (UDMF only) else { MapSector* sector = context_.map().getSector(items[a].index); if (Game::configuration().featureSupported(Game::UDMFFeature::FlatPanning)) { if (items[a].type == ItemType::Floor) { if (x) { double offset = sector->floatProperty("xpanningfloor"); sector->setFloatProperty("xpanningfloor", offset + amount); } else { double offset = sector->floatProperty("ypanningfloor"); sector->setFloatProperty("ypanningfloor", offset + amount); } changed = true; } else if (items[a].type == ItemType::Ceiling) { if (x) { double offset = sector->floatProperty("xpanningceiling"); sector->setFloatProperty("xpanningceiling", offset + amount); } else { double offset = sector->floatProperty("ypanningceiling"); sector->setFloatProperty("ypanningceiling", offset + amount); } changed = true; } } } } // End undo level context_.endUndoRecord(changed); // Editor message if (items.size() > 0 && changed) { string axis = "X"; if (!x) axis = "Y"; if (amount > 0) context_.addEditorMessage(S_FMT("%s offset increased by %d", axis, amount)); else context_.addEditorMessage(S_FMT("%s offset decreased by %d", axis, -amount)); } }
/* LineInfoOverlay::update * Updates the overlay with info from [line] *******************************************************************/ void LineInfoOverlay::update(MapLine* line) { if (!line) return; //info.clear(); string info_text; int map_format = MapEditor::editContext().mapDesc().format; // General line info if (Global::debug) info_text += (S_FMT("Line #%d (%d)\n", line->getIndex(), line->getId())); else info_text += (S_FMT("Line #%d\n", line->getIndex())); info_text += (S_FMT("Length: %d\n", MathStuff::round(line->getLength()))); // Line special int as_id = line->intProperty("special"); if (line->props().propertyExists("macro")) { int macro = line->intProperty("macro"); info_text += (S_FMT("Macro: #%d\n", macro)); } else info_text += (S_FMT("Special: %d (%s)\n", as_id, Game::configuration().actionSpecialName(as_id))); // Line trigger if (map_format == MAP_HEXEN || map_format == MAP_UDMF) info_text += (S_FMT("Trigger: %s\n", Game::configuration().spacTriggerString(line, map_format))); // Line args (or sector tag) if (map_format == MAP_HEXEN || map_format == MAP_UDMF) { int args[5]; args[0] = line->intProperty("arg0"); args[1] = line->intProperty("arg1"); args[2] = line->intProperty("arg2"); args[3] = line->intProperty("arg3"); args[4] = line->intProperty("arg4"); string argxstr[2]; argxstr[0] = line->stringProperty("arg0str"); argxstr[1] = line->stringProperty("arg1str"); string argstr = Game::configuration().actionSpecial(as_id).argSpec().stringDesc(args, argxstr); if (!argstr.IsEmpty()) info_text += (S_FMT("%s", argstr)); else info_text += ("No Args"); } else info_text += (S_FMT("Sector Tag: %d", line->intProperty("arg0"))); // Line flags if (map_format != MAP_UDMF) info_text += (S_FMT("\nFlags: %s", Game::configuration().lineFlagsString(line))); // Setup text box text_box->setText(info_text); // Check needed textures int needed_tex = line->needsTexture(); // Front side MapSide* s = line->s1(); if (s) { int xoff = s->intProperty("offsetx"); int yoff = s->intProperty("offsety"); side_front.exists = true; if (Global::debug) side_front.info = S_FMT("Front Side #%d (%d) (Sector %d)", s->getIndex(), s->getId(), s->getSector()->getIndex()); else side_front.info = S_FMT("Front Side #%d (Sector %d)", s->getIndex(), s->getSector()->getIndex()); side_front.offsets = S_FMT("Offsets: (%d, %d)", xoff, yoff); side_front.tex_upper = s->getTexUpper(); side_front.tex_middle = s->getTexMiddle(); side_front.tex_lower = s->getTexLower(); side_front.needs_lower = ((needed_tex & TEX_FRONT_LOWER) > 0); side_front.needs_middle = ((needed_tex & TEX_FRONT_MIDDLE) > 0); side_front.needs_upper = ((needed_tex & TEX_FRONT_UPPER) > 0); } else side_front.exists = false; // Back side s = line->s2(); if (s) { int xoff = s->intProperty("offsetx"); int yoff = s->intProperty("offsety"); side_back.exists = true; if (Global::debug) side_back.info = S_FMT("Back Side #%d (%d) (Sector %d)", s->getIndex(), s->getId(), s->getSector()->getIndex()); else side_back.info = S_FMT("Back Side #%d (Sector %d)", s->getIndex(), s->getSector()->getIndex()); side_back.offsets = S_FMT("Offsets: (%d, %d)", xoff, yoff); side_back.tex_upper = s->getTexUpper(); side_back.tex_middle = s->getTexMiddle(); side_back.tex_lower = s->getTexLower(); side_back.needs_lower = ((needed_tex & TEX_BACK_LOWER) > 0); side_back.needs_middle = ((needed_tex & TEX_BACK_MIDDLE) > 0); side_back.needs_upper = ((needed_tex & TEX_BACK_UPPER) > 0); } else side_back.exists = false; }