void BTEditor::editMap(BTDisplay &d, const char *filename) { BTDisplayConfig *oldConfig = d.getConfig(); BTDisplayConfig config; XMLSerializer parser; config.serialize(&parser); parser.parse(BTDisplay::applyDisplayDir("data/mapedit.xml").c_str(), true); d.setConfig(&config); loadMap(filename); xPos = 0; yPos = 0; facing = 0; p3dConfig = d.setWallGraphics(levelMap->getType()); unsigned char key = ' '; if (currentWall < p3dConfig->mapType.size()) d.drawLabel("wall", p3dConfig->mapType[currentWall]->name.c_str()); else d.drawLabel("wall", "Clear"); while (key != 'q') { if (levelMap->getSquare(yPos, xPos).getSpecial() > -1) d.drawLabel("main", levelMap->getSpecial(levelMap->getSquare(yPos, xPos).getSpecial())->getName()); else d.drawLabel("main", ""); if (levelMap->getSquare(yPos, xPos).getStreet() > -1) d.drawLabel("street", levelMap->getStreetName(levelMap->getSquare(yPos, xPos).getStreet()).c_str()); else d.drawLabel("street", ""); d.drawView(); key = d.readChar(); switch (key) { case BTKEY_UP: if (yPos > 0) yPos--; else yPos = getYSize() - 1; break; case BTKEY_LEFT: if (xPos > 0) xPos--; else xPos = getXSize() - 1; break; case BTKEY_DOWN: if (yPos < getYSize() - 1) yPos++; else yPos = 0; break; case BTKEY_RIGHT: if (xPos < getXSize() - 1) xPos++; else xPos = 0; break; case BTKEY_PGDN: case '2': if (facing < 3) facing++; else facing = 0; break; case BTKEY_END: case '1': if (facing > 0) facing--; else facing = 3; break; case 13: { int wall = 0; if (currentWall < p3dConfig->mapType.size()) wall = p3dConfig->mapType[currentWall]->type; levelMap->getSquare(yPos, xPos).setWall(facing, wall); int xOpposite = xPos + Psuedo3D::changeXY[facing][0] + levelMap->getXSize(); xOpposite = xOpposite % levelMap->getXSize(); int yOpposite = yPos + Psuedo3D::changeXY[facing][1] + levelMap->getYSize(); yOpposite = yOpposite % levelMap->getYSize(); levelMap->getSquare(yOpposite, xOpposite).setWall((facing + 2) % 4, wall); break; } case ' ': if (currentWall < p3dConfig->mapType.size()) { currentWall++; } else { currentWall = 0; } if (currentWall < p3dConfig->mapType.size()) d.drawLabel("wall", p3dConfig->mapType[currentWall]->name.c_str()); else d.drawLabel("wall", "Clear"); break; case 'r': { if (d.getScreen(1)) d.getScreen(1)->setVisibility(true); std::string tmp = d.readString("X Size?", 3, ""); int newXSize = atol(tmp.c_str()); if (newXSize < 1) { d.clearText(); if (d.getScreen(1)) d.getScreen(1)->setVisibility(false); break; } tmp = d.readString("Y Size?", 3, ""); int newYSize = atol(tmp.c_str()); if (newYSize < 1) { d.clearText(); if (d.getScreen(1)) d.getScreen(1)->setVisibility(false); break; } levelMap->resize(newXSize, newYSize); d.clearText(); if (d.getScreen(1)) d.getScreen(1)->setVisibility(false); break; } case 'c': levelMap->getSquare(yPos, xPos).setSpecial(-1); break; case 's': { d.clearText(); if (d.getScreen(1)) d.getScreen(1)->setVisibility(true); int len = levelMap->getNumOfSpecials(); BTDisplay::selectItem list[len + 1]; for (int i = 0; i < len; ++i) { list[i].name = levelMap->getSpecial(i)->getName(); } list[len].name = "<New Special>"; d.addSelection(list, len + 1, startSpecial, currentSpecial); int key = d.process("ce"); d.clearText(); if (d.getScreen(1)) d.getScreen(1)->setVisibility(false); if ((key == 'e') || ((currentSpecial == len) && ((key == '\r') || (key == 'c')))) { editSpecial(d, levelMap->getSpecial(currentSpecial)); levelMap->getSquare(yPos, xPos).setSpecial(currentSpecial); } else if (key == 'c') { BTSpecial *s = new BTSpecial(*levelMap->getSpecial(currentSpecial)); levelMap->addSpecial(s); currentSpecial = len; editSpecial(d, s); levelMap->getSquare(yPos, xPos).setSpecial(currentSpecial); } else if (key == '\r') { levelMap->getSquare(yPos, xPos).setSpecial(currentSpecial); } if (currentWall < p3dConfig->mapType.size()) d.drawLabel("wall", p3dConfig->mapType[currentWall]->name.c_str()); else d.drawLabel("wall", "Clear"); break; } case 'l': levelMap->getSquare(yPos, xPos).setSpecial(currentSpecial); break; case 'b': levelMap->getSquare(yPos, xPos).setStreet(-1); break; case 'n': { d.clearText(); if (d.getScreen(1)) d.getScreen(1)->setVisibility(true); int len = levelMap->getNumOfStreets(); BTDisplay::selectItem list[len + 1]; for (int i = 0; i < len; ++i) { list[i].name = levelMap->getStreetName(i); } list[len].name = "<New Street>"; d.addSelection(list, len + 1, startStreet, currentStreet); int key = d.process("e"); d.clearText(); if ((key == 'e') || ((currentStreet == len) && (key == '\r'))) { std::string name; if (currentStreet != len) name = list[currentStreet].name; d.addReadString("Name: ", 25, name); key = d.process(); if (key == '\r') { if (currentStreet == len) levelMap->addStreetName(name); else levelMap->setStreetName(currentStreet, name); levelMap->getSquare(yPos, xPos).setStreet(currentStreet); } } else if (key == '\r') { levelMap->getSquare(yPos, xPos).setStreet(currentStreet); } d.clearText(); if (d.getScreen(1)) d.getScreen(1)->setVisibility(false); if (currentWall < p3dConfig->mapType.size()) d.drawLabel("wall", p3dConfig->mapType[currentWall]->name.c_str()); else d.drawLabel("wall", "Clear"); break; } case 'm': levelMap->getSquare(yPos, xPos).setStreet(currentStreet); break; case 'p': { ObjectSerializer serial; levelMap->serialize(&serial); BTMapPropertiesEditor mapPropEditor; int type = levelMap->getType(); mapPropEditor.edit(d, serial); if (levelMap->getType() != type) { p3dConfig = d.setWallGraphics(levelMap->getType()); currentWall = 0; } if (currentWall < p3dConfig->mapType.size()) d.drawLabel("wall", p3dConfig->mapType[currentWall]->name.c_str()); else d.drawLabel("wall", "Clear"); break; } default: break; } } if (d.getScreen(1)) d.getScreen(1)->setVisibility(true); d.drawText("Save?"); while ((key != 'y') && (key != 'n')) { key = d.readChar(); } if (key == 'y') { bool wrote = false; int len = strlen(levelMap->getFilename()); if ((len > 4) && (strcmp(".MAP", levelMap->getFilename() + (len - 4)) == 0)) { try { BinaryWriteFile f(levelMap->getFilename()); levelMap->write(f); wrote = true; } catch (const FileException &e) { PHYSFS_delete(levelMap->getFilename()); printf("Failed to write old map file: %s\n", e.what()); char tmp[len + 1]; strcpy(tmp, levelMap->getFilename()); strcpy(tmp + len - 3, "xml"); levelMap->setFilename(tmp); } } if (!wrote) { XMLSerializer parser; parser.add("map", levelMap); parser.write(levelMap->getFilename(), true); } } d.setConfig(oldConfig); }