List element IDs that don't have an identifier associated in a save
36800a76cd
lists missing element identifiers but neglects to handle IDs that don't even have one associated.
This commit is contained in:
parent
66136c8866
commit
9f8449357f
@ -488,10 +488,24 @@ void PreviewView::ShowLoadError()
|
|||||||
void PreviewView::ShowMissingCustomElements()
|
void PreviewView::ShowMissingCustomElements()
|
||||||
{
|
{
|
||||||
StringBuilder sb;
|
StringBuilder sb;
|
||||||
sb << "This save uses custom elements that are not currently available. Make sure that you use the mod and/or have all the scripts the save requires to fully load. A list of identifiers of missing custom elements follows, which may help you determine how to fix this problem.\n";
|
sb << "This save uses custom elements that are not currently available. Make sure that you use the mod and/or have all the scripts the save requires to fully load.";
|
||||||
for (auto &identifier : missingElementTypes)
|
auto remainingIds = missingElements.ids;
|
||||||
|
if (missingElements.identifiers.size())
|
||||||
{
|
{
|
||||||
sb << "\n - " << identifier.FromUtf8();
|
sb << "\n\nA list of identifiers of missing custom elements follows, which may help you determine how to fix this problem.\n";
|
||||||
|
for (auto &[ identifier, id ] : missingElements.identifiers)
|
||||||
|
{
|
||||||
|
sb << "\n - " << identifier.FromUtf8();
|
||||||
|
remainingIds.erase(id); // remove ids from the missing id set that are already covered by unknown identifiers
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (remainingIds.size())
|
||||||
|
{
|
||||||
|
sb << "\n\nA list of element IDs of missing custom elements with no identifier associated follows. This can only be fixed by the author of the save.\n";
|
||||||
|
for (auto id : remainingIds)
|
||||||
|
{
|
||||||
|
sb << "\n - " << id;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
new InformationMessage("Missing custom elements", sb.Build(), true);
|
new InformationMessage("Missing custom elements", sb.Build(), true);
|
||||||
}
|
}
|
||||||
@ -556,10 +570,10 @@ void PreviewView::NotifySaveChanged(PreviewModel * sender)
|
|||||||
|
|
||||||
if(save->GetGameSave())
|
if(save->GetGameSave())
|
||||||
{
|
{
|
||||||
std::tie(savePreview, missingElementTypes) = SaveRenderer::Ref().Render(save->GetGameSave(), false, true);
|
std::tie(savePreview, missingElements) = SaveRenderer::Ref().Render(save->GetGameSave(), false, true);
|
||||||
if (savePreview)
|
if (savePreview)
|
||||||
savePreview->ResizeToFit(RES / 2, true);
|
savePreview->ResizeToFit(RES / 2, true);
|
||||||
missingElementsButton->Visible = missingElementTypes.size();
|
missingElementsButton->Visible = missingElements.identifiers.size() || missingElements.ids.size();
|
||||||
UpdateLoadStatus();
|
UpdateLoadStatus();
|
||||||
}
|
}
|
||||||
else if (!sender->GetCanOpen())
|
else if (!sender->GetCanOpen())
|
||||||
|
@ -4,6 +4,7 @@
|
|||||||
#include <vector>
|
#include <vector>
|
||||||
#include "common/String.h"
|
#include "common/String.h"
|
||||||
#include "gui/interface/Window.h"
|
#include "gui/interface/Window.h"
|
||||||
|
#include "simulation/MissingElements.h"
|
||||||
|
|
||||||
namespace http
|
namespace http
|
||||||
{
|
{
|
||||||
@ -27,7 +28,7 @@ class PreviewController;
|
|||||||
class PreviewView: public ui::Window
|
class PreviewView: public ui::Window
|
||||||
{
|
{
|
||||||
PreviewController *c{};
|
PreviewController *c{};
|
||||||
std::vector<ByteString> missingElementTypes;
|
MissingElements missingElements;
|
||||||
std::unique_ptr<VideoBuffer> savePreview;
|
std::unique_ptr<VideoBuffer> savePreview;
|
||||||
ui::Button *openButton{};
|
ui::Button *openButton{};
|
||||||
ui::Button *browserOpenButton{};
|
ui::Button *browserOpenButton{};
|
||||||
|
10
src/simulation/MissingElements.h
Normal file
10
src/simulation/MissingElements.h
Normal file
@ -0,0 +1,10 @@
|
|||||||
|
#pragma once
|
||||||
|
#include <set>
|
||||||
|
#include <map>
|
||||||
|
#include "common/String.h"
|
||||||
|
|
||||||
|
struct MissingElements
|
||||||
|
{
|
||||||
|
std::map<ByteString, int> identifiers;
|
||||||
|
std::set<int> ids;
|
||||||
|
};
|
@ -20,7 +20,7 @@ void SaveRenderer::Flush(int begin, int end)
|
|||||||
std::fill(ren->graphicscache + begin, ren->graphicscache + end, gcache_item());
|
std::fill(ren->graphicscache + begin, ren->graphicscache + end, gcache_item());
|
||||||
}
|
}
|
||||||
|
|
||||||
std::pair<std::unique_ptr<VideoBuffer>, std::vector<ByteString>> SaveRenderer::Render(const GameSave *save, bool decorations, bool fire, Renderer *renderModeSource)
|
std::pair<std::unique_ptr<VideoBuffer>, MissingElements> SaveRenderer::Render(const GameSave *save, bool decorations, bool fire, Renderer *renderModeSource)
|
||||||
{
|
{
|
||||||
std::lock_guard<std::mutex> gx(renderMutex);
|
std::lock_guard<std::mutex> gx(renderMutex);
|
||||||
|
|
||||||
|
@ -5,6 +5,7 @@
|
|||||||
#include <vector>
|
#include <vector>
|
||||||
#include "common/ExplicitSingleton.h"
|
#include "common/ExplicitSingleton.h"
|
||||||
#include "common/String.h"
|
#include "common/String.h"
|
||||||
|
#include "MissingElements.h"
|
||||||
|
|
||||||
class GameSave;
|
class GameSave;
|
||||||
class VideoBuffer;
|
class VideoBuffer;
|
||||||
@ -18,7 +19,7 @@ class SaveRenderer: public ExplicitSingleton<SaveRenderer> {
|
|||||||
std::mutex renderMutex;
|
std::mutex renderMutex;
|
||||||
public:
|
public:
|
||||||
SaveRenderer();
|
SaveRenderer();
|
||||||
std::pair<std::unique_ptr<VideoBuffer>, std::vector<ByteString>> Render(const GameSave *save, bool decorations = true, bool fire = true, Renderer *renderModeSource = nullptr);
|
std::pair<std::unique_ptr<VideoBuffer>, MissingElements> Render(const GameSave *save, bool decorations = true, bool fire = true, Renderer *renderModeSource = nullptr);
|
||||||
void Flush(int begin, int end);
|
void Flush(int begin, int end);
|
||||||
virtual ~SaveRenderer();
|
virtual ~SaveRenderer();
|
||||||
};
|
};
|
||||||
|
@ -19,9 +19,9 @@ extern int Element_LOLZ_lolz[XRES/9][YRES/9];
|
|||||||
extern int Element_LOVE_RuleTable[9][9];
|
extern int Element_LOVE_RuleTable[9][9];
|
||||||
extern int Element_LOVE_love[XRES/9][YRES/9];
|
extern int Element_LOVE_love[XRES/9][YRES/9];
|
||||||
|
|
||||||
std::vector<ByteString> Simulation::Load(const GameSave *save, bool includePressure, Vec2<int> blockP) // block coordinates
|
MissingElements Simulation::Load(const GameSave *save, bool includePressure, Vec2<int> blockP) // block coordinates
|
||||||
{
|
{
|
||||||
std::vector<ByteString> missingElementTypes;
|
MissingElements missingElements;
|
||||||
auto partP = blockP * CELL;
|
auto partP = blockP * CELL;
|
||||||
unsigned int pmapmask = (1<<save->pmapbits)-1;
|
unsigned int pmapmask = (1<<save->pmapbits)-1;
|
||||||
|
|
||||||
@ -54,11 +54,23 @@ std::vector<ByteString> Simulation::Load(const GameSave *save, bool includePress
|
|||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
missingElementTypes.push_back(pi.first);
|
missingElements.identifiers.insert(pi);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
auto paletteLookup = [&partMap, &missingElements](int type) {
|
||||||
|
if (type > 0 && type < PT_NUM)
|
||||||
|
{
|
||||||
|
auto carriedType = partMap[type];
|
||||||
|
if (!carriedType) // type is not 0 so this shouldn't be 0 either
|
||||||
|
{
|
||||||
|
missingElements.ids.insert(type);
|
||||||
|
}
|
||||||
|
type = carriedType;
|
||||||
|
}
|
||||||
|
return type;
|
||||||
|
};
|
||||||
|
|
||||||
RecalcFreeParticles(false);
|
RecalcFreeParticles(false);
|
||||||
|
|
||||||
@ -86,7 +98,7 @@ std::vector<ByteString> Simulation::Load(const GameSave *save, bool includePress
|
|||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
tempPart.type = partMap[tempPart.type];
|
tempPart.type = paletteLookup(tempPart.type);
|
||||||
for (auto index : possiblyCarriesType)
|
for (auto index : possiblyCarriesType)
|
||||||
{
|
{
|
||||||
if (elements[tempPart.type].CarriesTypeIn & (1U << index))
|
if (elements[tempPart.type].CarriesTypeIn & (1U << index))
|
||||||
@ -94,10 +106,7 @@ std::vector<ByteString> Simulation::Load(const GameSave *save, bool includePress
|
|||||||
auto *prop = reinterpret_cast<int *>(reinterpret_cast<char *>(&tempPart) + properties[index].Offset);
|
auto *prop = reinterpret_cast<int *>(reinterpret_cast<char *>(&tempPart) + properties[index].Offset);
|
||||||
auto carriedType = *prop & int(pmapmask);
|
auto carriedType = *prop & int(pmapmask);
|
||||||
auto extra = *prop >> save->pmapbits;
|
auto extra = *prop >> save->pmapbits;
|
||||||
if (carriedType >= 0 && carriedType < PT_NUM)
|
carriedType = paletteLookup(carriedType);
|
||||||
{
|
|
||||||
carriedType = partMap[carriedType];
|
|
||||||
}
|
|
||||||
*prop = PMAP(extra, carriedType);
|
*prop = PMAP(extra, carriedType);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -329,7 +338,7 @@ std::vector<ByteString> Simulation::Load(const GameSave *save, bool includePress
|
|||||||
air->ApproximateBlockAirMaps();
|
air->ApproximateBlockAirMaps();
|
||||||
}
|
}
|
||||||
|
|
||||||
return missingElementTypes;
|
return missingElements;
|
||||||
}
|
}
|
||||||
|
|
||||||
std::unique_ptr<GameSave> Simulation::Save(bool includePressure, Rect<int> partR) // particle coordinates
|
std::unique_ptr<GameSave> Simulation::Save(bool includePressure, Rect<int> partR) // particle coordinates
|
||||||
|
@ -11,6 +11,7 @@
|
|||||||
#include "common/tpt-rand.h"
|
#include "common/tpt-rand.h"
|
||||||
#include "Element.h"
|
#include "Element.h"
|
||||||
#include "SimulationConfig.h"
|
#include "SimulationConfig.h"
|
||||||
|
#include "MissingElements.h"
|
||||||
#include <cstring>
|
#include <cstring>
|
||||||
#include <cstddef>
|
#include <cstddef>
|
||||||
#include <vector>
|
#include <vector>
|
||||||
@ -121,7 +122,7 @@ public:
|
|||||||
uint64_t frameCount;
|
uint64_t frameCount;
|
||||||
bool ensureDeterminism;
|
bool ensureDeterminism;
|
||||||
|
|
||||||
std::vector<ByteString> Load(const GameSave *save, bool includePressure, Vec2<int> blockP); // block coordinates
|
MissingElements Load(const GameSave *save, bool includePressure, Vec2<int> blockP); // block coordinates
|
||||||
std::unique_ptr<GameSave> Save(bool includePressure, Rect<int> partR); // particle coordinates
|
std::unique_ptr<GameSave> Save(bool includePressure, Rect<int> partR); // particle coordinates
|
||||||
void SaveSimOptions(GameSave &gameSave);
|
void SaveSimOptions(GameSave &gameSave);
|
||||||
SimulationSample GetSample(int x, int y);
|
SimulationSample GetSample(int x, int y);
|
||||||
|
Loading…
Reference in New Issue
Block a user