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()
|
||||
{
|
||||
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";
|
||||
for (auto &identifier : missingElementTypes)
|
||||
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.";
|
||||
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);
|
||||
}
|
||||
@ -556,10 +570,10 @@ void PreviewView::NotifySaveChanged(PreviewModel * sender)
|
||||
|
||||
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)
|
||||
savePreview->ResizeToFit(RES / 2, true);
|
||||
missingElementsButton->Visible = missingElementTypes.size();
|
||||
missingElementsButton->Visible = missingElements.identifiers.size() || missingElements.ids.size();
|
||||
UpdateLoadStatus();
|
||||
}
|
||||
else if (!sender->GetCanOpen())
|
||||
|
@ -4,6 +4,7 @@
|
||||
#include <vector>
|
||||
#include "common/String.h"
|
||||
#include "gui/interface/Window.h"
|
||||
#include "simulation/MissingElements.h"
|
||||
|
||||
namespace http
|
||||
{
|
||||
@ -27,7 +28,7 @@ class PreviewController;
|
||||
class PreviewView: public ui::Window
|
||||
{
|
||||
PreviewController *c{};
|
||||
std::vector<ByteString> missingElementTypes;
|
||||
MissingElements missingElements;
|
||||
std::unique_ptr<VideoBuffer> savePreview;
|
||||
ui::Button *openButton{};
|
||||
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::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);
|
||||
|
||||
|
@ -5,6 +5,7 @@
|
||||
#include <vector>
|
||||
#include "common/ExplicitSingleton.h"
|
||||
#include "common/String.h"
|
||||
#include "MissingElements.h"
|
||||
|
||||
class GameSave;
|
||||
class VideoBuffer;
|
||||
@ -18,7 +19,7 @@ class SaveRenderer: public ExplicitSingleton<SaveRenderer> {
|
||||
std::mutex renderMutex;
|
||||
public:
|
||||
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);
|
||||
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_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;
|
||||
unsigned int pmapmask = (1<<save->pmapbits)-1;
|
||||
|
||||
@ -54,11 +54,23 @@ std::vector<ByteString> Simulation::Load(const GameSave *save, bool includePress
|
||||
}
|
||||
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);
|
||||
|
||||
@ -86,7 +98,7 @@ std::vector<ByteString> Simulation::Load(const GameSave *save, bool includePress
|
||||
continue;
|
||||
}
|
||||
|
||||
tempPart.type = partMap[tempPart.type];
|
||||
tempPart.type = paletteLookup(tempPart.type);
|
||||
for (auto index : possiblyCarriesType)
|
||||
{
|
||||
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 carriedType = *prop & int(pmapmask);
|
||||
auto extra = *prop >> save->pmapbits;
|
||||
if (carriedType >= 0 && carriedType < PT_NUM)
|
||||
{
|
||||
carriedType = partMap[carriedType];
|
||||
}
|
||||
carriedType = paletteLookup(carriedType);
|
||||
*prop = PMAP(extra, carriedType);
|
||||
}
|
||||
}
|
||||
@ -329,7 +338,7 @@ std::vector<ByteString> Simulation::Load(const GameSave *save, bool includePress
|
||||
air->ApproximateBlockAirMaps();
|
||||
}
|
||||
|
||||
return missingElementTypes;
|
||||
return missingElements;
|
||||
}
|
||||
|
||||
std::unique_ptr<GameSave> Simulation::Save(bool includePressure, Rect<int> partR) // particle coordinates
|
||||
|
@ -11,6 +11,7 @@
|
||||
#include "common/tpt-rand.h"
|
||||
#include "Element.h"
|
||||
#include "SimulationConfig.h"
|
||||
#include "MissingElements.h"
|
||||
#include <cstring>
|
||||
#include <cstddef>
|
||||
#include <vector>
|
||||
@ -121,7 +122,7 @@ public:
|
||||
uint64_t frameCount;
|
||||
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
|
||||
void SaveSimOptions(GameSave &gameSave);
|
||||
SimulationSample GetSample(int x, int y);
|
||||
|
Loading…
Reference in New Issue
Block a user