mirror of
https://github.com/amyinspace/MagicSetEditor2.git
synced 2026-06-10 13:06:59 -04:00
mtg editor import
git-svn-id: svn://svn.code.sf.net/p/magicseteditor/code/trunk@118 0fc631ac-6414-0410-93d0-97cfa31319b6
This commit is contained in:
@@ -7,6 +7,17 @@
|
||||
// ----------------------------------------------------------------------------- : Includes
|
||||
|
||||
#include <data/format/formats.hpp>
|
||||
#include <data/set.hpp>
|
||||
#include <data/game.hpp>
|
||||
#include <data/stylesheet.hpp>
|
||||
#include <data/card.hpp>
|
||||
#include <data/field/text.hpp>
|
||||
#include <data/field/choice.hpp>
|
||||
#include <data/field/image.hpp>
|
||||
#include <util/tagged_string.hpp>
|
||||
#include <wx/wfstream.h>
|
||||
|
||||
DECLARE_TYPEOF_COLLECTION(CardP);
|
||||
|
||||
// ----------------------------------------------------------------------------- : MtgEditorFileFormat
|
||||
|
||||
@@ -18,6 +29,17 @@ class MtgEditorFileFormat : public FileFormat {
|
||||
virtual bool canImport() { return true; }
|
||||
virtual bool canExport(const Game&) { return false; }
|
||||
virtual SetP importSet(const String& filename);
|
||||
private:
|
||||
// Filter: se filename -> image directory
|
||||
// based on MtgEditor's: CardSet.getImageFolder
|
||||
String filter1(const String& str);
|
||||
// Filter: card name -> image name
|
||||
// based on MtgEditor's: Tools::purgeSpecialChars
|
||||
String filter2(const String& str);
|
||||
// Remove mtg editor tags
|
||||
void untag(const CardP& card, const String& field);
|
||||
// Translate all tags, mana tags get converted to <sym>, other tags are removed
|
||||
void translateTags(String& value);
|
||||
};
|
||||
|
||||
FileFormatP mtg_editor_file_format() {
|
||||
@@ -27,5 +49,222 @@ FileFormatP mtg_editor_file_format() {
|
||||
// ----------------------------------------------------------------------------- : Importing
|
||||
|
||||
SetP MtgEditorFileFormat::importSet(const String& filename) {
|
||||
return SetP();//TODO
|
||||
wxFileInputStream f(filename);
|
||||
#ifdef UNICODE
|
||||
wxTextInputStream file(f, _('\n'), wxConvLibc);
|
||||
#else
|
||||
wxTextInputStream file(f);
|
||||
#endif
|
||||
// create set
|
||||
SetP set(new Set(Game::byName(_("magic"))));
|
||||
|
||||
// parsing state
|
||||
CardP current_card;
|
||||
Defaultable<String>* target = nullptr; // value we are currently reading
|
||||
String layout = _("8e");
|
||||
String set_date, card_date;
|
||||
bool first = true;
|
||||
|
||||
// read file
|
||||
while (!f.Eof()) {
|
||||
// read a line
|
||||
if (!current_card) current_card = new_shared1<Card>(*set->game);
|
||||
String line = file.ReadLine();
|
||||
if (line == _("#SET###########")) { // set.title
|
||||
target = &set->value<TextValue>(_("title")).value;
|
||||
} else if (line == _("#SETDATE#######")) { // date
|
||||
// remember date for generation of illustration filename
|
||||
target = nullptr;
|
||||
set_date = file.ReadLine();
|
||||
} else if (line == _("#SHOWRARITY####") ||
|
||||
line == _("#FONTS#########") || line == _("#COUNT#########")) { // ignore
|
||||
target = nullptr;
|
||||
file.ReadLine();
|
||||
} else if (line == _("#LAYOUT########")) { // layout type
|
||||
target = nullptr;
|
||||
layout = file.ReadLine();
|
||||
} else if (line == _("#CARD##########") || line == _("#EOF###########")) { // begin/end of card
|
||||
if (!first) {
|
||||
// First [CARD##] indicates only the start of a card, subsequent ones also the end of the previous
|
||||
// card. We only care about the latter
|
||||
// remove all tags from all text values
|
||||
untag(current_card, _("name"));
|
||||
untag(current_card, _("super type"));
|
||||
untag(current_card, _("sub type"));
|
||||
untag(current_card, _("casting cost"));
|
||||
untag(current_card, _("flavor text"));
|
||||
untag(current_card, _("illustrator"));
|
||||
untag(current_card, _("copyright"));
|
||||
untag(current_card, _("power"));
|
||||
untag(current_card, _("toughness"));
|
||||
// translate mtg editor tags to mse2 tags
|
||||
translateTags(current_card->value<TextValue>(_("rule text")).value.mutate());
|
||||
// add the card to the set
|
||||
set->cards.push_back(current_card);
|
||||
}
|
||||
first = false;
|
||||
current_card = new_shared1<Card>(*set->game);
|
||||
target = ¤t_card->value<TextValue>(_("name")).value;
|
||||
} else if (line == _("#DATE##########")) { // date
|
||||
// remember date for generation of illustration filename
|
||||
target = nullptr;
|
||||
card_date = file.ReadLine();
|
||||
} else if (line == _("#TYPE##########")) { // super type
|
||||
target = ¤t_card->value<TextValue>(_("super type")).value;
|
||||
} else if (line == _("#SUBTYPE#######")) { // sub type
|
||||
target = ¤t_card->value<TextValue>(_("sub type")).value;
|
||||
} else if (line == _("#COST##########")) { // casting cost
|
||||
target = ¤t_card->value<TextValue>(_("casting cost")).value;
|
||||
} else if (line == _("#RARITY########") || line == _("#FREQUENCY#####")) { // rarity
|
||||
target = 0;
|
||||
line = file.ReadLine();
|
||||
if (line == _("0")) current_card->value<ChoiceValue>(_("rarity")).value.assign(_("common"));
|
||||
else if (line == _("1")) current_card->value<ChoiceValue>(_("rarity")).value.assign(_("uncommon"));
|
||||
else current_card->value<ChoiceValue>(_("rarity")).value.assign(_("rare"));
|
||||
} else if (line == _("#COLOR#########")) { // card color
|
||||
target = 0;
|
||||
line = file.ReadLine();
|
||||
current_card->value<ChoiceValue>(_("card color")).value.assign(line);
|
||||
} else if (line == _("#AUTOBG########")) { // card color.isDefault
|
||||
target = 0;
|
||||
line = file.ReadLine();
|
||||
if (line == _("TRUE")) {
|
||||
current_card->value<ChoiceValue>(_("card color")).value.makeDefault();
|
||||
}
|
||||
} else if (line == _("#RULETEXT######")) { // rule text
|
||||
target = ¤t_card->value<TextValue>(_("rule text")).value;
|
||||
} else if (line == _("#FLAVORTEXT####")) { // flavor text
|
||||
target = ¤t_card->value<TextValue>(_("flavor text")).value;
|
||||
} else if (line == _("#ARTIST########")) { // illustrator
|
||||
target = ¤t_card->value<TextValue>(_("illustrator")).value;
|
||||
} else if (line == _("#COPYRIGHT#####")) { // copyright
|
||||
target = ¤t_card->value<TextValue>(_("copyright")).value;
|
||||
} else if (line == _("#POWER#########")) { // power
|
||||
target = ¤t_card->value<TextValue>(_("power")).value;
|
||||
} else if (line == _("#TOUGHNESS#####")) { // toughness
|
||||
target = ¤t_card->value<TextValue>(_("toughness")).value;
|
||||
} else if (line == _("#ILLUSTRATION##") || line == _("#ILLUSTRATION8#")) { // image
|
||||
target = 0;
|
||||
line = file.ReadLine();
|
||||
if (!wxFileExists(line)) {
|
||||
// based on card name and date
|
||||
line = filter1(filename) + set_date + _("/") +
|
||||
filter2(current_card->value<TextValue>(_("name")).value()) + card_date + _(".jpg");
|
||||
}
|
||||
// copy image into set
|
||||
if (wxFileExists(line)) {
|
||||
String image_file = set->newFileName(_("image"),_(""));
|
||||
if (wxCopyFile(line, set->nameOut(image_file), true)) {
|
||||
current_card->value<ImageValue>(_("image")).filename = image_file;
|
||||
}
|
||||
}
|
||||
} else if (line == _("#TOMBSTONE#####")) { // tombstone
|
||||
target = 0;
|
||||
line = file.ReadLine();
|
||||
current_card->value<ChoiceValue>(_("card symbol")).value.assign(
|
||||
line==_("TRUE") ? _("tombstone") : _("none")
|
||||
);
|
||||
} else {
|
||||
// normal text
|
||||
if (target != 0) { // value of a text field
|
||||
if (!target->isDefault()) target->mutate() += _("\n");
|
||||
target->mutate() += line;
|
||||
} else {
|
||||
throw ParseError(_("Error in Mtg Editor file, unexpected text:\n") + line);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// set defaults for artist and copyright to that of the first card
|
||||
if (!set->cards.empty()) {
|
||||
String artist = set->cards[0]->value<TextValue>(_("illustrator")).value();
|
||||
String copyright = set->cards[0]->value<TextValue>(_("copyright")) .value();
|
||||
set->value<TextValue>(_("artist")) .value.assign(artist);
|
||||
set->value<TextValue>(_("copyright")).value.assign(copyright);
|
||||
// which cards have this value?
|
||||
FOR_EACH(card, set->cards) {
|
||||
Defaultable<String>& card_artist = card->value<TextValue>(_("illustrator")).value;
|
||||
Defaultable<String>& card_copyright = card->value<TextValue>(_("copyright")) .value;
|
||||
if (card_artist() == artist) card_artist.makeDefault();
|
||||
if (card_copyright() == copyright) card_copyright.makeDefault();
|
||||
}
|
||||
}
|
||||
|
||||
// Load stylesheet
|
||||
if (layout != _("8e")) {
|
||||
set->stylesheet = StyleSheet::byGameAndName(*set->game, _("old"));
|
||||
} else {
|
||||
set->stylesheet = StyleSheet::byGameAndName(*set->game, _("new"));
|
||||
}
|
||||
|
||||
return set;
|
||||
}
|
||||
|
||||
// ----------------------------------------------------------------------------- : Filtering
|
||||
|
||||
String MtgEditorFileFormat::filter1(const String& str) {
|
||||
String before, after, ret;
|
||||
// split path name
|
||||
size_t pos = str.find_last_of(_("/\\"));
|
||||
if (pos == String::npos) {
|
||||
before = _(""); after = str;
|
||||
} else {
|
||||
before = str.substr(0, pos + 1);
|
||||
after = str.substr(pos + 1);
|
||||
}
|
||||
// filter
|
||||
FOR_EACH(c, after) {
|
||||
if (isAlnum(c)) ret += c;
|
||||
else ret += _('_');
|
||||
}
|
||||
return before + ret;
|
||||
}
|
||||
|
||||
String MtgEditorFileFormat::filter2(const String& str) {
|
||||
String ret;
|
||||
FOR_EACH_CONST(c, str) {
|
||||
if (isAlnum(c)) ret += c;
|
||||
else if (c==_(' ') || c==_('-')) ret += _('_');
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
void MtgEditorFileFormat::untag(const CardP& card, const String& field) {
|
||||
Defaultable<String>& value = card->value<TextValue>(field).value;
|
||||
value.assignDontChangeDefault(untag_no_escape(value()));
|
||||
}
|
||||
|
||||
|
||||
void MtgEditorFileFormat::translateTags(String& value) {
|
||||
// Translate tags
|
||||
String ret;
|
||||
size_t pos = 0;
|
||||
while (pos < value.size()) {
|
||||
Char c = value.GetChar(pos);
|
||||
++pos;
|
||||
if (c == _('<')) {
|
||||
String tag;
|
||||
while (pos < value.size()) {
|
||||
c = value.GetChar(pos);
|
||||
++pos;
|
||||
if (c == _('>')) break;
|
||||
else tag += c;
|
||||
}
|
||||
tag.MakeUpper();
|
||||
unsigned long number;
|
||||
if (tag==_("W") || tag==_("U") || tag==_("B") || tag==_("R") || tag==_("G") || tag==_("X") || tag==_("Y") || tag==_("Z")) {
|
||||
ret += _("<sym>") + tag + _("</sym>");
|
||||
} else if (tag.ToULong(&number)) {
|
||||
ret += _("<sym>") + tag + _("</sym>");
|
||||
} else if (tag==_("T") || tag==_("TAP")) {
|
||||
ret += _("<sym>T</sym>");
|
||||
} else if (tag==_("THIS")) {
|
||||
ret += _("~");
|
||||
}
|
||||
} else {
|
||||
ret += c;
|
||||
}
|
||||
}
|
||||
// Join adjecent symbol sections
|
||||
value = replace_all(ret, _("</sym><sym>"), _(""));
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user