diff --git a/README.md b/README.md index e790e90..49ef5fa 100644 --- a/README.md +++ b/README.md @@ -1,23 +1,23 @@ -# UndertaleSaveEditor +## UndertaleSaveEditor +With Undertale Save Editor you can easily modify your Undertale save files. +Both *file0* and *undertale.ini* are supported. -If you're just looking for the executable (.exe file): You'll find it in the **[releases](https://github.com/Cofeiini/UndertaleSaveEditor/releases/)**. -*** -##### Some thoughts on compiling -If you, for some reason, want to compile this yourself, just open the ".pro" file with Qt Creator. Or use any method you like, that's just the way I do it. +Compiled with [MinGW](http://mingw.org/) +Compressed with [UPX](http://upx.sourceforge.net/) -For this project I used Qt 5.5.1 with STATIC linking, because I don't like having library files hanging loose from my executables. -I'm not sure if it works with older versions, since I recall using functions introduced in version 5.5.1 +## Download +The executables can be found in the **[releases](https://github.com/Cofeiini/UndertaleSaveEditor/releases/)**. -Also, I used Qmake and MinGW. -*** -Right now it's a mess. I intend to cleanup the code, replace images with some my own artwork and do something else I'm most likely forgetting. +## Compiling with Qt Creator +Just open the "UndertaleSaveEditor.pro" file with Qt Creator and click run. +Qt 5.10.1 was used for this project. -##### Something I'm forgetting: -- [x] Move settings to a dialog instead of a clumsy menu -- [ ] Place entries in groups -- [ ] Organize content with something (maybe tabs or toolbox) -- [ ] Add support for .ini files -- [ ] Add preset function, like a "Time Machine" -- [ ] Add option to "Reset", "True Reset" and "Undo Genocide" -- [ ] Add "Real-time Monitor" to watch save file for changes while playing -- [ ] Add "Change Highlighter" for "Real-time Monitor" +## Tested on following operating systems: +Operating System | Test Results +---|--- +Windows XP SP3 | **Working** +Windows 7 SP1 | **Working** +Windows 10 | **Working** +Ubuntu 16.04 | **Working** +Ubuntu 18.04 | **Working** +MacOS High Sierra | **Working** diff --git a/RELEASE.md b/RELEASE.md index 97e1636..4645008 100644 --- a/RELEASE.md +++ b/RELEASE.md @@ -3,8 +3,9 @@ Compressed with [UPX](http://upx.sourceforge.net/) #### Tested on following operating systems: Operating System | Test Results ---|--- -* Windows 10 (x64)|**Working** -* Windows 8 (x64)|**Working** -* Windows 7 SP1 (x64)|**Working** -* Windows XP SP3 (x86)|**Working** -* Ubuntu 15.10 (Wine 1.8-rc3)|**Working**, but can be slow when changing filters. +* Windows 10 (x64) | **Needs testing** +* Windows 8 (x64) | **Needs testing** +* Windows 7 SP1 (x64) | **Needs testing** +* Windows XP SP3 (x86) | **Needs testing** +* Ubuntu 18.04 | **Needs testing** +* MacOS High Sierra | **Needs testing** diff --git a/UndertaleSaveEditor.pro b/UndertaleSaveEditor.pro index a7da92a..825fa99 100644 --- a/UndertaleSaveEditor.pro +++ b/UndertaleSaveEditor.pro @@ -1,20 +1,33 @@ -CONFIG += static -greaterThan(QT_MAJOR_VERSION, 4): QT += widgets -QT += core gui -RC_ICONS = icon.ico -TARGET = UndertaleSaveEditor -TEMPLATE = app -VERSION = 0.4 - -FORMS += mainwindow.ui - -HEADERS += mainwindow.h\ - configdialog.h \ - dataeditor.h - -RESOURCES += assets.qrc - -SOURCES += main.cpp\ - mainwindow.cpp\ - configdialog.cpp \ - dataeditor.cpp +QT += core gui + +greaterThan(QT_MAJOR_VERSION, 4): QT += network widgets + +TARGET = UndertaleSaveEditor +TEMPLATE = app + +DEFINES += QT_DEPRECATED_WARNINGS + +win32:RC_FILE = win_ico.rc +macx:ICON = icon.icns + +CONFIG += static +VERSION = 1.0 +DEFINES += APP_VERSION=\\\"$$VERSION\\\" + +linux:QMAKE_LFLAGS += -no-pie + +SOURCES += \ + main.cpp\ + mainwindow.cpp \ + initools.cpp \ + pages.cpp \ + tools.cpp + +HEADERS += \ + mainwindow.h \ + initools.h \ + pages.h \ + tools.h + +RESOURCES += \ + assets.qrc diff --git a/assets.qrc b/assets.qrc index d2f85d1..33f9fbd 100644 --- a/assets.qrc +++ b/assets.qrc @@ -1,24 +1,14 @@ - - - images/box.png - images/flowey.png - strings/infofile - images/truechara.png - images/save.png - images/heart.png - images/amalgam_save.png - images/asriel.png - images/heartgtfo.png - images/heartbreak.png - images/tobdog.png - images/spaghetti.png - strings/dullfile - strings/rangefile - strings/typefile - strings/freshfile - strings/sortfile - strings/undertale.ini - images/tobdog_wrench.png - strings/roomfile - - + + + images/ico_player.png + images/ico_toriel.png + images/ico_napstablook.png + images/ico_dogshrine.png + images/ico_savepoint.png + images/ico_debug.png + images/ico_floppy.png + images/ico_floppy_red.png + fonts/Vegur-Regular.otf + images/icon.png + + diff --git a/configdialog.cpp b/configdialog.cpp deleted file mode 100644 index f048ed4..0000000 --- a/configdialog.cpp +++ /dev/null @@ -1,499 +0,0 @@ -#include "configdialog.h" - -ConfigDialog::ConfigDialog(QWidget *parent) : QDialog(parent) -{ - setWindowTitle("Settings"); - setWindowIcon(QIcon(":/images/tobdog_wrench.png")); - - configTab = new QTabWidget; - configTab->addTab(new DefaultsTab(this), "Defaults"); - configTab->addTab(new FiltersTab(this), "Filters"); - - configBox = new QDialogButtonBox(QDialogButtonBox::Ok | QDialogButtonBox::Cancel); - connect(configBox, SIGNAL(accepted()), this, SLOT(accept())); - connect(configBox, SIGNAL(rejected()), this, SLOT(reject())); - - QVBoxLayout *verticalContainer = new QVBoxLayout; - verticalContainer->addWidget(configTab); - verticalContainer->addWidget(configBox); - verticalContainer->setSizeConstraint(QLayout::SetFixedSize); - setLayout(verticalContainer); - - QObject *dTab = findChild("", Qt::FindChildrenRecursively); - QObject *fTab = findChild("", Qt::FindChildrenRecursively); - - connect(this, SIGNAL(initiator()), dTab, SLOT(initializer())); - connect(this, SIGNAL(transmitter(QString,QVariant)), dTab, SLOT(reciever(QString,QVariant))); - connect(this, SIGNAL(transmitter(QString,QVariant)), fTab, SLOT(reciever(QString,QVariant))); - connect(this, SIGNAL(configTransmitter()), parent, SLOT(configReciever())); -} - -void ConfigDialog::initSettings() -{ - int screen = QApplication::desktop()->screenNumber(QCursor::pos()); - int mResWidth = QApplication::desktop()->screen(screen)->width(); - int mResHeight = QApplication::desktop()->screen(screen)->height(); - - QWidget *w = NULL; - QString cName; - foreach (QWidget *var, QApplication::topLevelWidgets()) - { - cName = var->metaObject()->className(); - if(cName == "MainWindow") - { - w = var; - } - } - QSettings config(QSettings::IniFormat, QSettings::UserScope, QApplication::organizationName(), QApplication::applicationDisplayName()); - config.beginGroup("MainWindow"); - edict["maximized"] = config.value("maximized", false); - edict["size"] = config.value("size", QSize(w->property("minimumWidth").toInt(), w->property("minimumHeight").toInt())); - edict["position"] = config.value("position", QPoint((mResWidth/2) - (w->property("minimumWidth").toInt()/2), (mResHeight/2) - (w->property("minimumHeight").toInt()/2))); - config.endGroup(); - config.beginGroup("Settings"); - edict["file"] = config.value("file", "file0"); - edict["directory"] = config.value("directory", QDir::homePath() + "/AppData/Local/UNDERTALE/"); - edict["loadfile"] = config.value("loadfile", false); - edict["loaddir"] = config.value("loaddir", false); - edict["confirmsave"] = config.value("confirmsave", true); - edict["rememberlastdir"] = config.value("rememberlastdir", true); - config.endGroup(); - config.beginGroup("Filters"); - edict["hideboolean"] = config.value("hideboolean", false); - edict["hidecomment"] = config.value("hidecomment", true); - edict["hidecounter"] = config.value("hidecounter", false); - edict["hidenumber"] = config.value("hidenumber", false); - edict["hiderange"] = config.value("hiderange", false); - edict["hideunused"] = config.value("hideunused", true); - config.endGroup(); -} - -void ConfigDialog::showEvent(QShowEvent *event) -{ - QDialog::showEvent(event); - - emit initiator(); // To set dial values and ranges; prevents the window from jumping around when config is opened. - initSettings(); // To load settings from ini file. - - QWidget *w = NULL; - QString cName; - foreach (QWidget *var, QApplication::topLevelWidgets()) - { - cName = var->metaObject()->className(); - if(cName == "MainWindow") - { - w = var; - } - } - foreach(QString key, edict.keys()) - { - if(key == "position") - { - edict["position"] = w->property("pos"); - } - transmitter(key, edict.value(key)); - } -} - -void ConfigDialog::boolReciever(const bool &value) -{ - QString dummy = sender()->objectName(); - foreach(QString key, edict.keys()) - { - if(dummy == key) - { - edict[key] = value; - } - } -} - -void ConfigDialog::intReciever(const int &value) -{ - QString dummy = sender()->objectName(); - if(dummy == "mainw" || dummy == "mainh") - { - QSize mainSize = edict.value("size").toSize(); - if(dummy == "mainw") - { - mainSize.setWidth(value); - } - if(dummy == "mainh") - { - mainSize.setHeight(value); - } - edict["size"] = mainSize; - if(!edict.value("maximized").toBool()) - { - parent()->setProperty("size", mainSize); - } - } - - if(dummy == "mainx" || dummy == "mainy") - { - QPoint mainPos = edict.value("position").toPoint(); - if(dummy == "mainx") - { - mainPos.setX(value); - } - if(dummy == "mainy") - { - mainPos.setY(value); - } - edict["position"] = mainPos; - if(!edict.value("maximized").toBool()) - { - parent()->setProperty("pos", mainPos); - } - } -} - -void ConfigDialog::stringReciever(const QString &target, const QString &value) -{ - if(target == "dir") - { - edict["directory"] = value; - } - if(target == "file") - { - edict["file"] = value; - } -} - -void ConfigDialog::accept() -{ - QString group; - QSettings config(QSettings::IniFormat, QSettings::UserScope, QApplication::organizationName(), QApplication::applicationDisplayName()); - foreach(QString key, config.allKeys()) - { - group = key.section("/", 0, 0); - key = key.section("/", -1); - config.beginGroup(group); - config.setValue(key, edict.value(key)); - config.endGroup(); - } - emit configTransmitter(); - done(Accepted); -} - -void ConfigDialog::reject() -{ - done(Rejected); -} - -DefaultsTab::DefaultsTab(QWidget *parent) : QWidget(parent) -{ - QGridLayout *dialLayout = new QGridLayout; - QGridLayout *mainLayout = new QGridLayout; - - autoDirLabel = new QLabel; - autoFileLabel = new QLabel; - QCheckBox *autoDir = new QCheckBox("Load Working Directory"); - QCheckBox *autoFile = new QCheckBox("Load Working File"); - QCheckBox *mainMaximized = new QCheckBox("Start Maximized"); - QCheckBox *saveNag = new QCheckBox("Confirm Overwriting"); - QCheckBox *totalRecall = new QCheckBox("Remember Last Directory"); - QDial *mainH = new QDial; - QDial *mainW = new QDial; - QDial *mainX = new QDial; - QDial *mainY = new QDial; - QLabel *mainHLabel = new QLabel; - QLabel *mainWLabel = new QLabel; - QLabel *mainXLabel = new QLabel; - QLabel *mainYLabel = new QLabel; - QPushButton *autoDirBrowse = new QPushButton("..."); - QPushButton *autoFileBrowse = new QPushButton("..."); - - autoDir->setSizePolicy(QSizePolicy::Maximum, QSizePolicy::Fixed); - autoDirBrowse->setSizePolicy(QSizePolicy::Maximum, QSizePolicy::Fixed); - autoDirLabel->setFrameStyle(QFrame::Panel); - autoFile->setSizePolicy(QSizePolicy::Maximum, QSizePolicy::Fixed); - autoFileBrowse->setSizePolicy(QSizePolicy::Maximum, QSizePolicy::Fixed); - autoFileLabel->setFrameStyle(QFrame::Panel); - mainHLabel->setAlignment(Qt::AlignCenter); - mainHLabel->setFrameStyle(QFrame::Panel); - mainHLabel->setSizePolicy(QSizePolicy::Minimum, QSizePolicy::Fixed); - mainMaximized->setSizePolicy(QSizePolicy::Maximum, QSizePolicy::Fixed); - mainWLabel->setAlignment(Qt::AlignCenter); - mainWLabel->setFrameStyle(QFrame::Panel); - mainWLabel->setSizePolicy(QSizePolicy::Minimum, QSizePolicy::Fixed); - mainXLabel->setAlignment(Qt::AlignCenter); - mainXLabel->setFrameStyle(QFrame::Panel); - mainXLabel->setSizePolicy(QSizePolicy::Minimum, QSizePolicy::Fixed); - mainYLabel->setAlignment(Qt::AlignCenter); - mainYLabel->setFrameStyle(QFrame::Panel); - mainYLabel->setSizePolicy(QSizePolicy::Minimum, QSizePolicy::Fixed); - - autoDir->setObjectName("loaddir"); - autoDirBrowse->setObjectName("dirbrowse"); - autoDirLabel->setObjectName("directory"); - autoFile->setObjectName("loadfile"); - autoFileBrowse->setObjectName("filebrowse"); - autoFileLabel->setObjectName("file"); - mainH->setObjectName("mainh"); - mainHLabel->setObjectName("hlabel"); - mainMaximized->setObjectName("maximized"); - mainW->setObjectName("mainw"); - mainWLabel->setObjectName("wlabel"); - mainX->setObjectName("mainx"); - mainXLabel->setObjectName("xlabel"); - mainY->setObjectName("mainy"); - mainYLabel->setObjectName("ylabel"); - saveNag->setObjectName("confirmsave"); - totalRecall->setObjectName("rememberlastdir"); - - dialLayout->addWidget(mainW, 0, 0, 1, 1, Qt::AlignJustify); - dialLayout->addWidget(mainWLabel, 1, 0, 1, 1, Qt::AlignJustify); - dialLayout->addWidget(mainH, 0, 1, 1, 1, Qt::AlignJustify); - dialLayout->addWidget(mainHLabel, 1, 1, 1, 1, Qt::AlignJustify); - dialLayout->addWidget(mainX, 0, 2, 1, 1, Qt::AlignJustify); - dialLayout->addWidget(mainXLabel, 1, 2, 1, 1, Qt::AlignJustify); - dialLayout->addWidget(mainY, 0, 3, 1, 1, Qt::AlignJustify); - dialLayout->addWidget(mainYLabel, 1, 3, 1, 1, Qt::AlignJustify); - - mainLayout->setSizeConstraint(QLayout::SetFixedSize); - mainLayout->addWidget(mainMaximized, 0, 0); - mainLayout->addItem(dialLayout, 0, 1, 1, 4, Qt::AlignCenter); - mainLayout->addWidget(autoFile, 1, 0); - mainLayout->addWidget(autoFileLabel, 1, 1, 1, 4); - mainLayout->addWidget(autoFileBrowse, 1, 5); - mainLayout->addWidget(autoDir, 2, 0); - mainLayout->addWidget(autoDirLabel, 2, 1, 1, 4); - mainLayout->addWidget(autoDirBrowse, 2, 5); - mainLayout->addWidget(saveNag, 3, 0); - mainLayout->addWidget(totalRecall, 4, 0); - setLayout(mainLayout); - - items.append(mainMaximized); - items.append(mainW); - items.append(mainWLabel); - items.append(mainH); - items.append(mainHLabel); - items.append(mainX); - items.append(mainXLabel); - items.append(mainY); - items.append(mainYLabel); - items.append(autoFile); - items.append(autoFileLabel); - items.append(autoDir); - items.append(autoDirLabel); - items.append(saveNag); - items.append(totalRecall); - - QString cName; - foreach (QWidget *var, items) - { - cName = var->metaObject()->className(); - if(cName == "QCheckBox") - { - connect(var, SIGNAL(clicked(bool)), parent, SLOT(boolReciever(bool))); - } - if(cName == "QDial") - { - connect(var, SIGNAL(valueChanged(int)), parent, SLOT(intReciever(int))); - } - } - connect(mainW, SIGNAL(valueChanged(int)), mainWLabel, SLOT(setNum(int))); - connect(mainH, SIGNAL(valueChanged(int)), mainHLabel, SLOT(setNum(int))); - connect(mainX, SIGNAL(valueChanged(int)), mainXLabel, SLOT(setNum(int))); - connect(mainY, SIGNAL(valueChanged(int)), mainYLabel, SLOT(setNum(int))); - connect(autoFileBrowse, SIGNAL(released()), this, SLOT(fileBrowse())); - connect(autoDirBrowse, SIGNAL(released()), this, SLOT(fileBrowse())); - connect(this, SIGNAL(stringTransmitter(QString, QString)), parent, SLOT(stringReciever(QString, QString))); -} - -void DefaultsTab::initializer() -{ - QWidget *w = NULL; - QString cName, oName; - QRect desk = QApplication::desktop()->frameGeometry(); - - foreach (QWidget *var, QApplication::topLevelWidgets()) - { - cName = var->metaObject()->className(); - if(cName == "MainWindow") - { - w = var; - } - } - foreach (QWidget *var, items) - { - cName = var->metaObject()->className(); - oName = var->objectName(); - if(cName == "QDial") - { - var->blockSignals(true); - if(oName == "mainw") - { - var->setProperty("minimum", w->minimumWidth()); - var->setProperty("maximum", desk.width()); - var->setProperty("value", w->width()); - } - if(oName == "mainh") - { - var->setProperty("minimum", w->minimumHeight()); - var->setProperty("maximum", desk.height()); - var->setProperty("value", w->height()); - } - if(oName == "mainx") - { - var->setProperty("minimum", 0 - w->minimumWidth()); - var->setProperty("maximum", desk.x() + desk.width()); - var->setProperty("value", w->x()); - } - if(oName == "mainy") - { - var->setProperty("minimum", 0 - w->minimumHeight()); - var->setProperty("maximum", desk.y() + desk.height()); - var->setProperty("value", w->y()); - } - var->setProperty("minimumSize", QSize(75,75)); - var->setProperty("maximumSize", QSize(75,75)); - var->setProperty("notchesVisible", true); - var->setProperty("notchTarget", 14.8); - var->blockSignals(false); - } - if(cName == "QLabel") - { - if(oName == "wlabel") - { - var->setProperty("text", w->width()); - } - if(oName == "hlabel") - { - var->setProperty("text", w->height()); - } - if(oName == "xlabel") - { - var->setProperty("text", w->x()); - } - if(oName == "ylabel") - { - var->setProperty("text", w->y()); - } - } - } -} - -void DefaultsTab::fileBrowse() -{ - QString dummy = sender()->objectName(); - - if(dummy == "filebrowse") - { - QString target = QFileDialog::getOpenFileName(this, "Choose File", workDir.absolutePath()); - if(target == NULL) - { - return; - } - workFile.setFileName(target.section("/", -1)); - autoFileLabel->setText(workFile.fileName()); - emit stringTransmitter("file", workFile.fileName()); - } - else if(dummy == "dirbrowse") - { - QString target = QFileDialog::getExistingDirectory(this, "Choose Directory", workDir.absolutePath()); - if(target == NULL) - { - return; - } - workDir.setPath(target); - autoDirLabel->setText(workDir.absolutePath()); - emit stringTransmitter("dir", workDir.absolutePath()); - } -} - -void DefaultsTab::reciever(const QString &target, const QVariant &value) -{ - QString cName; - if(target == "file") - { - workFile.setFileName(value.toString()); - } - if(target == "directory") - { - workDir.setPath(value.toString()); - } - foreach (QWidget *var, items) - { - cName = var->metaObject()->className(); - if(target == var->objectName()) - { - if(cName == "QCheckBox") - { - var->setProperty("checked", value.toBool()); - } - if(cName == "QDial") - { - var->setProperty("value", value.toInt()); - } - if(cName == "QLabel") - { - var->setProperty("text", value.toString()); - } - } - } -} - -FiltersTab::FiltersTab(QWidget *parent) : QWidget(parent) -{ - - QVBoxLayout *mainLayout = new QVBoxLayout; - - QCheckBox *skipBool = new QCheckBox("Hide Boolean"); - skipBool->setObjectName("hideboolean"); - mainLayout->addWidget(skipBool); - items.append(skipBool); - - QCheckBox *skipCount = new QCheckBox("Hide Counter"); - skipCount->setObjectName("hidecounter"); - mainLayout->addWidget(skipCount); - items.append(skipCount); - - QCheckBox *skipRange = new QCheckBox("Hide Range"); - skipRange->setObjectName("hiderange"); - mainLayout->addWidget(skipRange); - items.append(skipRange); - - QCheckBox *skipNull = new QCheckBox("Hide Unused"); - skipNull->setObjectName("hideunused"); - mainLayout->addWidget(skipNull); - items.append(skipNull); - - QCheckBox *skipDull = new QCheckBox("Hide Comments"); - skipDull->setObjectName("hidecomment"); - mainLayout->addWidget(skipDull); - items.append(skipDull); - - QCheckBox *skipNum = new QCheckBox("Hide ID Number"); - skipNum->setObjectName("hidenumber"); - mainLayout->addWidget(skipNum); - items.append(skipNum); - - setLayout(mainLayout); - - QString cName; - foreach (QWidget *var, items) - { - cName = var->metaObject()->className(); - if(cName == "QCheckBox") - { - connect(var, SIGNAL(clicked(bool)), parent, SLOT(boolReciever(bool))); - } - } -} - -void FiltersTab::reciever(const QString &target, const QVariant &value) -{ - QString cName; - foreach (QWidget *var, items) - { - cName = var->metaObject()->className(); - if(target == var->objectName()) - { - if(cName == "QCheckBox") - { - var->setProperty("checked", value.toBool()); - } - } - } -} diff --git a/configdialog.h b/configdialog.h deleted file mode 100644 index baea5c5..0000000 --- a/configdialog.h +++ /dev/null @@ -1,79 +0,0 @@ -#ifndef CONFIGDIALOG_H -#define CONFIGDIALOG_H - -#include -#include -#include -#include -#include -#include - -class ConfigDialog : public QDialog -{ - Q_OBJECT - -protected: - void showEvent(QShowEvent *event) Q_DECL_OVERRIDE; - -signals: - void configTransmitter(); - void initiator(); - void transmitter(const QString &target, const QVariant &value); - -private slots: - void accept(); - void boolReciever(const bool &value); - void intReciever(const int &value); - void reject(); - void stringReciever(const QString &target, const QString &value); - -public: - explicit ConfigDialog(QWidget *parent = 0); - -private: - QDialogButtonBox *configBox; - QMap edict; - QString workPath; - QTabWidget *configTab; - void initSettings(); - -}; - -class DefaultsTab : public QWidget -{ - Q_OBJECT - -signals: - void stringTransmitter(const QString &target, const QString &value); - -private slots: - void fileBrowse(); - void initializer(); - void reciever(const QString &target, const QVariant &value); - -public: - explicit DefaultsTab(QWidget *parent = 0); - -private: - QDir workDir; - QFile workFile; - QLabel *autoDirLabel; - QLabel *autoFileLabel; - QVector items; -}; - -class FiltersTab : public QWidget -{ - Q_OBJECT - -private slots: - void reciever(const QString &target, const QVariant &value); - -public: - explicit FiltersTab(QWidget *parent = 0); - -private: - QVector items; -}; - -#endif // CONFIGDIALOG_H diff --git a/dataeditor.cpp b/dataeditor.cpp deleted file mode 100644 index a843457..0000000 --- a/dataeditor.cpp +++ /dev/null @@ -1,340 +0,0 @@ -#include "dataeditor.h" - -DataEditor::DataEditor(QWidget *parent, int index) : QComboBox(parent) -{ - if(index == 0) - { - InventoryEditor(); - } - else - { - StatusEditor(index); - } -} - -void DataEditor::InventoryEditor() -{ - id = 0; - QStringList allItems = (QStringList() << "" << "Monster Candy" << "Croquet Roll" << "Stick" << "Bandage" << "Rock Candy" << "Pumpkin Rings" << "Spider Donut" << "Stoic Onion" << "Ghost Fruit" << "Spider Cider" << "Butterscotch Pie" << "Faded Ribbon" << "Toy Knife" << "Tough Glove" << "Manly Bandanna" << "Snowman Piece" << "Nice Cream" << "Puppydough Ice cream" << "Bisicle" << "Unisicle" << "Cinnamon Bun" << "Temmie Flakes" << "Abandoned Quiche" << "Old Tutu" << "Ballet Shoes" << "Punch Card" << "Annoying Dog" << "Dog Salad" << "Dog Residue" << "Dog Residue" << "Dog Residue" << "Dog Residue" << "Dog Residue" << "Dog Residue" << "Astronaut Food" << "Instant Noodles" << "Crab Apple" << "Hot Dog...?" << "Hot Cat" << "Glamburger" << "Sea Tea" << "Starfait" << "Legendary Hero" << "Cloudy Glasses" << "Torn Notebook" << "Stained Apron" << "Burnt Pan" << "Cowboy Hat" << "Empty Gun" << "Heart Locket" << "Worn Dagger" << "Real Knife" << "The Locket" << "Bad Memory" << "Dream" << "Undyne's Letter" << "Undyne Letter EX" << "Potato Chips" << "Junk Food" << "Mystery Key" << "Face Steak" << "Hush Puppy" << "Snail Pie" << "temy armor"); - QStandardItemModel *inventoryModel = new QStandardItemModel(); - foreach (QString var, allItems) - { - QStandardItem *newItem = new QStandardItem(var); - inventoryModel->appendRow(newItem); - } - setModel(inventoryModel); -} - -void DataEditor::recieveValue(int num) -{ - switch(id) - { - case 98: - switch(num) - { - case -3: - num = 0; - break; - case -2: - num = 1; - break; - case -1: - num = 2; - break; - case 0: - num = 3; - break; - case 1: - num = 4; - break; - } - break; - case 231: - num -= 202; - break; - case 548: - QRegExp rx(QString::number(num) + ".*"); - num = rooms.indexOf(rx); - break; - } - setCurrentIndex(num); -} - -void DataEditor::trueIndexValue(int num) -{ - switch(id) - { - case 98: - switch(num) - { - case 0: - num = -3; - break; - case 1: - num = -2; - break; - case 2: - num = -1; - break; - case 3: - num = 0; - break; - case 4: - num = 1; - break; - } - break; - case 231: - switch(num) - { - case 0: - num = 202; - break; - case 1: - num = 203; - break; - case 2: - num = 204; - break; - case 3: - num = 205; - break; - } - break; - case 548: - QString dummy = rooms.value(num); - num = dummy.section("#", 0, 0).toInt(); - break; - } - - emit transmitData(num); -} - -PhoneEditor::PhoneEditor(QWidget *parent) : QComboBox(parent) -{ - QStringList allCalls = (QStringList() << "" << "Say Hello" << "Puzzle Help" << "About Yourself" << "Call Her \"Mom\"" << "Flirt" << "Toriel's Phone" << "Papyrus's Phone" << "Dimensional Box A" << "Dimensional Box B"); - QStandardItemModel *phoneModel = new QStandardItemModel(); - foreach (QString var, allCalls) - { - QStandardItem *newItem = new QStandardItem(var); - phoneModel->appendRow(newItem); - } - connect(this, SIGNAL(currentIndexChanged(int)), this, SLOT(recieveValue(int))); - setModel(phoneModel); -} - -void PhoneEditor::recieveValue(int num) -{ - switch(num) - { - case 0: - setCurrentIndex(0); - break; - case 7: - num = 210; - break; - case 8: - num = 220; - break; - case 9: - num = 221; - break; - case 210: - setCurrentIndex(7); - break; - case 220: - setCurrentIndex(8); - break; - case 221: - setCurrentIndex(9); - break; - default: - if(num < 200) - { - setCurrentIndex(num); - num += 200; - } - else - { - setCurrentIndex(num - 200); - } - break; - } - emit transmitData(num); -} - -void DataEditor::StatusEditor(int index) -{ - id = index; - QStringList statusList; - switch(index) - { - case 45: - statusList << "Flee" << "Kill" << "Talk" << "Bored"; - break; - case 53: - statusList << "Yellow names" << "White names" << "Pink names"; - break; - case 76: - statusList << "1st time visiting Home" << "Disobey" << "?2?" << "Fight" << "Kill" << "Spare"; - break; - case 77: - statusList << "" << "Butterscotch" << "Cinnamon"; - break; - case 83: - statusList << "Spare" << "Kill" << "Used Stick"; - break; - case 84: - statusList << "Spare" << "Kill" << "Used Stick"; - break; - case 85: - statusList << "Spare" << "Kill" << "Used Stick" << "Bored"; - break; - case 86: - statusList << "Spare" << "Kill" << "Maximum petting"; - break; - case 87: - statusList << "" << "Got a piece" << "Got another piece" << "???" << "The Snowman saw you eat the piece" << "Tried to talk after being spotted eating snow"; - break; - case 88: - statusList << "Spare" << "Laugh at joke" << "Kill"; - break; - case 89: - statusList << "Junior Jumble" << "Crosswords"; - break; - case 93: - statusList << "" << "Ate it" << "Left it"; - break; - case 98: - statusList << "Skip fight" << "Captured, 2nd time" << "Captured, 1st time" << "Spare" << "Kill"; - break; - case 103: - statusList << "" << "Stayed at the inn" << "Not enough GOLD"; - break; - case 107: - statusList << "Told the truth" << "Lied about clothes"; - break; - case 112: - statusList << "" << "Kill" << "Musical career"; - break; - case 119: - statusList << "" << "Outside the house" << "Inside the house" << "Unlock room" << "Date complete"; - break; - case 120: - statusList << "" << "Begin date" << "Date complete"; - break; - case 121: - statusList << "" << "Met without an umbrella" << "Went back to get an umbrella" << "Went back again to get rid of the umbrella"; - break; - case 123: - statusList << "" << "It's a horse stable." << "Do you want to go inside?" << "You jostle the door." << "It's locked."; - break; - case 124: - statusList << "" << "Talk" << "?2?" << "Lie on the ground" << "?4?" << "?5?" << "?6?" << "?7?" << "?8?" << "Don't lie on the ground"; - break; - case 125: - statusList << "" << "Spooktunes" << "Spookwave" << "Ghouliday Music"; - break; - case 127: - statusList << "" << "\"That Emblem\"" << "\"Emblem's meaning\"" << "\"The Prophecy\""; - break; - case 129: - statusList << "Walked away" << "Waited for Undyne to do something" << "Helped the kid"; - break; -// case 134: -// statusList << "" << "Cinnamon Pie" << "Butterscotch Pie"; -// break; - case 231: - statusList << "The Ruins" << "Snowdin" << "Waterfall" << "Hotlands"; - break; - case 296: - statusList << "" << "Special sale" << "Sell 1 more for special" << "Sell 2 more for special" << "Sell 3 more for special" << "Sell 4 more for special" << "Sell 5 more for special" << "Sell 6 more for special" << "Sell 7 more for special"; - break; - case 298: - statusList << "" << "Stayed at the hotel" << "Stayed at the hotel, again"; - break; - case 306: - statusList << "" << "Walked past it" << "It gets snapped"; - break; - case 312: - statusList << "Not encountered" << "Kill" << "Spare"; - break; -// case 313: -// statusList << "Not encountered" << "Spare" << "Kill"; -// break; - case 381: - statusList << "Spare" << "Kill" << "Spare, but no water"; - break; - case 386: - statusList << "Don't interact" << "Interact -> Punch" << "Interact -> Don't punch"; - break; - case 416: - statusList << "Not available" << "Available" << "Button pressed"; - break; - case 420: - statusList << "" << "?1?" << "?2?" << "?3?" << "House is on fire"; - break; - case 422: - statusList << "" << "Fries" << "Burger"; - break; - case 444: - statusList << "" << "Begin date" << "Date complete"; - break; - case 455: - statusList << "" << "Can be exposed" << "Already exposed"; - break; - case 465: - statusList << "" << "Remebered the name" << "Forgot the name"; - break; - case 466: - statusList << "" << "Buy" << "Talk"; - break; - case 490: - statusList << "" << "Snowdin" << "Waterfall" << "Hotland"; - break; -// case 492: -// statusList << "Regular" << "Temmie"; -// break; - case 524: - statusList << "" << "?1?" << "?2?" << "?3?" << "?4?" << "?5?" << "?6?" << "?7?" << "?8?" << "?9?" << "?10?" << "?11?" << "Exited the True Lab"; - break; - case 525: - statusList << "" << "?1?" << "Regular Letter" << "Letter EX"; - break; - case 527: - statusList << "\"I'm Onionsan!\"" << "?1?" << "?2?" << "?3?" << "?4?" << "?5?" << "\"I got nothing else...\"" << "?7?"; - break; - case 541: - statusList << "" << "Talked with Asriel at Ruins" << "Completed the Dreamer Battle"; - break; - case 548: - { - QFile file(":/strings/roomfile"); - QTextStream buff(&file); - if(!file.open(QFile::ReadOnly | QFile::Text)) - { - statusList << "0#room_start" << "1#room_introstory" << "2#room_introimage" << "3#room_intromenu" << "4#room_area1" << "5#room_area1_2" << "6#room_ruins1" << "7#room_ruins2" << "8#room_ruins3" << "9#room_ruins4" << "10#room_ruins5" << "11#room_ruins6" << "12#room_ruins7" << "13#room_ruins7A" << "14#room_ruins8" << "15#room_ruins9" << "16#room_ruins10" << "17#room_ruins11" << "18#room_ruins12A" << "19#room_ruins12" << "20#room_ruins12B" << "21#room_ruins13" << "22#room_ruins14" << "23#room_ruins15A" << "24#room_ruins15B" << "25#room_ruins15C" << "26#room_ruins15D" << "27#room_ruins15E" << "28#room_ruins16" << "29#room_ruins17" << "30#room_ruins18OLD" << "31#room_ruins19" << "32#room_torhouse1" << "33#room_torhouse2" << "34#room_torhouse3" << "35#room_torielroom" << "36#room_asrielroom" << "37#room_kitchen" << "38#room_basement1" << "39#room_basement2" << "40#room_basement3" << "41#room_basement4" << "42#room_basement5" << "43#room_ruinsexit" << "44#room_tundra1" << "45#room_tundra2" << "46#room_tundra3" << "47#room_tundra3A" << "48#room_tundra4" << "49#room_tundra5" << "50#room_tundra6" << "51#room_tundra6A" << "52#room_tundra7" << "53#room_tundra8" << "54#room_tundra8A" << "55#room_tundra9" << "56#room_tundra_spaghetti" << "57#room_tundra_snowpuzz" << "58#room_tundra_xoxosmall" << "59#room_tundra_xoxopuzz" << "60#room_tundra_randoblock" << "61#room_tundra_lesserdog" << "62#room_tundra_icehole" << "63#room_tundra_iceentrance" << "64#room_tundra_iceexit_new" << "65#room_tundra_iceexit" << "66#room_tundra_poffzone" << "67#room_tundra_dangerbridge" << "68#room_tundra_town" << "69#room_tundra_town2" << "70#room_tundra_dock" << "71#room_tundra_inn" << "72#room_tundra_inn_2f" << "73#room_tundra_grillby" << "74#room_tundra_library" << "75#room_tundra_garage" << "76#room_tundra_sanshouse" << "77#room_tundra_paproom" << "78#room_tundra_sansroom" << "79#room_tundra_sansroom_dark" << "80#room_tundra_sansbasement" << "81#room_fogroom" << "82#room_water1" << "83#room_water2" << "84#room_water3" << "85#room_water3A" << "86#room_water4" << "87#room_water_bridgepuzz1" << "88#room_water5" << "89#room_water5A" << "90#room_water6" << "91#room_water7" << "92#room_water8" << "93#room_water9" << "94#room_water_savepoint1" << "95#room_water11" << "96#room_water_nicecream" << "97#room_water12" << "98#room_water_shoe" << "99#room_water_bird" << "100#room_water_onionsan" << "101#room_water14" << "102#room_water_piano" << "103#room_water_dogroom" << "104#room_water_statue" << "105#room_water_prewaterfall" << "106#room_water_waterfall" << "107#room_water_waterfall2" << "108#room_water_waterfall3" << "109#room_water_waterfall4" << "110#room_water_preundyne" << "111#room_water_undynebridge" << "112#room_water_undynebridgeend" << "113#room_water_trashzone1" << "114#room_water_trashsavepoint" << "115#room_water_trashzone2" << "116#room_water_friendlyhub" << "117#room_water_undyneyard" << "118#room_water_undynehouse" << "119#room_water_blookyard" << "120#room_water_blookhouse" << "121#room_water_hapstablook" << "122#room_water_farm" << "123#room_water_prebird" << "124#room_water_shop" << "125#room_water_dock" << "126#room_water15" << "127#room_water16" << "128#room_water_temvillage" << "129#room_water17" << "130#room_water18" << "131#room_water19" << "132#room_water20" << "133#room_water21" << "134#room_water_undynefinal" << "135#room_water_undynefinal2" << "136#room_water_undynefinal3" << "137#room_fire1" << "138#room_fire2" << "139#room_fire_prelab" << "140#room_fire_dock" << "141#room_fire_lab1" << "142#room_fire_lab2" << "143#room_fire3" << "144#room_fire5" << "145#room_fire6" << "146#room_fire6A" << "147#room_fire_lasers1" << "148#room_fire7" << "149#room_fire8" << "150#room_fire_shootguy_2" << "151#room_fire9" << "152#room_fire_shootguy_1" << "153#room_fire_turn" << "154#room_fire_cookingshow" << "155#room_fire_savepoint1" << "156#room_fire_elevator_r1" << "157#room_fire_elevator_r2" << "158#room_fire_hotdog" << "159#room_fire_walkandbranch" << "160#room_fire_sorry" << "161#room_fire_apron" << "162#room_fire10" << "163#room_fire_rpuzzle" << "164#room_fire_mewmew2" << "165#room_fire_boysnightout" << "166#room_fire_newsreport" << "167#room_fire_coreview2" << "168#room_fire_elevator_l2" << "169#room_fire_elevator_l3" << "170#room_fire_spidershop" << "171#room_fire_walkandbranch2" << "172#room_fire_conveyorlaser" << "173#room_fire_shootguy_3" << "174#room_fire_preshootguy4" << "175#room_fire_shootguy_4" << "176#room_fire_savepoint2" << "177#room_fire_spider" << "178#room_fire_pacing" << "179#room_fire_operatest" << "180#room_fire_multitile" << "181#room_fire_hotelfront_1" << "182#room_fire_hotelfront_2" << "183#room_fire_hotellobby" << "184#room_fire_restaurant" << "185#room_fire_hoteldoors" << "186#room_fire_hotelbed" << "187#room_fire_elevator_r3" << "188#room_fire_precore" << "189#room_fire_core1" << "190#room_fire_core2" << "191#room_fire_core3" << "192#room_fire_core4" << "193#room_fire_core5" << "194#room_fire_core_freebattle" << "195#room_fire_core_laserfun" << "196#room_fire_core_branch" << "197#room_fire_core_bottomleft" << "198#room_fire_core_left" << "199#room_fire_core_topleft" << "200#room_fire_core_top" << "201#room_fire_core_topright" << "202#room_fire_core_right" << "203#room_fire_core_bottomright" << "204#room_fire_core_center" << "205#room_fire_shootguy_5" << "206#room_fire_core_treasureleft" << "207#room_fire_core_treasureright" << "208#room_fire_core_warrior" << "209#room_fire_core_bridge" << "210#room_fire_core_premett" << "211#room_fire_core_metttest" << "212#room_fire_core_final" << "213#room_fire_elevator" << "214#room_fire_elevator_l1" << "215#room_fire_finalelevator" << "216#room_castle_elevatorout" << "217#room_castle_precastle" << "218#room_castle_hook" << "219#room_castle_front" << "220#room_asghouse1" << "221#room_asghouse2" << "222#room_asghouse3" << "223#room_asgoreroom" << "224#room_asrielroom_final" << "225#room_kitchen_final" << "226#room_basement1_final" << "227#room_basement2_final" << "228#room_basement3_final" << "229#room_basement4_final" << "230#room_lastruins_corridor" << "231#room_sanscorridor" << "232#room_castle_finalshoehorn" << "233#room_castle_coffins1" << "234#room_castle_coffins2" << "235#room_castle_throneroom" << "236#room_castle_prebarrier" << "237#room_castle_barrier" << "238#room_castle_exit" << "239#room_undertale_end" << "240#room_castle_trueexit" << "241#room_outsideworld" << "242#room_fire_labelevator" << "243#room_truelab_elevatorinside" << "244#room_truelab_elevator" << "245#room_truelab_hall1" << "246#room_truelab_hub" << "247#room_truelab_hall2" << "248#room_truelab_operatingroom" << "249#room_truelab_redlever" << "250#room_truelab_prebed" << "251#room_truelab_bedroom" << "252#room_truelab_mirror" << "253#room_truelab_bluelever" << "254#room_truelab_hall3" << "255#room_truelab_shower" << "256#room_truelab_determination" << "257#room_truelab_tv" << "258#room_truelab_cooler" << "259#room_truelab_greenlever" << "260#room_truelab_fan" << "261#room_truelab_castle_elevator" << "262#room_truelab_prepower" << "263#room_truelab_power" << "264#room_gaster" << "265#room_icecave1" << "266#room_ice_dog" << "267#room2" << "268#room_water_fakehallway" << "269#room_mysteryman" << "270#room_soundtest" << "271#TESTROOM" << "272#room_water_redacted" << "273#room_water13" << "274#room_overworld" << "275#room_overworld3" << "276#bullettest" << "277#room_water16A" << "278#room_end_castroll" << "279#room_end_highway" << "280#room_end_beach" << "281#room_end_metta" << "282#room_end_school" << "283#room_end_mtebott" << "284#room_creditsdodger" << "285#room_end_myroom" << "286#room_end_theend" << "287#room_spritecheck" << "288#room_joyconfig" << "289#room_controltest" << "290#room_f_start" << "291#room_f_intro" << "292#room_f_menu" << "293#room_f_room" << "294#room_floweyx" << "295#room_f_phrase" << "296#room_fire4" << "297#room_fire10_old" << "298#room_fire10A_old" << "299#room_tundra_placeholder" << "300#room_ruins12B_old" << "301#room_tundra_rollsnow" << "302#room_water7_older" << "303#room_meetundyne_old" << "304#room_water_mushroom" << "305#room_monsteralign_test" << "306#room_battle" << "307#room_floweybattle" << "308#room_fastbattle" << "309#room_storybattle" << "310#room_gameover" << "311#room_shop1" << "312#room_shop2" << "313#room_shop3" << "314#room_shop4" << "315#room_shop5" << "316#room_riverman_transition" << "317#room_papdate" << "318#room_adate" << "319#room_flowey_endchoice" << "320#room_flowey_regret" << "321#room_empty" << "322#room_emptywhite" << "323#room_emptyblack" << "324#room_nothingness" << "325#room_undertale" << "326#room_of_dog" << "327#room_quizholder" << "328#room_friendtest" << "329#room_bringitinguys" << "330#room_asrielappears" << "331#room_goodbyeasriel" << "332#room_asrielmemory" << "333#room_asrieltest" << "334#room_afinaltest"; - } - else - { - while(!buff.atEnd()) - { - QString dummy = ""; - buff.readLineInto(&dummy); - rooms << dummy; - dummy = dummy.section("#", -1); - statusList << dummy; - } - } - } - break; - } - QStandardItemModel *statusModel = new QStandardItemModel(); - foreach (QString var, statusList) - { - QStandardItem *newItem = new QStandardItem(var); - statusModel->appendRow(newItem); - } - connect(this, SIGNAL(currentIndexChanged(int)), this, SLOT(trueIndexValue(int))); - setModel(statusModel); -} diff --git a/dataeditor.h b/dataeditor.h deleted file mode 100644 index 76cca08..0000000 --- a/dataeditor.h +++ /dev/null @@ -1,52 +0,0 @@ -#ifndef DATAEDITOR_H -#define DATAEDITOR_H - -#include -#include -#include -#include -#include -#include - -class DataEditor : public QComboBox -{ - Q_OBJECT - Q_PROPERTY(int value MEMBER value WRITE recieveValue) - -public: - DataEditor(QWidget *parent = 0, int index = 0); - void InventoryEditor(); - void StatusEditor(int index = 0); - -signals: - void transmitData(int num); - -public slots: - void trueIndexValue(int num); - -private: - int value; - int id; - QStringList rooms; - void recieveValue(int num); -}; - -class PhoneEditor : public QComboBox -{ - Q_OBJECT - Q_PROPERTY(int value MEMBER value WRITE recieveValue) - -public: - PhoneEditor(QWidget *parent = 0); - -signals: - void transmitData(int index); - -public slots: - void recieveValue(int num); - -private: - int value; -}; - -#endif // DATAEDITOR_H diff --git a/fonts/Vegur-Regular.otf b/fonts/Vegur-Regular.otf new file mode 100644 index 0000000..28978bc Binary files /dev/null and b/fonts/Vegur-Regular.otf differ diff --git a/icon.icns b/icon.icns new file mode 100644 index 0000000..d4105fa Binary files /dev/null and b/icon.icns differ diff --git a/icon.ico b/icon.ico index 8f79224..923ae03 100644 Binary files a/icon.ico and b/icon.ico differ diff --git a/images/amalgam_save.png b/images/amalgam_save.png deleted file mode 100644 index 4b9e060..0000000 Binary files a/images/amalgam_save.png and /dev/null differ diff --git a/images/asriel.png b/images/asriel.png deleted file mode 100644 index dac6833..0000000 Binary files a/images/asriel.png and /dev/null differ diff --git a/images/box.png b/images/box.png deleted file mode 100644 index 07965ea..0000000 Binary files a/images/box.png and /dev/null differ diff --git a/images/flowey.png b/images/flowey.png deleted file mode 100644 index eca816c..0000000 Binary files a/images/flowey.png and /dev/null differ diff --git a/images/heart.png b/images/heart.png deleted file mode 100644 index 817fd70..0000000 Binary files a/images/heart.png and /dev/null differ diff --git a/images/heartbreak.png b/images/heartbreak.png deleted file mode 100644 index 96e7ef0..0000000 Binary files a/images/heartbreak.png and /dev/null differ diff --git a/images/heartgtfo.png b/images/heartgtfo.png deleted file mode 100644 index 35a87a3..0000000 Binary files a/images/heartgtfo.png and /dev/null differ diff --git a/images/ico_alphys.png b/images/ico_alphys.png new file mode 100644 index 0000000..86584fa Binary files /dev/null and b/images/ico_alphys.png differ diff --git a/images/ico_debug.png b/images/ico_debug.png new file mode 100644 index 0000000..1a78f07 Binary files /dev/null and b/images/ico_debug.png differ diff --git a/images/ico_dogshrine.png b/images/ico_dogshrine.png new file mode 100644 index 0000000..3c1844b Binary files /dev/null and b/images/ico_dogshrine.png differ diff --git a/images/ico_floppy.png b/images/ico_floppy.png new file mode 100644 index 0000000..2f6bc64 Binary files /dev/null and b/images/ico_floppy.png differ diff --git a/images/ico_floppy_red.png b/images/ico_floppy_red.png new file mode 100644 index 0000000..c7bc6d9 Binary files /dev/null and b/images/ico_floppy_red.png differ diff --git a/images/ico_mettaton.png b/images/ico_mettaton.png new file mode 100644 index 0000000..eb05c3f Binary files /dev/null and b/images/ico_mettaton.png differ diff --git a/images/ico_napstablook.png b/images/ico_napstablook.png new file mode 100644 index 0000000..a49fdb2 Binary files /dev/null and b/images/ico_napstablook.png differ diff --git a/images/ico_papyrus.png b/images/ico_papyrus.png new file mode 100644 index 0000000..4481605 Binary files /dev/null and b/images/ico_papyrus.png differ diff --git a/images/ico_player.png b/images/ico_player.png new file mode 100644 index 0000000..623870c Binary files /dev/null and b/images/ico_player.png differ diff --git a/images/ico_sans.png b/images/ico_sans.png new file mode 100644 index 0000000..8a83a20 Binary files /dev/null and b/images/ico_sans.png differ diff --git a/images/ico_savepoint.png b/images/ico_savepoint.png new file mode 100644 index 0000000..4b479a1 Binary files /dev/null and b/images/ico_savepoint.png differ diff --git a/images/ico_spaghetti.png b/images/ico_spaghetti.png new file mode 100644 index 0000000..6c84800 Binary files /dev/null and b/images/ico_spaghetti.png differ diff --git a/images/ico_toriel.png b/images/ico_toriel.png new file mode 100644 index 0000000..8f386c8 Binary files /dev/null and b/images/ico_toriel.png differ diff --git a/images/ico_trashcan.png b/images/ico_trashcan.png new file mode 100644 index 0000000..dd8e8b0 Binary files /dev/null and b/images/ico_trashcan.png differ diff --git a/images/ico_undyne.png b/images/ico_undyne.png new file mode 100644 index 0000000..e2b28a5 Binary files /dev/null and b/images/ico_undyne.png differ diff --git a/images/icon.png b/images/icon.png new file mode 100644 index 0000000..fe2b533 Binary files /dev/null and b/images/icon.png differ diff --git a/images/save.png b/images/save.png deleted file mode 100644 index fb5a80c..0000000 Binary files a/images/save.png and /dev/null differ diff --git a/images/spaghetti.png b/images/spaghetti.png deleted file mode 100644 index 0141c8a..0000000 Binary files a/images/spaghetti.png and /dev/null differ diff --git a/images/tobdog.png b/images/tobdog.png deleted file mode 100644 index d8f54d7..0000000 Binary files a/images/tobdog.png and /dev/null differ diff --git a/images/tobdog_wrench.png b/images/tobdog_wrench.png deleted file mode 100644 index fa95729..0000000 Binary files a/images/tobdog_wrench.png and /dev/null differ diff --git a/images/truechara.png b/images/truechara.png deleted file mode 100644 index 5920f5d..0000000 Binary files a/images/truechara.png and /dev/null differ diff --git a/initools.cpp b/initools.cpp new file mode 100644 index 0000000..8afc94c --- /dev/null +++ b/initools.cpp @@ -0,0 +1,69 @@ +#include "initools.h" + +#include + +IniCheckBox::IniCheckBox(QString id, MainWindow *mainWindow, QWidget *parent) : QCheckBox(parent), id(id), mw(mainWindow) +{ + connect(this, SIGNAL(stateChanged(int)), this, SLOT(updateSave(int))); + connect(mw, SIGNAL(updateIniWidgets()), this, SLOT(updateData())); + connect(this, SIGNAL(dataChanged(bool)), mw, SLOT(iniModified(bool))); +} +void IniCheckBox::updateSave(int i) +{ + mw->iniData.insert(id, values[i]); + emit dataChanged(true); +} +void IniCheckBox::updateData() +{ + setCheckState(states.value(static_cast(mw->iniData.value(id).toDouble()))); +} + +IniLineEdit::IniLineEdit(QString id, MainWindow *mainWindow, QWidget *parent) : QLineEdit(parent), id(id), mw(mainWindow) +{ + connect(this, SIGNAL(textEdited(QString)), this, SLOT(updateSave(QString))); + connect(mw, SIGNAL(updateIniWidgets()), this, SLOT(updateData())); + connect(this, SIGNAL(dataChanged(bool)), mw, SLOT(iniModified(bool))); +} +void IniLineEdit::updateSave(QString text) +{ + mw->iniData.insert(id, text); + emit dataChanged(true); +} +void IniLineEdit::updateData() +{ + setText(mw->iniData.value(id).toString()); +} + +IniSpinBox::IniSpinBox(QString id, MainWindow *mainWindow, QWidget *parent) : QSpinBox(parent), id(id), mw(mainWindow) +{ + setRange(INT_MIN, INT_MAX); + + connect(this, SIGNAL(valueChanged(int)), this, SLOT(updateIni(int))); + connect(mw, SIGNAL(updateIniWidgets()), this, SLOT(updateData())); + connect(this, SIGNAL(dataChanged(bool)), mw, SLOT(iniModified(bool))); +} +void IniSpinBox::updateIni(int i) +{ + mw->iniData.insert(id, i); + emit dataChanged(true); +} +void IniSpinBox::updateData() +{ + setValue(static_cast(mw->iniData.value(id).toDouble())); +} + +HorizontalLine::HorizontalLine(QWidget *parent) : QFrame(parent) +{ + setFixedHeight(3); + setLineWidth(1); + setFrameShadow(QFrame::Sunken); + setFrameShape(QFrame::HLine); +} + +VerticalLine::VerticalLine(QWidget *parent) : QFrame(parent) +{ + setFixedWidth(3); + setLineWidth(1); + setFrameShadow(QFrame::Sunken); + setFrameShape(QFrame::VLine); +} diff --git a/initools.h b/initools.h new file mode 100644 index 0000000..76b8bf8 --- /dev/null +++ b/initools.h @@ -0,0 +1,71 @@ +#ifndef INITOOLS_H +#define INITOOLS_H + +#include "mainwindow.h" + +#include +#include +#include + +class IniCheckBox : public QCheckBox +{ + Q_OBJECT +public: + IniCheckBox(QString id, MainWindow *mainWindow, QWidget *parent = nullptr); +signals: + void dataChanged(bool value); +public slots: + void updateSave(int i); + void updateData(); +private: + QString id; + int values[3] = {0, 1, 1}; + QMap states{{0, Qt::Unchecked}, {1, Qt::Checked}}; + MainWindow *mw; +}; + +class IniLineEdit : public QLineEdit +{ + Q_OBJECT +public: + IniLineEdit(QString id, MainWindow *mainWindow, QWidget *parent = nullptr); +signals: + void dataChanged(bool value); +public slots: + void updateSave(QString text); + void updateData(); +private: + QString id; + MainWindow *mw; +}; + +class IniSpinBox : public QSpinBox +{ + Q_OBJECT +public: + IniSpinBox(QString id, MainWindow *mainWindow, QWidget *parent = nullptr); +signals: + void dataChanged(bool value); +public slots: + void updateIni(int i); + void updateData(); +private: + QString id; + MainWindow *mw; +}; + +class HorizontalLine : public QFrame +{ + Q_OBJECT +public: + HorizontalLine(QWidget *parent = nullptr); +}; + +class VerticalLine : public QFrame +{ + Q_OBJECT +public: + VerticalLine(QWidget *parent = nullptr); +}; + +#endif // INITOOLS_H diff --git a/main.cpp b/main.cpp index 386b165..27d0e74 100644 --- a/main.cpp +++ b/main.cpp @@ -1,15 +1,27 @@ #include "mainwindow.h" #include +#include int main(int argc, char *argv[]) { - QApplication mApp(argc, argv); - mApp.setOrganizationName("Cofeiini"); - mApp.setApplicationName("Undertale Save Editor"); - mApp.setApplicationVersion("0.4"); - mApp.setWheelScrollLines(1); - MainWindow mWindow; - mWindow.show(); - - return mApp.exec(); + QApplication a(argc, argv); + a.setOrganizationName("Cofeiini"); + a.setApplicationName(QString("Undertale Save Editor")); + a.setApplicationVersion(APP_VERSION); +#if defined(Q_OS_LINUX) + a.setWindowIcon(QIcon(":/images/icon.png")); +#endif + + int fontId = QFontDatabase::addApplicationFont(":/fonts/Vegur-Regular.otf"); + if(fontId != -1) + { + QFont font = QFont("Vegur-Regular"); + font.setPixelSize(13); + a.setFont(font); + } + + MainWindow w; + w.show(); + + return a.exec(); } diff --git a/mainwindow.cpp b/mainwindow.cpp index a277261..f314d25 100644 --- a/mainwindow.cpp +++ b/mainwindow.cpp @@ -1,987 +1,498 @@ -/* - hsssssN msssssd Howdy! - ms--hyhy---/++o o+/----yds--hN This is the SOURCE CODE for Undertale Save Editor by Cofeiini. - s- ``om NNNNNNNNNN s`` :h - h+o dsss .sssm N++m hmm... - mo....om d:` -:. -:. `+d d+....sm You're new here, aren'tcha? -N+.``````o N: dMy dMs `/ /````` -sN -- oooom N dMy dMs ` hoooo. - Golly, you must be so confused. - ::. `o N `: oh+ sh/ :` ` /` -:+ Someone ought to teach you how things work around here. - mo`+N h`` :shysssssssyhs:` -d m- .sm I guess little old me will have to do. - Nsssssy s. +ossssssso/ :y ssssss - dyo. y- ``````` :d N`sym - d:` `-ddN Ndd----------/dd Ndd- .+m - N :s/ :++o +++- `+s. . - N :+ :++o +++- o. . - dd+------sddddN Ndddd+------sdm - y/oN - - - . `/m - . /N - - `o - Ns- `m - Ns -h - d/ :h - h- h: + N`m - Nh+dd+-----sdh+d - y++++++++oh - -But seriously... -My work probably breaks every programming standards and every possible from of "best practices". -I'll improve this code as I learn more about Qt... I promise. - -For now, I had no need for commenting. Instead I used debug output. -To me those debug lines are as good as comments, but to an "outsider" this might seem like a huge mess. Which it totally is. -Since I'm the only programmer in this project, I won't be adding comments any time soon. - -Feel free to correct me on practically anything. -*/ - #include "mainwindow.h" -#include "ui_mainwindow.h" - -MainWindow::MainWindow(QWidget *parent) : QMainWindow(parent), ui(new Ui::MainWindow) +#include "pages.h" + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +MainWindow::MainWindow(QWidget *parent) : QMainWindow(parent) { - ui->setupUi(this); - setWindowTitle(TITLELABEL); - setWindowFilePath(NULL); - - int screen = QApplication::desktop()->screenNumber(QCursor::pos()); - mResWidth = QApplication::desktop()->screen(screen)->width(); - mResHeight = QApplication::desktop()->screen(screen)->height(); - wMinWidth = MainWindow::minimumWidth(); - wMinHeight = MainWindow::minimumHeight(); - - entryTypes = (QStringList() << "bool" << "counter" << "range" << "timer" << "iEdit" << "pEdit" << "sEdit" << "unused"); -// invEntries = (QStringList() << "13" << "15" << "17" << "19" << "21" << "23" << "25" << "27" << "29" << "30" << "331" << "332" << "333" << "334" << "335" << "336" << "337" << "338" << "339" << "340" << "341" << "342" << "343" << "344" << "345" << "346" << "347" << "348" << "349" << "350" << "351" << "352" << "353" << "354"); -// cellEntries = (QStringList() << "14" << "16" << "18" << "20" << "22" << "24" << "26" << "28"); - - stats.fill(0,4); - readSettings(); - setupMenuBar(); - setupEntries(); - fileWasModified(0); - - settingsDialog = new ConfigDialog(this); - settingsDialog->setModal(true); +#if defined(Q_OS_LINUX) + workDir = QDir::homePath() + "/.config/UNDERTALE/"; +#elif defined(Q_OS_MACOS) + workDir = QDir::homePath() + "/Library/Application Support/com.tobyfox.undertale/"; +#else + workDir = QDir::homePath() + "/AppData/Local/UNDERTALE/"; +#endif + setWindowTitle(QApplication::applicationName() + " (v" + QApplication::applicationVersion() + ")"); + + // create actions + QAction *openFileAction = new QAction(tr("Open file"), this); + connect(openFileAction, &QAction::triggered, this, &MainWindow::openFile); + QAction *openIniAction = new QAction(tr("Open ini"), this); + connect(openIniAction, &QAction::triggered, this, &MainWindow::openIni); + saveAction = new QAction(tr("Save"), this); + saveAction->setEnabled(false); + connect(saveAction, &QAction::triggered, this, &MainWindow::saveFile); + saveAsAction = new QAction(tr("Save As..."), this); + saveAsAction->setEnabled(false); + connect(saveAsAction, &QAction::triggered, this, &MainWindow::saveFileAs); + QAction *exitAction = new QAction(tr("Exit"), this); + connect(exitAction, &QAction::triggered, this, &MainWindow::close); + + QAction *showDebugAction = new QAction(tr("Show Debug"), this); + showDebugAction->setCheckable(true); + showDebugAction->setChecked(false); + connect(showDebugAction, &QAction::toggled, this, &MainWindow::showDebug); + QAction *showDogAction = new QAction(tr("Show Dog Shrine"), this); + showDogAction->setCheckable(true); + showDogAction->setChecked(false); + connect(showDogAction, &QAction::toggled, this, &MainWindow::showDog); + + // create menus for menubar + QMenu *fileMenu = menuBar()->addMenu(tr("File")); + fileMenu->addAction(openFileAction); + fileMenu->addAction(openIniAction); + fileMenu->addAction(saveAction); + fileMenu->addAction(saveAsAction); + fileMenu->addSeparator(); + fileMenu->addAction(exitAction); + + QMenu *optionMenu = menuBar()->addMenu(tr("Options")); + optionMenu->addAction(showDebugAction); + optionMenu->addAction(showDogAction); + + // create list menu + icons = new QListWidget(); + icons->setViewMode(QListWidget::IconMode); + icons->setIconSize(QSize(64, 64)); + icons->setMovement(QListView::Static); + icons->setMaximumWidth(110); // 64 + 5 + 5 + 36 + icons->setSizePolicy(QSizePolicy::Fixed, QSizePolicy::Expanding); + icons->setSpacing(5); + + buttons.append(new QListWidgetItem(QIcon(":/images/ico_player.png"), + tr("Player"), icons)); + buttons.append(new QListWidgetItem(QIcon(":/images/ico_toriel.png"), + tr("Bosses"), icons)); + buttons.append(new QListWidgetItem(QIcon(":/images/ico_napstablook.png"), + tr("Monsters"), icons)); + buttons.append(new QListWidgetItem(QIcon(":/images/ico_savepoint.png"), + tr("Locations"), icons)); + buttons.append(new QListWidgetItem(QIcon(":/images/ico_debug.png"), + tr("Debug"), icons)); + buttons.append(new QListWidgetItem(QIcon(":/images/ico_dogshrine.png"), + tr("Dog Shrine"), icons)); + foreach (QListWidgetItem *item, buttons) + { + item->setTextAlignment(Qt::AlignHCenter); + item->setFlags(Qt::ItemIsSelectable | Qt::ItemIsEnabled); + } + buttons.at(4)->setHidden(true); + buttons.at(5)->setHidden(true); + + connect(icons, + SIGNAL(currentItemChanged(QListWidgetItem *, QListWidgetItem *)), + this, SLOT(changePage(QListWidgetItem *, QListWidgetItem *))); + + // create pages + pages = new QStackedWidget(); + pages->addWidget(new PlayerPage(this)); + pages->addWidget(new BossesPage(this)); + pages->addWidget(new MonstersPage(this)); + pages->addWidget(new LocationsPage(this)); + pages->addWidget(new DebugPage(this)); + pages->addWidget(new DogPage(this)); + + // setup central widget + window = new QTabWidget(); + + QWidget *fileWidget = new QWidget(); + QHBoxLayout *fileLayout = new QHBoxLayout; + fileLayout->addWidget(icons); + fileLayout->addWidget(pages); + fileWidget->setLayout(fileLayout); + + QWidget *iniWidget = new QWidget(); + QHBoxLayout *iniLayout = new QHBoxLayout(); + iniLayout->addWidget(new INIPage(this)); + iniWidget->setLayout(iniLayout); + + window->addTab(fileWidget, tr("file0")); + window->addTab(iniWidget, tr("undertale.ini")); + window->setTabEnabled(0, false); + window->setTabEnabled(1, false); + window->setTabIcon(0, floppy[0]); + window->setTabIcon(1, floppy[0]); + + setCentralWidget(window); + icons->setCurrentItem(buttons.at(0)); + emit updateWidgets(); + fileModified(false); + resize(1228, 690); } -void MainWindow::showEvent(QShowEvent *event) +void MainWindow::closeEvent(QCloseEvent *event) { - // Due to spacers in the ui, interface elements will overlap each other after the ui is displayed. The "update()" at the end remedies this problem. - QMainWindow::showEvent(event); - if(edict.value("maximized").toBool() == true) + if (checkIfFileSave()) { - showMaximized(); + event->accept(); } else { - if(MainWindow::width() < MainWindow::minimumWidth() || MainWindow::height() < MainWindow::minimumHeight()) - { - adjustSize(); - } - else - { - resize(edict.value("size").toSize()); - } - - if(MainWindow::x() > QApplication::desktop()->width() || MainWindow::y() > QApplication::desktop()->height()) - { - move((mResWidth/2) - (MainWindow::minimumWidth()/2), (mResHeight/2) - (MainWindow::minimumHeight()/2)); - } - else - { - move(edict.value("position").toPoint()); - } + event->ignore(); } - displayInfo(); - ui->contentLayout->update(); } -void MainWindow::setupEntries() +void MainWindow::showEvent(QShowEvent *event) { - // Using OverrideCursor because this phase takes forever. User input during this phase leads to bad times -#ifndef QT_NO_CURSOR - QApplication::setOverrideCursor(Qt::WaitCursor); -#endif - if(mem0.size() < 549) + QMainWindow::showEvent(event); + QUrl url("https://raw.githubusercontent.com/Cofeiini/UndertaleSaveEditor/master/version.json"); + downloader = new FileDownloader(url, this); + connect(downloader, SIGNAL(downloaded()), this, SLOT(loadData())); +} + +void MainWindow::changePage(QListWidgetItem *current, QListWidgetItem *previous) +{ + if (!current) { - for(int i = 1; i < 550; i++) - { - mem0[i] = ""; - } + current = previous; } + pages->setCurrentIndex(icons->row(current)); +} + +void MainWindow::fileModified(bool value) +{ + isFileModified = value; + window->setTabIcon(0, floppy[value]); +} + +void MainWindow::iniModified(bool value) +{ + isIniModified = value; + window->setTabIcon(1, floppy[value]); +} - int size = mem0.size(); - for(int i = 0; i < size; i++) +void MainWindow::openFile() +{ + if (checkIfFileSave()) { - QString curType = mem2.value(i+1); - QString val = mem0.value(i+1); - QString id = QString::number(i+1); - int mod = entryTypes.indexOf(curType); - switch(mod) - { - case 0: - { - // CheckBox, strangely, can be in three states. This fact of course needlessly complicates things. - QCheckBox *entry = new QCheckBox; - Qt::CheckState state = Qt::Unchecked; - QStringList lst = mem3.value(i+1).split(","); - entry->setObjectName(id); - entry->setText(val); - - if(lst.value(1) != "-1") - { - entry->setTristate(true); - if(lst.value(2) == val) - { - state = Qt::Checked; - } - else if(lst.value(1) == val) - { - state = Qt::PartiallyChecked; - } - entry->setCheckState(state); - } - else - { - if(lst.value(2) == val) - { - state = Qt::Checked; - } - entry->setChecked(state); - } - connect(entry, SIGNAL(stateChanged(int)), this, SLOT(dataBoolWasModified(int))); - items.append(entry); - } - break; - case 1: + // choose file + QString path = QFileDialog::getOpenFileName(this, tr("Open File"), workDir, QString("file (file*);;All Files (*)")); + if (path.isEmpty()) { - QSpinBox *entry = new QSpinBox; - int rMin = mem3.value(i+1).section(',',0,0).toInt(); - int rStep = mem3.value(i+1).section(',',1,1).toInt(); - qint32 rMax = mem3.value(i+1).section(',',2,2).toLong(); - - entry->setRange(rMin,rMax); - entry->setSingleStep(rStep); - entry->setValue(val.toInt()); - entry->setObjectName(id); - connect(entry, SIGNAL(valueChanged(QString)), this, SLOT(dataStringWasModified(QString))); - items.append(entry); - } - break; - case 2: - { - QSpinBox *entry = new QSpinBox; - int rMin = mem3.value(i+1).section(',',0,0).toInt(); - int rStep = mem3.value(i+1).section(',',1,1).toInt(); - int rMax = mem3.value(i+1).section(',',2,2).toInt(); - - entry->setRange(rMin, rMax); - entry->setSingleStep(rStep); - entry->setObjectName(id); - entry->setValue(val.toInt()); - connect(entry, SIGNAL(valueChanged(QString)), this, SLOT(dataStringWasModified(QString))); - items.append(entry); - } - break; - case 3: - { - // Displaying the time is bit more complicated. Scientific notation and all that jazz. - QDoubleSpinBox *entry = new QDoubleSpinBox(); - int rMin = mem3.value(i+1).section(',',0,0).toInt(); - int rStep = mem3.value(i+1).section(',',1,1).toInt(); - qint64 rMax = mem3.value(i+1).section(',',2,2).toLongLong(); - - entry->setDecimals(0); - entry->setRange(rMin,rMax); - entry->setSingleStep(rStep); - entry->setValue(val.toDouble()); - entry->setObjectName(id); - connect(entry, SIGNAL(valueChanged(double)), this, SLOT(dataTimeWasModified(double))); - items.append(entry); - } - break; - case 4: - { - DataEditor *entry = new DataEditor(this, 0); - entry->setObjectName(id); - entry->setProperty("value", val.toInt()); - connect(entry, SIGNAL(currentIndexChanged(int)), this, SLOT(dataComboWasModified(int))); - items.append(entry); + return; } - break; - case 5: + + filePath = path; + workDir = QFileInfo(path).dir().absolutePath(); + // open file + QFile file(path); + if (!file.open(QFile::ReadOnly | QFile::Text)) { - PhoneEditor *entry = new PhoneEditor; - entry->setObjectName(id); - entry->setProperty("value", val.toInt()); - connect(entry, SIGNAL(transmitData(int)), this, SLOT(dataComboWasModified(int))); - items.append(entry); + QMessageBox::warning(this, QApplication::applicationName(), + tr("Cannot read file %1:\n%2.") + .arg(QDir::toNativeSeparators(path), + file.errorString())); + return; } - break; - case 6: + + QTextStream in(&file); + + // count lines to make sure the file is valid + int count = 0; + QString l; + while (in.readLineInto(&l)) { - DataEditor* entry = new DataEditor(this, i+1); - entry->setObjectName(id); - entry->setProperty("value", val.toInt()); - connect(entry, SIGNAL(transmitData(int)), this, SLOT(dataComboWasModified(int))); - items.append(entry); + count++; } - break; - default: + if (count < 549) { - // Usually these are "unused" or "unaccessed"... Usually. - QLineEdit *entry = new QLineEdit; - entry->setText(val); - entry->setObjectName(id); - connect(entry, SIGNAL(textEdited(QString)), this, SLOT(dataStringWasModified(QString))); - items.append(entry); - } - break; + QMessageBox::warning(this, QApplication::applicationName(), + tr("File %1\n" + "does not contain enough data or is " + "incorrectly formated.") + .arg(QDir::toNativeSeparators(path))); + return; } - // Entry "title" label - QLabel *qLab = new QLabel(); - qLab->setText(QString(mem1.value(i+1))); - qLab->setFrameStyle(QFrame::Box | QFrame::Plain); - qLab->setFixedSize(220, 20); - qLab->setSizePolicy(QSizePolicy::Preferred, QSizePolicy::Fixed); - info[i] = qLab; - - // Entry number - QLabel *nLab = new QLabel(); - nLab->setText(id.rightJustified(3,'0')); - nLab->setAlignment(Qt::AlignCenter); - nLab->setFrameStyle(QFrame::Box | QFrame::Plain); - nLab->setFixedSize(30, 20); - nLab->setSizePolicy(QSizePolicy::Preferred, QSizePolicy::Fixed); - numfo[i] = nLab; - - // Entry comment - QTextBrowser *tBro = new QTextBrowser; - tBro->setText(mem4.value(i+1)); - tBro->setFixedSize(175, 50); - comment[i] = tBro; - - // Horizontal container for current row. Add all components in to the mix. - QHBoxLayout *hLay = new QHBoxLayout; - hLay->addWidget(comment[i]); - hLay->addWidget(numfo[i]); - hLay->addWidget(info[i]); - hLay->addWidget(items[i]); - - // Finally, add a little label for the time, which gets converted to human-readable format - if(curType == "timer") +#ifndef QT_NO_CURSOR + QApplication::setOverrideCursor(Qt::WaitCursor); +#endif + // read file to memory + in.seek(0); + for (int i = 1; i <= 549; i++) { - QLabel *tLab = new QLabel(); - qint64 tim = val.toDouble(); - int hour = std::fmod(tim/108000, 24); // divide value (1 000 000 for example) by frames*60*60 to get frames as hours (~9 hours) and modulo by (hours in a day) 24 = ~9h - int minute = std::fmod(tim/1800, 60); // divide value (1 000 000 for example) by frames*60 to get frames as minutes (~555 minutes) and modulo by (minutes in an hour) 60 = ~15m - int second = std::fmod(tim/30, 60); // divide value (1 000 000 for example) by frames(30fps) to get frames as seconds (~33 333 seconds) and modulo by (seconds in a minute) 60 = ~30s - // So 1 000 000 frames converts to roughly 9:15:30. 109 830 frames would convert to 01:01:01 - // I should consider either adding days counter or removing hours to days conversion. - tLab->setText( QString::number(hour) + ":" + QString::number(minute) + ":" + QString::number(second)); - tLab->setObjectName("timeLabel"); - tLab->setFrameStyle(QFrame::Box | QFrame::Plain); - tLab->setSizePolicy(QSizePolicy::Preferred, QSizePolicy::Fixed); - hLay->addWidget(tLab); + saveData.replace(i, in.readLine()); } - - // Add container to the interface - ui->contentLayout->addLayout(hLay); - } #ifndef QT_NO_CURSOR - QApplication::restoreOverrideCursor(); + QApplication::restoreOverrideCursor(); #endif + window->setTabEnabled(0, true); + window->setTabText(0, QFileInfo(path).fileName()); + window->setCurrentIndex(0); + emit updateWidgets(); + fileModified(false); + } + saveAction->setEnabled(true); + saveAsAction->setEnabled(true); } -void MainWindow::displayInfo() +void MainWindow::openIni() { -#ifndef QT_NO_CURSOR - QApplication::setOverrideCursor(Qt::WaitCursor); -#endif - - int size = mem0.size(); - for(int i = 0; i < size; i++) + if(checkIfIniSave()) { - comment[i]->setVisible(true); - numfo[i]->setVisible(true); - info[i]->setVisible(true); - items[i]->setVisible(true); - - // It's better to store the value inside a variable rather than fetch the value each time it's needed. - QString curType = mem2.value(i+1); - QString val = mem0.value(i+1); - QWidget *dummy = items[i]; - dummy->blockSignals(true); - if(curType == "bool") + // choose file + QString path = QFileDialog::getOpenFileName(this, tr("Open File"), workDir, QString("Ini File (*.ini);;All Files (*)")); + if (path.isEmpty()) { - dummy->setProperty("text", val); - dummy->setProperty("value", val.toInt()); - Qt::CheckState state = Qt::Unchecked; - QStringList lst = mem3.value(i+1).split(","); - - if(lst.value(2) == val) - { - state = Qt::Checked; - } - else if(lst.value(1) == val) - { - state = Qt::PartiallyChecked; - } - - if(dummy->property("isTristate") == true) - { - dummy->setProperty("checkState", state); - } - else - { - dummy->setProperty("checked", state); - } - - if(edict.value("hideboolean").toBool()) - { - comment[i]->setVisible(false); - numfo[i]->setVisible(false); - info[i]->setVisible(false); - items[i]->setVisible(false); - } - } - else if(curType == "counter") - { - dummy->setProperty("value", val.toInt()); - - if(edict.value("hidecounter").toBool()) - { - comment[i]->setVisible(false); - numfo[i]->setVisible(false); - info[i]->setVisible(false); - items[i]->setVisible(false); - } - } - else if(curType == "range") - { - dummy->setProperty("value", val.toInt()); - - if(edict.value("hiderange").toBool()) - { - comment[i]->setVisible(false); - numfo[i]->setVisible(false); - info[i]->setVisible(false); - items[i]->setVisible(false); - } - } - else if(curType == "timer") - { - dummy->setProperty("value", val.toDouble()); - } - else - { - dummy->setProperty("text", val); - if(edict.value("hideunused").toBool() && curType == "unused") - { - comment[i]->setVisible(false); - numfo[i]->setVisible(false); - info[i]->setVisible(false); - items[i]->setVisible(false); - } - } - - if(edict.value("hidecomment").toBool()) - { - comment[i]->setVisible(false); + return; } + iniPath = path; + workDir = QFileInfo(path).dir().absolutePath(); - if(edict.value("hidenumber").toBool()) + // read ini + QSettings iniRead(path, QSettings::IniFormat); + foreach (QString item, iniRead.allKeys()) { - numfo[i]->setVisible(false); + iniData.insert(item, iniRead.value(item)); } - dummy->blockSignals(false); + window->setTabEnabled(1, true); + window->setTabText(1, QFileInfo(path).fileName()); + window->setCurrentIndex(1); + emit updateIniWidgets(); + iniModified(false); } - - ui->contentLayout->update(); -#ifndef QT_NO_CURSOR - QApplication::restoreOverrideCursor(); -#endif + saveAction->setEnabled(true); + saveAsAction->setEnabled(true); } -void MainWindow::readSettings() +void MainWindow::saveFile() { -// Combination of read and write in case there's no previous settings file. If one does exist, this will have no effect since it writes the same value back immediately. - QString vName; - QSettings config(QSettings::IniFormat, QSettings::UserScope, QApplication::organizationName(), QApplication::applicationDisplayName()); - config.beginGroup("MainWindow"); - vName = "maximized"; - edict[vName] = config.value(vName, false); - config.setValue(vName, edict.value(vName)); - vName = "size"; - edict[vName] = config.value(vName, QSize(wMinWidth, wMinHeight)); - config.setValue(vName, edict.value(vName)); - vName = "position"; - edict[vName] = config.value(vName, QPoint((mResWidth/2) - (wMinWidth/2), (mResHeight/2) - (wMinHeight/2))); - config.setValue(vName, edict.value(vName)); - config.endGroup(); - config.beginGroup("Settings"); - vName = "file"; - edict[vName] = config.value(vName, "file0"); - config.setValue(vName, edict.value(vName)); - vName = "directory"; - edict[vName] = config.value(vName, UNDERTALE_PATH); - config.setValue(vName, edict.value(vName)); - vName = "loadfile"; - edict[vName] = config.value(vName, false); - config.setValue(vName, edict.value(vName)); - vName = "loaddir"; - edict[vName] = config.value(vName, false); - config.setValue(vName, edict.value(vName)); - vName = "confirmsave"; - edict[vName] = config.value(vName, true); - config.setValue(vName, edict.value(vName)); - vName = "rememberlastdir"; - edict[vName] = config.value(vName, true); - config.setValue(vName, edict.value(vName)); - config.endGroup(); - config.beginGroup("Filters"); - vName = "hideboolean"; - edict[vName] = config.value(vName, false); - config.setValue(vName, edict.value(vName)); - vName = "hidecomment"; - edict[vName] = config.value(vName, true); - config.setValue(vName, edict.value(vName)); - vName = "hidecounter"; - edict[vName] = config.value(vName, false); - config.setValue(vName, edict.value(vName)); - vName = "hidenumber"; - edict[vName] = config.value(vName, false); - config.setValue(vName, edict.value(vName)); - vName = "hiderange"; - edict[vName] = config.value(vName, false); - config.setValue(vName, edict.value(vName)); - vName = "hideunused"; - edict[vName] = config.value(vName, true); - config.setValue(vName, edict.value(vName)); - config.endGroup(); - - // A sprouting new feature... -// QSettings undertale(":/strings/undertale.ini", QSettings::IniFormat); -// inilist = undertale.allKeys(); -// for(int i = 0; i < inilist.size(); i++) -// { -// // See? "edict" and "law". -// law.insert(inilist.at(i), undertale.value(inilist.value(i)).toString()); -// } - -#ifndef QT_NO_CURSOR - QApplication::setOverrideCursor(Qt::WaitCursor); -#endif - // At the moment using FOUR different files is more convenient than a single really messy one. - QFile infofile(":/strings/infofile"); - QFile typefile(":/strings/typefile"); - QFile rangefile(":/strings/rangefile"); - QFile dullfile(":/strings/dullfile"); - QTextStream buffer1(&infofile); - QTextStream buffer2(&typefile); - QTextStream buffer3(&rangefile); - QTextStream buffer4(&dullfile); - if(!infofile.open(QFile::ReadOnly | QFile::Text) || !typefile.open(QFile::ReadOnly | QFile::Text) || !rangefile.open(QFile::ReadOnly | QFile::Text) || !dullfile.open(QFile::ReadOnly | QFile::Text)) + if(window->currentIndex() == 0) { - QMessageBox::warning(this, "Application", QString("Cannot read file.")); - ui->statusBar->showMessage(QString("Loading file failed")); - return; + writeFile(); } else { - int i = 0; - while(!buffer1.atEnd()) - { - buffer1.readLineInto(&mem1[++i]); // label - buffer2.readLineInto(&mem2[i]); // type - buffer3.readLineInto(&mem3[i]); // range - buffer4.readLineInto(&mem4[i]); // comment - mem4[i] = "" + mem4.value(i) + ""; - - if(mem2.value(i) == "bool") - { - stats[0]++; - } - if(mem2.value(i) == "counter") - { - stats[1]++; - } - if(mem2.value(i) == "range") - { - stats[2]++; - } - if(mem2.value(i) == "unused") - { - stats[3]++; - } - } + writeIni(); } - - infofile.close(); - typefile.close(); - rangefile.close(); - dullfile.close(); -#ifndef QT_NO_CURSOR - QApplication::restoreOverrideCursor(); -#endif - - workDir.setPath(QDir::currentPath()); - workFile = "file"; } -void MainWindow::setupMenuBar() +void MainWindow::saveFileAs() { - ui->menuConfig->setToolTipsVisible(true); - ui->menuFile->setToolTipsVisible(true); - ui->menuReset->setToolTipsVisible(true); - - ui->actionFileNew->setShortcut(QKeySequence::New); - ui->actionFileNew->setStatusTip("Start fresh. Fresh sold separately."); - ui->actionFileNew->setWhatsThis("This feature attempts to be similar to how the game makes a new save file."); - - ui->actionFileOpen->setShortcut(QKeySequence::Open); - ui->actionFileOpen->setStatusTip("For opening files, dummy."); - ui->actionFileOpen->setWhatsThis("Use your system's native filebrowser to conveniently select a pre-existing file."); - - ui->actionFileSave->setShortcut(QKeySequence::Save); - ui->actionFileSave->setStatusTip("It would be a SHAME, if you lost all your work."); - ui->actionFileSave->setWhatsThis("Saves your changes to currently open file, essentially replacing it."); - - ui->actionFileSaveAs->setShortcut(QKeySequence::SaveAs); - ui->actionFileSaveAs->setStatusTip("It would be a greater SHAME, if you lost your original file."); - ui->actionFileSaveAs->setWhatsThis("Use your system's native filebrowser to conveniently select name and location for your file."); - - ui->actionFileResetUndo->setStatusTip("Are you just going to throw away your progress?"); - ui->actionFileResetUndo->setWhatsThis("Restore data from a state when you first loaded your file."); - - ui->actionFileResetTrueReset->setStatusTip("What would Sans say about this?"); - ui->actionFileResetTrueReset->setWhatsThis("This will allow you to activate True Reset. Normally after certain conditions are met, player is presented with an option to reset."); - - ui->actionFileResetTransactionCancellation->setStatusTip("You felt your sins crawling on your back"); - ui->actionFileResetTransactionCancellation->setWhatsThis("Removes data and resets some values in an attempt to erase effects of Genodice Run and restore the \"Happy Ending\". If only you could erase your actions from your mind as easily."); - - ui->actionFileExit->setStatusTip("I will not stop you. However, when you leave... Please do not come back."); - ui->actionFileExit->setWhatsThis("Closes this program. Same as pressing the \"X\" at the top corner."); - - if(edict.value("loaddir").toBool()) - { - workDir.setPath(edict.value("directory").toString()); - if(!workDir.exists()) - { - QMessageBox::warning(this, "Application", QString("Cannot access directory %1:\n%2.").arg(workDir.path(), "Directory does not exist")); - workDir.setPath(QDir::currentPath()); - } - } - if(edict.value("loadfile").toBool()) + QFileDialog dialog(this); + dialog.setWindowModality(Qt::WindowModal); + dialog.setAcceptMode(QFileDialog::AcceptSave); + dialog.setFileMode(QFileDialog::AnyFile); + dialog.setDirectory(workDir); + if (dialog.exec() != QDialog::Accepted) { - workFile = edict.value("file").toString(); - if(QFile::exists(workDir.filePath(workFile))) - { - loadFile(workDir, workFile); - } - else - { - QMessageBox::warning(this, "Application", QString("Cannot access file %1:\n%2.").arg(workFile, "File does not exist")); - workFile.clear(); - } + return; } -} -bool MainWindow::castWork() -{ - if (isModified) + QString path = dialog.selectedFiles().first(); + if (path.isEmpty()) { - QMessageBox confirm; - confirm.setText("That's some really nice modifications."); - confirm.setInformativeText("It would be a SHAME if something\n\"happened\" to them."); - confirm.setStandardButtons(QMessageBox::Save | QMessageBox::Discard | QMessageBox::Cancel); - confirm.setDefaultButton(QMessageBox::Cancel); - confirm.setIconPixmap(QPixmap(":/images/flowey.png")); - int result = confirm.exec(); - switch(result) - { - case QMessageBox::Save: - return on_actionFileSave_triggered(); - - case QMessageBox::Cancel: - return false; - } + return; } - fileWasModified(0); - return true; -} -void MainWindow::loadFile(const QDir &fileDir, const QString &fileName) -{ - qDebug() << "BEGIN loadFile(" << fileDir.path() << ", " << fileName << ")"; - QFile file(fileDir.filePath(fileName)); - if(!file.open(QFile::ReadOnly | QFile::Text)) + workDir = QFileInfo(path).dir().absolutePath(); + if (QFileInfo(path).completeSuffix().contains("ini")) { - QMessageBox::warning(this, "Application", QString("Cannot read %1 in %2:\n%3.").arg(fileName, fileDir.path(), file.errorString())); - ui->statusBar->showMessage(QString("Loading %1 in %2 failed").arg(fileName, fileDir.path())); - return; + iniPath = path; + window->setTabText(1, QFileInfo(path).fileName()); + writeIni(); } else { - #ifndef QT_NO_CURSOR - QApplication::setOverrideCursor(Qt::WaitCursor); - #endif -// if(QFile::exists(fileDir.filePath("undertale.ini"))) -// { -// inilist.clear(); -// QSettings utconf(QString(fileDir.filePath("undertale.ini")), QSettings::IniFormat); -// inilist = utconf.allKeys(); -// for(int i = 0; i < inilist.size(); i++) -// { -// inivals.append(utconf.value(inilist.value(i)).toString()); -// qDebug() << "utconf[" << inilist.at(i) << "]:" << inivals.value(i); -// } -// } - QTextStream buffer(&file); - int i = 0; - while(!buffer.atEnd()) - { - buffer.readLineInto(&mem0[++i]); - mem0[i] = mem0.value(i).simplified(); - tem0[i] = mem0.value(i); - } - setWindowFilePath(fileDir.filePath(fileName)); - setWindowTitle(TITLELABEL); - ui->statusBar->showMessage(QString("Loading %1 in %2 complete").arg(fileName, fileDir.path())); - - if(edict.value("rememberlastdir").toBool()) - { - workDir = fileDir; - } + filePath = path; + window->setTabText(0, QFileInfo(path).fileName()); + writeFile(); } - file.close(); -#ifndef QT_NO_CURSOR - QApplication::restoreOverrideCursor(); -#endif } -bool MainWindow::saveFile(const QDir &fileDir, const QString &fileName) +void MainWindow::loadData() { - qDebug() << "BEGIN saveFile(" << fileDir.path() << ", " << fileName << ")"; - if(QFile::exists(fileDir.filePath(fileName)) && edict.value("confirmsave").toBool()) + QJsonObject json = QJsonDocument::fromJson(downloader->data).object(); + QString version = json["version"].toString(); + QStringList local = QApplication::applicationVersion().split('.'); + QStringList remote = version.split('.'); + + int lArr[4] = {0}, rArr[4] = {0}; + int len = local.size(); + for (int i = 0; i < len; i++) { - int result = QMessageBox::question(this, "Confirm Overwrite", QString("Do you want to overwrite %1?").arg(fileName), QMessageBox::Yes | QMessageBox::No); - if(result == QMessageBox::No) - { - return false; - } + lArr[i] = local.at(i).toInt(); } - QFile file(fileDir.filePath(fileName)); - if(!file.open(QFile::WriteOnly | QFile::Text)) + len = remote.size(); + for (int i = 0; i < len; i++) { - QMessageBox::warning(this, "Application", QString("Cannot read %1 in %2:\n%3.").arg(fileName, fileDir.path(), file.errorString())); - ui->statusBar->showMessage(QString("Saving %1 in %2 failed").arg(fileName, fileDir.path())); - return false; + rArr[i] = remote.at(i).toInt(); } - else + + bool remoteIsNewer = std::lexicographical_compare(lArr, lArr + 4, rArr, rArr + 4); + if(remoteIsNewer) { - #ifndef QT_NO_CURSOR - QApplication::setOverrideCursor(Qt::WaitCursor); - #endif - QTextStream buffer(&file); - int size = mem0.size(); - for(int i = 1; i <= size; i++) - { - if(i == size) - { - buffer << mem0.value(i); - } - else - { - endl(buffer << mem0.value(i)); - } - } - file.close(); - #ifndef QT_NO_CURSOR - QApplication::restoreOverrideCursor(); - #endif - if(edict.value("rememberlastdir").toBool()) - { - workDir = fileDir; - } - fileWasModified(0); - setWindowFilePath(fileDir.filePath(fileName)); - setWindowTitle(TITLELABEL); - ui->statusBar->showMessage(QString("Saving %1 in %2 complete").arg(fileName, fileDir.path())); + QMessageBox::information(this, tr("New version of this program is available"), + tr("Go to https://github.com/Cofeiini/UndertaleSaveEditor/releases to download version %1").arg(version), + QMessageBox::Ok); } - return true; -} - -void MainWindow::dataComboWasModified(int num) -{ - qDebug() << "dataComboWasModified(" << num << ")"; - int index = sender()->property("objectName").toInt(); - - mem0[index] = QString::number(num); - qDebug() << index << mem0.value(index); - - fileWasModified(1); } -void MainWindow::dataStringWasModified(QString string) +void MainWindow::showDebug(bool checked) { - qDebug() << "dataStringWasModified(" << string << ")"; - int index = sender()->property("objectName").toInt(); - mem0[index] = string; - fileWasModified(1); + buttons.at(4)->setHidden(!checked); } -void MainWindow::dataTimeWasModified(double num) +void MainWindow::showDog(bool checked) { - qDebug() << "dataTimeWasModified(" << num << ")"; - QString string = QString::number(num); - int index = sender()->property("objectName").toInt(); - mem0[index] = string; - - QLabel *timeLabel = this->findChild("timeLabel"); - qint64 tim = mem0.value(index).toDouble(); - int hour = std::fmod(tim/108000, 60); - int minute = std::fmod(tim/1800, 60); - int second = std::fmod(tim/30, 60); - timeLabel->setText( QString::number(hour) + ":" + QString::number(minute) + ":" + QString::number(second)); - fileWasModified(1); + buttons.at(5)->setHidden(!checked); } -void MainWindow::dataBoolWasModified(int num) +bool MainWindow::checkIfFileSave() { - qDebug() << "USE dataBoolWasModified(bool " << num << ")"; - QObject *dummy = sender(); - int index = dummy->property("objectName").toInt(); - int fst = mem3.value(index).section(',',0,0).toInt(); - int snd = mem3.value(index).section(',',1,1).toInt(); - int trd = mem3.value(index).section(',',2,2).toInt(); - switch(num) + if (!isFileModified) { - case 0: - num = fst; - break; - - case 1: - num = snd; - break; - - case 2: - num = trd; - break; + return true; } - mem0[index] = QString::number(num); - dummy->setProperty("text", QString::number(num)); - fileWasModified(1); -} - -void MainWindow::fileWasModified(bool mode) -{ - qDebug() << "BEGIN documentWasModified(" << mode << ")"; - QObject *dummy = sender(); - if(mode && dummy != NULL) + const QMessageBox::StandardButton ret = QMessageBox::warning( + this, QApplication::applicationName(), + tr("The file has been modified.\n" + "Do you want to save your changes?"), + QMessageBox::Save | QMessageBox::Discard | QMessageBox::Cancel); + switch (ret) { - int index = dummy->property("objectName").toInt(); - QString bak = tem0.value(index); - QString rep = mem0.value(index); - if(bak != rep) - { - isModified = true; - dummy->setProperty("styleSheet", "background-color: yellow"); - - if(totalChanges.indexOf(index) == -1) - { - totalChanges.append(index); - } - } - else - { - if(totalChanges.size() < 2) - { - isModified = false; - } - dummy->setProperty("styleSheet", ""); - totalChanges.removeAt(totalChanges.indexOf(index)); - } - } - else - { - isModified = false; - int size = mem0.size(); - for(int i = 0; i < size; i++) - { - QWidget *dummy = items[i]; - if(!isModified) - { - dummy->setProperty("styleSheet", ""); - } - } - totalChanges.clear(); + case QMessageBox::Save: + window->setCurrentIndex(0); + saveFile(); + return true; + case QMessageBox::Cancel: + return false; + default: // Discard + return true; } - setWindowModified(isModified); - qDebug() << totalChanges; } -void MainWindow::closeEvent(QCloseEvent *event) +bool MainWindow::checkIfIniSave() { - qDebug() << "BEGIN closeEvent(QCloseEvent " << &event << ")"; - if (castWork()) + if (!isIniModified) { - event->accept(); + return true; } - else + + const QMessageBox::StandardButton ret = QMessageBox::warning( + this, QApplication::applicationName(), + tr("The file has been modified.\n" + "Do you want to save your changes?"), + QMessageBox::Save | QMessageBox::Discard | QMessageBox::Cancel); + switch (ret) { - event->ignore(); + case QMessageBox::Save: + window->setCurrentIndex(1); + saveFile(); + return true; + case QMessageBox::Cancel: + return false; + default: // Discard + return true; } } -MainWindow::~MainWindow() +void MainWindow::writeFile() { - QSettings config(QSettings::IniFormat, QSettings::UserScope, QApplication::organizationName(), QApplication::applicationDisplayName()); - config.beginGroup("MainWindow"); - config.setValue("maximized", isMaximized()); - config.setValue("size", size()); - config.setValue("position", pos()); - config.endGroup(); - delete ui; -} - -void MainWindow::on_actionFileNew_triggered() -{ - if(castWork()) + QFile file(filePath); + if (!file.open(QFile::WriteOnly | QFile::Text)) { - QString cName = mem0.value(1); - int fun = qrand()%((100 + 1) - 1) + 1; - qDebug() << "cName: " << cName << ", fun: " << fun; - workFile.clear(); - workFile = "file"; - setWindowFilePath(workFile); - setWindowTitle(TITLELABEL); - - QFile freshFile(":/strings/freshfile"); - if(!freshFile.open(QFile::ReadOnly | QFile::Text)) - { - QMessageBox::warning(this, "Application", QString("Cannot generate a fresh file :\n%1.").arg(freshFile.errorString())); - ui->statusBar->showMessage(QString("Generating a fresh file failed")); - return; - } - else - { - #ifndef QT_NO_CURSOR - QApplication::setOverrideCursor(Qt::WaitCursor); - #endif - QTextStream freshBuffer(&freshFile); - int i = 0; - while(!freshBuffer.atEnd()) - { - freshBuffer.readLineInto(&mem0[++i]); - mem0[i] = mem0.value(i).simplified(); - } - freshFile.close(); - #ifndef QT_NO_CURSOR - QApplication::restoreOverrideCursor(); - #endif - - ui->statusBar->showMessage(QString("Generating a fresh file complete")); - } - mem0[1] = cName; - mem0[36] = QString::number(fun); - fileWasModified(1); - displayInfo(); + QMessageBox::warning( + this, QApplication::applicationName(), + tr("Cannot write file %1:\n%2.") + .arg(QDir::toNativeSeparators(filePath), file.errorString())); + return; } -} -void MainWindow::on_actionFileOpen_triggered() -{ - if (castWork()) + QTextStream out(&file); + +#ifndef QT_NO_CURSOR + QApplication::setOverrideCursor(Qt::WaitCursor); +#endif + for (int i = 1; i <= 549; i++) { - QDir targetDir; - QString targetFile = QFileDialog::getOpenFileName(this,"Select a file", workDir.path()); - if (!targetFile.isEmpty()) + out << saveData.at(i); + if (i < 549) { - workFile = targetFile.section("/", -1); - targetFile.chop(workFile.size()); - targetDir.setPath(targetFile); - loadFile(targetDir, workFile); + out << "\n"; } } - fileWasModified(0); - displayInfo(); +#ifndef QT_NO_CURSOR + QApplication::restoreOverrideCursor(); +#endif + fileModified(false); } -bool MainWindow::on_actionFileSave_triggered() +void MainWindow::writeIni() { - if (workFile.isEmpty()) - { - return on_actionFileSaveAs_triggered(); - } - else + QFile file(iniPath); + if (!file.open(QFile::ReadWrite | QFile::Text)) { - return saveFile(workDir, workFile); + QMessageBox::warning( + this, QApplication::applicationName(), + tr("Cannot write file %1:\n%2.") + .arg(QDir::toNativeSeparators(iniPath), file.errorString())); + return; } - return false; -} -bool MainWindow::on_actionFileSaveAs_triggered() -{ - QDir targetDir; - QString filter = ""; - QString targetFile = QFileDialog::getSaveFileName(this, "Save As...", workDir.path() + "/" + workFile, "", &filter, QFileDialog::DontConfirmOverwrite); - if(!targetFile.isEmpty()) + if (file.exists()) { - workFile = targetFile.section("/", -1); - targetFile.chop(workFile.size()); - targetDir.setPath(targetFile); - - return saveFile(targetDir, workFile); + file.resize(0); } - return false; -} + file.close(); -void MainWindow::on_actionFileExit_triggered() -{ - if(castWork()) + // this block is important! + // it prevents QSettings from messing with the file during cleanup { - this->close(); + QSettings out(iniPath, QSettings::IniFormat); + if(out.isWritable()) + { + foreach (QString item, iniData.keys()) + { + if (item == "Name") + { + out.setValue(item, "\"" + iniData.value(item).toString() + "\""); + } + else + { + out.setValue(item, "\"" + QString::number(iniData.value(item).toDouble(), 'f', 6) + "\""); + } + } + } } -} - -void MainWindow::on_actionFileResetUndo_triggered() -{ - // Is supposed to reset changes made to a file. Same as trying to open a new file and discarding changes. -} - -void MainWindow::on_actionFileResetTrueReset_triggered() -{ - // Intended to have same effect as the in-game "True Reset" - -} - -void MainWindow::on_actionFileResetTransactionCancellation_triggered() -{ - // For undoing certain SOUL transaction with a certain FALLEN CHILD -} - -void MainWindow::configReciever() -{ - QString group; - QSettings config(QSettings::IniFormat, QSettings::UserScope, QApplication::organizationName(), QApplication::applicationDisplayName()); - foreach(QString key, config.allKeys()) +#ifndef QT_NO_CURSOR + QApplication::setOverrideCursor(Qt::WaitCursor); +#endif + // cleanup all backslashes from the file + if(file.open(QFile::ReadWrite | QFile::Text)) { - group = key.section("/", 0, 0); - key = key.section("/", -1); - config.beginGroup(group); - edict[key] = config.value(key); - config.endGroup(); + QString s; + QTextStream out(&file); + while (!out.atEnd()) + { + QString line = out.readLine().remove('\\'); + if (!line.isEmpty()) + { + s.append(line + "\n"); + } + } + file.resize(0); + out << s; + file.close(); } - displayInfo(); -} - -void MainWindow::on_actionConfigDialog_triggered() -{ - settingsDialog->show(); +#ifndef QT_NO_CURSOR + QApplication::restoreOverrideCursor(); +#endif + iniModified(false); } diff --git a/mainwindow.h b/mainwindow.h index 3799e7d..5915577 100644 --- a/mainwindow.h +++ b/mainwindow.h @@ -1,105 +1,83 @@ #ifndef MAINWINDOW_H #define MAINWINDOW_H -#define TITLELABEL windowFilePath() + "[*]" + " - " + QApplication::applicationName() + " (v" + QApplication::applicationVersion() + ")" -#if defined(__linux__) -# define UNDERTALE_PATH (QDir::homePath() + "/.config/UNDERTALE/") -#elif defined(__macosx__) -# define UNDERTALE_PATH (QDir::homePath() + "/Library/Application Support/com.tobyfox.undertale/") -#else -# define UNDERTALE_PATH (QDir::homePath() + "/AppData/Local/UNDERTALE/") -#endif - -// I like having my includes in a single place -#include "configdialog.h" -#include "dataeditor.h" - -#include -#include -#include -#include -#include -#include -#include -#include -#include +#include #include -#include -#include -#include -#include -#include -#include +#include +#include +#include -namespace Ui +class FileDownloader : public QObject { - class MainWindow; -} + Q_OBJECT +public: + FileDownloader(QUrl url, QObject *parent) : QObject(parent) + { + connect(&manager, SIGNAL(finished(QNetworkReply*)), + this, SLOT(fileDownloaded(QNetworkReply*))); + manager.get(QNetworkRequest(url)); + } + QByteArray data; +signals: + void downloaded(); +private slots: + void fileDownloaded(QNetworkReply* reply) + { + data = reply->readAll(); + reply->deleteLater(); + reply = nullptr; + emit downloaded(); + } +private: + QNetworkAccessManager manager; +}; class MainWindow : public QMainWindow { Q_OBJECT - - public: - explicit MainWindow(QWidget *parent = 0); - ~MainWindow(); - - protected: - void closeEvent(QCloseEvent *event) Q_DECL_OVERRIDE; - void showEvent(QShowEvent *event) Q_DECL_OVERRIDE; - - private slots: - bool on_actionFileSaveAs_triggered(); - bool on_actionFileSave_triggered(); - - void configReciever(); - void dataBoolWasModified(int num); - void dataComboWasModified(int num); - void dataStringWasModified(QString string); - void dataTimeWasModified(double num); - void fileWasModified(bool mode); - - void on_actionConfigDialog_triggered(); - void on_actionFileExit_triggered(); - void on_actionFileNew_triggered(); - void on_actionFileOpen_triggered(); - void on_actionFileResetTransactionCancellation_triggered(); - void on_actionFileResetTrueReset_triggered(); - void on_actionFileResetUndo_triggered(); - - +public: + MainWindow(QWidget *parent = nullptr); + QStringList saveData = QString("null,Chara,1,20,20,10,0,10,0,4,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,3,4,0,0,0,0,0,100,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,14,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0").split(","); + QMap iniData; +protected: + void closeEvent(QCloseEvent *event) override; + void showEvent(QShowEvent * event) override; +signals: + void updateWidgets(); + void updateIniWidgets(); +public slots: + void changePage(QListWidgetItem *current, QListWidgetItem *previous); + void fileModified(bool value); + void iniModified(bool value); +private slots: + void openFile(); + void openIni(); + void saveFile(); + void saveFileAs(); + void loadData(); + void showDebug(bool checked); + void showDog(bool checked); private: - bool castWork(); - bool isModified; - bool saveFile(const QDir &fileDir, const QString &fileName); - int mResHeight; - int mResWidth; - int wMinHeight; - int wMinWidth; - void displayInfo(); - void loadFile(const QDir &fileDir, const QString &fileName); - void readSettings(); - void setupEntries(); - void setupMenuBar(); + bool checkIfFileSave(); + bool checkIfIniSave(); + void writeFile(); + void writeIni(); + + QString iniPath; + QString filePath; + QString workDir; + QVector buttons; - QDir workDir; - QHash mem0, mem1, mem2, mem3, mem4; - QHash tem0; - QLabel *info[549]; - QLabel *numfo[549]; - QMap law; - QMap edict; - QStringList inilist; - QStringList inivals; - QStringList entryTypes; - QString workFile; - QTextBrowser *comment[549]; - QVector stats; - QVector totalChanges; - QVector items; + FileDownloader *downloader; + QAction *saveAction; + QAction *saveAsAction; + QListWidget *icons; + QStackedWidget *pages; + QTabWidget *window; - ConfigDialog *settingsDialog; - Ui::MainWindow *ui; + bool isFileModified = false; + bool isIniModified = false; + QIcon floppy[2] = {QIcon(":/images/ico_floppy.png"), QIcon(":/images/ico_floppy_red.png")}; }; #endif // MAINWINDOW_H diff --git a/mainwindow.ui b/mainwindow.ui deleted file mode 100644 index d580b5b..0000000 --- a/mainwindow.ui +++ /dev/null @@ -1,290 +0,0 @@ - - - MainWindow - - - - 0 - 0 - 800 - 600 - - - - - 800 - 600 - - - - - :/images/tobdog.png:/images/tobdog.png - - - - - - QTabWidget::Triangular - - - - - 0 - 0 - - - - - - - - 0 - 0 - - - - QFrame::Box - - - QFrame::Plain - - - true - - - - - 0 - 0 - 780 - 539 - - - - - - - Qt::Horizontal - - - QSizePolicy::Expanding - - - - 40 - 20 - - - - - - - - 6 - - - QLayout::SetNoConstraint - - - - - - - Qt::Horizontal - - - QSizePolicy::Expanding - - - - 40 - 20 - - - - - - - - - - - - - - 0 - 0 - 800 - 21 - - - - true - - - - PointingHandCursor - - - - - - File - - - - false - - - - - - Reset - - - - - - - - - - - - - - - - PointingHandCursor - - - - - - Settings - - - - - - - - - - true - - - - :/images/heart.png:/images/heart.png - - - New - - - <html><head/><body><p>Generate a new save file.</p></body></html> - - - true - - - - - - :/images/box.png:/images/box.png - - - Open - - - <html><head/><body><p>Open a save file.</p></body></html> - - - - - - :/images/save.png:/images/save.png - - - Save - - - <html><head/><body><p>Save your current work.</p></body></html> - - - - - - :/images/amalgam_save.png:/images/amalgam_save.png - - - Save As... - - - <html><head/><body><p>Save your current work to specified file.</p></body></html> - - - - - - :/images/heartgtfo.png:/images/heartgtfo.png - - - Exit - - - <html><head/><body><p>Close this program.</p></body></html> - - - - - - :/images/heartbreak.png:/images/heartbreak.png - - - Undo Changes - - - <html><head/><body><p>Restore your file to it's original state.</p></body></html> - - - - - - :/images/asriel.png:/images/asriel.png - - - True Reset - - - <html><head/><body><p>Perform a True Reset, just like in the game.</p></body></html> - - - - - - :/images/truechara.png:/images/truechara.png - - - Transaction Cancellation - - - <html><head/><body><p>Cancel your transaction with a certain Fallen Child,<br>erasing your &quot;genocidal&quot; actions.</p></body></html> - - - - - - :/images/tobdog_wrench.png:/images/tobdog_wrench.png - - - Open Settings - - - <html><head/><body><p>Opens the settings dialog window.</p></body></html> - - - - - - - diff --git a/pages.cpp b/pages.cpp new file mode 100644 index 0000000..7d1dcf2 --- /dev/null +++ b/pages.cpp @@ -0,0 +1,862 @@ +#include "pages.h" +#include "tools.h" +#include "initools.h" + +#include +#include +#include +#include +#include + + +PlayerPage::PlayerPage(MainWindow *mainWindow, QWidget *parent) : QScrollArea(parent) +{ + QWidget *window = new QWidget(); + QGridLayout *mainLayout = new QGridLayout(); + + QGroupBox *attackGroup = new QGroupBox(tr("Attack")); + QGridLayout *attackLayout = new QGridLayout(); + attackLayout->addWidget(new QLabel("AT"), 0, 0, Qt::AlignRight); + attackLayout->addWidget(new CustomSpinBox(5, mainWindow), 0, 1); + attackLayout->addWidget(new QLabel("Weapon"), 1, 0, Qt::AlignRight); + attackLayout->addWidget(new WeaponComboBox(29, mainWindow), 1, 1); + attackLayout->addWidget(new QLabel("Weapon AT"), 2, 0, Qt::AlignRight); + attackLayout->addWidget(new CustomSpinBox(6, mainWindow), 2, 1); + attackGroup->setLayout(attackLayout); + + QGroupBox *defenceGroup = new QGroupBox(tr("Defence")); + QGridLayout *defenceLayout = new QGridLayout(); + defenceLayout->addWidget(new QLabel("DF"), 0, 0, Qt::AlignRight); + defenceLayout->addWidget(new CustomSpinBox(7, mainWindow), 0, 1); + defenceLayout->addWidget(new QLabel("Armor"), 1, 0, Qt::AlignRight); + defenceLayout->addWidget(new ArmorComboBox(30, mainWindow), 1, 1); + defenceLayout->addWidget(new QLabel("Armor DF"), 2, 0, Qt::AlignRight); + defenceLayout->addWidget(new CustomSpinBox(8, mainWindow), 2, 1); + defenceGroup->setLayout(defenceLayout); + + + QGroupBox *inventoryGroup = new QGroupBox(tr("Inventory")); + inventoryGroup->setLayout(new QVBoxLayout()); + for (int i = 13; i <= 27; i += 2) + { + inventoryGroup->layout()->addWidget(new ItemComboBox(i, mainWindow)); + } + + QGroupBox *phoneGroup = new QGroupBox(tr("Phone")); + phoneGroup->setLayout(new QVBoxLayout()); + for (int i = 14; i <= 28; i += 2) + { + phoneGroup->layout()->addWidget(new PhoneComboBox(i, mainWindow)); + } + + QGroupBox *dBoxAGroup = new QGroupBox(tr("Dimensional Box A")); + dBoxAGroup->setLayout(new QVBoxLayout()); + for (int i = 331; i <= 340; i++) + { + dBoxAGroup->layout()->addWidget(new ItemComboBox(i, mainWindow)); + } + + QGroupBox *dBoxBGroup = new QGroupBox(tr("Dimensional Box B")); + dBoxBGroup->setLayout(new QVBoxLayout()); + for (int i = 343; i <= 352; i++) + { + dBoxBGroup->layout()->addWidget(new ItemComboBox(i, mainWindow)); + } + + QGroupBox *killsGroup = new QGroupBox(tr("Kills")); + QGridLayout *killsLayout = new QGridLayout(); + killsLayout->addWidget(new QLabel("Kills"), 0, 0, Qt::AlignRight); + killsLayout->addWidget(new CustomSpinBox(12, mainWindow), 0, 1); + killsLayout->addWidget(new QLabel("Total"), 0, 2, Qt::AlignRight); + killsLayout->addWidget(new CustomSpinBox(232, mainWindow), 0, 3); + killsLayout->addWidget(new QLabel("Ruins"), 1, 0, Qt::AlignRight); + killsLayout->addWidget(new CustomSpinBox(233, mainWindow), 1, 1); + killsLayout->addWidget(new QLabel("Snowdin"), 1, 2, Qt::AlignRight); + killsLayout->addWidget(new CustomSpinBox(234, mainWindow), 1, 3); + killsLayout->addWidget(new QLabel("Waterfall"), 1, 4, Qt::AlignRight); + killsLayout->addWidget(new CustomSpinBox(235, mainWindow), 1, 5); + killsLayout->addWidget(new QLabel("Hotland"), 1, 6, Qt::AlignRight); + killsLayout->addWidget(new CustomSpinBox(236, mainWindow), 1, 7); + killsGroup->setLayout(killsLayout); + + QGroupBox *lastFightGroup = new QGroupBox(tr("Last fight")); + QGridLayout *lastFightLayout = new QGridLayout(); + lastFightLayout->addWidget(new CustomRadioButton(41, tr("Spare"), mainWindow), 0, 0); + lastFightLayout->addWidget(new CustomRadioButton(42, tr("Flee"), mainWindow), 0, 1); + lastFightLayout->addWidget(new CustomRadioButton(43, tr("Kill"), mainWindow), 1, 0); + lastFightLayout->addWidget(new CustomRadioButton(44, tr("Bored"), mainWindow), 1, 1); + lastFightGroup->setLayout(lastFightLayout); + + QFormLayout *checkboxLayout = new QFormLayout(); + checkboxLayout->addRow(tr("Hard Mode"), new CustomCheckBox(37, mainWindow)); + checkboxLayout->addRow(tr("True Pacifist"), new CustomCheckBox(38, mainWindow)); + checkboxLayout->addRow(tr("Disable encounters"), new CustomCheckBox(39, mainWindow)); + checkboxLayout->addRow(tr("Cooked Instant Noodles"), new CustomCheckBox(52, mainWindow)); + checkboxLayout->addRow(tr("Spared a certain monster"), new CustomCheckBox(58, mainWindow)); + checkboxLayout->addRow(tr("Used Punch Card while wearing Tough Glove"), new CustomCheckBox(109, mainWindow)); + checkboxLayout->addRow(tr("Have an umbrella"), new CustomCheckBox(116, mainWindow)); + checkboxLayout->addRow(tr("Genocide in Ruins"), new CustomCheckBox(252, mainWindow)); + checkboxLayout->addRow(tr("Genocide in Snowdin"), new CustomCheckBox(253, mainWindow)); + checkboxLayout->addRow(tr("Genocide in Waterfall"), new CustomCheckBox(254, mainWindow)); + checkboxLayout->addRow(tr("Genocide in Hotland"), new CustomCheckBox(255, mainWindow)); + checkboxLayout->addRow(tr("Genocide in Core"), new CustomCheckBox(256, mainWindow)); + checkboxLayout->addRow(tr("Ate Food"), new CustomCheckBox(291, mainWindow)); + checkboxLayout->addRow(tr("Inside the True Lab"), new CustomCheckBox(511, mainWindow)); + checkboxLayout->addRow(tr("Seen the cast"), new CustomCheckBox(530, mainWindow)); + + QFormLayout *spinBoxLayout = new QFormLayout(); + spinBoxLayout->addRow(tr("Spare counter"), new CustomSpinBox(54, mainWindow)); + spinBoxLayout->addRow(tr("Flee counter"), new CustomSpinBox(55, mainWindow)); + spinBoxLayout->addRow(tr("Dialog skip counter"), new CustomSpinBox(56, mainWindow)); + spinBoxLayout->addRow(tr("Gold spent on Spider bake sale"), new CustomSpinBox(90, mainWindow)); + spinBoxLayout->addRow(tr("Gold spent on Nice Cream"), new CustomSpinBox(91, mainWindow)); + spinBoxLayout->addRow(tr("Gold spent on Hot Dogs"), new CustomSpinBox(409, mainWindow)); + + mainLayout->addWidget(new QLabel("Name"), 0, 0, Qt::AlignRight); + mainLayout->addWidget(new CustomLineEdit(1, mainWindow), 0, 1); + mainLayout->addWidget(new QLabel("Plot"), 0, 2, Qt::AlignRight); + mainLayout->addWidget(new PlotEdit(543, mainWindow), 0, 3); + + mainLayout->addWidget(new QLabel("LV"), 1, 0, Qt::AlignRight); + mainLayout->addWidget(new CustomSpinBox(2, mainWindow), 1, 1); + mainLayout->addWidget(new QLabel("fun"), 1, 2, Qt::AlignRight); + mainLayout->addWidget(new CustomSpinBox(36, mainWindow), 1, 3); + + mainLayout->addWidget(new QLabel("Max HP"), 2, 0, Qt::AlignRight); + mainLayout->addWidget(new CustomSpinBox(3, mainWindow), 2, 1); + + mainLayout->addWidget(new QLabel("Gold"), 3, 0, Qt::AlignRight); + mainLayout->addWidget(new CustomSpinBox(11, mainWindow), 3, 1); + + mainLayout->addWidget(new QLabel("EXP"), 4, 0, Qt::AlignRight); + mainLayout->addWidget(new CustomSpinBox(10, mainWindow), 4, 1); + + mainLayout->addWidget(new QLabel("Time"), 5, 0, Qt::AlignRight); + mainLayout->addWidget(new TimeEdit(549, mainWindow), 5, 1); + mainLayout->addWidget(new QLabel("Room"), 5, 2, Qt::AlignRight); + mainLayout->addWidget(new RoomComboBox(548, mainWindow), 5, 3); + + mainLayout->addWidget(attackGroup, 0, 4, 3, 2); + mainLayout->addWidget(defenceGroup, 3, 4, 3, 2); + mainLayout->addWidget(inventoryGroup, 7, 0, 1, 2); + mainLayout->addWidget(phoneGroup, 7, 2, 1, 2); + mainLayout->addWidget(dBoxAGroup, 7, 4, 1, 1); + mainLayout->addWidget(dBoxBGroup, 7, 5, 1, 1); + mainLayout->addWidget(killsGroup, 8, 0, 1, 4); + mainLayout->addWidget(lastFightGroup, 8, 4, 1, 2); + mainLayout->addLayout(checkboxLayout, 9, 0, 1, 2); + mainLayout->addLayout(spinBoxLayout, 9, 3, 1, 2); + + window->setLayout(mainLayout); + setWidget(window); +} + +BossesPage::BossesPage(MainWindow *mainWindow, QWidget *parent) : QScrollArea(parent) +{ + QWidget *window = new QWidget(); + QVBoxLayout *mainLayout = new QVBoxLayout(); + + QGroupBox *floweyGroup = new QGroupBox(QString("Flowey")); + QFormLayout *floweyLayout = new QFormLayout(); + floweyLayout->addRow(tr("Stalker Flowey counter"), new CustomSpinBox(40, mainWindow)); + floweyLayout->addRow(tr("Killed Flowey"), new CustomCheckBox(506, mainWindow)); + floweyGroup->setLayout(floweyLayout); + + QGroupBox *torielGroup = new QGroupBox(QString("Toriel")); + QFormLayout *torielLayout = new QFormLayout(); + torielLayout->addRow(tr("Dog kidnapped Toriel's phone"), new CustomComboBox(68, mainWindow)); + torielLayout->addRow(tr("\"Say Hello\" counter"), new CustomSpinBox(71, mainWindow)); + torielLayout->addRow(tr("Flirted with Toriel"), new CustomCheckBox(72, mainWindow)); + torielLayout->addRow(tr("Called Toriel \"Mom\""), new CustomCheckBox(73, mainWindow)); + torielLayout->addRow(tr("Interaction with Toriel"), new CustomComboBox(76, mainWindow)); + torielLayout->addRow(tr("Chosen flavor of pie"), new CustomComboBox(77, mainWindow)); + torielLayout->addRow(tr("Toriel chat counter (Pacifist)"), new CustomSpinBox(222, mainWindow)); + torielLayout->addRow(tr("Checked messages from Toriel counter"), new CustomSpinBox(317, mainWindow)); + torielLayout->addRow(tr("Current messages from Toriel counter"), new CustomSpinBox(318, mainWindow)); + torielGroup->setLayout(torielLayout); + + QGroupBox *sansGroup = new QGroupBox(QString("sans")); + QFormLayout *sansLayout = new QFormLayout(); + sansLayout->addRow(tr("sans creeping in the forest"), new CustomComboBox(78, mainWindow)); + sansLayout->addRow(tr("Date with sans at Grillby's"), new CustomComboBox(120, mainWindow)); + sansLayout->addRow(tr("sans chat counter (Pacifist)"), new CustomSpinBox(223, mainWindow)); + sansLayout->addRow(tr("Fought sans"), new CustomCheckBox(302, mainWindow)); + sansLayout->addRow(tr("Tried to Spare sans"), new CustomCheckBox(303, mainWindow)); + sansLayout->addRow(tr("Food ordered at Grillby's"), new CustomComboBox(422, mainWindow)); + sansLayout->addRow(tr("Date with Sans at Mettaton Resort"), new CustomComboBox(444, mainWindow)); + sansLayout->addRow(tr("Got the key to sans's room"), new CustomComboBox(528, mainWindow)); + sansGroup->setLayout(sansLayout); + + QGroupBox *papyrusGroup = new QGroupBox(QString("Papyrus")); + QFormLayout *papyrusLayout = new QFormLayout(); + papyrusLayout->addRow(tr("Flirted with Papyrus"), new CustomCheckBox(97, mainWindow)); + papyrusLayout->addRow(tr("Interaction with Papyrus"), new CustomComboBox(98, mainWindow)); + papyrusLayout->addRow(tr("Fought Papyrus"), new CustomCheckBox(99, mainWindow)); + papyrusLayout->addRow(tr("Date with Papyrus"), new CustomComboBox(119, mainWindow)); + papyrusLayout->addRow(tr("Papyrus chat counter (Pacifist)"), new CustomSpinBox(226, mainWindow)); + papyrusLayout->addRow(tr("Skipped Papyrus's Special Attack (Genocide)"), new CustomCheckBox(321, mainWindow)); + papyrusLayout->addRow(tr("Skipped the Electric Maze puzzle (Genocide)"), new CustomCheckBox(322, mainWindow)); + papyrusLayout->addRow(tr("Papyrus phone call counter"), new CustomSpinBox(493, mainWindow)); + papyrusGroup->setLayout(papyrusLayout); + + QGroupBox *undyneGroup = new QGroupBox(QString("Undyne")); + QFormLayout *undyneLayout = new QFormLayout(); + undyneLayout->addRow(tr("Undyne fight counter"), new CustomSpinBox(130, mainWindow)); + undyneLayout->addRow(tr("Undyne chat counter (Pacifist)"), new CustomSpinBox(224, mainWindow)); + undyneLayout->addRow(tr("Asked you to talk to Napstablook (Pacifist)"), new CustomCheckBox(225, mainWindow)); + undyneLayout->addRow(tr("Killed Undyne the Undying"), new CustomCheckBox(282, mainWindow)); + undyneLayout->addRow(tr("Undyne got mad at the first bridge"), new CustomCheckBox(315, mainWindow)); + undyneLayout->addRow(tr("Undyne got mad at the large bridge"), new CustomCheckBox(316, mainWindow)); + undyneLayout->addRow(tr("Interaction with Undyne"), new CustomComboBox(381, mainWindow)); + undyneLayout->addRow(tr("Undyne's remaining HP"), new CustomSpinBox(382, mainWindow)); + undyneLayout->addRow(tr("Escaped from Undyne back to Waterfall"), new CustomCheckBox(383, mainWindow)); + undyneLayout->addRow(tr("Date with Undyne"), new CustomComboBox(420, mainWindow)); + undyneLayout->addRow(tr("Undyne moved to Papyrus's place"), new CustomCheckBox(496, mainWindow)); + undyneLayout->addRow(tr("Undyne talked about weather"), new CustomCheckBox(501, mainWindow)); + undyneLayout->addRow(tr("Interaction with Undyne's letter"), new CustomComboBox(525, mainWindow)); + undyneGroup->setLayout(undyneLayout); + + QGroupBox *alphysGroup = new QGroupBox(QString("Alphys")); + QFormLayout *alphysLayout = new QFormLayout(); + alphysLayout->addRow(tr("Alphys chat counter (Pacifist)"), new CustomSpinBox(227, mainWindow)); + alphysLayout->addRow(tr("Date with Alphys available"), new CustomCheckBox(523, mainWindow)); + alphysLayout->addRow(tr("Interaction with Alphys"), new CustomComboBox(524, mainWindow)); + alphysGroup->setLayout(alphysLayout); + + QGroupBox *mettatonGroup = new QGroupBox(QString("Mettaton")); + QFormLayout *mettatonLayout = new QFormLayout(); + mettatonLayout->addRow(tr("Mettaton chat counter (Pacifist)"), new CustomSpinBox(229, mainWindow)); + mettatonLayout->addRow(tr("Completed the Multicolor Tile Puzzle"), new CustomCheckBox(309, mainWindow)); + mettatonLayout->addRow(tr("Failed to defuse a bomb"), new CustomCheckBox(319, mainWindow)); + mettatonLayout->addRow(tr("Stepped on a green tile"), new CustomCheckBox(320, mainWindow)); + mettatonLayout->addRow(tr("State of the Shooter Mode"), new CustomComboBox(416, mainWindow)); + mettatonLayout->addRow(tr("Exposed Mettaton's switch"), new CustomComboBox(455, mainWindow)); + mettatonLayout->addRow(tr("Killed Mettaton"), new CustomCheckBox(456, mainWindow)); + mettatonGroup->setLayout(mettatonLayout); + + QGroupBox *asgoreGroup = new QGroupBox(QString("Asgore")); + QFormLayout *asgoreLayout = new QFormLayout(); + asgoreLayout->addRow(tr("Asgore chat counter (Pacifist)"), new CustomSpinBox(228, mainWindow)); + asgoreLayout->addRow(tr("Killed Asgore"), new CustomCheckBox(507, mainWindow)); + asgoreGroup->setLayout(asgoreLayout); + + QGroupBox *asrielGroup = new QGroupBox(QString("Asriel")); + QFormLayout *asrielLayout = new QFormLayout(); + asrielLayout->addRow(tr("Fought Asriel"), new CustomCheckBox(531, mainWindow)); + asrielLayout->addRow(tr("Stage of the final fight"), new CustomComboBox(532, mainWindow)); + asrielLayout->addRow(tr("Heart refuse counter"), new CustomSpinBox(533, mainWindow)); + asrielLayout->addRow(tr("Used a Dream"), new CustomCheckBox(534, mainWindow)); + asrielLayout->addRow(tr("Asriel turn counter"), new CustomSpinBox(535, mainWindow)); + asrielLayout->addRow(tr("Saved Undyne"), new CustomCheckBox(536, mainWindow)); + asrielLayout->addRow(tr("Saved Alphys"), new CustomCheckBox(537, mainWindow)); + asrielLayout->addRow(tr("Saved Papyrus and sans"), new CustomCheckBox(538, mainWindow)); + asrielLayout->addRow(tr("Saved Toriel and Asgore"), new CustomCheckBox(539, mainWindow)); + asrielLayout->addRow(tr("HP display"), new CustomComboBox(540, mainWindow)); + asrielLayout->addRow(tr("Child Asriel chat counter"), new CustomSpinBox(542, mainWindow)); + asrielGroup->setLayout(asrielLayout); + + mainLayout->addWidget(floweyGroup); + mainLayout->addWidget(torielGroup); + mainLayout->addWidget(sansGroup); + mainLayout->addWidget(papyrusGroup); + mainLayout->addWidget(undyneGroup); + mainLayout->addWidget(alphysGroup); + mainLayout->addWidget(mettatonGroup); + mainLayout->addWidget(asgoreGroup); + mainLayout->addWidget(asrielGroup); + window->setLayout(mainLayout); + setWidget(window); +} + +MonstersPage::MonstersPage(MainWindow *mainWindow, QWidget *parent) : QScrollArea(parent) +{ + QWidget *window = new QWidget(); + QHBoxLayout *mainLayout = new QHBoxLayout(); + QFormLayout *leftLayout = new QFormLayout(); + leftLayout->addRow(tr("Interaction with the first dummy"), new CustomComboBox(45, mainWindow)); + leftLayout->addRow(tr("Monster spare name color"), new CustomComboBox(53, mainWindow)); + leftLayout->addRow(tr("Interaction with Doggo"), new CustomComboBox(83, mainWindow)); + leftLayout->addRow(tr("Interaction with Dogamy and Dogaressa"), new CustomComboBox(84, mainWindow)); + leftLayout->addRow(tr("Interaction with Greater Dog"), new CustomComboBox(85, mainWindow)); + leftLayout->addRow(tr("Interaction with Lesser Dog"), new CustomComboBox(86, mainWindow)); + leftLayout->addRow(tr("Interaction with Snowman"), new CustomComboBox(87, mainWindow)); + leftLayout->addRow(tr("Interaction with Snowdrake"), new CustomComboBox(88, mainWindow)); + leftLayout->addRow(tr("Placed googly eyes on Gyftrot"), new CustomCheckBox(105, mainWindow)); + leftLayout->addRow(tr("Interaction with Shyren"), new CustomComboBox(112, mainWindow)); + leftLayout->addRow(tr("Interaction with Monster Kid"), new CustomComboBox(122, mainWindow)); + leftLayout->addRow(tr("Monster Kid tripped on a bridge"), new CustomComboBox(129, mainWindow)); + leftLayout->addRow(tr("Spared Frogit"), new CustomCheckBox(161, mainWindow)); + leftLayout->addRow(tr("Spared Whimsun"), new CustomCheckBox(162, mainWindow)); + leftLayout->addRow(tr("Spared Moldsmal"), new CustomCheckBox(163, mainWindow)); + leftLayout->addRow(tr("Spared Loox"), new CustomCheckBox(164, mainWindow)); + leftLayout->addRow(tr("Spared Vegitoid"), new CustomCheckBox(165, mainWindow)); + leftLayout->addRow(tr("Spared Migosp"), new CustomCheckBox(166, mainWindow)); + leftLayout->addRow(tr("Spared Snowdrake"), new CustomCheckBox(167, mainWindow)); + leftLayout->addRow(tr("Spared Ice Cap"), new CustomCheckBox(168, mainWindow)); + leftLayout->addRow(tr("Spared Gyftrot"), new CustomCheckBox(169, mainWindow)); + leftLayout->addRow(tr("Spared Doggo"), new CustomCheckBox(170, mainWindow)); + leftLayout->addRow(tr("Spared Dogamy and Dogaressa"), new CustomCheckBox(171, mainWindow)); + leftLayout->addRow(tr("Spared Lesser Dog"), new CustomCheckBox(172, mainWindow)); + leftLayout->addRow(tr("Spared Greater Dog"), new CustomCheckBox(173, mainWindow)); + leftLayout->addRow(tr("Spared Aaron"), new CustomCheckBox(174, mainWindow)); + leftLayout->addRow(tr("Spared Moldbygg"), new CustomCheckBox(175, mainWindow)); + leftLayout->addRow(tr("Spared Woshua"), new CustomCheckBox(176, mainWindow)); + leftLayout->addRow(tr("Spared Temmie"), new CustomCheckBox(177, mainWindow)); + leftLayout->addRow(tr("Spared Mad Dummy"), new CustomCheckBox(178, mainWindow)); + leftLayout->addRow(tr("Spared Vulkin"), new CustomCheckBox(179, mainWindow)); + leftLayout->addRow(tr("Spared Tsunderplane"), new CustomCheckBox(180, mainWindow)); + leftLayout->addRow(tr("Spared Pyrope"), new CustomCheckBox(181, mainWindow)); + leftLayout->addRow(tr("Spared Final Froggit"), new CustomCheckBox(182, mainWindow)); + leftLayout->addRow(tr("Spared Whimsalot"), new CustomCheckBox(183, mainWindow)); + leftLayout->addRow(tr("Spared Astigmatism"), new CustomCheckBox(184, mainWindow)); + leftLayout->addRow(tr("Spared Madjick"), new CustomCheckBox(185, mainWindow)); + leftLayout->addRow(tr("Spared Knight Knight"), new CustomCheckBox(186, mainWindow)); + leftLayout->addRow(tr("Spared Endogeny"), new CustomCheckBox(187, mainWindow)); + leftLayout->addRow(tr("Killed Glad Dummy"), new CustomCheckBox(283, mainWindow)); + leftLayout->addRow(tr("Interaction with Snowman (Genocide)"), new CustomComboBox(284, mainWindow)); + leftLayout->addRow(tr("Interaction with So Sorry"), new CustomComboBox(312, mainWindow)); + leftLayout->addRow(tr("Fought Glyde"), new CustomCheckBox(313, mainWindow)); + leftLayout->addRow(tr("Killed the Royal Guards"), new CustomCheckBox(433, mainWindow)); + + QVBoxLayout *rightLayout = new QVBoxLayout(); + QGroupBox *napstablookGroup = new QGroupBox(QString("Napstablook")); + QFormLayout *napstablookLayout = new QFormLayout(); + napstablookLayout->addRow(tr("Napstablook encounter"), new CustomComboBox(67, mainWindow)); + napstablookLayout->addRow(tr("Date with Napstablook"), new CustomComboBox(124, mainWindow)); + napstablookLayout->addRow(tr("Spooked Aaron and Woshua with spooky tunes"), new CustomCheckBox(126, mainWindow)); + napstablookLayout->addRow(tr("Napstablook chat counter (Pacifist)"), new CustomSpinBox(230, mainWindow)); + napstablookLayout->addRow(tr("NAPSTABLOOK22 has sent you a friend request"), new CustomCheckBox(440, mainWindow)); + napstablookLayout->addRow(tr("Feel like garbage with Napstablook"), new CustomCheckBox(489, mainWindow)); + napstablookGroup->setLayout(napstablookLayout); + + QGroupBox *temmieGroup = new QGroupBox(QString("Temmie")); + QFormLayout *temmieLayout = new QFormLayout(); + temmieLayout->addRow(tr("Temmie sale countdown"), new CustomSpinBox(296, mainWindow)); + temmieLayout->addRow(tr("Temmie special sale"), new CustomCheckBox(297, mainWindow)); + temmieLayout->addRow(tr("Talked to allergic Temmie"), new CustomCheckBox(300, mainWindow)); + temmieLayout->addRow(tr("Send tem to \"cool leg\""), new CustomCheckBox(307, mainWindow)); + temmieGroup->setLayout(temmieLayout); + + QGroupBox *muffetGroup = new QGroupBox(QString("Muffet")); + QFormLayout *muffetLayout = new QFormLayout(); + muffetLayout->addRow(tr("Muffet bribing price"), new CustomSpinBox(413, mainWindow)); + muffetLayout->addRow(tr("Gold spent on bribing Muffet"), new CustomSpinBox(414, mainWindow)); + muffetLayout->addRow(tr("Muffet conversation"), new CustomComboBox(427, mainWindow)); + muffetLayout->addRow(tr("Killed Muffet"), new CustomCheckBox(428, mainWindow)); + muffetGroup->setLayout(muffetLayout); + + QGroupBox *riverPersonGroup = new QGroupBox(QString("River Person")); + QFormLayout *riverPersonLayout = new QFormLayout(); + riverPersonLayout->addRow(tr("River Person's destination"), new CustomComboBox(490, mainWindow)); + riverPersonLayout->addRow(tr("Boat ride counter"), new CustomSpinBox(491, mainWindow)); + riverPersonLayout->addRow(tr("River Person's boat is a dog"), new CustomCheckBox(492, mainWindow)); + riverPersonGroup->setLayout(riverPersonLayout); + + rightLayout->addWidget(napstablookGroup); + rightLayout->addWidget(temmieGroup); + rightLayout->addWidget(muffetGroup); + rightLayout->addWidget(riverPersonGroup); + rightLayout->addStretch(1); + + mainLayout->addLayout(leftLayout); + mainLayout->addLayout(rightLayout); + window->setLayout(mainLayout); + setWidget(window); +} + +LocationsPage::LocationsPage(MainWindow *mainWindow, QWidget *parent) : QScrollArea(parent) +{ + QWidget *window = new QWidget(); + QVBoxLayout *mainLayout = new QVBoxLayout(); + + QGroupBox *ruinsGroup = new QGroupBox(QString("Ruins")); + QFormLayout *ruinsLayout = new QFormLayout(); + ruinsLayout->addRow(tr("Tutorial Froggit encountered"), new CustomCheckBox(61, mainWindow)); + ruinsLayout->addRow(tr("First rock pushed"), new CustomCheckBox(66, mainWindow)); + ruinsLayout->addRow(tr("Second rock pushed"), new CustomCheckBox(63, mainWindow)); + ruinsLayout->addRow(tr("Third rock pushed"), new CustomCheckBox(62, mainWindow)); + ruinsLayout->addRow(tr("Fourth rock asked to move"), new CustomCheckBox(64, mainWindow)); + ruinsLayout->addRow(tr("Monster Candy taken"), new CustomComboBox(65, mainWindow)); + ruinsLayout->addRow(tr("Pillar switch counter"), new CustomSpinBox(74, mainWindow)); + ruinsLayout->addRow(tr("Tried to exit Ruins counter"), new CustomSpinBox(75, mainWindow)); + ruinsLayout->addRow(tr("Learned about \"water sausage\""), new CustomCheckBox(81, mainWindow)); + ruinsLayout->addRow(tr("Wrong pillar switch counter"), new CustomSpinBox(82, mainWindow)); + ruinsLayout->addRow(tr("Found a Faded Ribbon"), new CustomCheckBox(131, mainWindow)); + ruinsLayout->addRow(tr("Found the Toy Knife"), new CustomCheckBox(133, mainWindow)); + ruinsLayout->addRow(tr("Toriel's pie"), new CustomComboBox(134, mainWindow)); + ruinsGroup->setLayout(ruinsLayout); + + QGroupBox *snowdinGroup = new QGroupBox(QString("Snowdin")); + QFormLayout *snowdinLayout = new QFormLayout(); + snowdinLayout->addRow(tr("Harder puzzle"), new CustomComboBox(89, mainWindow)); + snowdinLayout->addRow(tr("Papyrus asks about spaghetti trap"), new CustomComboBox(93, mainWindow)); + snowdinLayout->addRow(tr("XO puzzle reset counter"), new CustomSpinBox(94, mainWindow)); + snowdinLayout->addRow(tr("Switch buried under snow"), new CustomComboBox(95, mainWindow)); + snowdinLayout->addRow(tr("Found 30G in a snow poff"), new CustomCheckBox(96, mainWindow)); + snowdinLayout->addRow(tr("Forest encounter counter"), new CustomSpinBox(101, mainWindow)); + snowdinLayout->addRow(tr("Interaction with Snowed Inn"), new CustomComboBox(103, mainWindow)); + snowdinLayout->addRow(tr("Staying at Snowed Inn"), new CustomCheckBox(104, mainWindow)); + snowdinLayout->addRow(tr("Found the Annoying Dog inside tall sink cabinet"), new CustomCheckBox(113, mainWindow)); + snowdinLayout->addRow(tr("Found 20G inside a \"saggy old couch\""), new CustomCheckBox(114, mainWindow)); + snowdinLayout->addRow(tr("Interacted with sans's puzzle"), new CustomCheckBox(285, mainWindow)); + snowdinLayout->addRow(tr("Stole from the shop (Genocide)"), new CustomCheckBox(286, mainWindow)); + snowdinLayout->addRow(tr("Tried to pet the dog in the dev room"), new CustomCheckBox(292, mainWindow)); + snowdinLayout->addRow(tr("Entering Snowdin forest"), new CustomComboBox(306, mainWindow)); + snowdinLayout->addRow(tr("The wrong number/prank call happened"), new CustomCheckBox(308, mainWindow)); + snowdinLayout->addRow(tr("Checked Papyrus's kitchen after the date"), new CustomCheckBox(314, mainWindow)); + snowdinLayout->addRow(tr("Won the Ball Game"), new CustomCheckBox(418, mainWindow)); + snowdinGroup->setLayout(snowdinLayout); + + QGroupBox *waterfallGroup = new QGroupBox(QString("Waterfall")); + QFormLayout *waterfallLayout = new QFormLayout(); + waterfallLayout->addRow(tr("Armor you are wearing when Papyrus calls"), new CustomComboBox(106, mainWindow)); + waterfallLayout->addRow(tr("Lied about your armor"), new CustomCheckBox(107, mainWindow)); + waterfallLayout->addRow(tr("Armor you are wearing when Undyne attacks"), new CustomComboBox(108, mainWindow)); + waterfallLayout->addRow(tr("Talked to Nice Cream Guy at Waterfall"), new CustomCheckBox(110, mainWindow)); + waterfallLayout->addRow(tr("Punch Card counter"), new CustomSpinBox(111, mainWindow)); + waterfallLayout->addRow(tr("Placed an umbrella on a statue"), new CustomCheckBox(117, mainWindow)); + waterfallLayout->addRow(tr("Met Monster Kid in the rain"), new CustomComboBox(121, mainWindow)); + waterfallLayout->addRow(tr("Interacted with Trash Zone SAVE Point"), new CustomCheckBox(122, mainWindow)); + waterfallLayout->addRow(tr("Spooky tune playing"), new CustomComboBox(125, mainWindow)); + waterfallLayout->addRow(tr("Talked with Gerson"), new CustomComboBox(127, mainWindow)); + waterfallLayout->addRow(tr("Got the Abandoned Quiche"), new CustomCheckBox(135, mainWindow)); + waterfallLayout->addRow(tr("Got the Old Tutu"), new CustomCheckBox(136, mainWindow)); + waterfallLayout->addRow(tr("Got the Ballet Shoes"), new CustomCheckBox(137, mainWindow)); + waterfallLayout->addRow(tr("Legendary artifact"), new CustomComboBox(138, mainWindow)); + waterfallLayout->addRow(tr("Cooler containing Astronaut Food"), new CustomComboBox(139, mainWindow)); + waterfallLayout->addRow(tr("Solved glowshroom puzzle"), new CustomCheckBox(301, mainWindow)); + waterfallLayout->addRow(tr("Talked to Clamgirl"), new CustomCheckBox(310, mainWindow)); + waterfallLayout->addRow(tr("Interaction with Elder Puzzler"), new CustomComboBox(311, mainWindow)); + waterfallLayout->addRow(tr("Interaction with Mad Dummy"), new CustomComboBox(386, mainWindow)); + waterfallLayout->addRow(tr("Solved the Piano Puzzle"), new CustomCheckBox(387, mainWindow)); + waterfallLayout->addRow(tr("Waterfall (first area) encounter counter"), new CustomSpinBox(388, mainWindow)); + waterfallLayout->addRow(tr("Waterfall (second area) encounter counter"), new CustomSpinBox(389, mainWindow)); + waterfallLayout->addRow(tr("Solved the first Bridge Seed Puzzle"), new CustomCheckBox(417, mainWindow)); + waterfallLayout->addRow(tr("Unlocked Mettaton's house"), new CustomCheckBox(464, mainWindow)); + waterfallLayout->addRow(tr("Drinks taken from the water cooler"), new CustomSpinBox(471, mainWindow)); + waterfallLayout->addRow(tr("Drinks poured on the ground in front of Undyne"), new CustomSpinBox(472, mainWindow)); + waterfallLayout->addRow(tr("Interaction with Onionsan"), new CustomComboBox(527, mainWindow)); + waterfallGroup->setLayout(waterfallLayout); + + QGroupBox *hotlandGroup = new QGroupBox(QString("Hotland")); + QFormLayout *hotlandLayout = new QFormLayout(); + hotlandLayout->addRow(tr("Got the Instant Noodles"), new CustomCheckBox(140, mainWindow)); + hotlandLayout->addRow(tr("Got the Burnt Pan"), new CustomCheckBox(141, mainWindow)); + hotlandLayout->addRow(tr("Got the Stained Apron"), new CustomCheckBox(142, mainWindow)); + hotlandLayout->addRow(tr("Nice Cream is sold out"), new CustomCheckBox(281, mainWindow)); + hotlandLayout->addRow(tr("Stole from Bratty & Catty (Genocide)"), new CustomCheckBox(287, mainWindow)); + hotlandLayout->addRow(tr("Delivered Sea Tea at the MTT Resort"), new CustomCheckBox(293, mainWindow)); + hotlandLayout->addRow(tr("Delivered Cinnamon Bun at the MTT Resort"), new CustomCheckBox(294, mainWindow)); + hotlandLayout->addRow(tr("Delivered Hot Dog at the MTT Resort"), new CustomCheckBox(295, mainWindow)); + hotlandLayout->addRow(tr("Stay at the MTT Resort"), new CustomComboBox(298, mainWindow)); + hotlandLayout->addRow(tr("Water poured on ground"), new CustomSpinBox(384, mainWindow)); + hotlandLayout->addRow(tr("Papyrus calls at the entrance to Hotland"), new CustomComboBox(385, mainWindow)); + hotlandLayout->addRow(tr("Have a cup of water"), new CustomCheckBox(397, mainWindow)); + hotlandLayout->addRow(tr("Disable Alphys's phone calls (Genocide)"), new CustomCheckBox(398, mainWindow)); + hotlandLayout->addRow(tr("Disable Alphys's messages (Genocide)"), new CustomCheckBox(399, mainWindow)); + hotlandLayout->addRow(tr("Current message received from Alphys"), new CustomSpinBox(400, mainWindow)); + hotlandLayout->addRow(tr("Deactivated the first group of lasers"), new CustomCheckBox(402, mainWindow)); + hotlandLayout->addRow(tr("Activated lasers at MTT News"), new CustomCheckBox(403, mainWindow)); + hotlandLayout->addRow(tr("Deactivated laser near Shooting Puzzle"), new CustomCheckBox(404, mainWindow)); + hotlandLayout->addRow(tr("Solved the west Shooting Puzzle"), new CustomCheckBox(405, mainWindow)); + hotlandLayout->addRow(tr("Solved the east Shooting Puzzle"), new CustomCheckBox(406, mainWindow)); + hotlandLayout->addRow(tr("Failed jetpack sequence"), new CustomCheckBox(408, mainWindow)); + hotlandLayout->addRow(tr("Hot Dog buy counter"), new CustomSpinBox(410, mainWindow)); + hotlandLayout->addRow(tr("Total Hot Dogs placed on head"), new CustomSpinBox(411, mainWindow)); + hotlandLayout->addRow(tr("Reached the limit on Head-Dogs"), new CustomCheckBox(412, mainWindow)); + hotlandLayout->addRow(tr("Bombs defused during MTT News"), new CustomSpinBox(426, mainWindow)); + hotlandLayout->addRow(tr("Current elevator floor"), new CustomComboBox(429, mainWindow)); + hotlandLayout->addRow(tr("Solved the south Shooting Puzzle"), new CustomCheckBox(430, mainWindow)); + hotlandLayout->addRow(tr("Solved the north Shooting Puzzle"), new CustomCheckBox(431, mainWindow)); + hotlandLayout->addRow(tr("Undyne mentioned mind control"), new CustomCheckBox(432, mainWindow)); + hotlandLayout->addRow(tr("Bought something from Muffet"), new CustomCheckBox(434, mainWindow)); + hotlandLayout->addRow(tr("Pressed all three switches on the conveyor"), new CustomCheckBox(435, mainWindow)); + hotlandLayout->addRow(tr("Talked with Bratty and Catty"), new CustomComboBox(436, mainWindow)); + hotlandLayout->addRow(tr("Talked with Bratty and Catty about Mettaton"), new CustomComboBox(437, mainWindow)); + hotlandLayout->addRow(tr("Talked with Bratty and Catty about Alphys"), new CustomComboBox(438, mainWindow)); + hotlandLayout->addRow(tr("Hotland encounter counter"), new CustomSpinBox(439, mainWindow)); + hotlandLayout->addRow(tr("Flamey challenge"), new CustomComboBox(465, mainWindow)); + hotlandLayout->addRow(tr("Interaction with Burger Pants"), new CustomComboBox(466, mainWindow)); + hotlandLayout->addRow(tr("Talked with Burger Pants about Mettaton"), new CustomComboBox(467, mainWindow)); + hotlandLayout->addRow(tr("Chat with Burger Pants, Bratty and Catty"), new CustomComboBox(468, mainWindow)); + hotlandLayout->addRow(tr("Bought the Empty Gun"), new CustomCheckBox(473, mainWindow)); + hotlandLayout->addRow(tr("Bought the Cowboy Hat"), new CustomCheckBox(474, mainWindow)); + hotlandLayout->addRow(tr("Bought the Mystery Key"), new CustomCheckBox(475, mainWindow)); + hotlandLayout->addRow(tr("Bought the Face Steak"), new CustomCheckBox(476, mainWindow)); + hotlandGroup->setLayout(hotlandLayout); + + QGroupBox *coreGroup = new QGroupBox(QString("Core")); + QFormLayout *coreLayout = new QFormLayout(); + coreLayout->addRow(tr("Got the Glamburger from a trashcan"), new CustomCheckBox(143, mainWindow)); + coreLayout->addRow(tr("Got 100G from a trashcan"), new CustomCheckBox(144, mainWindow)); + coreLayout->addRow(tr("Tried to use the elevator in the Core lobby"), new CustomCheckBox(445, mainWindow)); + coreLayout->addRow(tr("Went right in the Core lobby"), new CustomCheckBox(446, mainWindow)); + coreLayout->addRow(tr("Went a bit to the right in the first crossroads"), new CustomCheckBox(447, mainWindow)); + coreLayout->addRow(tr("Went up in the first crossroads"), new CustomCheckBox(448, mainWindow)); + coreLayout->addRow(tr("Solved the Shooting Puzzle at the Sage's Path"), new CustomCheckBox(449, mainWindow)); + coreLayout->addRow(tr("Pressed the button at the Warrior's Path"), new CustomCheckBox(450, mainWindow)); + coreLayout->addRow(tr("Waited for 60 seconds on the final forcefield"), new CustomCheckBox(451, mainWindow)); + coreLayout->addRow(tr("Player ambushed on the Warrior's Path"), new CustomComboBox(452, mainWindow)); + coreLayout->addRow(tr("Core (first area) encounter counter"), new CustomSpinBox(454, mainWindow)); + coreLayout->addRow(tr("Core (second area) encounter counter"), new CustomSpinBox(457, mainWindow)); + coreGroup->setLayout(coreLayout); + + QGroupBox *castleGroup = new QGroupBox(QString("Castle")); + QFormLayout *castleLayout = new QFormLayout(); + castleLayout->addRow(tr("Got the Worn Dagger"), new CustomCheckBox(145, mainWindow)); + castleLayout->addRow(tr("Got the Heart Locket"), new CustomCheckBox(146, mainWindow)); + castleLayout->addRow(tr("Target floor of the castle elevator"), new CustomComboBox(462, mainWindow)); + castleLayout->addRow(tr("Used the elevator for the first time"), new CustomCheckBox(463, mainWindow)); + castleLayout->addRow(tr("The Tale of the Fallen Human"), new CustomComboBox(481, mainWindow)); + castleLayout->addRow(tr("Got the key in the kitchen"), new CustomCheckBox(483, mainWindow)); + castleLayout->addRow(tr("Got the key in the hallway"), new CustomCheckBox(484, mainWindow)); + castleLayout->addRow(tr("Padlocks in the New Home"), new CustomComboBox(485, mainWindow)); + castleLayout->addRow(tr("Story heard counter (the kitchen)"), new CustomSpinBox(486, mainWindow)); + castleLayout->addRow(tr("Story heard counter (the hallway)"), new CustomSpinBox(487, mainWindow)); + castleLayout->addRow(tr("Have any unfinished business"), new CustomCheckBox(488, mainWindow)); + castleLayout->addRow(tr("True Pacifist conversation"), new CustomComboBox(541, mainWindow)); + castleGroup->setLayout(castleLayout); + + QGroupBox *trueLabGroup = new QGroupBox(QString("True Lab")); + QFormLayout *trueLabLayout = new QFormLayout(); + trueLabLayout->addRow(tr("Entered True Lab lobby"), new CustomCheckBox(510, mainWindow)); + trueLabLayout->addRow(tr("Interaction with Red switch"), new CustomComboBox(512, mainWindow)); + trueLabLayout->addRow(tr("Interaction with Blue switch"), new CustomComboBox(513, mainWindow)); + trueLabLayout->addRow(tr("Interaction with Green switch"), new CustomComboBox(514, mainWindow)); + trueLabLayout->addRow(tr("Interaction with Yellow switch"), new CustomComboBox(515, mainWindow)); + trueLabLayout->addRow(tr("Finished talking to Alphys"), new CustomCheckBox(516, mainWindow)); + trueLabLayout->addRow(tr("Sink interaction counter"), new CustomSpinBox(517, mainWindow)); + trueLabLayout->addRow(tr("Red key location"), new CustomComboBox(518, mainWindow)); + trueLabLayout->addRow(tr("Spared Reaper Bird"), new CustomCheckBox(519, mainWindow)); + trueLabLayout->addRow(tr("Spared Lemon Bread"), new CustomCheckBox(520, mainWindow)); + trueLabLayout->addRow(tr("Turned on the lab's ventilation"), new CustomCheckBox(521, mainWindow)); + trueLabLayout->addRow(tr("Restored power to the elevator"), new CustomCheckBox(522, mainWindow)); + trueLabLayout->addRow(tr("Potato Chisps buy counter"), new CustomSpinBox(526, mainWindow)); + trueLabGroup->setLayout(trueLabLayout); + + mainLayout->addWidget(ruinsGroup); + mainLayout->addWidget(snowdinGroup); + mainLayout->addWidget(waterfallGroup); + mainLayout->addWidget(hotlandGroup); + mainLayout->addWidget(castleGroup); + mainLayout->addWidget(trueLabGroup); + window->setLayout(mainLayout); + setWidget(window); +} + +DebugPage::DebugPage(MainWindow *mainWindow, QWidget *parent) : QScrollArea(parent) +{ + QWidget *window = new QWidget(); + QFormLayout *mainLayout = new QFormLayout(); + + mainLayout->addRow(tr("Bypass counted kills"), new CustomCheckBox(35, mainWindow)); + mainLayout->addRow(tr("Murder level override"), new CustomSpinBox(57, mainWindow)); + mainLayout->addRow(tr("Debug text skip"), new CustomCheckBox(59, mainWindow)); + window->setLayout(mainLayout); + setWidget(window); +} + +DogPage::DogPage(MainWindow *mainWindow, QWidget *parent) : QScrollArea(parent) +{ + QWidget *window = new QWidget(); + QFormLayout *mainLayout = new QFormLayout(); + + mainLayout->addRow(tr("Gold donated"), new CustomSpinBox(323, mainWindow)); + mainLayout->addRow(tr("Donation threshold"), new CustomSpinBox(324, mainWindow)); + mainLayout->addRow(tr("Reached donation goal"), new CustomSpinBox(325, mainWindow)); + mainLayout->addRow(tr("Dogshrine upgrades"), new CustomSpinBox(326, mainWindow)); + mainLayout->addRow(tr("Tried to use the donation box"), new CustomCheckBox(327, mainWindow)); + window->setLayout(mainLayout); + setWidget(window); +} + +INIPage::INIPage(MainWindow *mainWindow, QWidget *parent) : QScrollArea(parent) +{ + QWidget *window = new QWidget(); + QGridLayout *mainLayout = new QGridLayout(); + + mainLayout->addWidget(new QLabel("General"), 0, 0); + mainLayout->addWidget(new HorizontalLine(), 0, 1, 1, 4); + mainLayout->addWidget(new VerticalLine(), 1, 0, 16, 1); + mainLayout->addWidget(new VerticalLine(), 1, 4, 16, 1); + mainLayout->addWidget(new QLabel("BC"), 1, 1); + mainLayout->addWidget(new IniSpinBox("BC", mainWindow), 1, 2); + mainLayout->addWidget(new QLabel("For those \"Get an item\" trophies"), 1, 3); + mainLayout->addWidget(new QLabel("BH"), 2, 1); + mainLayout->addWidget(new IniCheckBox("BH", mainWindow), 2, 2); + mainLayout->addWidget(new QLabel("Border Hard Mode. Console exclusive stuff"), 2, 3); + mainLayout->addWidget(new QLabel("BP"), 3, 1); + mainLayout->addWidget(new IniCheckBox("BP", mainWindow), 3, 2); + mainLayout->addWidget(new QLabel("Border Pacifist. Console exclusive stuff"), 3, 3); + mainLayout->addWidget(new QLabel("BW"), 4, 1); + mainLayout->addWidget(new IniCheckBox("BW", mainWindow), 4, 2); + mainLayout->addWidget(new QLabel("Border Won. Console exclusive stuff"), 4, 3); + mainLayout->addWidget(new QLabel("CH"), 5, 1); + mainLayout->addWidget(new IniCheckBox("CH", mainWindow), 5, 2); + mainLayout->addWidget(new QLabel("Complete Hard Mode"), 5, 3); + mainLayout->addWidget(new QLabel("CP"), 6, 1); + mainLayout->addWidget(new IniCheckBox("CP", mainWindow), 6, 2); + mainLayout->addWidget(new QLabel("Complete Pacifist"), 6, 3); + mainLayout->addWidget(new QLabel("Gameover"), 7, 1); + mainLayout->addWidget(new IniSpinBox("Gameover", mainWindow), 7, 2); + mainLayout->addWidget(new QLabel("Game Over counter"), 7, 3); + mainLayout->addWidget(new QLabel("Kills"), 8, 1); + mainLayout->addWidget(new IniSpinBox("Kills", mainWindow), 8, 2); + mainLayout->addWidget(new QLabel("Kills counter"), 8, 3); + mainLayout->addWidget(new QLabel("Love"), 9, 1); + mainLayout->addWidget(new IniSpinBox("Love", mainWindow), 9, 2); + mainLayout->addWidget(new QLabel("LV"), 9, 3); + mainLayout->addWidget(new QLabel("Name"), 10, 1); + mainLayout->addWidget(new IniLineEdit("Name", mainWindow), 10, 2); + mainLayout->addWidget(new QLabel("Your name"), 10, 3); + mainLayout->addWidget(new QLabel("Room"), 11, 1); + mainLayout->addWidget(new IniSpinBox("Room", mainWindow), 11, 2); + mainLayout->addWidget(new QLabel("Current room"), 11, 3); + mainLayout->addWidget(new QLabel("Tale"), 12, 1); + mainLayout->addWidget(new IniCheckBox("Tale", mainWindow), 12, 2); + mainLayout->addWidget(new QLabel("Heard the Tale of The Fallen Human"), 12, 3); + mainLayout->addWidget(new QLabel("Time"), 13, 1); + mainLayout->addWidget(new IniSpinBox("Time", mainWindow), 13, 2); + mainLayout->addWidget(new QLabel("Time"), 13, 3); + mainLayout->addWidget(new QLabel("Truth"), 14, 1); + mainLayout->addWidget(new IniCheckBox("Truth", mainWindow), 14, 2); + mainLayout->addWidget(new QLabel("(Never set) Activates \"Activity Level A\" and \"Activity Level B\""), 14, 3); + mainLayout->addWidget(new QLabel("Won"), 15, 1); + mainLayout->addWidget(new IniSpinBox("Won", mainWindow), 15, 2); + mainLayout->addWidget(new QLabel("Reached an ending"), 15, 3); + mainLayout->addWidget(new QLabel("fun"), 16, 1); + mainLayout->addWidget(new IniSpinBox("fun", mainWindow), 16, 2); + mainLayout->addWidget(new QLabel("Randomly generated number at the start of the game"), 16, 3); + mainLayout->addWidget(new HorizontalLine(), 17, 0, 1, 5); + + mainLayout->addWidget(new QLabel("Flowey"), 18, 0); + mainLayout->addWidget(new HorizontalLine(), 18, 1, 1, 4); + mainLayout->addWidget(new VerticalLine(), 19, 0, 15, 1); + mainLayout->addWidget(new VerticalLine(), 19, 4, 15, 1); + mainLayout->addWidget(new QLabel("AF"), 19, 1); + mainLayout->addWidget(new IniCheckBox("Flowey/AF", mainWindow), 19, 2); + mainLayout->addWidget(new QLabel("Ending where True Lab was unfinished"), 19, 3); + mainLayout->addWidget(new QLabel("AK"), 20, 1); + mainLayout->addWidget(new IniCheckBox("Flowey/AK", mainWindow), 20, 2); + mainLayout->addWidget(new QLabel("Ending where only Asgore was killed"), 20, 3); + mainLayout->addWidget(new QLabel("Alter"), 21, 1); + mainLayout->addWidget(new IniCheckBox("Flowey/Alter", mainWindow), 21, 2); + mainLayout->addWidget(new QLabel("Intro Flowey if truename is 1, IK is over 0 or NK is over 0"), 21, 3); + mainLayout->addWidget(new QLabel("CHANGE"), 22, 1); + mainLayout->addWidget(new IniSpinBox("Flowey/CHANGE", mainWindow), 22, 2); + mainLayout->addWidget(new QLabel("1 after IK is 1, but made no kills. 2 after CHANGE is less than 2 (if NK is 1, CHANGE must be over 0), but made at least 1 kill"), 22, 3); + mainLayout->addWidget(new QLabel("CK"), 23, 1); + mainLayout->addWidget(new IniCheckBox("Flowey/CK", mainWindow), 23, 2); + mainLayout->addWidget(new QLabel("(Never set) (Never used)"), 23, 3); + mainLayout->addWidget(new QLabel("EX"), 24, 1); + mainLayout->addWidget(new IniSpinBox("Flowey/EX", mainWindow), 24, 2); + mainLayout->addWidget(new QLabel("Endings where you killed at least once, but spared Asgore, didn't complete any dates and NK is 1 (or IK is 1)"), 24, 3); + mainLayout->addWidget(new QLabel("FloweyExplain1"), 25, 1); + mainLayout->addWidget(new IniCheckBox("Flowey/FloweyExplain1", mainWindow), 25, 2); + mainLayout->addWidget(new QLabel("First spare Toriel then kill her (or the reverse). Flowey will explain the power of saving"), 25, 3); + mainLayout->addWidget(new QLabel("IK"), 26, 1); + mainLayout->addWidget(new IniCheckBox("Flowey/IK", mainWindow), 26, 2); + mainLayout->addWidget(new QLabel("Ending where you made at least 1 kill (if NK is 0, IK must be 0)"), 26, 3); + mainLayout->addWidget(new QLabel("K"), 27, 1); + mainLayout->addWidget(new IniCheckBox("Flowey/K", mainWindow), 27, 2); + mainLayout->addWidget(new QLabel("Killed Flowey"), 27, 3); + mainLayout->addWidget(new QLabel("Met1"), 28, 1); + mainLayout->addWidget(new IniSpinBox("Flowey/Met1", mainWindow), 28, 2); + mainLayout->addWidget(new QLabel("Intro Flowey counter"), 28, 3); + mainLayout->addWidget(new QLabel("NK"), 29, 1); + mainLayout->addWidget(new IniCheckBox("Flowey/NK", mainWindow), 29, 2); + mainLayout->addWidget(new QLabel("Ending where you made no kills"), 29, 3); + mainLayout->addWidget(new QLabel("SK"), 30, 1); + mainLayout->addWidget(new IniCheckBox("Flowey/SK", mainWindow), 30, 2); + mainLayout->addWidget(new QLabel("Flowey didn't kill Asgore"), 30, 3); + mainLayout->addWidget(new QLabel("SPECIALK"), 31, 1); + mainLayout->addWidget(new IniCheckBox("Flowey/SPECIALK", mainWindow), 31, 2); + mainLayout->addWidget(new QLabel("Ending where \"truename\" is 1"), 31, 3); + mainLayout->addWidget(new QLabel("alter2"), 32, 1); + mainLayout->addWidget(new IniCheckBox("Flowey/alter2", mainWindow), 32, 2); + mainLayout->addWidget(new QLabel("Reached the end of the Ruins while killing everything (Ruins genocide)"), 32, 3); + mainLayout->addWidget(new QLabel("truename"), 33, 1); + mainLayout->addWidget(new IniCheckBox("Flowey/truename", mainWindow), 33, 2); + mainLayout->addWidget(new QLabel("Reached the end of the Ruins while killing everything (Ruins genocide)"), 33, 3); + mainLayout->addWidget(new HorizontalLine(), 34, 0, 1, 5); + + mainLayout->addWidget(new QLabel("Toriel"), 35, 0); + mainLayout->addWidget(new HorizontalLine(), 35, 1, 1, 4); + mainLayout->addWidget(new VerticalLine(), 36, 0, 3, 1); + mainLayout->addWidget(new VerticalLine(), 36, 4, 3, 1); + mainLayout->addWidget(new QLabel("Bscotch"), 36, 1); + mainLayout->addWidget(new IniSpinBox("Toriel/Bscotch", mainWindow), 36, 2); + mainLayout->addWidget(new QLabel("Chosen flavor of pie. 1 is Butterscotch. 2 is Cinnamon"), 36, 3); + mainLayout->addWidget(new QLabel("TK"), 37, 1); + mainLayout->addWidget(new IniSpinBox("Toriel/TK", mainWindow), 37, 2); + mainLayout->addWidget(new QLabel("Kill counter"), 37, 3); + mainLayout->addWidget(new QLabel("TS"), 38, 1); + mainLayout->addWidget(new IniSpinBox("Toriel/TS", mainWindow), 38, 2); + mainLayout->addWidget(new QLabel("Spare counter"), 38, 3); + mainLayout->addWidget(new HorizontalLine(), 39, 0, 1, 5); + + mainLayout->addWidget(new QLabel("Sans"), 40, 0); + mainLayout->addWidget(new HorizontalLine(), 40, 1, 1, 4); + mainLayout->addWidget(new VerticalLine(), 41, 0, 12, 1); + mainLayout->addWidget(new VerticalLine(), 41, 4, 12, 1); + mainLayout->addWidget(new QLabel("EndMet"), 41, 1); + mainLayout->addWidget(new IniCheckBox("Sans/EndMet", mainWindow), 41, 2); + mainLayout->addWidget(new QLabel("Met at the judgement hallway"), 41, 3); + mainLayout->addWidget(new QLabel("F"), 42, 1); + mainLayout->addWidget(new IniSpinBox("Sans/F", mainWindow), 42, 2); + mainLayout->addWidget(new QLabel("Fight counter"), 42, 3); + mainLayout->addWidget(new QLabel("Intro"), 43, 1); + mainLayout->addWidget(new IniSpinBox("Sans/Intro", mainWindow), 43, 2); + mainLayout->addWidget(new QLabel("Fight Intro counter"), 43, 3); + mainLayout->addWidget(new QLabel("M1"), 44, 1); + mainLayout->addWidget(new IniSpinBox("Sans/M1", mainWindow), 44, 2); + mainLayout->addWidget(new QLabel("Meeting for the first time counter"), 44, 3); + mainLayout->addWidget(new QLabel("MeetLv"), 45, 1); + mainLayout->addWidget(new IniSpinBox("Sans/MeetLv", mainWindow), 45, 2); + mainLayout->addWidget(new QLabel("Final meeting at LV other than 1 or 2"), 45, 3); + mainLayout->addWidget(new QLabel("MeetLv1"), 46, 1); + mainLayout->addWidget(new IniSpinBox("Sans/MeetLv1", mainWindow), 46, 2); + mainLayout->addWidget(new QLabel("Final meeting at LV 1"), 46, 3); + mainLayout->addWidget(new QLabel("MeetLv2"), 47, 1); + mainLayout->addWidget(new IniSpinBox("Sans/MeetLv2", mainWindow), 47, 2); + mainLayout->addWidget(new QLabel("Final meeting at LV 2"), 47, 3); + mainLayout->addWidget(new QLabel("MP"), 48, 1); + mainLayout->addWidget(new IniSpinBox("Sans/MP", mainWindow), 48, 2); + mainLayout->addWidget(new QLabel("(Never used) Offered to Spare"), 48, 3); + mainLayout->addWidget(new QLabel("Pass"), 49, 1); + mainLayout->addWidget(new IniSpinBox("Sans/Pass", mainWindow), 49, 2); + mainLayout->addWidget(new QLabel("Secret codeword counter. You'll hear the first codeword at the sans' judgement if MeetLv1 is over 0"), 49, 3); + mainLayout->addWidget(new QLabel("SK"), 50, 1); + mainLayout->addWidget(new IniSpinBox("Sans/SK", mainWindow), 50, 2); + mainLayout->addWidget(new QLabel("Kill counter"), 50, 3); + mainLayout->addWidget(new QLabel("SS"), 51, 1); + mainLayout->addWidget(new IniSpinBox("Sans/SS", mainWindow), 51, 2); + mainLayout->addWidget(new QLabel("Spare counter"), 51, 3); + mainLayout->addWidget(new QLabel("SS2"), 52, 1); + mainLayout->addWidget(new IniSpinBox("Sans/SS2", mainWindow), 52, 2); + mainLayout->addWidget(new QLabel("Spare again counter"), 52, 3); + mainLayout->addWidget(new HorizontalLine(), 53, 0, 1, 5); + + mainLayout->addWidget(new QLabel("Papyrus"), 54, 0); + mainLayout->addWidget(new HorizontalLine(), 54, 1, 1, 4); + mainLayout->addWidget(new VerticalLine(), 56, 0, 4, 1); + mainLayout->addWidget(new VerticalLine(), 56, 4, 4, 1); + mainLayout->addWidget(new QLabel("M1"), 56, 1); + mainLayout->addWidget(new IniSpinBox("Papyrus/M1", mainWindow), 56, 2); + mainLayout->addWidget(new QLabel("Meeting for the first time counter"), 56, 3); + mainLayout->addWidget(new QLabel("PD"), 57, 1); + mainLayout->addWidget(new IniSpinBox("Papyrus/PD", mainWindow), 57, 2); + mainLayout->addWidget(new QLabel("Date complete counter. Changes title menu"), 57, 3); + mainLayout->addWidget(new QLabel("PK"), 58, 1); + mainLayout->addWidget(new IniSpinBox("Papyrus/PK", mainWindow), 58, 2); + mainLayout->addWidget(new QLabel("Kill counter"), 58, 3); + mainLayout->addWidget(new QLabel("PS"), 59, 1); + mainLayout->addWidget(new IniSpinBox("Papyrus/PS", mainWindow), 59, 2); + mainLayout->addWidget(new QLabel("Spare counter"), 59, 3); + mainLayout->addWidget(new HorizontalLine(), 60, 0, 1, 5); + + mainLayout->addWidget(new QLabel("Undyne"), 61, 0); + mainLayout->addWidget(new HorizontalLine(), 61, 1, 1, 4); + mainLayout->addWidget(new VerticalLine(), 62, 0, 1, 1); + mainLayout->addWidget(new VerticalLine(), 62, 4, 1, 1); + mainLayout->addWidget(new QLabel("UD"), 62, 1); + mainLayout->addWidget(new IniSpinBox("Undyne/UD", mainWindow), 62, 2); + mainLayout->addWidget(new QLabel("Date complete counter. Changes title menu"), 62, 3); + mainLayout->addWidget(new HorizontalLine(), 63, 0, 1, 5); + + mainLayout->addWidget(new QLabel("Alphys"), 64, 0); + mainLayout->addWidget(new HorizontalLine(), 64, 1, 1, 4); + mainLayout->addWidget(new VerticalLine(), 65, 0, 1, 1); + mainLayout->addWidget(new VerticalLine(), 65, 4, 1, 1); + mainLayout->addWidget(new QLabel("AD"), 65, 1); + mainLayout->addWidget(new IniSpinBox("Alphys/AD", mainWindow), 65, 2); + mainLayout->addWidget(new QLabel("Date complete counter. Changes title menu"), 65, 3); + mainLayout->addWidget(new HorizontalLine(), 66, 0, 1, 5); + + mainLayout->addWidget(new QLabel("MTT"), 67, 0); + mainLayout->addWidget(new HorizontalLine(), 67, 1, 1, 4); + mainLayout->addWidget(new VerticalLine(), 68, 0, 1, 1); + mainLayout->addWidget(new VerticalLine(), 68, 4, 1, 1); + mainLayout->addWidget(new QLabel("EssayNo"), 68, 1); + mainLayout->addWidget(new IniSpinBox("MTT/EssayNo", mainWindow), 68, 2); + mainLayout->addWidget(new QLabel("Essay counter"), 68, 3); + mainLayout->addWidget(new HorizontalLine(), 69, 0, 1, 5); + + mainLayout->addWidget(new QLabel("Mett"), 70, 0); + mainLayout->addWidget(new HorizontalLine(), 70, 1, 1, 4); + mainLayout->addWidget(new VerticalLine(), 71, 0, 1, 1); + mainLayout->addWidget(new VerticalLine(), 71, 4, 1, 1); + mainLayout->addWidget(new QLabel("O"), 71, 1); + mainLayout->addWidget(new IniCheckBox("Mett/O", mainWindow), 71, 2); + mainLayout->addWidget(new QLabel("Experienced the Mettaton opera"), 71, 3); + mainLayout->addWidget(new HorizontalLine(), 72, 0, 1, 5); + + mainLayout->addWidget(new QLabel("Mettaton"), 73, 0); + mainLayout->addWidget(new HorizontalLine(), 73, 1, 1, 4); + mainLayout->addWidget(new VerticalLine(), 74, 0, 1, 1); + mainLayout->addWidget(new VerticalLine(), 74, 4, 1, 1); + mainLayout->addWidget(new QLabel("BossMet"), 74, 1); + mainLayout->addWidget(new IniCheckBox("Mettaton/BossMet", mainWindow), 74, 2); + mainLayout->addWidget(new QLabel("Encountered Mettaton"), 74, 3); + mainLayout->addWidget(new HorizontalLine(), 75, 0, 1, 5); + + mainLayout->addWidget(new QLabel("Asgore"), 76, 0); + mainLayout->addWidget(new HorizontalLine(), 76, 1, 1, 4); + mainLayout->addWidget(new VerticalLine(), 77, 0, 1, 1); + mainLayout->addWidget(new VerticalLine(), 77, 4, 1, 1); + mainLayout->addWidget(new QLabel("KillYou"), 77, 1); + mainLayout->addWidget(new IniSpinBox("Asgore/KillYou", mainWindow), 77, 2); + mainLayout->addWidget(new QLabel("Your death counter"), 77, 3); + mainLayout->addWidget(new HorizontalLine(), 78, 0, 1, 5); + + mainLayout->addWidget(new QLabel("FFFFF"), 79, 0); + mainLayout->addWidget(new HorizontalLine(), 79, 1, 1, 4); + mainLayout->addWidget(new VerticalLine(), 80, 0, 4, 1); + mainLayout->addWidget(new VerticalLine(), 80, 4, 4, 1); + mainLayout->addWidget(new QLabel("D"), 80, 1); + mainLayout->addWidget(new IniSpinBox("FFFFF/D", mainWindow), 80, 2); + mainLayout->addWidget(new QLabel("Your death counter"), 80, 3); + mainLayout->addWidget(new QLabel("E"), 81, 1); + mainLayout->addWidget(new IniSpinBox("FFFFF/E", mainWindow), 81, 2); + mainLayout->addWidget(new QLabel("0 after short credits. 1 after Omega Flowey fight. 2 after killing Flowey"), 81, 3); + mainLayout->addWidget(new QLabel("F"), 82, 1); + mainLayout->addWidget(new IniSpinBox("FFFFF/F", mainWindow), 82, 2); + mainLayout->addWidget(new QLabel("0 after short credits. 1 after Omega Flowey fight"), 82, 3); + mainLayout->addWidget(new QLabel("P"), 83, 1); + mainLayout->addWidget(new IniSpinBox("FFFFF/P", mainWindow), 83, 2); + mainLayout->addWidget(new QLabel("1 after starting Omega Flowey fight. 2 after knife part. 3 after glove part. 4 after shoe part. 5 after book part. 6 after pan part. 7 after gun part"), 83, 3); + mainLayout->addWidget(new HorizontalLine(), 84, 0, 1, 5); + + mainLayout->addWidget(new QLabel("EndF"), 85, 0); + mainLayout->addWidget(new HorizontalLine(), 85, 1, 1, 4); + mainLayout->addWidget(new VerticalLine(), 86, 0, 1, 1); + mainLayout->addWidget(new VerticalLine(), 86, 4, 1, 1); + mainLayout->addWidget(new QLabel("EndF"), 86, 1); + mainLayout->addWidget(new IniSpinBox("EndF/EndF", mainWindow), 86, 2); + mainLayout->addWidget(new QLabel("1 after pacifist ending. 2 after Flowey talks about resetting"), 86, 3); + mainLayout->addWidget(new HorizontalLine(), 87, 0, 1, 5); + + mainLayout->addWidget(new QLabel("F7"), 88, 0); + mainLayout->addWidget(new HorizontalLine(), 88, 1, 1, 4); + mainLayout->addWidget(new VerticalLine(), 89, 0, 1, 1); + mainLayout->addWidget(new VerticalLine(), 89, 4, 1, 1); + mainLayout->addWidget(new QLabel("F7"), 89, 1); + mainLayout->addWidget(new IniCheckBox("F7/F7", mainWindow), 89, 2); + mainLayout->addWidget(new QLabel("Asriel fight over. Changes title menu"), 89, 3); + mainLayout->addWidget(new HorizontalLine(), 90, 0, 1, 5); + + mainLayout->addWidget(new QLabel("reset"), 91, 0); + mainLayout->addWidget(new HorizontalLine(), 91, 1, 1, 4); + mainLayout->addWidget(new VerticalLine(), 92, 0, 2, 1); + mainLayout->addWidget(new VerticalLine(), 92, 4, 2, 1); + mainLayout->addWidget(new QLabel("reset"), 92, 1); + mainLayout->addWidget(new IniCheckBox("reset/reset", mainWindow), 92, 2); + mainLayout->addWidget(new QLabel("Set on naming screen. Activates \"Activity Level A\" and \"Activity Level B\""), 92, 3); + mainLayout->addWidget(new QLabel("s_key"), 93, 1); + mainLayout->addWidget(new IniCheckBox("reset/s_key", mainWindow), 93, 2); + mainLayout->addWidget(new QLabel("Set if you hit 0 names on credits. Opens the mysterious door in Snowdin forest"), 93, 3); + mainLayout->addWidget(new HorizontalLine(), 94, 0, 1, 5); + + window->setLayout(mainLayout); + setWidget(window); +} diff --git a/pages.h b/pages.h new file mode 100644 index 0000000..9757188 --- /dev/null +++ b/pages.h @@ -0,0 +1,57 @@ +#ifndef PAGES_H +#define PAGES_H + +#include "mainwindow.h" + +#include +#include + +class PlayerPage : public QScrollArea +{ + Q_OBJECT +public: + PlayerPage(MainWindow *mainWindow, QWidget *parent = nullptr); +}; + +class BossesPage : public QScrollArea +{ + Q_OBJECT +public: + BossesPage(MainWindow *mainWindow, QWidget *parent = nullptr); +}; + +class MonstersPage : public QScrollArea +{ + Q_OBJECT +public: + MonstersPage(MainWindow *mainWindow, QWidget *parent = nullptr); +}; + +class LocationsPage : public QScrollArea +{ + Q_OBJECT +public: + LocationsPage(MainWindow *mainWindow, QWidget *parent = nullptr); +}; + +class DebugPage : public QScrollArea +{ + Q_OBJECT +public: + DebugPage(MainWindow *mainWindow, QWidget *parent = nullptr); +}; + +class DogPage : public QScrollArea +{ + Q_OBJECT +public: + DogPage(MainWindow *mainWindow, QWidget *parent = nullptr); +}; + +class INIPage : public QScrollArea +{ + Q_OBJECT +public: + INIPage(MainWindow *mainWindow, QWidget *parent = nullptr); +}; +#endif // PAGES_H diff --git a/strings/dullfile b/strings/dullfile deleted file mode 100644 index 2011960..0000000 --- a/strings/dullfile +++ /dev/null @@ -1,549 +0,0 @@ -"Easy to change, huh?" -"You want some LOVE, don't you?" -comment -Unused "ENERGY" value -comment -comment -comment -comment -Maybe "Spell", which is unused -"You will be judged for every EXP you've earned." -comment -"When you kill someone, your EXP increases." -Inventory, Slot 1 -Phone, Slot 1 -Inventory, Slot 2 -Phone, Slot 2 -Inventory, Slot 3 -Phone, Slot 3 -Inventory, Slot 4 -Phone, Slot 4 -Inventory, Slot 5 -Phone, Slot 5 -Inventory, Slot 6 -Phone, Slot 6 -Inventory, Slot 7 -Phone, Slot 7 -Inventory, Slot 8 -Phone, Slot 8 -comment -comment -[This might actually be in a different location on this list.]
Determines the type of the final scene in the bedroom. -unused -unused -unused -When 1, upon encountering Undyne, she will treat you as if you killed no monsters, even if you killed one. -Chosen randomly when you start a new run, set to 0 after specific events. -comment -Post-Asriel fight status. -Receive Undyne's letter or kill Mettaton Neo.
Needs confirmation if it works when set manually. -unaccessed -comment -comment -comment -Let the battle take too long.
Occurs only in the ruins. -Flee (0),
Kill (1),
Talk (2),
Bored (3).
Changes what Mad Dummy says. -comment -Occurs when triggering "quick" battles (i.e. Undyne's spears, lasers). -unaccessed -unaccessed -unused -comment -Non-Genocide only. -Set when you talk to the frog in the ruins and say "It's bad".
When sparing monsters:
0 for yellow names,
1 for white,
2 for pink.
Also a small easter egg in the trash area if not equal to 0. -comment -comment -comment -If set to anything other than 0, overrides the calculated murder level. -If you spare specific opponents, certain events that occur with a high murder level won't happen.
Similar to a "redemption" flag.
If you spare any of those monsters, the game is less desolated. -Keeping C pressed during dialogue will quickly skip sentences. -comment -comment -comment -comment -comment -comment -"This monster doesn't seem to have a sense of humor..." -Wait for Toriel to call you when she asks to stay in a room. -unused -unused -unused -After 4, Toriel's reaction stays the same -comment -In combination with flirted_toriel, affects a few dialogues. -When greater than 25, changes the displayed text upon pressing a switch. -After 10, Toriel's reaction stays the same. -1st time at "Home" (0),
Disobeyed (1),
Fight (3),
Kill (4),
Spare (5) -??? (0),
Butterscotch (1),
Cinnamon (2) -"Don't you know how to greet a new pal?" -unused -unused -Read about water sausages in Toriel's room.
Makes you recognize the plant in Toriel's living room. -After a while, gives you a hint about which switch to press. -1 if you kill Doggo,
2 if you throw him a stick and spare him. -1 if you kill Dogamy and/or Dogaressa,
2 if you damage them first and then throw a stick. -1 if you kill Greater Dog,
2 if you throw him a stick and spare him,
3 if you ignore him repeatedly. -1 if you kill Lesser Dog,
2 if you pet him until his neck extends at max.
If 2, room_ruins6 will be filled with broken dog structures. -1 if you get a Snowman Piece from the snowman in room_tundra6A,
2 if you get another piece after disposing of the first one,
4 if you use the Snowman Piece in front of the him,
5 if you talk to the him when the flag is 4. -1 if you laugh at Snowdrake's joke;
2 if you kill him, all future instances of Snowdrake are replaced with Chilldrakes. -? after Sans' puzzle ? Junior Jumble or Crosswords ? -comment -Seems to change when business relocates -unused -??? (1),
Left it (2) -Affects the dialogue with Sans after the puzzle.
Slightly different result if equals to 0 and M1 under the Sans category in undertale.ini is greater than 1. -comment -comment -comment -Skip fight (-3),
Improved "prison" (-2),
Captured (-1),
Spare (0),
Kill (1) -"He likes to say: Nyeh heh heh!" -Very slightly changes the dialogue with Burgerpants. -comment -unused -After "Not enough GOLD" (0),
Stay a night (1),
Not enough GOLD (2) -comment -Set if you "betray" Gyftrot by putting a present after removing some gifts off him.
Unaccessed -Equals to the id of the armor you're wearing upon the first call.
The combination of these affects the dialogue you get in Papyrus' second phone call. -Told the truth (0),
Lied about your clothes (1) -Equals to the id of the armor Undyne saw you wear. -Used Punch Card while wearing Tough Glove during battle. -Made a sale in Snowdin (8).
Changes mood and use of Punch Cards. -comment -Kill (1),
Had a musical career (2).
Affects one of the Amalgamate battle, you'll know the song.
Affects the Amalgamate's dialogue in the room after the True Pacifist ending. -comment -comment -Would affect the dialogue in room_water_mushroom, but it can't be accessed normally. -comment -Music box starts playing -unused -Outside house (1),
Inside house (2),
Unlock Papyrus's Room (3),
Date complete (4) -Seen any talking flowers? (1),
Is Papyrus cool? (2). -1 if you meet Monster Kid without an umbrella;
2 if, with flag set to 1, you get an umbrella and talk to him;
3 if, with flag set to 2, you dispose of the umbrella and talk to him again. -comment -"It's a horse stable."
"Do you want to go inside?"
"You jostle the door."
"It's locked." -Chat in the house (1),
Feel like "cosmic" garbage (3),
Don't lie on the ground (9) -Spooktunes (1),
Spookwave (2),
Ghouliday Music (3) -"..."
"if you're so scared, why do you keep winking?"
"THESE ARE WINKS OF FEAR ; )" -"That Emblem" (1),
"Emblem's meaning" (2),
"The Prophecy" (3) -Would prevent the NPC in room_water_prebird from repeating himself.
Cut content. -Exited (0),
Let Undyne do it (1),
Did it yourself (2) -Makes the fight more or less difficult, depending on a few factors (saved Monster Kid, how many times you died, etc.). -"If you're cuter, monsters won't hit you as hard." -unused -"Made of plastic."
"A rarity nowadays." -??? (1),
Butterscotch Pie (2),
??? (3) -"A psychologically damaged spinach egg pie." -"Finally, a protective piece of armor." -"These used shoes make you feel incredibly dangerous." -"The dog absorbs the artifact." -"For feeding a pet astronaut." -"Comes with everything you need for a quick meal!" -"Damage is rather consistent."
"Consumable items heal 4 more HP." -"Heals 1 HP every other turn." -comment -comment -"Perfect for cutting plants and vines." -"It says Best Friends Forever." -unused -unused -unused -unused -unused -unused -unused -unused -unused -unused -unused -unused -unused -unused -"Life is difficult for this enemy." -"This monster is too sensitive to fight..." -"Stereotypical: Curvaceously attractive, but no brains..." -"Don't pick on him."
"Family name: Eyewalker" -"Serving Size: 1 Monster"
"Not monitored by the USDA" -"It seems evil, but it's just with the wrong crowd..." -"This teen comedian fights to keep a captive audience." -"This teen wonders why it isn't named 'Ice Hat.'" -"Some teens "decorated" it as a prank." -"Easily excited by movement."
"Hobbies include: squirrels." -"DOGAMY: Husband of Dogaressa. Knows only what he smells."
"DOGARESSA: This puppy finds her hubby lovely. SMELLS ONLY?" -"Wields a stone dogger made of pomer-granite." -"It's so excited that it thinks fighting is just play." -"This seahorse has a lot of HP (Horsepower)." -"One size greater than Moldaverage." -"This humble germophobe seeks to cleanse the whole world." -"Loves to pet cute humans."
"But you're allergic!" -"Because they're a ghost, physical attacks will fail." -"Mistakenly believes its lava can heal people." -"Seems mean, but does it secretly like you?" -"This mischievous monster is never warm enough." -"Its future looks brighter and brighter." -"It finally stopped worrying." -"This relentless bully ALWAYS gets its way." -"This magical mercenary only says magic words." -"This megaton mercenary wields the Good Morningstar." -"It's unclear how many dogs this counts as." -unused -unused -unused -unused -unused -unused -unused -unused -unused -unused -unused -unused -unused -unused -unused -unused -unused -unused -unused -unused -unused -unused -unused -unused -unused -unused -unused -unused -unused -unused -unused -unused -unused -unused -comment -comment -comment -Keep talking to Undyne.
Meet at courtyard. -comment -comment -comment -comment -comment -Ruins (202),
Snowdin (203),
Waterfall (204),
Hotland (205) -comment -comment -comment -comment -comment -unused -unused -unused -unused -unused -unused -unused -unused -unused -unused -unused -unused -unused -unused -unused -monsterpopulation1: 20 -monsterpopulation2: 16 -monsterpopulation3: 18 -monsterpopulation4: 40 -comment -unused -unused -unused -unused -unused -unused -unused -unused -unused -unused -unused -unused -unused -unused -unused -unused -unused -unused -unused -unused -unused -unused -unused -unused -Nicecream Guy's outlook of his business will depend on your interactions with him. -comment -comment -Take pieces of the snowman to kill him. -comment -comment -comment -unused -unused -unused -Sans comments on it (0),
Nothing (1) ? affects Neutral Ending ? -Interact with the fake dog in the dev room. -Hotel Room (???) -Hotel Room (???) -Hotel Room (???) -MUST HAVE IT! (1),
sell 1 more item (2),
sell 2 more items (3),
sell 3 more items (4),
sell 4 more items (5),
sell 5 more items (6),
sell 6 more items (7),
sell 7 more items (8) -comment -1 the first time you stay at the hotel,
2 if you stay at the hotel again. -unused -comment -Set when you slove the glowshroom puzzle in the mushrooms path near Temmie Village. -"it's a beautiful day outside."
"birds are singing, flowers are blooming..."
"on days like these, kids like you..."
"Should be burning in hell." -"if we're really friends..."
"you won't come back." -unused -unused -Walked past it (1),
Stick gets snapped (2) -comment -comment -Affects a dialogue with Papyrus on the phone. -comment -comment -Kill (1),
Spare (2) -Spare (1),
Kill (2) -After the date, go in Papyrus' kitchen.
Prevents Glyde from appearing and affects the dialogue with Papyrus on the phone. -When Undyne throws her 100th spear, be in room_water8. -Something to do with the spear tile generation, but is unaccessed. -comment -Unclear specifics, but has to do with the amount of SMS you'll receive. -comment -comment -unused -unused -unused -unused -unused -unused -unused -unused -unused -unused -comment -comment -comment -comment -comment -comment -comment -comment -comment -comment -comment -comment -comment -comment -comment -comment -comment -comment -comment -comment -comment -comment -comment -comment -unused -unused -unused -unused -unused -unused -unused -unused -unused -unused -unused -unused -unused -unused -unused -unused -unused -unused -unused -unused -unused -unused -unused -unused -unused -unused -Kill (1),
Spare, but don't give water (2) -Undyne's HP after the battle.
Unaccessed. -"The heroine that NEVER gives up." -Affects the dialogue with Clamguy, creates a puddle after a while. -comment -No interaction (0),
Interract -> Punch (1),
Interract -> No punch (2).
Mad Dummy will comments on this before fighting. -comment -comment -comment -unused -Seems to affect the rain's rendering.
??? (0),
??? (1) -Seems to affect the rain's rendering.
??? (0.08) -Seems to affect the rain's rendering.
??? (0.08),
??? (0.5) -Seems to affect the rain's rendering.
??? (-1),
??? (272) -Seems to affect the rain's rendering.
??? (-1),
??? (273) -unused -comment -Reach the lab in a genocide run. -comment -comment -Enter a quick battle (i.e. lasers, spears). -comment -comment -comment -comment -comment -Unclear, seems to be used as a position variable. -comment -comment -comment -Buy a hot dog with no space in your inventory. -Buy a hot dog with 30 hot dogs on your head. -Increases after each use. Get's halved if Struggle 3 times, but only once. -Would you buy Muffet? I'd buy Muffet. -unused -1 if yellow button available,
2 if yellow button pressed. -Unclear specifics. -Win the ball game in an extremely short time. -Something to do with the fall animation. -??? (1),
??? (2),
??? (3),
House is on fire (4) -Unclear, but it seems to determine the sprite for Undyne's expression. -Fries (1),
Burger (2) ? Ketchup ? -unused -Internal to Madjick's battle. Something to do with Stick -unused -comment -"If she invites you to her parlor, excuse yourself." -comment -comment -comment -comment -Call Papyrus when the Royal Guards are in the room. Slightly affects the dialogue with the guards when you spare them. -Affects the dialogue during Papyrus' and Undyne's phone call. -Buy a 9999 gold spider bakery sale item. -Disable the third laser despite of Alphys' phone call. -Bratty and Catty's conversations. -comment -comment -comment -comment -unused -unused -unused -2 after you eat at the restaurant with Sans. -comment -comment -comment -comment -Pre-castle specific flags, seem to affect whether you can proceed or not and are naturally set as you progress. -Pre-castle specific flags, seem to affect whether you can proceed or not and are naturally set as you progress. -Pre-castle specific flags, seem to affect whether you can proceed or not and are naturally set as you progress. -Pre-castle specific flags, seem to affect whether you can proceed or not and are naturally set as you progress. -unused -comment -Turn available (1),
Already turned (2).
Probably used if Game Over during Mettaton battle. -1: kill Mettaton. -Incremental values: as you battle unique monsters in the core. -unused -unused -unused -Unclear, but it seems to determine the sprite for Alphy's expression. -Determines which direction the elevator will go. -comment -comment -Remebered the name (1),
Forgot the name (2). -Bought something (1),
Had a chat (2).
Probably about the origin of the name. -Burgerpants' MTT conversation. -Burgerpants' conversation about Bratty and Catty. -unused -unused -comment -comment -"An antique revolver."
"It has no ammo." -"This battle-worn hat makes you want to grow a beard." -"Unique"
"It is too bent to fit on your key chain." -"Huge steak in the shape of Mettaton's face."
Character names Drak, Gigi and Gugu changes Face Steak to FSteak. -unused -unused -unused -unused -comment -unused -comment -comment -comment -Seem to determine which step of the story to tell next. -comment -"A strange light fills the room."
"Twilight is shining through the barrier."
"It seems your journey is finally over."
"You're filled with DETERMINATION." -comment -Snowdin (1),
Waterfall (2),
Hotland (3) -About where to find Temmie Village -??? (0),
Temmie (1) -Allows the second part of the call to occur when calling twice.
Every room has two or more conversation parts. -unused -unused -After Undyne's date, calling Papyrus includes Undyne in the conversation. -unused -unused -unused -unused -Call Papyrus and Undyne in room_fire_lasers1.
Just a counter used for this specific call, allowing the third part to occur. -unused -unused -unused -unused -Not sure about this one. -comment -unused -unused -unused -comment -Various values.
Only affects what happens in the lab, used to progress through. -Various values.
Only affects what happens in the lab, used to progress through. -Various values.
Only affects what happens in the lab, used to progress through. -Various values.
Only affects what happens in the lab, used to progress through. -Various values.
Only affects what happens in the lab, used to progress through. -Various values.
Only affects what happens in the lab, used to progress through. -Various values.
Only affects what happens in the lab, used to progress through. -Various values.
Only affects what happens in the lab, used to progress through. -Various values.
Only affects what happens in the lab, used to progress through. -Various values.
Only affects what happens in the lab, used to progress through. -Various values.
Only affects what happens in the lab, used to progress through. -Various values.
Only affects what happens in the lab, used to progress through. -12 after you exit the true lab. -??? (1),
??? (2),
Letter EX (3) -comment -??? (1),
??? (2),
??? (3),
??? (4),
??? (5),
"I got nothing." (6),
??? (7?) -comment -unused -comment -comment -comment -fighting_asriel must be 1.
Can't die. -comment -unused -comment -comment -comment -comment -Sets the HP to decimal values. -2 if you complete the True Pacifist boss fight,
1 if you talk to Asriel in the ruins after the True Pacifist boss fight. -Progress through the conversation with Asriel in the ruins. -comment -comment -comment -comment -comment -comment -Time is counted in frames. 30 frames per second.
Due to scientific notation, any number going over six digits gets truncated to exactly six.
The seventh digit gets rounded to closest integer, any subsequent digit is effectively ignored. diff --git a/strings/freshfile b/strings/freshfile deleted file mode 100644 index e341738..0000000 --- a/strings/freshfile +++ /dev/null @@ -1,549 +0,0 @@ -Chara -1 -20 -20 -10 -0 -10 -0 -4 -0 -0 -0 -0 -0 -0 -0 -0 -0 -0 -0 -0 -0 -0 -0 -0 -0 -0 -0 -3 -4 -0 -0 -0 -0 -0 -100 -0 -0 -0 -0 -0 -0 -0 -0 -0 -0 -0 -0 -0 -0 -0 -0 -0 -0 -0 -0 -0 -0 -0 -0 -0 -0 -0 -0 -0 -0 -0 -0 -0 -0 -0 -0 -0 -0 -0 -0 -0 -0 -0 -0 -0 -0 -0 -0 -0 -0 -0 -0 -0 -0 -0 -0 -0 -0 -0 -0 -0 -0 -0 -0 -0 -0 -0 -0 -0 -0 -0 -0 -0 -0 -0 -0 -0 -0 -0 -0 -0 -0 -0 -0 -0 -0 -0 -0 -0 -0 -0 -0 -0 -0 -0 -0 -0 -0 -0 -0 -0 -0 -0 -0 -0 -0 -0 -0 -0 -0 -0 -0 -0 -0 -0 -0 -0 -0 -0 -0 -0 -0 -0 -0 -0 -0 -0 -0 -0 -0 -0 -0 -0 -0 -0 -0 -0 -0 -0 -0 -0 -0 -0 -0 -0 -0 -0 -0 -0 -0 -0 -0 -0 -0 -0 -0 -0 -0 -0 -0 -0 -0 -0 -0 -0 -0 -0 -0 -0 -0 -0 -0 -0 -0 -0 -0 -0 -0 -0 -0 -0 -0 -0 -0 -0 -0 -0 -0 -0 -0 -0 -0 -0 -0 -0 -0 -0 -0 -0 -0 -0 -0 -0 -0 -0 -0 -0 -0 -0 -0 -0 -0 -0 -0 -0 -0 -0 -0 -0 -0 -0 -0 -0 -0 -0 -0 -0 -0 -0 -0 -0 -0 -0 -0 -0 -0 -0 -0 -0 -0 -0 -0 -0 -0 -0 -0 -0 -0 -0 -0 -0 -0 -0 -0 -0 -0 -0 -0 -0 -0 -0 -0 -0 -0 -0 -0 -0 -0 -0 -0 -0 -0 -0 -0 -0 -0 -0 -0 -0 -0 -0 -0 -0 -0 -0 -0 -0 -0 -0 -0 -0 -0 -0 -0 -14 -0 -0 -0 -0 -0 -0 -0 -0 -0 -0 -0 -0 -0 -0 -0 -0 -0 -0 -0 -0 -0 -0 -0 -0 -0 -0 -0 -0 -0 -0 -0 -0 -0 -0 -0 -0 -0 -0 -0 -0 -0 -0 -0 -0 -0 -0 -0 -0 -0 -0 -0 -0 -0 -0 -0 -0 -0 -0 -0 -0 -0 -0 -0 -0 -0 -0 -0 -0 -0 -0 -0 -0 -0 -0 -0 -0 -0 -0 -0 -0 -0 -0 -0 -0 -0 -0 -0 -0 -0 -0 -0 -0 -0 -0 -0 -0 -0 -0 -0 -0 -0 -0 -0 -0 -0 -0 -0 -0 -0 -0 -0 -0 -0 -0 -0 -0 -0 -0 -0 -0 -0 -0 -0 -0 -0 -0 -0 -0 -0 -0 -0 -0 -0 -0 -0 -0 -0 -0 -0 -0 -0 -0 -0 -0 -0 -0 -0 -0 -0 -0 -0 -0 -0 -0 -0 -0 -0 -0 -0 -0 -0 -0 -0 -0 -0 -0 -0 -0 -0 -0 -0 -0 -0 -0 -0 -0 -0 -0 -0 -0 -0 -0 -0 -0 -0 -0 -0 -0 -0 -0 -0 -0 -0 -0 -0 -0 -0 -0 -0 -0 -0 -0 -0 -0 -0 -0 -0 -0 -0 -0 -0 -2 -1 -1 -0 -0 -4 -0 \ No newline at end of file diff --git a/strings/infofile b/strings/infofile deleted file mode 100644 index cc6222d..0000000 --- a/strings/infofile +++ /dev/null @@ -1,549 +0,0 @@ -Name -LOVE -Max HP -Max EN -Base AT -Boosted AT -Base DF -Boosted DF -sp -EXP -GOLD -Kills -ITEM (1) -CELL (1) -ITEM (2) -CELL (2) -ITEM (3) -CELL (3) -ITEM (4) -CELL (4) -ITEM (5) -CELL (5) -ITEM (6) -CELL (6) -ITEM (7) -CELL (7) -ITEM (8) -CELL (8) -WEAPON -ARMOR -choice_left_toriel -unused -unused -unused -undyne_trigger_override -Fun -hardmode -true_pacifist -disable_random_encounters -unaccessed -Previous fight (Spare) -Previous fight (Flee) -Previous fight (Kill) -Previous fight (Bored) -Interaction with Dummy (Ruins) -in_battle -type_heart_transition -unaccessed -unaccessed -unused -animation_index -cooked_noodles -name_color -MERCY -> Spare -MERCY -> Flee -Dialogue skipped -murderlevel_override -spared_specific -fast_text_skip -tutorial_froggit_encountered -Gray Rock (1st) pushed -Gray Rock (2nd) pushed -Gray Rock (3rd) pushed -Gray Rock (4th) asked to move -candy_taken -SPARE -> Napstablook -waited_toriel -unused -unused -unused -CELL -> Toriel -> Say Hello -CELL -> Toriel -> Flirt -CELL -> Toriel -> Call "Mom" -ruins_switches_pressed -Tried to exit "Home" -Interaction with Toriel -Chosen flavor -Sans creeping -unused -unused -Learned about "water sausage" -wrong_switches_pressed -Interaction with Doggo -Interaction with Dogamy and Dogaressa -Interaction with Greater Dog -Interaction with Lesser Dog -Interaction with Snowman -Interaction with Snowdrake -choice_harder_puzzle -GOLD spent on Spider Bakesale -GOLD spent on Nice Cream -unused -Papyrus asks about spaghetti trap -Reset XO puzzle -Switch buried under snow -Found 30G in a snow poff -Flirted with Papyrus -Interaction with Papyrus -Encountered Papyrus -bpants_alt_dialogue -Snowdin Forest Progress -unused -Interaction with Snowed Inn -stayed_inn -Betray Gyftrot -armor_papyrus_inquiry -choice_papyrus_inquiry -armor_undyne_saw -Tough Punch Card -Interaction with Nice Cream business -Nice Cream Punch Cards bought -Interaction with Shyren -Found the Annoying Dog -Found 20G inside a "saggy old couch" -unaccessed -Have an umbrella -Placed an umbrella on a statue -unused -Progress of date with Papyrus -Progress of date with Sans at Grillby's -Monster Kid in the rain -interacted_garbage_savepoint -Interaction with "Stable" -Progress of date with Napstablook -Spooky tune playing -Spooked Aaron and Woshua -Talked with Gerson -creepy_friend_seen -Interaction with Monster Kid -undyne_difficulty -Found a Faded Ribbon -unused -Found the Toy Knife -Found a slice of pie -Got the Abandoned Quiche -Got the Old Tutu -Got the Ballet Shoes -Found a legendary artifact -Got the Astronaut Food -Got the Instant Noodles. -Got the Burnt Pan -Got the Stained Apron -Got the Glamburger (Trashcan) -Got 100G (Trashcan) -Got the Worn Dagger -Got the Heart-shaped Locket -unused -unused -unused -unused -unused -unused -unused -unused -unused -unused -unused -unused -unused -unused -SPARE -> Froggit -SPARE -> Whimsun -SPARE -> Moldsmal -SPARE -> Loox -SPARE -> Vegetoid -SPARE -> Migosp -SPARE -> Snowdrake -SPARE -> Icecap -SPARE -> Gyftrot -SPARE -> Doggo -SPARE -> Dogamy and Dogaressa -SPARE -> Lesserdog -SPARE -> Greatdog -SPARE -> Aaron -SPARE -> Moldbygg -SPARE -> Woshua -SPARE -> Temmie -SPARE -> Mad Dummy -SPARE -> Vulkin -SPARE -> Tsunderplane -SPARE -> Pyrope -SPARE -> Final Froggit -SPARE -> Whimsalot -SPARE -> Astigmatism -SPARE -> Madjick -SPARE -> Knight Knight -SPARE -> Endogeny -unused -unused -unused -unused -unused -unused -unused -unused -unused -unused -unused -unused -unused -unused -unused -unused -unused -unused -unused -unused -unused -unused -unused -unused -unused -unused -unused -unused -unused -unused -unused -unused -unused -unused -Talked to Toriel (Pacifist) -Talked to Sans (Pacifist) -Talked to Undyne (Pacifist) -Unlock conversations with Napstablook -Talked to Papyrus (Pacifist) -Talked to Alphys (Pacifist) -Talked to Asgore (Pacifist) -Talked to Mettaton (Pacifist) -Talked to Napstablook (Pacifist) -Area for kill counter -Total Kills -Kills (Ruins) -Kills (Snowdin) -Kills (Waterfall) -Kills (Hotland) -unused -unused -unused -unused -unused -unused -unused -unused -unused -unused -unused -unused -unused -unused -unused -Genocide (Ruins) -Genocide (Snowdin) -Genocide (Waterfall) -Genocide (Hotland) -Genocide (CORE) -unused -unused -unused -unused -unused -unused -unused -unused -unused -unused -unused -unused -unused -unused -unused -unused -unused -unused -unused -unused -unused -unused -unused -unused -nicecream_business2 -KILL -> Undyne the Undying -KILL -> Glad Dummy -KILL -> Snowman -Interacted with Sans' puzzle -robbed_snowdin -robbed_core -unused -unused -unused -Ate Food -interacted_fakedog -Delivered Sea Tea -Delivered Cinnabun -Delivered "Hot Dog" -Sell stuff to Temmie -Temmie Armor discount -status_hotel -unused -Talk to Allergic Temmie -Solved glowing shroom puzzle -Encountered Sans -Accepted Sans' MERCY -unused -unused -Heavy stick at Ruins exit -Sent Temmie to Cool Leg -Prank call -completed_tile_puzzle -Interacted with "Clamgirl" -Talked to "Puzzle Elder" -Interaction with So Sorry -SPARE -> Glyde -check_papyrus_kitchen_again -undyne_spears_anger -unaccessed -conversation_toriel_sms -conversation_sms_parameters -failed_defusing -stepped_green_tile -unused -unused -unused -unused -unused -unused -unused -unused -unused -unused -DIMENSIONAL BOX A (1) -DIMENSIONAL BOX A (2) -DIMENSIONAL BOX A (3) -DIMENSIONAL BOX A (4) -DIMENSIONAL BOX A (5) -DIMENSIONAL BOX A (6) -DIMENSIONAL BOX A (7) -DIMENSIONAL BOX A (8) -DIMENSIONAL BOX A (9) -DIMENSIONAL BOX A (10) -DIMENSIONAL BOX A (11) -DIMENSIONAL BOX A (12) -DIMENSIONAL BOX B (1) -DIMENSIONAL BOX B (2) -DIMENSIONAL BOX B (3) -DIMENSIONAL BOX B (4) -DIMENSIONAL BOX B (5) -DIMENSIONAL BOX B (6) -DIMENSIONAL BOX B (7) -DIMENSIONAL BOX B (8) -DIMENSIONAL BOX B (9) -DIMENSIONAL BOX B (10) -DIMENSIONAL BOX B (11) -DIMENSIONAL BOX B (12) -unused -unused -unused -unused -unused -unused -unused -unused -unused -unused -unused -unused -unused -unused -unused -unused -unused -unused -unused -unused -unused -unused -unused -unused -unused -unused -Interaction with Undyne -undyne_hp_left -Encountered Undyne -poured_water_ground -conversation_papyrus_calls -Interaction with Mad Dummy -Solved piano puzzle -Encounters in Waterfall area -Encounters near Temmie Village -unused -rain_parameters -rain_parameters -rain_parameters -rain_parameters -rain_parameters -unused -have_water -disable_alphys_calls -disable_alphys_statuses -conversation_alphys_statuses -quick_battle -Disable Laser (1) -Enable Laser (2) -Disable Laser (2) -Solved shooting puzzle (1) -Solved shooting puzzle (2) -conveyor_puzzle_variable -failed_jetpack_segment -GOLD spent on Hot Dogs -conversation_hotdogs -Hot Dogs placed on your head -reached_headdogs_limit -Muffet's price -GOLD spent on bribing Muffet -unused -status_yellow_button -reset_bridgeseed_puzzle -won_ball_game -fall_animation_parameters -Progress of date with Undyne -undyne_expression -Food at Grillby's -unused -unclear -unused -bombs_defused -Encountered Muffet -KILL -> Muffet -current_elevator_floor -Solved shooting puzzle (3) -Solved shooting puzzle (4) -asked_papyrus_rg -KILL -> Royal Guards -Spent 9999 GOLD on Muffet's bake sale -Disabled Laser (3) -Talked to Bratty and Catty -Bratty and Catty: Mettaton -Bratty and Catty: Alphys -Encounters in Hotland area -Napstablook's friend request -unused -unused -unused -Progress of date with Sans at the Restaurant -Alphys helped with puzzle (1) -Alphys helped with puzzle (2) -Alphys helped with puzzle (3) -Alphys helped with puzzle (4) -unclear -unclear -unclear -unclear -unused -Encounters in CORE area -Exposed Mettaton's switch -KILL -> Mettaton -progress_core_battles2 -unused -unused -unused -alphys_expression -Elevator target floor -rode_long_elevator -Unlocked Mettaton's House -choice_flamey_challenge -Interaction with Burger Pants -conversation_mtt -conversation_girls -unused -unused -Drinks taken from cooler -Drinks wasted -Bought Empty Gun -Bought Cowboy Hat -Bought Mystery Key -Bought Face Steak -unused -unused -unused -unused -progress_early_story -unused -Got the Castle Key (1) -Got the Castle Key (2) -unlocked_latchkey -early_story_parameter1 -early_story_parameter2 -Point of No Return -experience_cosmic_garbage -Riverperson destination -Got a hint from Riverperson -Riverperson's boat looks like Temmie -called_already -unused -unused -Undyne moved to Papyrus' place -unused -unused -unused -unused -conversation_undyne_mad -unused -unused -unused -unused -KILL -> Flowey -KILL -> Asgore -unused -unused -unused -Solved True lab -truelab_events -truelab_events -truelab_events -truelab_events -truelab_events -truelab_events -truelab_events -truelab_events -truelab_events -truelab_events -truelab_events -truelab_events -Progress of date with Alphys -Undyne's letter -popato_chisps_bought -Talked to Onionsan -got_sans_room_key -unused -seen_cast -fighting_asriel -conversation_asriel_fight -Does your SOUL Re-Fuse -Final stage of the Dreamer Battle -unused -saved_lost_soul -saved_lost_soul -saved_lost_soul -saved_lost_soul -toggle_final_beam -plot_over -conversation_asriel2 -Progress -menuchoice1 -menuchoice2 -menuchoice3 -Current Song -Current Room -Play Time diff --git a/strings/rangefile b/strings/rangefile deleted file mode 100644 index eac1afe..0000000 --- a/strings/rangefile +++ /dev/null @@ -1,549 +0,0 @@ -65535 -1,1,20 -0,1,9999 -0,1,9999 -0,1,9999 -0,1,9999 -0,1,9999 -0,1,9999 -0,1,9999 -0,1,99999 -0,1,2147483647 -0,1,9999 -0,1,64 -0,1,512 -0,1,64 -0,1,512 -0,1,64 -0,1,512 -0,1,64 -0,1,512 -0,1,64 -0,1,512 -0,1,64 -0,1,512 -0,1,64 -0,1,512 -0,1,64 -0,1,512 -0,1,64 -0,1,64 -0,-1,1 -unused -unused -unused -0,-1,1 -0,1,100 -0,-1,1 -0,-1,1 -0,-1,1 -unused -0,-1,1 -0,-1,1 -0,-1,1 -0,-1,1 -0,1,3 -0,-1,1 -0,-1,1 -unused -unused -unused --1,1,255 -0,-1,1 -0,1,2 -0,1,9999 -0,1,9999 -0,1,9999 --1,1,255 -0,-1,1 -0,-1,1 -0,-1,1 -0,-1,1 -0,-1,1 -0,-1,1 -0,-1,1 -0,1,4 -0,-1,1 -0,1,2 -unused -unused -unused -0,1,255 -0,1,255 -0,-1,1 -0,1,9999 -0,1,9999 -0,1,5 -0,2,2 --1,1,100 -unused -unused -0,-1,1 -0,1,9999 -0,1,2 -0,1,2 -0,1,3 -0,1,2 -0,1,5 -0,1,9999 -0,1,10 -0,1,9999 -0,1,9999 -unused -0,1,10 -0,1,9999 -0,-1,1 -0,-1,1 -0,-1,1 --3,1,255 -0,-1,1 -0,-1,1 -0,1,255 -unused -0,1,2 -0,-1,1 -0,-1,1 -0,1,255 -0,1,10 -0,1,255 -0,-1,1 -0,-1,8 -0,1,9999 -0,1,10 -0,-1,1 -0,-1,1 -unused -0,-1,1 -0,-1,1 -unused -0,1,4 -0,1,2 -0,1,255 -0,-1,1 -0,1,10 -0,1,10 -0,1,10 -0,-1,1 -0,1,3 -0,-1,1 -0,1,10 -0,1,9999 -0,-1,1 -0,-1,1 -0,-1,1 -0,1,2 -0,-1,1 -0,-1,1 -0,-1,1 -0,-1,1 -0,2,3 -0,-1,1 -0,-1,1 -0,-1,1 -0,-1,1 -0,-1,1 -0,-1,1 -0,-1,1 -unused -unused -unused -unused -unused -unused -unused -unused -unused -unused -unused -unused -unused -unused -0,-1,1 -0,-1,1 -0,-1,1 -0,-1,1 -0,-1,1 -0,-1,1 -0,-1,1 -0,-1,1 -0,-1,1 -0,-1,1 -0,-1,1 -0,-1,1 -0,-1,1 -0,-1,1 -0,-1,1 -0,-1,1 -0,-1,1 -0,-1,1 -0,-1,1 -0,-1,1 -0,-1,1 -0,-1,1 -0,-1,1 -0,-1,1 -0,-1,1 -0,-1,1 -0,-1,1 -unused -unused -unused -unused -unused -unused -unused -unused -unused -unused -unused -unused -unused -unused -unused -unused -unused -unused -unused -unused -unused -unused -unused -unused -unused -unused -unused -unused -unused -unused -unused -unused -unused -unused -0,1,9999 -0,1,9999 -0,1,9999 -0,-1,1 -0,1,9999 -0,1,9999 -0,1,9999 -0,1,9999 -0,1,9999 -0,1,9999 -0,1,9999 -0,1,9999 -0,1,9999 -0,1,9999 -0,1,9999 -unused -unused -unused -unused -unused -unused -unused -unused -unused -unused -unused -unused -unused -unused -unused -0,-1,1 -0,-1,1 -0,-1,1 -0,-1,1 -0,-1,1 -unused -unused -unused -unused -unused -unused -unused -unused -unused -unused -unused -unused -unused -unused -unused -unused -unused -unused -unused -unused -unused -unused -unused -unused -0,1,9999 -0,-1,1 -0,-1,1 -0,1,9999 -0,-1,1 -0,-1,1 -0,-1,1 -unused -unused -unused -0,-1,1 -0,-1,1 -0,-1,1 -0,-1,1 -0,-1,1 -0,1,10 -0,1,255 -0,1,255 -unused -0,-1,1 -0,-1,1 -0,-1,1 -0,-1,1 -unused -unused -0,1,100 -0,-1,1 -0,-1,1 -0,-1,1 -0,-1,1 -0,1,9999 -0,1,10 -0,-1,1 -0,-1,1 -0,-1,1 -0,1,255 -0,1,9999 -0,1,255 -0,-1,1 -0,-1,1 -unused -unused -unused -unused -unused -unused -unused -unused -unused -unused -0,1,255 -0,1,255 -0,1,255 -0,1,255 -0,1,255 -0,1,255 -0,1,255 -0,1,255 -0,1,255 -0,1,255 -0,1,255 -0,1,255 -0,1,255 -0,1,255 -0,1,255 -0,1,255 -0,1,255 -0,1,255 -0,1,255 -0,1,255 -0,1,255 -0,1,255 -0,1,255 -0,1,255 -unused -unused -unused -unused -unused -unused -unused -unused -unused -unused -unused -unused -unused -unused -unused -unused -unused -unused -unused -unused -unused -unused -unused -unused -unused -unused -0,1,255 -0,1,9999 -0,-1,1 -0,1,9999 -0,1,9999 -0,1,10 -0,-1,1 -0,1,9999 -0,1,9999 -unused -0,0.01,512 -0,1,512 -0,1,512 -0,1,512 -0,1,512 -unused -0,-1,1 -0,-1,1 -0,-1,1 -0,1,9999 -0,-1,1 -0,-1,1 -0,-1,1 -0,-1,1 -0,-1,1 -0,-1,1 -0,1,255 -0,-1,1 -0,1,9999 -0,1,9999 -0,1,9999 -0,-1,1 -0,1,9999 -0,1,9999 -unused -0,1,10 -0,1,9999 -0,-1,1 --1,1,255 -0,1,255 --1,1,255 -0,1,10 -unused --1,1,255 -unused -0,1,9999 -0,-1,1 -0,-1,1 -0,1,255 -0,-1,1 -0,-1,1 -0,-1,1 -0,-1,1 -0,-1,1 -0,-1,1 -0,1,9999 -0,1,9999 -0,1,9999 -0,1,9999 -0,-1,1 -unused -unused -unused -0,1,255 -0,-1,1 -0,-1,1 -0,-1,1 -0,-1,1 --1,1,255 --1,1,255 --1,1,255 --1,1,255 -unused -0,1,9999 -0,1,9999 -0,-1,1 -0,1,9999 -unused -unused -unused --1,1,255 -0,-1,1 -0,-1,1 -0,-1,1 -0,1,10 -0,1,255 -0,1,9999 -0,1,9999 -unused -unused -0,1,9999 -0,1,9999 -0,-1,1 -0,-1,1 -0,-1,1 -0,-1,1 -unused -unused -unused -unused -0,1,9999 -unused -0,-1,1 -0,-1,1 -0,-1,1 -0,1,255 -0,1,255 -0,-1,1 -0,-1,1 -0,1,3 -0,-1,1 -0,-1,1 -0,1,10 -unused -unused -0,-1,1 -unused -unused -unused -unused -0,-1,1 -unused -unused -unused -unused -0,-1,1 -0,-1,1 -unused -unused -unused -0,-1,1 -0,1,255 -0,1,255 -0,1,255 -0,1,255 -0,1,255 -0,1,255 -0,1,255 -0,1,255 -0,1,255 -0,1,255 -0,1,255 -0,1,255 -0,1,255 -0,1,10 -0,1,9999 -0,1,9999 -0,-1,1 -unused -0,-1,1 -0,-1,1 -0,1,9999 -0,-1,1 -0,-1,1 -unused -0,-1,1 -0,-1,1 -0,-1,1 -0,-1,1 -0,-1,1 -0,1,1024 -0,1,9999 -0,1,1024 -0,1,255 -0,1,255 -0,1,255 -0,1,1024 -0,1,334 -0,1,9223372036854775807 diff --git a/strings/roomfile b/strings/roomfile deleted file mode 100644 index e2be87a..0000000 --- a/strings/roomfile +++ /dev/null @@ -1,335 +0,0 @@ -6#Ruins - Entrance -12#Ruins - Leaf Pile -18#Ruins - Mouse Hole -31#Ruins - Home -46#Snowdin - Box Road -56#Snowdin - Spaghetti -61#Snowdin - Dog House -68#Snowdin - Town -83#Waterfall - Checkpoint -86#Waterfall - Hallway -94#Waterfall - Crystal -110#Waterfall - Bridge -114#Waterfall - Trash Zone -116#Waterfall - Quiet Area -128#Waterfall - Temmie Village -134#Waterfall - Undyne Arena -139#Hotland - Laboratory Entrance -145#Hotland - Magma Chamber -155#Hotland - Core View -164#Hotland - Bad Opinion Zone -176#Hotland - Spider Entrance -183#Hotland - Hotel Lobby -196#Hotland - Core Branch -210#Hotland - Core End -216#Castle Elevator -219#New Home -231#Last Corridor -232#Throne Entrance -235#Throne Room -236#The End -246#True Laboratory -251#True Lab - Bedroom -0#room_start -1#room_introstory -2#room_introimage -3#room_intromenu -4#room_area1 -5#room_area1_2 -7#Ruins - 2 -8#Ruins - 3 -9#Ruins - 4 -10#Ruins - 5 -11#Ruins - 6 -13#Ruins - 7A -14#Ruins - 8 -15#Ruins - 9 -16#Ruins - 10 -17#Ruins - 11 -19#Ruins - 12 -20#Ruins - 12B -21#Ruins - 13 -22#Ruins - 14 -23#Ruins - 15A -24#Ruins - 15B -25#Ruins - 15C -26#Ruins - 15D -27#Ruins - 15E -28#Ruins - 16 -29#Ruins - 17 -30#Ruins - 18OLD -32#Home - Entrance Hall -33#Home - Living Room -34#Home - Hall -35#Home - Toriel's Room -36#Home - Asriel's Room -37#Home - Kitchen -38#room_basement1 -39#room_basement2 -40#room_basement3 -41#room_basement4 -42#room_basement5 -43#Snowdin - Ruins Exit -44#Snowdin - 1 -45#Snowdin - 2 -47#Snowdin - 3A -48#Snowdin - 4 -49#Snowdin - 5 -50#Snowdin - 6 -51#Snowdin - 6A -52#Snowdin - 7 -53#Snowdin - 8 -54#Snowdin - 8A -55#Snowdin - 9 -57#Snowdin - Snow Puzzle -58#Snowdin - XO Puzzle (Small) -59#Snowdin - XO Puzzle (Papyrus) -60#Snowdin - Tile Puzzle -62#Snowdin - icehole -63#Snowdin - iceentrance -64#Snowdin - iceexit_new -65#Snowdin - iceexit -66#Snowdin - Snow Poff Zone -67#Snowdin - Dangerous Bridge Puzzle -69#Snowdin - town2 -70#Snowdin - Dock -71#Snowdin - Snowed Inn -72#Snowdin - Snowed Inn (2nd floor) -73#Snowdin - Grillby's -74#Snowdin - Library -75#Snowdin - Garage -76#Snowdin - Papyrus's and Sans's House -77#Snowdin - Papyrus's Room -78#Snowdin - Sans's Room -79#Snowdin - Sans's Room (Dark) -80#Snowdin - Sans's Basement -81#Snowdin - Foggy Hallway -82#Waterfall - 1 -84#Waterfall - 3 -85#Waterfall - 3A -87#Waterfall - bridgepuzz1 -88#Waterfall - 5 -89#Waterfall - 5A -90#Waterfall - 6 -91#Waterfall - 7 -92#Waterfall - 8 -93#Waterfall - 9 -95#Waterfall - 11 -96#Waterfall - nicecream -97#Waterfall - 12 -98#Waterfall - shoe -99#Waterfall - bird -100#Waterfall - Onionsan -101#Waterfall - 14 -102#Waterfall - Piano Puzzle -103#Waterfall - dogroom -104#Waterfall - Music Box Statue -105#Waterfall - prewaterfall -106#Waterfall - waterfall -107#Waterfall - waterfall2 -108#Waterfall - waterfall3 -109#Waterfall - waterfall4 -111#Waterfall - undynebridge -112#Waterfall - undynebridgeend -113#Waterfall - trashzone1 -115#Waterfall - trashzone2 -117#Waterfall - Undyne's Yard -118#Waterfall - Undyne's House -119#Waterfall - Blooky's Yard -120#Waterfall - Blooky's House -121#Waterfall - hapstablook -122#Waterfall - Blook Farm -123#Waterfall - prebird -124#Waterfall - Gerson's Shop -125#Waterfall - Dock -126#Waterfall - 15 -127#Waterfall - 16 -129#Waterfall - 17 -130#Waterfall - 18 -131#Waterfall - 19 -132#Waterfall - 20 -133#Waterfall - Puzzle Elder -135#Waterfall - Arena Exit -136#Waterfall - Hotland Entrance -137#Hotland - Sans's Station -138#Hotland - Water Cooler -140#Hotland - Dock -141#Hotland - lab1 -142#Hotland - lab2 -143#Hotland - 3 -144#Hotland - 5 -146#Hotland - 6A -147#Hotland - lasers1 -148#Hotland - 7 -149#Hotland - 8 -150#Hotland - shootguy_2 -151#Hotland - 9 -152#Hotland - shootguy_1 -153#Hotland - turn -154#Hotland - cookingshow -156#Hotland - elevator_r1 -157#Hotland - elevator_r2 -158#Hotland - hotdog -159#Hotland - walkandbranch -160#Hotland - sorry -161#Hotland - apron -162#Hotland - 10 -163#Hotland - rpuzzle -165#Hotland - boysnightout -166#Hotland - newsreport -167#Hotland - coreview2 -168#Hotland - elevator_l2 -169#Hotland - elevator_l3 -170#Hotland - spidershop -171#Hotland - walkandbranch2 -172#Hotland - conveyorlaser -173#Hotland - shootguy_3 -174#Hotland - preshootguy4 -175#Hotland - shootguy_4 -177#Hotland - Spider's Web -178#Hotland - pacing -179#Hotland - operatest -180#Hotland - Tile Puzzle EX -181#Hotland - hotelfront_1 -182#Hotland - hotelfront_2 -184#Hotel - Restaurant -185#Hotland - hoteldoors -186#Hotland - hotelbed -187#Hotland - elevator_r3 -188#Hotland - precore -189#Hotland - core1 -190#Hotland - core2 -191#Hotland - core3 -192#Hotland - core4 -193#Hotland - core5 -194#Hotland - core_freebattle -195#Hotland - core_laserfun -197#Hotland - core_bottomleft -198#Hotland - core_left -199#Hotland - core_topleft -200#Hotland - core_top -201#Hotland - core_topright -202#Hotland - core_right -203#Hotland - core_bottomright -204#Hotland - core_center -205#Hotland - shootguy_5 -206#Hotland - core_treasureleft -207#Hotland - core_treasureright -208#Hotland - core_warrior -209#Hotland - core_bridge -211#Hotland - core_metttest -212#Hotland - core_final -213#Hotland - elevator -214#Hotland - elevator_l1 -215#Hotland - finalelevator -217#room_castle_precastle -218#room_castle_hook -220#room_asghouse1 -221#room_asghouse2 -222#room_asghouse3 -223#room_asgoreroom -224#room_asrielroom_final -225#room_kitchen_final -226#room_basement1_final -227#room_basement2_final -228#room_basement3_final -229#room_basement4_final -230#room_lastruins_corridor -233#room_castle_coffins1 -234#room_castle_coffins2 -237#room_castle_barrier -238#room_castle_exit -239#room_undertale_end -240#room_castle_trueexit -241#room_outsideworld -242#Hotland - labelevator -243#True Lab - elevatorinside -244#True Lab - elevator -245#True Lab - hall1 -247#True Lab - hall2 -248#True Lab - operatingroom -249#True Lab - Red Lever -250#True Lab - prebed -252#True Lab - mirror -253#True Lab - Blue Lever -254#True Lab - hall3 -255#True Lab - shower -256#True Lab - determination -257#True Lab - tv -258#True Lab - cooler -259#True Lab - Green Lever -260#True Lab - fan -261#True Lab - castle_elevator -262#True Lab - prepower -263#True Lab - power -264#room_gaster -265#room_icecave1 -266#room_ice_dog -267#room2 -268#Waterfall - fakehallway -269#room_mysteryman -270#room_soundtest -271#TESTROOM -272#Waterfall - redacted -273#Waterfall - 13 -274#room_overworld -275#room_overworld3 -276#bullettest -277#Waterfall - 16A -278#room_end_castroll -279#room_end_highway -280#room_end_beach -281#room_end_metta -282#room_end_school -283#room_end_mtebott -284#room_creditsdodger -285#room_end_myroom -286#room_end_theend -287#room_spritecheck -288#room_joyconfig -289#room_controltest -290#room_f_start -291#room_f_intro -292#room_f_menu -293#room_f_room -294#room_floweyx -295#room_f_phrase -296#Hotland - 4 -297#Hotland - 10_old -298#Hotland - 10A_old -299#Snowdin - placeholder -300#Ruins - 12B_old -301#Snowdin - rollsnow -302#Waterfall - 7_older -303#room_meetundyne_old -304#Waterfall - mushroom -305#room_monsteralign_test -306#room_battle -307#room_floweybattle -308#room_fastbattle -309#room_storybattle -310#room_gameover -311#room_shop1 -312#room_shop2 -313#room_shop3 -314#room_shop4 -315#room_shop5 -316#room_riverman_transition -317#room_papdate -318#room_adate -319#room_flowey_endchoice -320#room_flowey_regret -321#room_empty -322#room_emptywhite -323#room_emptyblack -324#room_nothingness -325#room_undertale -326#room_of_dog -327#room_quizholder -328#room_friendtest -329#room_bringitinguys -330#room_asrielappears -331#room_goodbyeasriel -332#room_asrielmemory -333#room_asrieltest -334#room_afinaltest \ No newline at end of file diff --git a/strings/sortfile b/strings/sortfile deleted file mode 100644 index 22f14b7..0000000 --- a/strings/sortfile +++ /dev/null @@ -1,549 +0,0 @@ -"Easy to change, huh?" -"You want some LOVE, don't you?" -comment -Unused "ENERGY" value -comment -comment -comment -comment -Maybe "Spell", which is unused -"You will be judged for every EXP you've earned." -comment -"When you kill someone, your EXP increases." -Inventory, Slot 1 -Phone, Slot 1 -Inventory, Slot 2 -Phone, Slot 2 -Inventory, Slot 3 -Phone, Slot 3 -Inventory, Slot 4 -Phone, Slot 4 -Inventory, Slot 5 -Phone, Slot 5 -Inventory, Slot 6 -Phone, Slot 6 -Inventory, Slot 7 -Phone, Slot 7 -Inventory, Slot 8 -Phone, Slot 8 -comment -comment -[This might actually be in a different location on this list.]
Determines the type of the final scene in the bedroom. -unused -unused -unused -When 1, upon encountering Undyne, she will treat you as if you killed no monsters, even if you killed one. -Chosen randomly when you start a new run, set to 0 after specific events. -comment -Post-Asriel fight status. -Receive Undyne's letter or kill Mettaton Neo.
Needs confirmation if it works when set manually. -unaccessed -comment -comment -comment -Let the battle take too long.
Occurs only in the ruins. -Flee (0),
Kill (1),
Talk (2),
Bored (3).
Changes what Mad Dummy says. -comment -Occurs when triggering "quick" battles (i.e. Undyne's spears, lasers). -unaccessed -unaccessed -unused -comment -Non-Genoside only. -Set when you talk to the frog in the ruins.
When sparing monsters:
0 for yellow names,
1 for white,
2 for pink.
Also a small easter egg in the trash area if not equal to 0. -comment -comment -comment -If set to anything other than 0, overrides the calculated murder level. -If you spare specific opponents, certain events that occur with a high murder level won't happen.
Similar to a "redemption" flag.
If you spare any of those monsters, the game is less desolated. -Keeping C pressed during dialogue will quickly skip sentences. -comment -comment -comment -comment -comment -comment -"This monster doesn't seem to have a sense of humor..." -Wait for Toriel to call you when she asks to stay in a room. -unused -unused -unused -After 4, Toriel's raction stays the same -comment -In combination with flirted_toriel, affects a few dialogues. -When greater than 25, changes the displayed text upon pressing a switch. -After 10, Toriel's raction stays the same. -1st time at "Home" (0),
Disobeyed (1),
Fight (3),
Kill (4),
Spare (5) -??? (0),
Butterscotch (1),
??? (2) -"Don't you know how to greet a new pal?" -unused -unused -Read about water sausages in Toriel's room.
Makes you recognize the plant in Toriel's living room. -After a while, gives you a hint about which switch to press. -1 if you kill Doggo,
2 if you throw him a stick and spare him. -1 if you kill Dogamy and/or Dogaressa,
2 if you damage them first and then throw a stick. -1 if you kill Greater Dog,
2 if you throw him a stick and spare him,
3 if you ignore him repeatedly. -1 if you kill Lesser Dog,
2 if you pet him until his neck extends at max.
If 2, room_ruins6 will be filled with broken dog structures. -1 if you get a Snowman Piece from the snowman in room_tundra6A,
2 if you get another piece after disposing of the first one,
4 if you use the Snowman Piece in front of the him,
5 if you talk to the him when the flag is 4. -1 if you laugh at Snowdrake's joke;
2 if you kill him, all future instances of Snowdrake with Chilldrakes. -? after Sans' puzzle ? Junior Jumble or Crosswords ? -comment -Seems to change when business relocates -unused -??? (1),
Left it (2) -Affects the dialogue with Sans after the puzzle.
Slightly different result if equals to 0 and M1 under the Sans category in undertale.ini is greater than 1. -comment -comment -comment -Skip fight (-3),
Improved "prison" (-2),
Captured (-1),
Spare (0),
Kill (1) -"He likes to say: Nyeh heh heh!" -Very slightly changes the dialogue with Burgerpants. -comment -unused -After "Not enough GOLD" (0),
Saty a night (1),
Not enough GOLD (2) -comment -Set if you "betray" Gyftrot by putting a present after removing some gifts off him.
Unaccessed -Equals to the id of the armor you're wearing upon the first call.
The combination of these affects the dialogue you get in Papyrus' second phone call. -Told the truth (0),
Lied about your clothes (1) -Equals to the id of the armor Undyne saw you wear. -Used Punch Card while wearing Tough Glove during battle. -Made a sale in Snowdin (8).
Changes mood and use of Punch Cards. -comment -Kill (1),
Had a musical career (2).
Affects one of the Amalgamate battle, you'll know the song.
Affects the Amalgamate's dialogue in the room after the True Pacifist ending. -comment -comment -Would affect the dialogue in room_water_mushroom, but it can't be accessed normally. -comment -Music box starts playing -unused -Outside house (1),
Inside house (2),
Unlock Papyrus's Room (3),
Date complete (4) -Seen any talking flowers? (1),
Is Papyrus cool? (2). -1 if you meet Monster Kid without an umbrella;
2 if, with flag set to 1, you get an umbrella and talk to him;
3 if, with flag set to 2, you dispose of the umbrella and talk to him again. -comment -"It's a horse stable."
"Do you want to go inside?"
"You jostle the door."
"It's locked." -Chat in the house (1),
Feel like "cosmic" garbage (3),
Don't lie on the ground (9) -Spooktunes (1),
Spookwave (2),
Ghouliday Music (3) -"..."
"if you're so scared, why do you keep winking?"
"THESE ARE WINKS OF FEAR ; )" -"That Emblem" (1),
"Emblem's meaning" (2),
"The Prophecy" (3) -Would prevent the NPC in room_water_prebird from repeating himself.
Cut content. -Exited (0),
Let Undyne do it (1),
Did it yourself (2) -Makes the fight more or less difficult, depending on a few factors (saved Monster Kid, how many times you died, etc.). -"If you're cuter, monsters won't hit you as hard." -unused -"Made of plastic."
"A rarity nowadays." -??? (1),
Butterscotch Pie (2),
??? (3) -"A psychologically damaged spinach egg pie." -"Finally, a protective piece of armor." -"These used shoes make you feel incredibly dangerous." -"The dog absorbs the artifact." -"For feeding a pet astronaut." -"Comes with everything you need for a quick meal!" -"Damage is rather consistent."
"Consumable items heal 4 more HP." -"Heals 1 HP every other turn." -comment -comment -"Perfect for cutting plants and vines." -"It says Best Friends Forever." -unused -unused -unused -unused -unused -unused -unused -unused -unused -unused -unused -unused -unused -unused -"Life is difficult for this enemy." -"This monster is too sensitive to fight..." -"Stereotypical: Curvaceously attractive, but no brains..." -"Don't pick on him."
"Family name: Eyewalker" -"Serving Size: 1 Monster"
"Not monitored by the USDA" -"It seems evil, but it's just with the wrong crowd..." -"This teen comedian fights to keep a captive audience." -"This teen wonders why it isn't named 'Ice Hat.'" -"Some teens "decorated" it as a prank." -"Easily excited by movement."
"Hobbies include: squirrels." -"DOGAMY: Husband of Dogaressa. Knows only what he smells."
"DOGARESSA: This puppy finds her hubby lovely. SMELLS ONLY?" -"Wields a stone dogger made of pomer-granite." -"It's so excited that it thinks fighting is just play." -"This seahorse has a lot of HP (Horsepower)." -"One size greater than Moldaverage." -"This humble germophobe seeks to cleanse the whole world." -"Loves to pet cute humans."
"But you're allergic!" -"Because they're a ghost, physical attacks will fail." -"Mistakenly believes its lava can heal people." -"Seems mean, but does it secretly like you?" -"This mischievous monster is never warm enough." -"Its future looks brighter and brighter." -"It finally stopped worrying." -"This relentless bully ALWAYS gets its way." -"This magical mercenary only says magic words." -"This megaton mercenary wields the Good Morningstar." -"It's unclear how many dogs this counts as." -unused -unused -unused -unused -unused -unused -unused -unused -unused -unused -unused -unused -unused -unused -unused -unused -unused -unused -unused -unused -unused -unused -unused -unused -unused -unused -unused -unused -unused -unused -unused -unused -unused -unused -comment -comment -comment -Keep talking to Undyne.
Meet at courtyard. -comment -comment -comment -comment -comment -Ruins (202),
Snowdin (203),
Waterfall (204),
Hotland (205) -comment -comment -comment -comment -comment -unused -unused -unused -unused -unused -unused -unused -unused -unused -unused -unused -unused -unused -unused -unused -monsterpopulation1: 20 -monsterpopulation2: 16 -monsterpopulation3: 18 -monsterpopulation4: 40 -comment -unused -unused -unused -unused -unused -unused -unused -unused -unused -unused -unused -unused -unused -unused -unused -unused -unused -unused -unused -unused -unused -unused -unused -unused -Nicecream Guy's outlook of his business will depend on your interactions with him. -comment -comment -Take pieces of the snowman to kill him. -comment -comment -comment -unused -unused -unused -Sans comments on it (0),
Nothing (1) ? affects Neutral Ending ? -Interact with the fake dog in the dev room. -Hotel Room (???) -Hotel Room (???) -Hotel Room (???) -MUST HAVE IT! (1),
meh (2),
meh (3),
meh (4),
meh (5),
meh (6),
meh (7),
meh (8) -comment -1 the first time you stay at the hotel,
2 if you stay at the hotel again. -unused -comment -Set when you slove the glowshroom puzzle in the mushrooms path near Temmie Village. -"it's a beautiful day outside."
"birds are singing, flowers are blooming..."
"on days like these, kids like you..."
"Should be burning in hell." -"if we're really friends..."
"you won't come back." -unused -unused -Walked past it (1),
stick gets snapped (2) -comment -comment -Affects a dialogue with Papyrus on the phone. -comment -comment -Kill (1),
Spare (2) -Spare (1),
Kill (2) -After the date, go in Papyrus' kitchen.
Prevents Glyde from appearing and affects the dialogue with Papyrus on the phone. -When Undyne throws her 100th spear, be in room_water8. -Something to do with the spear tile generation, but is unaccessed. -comment -Unclear specifics, but has to do with the amount of SMS you'll receive. -comment -comment -unused -unused -unused -unused -unused -unused -unused -unused -unused -unused -comment -comment -comment -comment -comment -comment -comment -comment -comment -comment -comment -comment -comment -comment -comment -comment -comment -comment -comment -comment -comment -comment -comment -comment -unused -unused -unused -unused -unused -unused -unused -unused -unused -unused -unused -unused -unused -unused -unused -unused -unused -unused -unused -unused -unused -unused -unused -unused -unused -unused -Kill (1),
Spare, but don't give water (2) -Equals to the HP Undyne died with.
Unaccessed. -"The heroine that NEVER gives up." -Affects the dialogue with Clamguy, creates a puddle after a while. -comment -No interaction (0),
Interract -> Punch (1),
Interract -> No punch (2).
Mad Dummy will comments on this before fighting. -comment -comment -comment -unused -Seems to affect the rain's rendering.
??? (0),
??? (1) -Seems to affect the rain's rendering.
??? (0.08) -Seems to affect the rain's rendering.
??? (0.08),
??? (0.5) -Seems to affect the rain's rendering.
??? (-1),
??? (272) -Seems to affect the rain's rendering.
??? (-1),
??? (273) -unused -comment -Reach the lab in a genocide run. -comment -comment -Enter a quick battle (i.e. lasers, spears). -comment -comment -comment -comment -comment -Unclear, seems to be used as a position variable. -comment -comment -comment -Buy a hot dog with no space in your inventory. -Buy a hot dog with 30 hot dogs on your head. -Increases after each use. Get's halved if Struggle 3 times, but only once. -Would you buy Muffet? I'd buy Muffet. -unused -1 if yellow button available,
2 if yellow button pressed. -Unclear specifics. -Win the ball game in an extremely short time. -Something to do with the fall animation. -??? (1),
??? (2),
??? (3),
House is on fire (4) -Unclear, but it seems to determine the sprite for Undyne's expression. -Fries (1),
Burger (2) ? Ketchup ? -unused -Internal to Madjick's battle. Something to do with Stick -unused -comment -"If she invites you to her parlor, excuse yourself." -comment -comment -comment -comment -Call Papyrus when the Royal Guards are in the room. Slightly affects the dialogue with the guards when you spare them. -Affects the dialogue during Papyrus' and Undyne's phone call. -Buy a 9999 gold spider bakery sale item. -Disable the third laser despite of Alphys' phone call. -Bratty and Catty's conversations. -comment -comment -comment -comment -unused -unused -unused -2 after you eat at the restaurant with Sans. -comment -comment -comment -comment -Pre-castle specific flags, seem to affect whether you can proceed or not and are naturally set as you progress. -Pre-castle specific flags, seem to affect whether you can proceed or not and are naturally set as you progress. -Pre-castle specific flags, seem to affect whether you can proceed or not and are naturally set as you progress. -Pre-castle specific flags, seem to affect whether you can proceed or not and are naturally set as you progress. -unused -comment -Turn available (1),
Already turned (2).
Propably used if Game Over during Mettaton battle. -1: kill Mettaton. -Incremental values: as you battle unique monsters in the core. -unused -unused -unused -Unclear, but it seems to determine the sprite for Alphy's expression. -Determines which direction the elevator will go. -comment -comment -Remebered the name (1),
Forgot the name (2). -Bought something (1),
Had a chat (2).
Propably about the origin of the name. -Burgerpants' MTT conversation. -Burgerpants' conversation about Bratty and Catty. -unused -unused -comment -comment -"An antique revolver."
"It has no ammo." -"This battle-worn hat makes you want to grow a beard." -"Unique"
"It is too bent to fit on your keychain." -"Huge steak in the shape of Mettaton's face."
Character names Drak, Gigi and Gugu changes Face Steak to FSteak. -unused -unused -unused -unused -comment -unused -comment -comment -comment -Seem to determine which step of the story to tell next. -comment -"A strange light fills the room."
"Twilight is shining through the barrier."
"It seems your journey is finally over."
"You're filled with DETERMINATION." -comment -Snowdin (1),
Waterfall (2),
Hotland (3) -About where to find Temmie Village -??? (0),
Temmie (1) -Allows the second part of the call to occur when calling twice.
Every room has two or more conversation parts. -unused -unused -After Undyne's date, calling Papyrus includes Undyne in the conversation. -unused -unused -unused -unused -Call Papyrus and Undyne in room_fire_lasers1.
Just a counter used for this specific call, allowing the third part to occur. -unused -unused -unused -unused -Not sure about this one. -comment -unused -unused -unused -comment -Various values.
Only affects what happens in the lab, used to progress through. -Various values.
Only affects what happens in the lab, used to progress through. -Various values.
Only affects what happens in the lab, used to progress through. -Various values.
Only affects what happens in the lab, used to progress through. -Various values.
Only affects what happens in the lab, used to progress through. -Various values.
Only affects what happens in the lab, used to progress through. -Various values.
Only affects what happens in the lab, used to progress through. -Various values.
Only affects what happens in the lab, used to progress through. -Various values.
Only affects what happens in the lab, used to progress through. -Various values.
Only affects what happens in the lab, used to progress through. -Various values.
Only affects what happens in the lab, used to progress through. -Various values.
Only affects what happens in the lab, used to progress through. -12 after you exit the true lab. -??? (1),
??? (2),
Letter EX (3) -comment -??? (1),
??? (2),
??? (3),
??? (4),
??? (5),
"I got nothing." (6),
??? (7?) -comment -unused -comment -comment -comment -fighting_asriel must be 1.
Can't die. -comment -unused -comment -comment -comment -comment -Sets the HP to decimal values. -2 if you complete the True Pacifist boss fight,
1 if you talk to Asriel in the ruins after the True Pacifist boss fight. -Progress through the conversation with Asriel in the ruins. -comment -comment -comment -comment -comment -comment -comment \ No newline at end of file diff --git a/strings/typefile b/strings/typefile deleted file mode 100644 index 96d33c2..0000000 --- a/strings/typefile +++ /dev/null @@ -1,549 +0,0 @@ -string -range -range -range -range -range -range -range -range -range -counter -range -iEdit -pEdit -iEdit -pEdit -iEdit -pEdit -iEdit -pEdit -iEdit -pEdit -iEdit -pEdit -iEdit -pEdit -iEdit -pEdit -iEdit -iEdit -bool -unused -unused -unused -bool -range -bool -bool -bool -unused -bool -bool -bool -bool -sEdit -bool -bool -unused -unused -unused -range -bool -sEdit -counter -counter -counter -range -bool -bool -bool -bool -bool -bool -bool -range -bool -bool -unused -unused -unused -counter -counter -bool -counter -counter -sEdit -sEdit -range -unused -unused -bool -counter -sEdit -sEdit -sEdit -sEdit -sEdit -sEdit -sEdit -range -range -unused -sEdit -counter -bool -bool -bool -sEdit -bool -bool -counter -unused -sEdit -bool -bool -range -sEdit -range -bool -bool -counter -sEdit -bool -bool -unused -bool -bool -unused -sEdit -sEdit -sEdit -bool -sEdit -sEdit -sEdit -bool -sEdit -bool -sEdit -counter -bool -bool -bool -bool -bool -bool -bool -bool -bool -bool -bool -bool -bool -bool -bool -bool -unused -unused -unused -unused -unused -unused -unused -unused -unused -unused -unused -unused -unused -unused -bool -bool -bool -bool -bool -bool -bool -bool -bool -bool -bool -bool -bool -bool -bool -bool -bool -bool -bool -bool -bool -bool -bool -bool -bool -bool -bool -unused -unused -unused -unused -unused -unused -unused -unused -unused -unused -unused -unused -unused -unused -unused -unused -unused -unused -unused -unused -unused -unused -unused -unused -unused -unused -unused -unused -unused -unused -unused -unused -unused -unused -counter -counter -counter -bool -counter -counter -counter -counter -counter -sEdit -counter -counter -counter -counter -counter -unused -unused -unused -unused -unused -unused -unused -unused -unused -unused -unused -unused -unused -unused -unused -bool -bool -bool -bool -bool -unused -unused -unused -unused -unused -unused -unused -unused -unused -unused -unused -unused -unused -unused -unused -unused -unused -unused -unused -unused -unused -unused -unused -unused -range -bool -bool -counter -bool -bool -bool -unused -unused -unused -bool -bool -bool -bool -bool -sEdit -range -sEdit -unused -bool -bool -bool -bool -unused -unused -sEdit -bool -bool -bool -bool -counter -sEdit -bool -bool -bool -range -counter -range -bool -bool -unused -unused -unused -unused -unused -unused -unused -unused -unused -unused -iEdit -iEdit -iEdit -iEdit -iEdit -iEdit -iEdit -iEdit -iEdit -iEdit -iEdit -iEdit -iEdit -iEdit -iEdit -iEdit -iEdit -iEdit -iEdit -iEdit -iEdit -iEdit -iEdit -iEdit -unused -unused -unused -unused -unused -unused -unused -unused -unused -unused -unused -unused -unused -unused -unused -unused -unused -unused -unused -unused -unused -unused -unused -unused -unused -unused -sEdit -range -bool -counter -counter -sEdit -bool -counter -counter -unused -range -range -range -range -range -unused -bool -bool -bool -counter -bool -bool -bool -bool -bool -bool -range -bool -range -counter -counter -bool -range -range -unused -sEdit -range -bool -range -sEdit -range -sEdit -unused -range -unused -counter -bool -bool -range -bool -bool -bool -bool -bool -bool -counter -counter -counter -counter -bool -unused -unused -unused -sEdit -bool -bool -bool -bool -range -range -range -range -unused -counter -sEdit -bool -counter -unused -unused -unused -range -bool -bool -bool -sEdit -sEdit -counter -counter -unused -unused -counter -counter -bool -bool -bool -bool -unused -unused -unused -unused -counter -unused -bool -bool -bool -range -range -bool -bool -sEdit -bool -bool -range -unused -unused -bool -unused -unused -unused -unused -bool -unused -unused -unused -unused -bool -bool -unused -unused -unused -bool -range -range -range -range -range -range -range -range -range -range -range -range -sEdit -sEdit -counter -sEdit -bool -unused -bool -bool -counter -bool -bool -unused -bool -bool -bool -bool -bool -sEdit -counter -range -range -range -range -range -sEdit -timer \ No newline at end of file diff --git a/strings/undertale.ini b/strings/undertale.ini deleted file mode 100644 index 20846f0..0000000 --- a/strings/undertale.ini +++ /dev/null @@ -1,54 +0,0 @@ -[Alphys] -AD="1.000000" -[FFFFF] -E="0.000000" -F="0.000000" -P="7.000000" -[MTT] -EssayNo="1.000000" -[Papyrus] -M1="1.000000" -PD="1.000000" -PS="1.000000" -PK="1.000000" -[Flowey] -AF="1.000000" -EX="5.000000" -Met1="1.000000" -NK="1.000000" -truename="1.000000" -alter2="1.000000" -[General] -Fun="42.000000" -Kills="0.000000" -Love="1.000000" -Name="Chara" -Room="236.000000" -Tale="1.000000" -Time="3674831.000000" -Won="7.000000" -[Toriel] -Bscotch="2.000000" -TS="1.000000" -TK="1.000000" -[Sans] -EndMet="1.000000" -M1="1.000000" -MeetLv1="7.000000" -Pass="3.000000" -MP="1.000000" -F="1.000000" -Intro="1.000000" -SK="1.000000" -[Undyne] -UD="1.000000" -[Mett] -O="1.000000" -[Mettaton] -BossMet="1.000000" -[F7] -F7="1.000000" -[reset] -s_key="1.000000" -[EndF] -EndF="2.000000" \ No newline at end of file diff --git a/tools.cpp b/tools.cpp new file mode 100644 index 0000000..8c476dc --- /dev/null +++ b/tools.cpp @@ -0,0 +1,2134 @@ +#include "tools.h" + +#include + +CustomLineEdit::CustomLineEdit(int id, MainWindow *mainWindow, QWidget *parent) : QLineEdit(parent), id(id), mw(mainWindow) +{ + switch (id) + { + case 1: + setToolTip(tr("if length of the name is >=7 add text \"Easy to change, huh?\" next to the name")); + break; + } + + connect(this, SIGNAL(textEdited(QString)), this, SLOT(updateSave(QString))); + connect(mw, SIGNAL(updateWidgets()), this, SLOT(updateData())); + connect(this, SIGNAL(dataChanged(bool)), mw, SLOT(fileModified(bool))); +} +void CustomLineEdit::updateSave(QString text) +{ + mw->saveData.replace(id, text); + emit dataChanged(true); +} +void CustomLineEdit::updateData() +{ + setText(mw->saveData.at(id)); +} + +CustomComboBox::CustomComboBox(int id, MainWindow *mainWindow, QWidget *parent) : QComboBox(parent), id(id), mw(mainWindow) +{ + switch (id) + { + case 45: + addItem(tr("Fled")); + values.append(0); + indexes.insert(0, 0); + addItem(tr("Killed")); + values.append(1); + indexes.insert(1, 1); + addItem(tr("Spared")); + values.append(2); + indexes.insert(2, 2); + addItem(tr("Bored")); + values.append(3); + indexes.insert(3, 3); + + setToolTip(tr("set to \"%1\", if bored a monster in Ruins.\n" + "changes what Mad Dummy says").arg(itemText(3))); + break; + case 53: + addItem(tr("Yellow")); + values.append(0); + indexes.insert(0, 0); + addItem(tr("White")); + values.append(1); + indexes.insert(1, 1); + addItem(tr("Pink")); + values.append(2); + indexes.insert(2, 2); + + setToolTip(tr("if not \"%1\", there will be a pile of yellow names in the trash").arg(itemText(0))); + break; + case 65: + addItem(tr("No candy taken")); + values.append(0); + indexes.insert(0, 0); + addItem(tr("\"You took a piece of candy.\"")); + values.append(1); + indexes.insert(1, 1); + addItem(tr("\"You took more candy.\"")); + values.append(2); + indexes.insert(2, 2); + addItem(tr("\"You take another piece.\"")); + values.append(3); + indexes.insert(3, 3); + addItem(tr("\"You took too much too fast.\"")); + values.append(4); + indexes.insert(4, 4); + + setToolTip(tr("")); + break; + case 67: + addItem(tr("Blocking the way")); + values.append(0); + indexes.insert(0, 0); + addItem(tr("Not blocking the way")); + values.append(1); + indexes.insert(1, 1); + addItem(tr("Talked to in a pit")); + values.append(2); + indexes.insert(2, 2); + + setToolTip(tr("")); + break; + case 68: + addItem(tr("Phone not kidnapped")); + values.append(0); + indexes.insert(0, 0); + addItem(tr("Phone kidnapped")); + values.append(1); + indexes.insert(1, 1); + addItem(tr("\"My apologies. A strange dog kidnapped my phone.\"")); + values.append(2); + indexes.insert(2, 2); + + setToolTip(tr("")); + break; + case 76: + addItem(tr("Arrived at \"Home\"")); + values.append(0); + indexes.insert(0, 0); + addItem(tr("Tried to exit Ruins")); + values.append(1); + indexes.insert(1, 1); + addItem(tr("Fought")); + values.append(3); + indexes.insert(3, 2); + addItem(tr("Killed")); + values.append(4); + indexes.insert(4, 3); + addItem(tr("Spared")); + values.append(5); + indexes.insert(5, 4); + + setToolTip(tr("")); + break; + case 77: + addItem(tr("Cinnamon")); + values.append(0); + indexes.insert(0, 0); + addItem(tr("Butterscotch")); + values.append(1); + indexes.insert(1, 1); + + setToolTip(tr("")); + break; + case 78: + addItem(tr("Reached the bridge")); + values.append(-1); + indexes.insert(-1, 0); + addItem(tr("Not reached")); + values.append(0); + indexes.insert(0, 1); + addItem(tr("Stick breaks")); + values.append(2); + indexes.insert(2, 3); + addItem(tr("Dark sans appears")); + values.append(3); + indexes.insert(3, 4); + + setToolTip(tr("")); + break; + case 83: + addItem(tr("Spared")); + values.append(0); + indexes.insert(0, 0); + addItem(tr("Killed")); + values.append(1); + indexes.insert(1, 1); + addItem(tr("Used Stick")); + values.append(2); + indexes.insert(2, 2); + + setToolTip(tr("")); + break; + case 84: + addItem(tr("Spared")); + values.append(0); + indexes.insert(0, 0); + addItem(tr("Killed")); + values.append(1); + indexes.insert(1, 1); + addItem(tr("Used Stick")); + values.append(2); + indexes.insert(2, 2); + + setToolTip(tr("")); + break; + case 85: + addItem(tr("Spared")); + values.append(0); + indexes.insert(0, 0); + addItem(tr("Killed")); + values.append(1); + indexes.insert(1, 1); + addItem(tr("Used Stick")); + values.append(2); + indexes.insert(2, 2); + addItem(tr("Bored")); + values.append(3); + indexes.insert(3, 3); + + setToolTip(tr("")); + break; + case 86: + addItem(tr("Spared")); + values.append(0); + indexes.insert(0, 0); + addItem(tr("Killed")); + values.append(1); + indexes.insert(1, 1); + addItem(tr("Petted")); + values.append(2); + indexes.insert(2, 2); + + setToolTip(tr("")); + break; + case 87: + addItem(tr("No interaction")); + values.append(0); + indexes.insert(0, 0); + addItem(tr("Got a piece")); + values.append(1); + indexes.insert(1, 1); + addItem(tr("Got another piece")); + values.append(2); + indexes.insert(2, 2); + addItem(tr("Ate the piece in front of him")); + values.append(4); + indexes.insert(4, 3); + addItem(tr("Spoke with after eating a piece")); + values.append(5); + indexes.insert(5, 4); + + setToolTip(tr("")); + break; + case 88: + addItem(tr("Not encountered")); + values.append(0); + indexes.insert(0, 0); + addItem(tr("Laughed at jokes")); + values.append(1); + indexes.insert(1, 1); + addItem(tr("Killed")); + values.append(2); + indexes.insert(2, 2); + + setToolTip(tr("if \"%1\", Chilldrakes will show up").arg(itemText(2))); + break; + case 89: + addItem(tr("Junior Jumble")); + values.append(0); + indexes.insert(0, 0); + addItem(tr("Crossword")); + values.append(1); + indexes.insert(1, 1); + + setToolTip(tr("")); + break; + case 93: + addItem(tr("Not set")); + values.append(0); + indexes.insert(0, 0); + addItem(tr("Ate it")); + values.append(1); + indexes.insert(1, 1); + addItem(tr("Left it")); + values.append(2); + indexes.insert(2, 2); + + setToolTip(tr("")); + break; + case 95: + addItem(tr("Not pressed")); + values.append(-1); + indexes.insert(-1, 0); + addItem(tr("Available")); + values.append(0); + indexes.insert(0, 1); + addItem(tr("Pressed")); + values.append(1); + indexes.insert(1, 2); + + setToolTip(tr("")); + break; + case 98: + addItem(tr("Captured you thrice")); + values.append(-3); + indexes.insert(-3, 0); + addItem(tr("Captured you twice")); + values.append(-2); + indexes.insert(-2, 1); + addItem(tr("Captured you")); + values.append(-1); + indexes.insert(-1, 2); + addItem(tr("Spared")); + values.append(0); + indexes.insert(0, 3); + addItem(tr("Killed")); + values.append(1); + indexes.insert(1, 4); + + setToolTip(tr("if \"%1\", skip Papyrus's battle").arg(itemText(0))); + break; + case 103: + addItem(tr("Not visited")); + values.append(0); + indexes.insert(0, 0); + addItem(tr("Paid 80G")); + values.append(1); + indexes.insert(1, 1); + addItem(tr("Stayed for free")); + values.append(2); + indexes.insert(2, 2); + + setToolTip(tr("")); + break; + case 106: + addItem(tr("Not reached")); + values.append(0); + indexes.insert(0, 0); + addItem(tr("Bandage")); + values.append(4); + indexes.insert(4, 1); + addItem(tr("Faded Ribbon")); + values.append(12); + indexes.insert(12, 2); + addItem(tr("Manly Bandanna")); + values.append(15); + indexes.insert(15, 3); + addItem(tr("Old Tutu")); + values.append(24); + indexes.insert(24, 4); + + setToolTip(tr("")); + break; + case 108: + addItem(tr("Not reached")); + values.append(0); + indexes.insert(0, 0); + addItem(tr("Bandage")); + values.append(4); + indexes.insert(4, 1); + addItem(tr("Faded Ribbon")); + values.append(12); + indexes.insert(12, 2); + addItem(tr("Manly Bandanna")); + values.append(15); + indexes.insert(15, 3); + addItem(tr("Old Tutu")); + values.append(24); + indexes.insert(24, 4); + + setToolTip(tr("")); + break; + case 112: + addItem(tr("Not encountered")); + values.append(0); + indexes.insert(0, 0); + addItem(tr("Killed")); + values.append(1); + indexes.insert(1, 1); + addItem(tr("Had a musical career")); + values.append(2); + indexes.insert(2, 2); + + setToolTip(tr("if \"%1\", you'll know the song for Knight Knight and Lemon Bread").arg(itemText(2))); + break; + case 119: + addItem(tr("No date")); + values.append(0); + indexes.insert(0, 0); + addItem(tr("Outside the house")); + values.append(1); + indexes.insert(1, 1); + addItem(tr("Inside the house")); + values.append(2); + indexes.insert(2, 2); + addItem(tr("Unlock Papyrus's room")); + values.append(3); + indexes.insert(3, 3); + addItem(tr("Date complete")); + values.append(4); + indexes.insert(4, 4); + + setToolTip(tr("")); + break; + case 120: + addItem(tr("No date")); + values.append(0); + indexes.insert(0, 0); + addItem(tr("Date started")); + values.append(1); + indexes.insert(1, 1); + addItem(tr("Date complete")); + values.append(2); + indexes.insert(2, 2); + + setToolTip(tr("")); + break; + case 121: + addItem(tr("Not met")); + values.append(0); + indexes.insert(0, 0); + addItem(tr("\"You can't hold an umbrella either?\"")); + values.append(1); + indexes.insert(1, 1); + addItem(tr("\"You got us an umbrella?\"")); + values.append(2); + indexes.insert(2, 2); + addItem(tr("\"Where's the umbrella...?\"")); + values.append(3); + indexes.insert(3, 3); + + setToolTip(tr("")); + break; + case 122: + addItem(tr("Not met")); + values.append(0); + indexes.insert(0, 0); + addItem(tr("Talked about Undyne")); + values.append(1); + indexes.insert(1, 1); + addItem(tr("Talked about a school project")); + values.append(3); + indexes.insert(3, 2); + addItem(tr("Talked about teachers")); + values.append(4); + indexes.insert(4, 3); + addItem(tr("Staring at the castle in the distance")); + values.append(6); + indexes.insert(6, 4); + addItem(tr("Helped you climb over a ledge")); + values.append(10); + indexes.insert(10, 5); + + setToolTip(tr("this value is also used for \"Interacted with Trash Zone SAVE Point\"-entry")); + break; + case 124: + addItem(tr("No date")); + values.append(0); + indexes.insert(0, 0); + addItem(tr("Chatted in the house")); + values.append(1); + indexes.insert(1, 1); + addItem(tr("Lied on the ground")); + values.append(3); + indexes.insert(3, 2); + addItem(tr("Didn't lie on the ground")); + values.append(9); + indexes.insert(9, 3); + + setToolTip(tr("")); + break; + case 125: + addItem(tr("Not playing")); + values.append(0); + indexes.insert(0, 0); + addItem(tr("Spooktunes")); + values.append(1); + indexes.insert(1, 1); + addItem(tr("Spookwave")); + values.append(2); + indexes.insert(2, 2); + addItem(tr("Ghouliday Music")); + values.append(3); + indexes.insert(3, 3); + + setToolTip(tr("")); + break; + case 127: + addItem(tr("\"That emblem\"")); + values.append(0); + indexes.insert(0, 0); + addItem(tr("\"Emblem's meaning (NEW)\"")); + values.append(1); + indexes.insert(1, 1); + addItem(tr("\"The prophecy (NEW)\"")); + values.append(2); + indexes.insert(2, 2); + addItem(tr("\"The prophecy\"")); + values.append(3); + indexes.insert(3, 3); + + setToolTip(tr("")); + break; + case 129: + addItem(tr("You ran away")); + values.append(0); + indexes.insert(0, 0); + addItem(tr("You helped Monster Kid")); + values.append(1); + indexes.insert(1, 1); + addItem(tr("You stood and watched")); + values.append(2); + indexes.insert(2, 2); + + setToolTip(tr("")); + break; + case 134: + addItem(tr("Pie is cooling")); + values.append(0); + indexes.insert(0, 0); + addItem(tr("Pie is ready")); + values.append(1); + indexes.insert(1, 1); + addItem(tr("Got a slice")); + values.append(2); + indexes.insert(2, 2); + + setToolTip(tr("")); + break; + case 138: + addItem(tr("\"It's a legendary artifact.\"")); + values.append(0); + indexes.insert(0, 0); + addItem(tr("\"The artifact is gone.\"")); + values.append(1); + indexes.insert(1, 1); + addItem(tr("\"You're carrying too many dogs.\"")); + values.append(2); + indexes.insert(2, 2); + + setToolTip(tr("")); + break; + case 139: + addItem(tr("Not checked the cooler")); + values.append(0); + indexes.insert(0, 0); + addItem(tr("Two food bars available")); + values.append(1); + indexes.insert(1, 1); + addItem(tr("One food bar available")); + values.append(2); + indexes.insert(2, 2); + addItem(tr("The cooler is empty")); + values.append(3); + indexes.insert(3, 3); + + setToolTip(tr("")); + break; + case 284: + addItem(tr("\"Hello. I am a snowman. I cannot move.\"")); + values.append(0); + indexes.insert(0, 0); + addItem(tr("\"Soon there won't be any of me left...\"")); + values.append(1); + indexes.insert(1, 1); + addItem(tr("\"Stop... Please...\"")); + values.append(2); + indexes.insert(2, 2); + addItem(tr("(A useless pile of snow.)")); + values.append(3); + indexes.insert(3, 3); + + setToolTip(tr("")); + break; + case 298: + addItem(tr("Not stayed")); + values.append(0); + indexes.insert(0, 0); + addItem(tr("First time")); + values.append(1); + indexes.insert(1, 1); + addItem(tr("Second time")); + values.append(2); + indexes.insert(2, 2); + + setToolTip(tr("")); + break; + case 306: + addItem(tr("No action")); + values.append(0); + indexes.insert(0, 0); + addItem(tr("Heavy stick is broken")); + values.append(1); + indexes.insert(1, 1); + addItem(tr("Shadow appeared")); + values.append(2); + indexes.insert(2, 2); + + setToolTip(tr("")); + break; + case 311: + addItem(tr("Not talked")); + values.append(0); + indexes.insert(0, 0); + addItem(tr("Talked")); + values.append(1); + indexes.insert(1, 1); + addItem(tr("Tried to push box")); + values.append(2); + indexes.insert(2, 2); + + setToolTip(tr("")); + break; + case 312: + addItem(tr("Not encountered")); + values.append(0); + indexes.insert(0, 0); + addItem(tr("Killed")); + values.append(1); + indexes.insert(1, 1); + addItem(tr("Spared")); + values.append(2); + indexes.insert(2, 2); + + setToolTip(tr("")); + break; + case 381: + addItem(tr("Given water")); + values.append(0); + indexes.insert(0, 0); + addItem(tr("Killed")); + values.append(1); + indexes.insert(1, 1); + addItem(tr("Spared, but no water")); + values.append(2); + indexes.insert(2, 2); + + setToolTip(tr("")); + break; + case 385: + addItem(tr("No call")); + values.append(0); + indexes.insert(0, 0); + addItem(tr("Unknown")); + values.append(1); + indexes.insert(1, 1); + addItem(tr("Called")); + values.append(2); + indexes.insert(2, 2); + + setToolTip(tr("")); + break; + case 386: + addItem(tr("No interaction")); + values.append(0); + indexes.insert(0, 0); + addItem(tr("Punched the dummy")); + values.append(1); + indexes.insert(1, 1); + addItem(tr("Stared for a moment")); + values.append(2); + indexes.insert(2, 2); + + setToolTip(tr("Mad Dummy will comment on this before fighting")); + break; + case 416: + addItem(tr("Not available")); + values.append(0); + indexes.insert(0, 0); + addItem(tr("Available")); + values.append(1); + indexes.insert(1, 1); + addItem(tr("Activated")); + values.append(2); + indexes.insert(2, 2); + + setToolTip(tr("")); + break; + case 420: + addItem(tr("No date")); + values.append(0); + indexes.insert(0, 0); + addItem(tr("Talking outside")); + values.append(3); + indexes.insert(3, 1); + addItem(tr("Running to Papyrus's place")); + values.append(4); + indexes.insert(4, 2); + addItem(tr("Arrived at Papyrus's place")); + values.append(5); + indexes.insert(5, 3); + + setToolTip(tr("")); + break; + case 422: + addItem(tr("Nothing")); + values.append(0); + indexes.insert(0, 0); + addItem(tr("Fries")); + values.append(1); + indexes.insert(1, 1); + addItem(tr("Burger")); + values.append(2); + indexes.insert(2, 2); + + setToolTip(tr("")); + break; + case 427: + addItem(tr("\"Did you hear what they said?\"")); + values.append(0); + indexes.insert(0, 0); + addItem(tr("\"They said a human wearing a striped shirt...\"")); + values.append(1); + indexes.insert(1, 1); + addItem(tr("\"I heard that they hate spiders.\"")); + values.append(2); + indexes.insert(2, 2); + addItem(tr("\"I heard that they love to stomp on them.\"")); + values.append(3); + indexes.insert(3, 3); + addItem(tr("\"I heard that they like to tear their legs off.\"")); + values.append(4); + indexes.insert(4, 4); + addItem(tr("\"I heard...\"")); + values.append(5); + indexes.insert(5, 5); + + setToolTip(tr("")); + break; + case 429: + addItem(tr("Left Floor 1")); + values.append(0); + indexes.insert(0, 0); + addItem(tr("Right Floor 1")); + values.append(1); + indexes.insert(1, 1); + addItem(tr("Right Floor 2")); + values.append(2); + indexes.insert(2, 2); + addItem(tr("Left Floor 2")); + values.append(3); + indexes.insert(3, 3); + addItem(tr("Left Floor 3")); + values.append(4); + indexes.insert(4, 4); + addItem(tr("Right Floor 3")); + values.append(5); + indexes.insert(5, 5); + + setToolTip(tr("")); + break; + case 436: + addItem(tr("\"About your wares\"")); + values.append(0); + indexes.insert(0, 0); + addItem(tr("\"Origin of wares (NEW)\"")); + values.append(1); + indexes.insert(1, 1); + addItem(tr("\"Origin of garbage (NEW)\"")); + values.append(2); + indexes.insert(2, 2); + addItem(tr("\"Origin of garbage\"")); + values.append(3); + indexes.insert(3, 3); + + setToolTip(tr("")); + break; + case 437: + addItem(tr("\"About Mettaton\"")); + values.append(0); + indexes.insert(0, 0); + addItem(tr("\"Origin of Mettaton (NEW)\"")); + values.append(1); + indexes.insert(1, 1); + addItem(tr("\"About Mettaton (OLD?\?\?)\"")); + values.append(2); + indexes.insert(2, 2); + + setToolTip(tr("")); + break; + case 438: + addItem(tr("\"About Alphys\"")); + values.append(0); + indexes.insert(0, 0); + addItem(tr("\"Royal Scientist (NEW)\"")); + values.append(1); + indexes.insert(1, 1); + addItem(tr("\"About ASGORE (NEW)\"")); + values.append(2); + indexes.insert(2, 2); + addItem(tr("\"About ASGORE\"")); + values.append(3); + indexes.insert(3, 3); + + setToolTip(tr("")); + break; + case 444: + addItem(tr("No Date")); + values.append(0); + indexes.insert(0, 0); + addItem(tr("Date started")); + values.append(1); + indexes.insert(1, 1); + addItem(tr("Date complete")); + values.append(2); + indexes.insert(2, 2); + + setToolTip(tr("")); + break; + case 452: + addItem(tr("Not reached")); + values.append(0); + indexes.insert(0, 0); + addItem(tr("Whimsalot and Final Froggit")); + values.append(1); + indexes.insert(1, 1); + addItem(tr("Knight Knight and Madjick")); + values.append(2); + indexes.insert(2, 2); + addItem(tr("Final Froggit, Astigmatism and Whimsalot")); + values.append(3); + indexes.insert(3, 3); + + setToolTip(tr("")); + break; + case 455: + addItem(tr("Not encountered")); + values.append(0); + indexes.insert(0, 0); + addItem(tr("Can be exposed")); + values.append(1); + indexes.insert(1, 1); + addItem(tr("Switch exposed")); + values.append(2); + indexes.insert(2, 2); + + setToolTip(tr("")); + break; + case 462: + addItem(tr("Core")); + values.append(0); + indexes.insert(0, 0); + addItem(tr("Castle")); + values.append(1); + indexes.insert(1, 1); + + setToolTip(tr("")); + break; + case 465: + addItem(tr("Not talked")); + values.append(0); + indexes.insert(0, 0); + addItem(tr("Remembered the name")); + values.append(1); + indexes.insert(1, 1); + addItem(tr("Forgot the name")); + values.append(2); + indexes.insert(2, 2); + + setToolTip(tr("")); + break; + case 466: + addItem(tr("Not talked")); + values.append(0); + indexes.insert(0, 0); + addItem(tr("Bought something")); + values.append(1); + indexes.insert(1, 1); + addItem(tr("Talked")); + values.append(2); + indexes.insert(2, 2); + + setToolTip(tr("")); + break; + case 467: + addItem(tr("\"Mettaton\"")); + values.append(0); + indexes.insert(0, 0); + addItem(tr("\"Why is Mettaton bad (NEW)\"")); + values.append(1); + indexes.insert(1, 1); + addItem(tr("\"Why else is MTT bad (NEW)\"")); + values.append(2); + indexes.insert(2, 2); + addItem(tr("\"Why else is MTT bad\"")); + values.append(3); + indexes.insert(3, 3); + + setToolTip(tr("")); + break; + case 468: // TEST + addItem(tr("[B.Pants] \"Romance Advice\"")); + values.append(0); + indexes.insert(0, 0); + addItem(tr("[B.Pants] \"Glamburger Story (NEW)\"")); + values.append(1); + indexes.insert(1, 1); + addItem(tr("[B&C] \"Burgerpants (NEW)\"")); + values.append(2); + indexes.insert(2, 2); + addItem(tr("[B&C] \"More Burgerpants (NEW)\"")); + values.append(4); + indexes.insert(4, 3); + addItem(tr("[B.Pants] \"Bratty & Catty (NEW)\"")); + values.append(5); + indexes.insert(5, 4); + addItem(tr("[B&C] \"Burgerpants hangout (NEW)\"")); + values.append(6); + indexes.insert(6, 5); + addItem(tr("[B&C] \"That kind of guy (NEW)\"")); + values.append(7); + indexes.insert(7, 6); + addItem(tr("[B.Pants] \"Catty's Invitation (NEW)\"")); + values.append(8); + indexes.insert(8, 7); + addItem(tr("[B.Pants] \"Catty's Invitation\"")); + values.append(9); + indexes.insert(9, 8); + + setToolTip(tr("The conversation takes place in two shops [marked in square brackets]")); + break; + case 481: + addItem(tr("\"A long time ago, a human fell into the RUINS.\"")); + values.append(0); + indexes.insert(0, 0); + addItem(tr("\"ASRIEL, the king's son, heard the human's call.\"")); + values.append(1); + indexes.insert(1, 1); + addItem(tr("\"Over time, ASRIEL and the human became like siblings.\"")); + values.append(2); + indexes.insert(2, 2); + addItem(tr("\"Then... One day...\"")); + values.append(3); + indexes.insert(3, 3); + addItem(tr("\"The sick human had only one request.\"")); + values.append(4); + indexes.insert(4, 4); + addItem(tr("\"The next day.\"")); + values.append(5); + indexes.insert(5, 5); + addItem(tr("\"ASRIEL, wracked with grief, absorbed the human's SOUL.\"")); + values.append(6); + indexes.insert(6, 6); + addItem(tr("\"With the human SOUL, ASRIEL crossed through the barrier.\"")); + values.append(7); + indexes.insert(7, 7); + addItem(tr("\"ASRIEL reached the center of the village.\"")); + values.append(8); + indexes.insert(8, 8); + addItem(tr("\"Suddenly, screams rang out.\"")); + values.append(9); + indexes.insert(9, 9); + addItem(tr("\"The humans attacked him with everything they had.\"")); + values.append(10); + indexes.insert(10, 10); + addItem(tr("\"But...\"")); + values.append(11); + indexes.insert(11, 11); + addItem(tr("\"Wounded, ASRIEL stumbled home.\"")); + values.append(12); + indexes.insert(12, 12); + addItem(tr("\"The kingdom fell into despair.\"")); + values.append(13); + indexes.insert(13, 13); + addItem(tr("\"The king decided it was time to end our suffering.\"")); + values.append(14); + indexes.insert(14, 14); + addItem(tr("\"It's not long now.\"")); + values.append(15); + indexes.insert(15, 15); + addItem(tr("\"You should be smiling, too.\"")); + values.append(16); + indexes.insert(16, 16); + addItem(tr("\"You're going to be free.\"")); + values.append(17); + indexes.insert(17, 17); + + setToolTip(tr("")); + break; + case 485: + addItem(tr("(The way is blocked by two padlocks.)")); + values.append(0); + indexes.insert(0, 0); + addItem(tr("(You'll need both keys to get through.)")); + values.append(0.5); + indexes.insert(0.5, 1); + addItem(tr("(You unlocked the chain.)")); + values.append(1); + indexes.insert(1, 2); + + setToolTip(tr("")); + break; + case 490: + addItem(tr("Hotland")); + values.append(0); + indexes.insert(0, 0); + addItem(tr("Snowdin")); + values.append(1); + indexes.insert(1, 1); + addItem(tr("Waterfall")); + values.append(2); + indexes.insert(2, 2); + addItem(tr("Hotland")); + values.append(3); + indexes.insert(3, 3); + + setToolTip(tr("")); + break; + case 512: + addItem(tr("Need to find it")); + values.append(0); + indexes.insert(0, 0); + addItem(tr("Found it in the sink")); + values.append(1); + indexes.insert(1, 1); + addItem(tr("(You put it on your keychain.)")); + values.append(2); + indexes.insert(2, 2); + addItem(tr("(The red switch has been turned on.)")); + values.append(3); + indexes.insert(3, 3); + + setToolTip(tr("")); + break; + case 513: + addItem(tr("Need to find it")); + values.append(0); + indexes.insert(0, 0); + addItem(tr("Found it in the refrigerator")); + values.append(1); + indexes.insert(1, 1); + addItem(tr("(You put it on your keychain.)")); + values.append(2); + indexes.insert(2, 2); + addItem(tr("(The blue switch has been turned on.)")); + values.append(3); + indexes.insert(3, 3); + + setToolTip(tr("")); + break; + case 514: + addItem(tr("Need to find it")); + values.append(0); + indexes.insert(0, 0); + addItem(tr("Found it in the bathtub")); + values.append(1); + indexes.insert(1, 1); + addItem(tr("(You put it on your keychain.)")); + values.append(2); + indexes.insert(2, 2); + addItem(tr("(The green switch has been turned on.)")); + values.append(3); + indexes.insert(3, 3); + + setToolTip(tr("")); + break; + case 515: + addItem(tr("Need to find it")); + values.append(0); + indexes.insert(0, 0); + addItem(tr("Found it under the bedsheets")); + values.append(1); + indexes.insert(1, 1); + addItem(tr("(You put it on your keychain.)")); + values.append(2); + indexes.insert(2, 2); + addItem(tr("(The yellow switch has been turned on.)")); + values.append(3); + indexes.insert(3, 3); + + setToolTip(tr("")); + break; + case 518: + addItem(tr("Not checked any sink")); + values.append(0); + indexes.insert(0, 0); + addItem(tr("The left sink")); + values.append(1); + indexes.insert(1, 1); + addItem(tr("The middle sink")); + values.append(2); + indexes.insert(2, 2); + addItem(tr("The right sink")); + values.append(3); + indexes.insert(3, 3); + + setToolTip(tr("")); + break; + case 524: + addItem(tr("No interaction")); + values.append(0); + indexes.insert(0, 0); + addItem(tr("Undyne's Letter is available")); + values.append(8); + indexes.insert(8, 1); + addItem(tr("Got Undyne's Letter")); + values.append(9); + indexes.insert(9, 2); + addItem(tr("Date complete")); + values.append(10); + indexes.insert(10, 3); + addItem(tr("Received a call from Papyrus")); + values.append(11); + indexes.insert(11, 4); + addItem(tr("Completed the True Lab")); + values.append(12); + indexes.insert(12, 5); + + setToolTip(tr("")); + break; + case 525: + addItem(tr("No interaction")); + values.append(0); + indexes.insert(0, 0); + addItem(tr("Lost the letter")); + values.append(1); + indexes.insert(1, 1); + addItem(tr("Undyne's Letter")); + values.append(2); + indexes.insert(2, 2); + addItem(tr("Undyne's Letter EX")); + values.append(3); + indexes.insert(3, 3); + + setToolTip(tr("")); + break; + case 527: + addItem(tr("Onionsan doesn't want to talk")); + values.append(-1); + indexes.insert(-1, 0); + addItem(tr("No interaction")); + values.append(0); + indexes.insert(0, 1); + addItem(tr("\"I'm Onionsan!\"")); + values.append(1); + indexes.insert(1, 2); + addItem(tr("\"You're visiting Waterfall, huh!\"")); + values.append(2); + indexes.insert(2, 3); + addItem(tr("\"Even though, the water's getting so shallow here...\"")); + values.append(3); + indexes.insert(3, 4); + addItem(tr("\"Undyne's gonna fix everything, y'hear!\"")); + values.append(4); + indexes.insert(4, 5); + addItem(tr("\"That's the end of this room.\"")); + values.append(5); + indexes.insert(5, 6); + addItem(tr("\"Yeah, me too...\"")); + values.append(6); + indexes.insert(6, 7); + addItem(tr("\"I've been wondering when we're all gonna go free.\"")); + values.append(7); + indexes.insert(7, 8); + + setToolTip(tr("")); + break; + case 528: + addItem(tr("Haven't got the key")); + values.append(0); + indexes.insert(0, 0); + addItem(tr("Got the key")); + values.append(1); + indexes.insert(1, 1); + addItem(tr("Entered sans's room")); + values.append(2); + indexes.insert(2, 2); + addItem(tr("Found the silver key")); + values.append(3); + indexes.insert(3, 3); + + setToolTip(tr("")); + break; + case 532: + addItem(tr("Not Reached")); + values.append(0); + indexes.insert(0, 0); + addItem(tr("Save everyone")); + values.append(1); + indexes.insert(1, 1); + addItem(tr("Save someone else")); + values.append(2); + indexes.insert(2, 2); + addItem(tr("Save Asriel")); + values.append(3); + indexes.insert(3, 3); + + setToolTip(tr("")); + break; + case 540: + addItem(tr("Normal")); + values.append(0); + indexes.insert(0, 0); + addItem(tr("\"00.001\"")); + values.append(1); + indexes.insert(1, 1); + addItem(tr("\"00.0001\"")); + values.append(2); + indexes.insert(2, 2); + addItem(tr("\"00.000001\"")); + values.append(3); + indexes.insert(3, 3); + addItem(tr("\"00.0000000001\"")); + values.append(4); + indexes.insert(4, 4); + + setToolTip(tr("")); + break; + case 541: + addItem(tr("Not reached")); + values.append(0); + indexes.insert(0, 0); + addItem(tr("Talked with child Asriel")); + values.append(1); + indexes.insert(1, 1); + addItem(tr("Talked with everyone")); + values.append(2); + indexes.insert(2, 2); + + setToolTip(tr("")); + break; + } + + connect(this, SIGNAL(currentIndexChanged(int)), this, SLOT(updateSave(int))); + connect(mw, SIGNAL(updateWidgets()), this, SLOT(updateData())); + connect(this, SIGNAL(dataChanged(bool)), mw, SLOT(fileModified(bool))); +} +void CustomComboBox::updateSave(int i) +{ + mw->saveData.replace(id, QString::number(values[i])); + emit dataChanged(true); +} +void CustomComboBox::updateData() +{ + setCurrentIndex(indexes.value(mw->saveData.at(id).toInt())); +} + +CustomSpinBox::CustomSpinBox(int id, MainWindow *mainWindow, QWidget *parent) : QSpinBox(parent), id(id), mw(mainWindow) +{ + setRange(INT_MIN, INT_MAX); + switch (id) + { + case 2: + setRange(1, 20); + break; + case 10: + setMaximum(99999); + break; + case 56: + setToolTip(tr("if this is >5, remove a frog from the \"four frog\" room")); + break; + case 71: + setToolTip(tr("if this is >=4, Toriel's reaction stays the same")); + break; + case 74: + setToolTip(tr("if this is >25, you'll make the switches uncomfortable")); + break; + case 75: + setToolTip(tr("if this is >9, Toriel's reaction stays the same")); + break; + case 82: + setToolTip(tr("if this is 2, you'll get a hint about the blue switch in the second room")); + break; + case 90: + setToolTip(tr("if this is >= 9000, skip Muffet battle\n" + "checked values during battle: >0, >20, >50\n" + "checked values during NPC talk: >=1, >=13, >=25, >=40, >=70, >=100, >=9000")); + break; + case 94: + setToolTip(tr("if this is >5, changes sans's dialog after the puzzle")); + break; + case 101: // TEST + setToolTip(tr("0 = Snowdrake\n" + "1 = Ice Cap\n" + "2 (if not encountered Doggo) = random\n" + "2 (if encountered Doggo) = Lesser Dog\n" + "4 = random")); + break; + case 232: + setToolTip(tr("calculated from regular kill counter")); + break; + case 317: + setToolTip(tr("if this is >=17, Toriel has not sent any more messages")); + break; + case 318: + setToolTip(tr("forces player to move to another room to receive a new message")); + break; + case 384: + setToolTip(tr("affects dialog with \"Clamguy\"\n" + "if true pacifist and large puddle, a small tree will grow in the puddle")); + break; + case 388: + setToolTip(tr("0 = Aaron\n" + "1 = Woshua\n" + "2 = Moldsmal\n" + ">2 = random")); + break; + case 389: + setToolTip(tr("0 = Temmie\n" + "1 = Moldsmal and Moldbygg\n" + "2 = Woshua and Aaron\n" + "3 = Moldbygg and Woshua\n" + ">3 = random")); + break; + case 400: + setToolTip(tr("value 99 skips all messages")); + break; + case 439: + setToolTip(tr("0 = Vulkin\n" + "1 = Tsunderplane\n" + "2 = Pyrope\n" + "3 = Tsunderplane and Vulkin\n" + "4 = Pyrope and Pyrope\n" + ">4 = random")); + break; + case 454: + setToolTip(tr("0 = Whimsalot and Final Froggit\n" + "1 = Whimsalot and Astigmatism\n" + "2 = Knight Knight and Madjick\n" + ">2 = random")); + break; + case 457: + setToolTip(tr("0 = Astigmatism\n" + "1 = Whimsalot and Final Froggit\n" + "2 = Whimsalot and Astigmatism\n" + "3 = Final Froggit and Astigmatism\n" + "4 = Knight Knight and Madjick\n" + ">4 = random")); + break; + case 493: + setToolTip(tr("resets after changing rooms")); + break; + case 517: + setToolTip(tr("if this is 2, Memoryhead appears\n" + "if this is 13, dialog says \"You really like to wash your hands.\"")); + break; + case 526: + setToolTip(tr("if this is 8, the vending machine is empty")); + break; + } + + connect(this, SIGNAL(valueChanged(QString)), this, SLOT(updateSave(QString))); + connect(mw, SIGNAL(updateWidgets()), this, SLOT(updateData())); + connect(this, SIGNAL(dataChanged(bool)), mw, SLOT(fileModified(bool))); +} +void CustomSpinBox::updateSave(QString text) +{ + mw->saveData.replace(id, text); + emit dataChanged(true); +} +void CustomSpinBox::updateData() +{ + setValue(mw->saveData.at(id).toInt()); +} + +CustomCheckBox::CustomCheckBox(int id, MainWindow *mainWindow, QWidget *parent) : QCheckBox(parent), id(id), mw(mainWindow) +{ + switch (id) + { + case 35: + setToolTip(tr("makes Undyne act as if you made no kills")); + break; + case 58: + setToolTip(tr("aborts the genocide-run\n" + "set to true if you spare Dogamy and Dogaressa, Doggo, Glad Dummy, Greater Dog,\n" + "Lesser Dog, Monster Kid, Muffet, Papyrus, Royal Guard 1, Royal Guard 2, Shyren or Toriel")); + break; + case 59: + setToolTip(tr("hold down C to instantly skip text")); + break; + case 72: + setToolTip(tr("Toriel tells about this to sans in True Pacifist ending")); + break; + case 73: + setToolTip(tr("Toriel tells about this to sans in True Pacifist ending")); + break; + case 117: + setToolTip(tr("music box starts playing")); + break; + case 122: + setToolTip(tr("this value is also used for \"Interaction with Monster Kid\"-entry")); + break; + case 281: + setToolTip(tr("stays false, if Royal Guards are dead")); + break; + case 286: + setToolTip(tr("took 758G from behind the counter")); + break; + case 287: + setToolTip(tr("stole 5G from the till")); + break; + case 291: + setToolTip(tr("sans will comment on this in the ending phone call")); + break; + case 293: + setToolTip(tr("reward is 99G")); + break; + case 294: + setToolTip(tr("reward is 99G")); + break; + case 295: + setToolTip(tr("reward is a Hush Puppy\n" + "hint: try to deliver Hot Cat, Dog Salad or Dog Residue")); + break; + case 302: + setToolTip(tr("you're gonna have a bad time")); + break; + case 309: + setToolTip(tr("Papyrus will comment on this")); + break; + case 314: + setToolTip(tr("disables Glyde encounter")); + break; + case 315: + setToolTip(tr("Undyne's spear attacks become very fast\n" + "Monster kid comments on how mad Undyne was")); + break; + case 316: + setToolTip(tr("Undyne's spear attacks become very fast")); + break; + case 383: + setToolTip(tr("Undyne says \"I KNEW you would come back here!\" before attacking")); + break; + case 432: + setToolTip(tr("changes Royal Guard dialog during fight")); + break; + case 496: + setToolTip(tr("changes \"Papyrus's Phone\" to \"Papyrus and Undyne\"")); + break; + case 510: + setToolTip(tr("starts the True Lab music")); + break; + case 511: + setToolTip(tr("adds a shade on the player")); + break; + case 516: + setToolTip(tr("turns on some diary panels")); + break; + } + + connect(this, SIGNAL(stateChanged(int)), this, SLOT(updateSave(int))); + connect(mw, SIGNAL(updateWidgets()), this, SLOT(updateData())); + connect(this, SIGNAL(dataChanged(bool)), mw, SLOT(fileModified(bool))); +} +void CustomCheckBox::updateSave(int i) +{ + mw->saveData.replace(id, QString::number(values[i])); + emit dataChanged(true); +} +void CustomCheckBox::updateData() +{ + setCheckState(states.value(mw->saveData.at(id).toInt())); +} + +CustomRadioButton::CustomRadioButton(int id, QString text, MainWindow *mainWindow, QWidget *parent) : QRadioButton(text, parent), id(id), mw(mainWindow) +{ + switch (id) + { + case 44: + setToolTip(tr("only in the Ruins")); + break; + } + + connect(this, SIGNAL(toggled(bool)), this, SLOT(updateSave(bool))); + connect(mw, SIGNAL(updateWidgets()), this, SLOT(updateData())); + connect(this, SIGNAL(dataChanged(bool)), mw, SLOT(fileModified(bool))); +} +void CustomRadioButton::updateSave(bool checked) +{ + mw->saveData.replace(id, QString::number(checked)); + emit dataChanged(true); +} +void CustomRadioButton::updateData() +{ + setChecked(mw->saveData.at(id).toInt()); +} + +ItemComboBox::ItemComboBox(int id, MainWindow *mainWindow, QWidget *parent) : QComboBox(parent), id(id), mw(mainWindow) +{ + addItem(tr("None")); + addItem(tr("Monster Candy")); + addItem(tr("Croquet Roll")); + addItem(tr("Stick")); + addItem(tr("Bandage")); + addItem(tr("Rock Candy")); + addItem(tr("Pumpkin Rings")); + addItem(tr("Spider Donut")); + addItem(tr("Stoic Onion")); + addItem(tr("Ghost Fruit")); + addItem(tr("Spider Cider")); + addItem(tr("Butterscotch Pie")); + addItem(tr("Faded Ribbon")); + addItem(tr("Toy Knife")); + addItem(tr("Tough Glove")); + addItem(tr("Manly Bandanna")); + addItem(tr("Snowman Piece")); + addItem(tr("Nice Cream")); + addItem(tr("Puppydough Icecream")); + addItem(tr("Bisicle")); + addItem(tr("Unisicle")); + addItem(tr("Cinnamon Bunny")); + addItem(tr("Temmie Flakes")); + addItem(tr("Abandoned Quiche")); + addItem(tr("Old Tutu")); + addItem(tr("Ballet Shoes")); + addItem(tr("Punch Card")); + addItem(tr("Annoying Dog")); + addItem(tr("Dog Salad")); + addItem(tr("Dog Residue")); + addItem(tr("Dog Residue")); + addItem(tr("Dog Residue")); + addItem(tr("Dog Residue")); + addItem(tr("Dog Residue")); + addItem(tr("Dog Residue")); + addItem(tr("Astronaut Food")); + addItem(tr("Instant Noodles")); + addItem(tr("Crab Apple")); + addItem(tr("Hot Dog...?")); + addItem(tr("Hot Cat")); + addItem(tr("Glamburger")); + addItem(tr("Sea Tea")); + addItem(tr("Starfait")); + addItem(tr("Legendary Hero")); + addItem(tr("Cloudy Glasses")); + addItem(tr("Torn Notebook")); + addItem(tr("Stained Apron")); + addItem(tr("Burnt Pan")); + addItem(tr("Cowboy Hat")); + addItem(tr("Empty Gun")); + addItem(tr("Heart Locket")); + addItem(tr("Worn Dagger")); + addItem(tr("Real Knife")); + addItem(tr("The Locket")); + addItem(tr("Bad Memory")); + addItem(tr("Dream")); + addItem(tr("Undyne's Letter")); + addItem(tr("Undyne's Letter EX")); + addItem(tr("Popato Chisps")); + addItem(tr("Junk Food")); + addItem(tr("Mystery Key")); + addItem(tr("Face Steak")); + addItem(tr("Hush Puppy")); + addItem(tr("Snail Pie")); + addItem(tr("temy armor")); + + connect(this, SIGNAL(currentIndexChanged(int)), this, SLOT(updateSave(int))); + connect(mw, SIGNAL(updateWidgets()), this, SLOT(updateData())); + connect(this, SIGNAL(dataChanged(bool)), mw, SLOT(fileModified(bool))); +} +void ItemComboBox::updateSave(int i) +{ + mw->saveData.replace(id, QString::number(i)); + emit dataChanged(true); +} +void ItemComboBox::updateData() +{ + setCurrentIndex(mw->saveData.at(id).toInt()); +} + +PhoneComboBox::PhoneComboBox(int id, MainWindow *mainWindow, QWidget *parent) : QComboBox(parent), id(id), mw(mainWindow) +{ + addItem(tr("None")); + addItem(tr("Say Hello")); + addItem(tr("Puzzle Help")); + addItem(tr("About Yourself")); + addItem(tr("Call Her \"Mom\"")); + addItem(tr("Flirt")); + addItem(tr("Toriel's Phone")); + addItem(tr("Papyrus's Phone")); + addItem(tr("Dimensional Box A")); + addItem(tr("Dimensional Box B")); + + connect(this, SIGNAL(currentIndexChanged(int)), this, SLOT(updateSave(int))); + connect(mw, SIGNAL(updateWidgets()), this, SLOT(updateData())); + connect(this, SIGNAL(dataChanged(bool)), mw, SLOT(fileModified(bool))); +} +void PhoneComboBox::updateSave(int i) +{ + mw->saveData.replace(id, QString::number(values[i])); + emit dataChanged(true); +} +void PhoneComboBox::updateData() +{ + setCurrentIndex(indexes.value(mw->saveData.at(id).toInt())); +} + +WeaponComboBox::WeaponComboBox(int id, MainWindow *mainWindow, QWidget *parent) : QComboBox(parent), id(id), mw(mainWindow) +{ + addItem(tr("Stick")); + addItem(tr("Toy Knife")); + addItem(tr("Tough Glove")); + addItem(tr("Ballet Shoes")); + addItem(tr("Torn Notebook")); + addItem(tr("Burnt Pan")); + addItem(tr("Empty Gun")); + addItem(tr("Worn Dagger")); + addItem(tr("Real Knife")); + + connect(this, SIGNAL(currentIndexChanged(int)), this, SLOT(updateSave(int))); + connect(mw, SIGNAL(updateWidgets()), this, SLOT(updateData())); + connect(this, SIGNAL(dataChanged(bool)), mw, SLOT(fileModified(bool))); +} +void WeaponComboBox::updateSave(int i) +{ + mw->saveData.replace(id, QString::number(values[i])); + emit dataChanged(true); +} +void WeaponComboBox::updateData() +{ + setCurrentIndex(indexes.value(mw->saveData.at(id).toInt())); +} + +ArmorComboBox::ArmorComboBox(int id, MainWindow *mainWindow, QWidget *parent) : QComboBox(parent), id(id), mw(mainWindow) +{ + addItem(tr("Bandage")); + addItem(tr("Faded Ribbon")); + addItem(tr("Manly Bandanna")); + addItem(tr("Old Tutu")); + addItem(tr("Clouded Glasses")); + addItem(tr("Stained Apron")); + addItem(tr("Cowboy Hat")); + addItem(tr("Heart Locket")); + addItem(tr("The Locket")); + addItem(tr("Temmie Armor")); + + connect(this, SIGNAL(currentIndexChanged(int)), this, SLOT(updateSave(int))); + connect(mw, SIGNAL(updateWidgets()), this, SLOT(updateData())); + connect(this, SIGNAL(dataChanged(bool)), mw, SLOT(fileModified(bool))); +} +void ArmorComboBox::updateSave(int i) +{ + mw->saveData.replace(id, QString::number(values[i])); + emit dataChanged(true); +} +void ArmorComboBox::updateData() +{ + setCurrentIndex(indexes.value(mw->saveData.at(id).toInt())); +} + +RoomComboBox::RoomComboBox(int id, MainWindow *mainWindow, QWidget *parent) : QComboBox(parent), id(id), mw(mainWindow) +{ + addItem(QString("Ruins - Entrance")); + addItem(QString("Ruins - Leaf Pile")); + addItem(QString("Ruins - Mouse Hole")); + addItem(QString("Ruins - Home")); + addItem(QString("Snowdin - Box Road")); + addItem(QString("Snowdin - Spaghetti")); + addItem(QString("Snowdin - Dog House")); + addItem(QString("Snowdin - Town")); + addItem(QString("Waterfall - Checkpoint")); + addItem(QString("Waterfall - Hallway")); + addItem(QString("Waterfall - Crystal")); + addItem(QString("Waterfall - Bridge")); + addItem(QString("Waterfall - Trash Zone")); + addItem(QString("Waterfall - Quiet Area")); + addItem(QString("Waterfall - Temmie Village")); + addItem(QString("Waterfall - Undyne Arena")); + addItem(QString("Hotland - Laboratory Entrance")); + addItem(QString("Hotland - Magma Chamber")); + addItem(QString("Hotland - Core View")); + addItem(QString("Hotland - Bad Opinion Zone")); + addItem(QString("Hotland - Spider Entrance")); + addItem(QString("Hotland - Hotel Lobby")); + addItem(QString("Hotland - Core Branch")); + addItem(QString("Hotland - Core End")); + addItem(QString("Castle Elevator")); + addItem(QString("New Home")); + addItem(QString("Last Corridor")); + addItem(QString("Throne Entrance")); + addItem(QString("Throne Room")); + addItem(QString("The End")); + addItem(QString("True Laboratory")); + addItem(QString("True Lab - Bedroom")); + addItem(QString("room_start")); + addItem(QString("room_introstory")); + addItem(QString("room_introimage")); + addItem(QString("room_intromenu")); + addItem(QString("room_area1")); + addItem(QString("room_area1_2")); + addItem(QString("Ruins - 2")); + addItem(QString("Ruins - 3")); + addItem(QString("Ruins - 4")); + addItem(QString("Ruins - 5")); + addItem(QString("Ruins - 6")); + addItem(QString("Ruins - 7A")); + addItem(QString("Ruins - 8")); + addItem(QString("Ruins - 9")); + addItem(QString("Ruins - 10")); + addItem(QString("Ruins - 11")); + addItem(QString("Ruins - 12")); + addItem(QString("Ruins - 12B")); + addItem(QString("Ruins - 13")); + addItem(QString("Ruins - 14")); + addItem(QString("Ruins - 15A")); + addItem(QString("Ruins - 15B")); + addItem(QString("Ruins - 15C")); + addItem(QString("Ruins - 15D")); + addItem(QString("Ruins - 15E")); + addItem(QString("Ruins - 16")); + addItem(QString("Ruins - 17")); + addItem(QString("Ruins - 18OLD")); + addItem(QString("Home - Entrance Hall")); + addItem(QString("Home - Living Room")); + addItem(QString("Home - Hall")); + addItem(QString("Home - Toriel's Room")); + addItem(QString("Home - Asriel's Room")); + addItem(QString("Home - Kitchen")); + addItem(QString("room_basement1")); + addItem(QString("room_basement2")); + addItem(QString("room_basement3")); + addItem(QString("room_basement4")); + addItem(QString("room_basement5")); + addItem(QString("Snowdin - Ruins Exit")); + addItem(QString("Snowdin - 1")); + addItem(QString("Snowdin - 2")); + addItem(QString("Snowdin - 3A")); + addItem(QString("Snowdin - 4")); + addItem(QString("Snowdin - 5")); + addItem(QString("Snowdin - 6")); + addItem(QString("Snowdin - 6A")); + addItem(QString("Snowdin - 7")); + addItem(QString("Snowdin - 8")); + addItem(QString("Snowdin - 8A")); + addItem(QString("Snowdin - 9")); + addItem(QString("Snowdin - Snow Puzzle")); + addItem(QString("Snowdin - XO Puzzle (Small)")); + addItem(QString("Snowdin - XO Puzzle (Papyrus)")); + addItem(QString("Snowdin - Tile Puzzle")); + addItem(QString("Snowdin - icehole")); + addItem(QString("Snowdin - iceentrance")); + addItem(QString("Snowdin - iceexit_new")); + addItem(QString("Snowdin - iceexit")); + addItem(QString("Snowdin - Snow Poff Zone")); + addItem(QString("Snowdin - Dangerous Bridge Puzzle")); + addItem(QString("Snowdin - town2")); + addItem(QString("Snowdin - Dock")); + addItem(QString("Snowdin - Snowed Inn")); + addItem(QString("Snowdin - Snowed Inn (2nd floor)")); + addItem(QString("Snowdin - Grillby's")); + addItem(QString("Snowdin - Library")); + addItem(QString("Snowdin - Garage")); + addItem(QString("Snowdin - Papyrus's and Sans's House")); + addItem(QString("Snowdin - Papyrus's Room")); + addItem(QString("Snowdin - Sans's Room")); + addItem(QString("Snowdin - Sans's Room (Dark)")); + addItem(QString("Snowdin - Sans's Basement")); + addItem(QString("Snowdin - Foggy Hallway")); + addItem(QString("Waterfall - 1")); + addItem(QString("Waterfall - 3")); + addItem(QString("Waterfall - 3A")); + addItem(QString("Waterfall - bridgepuzz1")); + addItem(QString("Waterfall - 5")); + addItem(QString("Waterfall - 5A")); + addItem(QString("Waterfall - 6")); + addItem(QString("Waterfall - 7")); + addItem(QString("Waterfall - 8")); + addItem(QString("Waterfall - 9")); + addItem(QString("Waterfall - 11")); + addItem(QString("Waterfall - nicecream")); + addItem(QString("Waterfall - 12")); + addItem(QString("Waterfall - shoe")); + addItem(QString("Waterfall - bird")); + addItem(QString("Waterfall - Onionsan")); + addItem(QString("Waterfall - 14")); + addItem(QString("Waterfall - Piano Puzzle")); + addItem(QString("Waterfall - dogroom")); + addItem(QString("Waterfall - Music Box Statue")); + addItem(QString("Waterfall - prewaterfall")); + addItem(QString("Waterfall - waterfall")); + addItem(QString("Waterfall - waterfall2")); + addItem(QString("Waterfall - waterfall3")); + addItem(QString("Waterfall - waterfall4")); + addItem(QString("Waterfall - undynebridge")); + addItem(QString("Waterfall - undynebridgeend")); + addItem(QString("Waterfall - trashzone1")); + addItem(QString("Waterfall - trashzone2")); + addItem(QString("Waterfall - Undyne's Yard")); + addItem(QString("Waterfall - Undyne's House")); + addItem(QString("Waterfall - Blooky's Yard")); + addItem(QString("Waterfall - Blooky's House")); + addItem(QString("Waterfall - hapstablook")); + addItem(QString("Waterfall - Blook Farm")); + addItem(QString("Waterfall - prebird")); + addItem(QString("Waterfall - Gerson's Shop")); + addItem(QString("Waterfall - Dock")); + addItem(QString("Waterfall - 15")); + addItem(QString("Waterfall - 16")); + addItem(QString("Waterfall - 17")); + addItem(QString("Waterfall - 18")); + addItem(QString("Waterfall - 19")); + addItem(QString("Waterfall - 20")); + addItem(QString("Waterfall - Puzzle Elder")); + addItem(QString("Waterfall - Arena Exit")); + addItem(QString("Waterfall - Hotland Entrance")); + addItem(QString("Hotland - Sans's Station")); + addItem(QString("Hotland - Water Cooler")); + addItem(QString("Hotland - Dock")); + addItem(QString("Hotland - lab1")); + addItem(QString("Hotland - lab2")); + addItem(QString("Hotland - 3")); + addItem(QString("Hotland - 5")); + addItem(QString("Hotland - 6A")); + addItem(QString("Hotland - lasers1")); + addItem(QString("Hotland - 7")); + addItem(QString("Hotland - 8")); + addItem(QString("Hotland - shootguy_2")); + addItem(QString("Hotland - 9")); + addItem(QString("Hotland - shootguy_1")); + addItem(QString("Hotland - turn")); + addItem(QString("Hotland - cookingshow")); + addItem(QString("Hotland - elevator_r1")); + addItem(QString("Hotland - elevator_r2")); + addItem(QString("Hotland - hotdog")); + addItem(QString("Hotland - walkandbranch")); + addItem(QString("Hotland - sorry")); + addItem(QString("Hotland - apron")); + addItem(QString("Hotland - 10")); + addItem(QString("Hotland - rpuzzle")); + addItem(QString("Hotland - boysnightout")); + addItem(QString("Hotland - newsreport")); + addItem(QString("Hotland - coreview2")); + addItem(QString("Hotland - elevator_l2")); + addItem(QString("Hotland - elevator_l3")); + addItem(QString("Hotland - spidershop")); + addItem(QString("Hotland - walkandbranch2")); + addItem(QString("Hotland - conveyorlaser")); + addItem(QString("Hotland - shootguy_3")); + addItem(QString("Hotland - preshootguy4")); + addItem(QString("Hotland - shootguy_4")); + addItem(QString("Hotland - Spider's Web")); + addItem(QString("Hotland - pacing")); + addItem(QString("Hotland - operatest")); + addItem(QString("Hotland - Tile Puzzle EX")); + addItem(QString("Hotland - hotelfront_1")); + addItem(QString("Hotland - hotelfront_2")); + addItem(QString("Hotel - Restaurant")); + addItem(QString("Hotland - hoteldoors")); + addItem(QString("Hotland - hotelbed")); + addItem(QString("Hotland - elevator_r3")); + addItem(QString("Hotland - precore")); + addItem(QString("Hotland - core1")); + addItem(QString("Hotland - core2")); + addItem(QString("Hotland - core3")); + addItem(QString("Hotland - core4")); + addItem(QString("Hotland - core5")); + addItem(QString("Hotland - core_freebattle")); + addItem(QString("Hotland - core_laserfun")); + addItem(QString("Hotland - core_bottomleft")); + addItem(QString("Hotland - core_left")); + addItem(QString("Hotland - core_topleft")); + addItem(QString("Hotland - core_top")); + addItem(QString("Hotland - core_topright")); + addItem(QString("Hotland - core_right")); + addItem(QString("Hotland - core_bottomright")); + addItem(QString("Hotland - core_center")); + addItem(QString("Hotland - shootguy_5")); + addItem(QString("Hotland - core_treasureleft")); + addItem(QString("Hotland - core_treasureright")); + addItem(QString("Hotland - core_warrior")); + addItem(QString("Hotland - core_bridge")); + addItem(QString("Hotland - core_metttest")); + addItem(QString("Hotland - core_final")); + addItem(QString("Hotland - elevator")); + addItem(QString("Hotland - elevator_l1")); + addItem(QString("Hotland - finalelevator")); + addItem(QString("room_castle_precastle")); + addItem(QString("room_castle_hook")); + addItem(QString("room_asghouse1")); + addItem(QString("room_asghouse2")); + addItem(QString("room_asghouse3")); + addItem(QString("room_asgoreroom")); + addItem(QString("room_asrielroom_final")); + addItem(QString("room_kitchen_final")); + addItem(QString("room_basement1_final")); + addItem(QString("room_basement2_final")); + addItem(QString("room_basement3_final")); + addItem(QString("room_basement4_final")); + addItem(QString("room_lastruins_corridor")); + addItem(QString("room_castle_coffins1")); + addItem(QString("room_castle_coffins2")); + addItem(QString("room_castle_barrier")); + addItem(QString("room_castle_exit")); + addItem(QString("room_undertale_end")); + addItem(QString("room_castle_trueexit")); + addItem(QString("room_outsideworld")); + addItem(QString("Hotland - labelevator")); + addItem(QString("True Lab - elevatorinside")); + addItem(QString("True Lab - elevator")); + addItem(QString("True Lab - hall1")); + addItem(QString("True Lab - hall2")); + addItem(QString("True Lab - operatingroom")); + addItem(QString("True Lab - Red Lever")); + addItem(QString("True Lab - prebed")); + addItem(QString("True Lab - mirror")); + addItem(QString("True Lab - Blue Lever")); + addItem(QString("True Lab - hall3")); + addItem(QString("True Lab - shower")); + addItem(QString("True Lab - determination")); + addItem(QString("True Lab - tv")); + addItem(QString("True Lab - cooler")); + addItem(QString("True Lab - Green Lever")); + addItem(QString("True Lab - fan")); + addItem(QString("True Lab - castle_elevator")); + addItem(QString("True Lab - prepower")); + addItem(QString("True Lab - power")); + addItem(QString("room_gaster")); + addItem(QString("room_icecave1")); + addItem(QString("room_ice_dog")); + addItem(QString("room2")); + addItem(QString("Waterfall - fakehallway")); + addItem(QString("room_mysteryman")); + addItem(QString("room_soundtest")); + addItem(QString("TESTROOM")); + addItem(QString("Waterfall - redacted")); + addItem(QString("Waterfall - 13")); + addItem(QString("room_overworld")); + addItem(QString("room_overworld3")); + addItem(QString("bullettest")); + addItem(QString("Waterfall - 16A")); + addItem(QString("room_end_castroll")); + addItem(QString("room_end_highway")); + addItem(QString("room_end_beach")); + addItem(QString("room_end_metta")); + addItem(QString("room_end_school")); + addItem(QString("room_end_mtebott")); + addItem(QString("room_creditsdodger")); + addItem(QString("room_end_myroom")); + addItem(QString("room_end_theend")); + addItem(QString("room_spritecheck")); + addItem(QString("room_joyconfig")); + addItem(QString("room_controltest")); + addItem(QString("room_f_start")); + addItem(QString("room_f_intro")); + addItem(QString("room_f_menu")); + addItem(QString("room_f_room")); + addItem(QString("room_floweyx")); + addItem(QString("room_f_phrase")); + addItem(QString("Hotland - 4")); + addItem(QString("Hotland - 10_old")); + addItem(QString("Hotland - 10A_old")); + addItem(QString("Snowdin - placeholder")); + addItem(QString("Ruins - 12B_old")); + addItem(QString("Snowdin - rollsnow")); + addItem(QString("Waterfall - 7_older")); + addItem(QString("room_meetundyne_old")); + addItem(QString("Waterfall - mushroom")); + addItem(QString("room_monsteralign_test")); + addItem(QString("room_battle")); + addItem(QString("room_floweybattle")); + addItem(QString("room_fastbattle")); + addItem(QString("room_storybattle")); + addItem(QString("room_gameover")); + addItem(QString("room_shop1")); + addItem(QString("room_shop2")); + addItem(QString("room_shop3")); + addItem(QString("room_shop4")); + addItem(QString("room_shop5")); + addItem(QString("room_riverman_transition")); + addItem(QString("room_papdate")); + addItem(QString("room_adate")); + addItem(QString("room_flowey_endchoice")); + addItem(QString("room_flowey_regret")); + addItem(QString("room_empty")); + addItem(QString("room_emptywhite")); + addItem(QString("room_emptyblack")); + addItem(QString("room_nothingness")); + addItem(QString("room_undertale")); + addItem(QString("room_of_dog")); + addItem(QString("room_quizholder")); + addItem(QString("room_friendtest")); + addItem(QString("room_bringitinguys")); + addItem(QString("room_asrielappears")); + addItem(QString("room_goodbyeasriel")); + addItem(QString("room_asrielmemory")); + addItem(QString("room_asrieltest")); + addItem(QString("room_afinaltest")); + + connect(this, SIGNAL(currentIndexChanged(int)), this, SLOT(updateSave(int))); + connect(mw, SIGNAL(updateWidgets()), this, SLOT(updateData())); + connect(this, SIGNAL(dataChanged(bool)), mw, SLOT(fileModified(bool))); +} +void RoomComboBox::updateSave(int i) +{ + mw->saveData.replace(id, QString::number(values[i])); + emit dataChanged(true); +} +void RoomComboBox::updateData() +{ + setCurrentIndex(indexes.value(mw->saveData.at(id).toInt())); +} + +TimeEdit::TimeEdit(int id, MainWindow *mainWindow, QWidget *parent) : QWidget(parent), id(id), mw(mainWindow) +{ + data = new QDoubleSpinBox(); + data->setDecimals(0); + data->setRange(0, INT64_MAX); + label = new QLabel(QString("00:00:00")); + + setLayout(new QHBoxLayout()); + layout()->addWidget(label); + layout()->addWidget(data); + + connect(data, SIGNAL(valueChanged(double)), this, SLOT(updateSave(double))); + connect(mw, SIGNAL(updateWidgets()), this, SLOT(updateData())); + connect(this, SIGNAL(dataChanged(bool)), mw, SLOT(fileModified(bool))); +} +void TimeEdit::updateSave(double d) +{ + int h = qRound(d/108000.0); + int m = qRound(d/1800) % 60; + int s = qRound(d/30) % 60; + label->setText(QString("%1:%2:%3").arg(h, 2, 'f', 0, '0').arg(m, 2, 'f', 0, '0').arg(s, 2, 'f', 0, '0')); + mw->saveData.replace(id, QString::number(d, 'g', 5)); + emit dataChanged(true); +} +void TimeEdit::updateData() +{ + double d = mw->saveData.at(id).toDouble(); + data->setValue(d); + int h = qRound(d/108000.0); + int m = qRound(d/1800) % 60; + int s = qRound(d/30) % 60; + label->setText(QString("%1:%2:%3").arg(h, 2, 'f', 0, '0').arg(m, 2, 'f', 0, '0').arg(s, 2, 'f', 0, '0')); +} + + +PlotEdit::PlotEdit(int id, MainWindow *mainWindow, QWidget *parent) : QComboBox(parent), id(id), mw(mainWindow) +{ + addItem(tr("New Game")); + addItem(tr("Met Flowey")); + addItem(tr("Toriel escorted you to the next room")); + addItem(tr("Toriel explained puzzles")); + addItem(tr("Switch puzzle started")); + addItem(tr("Pulled first switch")); + addItem(tr("Pulled second switch")); + addItem(tr("Practice dummy")); + addItem(tr("Interacted with the dummy")); + addItem(tr("Dummy encounter done")); + addItem(tr("Dangerous puzzle started")); + addItem(tr("Dangerous puzzle ended")); + addItem(tr("Independence test started")); + addItem(tr("Independence test ended")); + addItem(tr("Toriel called about leaving the room")); + addItem(tr("Toriel called about pie flavor")); + addItem(tr("Toriel called again")); + addItem(tr("Toriel called about allergies")); + addItem(tr("Cheered Napstablook")); + addItem(tr("Napstablook encounter done")); + addItem(tr("Talked with Napstablook")); + addItem(tr("Napstablook disappeared")); + addItem(tr("Toriel called about picking up items")); + addItem(tr("Hit the switch in a pit")); + addItem(tr("Pressed a blue switch")); + addItem(tr("Pressed a red switch")); + addItem(tr("Pressed a green switch")); + addItem(tr("Met Toriel again")); + addItem(tr("Toriel told about pie")); + addItem(tr("Toriel showed you your room")); + addItem(tr("Talked with Toriel")); + addItem(tr("Talked with Toriel more")); + addItem(tr("Talked with Toriel some more")); + addItem(tr("Listened about snail facts")); + addItem(tr("You asked \"How to exit the Ruins\"")); + addItem(tr("Toriel has to do something")); + addItem(tr("Toriel went to the basement")); + addItem(tr("Toriel is going to destroy the exit")); + addItem(tr("Toriel warned about Asgore")); + addItem(tr("Toriel warned you for the last time")); + addItem(tr("Toriel encounter done")); + addItem(tr("Talked with Flowey")); + addItem(tr("Exited Ruins")); + addItem(tr("Conveniently-shaped lamp")); + addItem(tr("sans left the area")); + addItem(tr("Papyrus met the human")); + addItem(tr("Doggo encounter done")); + addItem(tr("Doggo went to get dog treats")); + addItem(tr("Solved the electricity maze")); + addItem(tr("\"Solved\" sans's puzzle")); + addItem(tr("Found the buried switch")); + addItem(tr("Dogamy and Dogaressa encounter done")); + addItem(tr("Dogamy and Dogaressa left the area")); + addItem(tr("Solved the first XO puzzle")); + addItem(tr("Reached the second XO puzzle")); + addItem(tr("Solved the second XO puzzle")); + addItem(tr("Skip the XO puzzles")); + addItem(tr("\"Solved\" the Multicolor Tile Puzzle")); + addItem(tr("Greater Dog encounter done")); + addItem(tr("Greater Dog encounter done")); + addItem(tr("Solved the third XO puzzle")); + addItem(tr("Greater Dog left the area")); + addItem(tr("\"Solved\" the final puzzle")); + addItem(tr("Papyrus encounter done")); + addItem(tr("Papyrus left the area")); + addItem(tr("(unused) Monster Kid trigger")); + addItem(tr("Undyne spotted you in the sea-grass")); + addItem(tr("Papyrus called about your armor")); + addItem(tr("Found the hidden door")); + addItem(tr("(unused) Solved torch puzzle")); + addItem(tr("Undyne grabbed Monster Kid in the sea-grass")); + addItem(tr("Encountered Shyren")); + addItem(tr("Monster Kid offered to help climb a ledge")); + addItem(tr("Monster Kid left the area")); + addItem(tr("Wakeup in the Trash Zone")); + addItem(tr("Mad Dummy encounter done")); + addItem(tr("Napstablook went home")); + addItem(tr("Undyne dragged Monster Kid away")); + addItem(tr("Walked to the end of Echo Flower path")); + addItem(tr("Monster Kid tripped on a bridge")); + addItem(tr("Undyne confronted you")); + addItem(tr("Undyne encounter done")); + addItem(tr("Mettaton's game show")); + addItem(tr("Alphys upgraded your phone")); + addItem(tr("Alphys hung up on you")); + addItem(tr("Alphys called about the lasers")); + addItem(tr("Alphys called about the Shooting Puzzles")); + addItem(tr("Opened the first large door")); + addItem(tr("Alphys called about the puzzles again")); + addItem(tr("Alphys called during Mettaton's cooking show")); + addItem(tr("Mettaton's cooking show done")); + addItem(tr("Alphys called about the Core")); + addItem(tr("Alphys called about the conveyor puzzle")); + addItem(tr("Alphys tried to help with the timing")); + addItem(tr("Alphys called about going to the bathroom")); + addItem(tr("Royal Guard encounter done")); + addItem(tr("Skip Hotland puzzles")); + addItem(tr("MTT News done")); + addItem(tr("Alphys called about Asgore")); + addItem(tr("Alphys called about the Shooting Puzzles")); + addItem(tr("Opened the second large door")); + addItem(tr("Muffet encounter done")); + addItem(tr("Mettaton opera")); + addItem(tr("Mettaton's Multicolor Tile Puzzle done")); + addItem(tr("Exited the MTT Resort")); + addItem(tr("Alphys called at the Core lobby")); + addItem(tr("Fought mercenaries")); + addItem(tr("Alphys called about the order of lasers")); + addItem(tr("Alphys called after the lasers")); + addItem(tr("Alphys called at the crossroads")); + addItem(tr("(unused) Laser event")); + addItem(tr("Alphys called about how everything is under control")); + addItem(tr("Alphys called at the Core Branch")); + addItem(tr("Mettaton EX encounter done")); + addItem(tr("Alphys told the truth")); + addItem(tr("sans judged you")); + addItem(tr("Met Asgore")); + addItem(tr("Asgore told how tense this is")); + addItem(tr("Asgore entered the barrier room")); + addItem(tr("True Pacifist")); + + connect(this, SIGNAL(currentIndexChanged(int)), this, SLOT(updateSave(int))); + connect(mw, SIGNAL(updateWidgets()), this, SLOT(updateData())); + connect(this, SIGNAL(dataChanged(bool)), mw, SLOT(fileModified(bool))); +} +void PlotEdit::updateSave(int i) +{ + mw->saveData.replace(id, QString::number(values[i])); + emit dataChanged(true); +} +void PlotEdit::updateData() +{ + setCurrentIndex(indexes.value(mw->saveData.at(id).toInt())); +} diff --git a/tools.h b/tools.h new file mode 100644 index 0000000..378b8e7 --- /dev/null +++ b/tools.h @@ -0,0 +1,209 @@ +#ifndef TOOLS_H +#define TOOLS_H + +#include "mainwindow.h" + +#include +#include +#include +#include +#include +#include + +class CustomLineEdit : public QLineEdit +{ + Q_OBJECT +public: + CustomLineEdit(int id, MainWindow *mainWindow, QWidget *parent = nullptr); +signals: + void dataChanged(bool value); +public slots: + void updateSave(QString text); + void updateData(); +private: + int id; + MainWindow *mw; +}; + +class CustomSpinBox : public QSpinBox +{ + Q_OBJECT +public: + CustomSpinBox(int id, MainWindow *mainWindow, QWidget *parent = nullptr); +signals: + void dataChanged(bool value); +public slots: + void updateSave(QString text); + void updateData(); +private: + int id; + MainWindow *mw; +}; + +class CustomComboBox : public QComboBox +{ + Q_OBJECT +public: + CustomComboBox(int id, MainWindow *mainWindow, QWidget *parent = nullptr); +signals: + void dataChanged(bool value); +public slots: + void updateSave(int i); + void updateData(); +private: + int id; + QList values; + QMap indexes; + MainWindow *mw; +}; + +class CustomCheckBox : public QCheckBox +{ + Q_OBJECT +public: + CustomCheckBox(int id, MainWindow *mainWindow, QWidget *parent = nullptr); +signals: + void dataChanged(bool value); +public slots: + void updateSave(int i); + void updateData(); +private: + int id; + int values[3] = {0, 1, 1}; + QMap states{{0, Qt::Unchecked}, {1, Qt::Checked}}; + MainWindow *mw; +}; + +class CustomRadioButton : public QRadioButton +{ + Q_OBJECT +public: + CustomRadioButton(int id, QString text, MainWindow *mainWindow, QWidget *parent = nullptr); +signals: + void dataChanged(bool value); +public slots: + void updateSave(bool checked); + void updateData(); +private: + int id; + MainWindow *mw; +}; + +class ItemComboBox : public QComboBox +{ + Q_OBJECT +public: + ItemComboBox(int id, MainWindow *mainWindow, QWidget *parent = nullptr); +signals: + void dataChanged(bool value); +public slots: + void updateSave(int i); + void updateData(); +private: + int id; + MainWindow *mw; +}; + +class PhoneComboBox : public QComboBox +{ + Q_OBJECT +public: + PhoneComboBox(int id, MainWindow *mainWindow, QWidget *parent = nullptr); +signals: + void dataChanged(bool value); +public slots: + void updateSave(int i); + void updateData(); +private: + int id; + int values[10] = {0, 201, 202, 203, 204, 205, 206, 210, 220, 221}; + QMap indexes{{201, 1}, {202, 2}, {203, 3}, {204, 4}, {205, 5}, {206, 6}, {210, 7}, {220, 8}, {221, 9}}; + MainWindow *mw; +}; + +class WeaponComboBox : public QComboBox +{ + Q_OBJECT +public: + WeaponComboBox(int id, MainWindow *mainWindow, QWidget *parent = nullptr); +signals: + void dataChanged(bool value); +public slots: + void updateSave(int i); + void updateData(); +private: + int id; + int values[10] = {0, 3, 13, 14, 25, 45, 47, 49, 51, 52}; + QMap indexes{{3, 0}, {13, 1}, {14, 2}, {25, 3}, {45, 4}, {47, 5}, {49, 6}, {51, 7}, {52, 8}}; + MainWindow *mw; +}; + +class ArmorComboBox : public QComboBox +{ + Q_OBJECT +public: + ArmorComboBox(int id, MainWindow *mainWindow, QWidget *parent = nullptr); +signals: + void dataChanged(bool value); +public slots: + void updateSave(int i); + void updateData(); +private: + int id; + int values[11] = {0, 4, 12, 15, 24, 44, 46, 48, 50, 53, 64}; + QMap indexes{{4, 0}, {12, 1}, {15, 2}, {24, 3}, {44, 4}, {46, 5}, {48, 6}, {50, 7}, {53, 8}, {64, 9}}; + MainWindow *mw; +}; + +class RoomComboBox : public QComboBox +{ + Q_OBJECT +public: + RoomComboBox(int id, MainWindow *mainWindow, QWidget *parent = nullptr); +signals: + void dataChanged(bool value); +public slots: + void updateSave(int i); + void updateData(); +private: + int id; + int values[335] = {6, 12, 18, 31, 46, 56, 61, 68, 83, 86, 94, 110, 114, 116, 128, 134, 139, 145, 155, 164, 176, 183, 196, 210, 216, 219, 231, 232, 235, 236, 246, 251, 0, 1, 2, 3, 4, 5, 7, 8, 9, 10, 11, 13, 14, 15, 16, 17, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, 45, 47, 48, 49, 50, 51, 52, 53, 54, 55, 57, 58, 59, 60, 62, 63, 64, 65, 66, 67, 69, 70, 71, 72, 73, 74, 75, 76, 77, 78, 79, 80, 81, 82, 84, 85, 87, 88, 89, 90, 91, 92, 93, 95, 96, 97, 98, 99, 100, 101, 102, 103, 104, 105, 106, 107, 108, 109, 111, 112, 113, 115, 117, 118, 119, 120, 121, 122, 123, 124, 125, 126, 127, 129, 130, 131, 132, 133, 135, 136, 137, 138, 140, 141, 142, 143, 144, 146, 147, 148, 149, 150, 151, 152, 153, 154, 156, 157, 158, 159, 160, 161, 162, 163, 165, 166, 167, 168, 169, 170, 171, 172, 173, 174, 175, 177, 178, 179, 180, 181, 182, 184, 185, 186, 187, 188, 189, 190, 191, 192, 193, 194, 195, 197, 198, 199, 200, 201, 202, 203, 204, 205, 206, 207, 208, 209, 211, 212, 213, 214, 215, 217, 218, 220, 221, 222, 223, 224, 225, 226, 227, 228, 229, 230, 233, 234, 237, 238, 239, 240, 241, 242, 243, 244, 245, 247, 248, 249, 250, 252, 253, 254, 255, 256, 257, 258, 259, 260, 261, 262, 263, 264, 265, 266, 267, 268, 269, 270, 271, 272, 273, 274, 275, 276, 277, 278, 279, 280, 281, 282, 283, 284, 285, 286, 287, 288, 289, 290, 291, 292, 293, 294, 295, 296, 297, 298, 299, 300, 301, 302, 303, 304, 305, 306, 307, 308, 309, 310, 311, 312, 313, 314, 315, 316, 317, 318, 319, 320, 321, 322, 323, 324, 325, 326, 327, 328, 329, 330, 331, 332, 333, 334}; + QMap indexes{{6, 0}, {12, 1}, {18, 2}, {31, 3}, {46, 4}, {56, 5}, {61, 6}, {68, 7}, {83, 8}, {86, 9}, {94, 10}, {110, 11}, {114, 12}, {116, 13}, {128, 14}, {134, 15}, {139, 16}, {145, 17}, {155, 18}, {164, 19}, {176, 20}, {183, 21}, {196, 22}, {210, 23}, {216, 24}, {219, 25}, {231, 26}, {232, 27}, {235, 28}, {236, 29}, {246, 30}, {251, 31}, {0, 32}, {1, 33}, {2, 34}, {3, 35}, {4, 36}, {5, 37}, {7, 38}, {8, 39}, {9, 40}, {10, 41}, {11, 42}, {13, 43}, {14, 44}, {15, 45}, {16, 46}, {17, 47}, {19, 48}, {20, 49}, {21, 50}, {22, 51}, {23, 52}, {24, 53}, {25, 54}, {26, 55}, {27, 56}, {28, 57}, {29, 58}, {30, 59}, {32, 60}, {33, 61}, {34, 62}, {35, 63}, {36, 64}, {37, 65}, {38, 66}, {39, 67}, {40, 68}, {41, 69}, {42, 70}, {43, 71}, {44, 72}, {45, 73}, {47, 74}, {48, 75}, {49, 76}, {50, 77}, {51, 78}, {52, 79}, {53, 80}, {54, 81}, {55, 82}, {57, 83}, {58, 84}, {59, 85}, {60, 86}, {62, 87}, {63, 88}, {64, 89}, {65, 90}, {66, 91}, {67, 92}, {69, 93}, {70, 94}, {71, 95}, {72, 96}, {73, 97}, {74, 98}, {75, 99}, {76, 100}, {77, 101}, {78, 102}, {79, 103}, {80, 104}, {81, 105}, {82, 106}, {84, 107}, {85, 108}, {87, 109}, {88, 110}, {89, 111}, {90, 112}, {91, 113}, {92, 114}, {93, 115}, {95, 116}, {96, 117}, {97, 118}, {98, 119}, {99, 120}, {100, 121}, {101, 122}, {102, 123}, {103, 124}, {104, 125}, {105, 126}, {106, 127}, {107, 128}, {108, 129}, {109, 130}, {111, 131}, {112, 132}, {113, 133}, {115, 134}, {117, 135}, {118, 136}, {119, 137}, {120, 138}, {121, 139}, {122, 140}, {123, 141}, {124, 142}, {125, 143}, {126, 144}, {127, 145}, {129, 146}, {130, 147}, {131, 148}, {132, 149}, {133, 150}, {135, 151}, {136, 152}, {137, 153}, {138, 154}, {140, 155}, {141, 156}, {142, 157}, {143, 158}, {144, 159}, {146, 160}, {147, 161}, {148, 162}, {149, 163}, {150, 164}, {151, 165}, {152, 166}, {153, 167}, {154, 168}, {156, 169}, {157, 170}, {158, 171}, {159, 172}, {160, 173}, {161, 174}, {162, 175}, {163, 176}, {165, 177}, {166, 178}, {167, 179}, {168, 180}, {169, 181}, {170, 182}, {171, 183}, {172, 184}, {173, 185}, {174, 186}, {175, 187}, {177, 188}, {178, 189}, {179, 190}, {180, 191}, {181, 192}, {182, 193}, {184, 194}, {185, 195}, {186, 196}, {187, 197}, {188, 198}, {189, 199}, {190, 200}, {191, 201}, {192, 202}, {193, 203}, {194, 204}, {195, 205}, {197, 206}, {198, 207}, {199, 208}, {200, 209}, {201, 210}, {202, 211}, {203, 212}, {204, 213}, {205, 214}, {206, 215}, {207, 216}, {208, 217}, {209, 218}, {211, 219}, {212, 220}, {213, 221}, {214, 222}, {215, 223}, {217, 224}, {218, 225}, {220, 226}, {221, 227}, {222, 228}, {223, 229}, {224, 230}, {225, 231}, {226, 232}, {227, 233}, {228, 234}, {229, 235}, {230, 236}, {233, 237}, {234, 238}, {237, 239}, {238, 240}, {239, 241}, {240, 242}, {241, 243}, {242, 244}, {243, 245}, {244, 246}, {245, 247}, {247, 248}, {248, 249}, {249, 250}, {250, 251}, {252, 252}, {253, 253}, {254, 254}, {255, 255}, {256, 256}, {257, 257}, {258, 258}, {259, 259}, {260, 260}, {261, 261}, {262, 262}, {263, 263}, {264, 264}, {265, 265}, {266, 266}, {267, 267}, {268, 268}, {269, 269}, {270, 270}, {271, 271}, {272, 272}, {273, 273}, {274, 274}, {275, 275}, {276, 276}, {277, 277}, {278, 278}, {279, 279}, {280, 280}, {281, 281}, {282, 282}, {283, 283}, {284, 284}, {285, 285}, {286, 286}, {287, 287}, {288, 288}, {289, 289}, {290, 290}, {291, 291}, {292, 292}, {293, 293}, {294, 294}, {295, 295}, {296, 296}, {297, 297}, {298, 298}, {299, 299}, {300, 300}, {301, 301}, {302, 302}, {303, 303}, {304, 304}, {305, 305}, {306, 306}, {307, 307}, {308, 308}, {309, 309}, {310, 310}, {311, 311}, {312, 312}, {313, 313}, {314, 314}, {315, 315}, {316, 316}, {317, 317}, {318, 318}, {319, 319}, {320, 320}, {321, 321}, {322, 322}, {323, 323}, {324, 324}, {325, 325}, {326, 326}, {327, 327}, {328, 328}, {329, 329}, {330, 330}, {331, 331}, {332, 332}, {333, 333}, {334, 334}}; + MainWindow *mw; +}; + +class TimeEdit : public QWidget +{ + Q_OBJECT +public: + TimeEdit(int id, MainWindow *mainWindow, QWidget *parent = nullptr); +signals: + void dataChanged(bool value); +public slots: + void updateSave(double d); + void updateData(); +private: + int id; + MainWindow *mw; + QDoubleSpinBox *data; + QLabel *label; +}; + +class PlotEdit : public QComboBox +{ + Q_OBJECT +public: + PlotEdit(int id, MainWindow *mainWindow, QWidget *parent = nullptr); +signals: + void dataChanged(bool value); +public slots: + void updateSave(int i); + void updateData(); +private: + int id; + double values[120] = {0, 1, 2, 3, 4, 4.5, 5, 5.5, 6, 7, 7.5, 8, 8.5, 9, 9.2, 9.4, 9.6, 9.8, 10.3, 10.35, 10.4, 11, 12, 13, 14, 15, 16, 17, 18, 19, 19.1, 19.2, 19.3, 19.4, 19.9, 20, 21, 22, 23, 24, 25, 28, 30, 36, 37, 40, 41, 42, 43, 47, 49, 50, 51, 53, 54, 56, 57, 58, 60, 61, 63, 65, 67, 100, 101, 104, 106, 107, 108, 109, 110, 111, 112, 113, 115, 116, 117, 118, 119, 120, 121, 122, 126, 127, 130, 131, 132, 133, 133.5, 134, 135, 137, 139, 140, 143, 146, 160, 161, 162, 163, 164, 165, 167, 168, 176, 177, 179, 180, 181, 182, 183, 184, 185, 193, 199, 201, 206, 207, 208, 999}; + QMap indexes{{0, 0}, {1, 1}, {2, 2}, {3, 3}, {4, 4}, {4.5, 5}, {5, 6}, {5.5, 7}, {6, 8}, {7, 9}, {7.5, 10}, {8, 11}, {8.5, 12}, {9, 13}, {9.2, 14}, {9.4, 15}, {9.6, 16}, {9.8, 17}, {10.3, 18}, {10.35, 19}, {10.4, 20}, {11, 21}, {12, 22}, {13, 23}, {14, 24}, {15, 25}, {16, 26}, {17, 27}, {18, 28}, {19, 29}, {19.1, 30}, {19.2, 31}, {19.3, 32}, {19.4, 33}, {19.9, 34}, {20, 35}, {21, 36}, {22, 37}, {23, 38}, {24, 39}, {25, 40}, {28, 41}, {30, 42}, {36, 43}, {37, 44}, {40, 45}, {41, 46}, {42, 47}, {43, 48}, {47, 49}, {49, 50}, {50, 51}, {51, 52}, {53, 53}, {54, 54}, {56, 55}, {57, 56}, {58, 57}, {60, 58}, {61, 59}, {63, 60}, {65, 61}, {67, 62}, {100, 63}, {101, 64}, {104, 65}, {106, 66}, {107, 67}, {108, 68}, {109, 69}, {110, 70}, {111, 71}, {112, 72}, {113, 73}, {115, 74}, {116, 75}, {117, 76}, {118, 77}, {119, 78}, {120, 79}, {121, 80}, {122, 81}, {126, 82}, {127, 83}, {130, 84}, {131, 85}, {132, 86}, {133, 87}, {133.5, 88}, {134, 89}, {135, 90}, {137, 91}, {139, 92}, {140, 93}, {143, 94}, {146, 95}, {160, 96}, {161, 97}, {162, 98}, {163, 99}, {164, 100}, {165, 101}, {167, 102}, {168, 103}, {176, 104}, {177, 105}, {179, 106}, {180, 107}, {181, 108}, {182, 109}, {183, 110}, {184, 111}, {185, 112}, {193, 113}, {199, 114}, {201, 115}, {206, 116}, {207, 117}, {208, 118}, {999, 119}}; + MainWindow *mw; +}; + +#endif // TOOLS_H diff --git a/version.json b/version.json index c8a53a3..d61663d 100644 --- a/version.json +++ b/version.json @@ -1,3 +1,3 @@ { - "version" : "0.4" + "version" : "1.0" } \ No newline at end of file