Skip to content

Commit

Permalink
Item filters rework.
Browse files Browse the repository at this point in the history
  • Loading branch information
mapron committed Jan 15, 2022
1 parent 6d270d2 commit 248b0a7
Show file tree
Hide file tree
Showing 9 changed files with 131 additions and 51 deletions.
3 changes: 1 addition & 2 deletions src/CascWrapper.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -74,8 +74,7 @@ bool ExtractTables(const QString& d2rpath, GenOutput& output, const JsonFileSet&

auto loadDoc(QJsonDocument::fromJson(buffer));

auto data = loadDoc.object();
output.jsonFiles[path] = data;
output.jsonFiles[path] = loadDoc;
}

return true;
Expand Down
6 changes: 3 additions & 3 deletions src/CommonTypes.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -58,9 +58,9 @@ struct CopyFileInfo {
};

struct GenOutput {
TableSet tableSet;
QMap<QString, QJsonObject> jsonFiles;
QList<CopyFileInfo> copyFiles;
TableSet tableSet;
QMap<QString, QJsonDocument> jsonFiles;
QList<CopyFileInfo> copyFiles;
};

class IConfigPage : public QWidget {
Expand Down
131 changes: 99 additions & 32 deletions src/ConfigPageDropFiltering.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,30 @@
#include "ConfigPageDropFiltering.hpp"

#include <QLabel>
#include <QJsonDocument>
#include <QJsonArray>

namespace {
const QString s_itemnamesJson = "data\\local\\lng\\strings\\item-names.json";
const QString s_affixnamesJson = "data\\local\\lng\\strings\\item-nameaffixes.json";

const QLatin1String s_colorLightGray("\xC3\xBF\x63\x30"); // (Item Descriptions)
const QLatin1String s_colorRed("\xC3\xBF\x63\x31"); //
const QLatin1String s_colorBrightGreen("\xC3\xBF\x63\x32"); // (Set Items)
const QLatin1String s_colorBlue("\xC3\xBF\x63\x33"); // (Magic Items)
const QLatin1String s_colorGold("\xC3\xBF\x63\x34"); // (Unique Items)
const QLatin1String s_colorDarkGray("\xC3\xBF\x63\x35"); // (Socketed/Ethereal Items)
const QLatin1String s_colorTransparent("\xC3\xBF\x63\x36"); // (Text Doesn't Show)
const QLatin1String s_colorTan("\xC3\xBF\x63\x37"); //
const QLatin1String s_colorOrange("\xC3\xBF\x63\x38"); // (Crafted Items)
const QLatin1String s_colorYellow("\xC3\xBF\x63\x39"); // (Rare Items)
const QLatin1String s_colorDarkGreen("\xC3\xBF\x63\x3A"); //
const QLatin1String s_colorPurple("\xC3\xBF\x63\x3B"); //
const QLatin1String s_colorWhite("\xC3\xBF\x63\x2F"); // (Brighter than Light Gray)

const QString s_hidden = QString("%1").arg(s_colorTransparent);

}

ConfigPageDropFiltering::ConfigPageDropFiltering(QWidget* parent)
: ConfigPageAbstract(parent)
Expand All @@ -18,57 +42,100 @@ ConfigPageDropFiltering::ConfigPageDropFiltering(QWidget* parent)
{ { "mp1", "mp2", "mp3", "mp4", "mp5" }, "mpsa", "All Mana pots" },
{ { "rvs" }, "rvs", "Rejuv pots" },
{ { "rvl" }, "rvl", "Full Rejuv pots" },
{ { "Ammo" }, "ammo", "Bolts/Arrows" },
{ { "vps", "yps", "wms" }, "ammo", "Stamina/Antidote/Thawing" },
{ { "Misc 0", "Misc 1", "Misc 2" }, "junks", "Keys/Fire/Poison pots" },
{ { "aqv", "cqv" }, "ammo", "Bolts/Arrows" },
{ { "vps", "yps", "wms" }, "stam", "Stamina/Antidote/Thawing" },
{ { "key", "opl", "opm", "ops", "gpl", "gpm", "gps" }, "junks", "Keys,Fire/Poison pots" },
}

{
addWidget(new QLabel("<b>Warning</b>: please note, there is no real way to filter drops in D2R;<br>"
"Instead of filtering loot, we just make it to not drop at all instead.<br>"
"In practice, it's the same for user, but you have no way to pick an item if you changed you mind.<br>"
"Other approach - is to change item tag to something really short - that solution require <br>"
"localization edits, which is possible, but not yet supported.<br>"
"All options below just <b>replace drops with NoDrop</b>, so no real affect on probabilities of other items."
addWidget(new QLabel("<b>Make item names compact</b>: this will make item names take less space, e.g. '!HP2' for health potion.",
this));
addEditors(QList<IValueWidget*>()
<< new CheckboxWidget("Compact potion names", "compact_pots", false, this)
<< new CheckboxWidget("Compact TP/ID scrolls", "compact_scrolls", false, this));

,
addWidget(new QLabel("<b>Hide items on the ground</b>: this will make item names transparent; <br>"
"you still can pickup them, but their labels will be invisible on Alt press.<br>"
"<b>Note</b>: affects only en-US locale.",
this));
for (auto& item : m_items)
addEditors(QList<IValueWidget*>()
<< new CheckboxWidget("Disable " + item.title, "nodrop_" + item.settingKey, false, this));
<< new CheckboxWidget("Hide " + item.title, "hide_" + item.settingKey, false, this));

addEditors(QList<IValueWidget*>()
<< new CheckboxWidget("Hide low quality/damaged/cracked items", "hide_lowq", false, this));
closeLayout();
}

JsonFileSet ConfigPageDropFiltering::extraFiles() const
{
if (isAllDefault())
return {};

return { s_itemnamesJson, s_affixnamesJson };
}

KeySet ConfigPageDropFiltering::generate(GenOutput& output, QRandomGenerator& rng, const GenerationEnvironment& env) const
{
if (isAllDefault())
return {};
KeySet result;
result << "treasureclassex";

TableView view(output.tableSet.tables["treasureclassex"]);

QSet<QString> disabledIds;
for (auto& item : m_items) {
const bool disable = getWidgetValue("nodrop_" + item.settingKey);
if (disable)
disabledIds += item.internalIds;
auto replaceJson = [&output](const QMap<QString, QString>& replacements, const QString& name) {
if (replacements.isEmpty())
return;
auto& jsonDoc = output.jsonFiles[name];
auto jsonArray = jsonDoc.array();
for (QJsonValueRef lang : jsonArray) {
QJsonObject obj = lang.toObject();
const QString key = obj["Key"].toString();
if (replacements.contains(key))
obj["enUS"] = replacements[key];
lang = obj;
}
jsonDoc.setArray(jsonArray);
};
QMap<QString, QString> replacementsItems;
QMap<QString, QString> replacementsAffix;
if (getWidgetValue("compact_pots")) {
replacementsItems.insert(QMap<QString, QString>{
{ "mp1", QString("%1!%2MP1").arg(s_colorBlue).arg(s_colorLightGray) },
{ "mp2", QString("%1!%2MP2").arg(s_colorBlue).arg(s_colorLightGray) },
{ "mp3", QString("%1!%2MP3").arg(s_colorBlue).arg(s_colorLightGray) },
{ "mp4", QString("%1!%2MP4").arg(s_colorBlue).arg(s_colorLightGray) },
{ "mp5", QString("%1!%2MP5").arg(s_colorBlue).arg(s_colorLightGray) },
{ "hp1", QString("%1!%2HP1").arg(s_colorRed).arg(s_colorLightGray) },
{ "hp2", QString("%1!%2HP2").arg(s_colorRed).arg(s_colorLightGray) },
{ "hp3", QString("%1!%2HP3").arg(s_colorRed).arg(s_colorLightGray) },
{ "hp4", QString("%1!%2HP4").arg(s_colorRed).arg(s_colorLightGray) },
{ "hp5", QString("%1!%2HP5").arg(s_colorRed).arg(s_colorLightGray) },
{ "rvs", QString("%1Rej%2").arg(s_colorPurple).arg(s_colorLightGray) },
{ "rvl", QString("%1Full%2").arg(s_colorPurple).arg(s_colorLightGray) },
});
}
if (getWidgetValue("compact_scrolls")) {
replacementsItems.insert(QMap<QString, QString>{
{ "tsc", QString("%1•%2TP").arg(s_colorBlue).arg(s_colorLightGray) },
{ "isc", QString("%1•%2ID").arg(s_colorRed).arg(s_colorLightGray) },
});
}
if (!disabledIds.empty()) {
for (auto& row : view) {
DropSet dropSet;
dropSet.readRow(row);
for (int i = dropSet.m_items.size() - 1; i >= 0; i--) {
auto& dropItem = dropSet.m_items[i];
QString& tcName = dropItem.tc;
if (disabledIds.contains(tcName)) {
dropSet.m_noDrop += dropItem.prob;
dropSet.m_items.removeAt(i);
}
}
dropSet.writeRow(row);
if (getWidgetValue("hide_lowq")) {
replacementsAffix.insert(QMap<QString, QString>{
{ "Low Quality", s_hidden },
{ "Damaged", s_hidden },
{ "Cracked", s_hidden },
{ "Crude", s_hidden },
});
}
for (const auto& item : m_items) {
if (getWidgetValue("hide_" + item.settingKey)) {
for (auto& id : item.internalIds)
replacementsItems.insert(id, s_hidden);
}
}

replaceJson(replacementsItems, s_itemnamesJson);
replaceJson(replacementsAffix, s_affixnamesJson);

return result;
}
1 change: 1 addition & 0 deletions src/ConfigPageDropFiltering.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -28,5 +28,6 @@ class ConfigPageDropFiltering : public ConfigPageAbstract {
{
return "drop_filter";
}
JsonFileSet extraFiles() const override;
KeySet generate(GenOutput& output, QRandomGenerator& rng, const GenerationEnvironment& env) const override;
};
6 changes: 5 additions & 1 deletion src/ConfigPageMonRandomizer.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,8 @@
*/
#include "ConfigPageMonRandomizer.hpp"

#include <QJsonDocument>

namespace {

constexpr const int s_maxIngameLevel = 110;
Expand Down Expand Up @@ -318,14 +320,16 @@ KeySet ConfigPageMonRandomizer::generate(GenOutput& output, QRandomGenerator& rn
typeTable.newCopies = std::move(newCopies);
}
if (output.jsonFiles.contains(s_monstersJson)) {
auto& jsonObject = output.jsonFiles[s_monstersJson];
auto& jsonDoc = output.jsonFiles[s_monstersJson];
auto jsonObject = jsonDoc.object();
for (const auto& copy : typeTable.newCopies) {
const auto& sourceId = copy.sourceId;
const auto& newId = copy.newId;
const auto modelName = jsonObject[sourceId].toString();
assert(!modelName.isEmpty());
jsonObject[newId] = modelName;
}
jsonDoc.setObject(jsonObject);
}

return result;
Expand Down
10 changes: 7 additions & 3 deletions src/MainConfigPage.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@
#include <QFileInfo>
#include <QDir>
#include <QMessageBox>
#include <QJsonDocument>

namespace {

Expand Down Expand Up @@ -386,16 +387,19 @@ void MainConfigPage::setLaunch(QString arg)
QMessageBox::warning(this, "warning", "Failed to locate Battle.net.config");
return;
}
QJsonObject data;
if (!readJsonFile(config, data)) {
QJsonDocument doc;
if (!readJsonFile(config, doc)) {
QMessageBox::warning(this, "warning", "Failed to read data from Battle.net.config");
return;
}
QJsonObject data = doc.object();

auto valGames = data["Games"].toObject();
auto valOsi = valGames["osi"].toObject();
valOsi["AdditionalLaunchArguments"] = arg;
valGames["osi"] = valOsi;
data["Games"] = valGames;
if (!writeJsonFile(config, data, true))
doc.setObject(data);
if (!writeJsonFile(config, doc, true))
QMessageBox::warning(this, "warning", "Failed to write data to Battle.net.config");
}
10 changes: 6 additions & 4 deletions src/MainWindow.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,7 @@
#include <QFileDialog>
#include <QProcess>
#include <QLabel>
#include <QJsonDocument>
#include <QDesktopServices>

MainWindow::MainWindow()
Expand Down Expand Up @@ -183,7 +184,7 @@ void MainWindow::generate(const GenerationEnvironment& env)
QJsonObject modinfo;
modinfo["name"] = env.modName;
modinfo["savepath"] = env.modName + "/";
if (!writeJsonFile(modRoot + "modinfo.json", modinfo)) {
if (!writeJsonFile(modRoot + "modinfo.json", QJsonDocument(modinfo))) {
QMessageBox::warning(this, "error", "Failed to write modinfo.");
return;
}
Expand Down Expand Up @@ -259,14 +260,15 @@ bool MainWindow::saveConfig(const QString& filename) const
data[page->settingKey()] = pageData;
}
QDir().mkpath(QFileInfo(filename).absolutePath());
return writeJsonFile(filename, data);
return writeJsonFile(filename, QJsonDocument(data));
}

bool MainWindow::loadConfig(const QString& filename)
{
QJsonObject data;
if (!readJsonFile(filename, data))
QJsonDocument doc;
if (!readJsonFile(filename, doc))
return false;
QJsonObject data = doc.object();

{
for (auto* page : m_pages)
Expand Down
11 changes: 7 additions & 4 deletions src/Utils.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@
#include <QFile>
#include <QJsonDocument>

bool readJsonFile(const QString& file, QJsonObject& data)
bool readJsonFile(const QString& file, QJsonDocument& data)
{
QFile loadFile(file);

Expand All @@ -20,21 +20,24 @@ bool readJsonFile(const QString& file, QJsonObject& data)

QJsonDocument loadDoc(QJsonDocument::fromJson(saveData));

data = loadDoc.object();
data = loadDoc;

return true;
}

bool writeJsonFile(const QString& file, const QJsonObject& data, bool escape)
bool writeJsonFile(const QString& file, const QJsonDocument& data, bool escape)
{
QFile saveFile(file);

if (!saveFile.open(QIODevice::WriteOnly)) {
return false;
}
QByteArray datastr = QJsonDocument(data).toJson(QJsonDocument::Indented);
QByteArray datastr = data.toJson(QJsonDocument::Indented);
if (escape)
datastr.replace(QByteArray("/"), QByteArray("\\/")); // weird battlenet format.

datastr.replace(QByteArray("\xC3\x83\xC2\xBF\x63"), QByteArray("\xC3\xBF\x63")); // hack: replace color codes converter to UTF-8 from latin-1.

saveFile.write(datastr);

return true;
Expand Down
4 changes: 2 additions & 2 deletions src/Utils.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -7,8 +7,8 @@

#include "CommonTypes.hpp"

bool readJsonFile(const QString& file, QJsonObject& data);
bool writeJsonFile(const QString& file, const QJsonObject& data, bool escape = false);
bool readJsonFile(const QString& file, QJsonDocument& data);
bool writeJsonFile(const QString& file, const QJsonDocument& data, bool escape = false);

bool readCSV(const QString& csvData, Table& table);
bool writeCSV(QString& csvData, const Table& table);
Expand Down

0 comments on commit 248b0a7

Please sign in to comment.