예제 #1
0
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);
}
예제 #2
0
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();
}
예제 #3
0
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);
}
예제 #4
0
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;
 }
}
예제 #5
0
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);
}