void BTSerializedEditor::edit(BTDisplay &d, ObjectSerializer &serial) { BTDisplayConfig *oldConfig = d.getConfig(); BTDisplayConfig config; XMLSerializer parser; config.serialize(&parser); parser.parse(BTDisplay::applyDisplayDir("data/specialedit.xml").c_str(), true); d.setConfig(&config); int start(0); int current(0); BitField active; std::vector<BTDisplay::selectItem> list(entries); initActive(serial, active); int len = setup(serial, active, list); d.addSelection(list.data(), len, start, current); int key; char extra[2] = {BTKEY_DEL, 0}; while (27 != (key = d.process(extra))) { d.clearText(); XMLAction *curField = NULL; if (list[current].value < entries) curField = serial.find(field[list[current].value], NULL); if (key == BTKEY_DEL) { if (curField) { int where = 0; if (curField->getType() == XMLTYPE_CREATE) { XMLArray *obj = reinterpret_cast<XMLArray*>(curField->object); int where = 0; for (int i = current - 1; (i >= 0) && (list[i].value == list[current].value); --i) { ++where; } if (where < obj->size()) { obj->erase(where); for (int i = current; i < len - 1; ++i) { list[i].name = list[i + 1].name; list[i].value = list[i + 1].value; } --len; } } else if (curField->getType() == XMLTYPE_VECTORSTRING) { std::vector<std::string> *obj = reinterpret_cast<std::vector<std::string>*>(curField->object); int where = 0; for (int i = current - 1; (i >= 0) && (list[i].value == list[current].value); --i) { ++where; } if (where < obj->size()) { obj->erase(obj->begin() + where); for (int i = current; i < len - 1; ++i) { list[i].name = list[i + 1].name; list[i].value = list[i + 1].value; } --len; } } } else { delSpecialField(d, serial, list[current].value); } } else { if (curField) { int where = 0; if (curField->getType() == XMLTYPE_CREATE) { XMLArray *obj = reinterpret_cast<XMLArray*>(curField->object); for (int i = current - 1; (i >= 0) && (list[i].value == list[current].value); --i) { ++where; } if (where >= obj->size()) { obj->push_back((*reinterpret_cast<XMLObject::create>(curField->data))(field[list[current].value], NULL)); list.push_back(BTDisplay::selectItem()); for (int i = list.size() - 1; i > current; --i) { list[i].name = list[i - 1].name; list[i].value = list[i - 1].value; } len++; } } else if (curField->getType() == XMLTYPE_VECTORSTRING) { std::vector<std::string> *obj = reinterpret_cast<std::vector<std::string>*>(curField->object); for (int i = current - 1; (i >= 0) && (list[i].value == list[current].value); --i) { ++where; } if (where >= obj->size()) { obj->push_back(std::string()); list.push_back(BTDisplay::selectItem()); for (int i = list.size() - 1; i > current; --i) { list[i].name = list[i - 1].name; list[i].value = list[i - 1].value; } len++; } } editField(d, serial, description[list[current].value], curField, list[current].value, where); if (curField->getType() == XMLTYPE_OBJECT) { XMLObject *obj = reinterpret_cast<XMLObject*>(curField->object); BTDice *dice = dynamic_cast<BTDice*>(obj); if (dice) list[current].name = std::string(description[list[current].value]) + ": " + dice->createString(); } else if (curField->getType() == XMLTYPE_VECTORSTRING) { std::vector<std::string> *obj = reinterpret_cast<std::vector<std::string>*>(curField->object); list[current].name = std::string(description[list[current].value]) + ": " + (*obj)[where]; } else if (curField->getType() != XMLTYPE_CREATE) { list[current].name = std::string(description[list[current].value]) + ": " + curField->createString(); } else { XMLArray *obj = reinterpret_cast<XMLArray*>(curField->object); list[current].name = std::string(description[list[current].value]) + ": " + obj->get(where)->createString(); } } else { handleSpecialField(d, serial, list[current].value); } } if (updateActive(serial, active, list[current].value)) len = setup(serial, active, list); d.addSelection(list.data(), len, start, current); } complete(serial); d.clearText(); d.setConfig(oldConfig); }
void BTSerializedEditor::editField(BTDisplay &d, ObjectSerializer &serial, const char *text, XMLAction *curField, int modField, int where) { int key; switch (curField->getType()) { case XMLTYPE_STDSTRING: { std::string val = curField->createString(); d.addReadString(std::string(text) + ": ", 100, val); key = d.process(); if ('\r' == key) *(reinterpret_cast<std::string*>(curField->object)) = val; break; } case XMLTYPE_STRING: { std::string val = curField->createString(); d.addReadString(std::string(text) + ": ", 100, val); key = d.process(); if ('\r' == key) { char *str = *(reinterpret_cast<char**>(curField->object)); if (str) { delete [] str; } int len = val.length(); str = new char[len + 1]; strncpy(str, val.c_str(), len); str[len] = 0; *(reinterpret_cast<char**>(curField->object)) = str; } break; } case XMLTYPE_BOOL: { BTDisplay::selectItem vals[2]; vals[0].name = "false"; vals[1].name = "true"; int lookupStart(0); int lookupCurrent((*(reinterpret_cast<bool*>(curField->object)) ? 1 : 0)); d.addSelection(vals, 2, lookupStart, lookupCurrent); if (27 != d.process()) { *(reinterpret_cast<bool*>(curField->object)) = lookupCurrent; } break; } case XMLTYPE_BITFIELD: { ValueLookup *lookup = reinterpret_cast<ValueLookup*>(curField->data); BitField *bits = reinterpret_cast<BitField*>(curField->object); BTDisplay::selectItem lookupItem[lookup->size()]; for (int i = 0; i < lookup->size(); ++i) { lookupItem[i].name = lookup->getName(i); if (bits->isSet(i)) lookupItem[i].first = '*'; } int lookupStart(0); int lookupCurrent(0); d.addSelection(lookupItem, lookup->size(), lookupStart, lookupCurrent); int key; while (27 != (key = d.process())) { if (bits->toggle(lookupCurrent)) lookupItem[lookupCurrent].first = '*'; else lookupItem[lookupCurrent].first = 0; } break; } case XMLTYPE_INT: { if (curField->data) { ValueLookup *lookup = reinterpret_cast<ValueLookup*>(curField->data); bool extra = ((curField->extra == EXTRA_NONE) ? false : true); BTDisplay::selectItem lookupItem[lookup->size() + (extra ? 1 : 0)]; int i = 0; if (extra) { lookupItem[0].name = curField->extraText; lookupItem[0].value = -1; ++i; } int endIndex = lookup->getEndIndex(); int lookupCurrent(0); int valIndex((*(reinterpret_cast<int*>(curField->object))) + (extra ? 1 : 0)); for (int curIndex = lookup->getFirstIndex(); curIndex != endIndex; curIndex = lookup->getNextIndex(curIndex)) { lookupItem[i].name = lookup->getName(curIndex); lookupItem[i].value = curIndex; if (curIndex == valIndex) lookupCurrent = i; ++i; } int lookupStart(0); d.addSelection(lookupItem, lookup->size() + (extra ? 1 : 0), lookupStart, lookupCurrent); if (27 != d.process()) { *(reinterpret_cast<int*>(curField->object)) = lookupItem[lookupCurrent].value; } } else { std::string val = curField->createString(); d.addReadString(std::string(text) + ": ", 100, val); key = d.process(); if ('\r' == key) *(reinterpret_cast<int*>(curField->object)) = atol(val.c_str()); } break; } case XMLTYPE_UINT: { std::string val = curField->createString(); d.addReadString(std::string(text) + ": ", 100, val); key = d.process(); if ('\r' == key) *(reinterpret_cast<unsigned int*>(curField->object)) = atol(val.c_str()); break; } case XMLTYPE_INT16: { std::string val = curField->createString(); d.addReadString(std::string(text) + ": ", 100, val); key = d.process(); if ('\r' == key) *(reinterpret_cast<int16_t*>(curField->object)) = atol(val.c_str()); break; } case XMLTYPE_VECTORUINT: { std::vector<unsigned int> *vec = reinterpret_cast<std::vector<unsigned int> *>(curField->object); std::string val; for (size_t i = 0; i < vec->size(); ++i) { if (i != 0) val += ","; char convert[30]; sprintf(convert, "%u", (*vec)[i]); val += convert; } d.addReadString(std::string(text) + ": ", 100, val); key = d.process(); if ('\r' == key) { size_t i = 0; const char *start = val.c_str(); for (const char *comma = strchr(val.c_str(), ','); (start) && (*start); ++i) { if (i < vec->size()) (*vec)[i] = atol(start); else vec->push_back(atol(start)); start = comma; if (start) { if ((*start) == ',') ++start; comma = strchr(start, ','); } } if (i < vec->size()) vec->resize(i); } break; } case XMLTYPE_OBJECT: { XMLObject *obj = reinterpret_cast<XMLObject*>(curField->object); BTDice *dice = dynamic_cast<BTDice*>(obj); if (dice) { std::ostringstream stream; stream << dice->getNumber(); std::string val = stream.str(); d.addReadString(std::string(text) + "- Number of Dice: ", 100, val); key = d.process(); if ('\r' == key) dice->setNumber(atol(val.c_str())); d.clearText(); stream.str(""); stream << dice->getType(); val = stream.str(); d.addReadString(std::string(text) + "- Type of Dice: ", 100, val); key = d.process(); if ('\r' == key) dice->setType(atol(val.c_str())); d.clearText(); stream.str(""); stream << dice->getModifier(); val = stream.str(); d.addReadString(std::string(text) + "- Modifier to Roll: ", 100, val); key = d.process(); if ('\r' == key) dice->setModifier(atol(val.c_str())); } else printf("Unsuppported type: %d\n", curField->getType()); break; } case XMLTYPE_CREATE: { XMLArray *obj = reinterpret_cast<XMLArray*>(curField->object); handleObject(d, obj->get(where), modField); break; } case XMLTYPE_PICTURE: { BTDisplayConfig *oldConfig = d.getConfig(); BTDisplayConfig config; XMLSerializer parser; config.serialize(&parser); parser.parse(BTDisplay::applyDisplayDir("data/pictureselect.xml").c_str(), true); d.setConfig(&config); d.clearText(); d.addText(text); int val(reinterpret_cast<PictureIndex*>(curField->object)->value); d.addSelectImage(val); key = d.process(); if ('\r' == key) reinterpret_cast<PictureIndex*>(curField->object)->value = val; d.clearImage(); d.setConfig(oldConfig); break; } case XMLTYPE_VECTORSTRING: { std::vector<std::string> *obj = reinterpret_cast<std::vector<std::string>*>(curField->object); std::string val = (*obj)[where]; d.addReadString(std::string(text) + ": ", 100, val); key = d.process(); if ('\r' == key) (*obj)[where] = val; break; } default: printf("Unsuppported type: %d\n", curField->getType()); break; } d.clearText(); }
void BTEditor::editSpecial(BTDisplay &d, BTSpecial *special) { if (NULL == special) { special = new BTSpecial; levelMap->addSpecial(special); } BTDisplayConfig *oldConfig = d.getConfig(); BTDisplayConfig config; XMLSerializer parser; config.serialize(&parser); parser.parse(BTDisplay::applyDisplayDir("data/specialedit.xml").c_str(), true); d.setConfig(&config); int start(0); int current(0); BTSpecialBody *body = special->getBody(); std::vector<operationList> ops; std::vector<BTDisplay::selectItem> list(2); list[0].name = std::string("Name: ") + special->getName(); list[1].name = "Flags: " + special->printFlags(false); buildOperationList(d, body, list, ops); d.addSelection(list.data(), list.size(), start, current); int key; char extra[6] = {BTKEY_INS, BTKEY_DEL, BTKEY_CTRL_C, BTKEY_CTRL_V, BTKEY_CTRL_X, 0}; while (27 != (key = d.process(extra))) { d.clearText(); if (current == 0) { std::string name = special->getName(); d.addReadString("Name: ", 25, name); key = d.process(); if ('\r' == key) special->setName(name); d.clearText(); list[0].name = std::string("Name: ") + special->getName(); } else if (current == 1) { BTSpecialFlagList &lookup = getSpecialFlagList(); BitField bits = special->getFlag(); BTDisplay::selectItem lookupItem[lookup.size()]; for (size_t i = 0; i < lookup.size(); ++i) { lookupItem[i].name = lookup.getName(i); if (bits.isSet(i)) lookupItem[i].first = '*'; } int lookupStart(0); int lookupCurrent(0); d.addSelection(lookupItem, lookup.size(), lookupStart, lookupCurrent); int key; while (27 != (key = d.process())) { if (bits.toggle(lookupCurrent)) lookupItem[lookupCurrent].first = '*'; else lookupItem[lookupCurrent].first = 0; } special->setFlag(bits); d.clearText(); list[1].name = "Flags: " + special->printFlags(false); } else { if (BTKEY_INS == key) { if ((ops[list[current].value].op != NULL) && (ops[list[current].value].parent != NULL)) { ops[list[current].value].parent->insertOperation(ops[list[current].value].op, new BTSpecialCommand(BTSPECIALCOMMAND_NOTHING)); } } else if (BTKEY_DEL == key) { if ((ops[list[current].value].op != NULL) && (ops[list[current].value].parent != NULL)) { ops[list[current].value].parent->eraseOperation(ops[list[current].value].op); } } else if (BTKEY_CTRL_X == key) { if ((ops[list[current].value].op != NULL) && (ops[list[current].value].parent != NULL)) { if (clipboard) delete clipboard; clipboard = ops[list[current].value].op->clone(); ops[list[current].value].parent->eraseOperation(ops[list[current].value].op); } } else if (BTKEY_CTRL_C == key) { if ((ops[list[current].value].op != NULL) && (ops[list[current].value].parent != NULL)) { if (clipboard) delete clipboard; clipboard = ops[list[current].value].op->clone(); } } else if (BTKEY_CTRL_V == key) { if ((ops[list[current].value].parent != NULL) && (clipboard)) { if (ops[list[current].value].op) ops[list[current].value].parent->insertOperation(ops[list[current].value].op, clipboard->clone()); else ops[list[current].value].parent->addOperation(clipboard->clone()); } } else if ('\r' == key) { BTSpecialOperation *op = editSpecialOperation(d, ops[list[current].value].op); if (op) { if (ops[list[current].value].op) ops[list[current].value].parent->replaceOperation(ops[list[current].value].op, op); else ops[list[current].value].parent->addOperation(op); } } } ops.clear(); list.resize(2); buildOperationList(d, body, list, ops); d.addSelection(list.data(), list.size(), start, current); } d.clearText(); d.setConfig(oldConfig); }
BTSpecialOperation *BTEditor::editSpecialOperation(BTDisplay &d, BTSpecialOperation *special) { BTDisplay::selectItem cmds[BT_SPECIALCOMMANDS + BT_CONDITIONALCOMMANDS]; for (int i = 0; i < BT_CONDITIONALCOMMANDS; ++i) { cmds[i].name = std::string("if ") + conditionalCommands[i]; cmds[i].value = i; } for (int i = 0; i < BT_SPECIALCOMMANDS; ++i) { cmds[i + BT_CONDITIONALCOMMANDS].name = specialCommands[i]; cmds[i + BT_CONDITIONALCOMMANDS].value = i + BT_CONDITIONALCOMMANDS; } std::sort(cmds, cmds + BT_SPECIALCOMMANDS + BT_CONDITIONALCOMMANDS); int start(0); int current(0); { BTSpecialConditional *specialCond = dynamic_cast<BTSpecialConditional*>(special); if (NULL != specialCond) { for (int i = 0; i < BT_SPECIALCOMMANDS + BT_CONDITIONALCOMMANDS; i++) { if (cmds[i].value == specialCond->getType()) { current = i; break; } } } BTSpecialCommand *specialCom = dynamic_cast<BTSpecialCommand*>(special); if (NULL != specialCom) { for (int i = 0; i < BT_SPECIALCOMMANDS + BT_CONDITIONALCOMMANDS; i++) { if (cmds[i].value == specialCom->getType() + BT_CONDITIONALCOMMANDS) { current = i; break; } } } } int original = current; d.addSelection(cmds, BT_SPECIALCOMMANDS + BT_CONDITIONALCOMMANDS, start, current); int key = d.process(); d.clearText(); if (key == 27) return NULL; std::string text; int number[3] = {0, 0, 0}; int count = 0; const char *cmd = NULL; if (cmds[current].value < BT_CONDITIONALCOMMANDS) { cmd = conditionalCommands[cmds[current].value]; if (original == current) { BTSpecialConditional *specialCond = dynamic_cast<BTSpecialConditional*>(special); if (NULL != specialCond) { for (int i = 0; i < specialCond->getArgumentCount(); i++) { number[i] = specialCond->getNumber(i); } text = specialCond->getText(); } } } else { cmd = specialCommands[cmds[current].value - BT_CONDITIONALCOMMANDS]; if (original == current) { BTSpecialCommand *specialCom = dynamic_cast<BTSpecialCommand*>(special); if (NULL != specialCom) { for (int i = 0; i < 3; i++) { number[i] = specialCom->getNumber(i); } text = specialCom->getText(); } } } const char *dollarSign; std::string newMap; int facingDir = -1; while (dollarSign = strchr(cmd, '$')) { switch (dollarSign[1]) { case 'S': { int len = levelMap->getNumOfSpecials(); BTDisplay::selectItem list[len]; for (int i = 0; i < len; ++i) { list[i].name = levelMap->getSpecial(i)->getName(); } int specialStart(0); d.addSelection(list, len, specialStart, number[count]); int key = d.process(); d.clearText(); if (key == 27) return NULL; count++; break; } case 'I': { BTFactory<BTItem> &itemList = getItemList(); BTDisplay::selectItem items[itemList.size()]; for (size_t i = 0; i < itemList.size(); ++i) items[i].name = itemList[i].getName(); int itemStart(0); d.addSelection(items, itemList.size(), itemStart, number[count]); int key = d.process(); d.clearText(); if (key == 27) return NULL; count++; break; } case 'A': case 'M': { BTFactory<BTMonster> &monsterList = getMonsterList(); BTDisplay::selectItem monsters[monsterList.size()]; for (size_t i = 0; i < monsterList.size(); ++i) monsters[i].name = monsterList[i].getName(); int monsterStart(0); d.addSelection(monsters, monsterList.size(), monsterStart, number[count]); int key = d.process(); d.clearText(); if (key == 27) return NULL; count++; break; } case 'X': { BTFactory<BTSpell, BTSpell1> &spellList = getSpellList(); BTDisplay::selectItem spells[spellList.size()]; for (size_t i = 0; i < spellList.size(); ++i) spells[i].name = spellList[i].getName(); int spellStart(0); d.addSelection(spells, spellList.size(), spellStart, number[count]); int key = d.process(); d.clearText(); if (key == 27) return NULL; count++; break; } case 'L': { if ((newMap.empty()) || (0 != PHYSFS_exists(newMap.c_str()))) { int origX = xPos; int origY = yPos; int origFacing = facing; bool toggle = false; if ((!newMap.empty()) && (newMap != levelMap->getFilename())) { toggleMap(); loadMap(newMap.c_str()); toggle = true; } BTDisplayConfig *oldConfig = d.getConfig(); BTDisplayConfig config; XMLSerializer parser; config.serialize(&parser); parser.parse(BTDisplay::applyDisplayDir("data/mapedit.xml").c_str(), true); d.setConfig(&config); xPos = number[count] % levelMap->getXSize(); yPos = levelMap->getYSize() - 1 - (number[count + 1] % levelMap->getYSize()); facing = number[count + 2]; p3dConfig = d.setWallGraphics(levelMap->getType()); unsigned char key = ' '; while (key != '\r') { if (levelMap->getSquare(yPos, xPos).getSpecial() > -1) d.drawLabel("main", levelMap->getSpecial(levelMap->getSquare(yPos, xPos).getSpecial())->getName()); else d.drawLabel("main", ""); 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: if (facing < 3) facing++; else facing = 0; break; case BTKEY_END: if (facing > 0) facing--; else facing = 3; break; default: break; } } number[count++] = xPos; number[count++] = levelMap->getYSize() - 1 - yPos; facingDir = facing; d.clearText(); d.setConfig(oldConfig); if (toggle) { toggleMap(); p3dConfig = d.setWallGraphics(levelMap->getType()); } xPos = origX; yPos = origY; facing = origFacing; break; } // Fall through to $O processing if map file does not exist. } case 'O': { std::string val; if (number[count] != 0) { char convert[30]; sprintf(convert, "%d", number[count]); val = convert; } d.addReadString("X>", 100, val); key = d.process(); d.clearText(); if (27 == key) return NULL; number[count++] = atol(val.c_str()); val = ""; if (number[count] != 0) { char convert[30]; sprintf(convert, "%d", number[count]); val = convert; } d.addReadString("Y>", 100, val); key = d.process(); d.clearText(); if (27 == key) return NULL; number[count++] = atol(val.c_str()); break; } case 'T': { BTDisplay::selectItem damage[BT_MONSTEREXTRADAMAGE]; for (int i = 0; i < BT_MONSTEREXTRADAMAGE; ++i) damage[i].name = extraDamage[i]; int damageStart(0); d.addSelection(damage, BT_MONSTEREXTRADAMAGE, damageStart, number[count]); int key = d.process(); d.clearText(); if (key == 27) return NULL; count++; break; } case 'C': { BTJobList &jobList = getJobList(); BTDisplay::selectItem jobs[jobList.size()]; for (size_t i = 0; i < jobList.size(); ++i) jobs[i].name = jobList[i]->name; int jobStart(0); d.addSelection(jobs, jobList.size(), jobStart, number[count]); int key = d.process(); d.clearText(); if (key == 27) return NULL; count++; break; } case 'R': { BTRaceList &raceList = getRaceList(); BTDisplay::selectItem races[raceList.size()]; for (size_t i = 0; i < raceList.size(); ++i) races[i].name = raceList[i]->name; int raceStart(0); d.addSelection(races, raceList.size(), raceStart, number[count]); int key = d.process(); d.clearText(); if (key == 27) return NULL; count++; break; } case 'D': { if (facingDir != -1) { number[count++] = facingDir; } else { BTDisplay::selectItem dir[BT_DIRECTIONS]; for (int i = 0; i < BT_DIRECTIONS; ++i) dir[i].name = directions[i]; int dirStart(0); d.addSelection(dir, BT_DIRECTIONS, dirStart, number[count]); int key = d.process(); d.clearText(); if (key == 27) return NULL; count++; } break; } case '#': case 'G': case 'F': case '!': case 'J': { std::string val; if (number[count] != 0) { char convert[30]; sprintf(convert, "%d", number[count]); val = convert; } d.addReadString("Number>", 100, val); key = d.process(); d.clearText(); if (27 == key) return NULL; number[count++] = atol(val.c_str()); break; } case 'P': { BTDisplayConfig *oldConfig = d.getConfig(); BTDisplayConfig config; XMLSerializer parser; config.serialize(&parser); parser.parse(BTDisplay::applyDisplayDir("data/pictureselect.xml").c_str(), true); d.setConfig(&config); d.clearText(); d.addText("Select Image"); int val(number[count]); d.addSelectImage(val); key = d.process(); d.clearText(); d.clearImage(); d.setConfig(oldConfig); if (27 == key) return NULL; number[count++] = val; break; } case 'E': { BTDisplay::selectItem effects[BT_SPELLTYPES_FULL]; for (int i = 0; i < BT_SPELLTYPES_FULL; ++i) effects[i].name = spellTypes[i]; int effectStart(0); d.addSelection(effects, BT_SPELLTYPES_FULL, effectStart, number[count]); int key = d.process(); d.clearText(); if (key == 27) return NULL; count++; break; } case 'N': { char **files = PHYSFS_enumerateFiles(""); char **i; int count(1); for (i = files; *i != NULL; i++) { if (checkSkipFiles(*i)) continue; int len = strlen(*i); if ((len > 4) && (strcmp(".MAP", (*i) + (len - 4)) == 0)) { char tmp[len + 1]; strcpy(tmp, (*i)); strcpy(tmp + len - 3, "xml"); if (0 == PHYSFS_exists(tmp)) { count++; } } else if ((len > 4) && (strcmp(".xml", (*i) + (len - 4)) == 0)) { count++; } } BTDisplay::selectItem *list = new BTDisplay::selectItem[count]; int current = 0; for (i = files; *i != NULL; i++) { if (checkSkipFiles(*i)) continue; int len = strlen(*i); if ((len > 4) && (strcmp(".MAP", (*i) + (len - 4)) == 0)) { char tmp[len + 1]; strcpy(tmp, (*i)); strcpy(tmp + len - 3, "xml"); if (0 == PHYSFS_exists(tmp)) { list[current].name = *i; current++; } } else if ((len > 4) && (strcmp(".xml", (*i) + (len - 4)) == 0)) { list[current].name = *i; current++; } } list[current].name = "<New Map>"; PHYSFS_freeList(files); int start(0); int select(0); d.clearElements(); d.addSelection(list, count, start, select); unsigned int key = d.process(); d.clearText(); if (27 == key) return NULL; else if (count - 1 != select) text = list[select].name; else { d.addReadString(">", 100, text); key = d.process(); d.clearText(); if (27 == key) return NULL; } newMap = text; break; } case 'K': { BTSkillList &skillList = getSkillList(); BTDisplay::selectItem items[skillList.size()]; for (size_t i = 0; i < skillList.size(); ++i) items[i].name = skillList[i]->name; int itemStart(0); d.addSelection(items, skillList.size(), itemStart, number[count]); int key = d.process(); d.clearText(); if (key == 27) return NULL; count++; break; } case '$': default: d.addReadString(">", 100, text); key = d.process(); d.clearText(); if (27 == key) return NULL; break; } cmd = dollarSign + 2; } if (cmds[current].value < BT_CONDITIONALCOMMANDS) { BTSpecialConditional *opNew = new BTSpecialConditional(cmds[current].value, text.c_str()); for (int i = 0; i < count; ++i) opNew->addNumber(number[i]); BTSpecialConditional *opOld = dynamic_cast<BTSpecialConditional*>(special); if (opOld) { opNew->getThenClause()->moveFrom(opOld->getThenClause()); opNew->getElseClause()->moveFrom(opOld->getElseClause()); } return opNew; } else { BTSpecialCommand *opNew = new BTSpecialCommand(cmds[current].value - BT_CONDITIONALCOMMANDS); opNew->setText(text); for (int i = 0; i < count; ++i) opNew->setNumber(i, number[i]); return opNew; } }
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); }