Beispiel #1
0
	bool fixProblem(unsigned index, unsigned fix_type, MapEditor* editor)
	{
		if (index >= things.size())
			return false;

		if (fix_type == 0)
		{
			MapThing* thing = things[index];
			MapLine* line = lines[index];

			// Get nearest line point to thing
			fpoint2_t np = MathStuff::closestPointOnLine(thing->xPos(), thing->yPos(), line->x1(), line->y1(), line->x2(), line->y2());

			// Get distance to move
			double r = theGameConfiguration->thingType(thing->getType())->getRadius();
			double dist = MathStuff::distance(0, 0, r, r);

			editor->beginUndoRecord("Move Thing", true, false, false);

			// Move along line direction
			map->moveThing(thing->getIndex(), np.x - (line->frontVector().x * dist), np.y - (line->frontVector().y * dist));

			editor->endUndoRecord();

			return true;
		}

		return false;
	}
Beispiel #2
0
void MapSpecials::applyLineSlopeThing(SLADEMap* map, MapThing* thing)
{
	int lineid = thing->intProperty("arg0");
	if (!lineid)
	{
		LOG_MESSAGE(1, "Ignoring line slope thing %d with no lineid argument", thing->getIndex());
		return;
	}

	// These are computed on first use, to avoid extra work if no lines match
	MapSector* containing_sector = nullptr;
	double thingz;

	vector<MapLine*> lines;
	map->getLinesById(lineid, lines);
	for (unsigned b = 0; b < lines.size(); b++)
	{
		MapLine* line = lines[b];

		// Line slope things only affect the sector on the side of the line
		// that faces the thing
		double side = MathStuff::lineSide(thing->point(), line->seg());
		MapSector* target = nullptr;
		if (side < 0)
			target = line->backSector();
		else if (side > 0)
			target = line->frontSector();
		if (!target)
			continue;

		// Need to know the containing sector's height to find the thing's true height
		if (!containing_sector)
		{
			int containing_sector_idx = map->sectorAt(thing->point());
			if (containing_sector_idx < 0)
				return;
			containing_sector = map->getSector(containing_sector_idx);
			thingz = (
				containing_sector->getPlane<p>().height_at(thing->point())
				+ thing->floatProperty("height")
			);
		}

		// Three points: endpoints of the line, and the thing itself
		plane_t target_plane = target->getPlane<p>();
		fpoint3_t p1(lines[b]->x1(), lines[b]->y1(), target_plane.height_at(lines[b]->point1()));
		fpoint3_t p2(lines[b]->x2(), lines[b]->y2(), target_plane.height_at(lines[b]->point2()));
		fpoint3_t p3(thing->xPos(), thing->yPos(), thingz);
		target->setPlane<p>(MathStuff::planeFromTriangle(p1, p2, p3));
	}
}
Beispiel #3
0
/* MapSector::updateBBox
 * Calculates the sector's bounding box
 *******************************************************************/
void MapSector::updateBBox()
{
	// Reset bounding box
	bbox.reset();

	for (unsigned a = 0; a < connected_sides.size(); a++)
	{
		MapLine* line = connected_sides[a]->getParentLine();
		if (!line) continue;
		bbox.extend(line->v1()->xPos(), line->v1()->yPos());
		bbox.extend(line->v2()->xPos(), line->v2()->yPos());
	}

	text_point.set(0, 0);
	setGeometryUpdated();
}
Beispiel #4
0
	bool fixProblem(unsigned index, unsigned fix_type, MapEditor* editor)
	{
		if (index >= lines.size())
			return false;

		MapLine* line = map->getLine(lines[index]);
		if (line->s2())
		{
			// Flip
			if (fix_type == 0)
			{
				line->flip();
				return true;
			}

			// Create sector
			else if (fix_type == 1)
			{
				fpoint2_t pos = line->dirTabPoint(0.1);
				editor->createSector(pos.x, pos.y);
				doCheck();
				return true;
			}
		}
		else
		{
			// Delete
			if (fix_type == 0)
			{
				map->removeLine(line);
				doCheck();
				return true;
			}

			// Create sector
			else if (fix_type == 1)
			{
				fpoint2_t pos = line->dirTabPoint(0.1);
				editor->createSector(pos.x, pos.y);
				doCheck();
				return true;
			}
		}

		return false;
	}
Beispiel #5
0
/* MapLine::copy
 * Copies another map object [c]
 *******************************************************************/
void MapLine::copy(MapObject* c)
{
	if(getObjType() != c->getObjType())
		return;

	MapObject::copy(c);

	MapLine* l = static_cast<MapLine*>(c);

	if(side1 && l->side1)
		side1->copy(l->side1);

	if(side2 && l->side2)
		side2->copy(l->side2);

	setIntProperty("special", l->intProperty("special"));
}
Beispiel #6
0
/* MapSector::isWithin
 * Returns true if the point is inside the sector
 *******************************************************************/
bool MapSector::isWithin(fpoint2_t point)
{
	// Check with bbox first
	if (!boundingBox().contains(point))
		return false;

	// Find nearest line in the sector
	double dist;
	double min_dist = 999999;
	MapLine* nline = nullptr;
	for (unsigned a = 0; a < connected_sides.size(); a++)
	{
		// Calculate distance to line
		//if (connected_sides[a] == NULL) {
		//	LOG_MESSAGE(3, "Warning: connected side #%i is a NULL pointer!", a);
		//	continue;
		//} else if (connected_sides[a]->getParentLine() == NULL) {
		//	LOG_MESSAGE(3, "Warning: connected side #%i has a NULL pointer parent line!", connected_sides[a]->getIndex());
		//	continue;
		//}
		dist = connected_sides[a]->getParentLine()->distanceTo(point);

		// Check distance
		if (dist < min_dist)
		{
			nline = connected_sides[a]->getParentLine();
			min_dist = dist;
		}
	}

	// No nearest (shouldn't happen)
	if (!nline)
		return false;

	// Check the side of the nearest line
	double side = MathStuff::lineSide(point, nline->seg());
	if (side >= 0 && nline->frontSector() == this)
		return true;
	else if (side < 0 && nline->backSector() == this)
		return true;
	else
		return false;
}
Beispiel #7
0
/** Removes the map entry of the given font.
 *  If the font is locked (because it's already in use) nothing happens.
 *  @param[in] mapline parsed font data
 *  @return true if entry has been removed */
bool FontMap::remove (const MapLine &mapline) {
	bool removed = false;
	if (!mapline.texname().empty()) {
		vector<Subfont*> subfonts;
		if (mapline.sfd())
			mapline.sfd()->subfonts(subfonts);
		else
			subfonts.push_back(nullptr);
		for (const Subfont *subfont : subfonts) {
			string fontname = mapline.texname()+(subfont ? subfont->id() : "");
			auto it = _entries.find(fontname);
			if (it != _entries.end() && !it->second->locked) {
				_entries.erase(it);
				removed = true;
			}
		}
	}
	return removed;
}
Beispiel #8
0
/* MapSector::distanceTo
 * Returns the minimum distance from the point to the closest line in
 * the sector
 *******************************************************************/
double MapSector::distanceTo(fpoint2_t point, double maxdist)
{
	// Init
	if (maxdist < 0)
		maxdist = 9999999;

	// Check bounding box first
	if (!bbox.is_valid())
		updateBBox();
	double min_dist = 9999999;
	double dist = MathStuff::distanceToLine(point, bbox.left_side());
	if (dist < min_dist) min_dist = dist;
	dist = MathStuff::distanceToLine(point, bbox.top_side());
	if (dist < min_dist) min_dist = dist;
	dist = MathStuff::distanceToLine(point, bbox.right_side());
	if (dist < min_dist) min_dist = dist;
	dist = MathStuff::distanceToLine(point, bbox.bottom_side());
	if (dist < min_dist) min_dist = dist;

	if (min_dist > maxdist && !bbox.contains(point))
		return -1;

	// Go through connected sides
	for (unsigned a = 0; a < connected_sides.size(); a++)
	{
		// Get side parent line
		MapLine* line = connected_sides[a]->getParentLine();
		if (!line) continue;

		// Check distance
		dist = line->distanceTo(point);
		if (dist < min_dist)
			min_dist = dist;
	}

	return min_dist;
}
Beispiel #9
0
/* MapSector::getVertices
 * Adds all vertices that are part of the sector to [list]
 *******************************************************************/
bool MapSector::getVertices(vector<MapObject*>& list)
{
	// Go through connected sides
	MapLine* line;
	for (unsigned a = 0; a < connected_sides.size(); a++)
	{
		line = connected_sides[a]->getParentLine();

		// Add the side's parent line's vertices to the list if they doesn't already exist
		if (line->v1() && std::find(list.begin(), list.end(), line->v1()) == list.end())
			list.push_back(line->v1());
		if (line->v2() && std::find(list.begin(), list.end(), line->v2()) == list.end())
			list.push_back(line->v2());
	}

	return true;
}
Beispiel #10
0
	void doCheck()
	{
		double radius;

		// Get list of lines to check
		vector<MapLine*> check_lines;
		MapLine* line;
		for (unsigned a = 0; a < map->nLines(); a++)
		{
			line = map->getLine(a);

			// Skip if line is 2-sided and not blocking
			if (line->s2() && !theGameConfiguration->lineBasicFlagSet("blocking", line, map->currentFormat()))
				continue;

			check_lines.push_back(line);
		}

		// Go through things
		for (unsigned a = 0; a < map->nThings(); a++)
		{
			MapThing* thing = map->getThing(a);
			ThingType* tt = theGameConfiguration->thingType(thing->getType());

			// Skip if not a solid thing
			if (!tt->isSolid())
				continue;

			radius = tt->getRadius() - 1;

			// Go through lines
			for (unsigned b = 0; b < check_lines.size(); b++)
			{
				line = check_lines[b];

				// Check intersection
				if (MathStuff::boxLineIntersect(thing->xPos() - radius, thing->yPos() - radius,
					thing->xPos() + radius, thing->yPos() + radius,
					line->x1(), line->y1(), line->x2(), line->y2()))
				{
					things.push_back(thing);
					lines.push_back(line);
					break;
				}
			}
		}
	}
Beispiel #11
0
/** Appends given map line data to the font map if there is no entry for the corresponding
 *  font in the map yet.
 *  @param[in] mapline parsed font data
 *  @return true if data has been appended */
bool FontMap::append (const MapLine &mapline) {
	bool appended = false;
	if (!mapline.texname().empty()) {
		if (!mapline.fontfname().empty() || !mapline.encname().empty()) {
			vector<Subfont*> subfonts;
			if (mapline.sfd())
				mapline.sfd()->subfonts(subfonts);
			else
				subfonts.push_back(nullptr);
			for (Subfont *subfont : subfonts) {
				string fontname = mapline.texname()+(subfont ? subfont->id() : "");
				auto it = _entries.find(fontname);
				if (it == _entries.end()) {
					_entries.emplace(fontname, util::make_unique<Entry>(mapline, subfont));
					appended = true;
				}
			}
		}
	}
	return appended;
}
Beispiel #12
0
/** Replaces the map data of the given font.
 *  If the font is locked (because it's already in use) nothing happens.
 *  @param[in] mapline parsed font data
 *  @return true if data has been replaced */
bool FontMap::replace (const MapLine &mapline) {
	if (mapline.texname().empty())
		return false;
	if (mapline.fontfname().empty() && mapline.encname().empty())
		return remove(mapline);

	vector<Subfont*> subfonts;
	if (mapline.sfd())
		mapline.sfd()->subfonts(subfonts);
	else
		subfonts.push_back(nullptr);
	for (Subfont *subfont : subfonts) {
		string fontname = mapline.texname()+(subfont ? subfont->id() : "");
		auto it = _entries.find(fontname);
		if (it == _entries.end())
			_entries.emplace(fontname, util::make_unique<Entry>(mapline, subfont));
		else if (!it->second->locked)
			*it->second = Entry(mapline, subfont);
	}
	return true;
}
Beispiel #13
0
/* MapArchClipboardItem::pasteToMap
 * Pastes copied architecture to [map] at [position]
 *******************************************************************/
vector<MapVertex*> MapArchClipboardItem::pasteToMap(SLADEMap* map, fpoint2_t position)
{
    std::map<MapVertex*, MapVertex*> vertMap;
    std::map<MapSector*, MapSector*> sectMap;
    std::map<MapSide*, MapSide*> sideMap;
    // Not used yet...
    // std::map<MapLine*, MapLine*> lineMap;

    // Add vertices
    vector<MapVertex*> new_verts;
    for (unsigned a = 0; a < vertices.size(); a++)
    {
        new_verts.push_back(map->createVertex(position.x + vertices[a]->xPos(), position.y + vertices[a]->yPos()));
        new_verts.back()->copy(vertices[a]);
        vertMap[vertices[a]] = new_verts.back();
    }

    // Add sectors
    for (unsigned a = 0; a < sectors.size(); a++)
    {
        MapSector* new_sector = map->createSector();
        new_sector->copy(sectors[a]);
        sectMap[sectors[a]] = new_sector;
    }

    // Add sides
    int first_new_side = map->nSides();
    for (unsigned a = 0; a < sides.size(); a++)
    {
        // Get relative sector
        MapSector* sector = findInMap(sectMap, sides[a]->getSector());

        MapSide* new_side = map->createSide(sector);
        new_side->copy(sides[a]);
        sideMap[sides[a]] = new_side;
    }

    // Add lines
    int first_new_line = map->nLines();
    for (unsigned a = 0; a < lines.size(); a++)
    {
        // Get relative vertices
        MapVertex* v1 = findInMap(vertMap, lines[a]->v1());
        MapVertex* v2 = findInMap(vertMap, lines[a]->v2());

        if (!v1)
        {
            wxLogMessage("no v1");
            continue;
        }
        if (!v2)
        {
            wxLogMessage("no v2");
        }

        MapLine* newline = map->createLine(v1, v2, true);
        newline->copy(lines[a]);
        // lineMap[lines[a]] = newline;

        // Set relative sides
        bool s1 = false;
        bool s2 = !(lines[a]->s2());
        MapSide* newS1 = findInMap(sideMap, lines[a]->s1());
        MapSide* newS2 = findInMap(sideMap, lines[a]->s2());
        if(newS1)
            newline->setS1(newS1);
        if(newS2)
            newline->setS2(newS2);

        // Set important flags (needed when copying from Doom/Hexen format to UDMF)
        // Won't be needed when proper map format conversion stuff is implemented
        theGameConfiguration->setLineBasicFlag(
            "twosided",
            newline,
            map->currentFormat(),
            (newS1 && newS2)
        );
        theGameConfiguration->setLineBasicFlag(
            "blocking",
            newline,
            map->currentFormat(),
            !newS2
        );
    }

    // TODO:
    // - Split lines
    // - Merge lines

    //// Fix sector references
    //// TODO: figure out what lines are 'outside' on copy, only fix said lines
    //for (unsigned a = first_new_line; a < map->nLines(); a++)
    //{
    //	MapLine* line = map->getLine(a);
    //	MapSector* sec1 = map->getLineSideSector(line, true);
    //	MapSector* sec2 = map->getLineSideSector(line, false);
    //	int i1 = -1;
    //	int i2 = -2;
    //	if (sec1) i1 = sec1->getIndex();
    //	if (sec2) i2 = sec2->getIndex();
    //	map->setLineSector(a, i1, true);
    //	map->setLineSector(a, i2, false);
    //}

    return new_verts;
}
Beispiel #14
0
/* 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);
    }
}
Beispiel #15
0
/* MapArchClipboardItem::pasteToMap
 * Pastes copied architecture to [map] at [position]
 *******************************************************************/
vector<MapVertex*> MapArchClipboardItem::pasteToMap(SLADEMap* map, fpoint2_t position)
{
	std::map<MapVertex*, MapVertex*> vertMap;
	std::map<MapSector*, MapSector*> sectMap;
	std::map<MapSide*, MapSide*> sideMap;
	// Not used yet...
	// std::map<MapLine*, MapLine*> lineMap;

	// Add vertices
	vector<MapVertex*> new_verts;
	for (unsigned a = 0; a < vertices.size(); a++)
	{
		new_verts.push_back(map->createVertex(position.x + vertices[a]->xPos(), position.y + vertices[a]->yPos()));
		new_verts.back()->copy(vertices[a]);
		vertMap[vertices[a]] = new_verts.back();
	}

	// Add sectors
	for (unsigned a = 0; a < sectors.size(); a++)
	{
		MapSector* new_sector = map->createSector();
		new_sector->copy(sectors[a]);
		sectMap[sectors[a]] = new_sector;
	}

	// Add sides
	int first_new_side = map->nSides();
	for (unsigned a = 0; a < sides.size(); a++)
	{
		// Get relative sector
		MapSector* sector = findInMap(sectMap, sides[a]->getSector());

		MapSide* new_side = map->createSide(sector);
		new_side->copy(sides[a]);
		sideMap[sides[a]] = new_side;
	}

	// Add lines
	int first_new_line = map->nLines();
	for (unsigned a = 0; a < lines.size(); a++)
	{
		// Get relative vertices
		MapVertex* v1 = findInMap(vertMap, lines[a]->v1());
		MapVertex* v2 = findInMap(vertMap, lines[a]->v2());

		if (!v1)
		{
			wxLogMessage("no v1");
			continue;
		}
		if (!v2)
		{
			wxLogMessage("no v2");
		}

		MapLine* newline = map->createLine(v1, v2, true);
		newline->copy(lines[a]);
		// lineMap[lines[a]] = newline;

		// Set relative sides
		bool s1 = false;
		bool s2 = !(lines[a]->s2());
		MapSide* newS1 = findInMap(sideMap, lines[a]->s1());
		MapSide* newS2 = findInMap(sideMap, lines[a]->s2());
		if(newS1)
			newline->setS1(newS1);
		if(newS2)
			newline->setS2(newS2);
	}

	// TODO:
	// - Split lines
	// - Merge lines

	// Fix sector references
	// TODO: figure out what lines are 'outside' on copy, only fix said lines
	for (unsigned a = first_new_line; a < map->nLines(); a++)
	{
		MapLine* line = map->getLine(a);
		MapSector* sec1 = map->getLineSideSector(line, true);
		MapSector* sec2 = map->getLineSideSector(line, false);
		int i1 = -1;
		int i2 = -2;
		if (sec1) i1 = sec1->getIndex();
		if (sec2) i2 = sec2->getIndex();
		map->setLineSector(a, i1, true);
		map->setLineSector(a, i2, false);
	}

	return new_verts;
}
Beispiel #16
0
/* 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();
}
Beispiel #17
0
/* MapSpecials::processEternitySlopes
* Process Eternity slope specials
*******************************************************************/
void MapSpecials::processEternitySlopes(SLADEMap* map)
{
	// Eternity plans on having a few slope mechanisms,
	// which must be evaluated in a specific order.
	//  - Plane_Align, in line order
	//  - vertex triangle slopes, in sector order (wip)
	//  - Plane_Copy, in line order

	// First things first: reset every sector to flat planes
	for(unsigned a = 0; a < map->nSectors(); a++)
	{
		MapSector* target = map->getSector(a);
		target->setPlane<FLOOR_PLANE>(plane_t::flat(target->getPlaneHeight<FLOOR_PLANE>()));
		target->setPlane<CEILING_PLANE>(plane_t::flat(target->getPlaneHeight<CEILING_PLANE>()));
	}

	// Plane_Align (line special 181)
	for(unsigned a = 0; a < map->nLines(); a++)
	{
		MapLine* line = map->getLine(a);
		if(line->getSpecial() != 181)
			continue;

		MapSector* sector1 = line->frontSector();
		MapSector* sector2 = line->backSector();
		if(!sector1 || !sector2)
		{
			LOG_MESSAGE(1, "Ignoring Plane_Align on one-sided line %d", line->getIndex());
			continue;
		}
		if(sector1 == sector2)
		{
			LOG_MESSAGE(1, "Ignoring Plane_Align on line %d, which has the same sector on both sides", line->getIndex());
			continue;
		}

		int floor_arg = line->intProperty("arg0");
		if(floor_arg == 1)
			applyPlaneAlign<FLOOR_PLANE>(line, sector1, sector2);
		else if(floor_arg == 2)
			applyPlaneAlign<FLOOR_PLANE>(line, sector2, sector1);

		int ceiling_arg = line->intProperty("arg1");
		if(ceiling_arg == 1)
			applyPlaneAlign<CEILING_PLANE>(line, sector1, sector2);
		else if(ceiling_arg == 2)
			applyPlaneAlign<CEILING_PLANE>(line, sector2, sector1);
	}

	// Plane_Copy
	vector<MapSector*> sectors;
	for(unsigned a = 0; a < map->nLines(); a++)
	{
		MapLine* line = map->getLine(a);
		if(line->getSpecial() != 118)
			continue;

		int tag;
		MapSector* front = line->frontSector();
		MapSector* back = line->backSector();
		if((tag = line->intProperty("arg0")))
		{
			sectors.clear();
			map->getSectorsByTag(tag, sectors);
			if(sectors.size())
				front->setFloorPlane(sectors[0]->getFloorPlane());
		}
		if((tag = line->intProperty("arg1")))
		{
			sectors.clear();
			map->getSectorsByTag(tag, sectors);
			if(sectors.size())
				front->setCeilingPlane(sectors[0]->getCeilingPlane());
		}
		if((tag = line->intProperty("arg2")))
		{
			sectors.clear();
			map->getSectorsByTag(tag, sectors);
			if(sectors.size())
				back->setFloorPlane(sectors[0]->getFloorPlane());
		}
		if((tag = line->intProperty("arg3")))
		{
			sectors.clear();
			map->getSectorsByTag(tag, sectors);
			if(sectors.size())
				back->setCeilingPlane(sectors[0]->getCeilingPlane());
		}

		// The fifth "share" argument copies from one side of the line to the
		// other
		if(front && back)
		{
			int share = line->intProperty("arg4");

			if((share & 3) == 1)
				back->setFloorPlane(front->getFloorPlane());
			else if((share & 3) == 2)
				front->setFloorPlane(back->getFloorPlane());

			if((share & 12) == 4)
				back->setCeilingPlane(front->getCeilingPlane());
			else if((share & 12) == 8)
				front->setCeilingPlane(back->getCeilingPlane());
		}
	}
}
Beispiel #18
0
/* MapSpecials::processZDoomSlopes
 * Process ZDoom slope specials
 *******************************************************************/
void MapSpecials::processZDoomSlopes(SLADEMap* map)
{
	// ZDoom has a variety of slope mechanisms, which must be evaluated in a
	// specific order.
	//  - Plane_Align, in line order
	//  - line slope + sector tilt + vavoom, in thing order
	//  - slope copy things, in thing order
	//  - overwrite vertex heights with vertex height things
	//  - vertex triangle slopes, in sector order
	//  - Plane_Copy, in line order

	// First things first: reset every sector to flat planes
	for (unsigned a = 0; a < map->nSectors(); a++)
	{
		MapSector* target = map->getSector(a);
		target->setPlane<FLOOR_PLANE>(plane_t::flat(target->getPlaneHeight<FLOOR_PLANE>()));
		target->setPlane<CEILING_PLANE>(plane_t::flat(target->getPlaneHeight<CEILING_PLANE>()));
	}

	// Plane_Align (line special 181)
	for (unsigned a = 0; a < map->nLines(); a++)
	{
		MapLine* line = map->getLine(a);
		if (line->getSpecial() != 181)
			continue;

		MapSector* sector1 = line->frontSector();
		MapSector* sector2 = line->backSector();
		if (!sector1 || !sector2)
		{
			LOG_MESSAGE(1, "Ignoring Plane_Align on one-sided line %d", line->getIndex());
			continue;
		}
		if (sector1 == sector2)
		{
			LOG_MESSAGE(1, "Ignoring Plane_Align on line %d, which has the same sector on both sides", line->getIndex());
			continue;
		}

		int floor_arg = line->intProperty("arg0");
		if (floor_arg == 1)
			applyPlaneAlign<FLOOR_PLANE>(line, sector1, sector2);
		else if (floor_arg == 2)
			applyPlaneAlign<FLOOR_PLANE>(line, sector2, sector1);

		int ceiling_arg = line->intProperty("arg1");
		if (ceiling_arg == 1)
			applyPlaneAlign<CEILING_PLANE>(line, sector1, sector2);
		else if (ceiling_arg == 2)
			applyPlaneAlign<CEILING_PLANE>(line, sector2, sector1);
	}

	// Line slope things (9500/9501), sector tilt things (9502/9503), and
	// vavoom things (1500/1501), all in the same pass
	for (unsigned a = 0; a < map->nThings(); a++)
	{
		MapThing* thing = map->getThing(a);

		// Line slope things
		if (thing->getType() == 9500)
			applyLineSlopeThing<FLOOR_PLANE>(map, thing);
		else if (thing->getType() == 9501)
			applyLineSlopeThing<CEILING_PLANE>(map, thing);
		// Sector tilt things
		else if (thing->getType() == 9502)
			applySectorTiltThing<FLOOR_PLANE>(map, thing);
		else if (thing->getType() == 9503)
			applySectorTiltThing<CEILING_PLANE>(map, thing);
		// Vavoom things
		else if (thing->getType() == 1500)
			applyVavoomSlopeThing<FLOOR_PLANE>(map, thing);
		else if (thing->getType() == 1501)
			applyVavoomSlopeThing<CEILING_PLANE>(map, thing);
	}

	// Slope copy things (9510/9511)
	for (unsigned a = 0; a < map->nThings(); a++)
	{
		MapThing* thing = map->getThing(a);

		if (thing->getType() == 9510 || thing->getType() == 9511)
		{
			int target_idx = map->sectorAt(thing->point());
			if (target_idx < 0)
				continue;
			MapSector* target = map->getSector(target_idx);

			// First argument is the tag of a sector whose slope should be copied
			int tag = thing->intProperty("arg0");
			if (!tag)
			{
				LOG_MESSAGE(1, "Ignoring slope copy thing in sector %d with no argument", target_idx);
				continue;
			}

			vector<MapSector*> tagged_sectors;
			map->getSectorsByTag(tag, tagged_sectors);
			if (tagged_sectors.empty())
			{
				LOG_MESSAGE(1, "Ignoring slope copy thing in sector %d; no sectors have target tag %d", target_idx, tag);
				continue;
			}

			if (thing->getType() == 9510)
				target->setFloorPlane(tagged_sectors[0]->getFloorPlane());
			else
				target->setCeilingPlane(tagged_sectors[0]->getCeilingPlane());
		}
	}

	// Vertex height things
	// These only affect the calculation of slopes and shouldn't be stored in
	// the map data proper, so instead of actually changing vertex properties,
	// we store them in a hashmap.
	VertexHeightMap vertex_floor_heights;
	VertexHeightMap vertex_ceiling_heights;
	for (unsigned a = 0; a < map->nThings(); a++)
	{
		MapThing* thing = map->getThing(a);
		if (thing->getType() == 1504 || thing->getType() == 1505)
		{
			// TODO there could be more than one vertex at this point
			MapVertex* vertex = map->vertexAt(thing->xPos(), thing->yPos());
			if (vertex)
			{
				if (thing->getType() == 1504)
					vertex_floor_heights[vertex] = thing->floatProperty("height");
				else if (thing->getType() == 1505)
					vertex_ceiling_heights[vertex] = thing->floatProperty("height");
			}
		}
	}

	// Vertex heights -- only applies for sectors with exactly three vertices.
	// Heights may be set by UDMF properties, or by a vertex height thing
	// placed exactly on the vertex (which takes priority over the prop).
	vector<MapVertex*> vertices;
	for (unsigned a = 0; a < map->nSectors(); a++)
	{
		MapSector* target = map->getSector(a);
		vertices.clear();
		target->getVertices(vertices);
		if (vertices.size() != 3)
			continue;

		applyVertexHeightSlope<FLOOR_PLANE>(target, vertices, vertex_floor_heights);
		applyVertexHeightSlope<CEILING_PLANE>(target, vertices, vertex_ceiling_heights);
	}

	// Plane_Copy
	vector<MapSector*> sectors;
	for (unsigned a = 0; a < map->nLines(); a++)
	{
		MapLine* line = map->getLine(a);
		if (line->getSpecial() != 118)
			continue;

		int tag;
		MapSector* front = line->frontSector();
		MapSector* back = line->backSector();
		if ((tag = line->intProperty("arg0")) && front)
		{
			sectors.clear();
			map->getSectorsByTag(tag, sectors);
			if (sectors.size())
				front->setFloorPlane(sectors[0]->getFloorPlane());
		}
		if ((tag = line->intProperty("arg1")) && front)
		{
			sectors.clear();
			map->getSectorsByTag(tag, sectors);
			if (sectors.size())
				front->setCeilingPlane(sectors[0]->getCeilingPlane());
		}
		if ((tag = line->intProperty("arg2")) && back)
		{
			sectors.clear();
			map->getSectorsByTag(tag, sectors);
			if (sectors.size())
				back->setFloorPlane(sectors[0]->getFloorPlane());
		}
		if ((tag = line->intProperty("arg3")) && back)
		{
			sectors.clear();
			map->getSectorsByTag(tag, sectors);
			if (sectors.size())
				back->setCeilingPlane(sectors[0]->getCeilingPlane());
		}

		// The fifth "share" argument copies from one side of the line to the
		// other
		if (front && back)
		{
			int share = line->intProperty("arg4");

			if ((share & 3) == 1)
				back->setFloorPlane(front->getFloorPlane());
			else if ((share & 3) == 2)
				front->setFloorPlane(back->getFloorPlane());

			if ((share & 12) == 4)
				back->setCeilingPlane(front->getCeilingPlane());
			else if ((share & 12) == 8)
				front->setCeilingPlane(back->getCeilingPlane());
		}
	}
}
Beispiel #19
0
	void doCheck()
	{
		bool mixed = theGameConfiguration->mixTexFlats();

		// Go through lines
		for (unsigned a = 0; a < map->nLines(); a++)
		{
			MapLine* line = map->getLine(a);

			// Check front side textures
			if (line->s1())
			{
				// Get textures
				string upper = line->s1()->stringProperty("texturetop");
				string middle = line->s1()->stringProperty("texturemiddle");
				string lower = line->s1()->stringProperty("texturebottom");

				// Upper
				if (upper != "-" && texman->getTexture(upper, mixed) == &(GLTexture::missingTex()))
				{
					lines.push_back(line);
					parts.push_back(TEX_FRONT_UPPER);
				}

				// Middle
				if (middle != "-" && texman->getTexture(middle, mixed) == &(GLTexture::missingTex()))
				{
					lines.push_back(line);
					parts.push_back(TEX_FRONT_MIDDLE);
				}

				// Lower
				if (lower != "-" && texman->getTexture(lower, mixed) == &(GLTexture::missingTex()))
				{
					lines.push_back(line);
					parts.push_back(TEX_FRONT_LOWER);
				}
			}

			// Check back side textures
			if (line->s2())
			{
				// Get textures
				string upper = line->s2()->stringProperty("texturetop");
				string middle = line->s2()->stringProperty("texturemiddle");
				string lower = line->s2()->stringProperty("texturebottom");

				// Upper
				if (upper != "-" && texman->getTexture(upper, mixed) == &(GLTexture::missingTex()))
				{
					lines.push_back(line);
					parts.push_back(TEX_BACK_UPPER);
				}

				// Middle
				if (middle != "-" && texman->getTexture(middle, mixed) == &(GLTexture::missingTex()))
				{
					lines.push_back(line);
					parts.push_back(TEX_BACK_MIDDLE);
				}

				// Lower
				if (lower != "-" && texman->getTexture(lower, mixed) == &(GLTexture::missingTex()))
				{
					lines.push_back(line);
					parts.push_back(TEX_BACK_LOWER);
				}
			}
		}
	}
Beispiel #20
0
	void doCheck()
	{
		for (unsigned a = 0; a < map->nLines(); a++)
		{
			// Check what textures the line needs
			MapLine* line = map->getLine(a);
			MapSide* side1 = line->s1();
			MapSide* side2 = line->s2();
			int needs = line->needsTexture();

			// Check for missing textures (front side)
			if (side1)
			{
				// Upper
				if (needs == TEX_FRONT_UPPER && side1->stringProperty("texturetop") == "-")
				{
					lines.push_back(line);
					parts.push_back(TEX_FRONT_UPPER);
				}

				// Middle
				if (needs == TEX_FRONT_MIDDLE && side1->stringProperty("texturemiddle") == "-")
				{
					lines.push_back(line);
					parts.push_back(TEX_FRONT_MIDDLE);
				}

				// Lower
				if (needs == TEX_FRONT_LOWER && side1->stringProperty("texturebottom") == "-")
				{
					lines.push_back(line);
					parts.push_back(TEX_FRONT_LOWER);
				}
			}

			// Check for missing textures (back side)
			if (side2)
			{
				// Upper
				if (needs == TEX_BACK_UPPER && side2->stringProperty("texturetop") == "-")
				{
					lines.push_back(line);
					parts.push_back(TEX_BACK_UPPER);
				}

				// Middle
				if (needs == TEX_BACK_MIDDLE && side2->stringProperty("texturemiddle") == "-")
				{
					lines.push_back(line);
					parts.push_back(TEX_BACK_MIDDLE);
				}

				// Lower
				if (needs == TEX_BACK_LOWER && side2->stringProperty("texturebottom") == "-")
				{
					lines.push_back(line);
					parts.push_back(TEX_BACK_LOWER);
				}
			}
		}
	}
Beispiel #21
0
FontMap::Entry::Entry (const MapLine &mapline, Subfont *sf)
	: fontname(mapline.fontfname()), encname(mapline.encname()), subfont(sf), fontindex(mapline.fontindex()),
	  locked(false), style(mapline.bold(), mapline.extend(), mapline.slant())
{
}
Beispiel #22
0
void PolygonSplitter::openSector(MapSector* sector)
{
	// Check sector was given
	if (!sector)
		return;

	// Init
	clear();

	// Get list of sides connected to this sector
	vector<MapSide*>& sides = sector->connectedSides();

	// Go through sides
	MapLine* line;
	for (unsigned a = 0; a < sides.size(); a++)
	{
		line = sides[a]->getParentLine();

		// Ignore this side if its parent line has the same sector on both sides
		if (!line || line->doubleSector())
			continue;

		// Add the edge to the splitter (direction depends on what side of the line this is)
		if (line->s1() == sides[a])
			addEdge(line->v1()->xPos(), line->v1()->yPos(), line->v2()->xPos(), line->v2()->yPos());
		else
			addEdge(line->v2()->xPos(), line->v2()->yPos(), line->v1()->xPos(), line->v1()->yPos());
	}
}
Beispiel #23
0
/* MapCanvas::onKeyDown
 * Called when a key is pressed within the canvas
 *******************************************************************/
void MapCanvas::onKeyDown(wxKeyEvent& e)
{
	// Send to editor
	context_->input().updateKeyModifiersWx(e.GetModifiers());
	context_->input().keyDown(KeyBind::keyName(e.GetKeyCode()));

	// Testing
	if (Global::debug)
	{
		if (e.GetKeyCode() == WXK_F6)
		{
			Polygon2D poly;
			sf::Clock clock;
			LOG_MESSAGE(1, "Generating polygons...");
			for (unsigned a = 0; a < context_->map().nSectors(); a++)
			{
				if (!poly.openSector(context_->map().getSector(a)))
					LOG_MESSAGE(1, "Splitting failed for sector %d", a);
			}
			//int ms = clock.GetElapsedTime() * 1000;
			//LOG_MESSAGE(1, "Polygon generation took %dms", ms);
		}
		if (e.GetKeyCode() == WXK_F7)
		{
			// Get nearest line
			int nearest = context_->map().nearestLine(context_->input().mousePosMap(), 999999);
			MapLine* line = context_->map().getLine(nearest);
			if (line)
			{
				SectorBuilder sbuilder;

				// Determine line side
				double side = MathStuff::lineSide(context_->input().mousePosMap(), line->seg());
				if (side >= 0)
					sbuilder.traceSector(&(context_->map()), line, true);
				else
					sbuilder.traceSector(&(context_->map()), line, false);
			}
		}
		if (e.GetKeyCode() == WXK_F5)
		{
			// Get nearest line
			int nearest = context_->map().nearestLine(context_->input().mousePosMap(), 999999);
			MapLine* line = context_->map().getLine(nearest);

			// Get sectors
			MapSector* sec1 = context_->map().getLineSideSector(line, true);
			MapSector* sec2 = context_->map().getLineSideSector(line, false);
			int i1 = -1;
			int i2 = -1;
			if (sec1) i1 = sec1->getIndex();
			if (sec2) i2 = sec2->getIndex();

			context_->addEditorMessage(S_FMT("Front %d Back %d", i1, i2));
		}
		if (e.GetKeyCode() == WXK_F5 && context_->editMode() == Mode::Sectors)
		{
			PolygonSplitter splitter;
			splitter.setVerbose(true);
			splitter.openSector(context_->selection().hilightedSector());
			Polygon2D temp;
			splitter.doSplitting(&temp);
		}
	}

	// Update cursor in object edit mode
	//if (mouse_state == Input::MouseState::ObjectEdit)
	//	determineObjectEditState();

#ifndef __WXMAC__
	// Skipping events on OS X doesn't do anything but causes
	// sound alert (a.k.a. error beep) on every key press
	if (e.GetKeyCode() != WXK_UP &&
		e.GetKeyCode() != WXK_DOWN &&
		e.GetKeyCode() != WXK_LEFT &&
		e.GetKeyCode() != WXK_RIGHT &&
		e.GetKeyCode() != WXK_NUMPAD_UP &&
		e.GetKeyCode() != WXK_NUMPAD_DOWN &&
		e.GetKeyCode() != WXK_NUMPAD_LEFT &&
		e.GetKeyCode() != WXK_NUMPAD_RIGHT)
		e.Skip();
#endif // !__WXMAC__
}