Merge branch 'The-Powder-Toy:master' into paper
This commit is contained in:
commit
5613bf70f5
@ -212,6 +212,7 @@ if host_platform == 'emscripten'
|
||||
'-s', 'FS_DEBUG',
|
||||
'-s', 'MODULARIZE',
|
||||
'-s', 'EXPORT_NAME=create_' + app_exe,
|
||||
'-Wl,-u,_emscripten_run_callback_on_thread',
|
||||
'-lidbfs.js',
|
||||
]
|
||||
emcc_args = [
|
||||
|
@ -54,7 +54,7 @@ option(
|
||||
'build_num',
|
||||
type: 'integer',
|
||||
min: 0,
|
||||
value: 353,
|
||||
value: 354,
|
||||
description: 'Build number, should be strictly monotonously increasing across public releases'
|
||||
)
|
||||
option(
|
||||
@ -75,7 +75,7 @@ option(
|
||||
'upstream_build_num',
|
||||
type: 'integer',
|
||||
min: 0,
|
||||
value: 353,
|
||||
value: 354,
|
||||
description: 'Upstream build number, mod owners should not change this but merge upstream changes to it'
|
||||
)
|
||||
option(
|
||||
|
@ -12,6 +12,7 @@
|
||||
#include "common/platform/Platform.h"
|
||||
#include "graphics/Graphics.h"
|
||||
#include "simulation/SaveRenderer.h"
|
||||
#include "simulation/SimulationData.h"
|
||||
#include "common/tpt-rand.h"
|
||||
#include "gui/game/Favorite.h"
|
||||
#include "gui/Style.h"
|
||||
@ -180,6 +181,7 @@ struct ExplicitSingletons
|
||||
std::unique_ptr<SaveRenderer> saveRenderer;
|
||||
std::unique_ptr<Favorite> favorite;
|
||||
std::unique_ptr<ui::Engine> engine;
|
||||
std::unique_ptr<SimulationData> simulationData;
|
||||
std::unique_ptr<GameController> gameController;
|
||||
};
|
||||
static std::unique_ptr<ExplicitSingletons> explicitSingletons;
|
||||
@ -416,6 +418,7 @@ int Main(int argc, char *argv[])
|
||||
}
|
||||
|
||||
auto wrapWithBluescreen = [&]() {
|
||||
explicitSingletons->simulationData = std::make_unique<SimulationData>();
|
||||
explicitSingletons->gameController = std::make_unique<GameController>();
|
||||
auto *gameController = explicitSingletons->gameController.get();
|
||||
engine.ShowWindow(gameController->GetView());
|
||||
|
@ -6,6 +6,7 @@
|
||||
#include "gui/interface/Engine.h"
|
||||
#include "client/GameSave.h"
|
||||
#include "simulation/Simulation.h"
|
||||
#include "simulation/SimulationData.h"
|
||||
#include "common/platform/Platform.h"
|
||||
#include <ctime>
|
||||
#include <iostream>
|
||||
@ -39,6 +40,7 @@ int main(int argc, char *argv[])
|
||||
throw e;
|
||||
}
|
||||
|
||||
auto simulationData = std::make_unique<SimulationData>();
|
||||
Simulation * sim = new Simulation();
|
||||
Renderer * ren = new Renderer(sim);
|
||||
|
||||
|
@ -61,3 +61,5 @@ constexpr float GLASS_IOR = 1.9f;
|
||||
constexpr float GLASS_DISP = 0.07f;
|
||||
|
||||
constexpr float R_TEMP = 22;
|
||||
|
||||
constexpr bool LATENTHEAT = false;
|
||||
|
@ -3,6 +3,7 @@
|
||||
#include "Format.h"
|
||||
#include "simulation/Simulation.h"
|
||||
#include "simulation/ElementClasses.h"
|
||||
#include "simulation/elements/PIPE.h"
|
||||
#include "common/tpt-compat.h"
|
||||
#include "bson/BSON.h"
|
||||
#include "graphics/Renderer.h"
|
||||
@ -46,6 +47,86 @@ GameSave::GameSave(const std::vector<char> &data, bool newWantAuthors)
|
||||
}
|
||||
}
|
||||
|
||||
void GameSave::MapPalette()
|
||||
{
|
||||
int partMap[PT_NUM];
|
||||
for(int i = 0; i < PT_NUM; i++)
|
||||
{
|
||||
partMap[i] = i;
|
||||
}
|
||||
|
||||
auto &sd = SimulationData::CRef();
|
||||
auto &elements = sd.elements;
|
||||
if(palette.size())
|
||||
{
|
||||
if (version >= Version(98, 0))
|
||||
{
|
||||
for(int i = 0; i < PT_NUM; i++)
|
||||
{
|
||||
partMap[i] = 0;
|
||||
}
|
||||
}
|
||||
for(auto &pi : palette)
|
||||
{
|
||||
if (pi.second > 0 && pi.second < PT_NUM)
|
||||
{
|
||||
int myId = 0;
|
||||
for (int i = 0; i < PT_NUM; i++)
|
||||
{
|
||||
if (elements[i].Enabled && elements[i].Identifier == pi.first)
|
||||
{
|
||||
myId = i;
|
||||
}
|
||||
}
|
||||
if (myId)
|
||||
{
|
||||
partMap[pi.second] = myId;
|
||||
}
|
||||
else
|
||||
{
|
||||
missingElements.identifiers.insert(pi);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
auto paletteLookup = [this, &partMap](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;
|
||||
};
|
||||
|
||||
unsigned int pmapmask = (1<<pmapbits)-1;
|
||||
auto &possiblyCarriesType = Particle::PossiblyCarriesType();
|
||||
auto &properties = Particle::GetProperties();
|
||||
for (int n = 0; n < NPART && n < particlesCount; n++)
|
||||
{
|
||||
Particle &tempPart = particles[n];
|
||||
if (tempPart.type <= 0 || tempPart.type >= PT_NUM)
|
||||
{
|
||||
continue;
|
||||
}
|
||||
tempPart.type = paletteLookup(tempPart.type);
|
||||
for (auto index : possiblyCarriesType)
|
||||
{
|
||||
if (elements[tempPart.type].CarriesTypeIn & (1U << index))
|
||||
{
|
||||
auto *prop = reinterpret_cast<int *>(reinterpret_cast<char *>(&tempPart) + properties[index].Offset);
|
||||
auto carriedType = *prop & int(pmapmask);
|
||||
auto extra = *prop >> pmapbits;
|
||||
carriedType = paletteLookup(carriedType);
|
||||
*prop = PMAP(extra, carriedType);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void GameSave::Expand(const std::vector<char> &data)
|
||||
{
|
||||
try
|
||||
@ -67,6 +148,7 @@ void GameSave::Expand(const std::vector<char> &data)
|
||||
std::cerr << "Got Magic number '" << data[0] << data[1] << data[2] << "'" << std::endl;
|
||||
throw ParseException(ParseException::Corrupt, "Invalid save format");
|
||||
}
|
||||
MapPalette();
|
||||
}
|
||||
else
|
||||
{
|
||||
@ -114,9 +196,6 @@ std::pair<bool, std::vector<char>> GameSave::Serialise() const
|
||||
return { false, {} };
|
||||
}
|
||||
|
||||
extern const std::array<Vec2<int>, 8> Element_PIPE_offsets;
|
||||
void Element_PIPE_transformPatchOffsets(Particle &part, const std::array<int, 8> &offsetMap);
|
||||
|
||||
void GameSave::Transform(Mat2<int> transform, Vec2<int> nudge)
|
||||
{
|
||||
// undo translation by rotation
|
||||
@ -328,6 +407,7 @@ static void CheckBsonFieldFloat(bson_iterator iter, const char *field, float *se
|
||||
|
||||
void GameSave::readOPS(const std::vector<char> &data)
|
||||
{
|
||||
auto &builtinGol = SimulationData::builtinGol;
|
||||
constexpr auto currentVersion = Version(currentVersionMajor, 0);
|
||||
constexpr auto nextVersion = Version(nextVersionMajor, 0);
|
||||
|
||||
@ -1185,6 +1265,7 @@ void GameSave::readOPS(const std::vector<char> &data)
|
||||
#define MTOS(str) MTOS_EXPAND(str)
|
||||
void GameSave::readPSv(const std::vector<char> &dataVec)
|
||||
{
|
||||
auto &builtinGol = SimulationData::builtinGol;
|
||||
Renderer::PopulateTables();
|
||||
|
||||
unsigned char * saveData = (unsigned char *)&dataVec[0];
|
||||
@ -1197,7 +1278,7 @@ void GameSave::readPSv(const std::vector<char> &dataVec)
|
||||
char tempSignText[255];
|
||||
sign tempSign("", 0, 0, sign::Left);
|
||||
|
||||
auto &elements = GetElements();
|
||||
auto &builtinElements = GetElements();
|
||||
|
||||
//New file header uses PSv, replacing fuC. This is to detect if the client uses a new save format for temperatures
|
||||
//This creates a problem for old clients, that display and "corrupt" error instead of a "newer version" error
|
||||
@ -1607,7 +1688,7 @@ void GameSave::readPSv(const std::vector<char> &dataVec)
|
||||
}
|
||||
else
|
||||
{
|
||||
particles[i-1].temp = elements[particles[i-1].type].DefaultProperties.temp;
|
||||
particles[i-1].temp = builtinElements[particles[i-1].type].DefaultProperties.temp;
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -1970,7 +2051,7 @@ std::pair<bool, std::vector<char>> GameSave::serialiseOPS() const
|
||||
That way, if we ever need a 25th bit, we won't have to change the save format
|
||||
*/
|
||||
|
||||
auto &elements = GetElements();
|
||||
auto &builtinElements = GetElements();
|
||||
auto &possiblyCarriesType = Particle::PossiblyCarriesType();
|
||||
auto &properties = Particle::GetProperties();
|
||||
// Allocate enough space to store all Particles and 3 bytes on top of that per Particle, for the field descriptors.
|
||||
@ -1980,6 +2061,9 @@ std::pair<bool, std::vector<char>> GameSave::serialiseOPS() const
|
||||
std::vector<unsigned> partsSaveIndex(NPART);
|
||||
unsigned int partsCount = 0;
|
||||
std::fill(&partsSaveIndex[0], &partsSaveIndex[0] + NPART, 0);
|
||||
auto &sd = SimulationData::CRef();
|
||||
auto &elements = sd.elements;
|
||||
std::set<int> paletteSet;
|
||||
for (auto pos : partS.OriginRect().Range<TOP_TO_BOTTOM, LEFT_TO_RIGHT>())
|
||||
{
|
||||
//Find the first particle in this position
|
||||
@ -1997,6 +2081,16 @@ std::pair<bool, std::vector<char>> GameSave::serialiseOPS() const
|
||||
//Store saved particle index+1 for this partsptr index (0 means not saved)
|
||||
partsSaveIndex[i] = (partsCount++) + 1;
|
||||
|
||||
paletteSet.insert(particles[i].type);
|
||||
for (auto index : possiblyCarriesType)
|
||||
{
|
||||
if (elements[particles[i].type].CarriesTypeIn & (1U << index))
|
||||
{
|
||||
auto *prop = reinterpret_cast<const int *>(reinterpret_cast<const char *>(&particles[i]) + properties[index].Offset);
|
||||
paletteSet.insert(TYP(*prop));
|
||||
}
|
||||
}
|
||||
|
||||
//Type (required)
|
||||
partsData[partsDataLen++] = particles[i].type;
|
||||
|
||||
@ -2200,7 +2294,7 @@ std::pair<bool, std::vector<char>> GameSave::serialiseOPS() const
|
||||
{
|
||||
for (auto index : possiblyCarriesType)
|
||||
{
|
||||
if (elements[particles[i].type].CarriesTypeIn & (1U << index))
|
||||
if (builtinElements[particles[i].type].CarriesTypeIn & (1U << index))
|
||||
{
|
||||
auto *prop = reinterpret_cast<const int *>(reinterpret_cast<const char *>(&particles[i]) + properties[index].Offset);
|
||||
if (TYP(*prop) > 0xFF)
|
||||
@ -2250,6 +2344,12 @@ std::pair<bool, std::vector<char>> GameSave::serialiseOPS() const
|
||||
}
|
||||
}
|
||||
|
||||
std::vector<PaletteItem> paletteData;
|
||||
for (int ID : paletteSet)
|
||||
{
|
||||
paletteData.push_back(GameSave::PaletteItem(elements[ID].Identifier, ID));
|
||||
}
|
||||
|
||||
unsigned int soapLinkDataLen = 0;
|
||||
std::vector<unsigned char> soapLinkData(3*soapCount);
|
||||
if (soapCount)
|
||||
@ -2381,10 +2481,10 @@ std::pair<bool, std::vector<char>> GameSave::serialiseOPS() const
|
||||
{
|
||||
bson_append_binary(&b, "parts", (char)BSON_BIN_USER, (const char *)&partsData[0], partsDataLen);
|
||||
|
||||
if (palette.size())
|
||||
if (paletteData.size())
|
||||
{
|
||||
bson_append_start_array(&b, "palette");
|
||||
for(auto iter = palette.begin(), end = palette.end(); iter != end; ++iter)
|
||||
for(auto iter = paletteData.begin(), end = paletteData.end(); iter != end; ++iter)
|
||||
{
|
||||
bson_append_int(&b, (*iter).first.c_str(), (*iter).second);
|
||||
}
|
||||
|
@ -5,6 +5,7 @@
|
||||
#include "common/Version.h"
|
||||
#include "simulation/Sign.h"
|
||||
#include "simulation/Particle.h"
|
||||
#include "simulation/MissingElements.h"
|
||||
#include "Misc.h"
|
||||
#include "SimulationConfig.h"
|
||||
#include <vector>
|
||||
@ -62,6 +63,8 @@ class GameSave
|
||||
void readPSv(const std::vector<char> &data);
|
||||
std::pair<bool, std::vector<char>> serialiseOPS() const;
|
||||
|
||||
void MapPalette();
|
||||
|
||||
public:
|
||||
Vec2<int> blockSize = { 0, 0 };
|
||||
bool fromNewerVersion = false;
|
||||
@ -101,6 +104,8 @@ public:
|
||||
int edgeMode = 0;
|
||||
bool wantAuthors = true;
|
||||
|
||||
MissingElements missingElements;
|
||||
|
||||
//Signs
|
||||
std::vector<sign> signs;
|
||||
StkmData stkm;
|
||||
|
@ -29,7 +29,7 @@ ThumbnailRendererTask::~ThumbnailRendererTask()
|
||||
|
||||
bool ThumbnailRendererTask::doWork()
|
||||
{
|
||||
std::tie(thumbnail, std::ignore) = SaveRenderer::Ref().Render(save.get(), decorations, fire);
|
||||
thumbnail = SaveRenderer::Ref().Render(save.get(), decorations, fire);
|
||||
if (thumbnail)
|
||||
{
|
||||
thumbnail->ResizeToFit(size, true);
|
||||
|
@ -28,4 +28,9 @@ public:
|
||||
{
|
||||
return *Instance();
|
||||
}
|
||||
|
||||
static const Type &CRef()
|
||||
{
|
||||
return Ref();
|
||||
}
|
||||
};
|
||||
|
@ -27,6 +27,21 @@ struct Version
|
||||
return *this < other || *this == other;
|
||||
}
|
||||
|
||||
constexpr bool operator >=(const Version &other) const
|
||||
{
|
||||
return !(*this < other);
|
||||
}
|
||||
|
||||
constexpr bool operator >(const Version &other) const
|
||||
{
|
||||
return !(*this <= other);
|
||||
}
|
||||
|
||||
constexpr bool operator !=(const Version &other) const
|
||||
{
|
||||
return !(*this == other);
|
||||
}
|
||||
|
||||
constexpr size_t operator [](size_t index) const
|
||||
{
|
||||
return components[index];
|
||||
|
@ -1,9 +1,7 @@
|
||||
#include "ElementPopulation.h"
|
||||
|
||||
#include "gui/interface/Engine.h"
|
||||
|
||||
#include "simulation/Simulation.h"
|
||||
|
||||
#include "simulation/SimulationData.h"
|
||||
#include "graphics/Graphics.h"
|
||||
|
||||
ElementPopulationDebug::ElementPopulationDebug(unsigned int id, Simulation * sim):
|
||||
@ -16,6 +14,8 @@ ElementPopulationDebug::ElementPopulationDebug(unsigned int id, Simulation * sim
|
||||
|
||||
void ElementPopulationDebug::Draw()
|
||||
{
|
||||
auto &sd = SimulationData::CRef();
|
||||
auto &elements = sd.elements;
|
||||
Graphics * g = ui::Engine::Ref().g;
|
||||
|
||||
int yBottom = YRES-10;
|
||||
@ -30,7 +30,7 @@ void ElementPopulationDebug::Draw()
|
||||
int bars = 0;
|
||||
for(int i = 0; i < PT_NUM; i++)
|
||||
{
|
||||
if(sim->elements[i].Enabled)
|
||||
if(elements[i].Enabled)
|
||||
{
|
||||
if(maxVal < sim->elementCount[i])
|
||||
maxVal = float(sim->elementCount[i]);
|
||||
@ -49,13 +49,13 @@ void ElementPopulationDebug::Draw()
|
||||
bars = 0;
|
||||
for(int i = 0; i < PT_NUM; i++)
|
||||
{
|
||||
if(sim->elements[i].Enabled)
|
||||
if(elements[i].Enabled)
|
||||
{
|
||||
auto count = sim->elementCount[i];
|
||||
auto barSize = int(count * scale - 0.5f);
|
||||
int barX = bars;//*2;
|
||||
|
||||
RGB<uint8_t> colour = sim->elements[i].Colour;
|
||||
RGB<uint8_t> colour = elements[i].Colour;
|
||||
|
||||
g->DrawLine({ xStart+barX, yBottom+3 }, { xStart+barX, yBottom+2 }, colour);
|
||||
if(sim->elementCount[i])
|
||||
|
@ -6,7 +6,7 @@
|
||||
#include "simulation/ElementClasses.h"
|
||||
#include "graphics/Graphics.h"
|
||||
|
||||
SurfaceNormals::SurfaceNormals(unsigned int id, Simulation *newSim, GameView *newView, GameController *newController) :
|
||||
SurfaceNormals::SurfaceNormals(unsigned int id, const Simulation *newSim, GameView *newView, GameController *newController) :
|
||||
DebugInfo(id), sim(newSim), view(newView), controller(newController)
|
||||
{
|
||||
}
|
||||
@ -29,7 +29,7 @@ void SurfaceNormals::Draw()
|
||||
auto &parts = sim->parts;
|
||||
auto x = int(parts[i].x + 0.5f);
|
||||
auto y = int(parts[i].y + 0.5f);
|
||||
auto mr = sim->PlanMove(i, x, y, false);
|
||||
auto mr = Simulation::PlanMove<false>(*sim, i, x, y);
|
||||
if (t == PT_PHOT)
|
||||
{
|
||||
if (parts[i].flags & FLAG_SKIPMOVE)
|
||||
@ -48,7 +48,7 @@ void SurfaceNormals::Draw()
|
||||
}
|
||||
}
|
||||
}
|
||||
auto gn = sim->get_normal_interp(t, parts[i].x, parts[i].y, mr.vx, mr.vy);
|
||||
auto gn = sim->get_normal_interp<false>(*sim, t, parts[i].x, parts[i].y, mr.vx, mr.vy);
|
||||
if (!gn.success)
|
||||
{
|
||||
return;
|
||||
|
@ -6,12 +6,12 @@ class GameView;
|
||||
class GameController;
|
||||
class SurfaceNormals : public DebugInfo
|
||||
{
|
||||
Simulation *sim;
|
||||
const Simulation *sim;
|
||||
GameView *view;
|
||||
GameController *controller;
|
||||
|
||||
public:
|
||||
SurfaceNormals(unsigned int id, Simulation *newSim, GameView *newView, GameController *newController);
|
||||
SurfaceNormals(unsigned int id, const Simulation *newSim, GameView *newView, GameController *newController);
|
||||
|
||||
void Draw() override;
|
||||
};
|
||||
|
@ -7,11 +7,13 @@
|
||||
#include "simulation/ElementClasses.h"
|
||||
#include "simulation/Air.h"
|
||||
#include "simulation/gravity/Gravity.h"
|
||||
#include "simulation/orbitalparts.h"
|
||||
#include <cmath>
|
||||
|
||||
std::unique_ptr<VideoBuffer> Renderer::WallIcon(int wallID, Vec2<int> size)
|
||||
{
|
||||
auto wtypes = LoadWalls();
|
||||
auto &sd = SimulationData::CRef();
|
||||
auto &wtypes = sd.wtypes;
|
||||
if (wallID < 0 || wallID >= int(wtypes.size()))
|
||||
return nullptr;
|
||||
wall_type const &wtype = wtypes[wallID];
|
||||
@ -170,14 +172,20 @@ void Renderer::DrawSigns()
|
||||
|
||||
void Renderer::render_parts()
|
||||
{
|
||||
auto &sd = SimulationData::CRef();
|
||||
auto &elements = sd.elements;
|
||||
auto &graphicscache = sd.graphicscache;
|
||||
GraphicsFuncContext gfctx;
|
||||
gfctx.ren = this;
|
||||
gfctx.sim = sim;
|
||||
gfctx.rng.seed(rng());
|
||||
gfctx.pipeSubcallCpart = nullptr;
|
||||
gfctx.pipeSubcallTpart = nullptr;
|
||||
int deca, decr, decg, decb, cola, colr, colg, colb, firea, firer, fireg, fireb, pixel_mode, q, i, t, nx, ny, x, y;
|
||||
int orbd[4] = {0, 0, 0, 0}, orbl[4] = {0, 0, 0, 0};
|
||||
Particle * parts;
|
||||
Element *elements;
|
||||
if(!sim)
|
||||
return;
|
||||
parts = sim->parts;
|
||||
elements = sim->elements.data();
|
||||
auto *parts = sim->parts;
|
||||
if (gridSize)//draws the grid
|
||||
{
|
||||
for (ny=0; ny<YRES; ny++)
|
||||
@ -199,7 +207,7 @@ void Renderer::render_parts()
|
||||
|
||||
if(nx >= XRES || nx < 0 || ny >= YRES || ny < 0)
|
||||
continue;
|
||||
if(TYP(sim->photons[ny][nx]) && !(sim->elements[t].Properties & TYPE_ENERGY) && t!=PT_STKM && t!=PT_STKM2 && t!=PT_FIGH)
|
||||
if(TYP(sim->photons[ny][nx]) && !(elements[t].Properties & TYPE_ENERGY) && t!=PT_STKM && t!=PT_STKM2 && t!=PT_FIGH)
|
||||
continue;
|
||||
|
||||
//Defaults
|
||||
@ -242,18 +250,22 @@ void Renderer::render_parts()
|
||||
}
|
||||
else if(!(colour_mode & COLOUR_BASC))
|
||||
{
|
||||
if (!elements[t].Graphics || (*(elements[t].Graphics))(this, &(sim->parts[i]), nx, ny, &pixel_mode, &cola, &colr, &colg, &colb, &firea, &firer, &fireg, &fireb)) //That's a lot of args, a struct might be better
|
||||
auto *graphics = elements[t].Graphics;
|
||||
auto makeReady = !graphics || graphics(gfctx, &(sim->parts[i]), nx, ny, &pixel_mode, &cola, &colr, &colg, &colb, &firea, &firer, &fireg, &fireb); //That's a lot of args, a struct might be better
|
||||
if (makeReady && sim->useLuaCallbacks)
|
||||
{
|
||||
graphicscache[t].isready = 1;
|
||||
graphicscache[t].pixel_mode = pixel_mode;
|
||||
graphicscache[t].cola = cola;
|
||||
graphicscache[t].colr = colr;
|
||||
graphicscache[t].colg = colg;
|
||||
graphicscache[t].colb = colb;
|
||||
graphicscache[t].firea = firea;
|
||||
graphicscache[t].firer = firer;
|
||||
graphicscache[t].fireg = fireg;
|
||||
graphicscache[t].fireb = fireb;
|
||||
// useLuaCallbacks is true so we locked sd.elementGraphicsMx exclusively
|
||||
auto &wgraphicscache = SimulationData::Ref().graphicscache;
|
||||
wgraphicscache[t].isready = 1;
|
||||
wgraphicscache[t].pixel_mode = pixel_mode;
|
||||
wgraphicscache[t].cola = cola;
|
||||
wgraphicscache[t].colr = colr;
|
||||
wgraphicscache[t].colg = colg;
|
||||
wgraphicscache[t].colb = colb;
|
||||
wgraphicscache[t].firea = firea;
|
||||
wgraphicscache[t].firer = firer;
|
||||
wgraphicscache[t].fireg = fireg;
|
||||
wgraphicscache[t].fireb = fireb;
|
||||
}
|
||||
}
|
||||
if((elements[t].Properties & PROP_HOT_GLOW) && sim->parts[i].temp>(elements[t].HighTemperature-800.0f))
|
||||
@ -431,7 +443,7 @@ void Renderer::render_parts()
|
||||
if(pixel_mode & PSPEC_STICKMAN)
|
||||
{
|
||||
int legr, legg, legb;
|
||||
playerst *cplayer;
|
||||
const playerst *cplayer;
|
||||
if(t==PT_STKM)
|
||||
cplayer = &sim->player;
|
||||
else if(t==PT_STKM2)
|
||||
@ -619,7 +631,7 @@ void Renderer::render_parts()
|
||||
}
|
||||
if(pixel_mode & PMODE_SPARK)
|
||||
{
|
||||
auto flicker = float(rng()%20);
|
||||
auto flicker = float(gfctx.rng()%20);
|
||||
auto gradv = 4*sim->parts[i].life + flicker;
|
||||
for (x = 0; gradv>0.5; x++) {
|
||||
auto col = RGBA<uint8_t>(
|
||||
@ -636,7 +648,7 @@ void Renderer::render_parts()
|
||||
}
|
||||
if(pixel_mode & PMODE_FLARE)
|
||||
{
|
||||
auto flicker = float(rng()%20);
|
||||
auto flicker = float(gfctx.rng()%20);
|
||||
auto gradv = flicker + fabs(parts[i].vx)*17 + fabs(sim->parts[i].vy)*17;
|
||||
BlendPixel({ nx, ny }, RGBA<uint8_t>(colr, colg, colb, int((gradv*4)>255?255:(gradv*4)) ));
|
||||
BlendPixel({ nx+1, ny }, RGBA<uint8_t>(colr, colg, colb,int( (gradv*2)>255?255:(gradv*2)) ));
|
||||
@ -658,7 +670,7 @@ void Renderer::render_parts()
|
||||
}
|
||||
if(pixel_mode & PMODE_LFLARE)
|
||||
{
|
||||
auto flicker = float(rng()%20);
|
||||
auto flicker = float(gfctx.rng()%20);
|
||||
auto gradv = flicker + fabs(parts[i].vx)*17 + fabs(parts[i].vy)*17;
|
||||
BlendPixel({ nx, ny }, RGBA<uint8_t>(colr, colg, colb, int((gradv*4)>255?255:(gradv*4)) ));
|
||||
BlendPixel({ nx+1, ny }, RGBA<uint8_t>(colr, colg, colb, int((gradv*2)>255?255:(gradv*2)) ));
|
||||
@ -685,7 +697,7 @@ void Renderer::render_parts()
|
||||
int r;
|
||||
float drad = 0.0f;
|
||||
float ddist = 0.0f;
|
||||
sim->orbitalparts_get(parts[i].life, parts[i].ctype, orbd, orbl);
|
||||
orbitalparts_get(parts[i].life, parts[i].ctype, orbd, orbl);
|
||||
for (r = 0; r < 4; r++) {
|
||||
ddist = ((float)orbd[r])/16.0f;
|
||||
drad = (TPT_PI_FLT * ((float)orbl[r]) / 180.0f)*1.41f;
|
||||
@ -702,7 +714,7 @@ void Renderer::render_parts()
|
||||
int r;
|
||||
float drad = 0.0f;
|
||||
float ddist = 0.0f;
|
||||
sim->orbitalparts_get(parts[i].life, parts[i].ctype, orbd, orbl);
|
||||
orbitalparts_get(parts[i].life, parts[i].ctype, orbd, orbl);
|
||||
for (r = 0; r < 4; r++) {
|
||||
ddist = ((float)orbd[r])/16.0f;
|
||||
drad = (TPT_PI_FLT * ((float)orbl[r]) / 180.0f)*1.41f;
|
||||
@ -927,6 +939,8 @@ void Renderer::draw_air()
|
||||
|
||||
void Renderer::DrawWalls()
|
||||
{
|
||||
auto &sd = SimulationData::CRef();
|
||||
auto &wtypes = sd.wtypes;
|
||||
for (int y = 0; y < YCELLS; y++)
|
||||
for (int x =0; x < XCELLS; x++)
|
||||
if (sim->bmap[y][x])
|
||||
@ -935,8 +949,8 @@ void Renderer::DrawWalls()
|
||||
if (wt >= UI_WALLCOUNT)
|
||||
continue;
|
||||
unsigned char powered = sim->emap[y][x];
|
||||
RGB<uint8_t> prgb = sim->wtypes[wt].colour;
|
||||
RGB<uint8_t> grgb = sim->wtypes[wt].eglow;
|
||||
RGB<uint8_t> prgb = wtypes[wt].colour;
|
||||
RGB<uint8_t> grgb = wtypes[wt].eglow;
|
||||
|
||||
if (findingElement)
|
||||
{
|
||||
@ -951,7 +965,7 @@ void Renderer::DrawWalls()
|
||||
pixel pc = prgb.Pack();
|
||||
pixel gc = grgb.Pack();
|
||||
|
||||
switch (sim->wtypes[wt].drawstyle)
|
||||
switch (wtypes[wt].drawstyle)
|
||||
{
|
||||
case 0:
|
||||
if (wt == WL_EWALL || wt == WL_STASIS)
|
||||
@ -1075,7 +1089,7 @@ void Renderer::DrawWalls()
|
||||
// when in blob view, draw some blobs...
|
||||
if (render_mode & PMODE_BLOB)
|
||||
{
|
||||
switch (sim->wtypes[wt].drawstyle)
|
||||
switch (wtypes[wt].drawstyle)
|
||||
{
|
||||
case 0:
|
||||
if (wt == WL_EWALL || wt == WL_STASIS)
|
||||
@ -1156,10 +1170,10 @@ void Renderer::DrawWalls()
|
||||
}
|
||||
}
|
||||
|
||||
if (sim->wtypes[wt].eglow.Pack() && powered)
|
||||
if (wtypes[wt].eglow.Pack() && powered)
|
||||
{
|
||||
// glow if electrified
|
||||
RGB<uint8_t> glow = sim->wtypes[wt].eglow;
|
||||
RGB<uint8_t> glow = wtypes[wt].eglow;
|
||||
int alpha = 255;
|
||||
int cr = (alpha*glow.Red + (255-alpha)*fire_r[y/CELL][x/CELL]) >> 8;
|
||||
int cg = (alpha*glow.Green + (255-alpha)*fire_g[y/CELL][x/CELL]) >> 8;
|
||||
|
@ -1,5 +1,6 @@
|
||||
#pragma once
|
||||
#include "Graphics.h"
|
||||
#include "gui/game/RenderPreset.h"
|
||||
#include "gui/interface/Point.h"
|
||||
#include "common/tpt-rand.h"
|
||||
#include "SimulationConfig.h"
|
||||
@ -12,28 +13,17 @@
|
||||
|
||||
class RenderPreset;
|
||||
class Simulation;
|
||||
class Renderer;
|
||||
struct Particle;
|
||||
|
||||
struct gcache_item
|
||||
struct GraphicsFuncContext
|
||||
{
|
||||
int isready;
|
||||
int pixel_mode;
|
||||
int cola, colr, colg, colb;
|
||||
int firea, firer, fireg, fireb;
|
||||
gcache_item() :
|
||||
isready(0),
|
||||
pixel_mode(0),
|
||||
cola(0),
|
||||
colr(0),
|
||||
colg(0),
|
||||
colb(0),
|
||||
firea(0),
|
||||
firer(0),
|
||||
fireg(0),
|
||||
fireb(0)
|
||||
{
|
||||
}
|
||||
const Renderer *ren;
|
||||
const Simulation *sim;
|
||||
RNG rng;
|
||||
const Particle *pipeSubcallCpart;
|
||||
Particle *pipeSubcallTpart;
|
||||
};
|
||||
typedef struct gcache_item gcache_item;
|
||||
|
||||
int HeatToColour(float temp);
|
||||
|
||||
@ -64,8 +54,7 @@ public:
|
||||
|
||||
RNG rng;
|
||||
|
||||
Simulation * sim;
|
||||
gcache_item *graphicscache;
|
||||
const Simulation *sim;
|
||||
|
||||
std::vector<unsigned int> render_modes;
|
||||
unsigned int render_mode;
|
||||
@ -147,8 +136,7 @@ public:
|
||||
|
||||
static std::unique_ptr<VideoBuffer> WallIcon(int wallID, Vec2<int> size);
|
||||
|
||||
Renderer(Simulation * sim);
|
||||
~Renderer();
|
||||
Renderer(Simulation *newSim);
|
||||
|
||||
#define RENDERER_TABLE(name) \
|
||||
static std::vector<RGB<uint8_t>> name; \
|
||||
|
@ -224,8 +224,8 @@ void Renderer::PopulateTables()
|
||||
}
|
||||
}
|
||||
|
||||
Renderer::Renderer(Simulation * sim):
|
||||
sim(NULL),
|
||||
Renderer::Renderer(Simulation *newSim):
|
||||
sim(newSim),
|
||||
render_mode(0),
|
||||
colour_mode(0),
|
||||
display_mode(0),
|
||||
@ -246,8 +246,6 @@ Renderer::Renderer(Simulation * sim):
|
||||
{
|
||||
PopulateTables();
|
||||
|
||||
this->sim = sim;
|
||||
|
||||
memset(fire_r, 0, sizeof(fire_r));
|
||||
memset(fire_g, 0, sizeof(fire_g));
|
||||
memset(fire_b, 0, sizeof(fire_b));
|
||||
@ -323,10 +321,6 @@ Renderer::Renderer(Simulation * sim):
|
||||
COLOUR_LIFE
|
||||
});
|
||||
|
||||
//Prepare the graphics cache
|
||||
graphicscache = new gcache_item[PT_NUM];
|
||||
std::fill(&graphicscache[0], &graphicscache[0] + PT_NUM, gcache_item());
|
||||
|
||||
prepare_alpha(CELL, 1.0f);
|
||||
}
|
||||
|
||||
@ -466,9 +460,4 @@ VideoBuffer Renderer::DumpFrame()
|
||||
return newBuffer;
|
||||
}
|
||||
|
||||
Renderer::~Renderer()
|
||||
{
|
||||
delete[] graphicscache;
|
||||
}
|
||||
|
||||
template struct RasterDrawMethods<Renderer>;
|
||||
|
15
src/graphics/gcache_item.h
Normal file
15
src/graphics/gcache_item.h
Normal file
@ -0,0 +1,15 @@
|
||||
#pragma once
|
||||
|
||||
struct gcache_item
|
||||
{
|
||||
int isready = 0;
|
||||
int pixel_mode = 0;
|
||||
int cola = 0;
|
||||
int colr = 0;
|
||||
int colg = 0;
|
||||
int colb = 0;
|
||||
int firea = 0;
|
||||
int firer = 0;
|
||||
int fireg = 0;
|
||||
int fireb = 0;
|
||||
};
|
@ -4,7 +4,7 @@
|
||||
#include "client/Client.h"
|
||||
#include "common/tpt-rand.h"
|
||||
#include "simulation/GOLString.h"
|
||||
#include "simulation/Simulation.h"
|
||||
#include "simulation/SimulationData.h"
|
||||
|
||||
#include "gui/Style.h"
|
||||
#include "gui/interface/Button.h"
|
||||
@ -23,14 +23,13 @@ class GOLWindow: public ui::Window
|
||||
ui::Button *highColourButton, *lowColourButton;
|
||||
ui::Textbox *nameField, *ruleField;
|
||||
GameModel &gameModel;
|
||||
Simulation *sim;
|
||||
int toolSelection;
|
||||
|
||||
void updateGradient();
|
||||
void validate();
|
||||
|
||||
public:
|
||||
GOLWindow(GameModel &gameModel, Simulation *sim, int toolSelection, int rule, RGB<uint8_t> colour1, RGB<uint8_t> colour2);
|
||||
GOLWindow(GameModel &gameModel, int toolSelection, int rule, RGB<uint8_t> colour1, RGB<uint8_t> colour2);
|
||||
|
||||
virtual ~GOLWindow()
|
||||
{}
|
||||
@ -39,12 +38,11 @@ public:
|
||||
void OnTryExit(ExitMethod method) override;
|
||||
};
|
||||
|
||||
GOLWindow::GOLWindow(GameModel &gameModel_, Simulation *sim_, int toolSelection, int rule, RGB<uint8_t> colour1, RGB<uint8_t> colour2):
|
||||
GOLWindow::GOLWindow(GameModel &gameModel_, int toolSelection, int rule, RGB<uint8_t> colour1, RGB<uint8_t> colour2):
|
||||
ui::Window(ui::Point(-1, -1), ui::Point(200, 108)),
|
||||
highColour(colour1.WithAlpha(0xFF)),
|
||||
lowColour(colour2.WithAlpha(0xFF)),
|
||||
gameModel(gameModel_),
|
||||
sim(sim_),
|
||||
toolSelection(toolSelection)
|
||||
{
|
||||
highColour.Alpha = 255;
|
||||
@ -135,6 +133,7 @@ void GOLWindow::updateGradient()
|
||||
|
||||
void GOLWindow::validate()
|
||||
{
|
||||
auto &sd = SimulationData::CRef();
|
||||
auto nameString = nameField->GetText();
|
||||
auto ruleString = ruleField->GetText();
|
||||
if (!ValidateGOLName(nameString))
|
||||
@ -149,7 +148,7 @@ void GOLWindow::validate()
|
||||
new ErrorMessage("Could not add GOL type", "Invalid rule provided");
|
||||
return;
|
||||
}
|
||||
if (sim->GetCustomGOLByRule(rule))
|
||||
if (sd.GetCustomGOLByRule(rule))
|
||||
{
|
||||
new ErrorMessage("Could not add GOL type", "This Custom GoL rule already exists");
|
||||
return;
|
||||
@ -204,5 +203,5 @@ void GOLWindow::OnDraw()
|
||||
|
||||
void GOLTool::OpenWindow(Simulation *sim, int toolSelection, int rule, RGB<uint8_t> colour1, RGB<uint8_t> colour2)
|
||||
{
|
||||
new GOLWindow(gameModel, sim, toolSelection, rule, colour1, colour2);
|
||||
new GOLWindow(gameModel, toolSelection, rule, colour1, colour2);
|
||||
}
|
||||
|
@ -31,6 +31,7 @@
|
||||
#include "simulation/Simulation.h"
|
||||
#include "simulation/SimulationData.h"
|
||||
#include "simulation/Snapshot.h"
|
||||
#include "simulation/elements/STKM.h"
|
||||
|
||||
#include "gui/dialogues/ErrorMessage.h"
|
||||
#include "gui/dialogues/InformationMessage.h"
|
||||
@ -757,11 +758,12 @@ void GameController::ResetAir()
|
||||
|
||||
void GameController::ResetSpark()
|
||||
{
|
||||
auto &sd = SimulationData::CRef();
|
||||
Simulation * sim = gameModel->GetSimulation();
|
||||
for (int i = 0; i < NPART; i++)
|
||||
if (sim->parts[i].type == PT_SPRK)
|
||||
{
|
||||
if (sim->parts[i].ctype >= 0 && sim->parts[i].ctype < PT_NUM && sim->elements[sim->parts[i].ctype].Enabled)
|
||||
if (sim->parts[i].ctype >= 0 && sim->parts[i].ctype < PT_NUM && sd.elements[sim->parts[i].ctype].Enabled)
|
||||
{
|
||||
sim->parts[i].type = sim->parts[i].ctype;
|
||||
sim->parts[i].ctype = sim->parts[i].life = 0;
|
||||
@ -849,6 +851,7 @@ void GameController::LoadRenderPreset(int presetNum)
|
||||
|
||||
void GameController::Update()
|
||||
{
|
||||
auto &sd = SimulationData::CRef();
|
||||
ui::Point pos = gameView->GetMousePosition();
|
||||
gameModel->GetRenderer()->mousePos = PointTranslate(pos);
|
||||
if (pos.X < XRES && pos.Y < YRES)
|
||||
@ -875,11 +878,10 @@ void GameController::Update()
|
||||
if (activeTool->Identifier.BeginsWith("DEFAULT_PT_"))
|
||||
{
|
||||
int sr = activeTool->ToolID;
|
||||
if (sr && sim->IsElementOrNone(sr))
|
||||
if (sr && sd.IsElementOrNone(sr))
|
||||
rightSelected = sr;
|
||||
}
|
||||
|
||||
void Element_STKM_set_element(Simulation *sim, playerst *playerp, int element);
|
||||
if (!sim->player.spwn)
|
||||
Element_STKM_set_element(sim, &sim->player, rightSelected);
|
||||
if (!sim->player2.spwn)
|
||||
@ -1497,20 +1499,14 @@ String GameController::ElementResolve(int type, int ctype)
|
||||
// "NONE" should never be displayed in the HUD
|
||||
if (!type)
|
||||
return "";
|
||||
if (gameModel && gameModel->GetSimulation())
|
||||
{
|
||||
return gameModel->GetSimulation()->ElementResolve(type, ctype);
|
||||
}
|
||||
return "";
|
||||
auto &sd = SimulationData::CRef();
|
||||
return sd.ElementResolve(type, ctype);
|
||||
}
|
||||
|
||||
String GameController::BasicParticleInfo(Particle const &sample_part)
|
||||
{
|
||||
if (gameModel && gameModel->GetSimulation())
|
||||
{
|
||||
return gameModel->GetSimulation()->BasicParticleInfo(sample_part);
|
||||
}
|
||||
return "";
|
||||
auto &sd = SimulationData::CRef();
|
||||
return sd.BasicParticleInfo(sample_part);
|
||||
}
|
||||
|
||||
void GameController::ReloadSim()
|
||||
@ -1529,18 +1525,15 @@ void GameController::ReloadSim()
|
||||
|
||||
bool GameController::IsValidElement(int type)
|
||||
{
|
||||
if (gameModel && gameModel->GetSimulation())
|
||||
{
|
||||
return (type && gameModel->GetSimulation()->IsElement(type));
|
||||
}
|
||||
else
|
||||
return false;
|
||||
auto &sd = SimulationData::CRef();
|
||||
return type && sd.IsElement(type);
|
||||
}
|
||||
|
||||
String GameController::WallName(int type)
|
||||
{
|
||||
if(gameModel && gameModel->GetSimulation() && type >= 0 && type < UI_WALLCOUNT)
|
||||
return gameModel->GetSimulation()->wtypes[type].name;
|
||||
auto &sd = SimulationData::CRef();
|
||||
if(type >= 0 && type < UI_WALLCOUNT)
|
||||
return sd.wtypes[type].name;
|
||||
else
|
||||
return String();
|
||||
}
|
||||
|
@ -56,6 +56,7 @@ GameModel::GameModel():
|
||||
decoSpace(0)
|
||||
{
|
||||
sim = new Simulation();
|
||||
sim->useLuaCallbacks = true;
|
||||
ren = new Renderer(sim);
|
||||
|
||||
activeTools = regularToolset;
|
||||
@ -219,6 +220,9 @@ void GameModel::BuildQuickOptionMenu(GameController * controller)
|
||||
|
||||
void GameModel::BuildMenus()
|
||||
{
|
||||
auto &sd = SimulationData::Ref();
|
||||
auto &elements = sd.elements;
|
||||
auto &builtinGol = SimulationData::builtinGol;
|
||||
int lastMenu = -1;
|
||||
if(activeMenu != -1)
|
||||
lastMenu = activeMenu;
|
||||
@ -253,35 +257,35 @@ void GameModel::BuildMenus()
|
||||
//Create menus
|
||||
for (int i = 0; i < SC_TOTAL; i++)
|
||||
{
|
||||
menuList.push_back(new Menu(sim->msections[i].icon, sim->msections[i].name, sim->msections[i].doshow));
|
||||
menuList.push_back(new Menu(sd.msections[i].icon, sd.msections[i].name, sd.msections[i].doshow));
|
||||
}
|
||||
|
||||
//Build menus from Simulation elements
|
||||
for(int i = 0; i < PT_NUM; i++)
|
||||
{
|
||||
if(sim->elements[i].Enabled)
|
||||
if(elements[i].Enabled)
|
||||
{
|
||||
Tool * tempTool;
|
||||
if(i == PT_LIGH)
|
||||
{
|
||||
tempTool = new Element_LIGH_Tool(i, sim->elements[i].Name, sim->elements[i].Description, sim->elements[i].Colour, sim->elements[i].Identifier, sim->elements[i].IconGenerator);
|
||||
tempTool = new Element_LIGH_Tool(i, elements[i].Name, elements[i].Description, elements[i].Colour, elements[i].Identifier, elements[i].IconGenerator);
|
||||
}
|
||||
else if(i == PT_TESC)
|
||||
{
|
||||
tempTool = new Element_TESC_Tool(i, sim->elements[i].Name, sim->elements[i].Description, sim->elements[i].Colour, sim->elements[i].Identifier, sim->elements[i].IconGenerator);
|
||||
tempTool = new Element_TESC_Tool(i, elements[i].Name, elements[i].Description, elements[i].Colour, elements[i].Identifier, elements[i].IconGenerator);
|
||||
}
|
||||
else if(i == PT_STKM || i == PT_FIGH || i == PT_STKM2)
|
||||
{
|
||||
tempTool = new PlopTool(i, sim->elements[i].Name, sim->elements[i].Description, sim->elements[i].Colour, sim->elements[i].Identifier, sim->elements[i].IconGenerator);
|
||||
tempTool = new PlopTool(i, elements[i].Name, elements[i].Description, elements[i].Colour, elements[i].Identifier, elements[i].IconGenerator);
|
||||
}
|
||||
else
|
||||
{
|
||||
tempTool = new ElementTool(i, sim->elements[i].Name, sim->elements[i].Description, sim->elements[i].Colour, sim->elements[i].Identifier, sim->elements[i].IconGenerator);
|
||||
tempTool = new ElementTool(i, elements[i].Name, elements[i].Description, elements[i].Colour, elements[i].Identifier, elements[i].IconGenerator);
|
||||
}
|
||||
|
||||
if (sim->elements[i].MenuSection >= 0 && sim->elements[i].MenuSection < SC_TOTAL && sim->elements[i].MenuVisible)
|
||||
if (elements[i].MenuSection >= 0 && elements[i].MenuSection < SC_TOTAL && elements[i].MenuVisible)
|
||||
{
|
||||
menuList[sim->elements[i].MenuSection]->AddTool(tempTool);
|
||||
menuList[elements[i].MenuSection]->AddTool(tempTool);
|
||||
}
|
||||
else
|
||||
{
|
||||
@ -301,7 +305,7 @@ void GameModel::BuildMenus()
|
||||
auto &prefs = GlobalPrefs::Ref();
|
||||
auto customGOLTypes = prefs.Get("CustomGOL.Types", std::vector<ByteString>{});
|
||||
std::vector<ByteString> validatedCustomLifeTypes;
|
||||
std::vector<Simulation::CustomGOLData> newCustomGol;
|
||||
std::vector<CustomGOLData> newCustomGol;
|
||||
bool removedAny = false;
|
||||
for (auto gol : customGOLTypes)
|
||||
{
|
||||
@ -311,7 +315,7 @@ void GameModel::BuildMenus()
|
||||
removedAny = true;
|
||||
continue;
|
||||
}
|
||||
Simulation::CustomGOLData gd;
|
||||
CustomGOLData gd;
|
||||
gd.nameString = parts[0];
|
||||
gd.ruleString = parts[1];
|
||||
auto &colour1String = parts[2];
|
||||
@ -350,26 +354,25 @@ void GameModel::BuildMenus()
|
||||
Tool * tempTool = new ElementTool(PT_LIFE|PMAPID(gd.rule), gd.nameString, "Custom GOL type: " + gd.ruleString, RGB<uint8_t>::Unpack(gd.colour1), "DEFAULT_PT_LIFECUST_"+gd.nameString.ToAscii(), NULL);
|
||||
menuList[SC_LIFE]->AddTool(tempTool);
|
||||
}
|
||||
sim->SetCustomGOL(newCustomGol);
|
||||
sd.SetCustomGOL(newCustomGol);
|
||||
}
|
||||
|
||||
//Build other menus from wall data
|
||||
for(int i = 0; i < UI_WALLCOUNT; i++)
|
||||
{
|
||||
Tool * tempTool = new WallTool(i, sim->wtypes[i].descs, sim->wtypes[i].colour, sim->wtypes[i].identifier, sim->wtypes[i].textureGen);
|
||||
Tool * tempTool = new WallTool(i, sd.wtypes[i].descs, sd.wtypes[i].colour, sd.wtypes[i].identifier, sd.wtypes[i].textureGen);
|
||||
menuList[SC_WALL]->AddTool(tempTool);
|
||||
//sim->wtypes[i]
|
||||
}
|
||||
|
||||
//Build menu for tools
|
||||
for (size_t i = 0; i < sim->tools.size(); i++)
|
||||
for (size_t i = 0; i < sd.tools.size(); i++)
|
||||
{
|
||||
Tool *tempTool = new Tool(
|
||||
i,
|
||||
sim->tools[i].Name,
|
||||
sim->tools[i].Description,
|
||||
sim->tools[i].Colour,
|
||||
sim->tools[i].Identifier
|
||||
sd.tools[i].Name,
|
||||
sd.tools[i].Description,
|
||||
sd.tools[i].Colour,
|
||||
sd.tools[i].Identifier
|
||||
);
|
||||
menuList[SC_TOOL]->AddTool(tempTool);
|
||||
}
|
||||
|
@ -1964,7 +1964,7 @@ void GameView::NotifyTransformedPlaceSaveChanged(GameModel *sender)
|
||||
{
|
||||
if (sender->GetTransformedPlaceSave())
|
||||
{
|
||||
std::tie(placeSaveThumb, std::ignore) = SaveRenderer::Ref().Render(sender->GetTransformedPlaceSave(), true, true, sender->GetRenderer());
|
||||
placeSaveThumb = SaveRenderer::Ref().Render(sender->GetTransformedPlaceSave(), true, true, sender->GetRenderer());
|
||||
selectMode = PlaceSave;
|
||||
selectPoint2 = mousePosition;
|
||||
}
|
||||
@ -2108,6 +2108,9 @@ void GameView::OnDraw()
|
||||
Graphics * g = GetGraphics();
|
||||
if (ren)
|
||||
{
|
||||
// we're the main thread, we may write graphicscache
|
||||
auto &sd = SimulationData::Ref();
|
||||
std::unique_lock lk(sd.elementGraphicsMx);
|
||||
ren->clearScreen();
|
||||
ren->RenderBegin();
|
||||
ren->SetSample(c->PointTranslate(currentMouse));
|
||||
|
@ -1,5 +1,6 @@
|
||||
#pragma once
|
||||
#include "Config.h"
|
||||
#include "SimulationConfig.h"
|
||||
#include "common/String.h"
|
||||
|
||||
inline ByteString VersionInfo()
|
||||
@ -23,9 +24,10 @@ inline ByteString VersionInfo()
|
||||
{
|
||||
sb << " LUACONSOLE";
|
||||
}
|
||||
#ifdef REALISTIC
|
||||
sb << " REALISTIC";
|
||||
#endif
|
||||
if constexpr (LATENTHEAT)
|
||||
{
|
||||
sb << " LATENTHEAT";
|
||||
}
|
||||
if constexpr (NOHTTP)
|
||||
{
|
||||
sb << " NOHTTP";
|
||||
|
@ -114,6 +114,8 @@ void PropertyWindow::Update()
|
||||
|
||||
void PropertyWindow::CheckProperty()
|
||||
{
|
||||
auto &sd = SimulationData::CRef();
|
||||
auto &elements = sd.elements;
|
||||
configuration.reset();
|
||||
PropertyTool::Configuration newConfiguration;
|
||||
if (!(property->GetOption().second!=-1 && textField->GetText().length() > 0))
|
||||
@ -142,7 +144,7 @@ void PropertyWindow::CheckProperty()
|
||||
else
|
||||
{
|
||||
// Try to parse as particle name
|
||||
v = sim->GetParticleType(value.ToUtf8());
|
||||
v = sd.GetParticleType(value.ToUtf8());
|
||||
|
||||
// Try to parse special GoL rules
|
||||
if (v == -1 && properties[property->GetOption().second].Name == "ctype")
|
||||
@ -160,7 +162,7 @@ void PropertyWindow::CheckProperty()
|
||||
}
|
||||
else
|
||||
{
|
||||
v = sim->GetParticleType(value.ToUtf8());
|
||||
v = sd.GetParticleType(value.ToUtf8());
|
||||
if (v == -1)
|
||||
{
|
||||
for (auto *elementTool : tool->gameModel.GetMenuList()[SC_LIFE]->GetToolList())
|
||||
@ -182,7 +184,7 @@ void PropertyWindow::CheckProperty()
|
||||
}
|
||||
}
|
||||
|
||||
if (properties[property->GetOption().second].Name == "type" && (v < 0 || v >= PT_NUM || !sim->elements[v].Enabled))
|
||||
if (properties[property->GetOption().second].Name == "type" && (v < 0 || v >= PT_NUM || !elements[v].Enabled))
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
@ -4,6 +4,7 @@
|
||||
|
||||
#include "client/Client.h"
|
||||
#include "client/SaveInfo.h"
|
||||
#include "client/GameSave.h"
|
||||
#include "client/http/AddCommentRequest.h"
|
||||
#include "client/http/ReportSaveRequest.h"
|
||||
|
||||
@ -570,7 +571,8 @@ void PreviewView::NotifySaveChanged(PreviewModel * sender)
|
||||
|
||||
if(save->GetGameSave())
|
||||
{
|
||||
std::tie(savePreview, missingElements) = SaveRenderer::Ref().Render(save->GetGameSave(), false, true);
|
||||
missingElements = save->GetGameSave()->missingElements;
|
||||
savePreview = SaveRenderer::Ref().Render(save->GetGameSave(), false, true);
|
||||
if (savePreview)
|
||||
savePreview->ResizeToFit(RES / 2, true);
|
||||
missingElementsButton->Visible = missingElements.identifiers.size() || missingElements.ids.size();
|
||||
|
@ -1,6 +1,7 @@
|
||||
#include "RenderView.h"
|
||||
|
||||
#include "simulation/ElementGraphics.h"
|
||||
#include "simulation/SimulationData.h"
|
||||
|
||||
#include "graphics/Graphics.h"
|
||||
#include "graphics/Renderer.h"
|
||||
@ -158,6 +159,9 @@ void RenderView::OnDraw()
|
||||
g->DrawFilledRect(WINDOW.OriginRect(), 0x000000_rgb);
|
||||
if(ren)
|
||||
{
|
||||
// we're the main thread, we may write graphicscache
|
||||
auto &sd = SimulationData::Ref();
|
||||
std::unique_lock lk(sd.elementGraphicsMx);
|
||||
ren->clearScreen();
|
||||
ren->RenderBegin();
|
||||
ren->RenderEnd();
|
||||
|
@ -26,12 +26,15 @@ void initLegacyProps()
|
||||
std::vector<StructProperty> properties = Element::GetProperties();
|
||||
for (auto prop : properties)
|
||||
{
|
||||
// TODO: move aliases to the property table in Element.cpp?
|
||||
if (prop.Name == "MenuVisible")
|
||||
legacyPropNames.insert(std::pair<ByteString, StructProperty>("menu", prop));
|
||||
else if (prop.Name == "PhotonReflectWavelengths")
|
||||
continue;
|
||||
else if (prop.Name == "CarriesTypeIn")
|
||||
continue;
|
||||
else if (prop.Name == "LatentHeat")
|
||||
continue;
|
||||
else if (prop.Name == "Temperature")
|
||||
legacyPropNames.insert(std::pair<ByteString, StructProperty>("heat", prop));
|
||||
else if (prop.Name == "HeatConduct")
|
||||
@ -152,6 +155,8 @@ int luacon_partswrite(lua_State* l)
|
||||
|
||||
int luacon_transitionread(lua_State* l)
|
||||
{
|
||||
auto &sd = SimulationData::CRef();
|
||||
auto &elements = sd.elements;
|
||||
ByteString key = tpt_lua_optByteString(l, 2, "");
|
||||
if (legacyTransitionNames.find(key) == legacyTransitionNames.end())
|
||||
return luaL_error(l, "Invalid property");
|
||||
@ -162,12 +167,12 @@ int luacon_transitionread(lua_State* l)
|
||||
lua_rawget(l, 1);
|
||||
int i = lua_tointeger (l, lua_gettop(l));
|
||||
lua_pop(l, 1);
|
||||
if (!luacon_sim->IsElement(i))
|
||||
if (!sd.IsElement(i))
|
||||
{
|
||||
return luaL_error(l, "Invalid index");
|
||||
}
|
||||
|
||||
intptr_t propertyAddress = (intptr_t)(((unsigned char*)&luacon_sim->elements[i]) + prop.Offset);
|
||||
intptr_t propertyAddress = (intptr_t)(((const unsigned char*)&elements[i]) + prop.Offset);
|
||||
LuaScriptInterface::LuaGetProperty(l, prop, propertyAddress);
|
||||
|
||||
return 1;
|
||||
@ -175,6 +180,8 @@ int luacon_transitionread(lua_State* l)
|
||||
|
||||
int luacon_transitionwrite(lua_State* l)
|
||||
{
|
||||
auto &sd = SimulationData::Ref();
|
||||
auto &elements = sd.elements;
|
||||
ByteString key = tpt_lua_optByteString(l, 2, "");
|
||||
if (legacyTransitionNames.find(key) == legacyTransitionNames.end())
|
||||
return luaL_error(l, "Invalid property");
|
||||
@ -185,7 +192,7 @@ int luacon_transitionwrite(lua_State* l)
|
||||
lua_rawget(l, 1);
|
||||
int i = lua_tointeger (l, lua_gettop(l));
|
||||
lua_pop(l, 1);
|
||||
if (!luacon_sim->IsElement(i))
|
||||
if (!sd.IsElement(i))
|
||||
{
|
||||
return luaL_error(l, "Invalid index");
|
||||
}
|
||||
@ -193,13 +200,13 @@ int luacon_transitionwrite(lua_State* l)
|
||||
if (prop.Type == StructProperty::TransitionType)
|
||||
{
|
||||
int type = luaL_checkinteger(l, 3);
|
||||
if (!luacon_sim->IsElementOrNone(type) && type != NT && type != ST)
|
||||
if (!sd.IsElementOrNone(type) && type != NT && type != ST)
|
||||
{
|
||||
return luaL_error(l, "Invalid element");
|
||||
}
|
||||
}
|
||||
|
||||
intptr_t propertyAddress = (intptr_t)(((unsigned char*)&luacon_sim->elements[i]) + prop.Offset);
|
||||
intptr_t propertyAddress = (intptr_t)(((unsigned char*)&elements[i]) + prop.Offset);
|
||||
LuaScriptInterface::LuaSetProperty(l, prop, propertyAddress, 3);
|
||||
|
||||
return 0;
|
||||
@ -207,6 +214,8 @@ int luacon_transitionwrite(lua_State* l)
|
||||
|
||||
int luacon_elementread(lua_State* l)
|
||||
{
|
||||
auto &sd = SimulationData::CRef();
|
||||
auto &elements = sd.elements;
|
||||
ByteString key = tpt_lua_optByteString(l, 2, "");
|
||||
if (legacyPropNames.find(key) == legacyPropNames.end())
|
||||
return luaL_error(l, "Invalid property");
|
||||
@ -217,12 +226,12 @@ int luacon_elementread(lua_State* l)
|
||||
lua_rawget(l, 1);
|
||||
int i = lua_tointeger (l, lua_gettop(l));
|
||||
lua_pop(l, 1);
|
||||
if (!luacon_sim->IsElement(i))
|
||||
if (!sd.IsElement(i))
|
||||
{
|
||||
return luaL_error(l, "Invalid index");
|
||||
}
|
||||
|
||||
intptr_t propertyAddress = (intptr_t)(((unsigned char*)&luacon_sim->elements[i]) + prop.Offset);
|
||||
intptr_t propertyAddress = (intptr_t)(((const unsigned char*)&elements[i]) + prop.Offset);
|
||||
LuaScriptInterface::LuaGetProperty(l, prop, propertyAddress);
|
||||
|
||||
return 1;
|
||||
@ -230,6 +239,9 @@ int luacon_elementread(lua_State* l)
|
||||
|
||||
int luacon_elementwrite(lua_State* l)
|
||||
{
|
||||
auto &sd = SimulationData::Ref();
|
||||
std::unique_lock lk(sd.elementGraphicsMx);
|
||||
auto &elements = sd.elements;
|
||||
ByteString key = tpt_lua_optByteString(l, 2, "");
|
||||
if (legacyPropNames.find(key) == legacyPropNames.end())
|
||||
return luaL_error(l, "Invalid property");
|
||||
@ -240,18 +252,18 @@ int luacon_elementwrite(lua_State* l)
|
||||
lua_rawget(l, 1);
|
||||
int i = lua_tointeger (l, lua_gettop(l));
|
||||
lua_pop(l, 1);
|
||||
if (!luacon_sim->IsElement(i))
|
||||
if (!sd.IsElement(i))
|
||||
{
|
||||
return luaL_error(l, "Invalid index");
|
||||
}
|
||||
|
||||
intptr_t propertyAddress = (intptr_t)(((unsigned char*)&luacon_sim->elements[i]) + prop.Offset);
|
||||
intptr_t propertyAddress = (intptr_t)(((unsigned char*)&elements[i]) + prop.Offset);
|
||||
LuaScriptInterface::LuaSetProperty(l, prop, propertyAddress, 3);
|
||||
|
||||
luacon_model->BuildMenus();
|
||||
auto *luacon_ci = static_cast<LuaScriptInterface *>(commandInterface);
|
||||
luacon_ci->custom_init_can_move();
|
||||
std::fill(&luacon_ren->graphicscache[0], &luacon_ren->graphicscache[0] + PT_NUM, gcache_item());
|
||||
sd.graphicscache = std::array<gcache_item, PT_NUM>();
|
||||
|
||||
return 0;
|
||||
}
|
||||
@ -278,21 +290,23 @@ String luacon_geterror()
|
||||
//tpt. api methods
|
||||
int luatpt_getelement(lua_State *l)
|
||||
{
|
||||
auto &sd = SimulationData::CRef();
|
||||
auto &elements = sd.elements;
|
||||
int t;
|
||||
if (lua_isnumber(l, 1))
|
||||
{
|
||||
t = luaL_optint(l, 1, 1);
|
||||
if (!luacon_sim->IsElementOrNone(t))
|
||||
if (!sd.IsElementOrNone(t))
|
||||
{
|
||||
return luaL_error(l, "Unrecognised element number '%d'", t);
|
||||
}
|
||||
tpt_lua_pushString(l, luacon_sim->elements[t].Name);
|
||||
tpt_lua_pushString(l, elements[t].Name);
|
||||
}
|
||||
else
|
||||
{
|
||||
luaL_checktype(l, 1, LUA_TSTRING);
|
||||
auto name = tpt_lua_optByteString(l, 1, "");
|
||||
if ((t = luacon_sim->GetParticleType(name))==-1)
|
||||
if ((t = sd.GetParticleType(name))==-1)
|
||||
return luaL_error(l, "Unrecognised element '%s'", name.c_str());
|
||||
lua_pushinteger(l, t);
|
||||
}
|
||||
@ -326,6 +340,7 @@ int luatpt_drawtext(lua_State* l)
|
||||
|
||||
int luatpt_create(lua_State* l)
|
||||
{
|
||||
auto &sd = SimulationData::CRef();
|
||||
int x, y, retid, t = -1;
|
||||
x = abs(luaL_optint(l, 1, 0));
|
||||
y = abs(luaL_optint(l, 2, 0));
|
||||
@ -334,13 +349,13 @@ int luatpt_create(lua_State* l)
|
||||
if (lua_isnumber(l, 3))
|
||||
{
|
||||
t = luaL_optint(l, 3, 0);
|
||||
if (!luacon_sim->IsElement(t))
|
||||
if (!sd.IsElement(t))
|
||||
{
|
||||
return luaL_error(l, "Unrecognised element number '%d'", t);
|
||||
}
|
||||
} else {
|
||||
auto name = tpt_lua_optByteString(l, 3, "dust");
|
||||
if ((t = luacon_sim->GetParticleType(name)) == -1)
|
||||
if ((t = sd.GetParticleType(name)) == -1)
|
||||
return luaL_error(l,"Unrecognised element '%s'", name.c_str());
|
||||
}
|
||||
retid = luacon_sim->create_part(-1, x, y, t);
|
||||
@ -547,6 +562,7 @@ int luatpt_reset_spark(lua_State* l)
|
||||
|
||||
int luatpt_set_property(lua_State* l)
|
||||
{
|
||||
auto &sd = SimulationData::CRef();
|
||||
auto *luacon_ci = static_cast<LuaScriptInterface *>(commandInterface);
|
||||
int r, i, x, y, w, h, t = 0, nx, ny, partsel = 0;
|
||||
float f = 0;
|
||||
@ -565,7 +581,7 @@ int luatpt_set_property(lua_State* l)
|
||||
if(!lua_isnumber(l, acount) && lua_isstring(l, acount))
|
||||
{
|
||||
auto name = tpt_lua_optByteString(l, acount, "none");
|
||||
if ((partsel = luacon_sim->GetParticleType(name)) == -1)
|
||||
if ((partsel = sd.GetParticleType(name)) == -1)
|
||||
return luaL_error(l, "Unrecognised element '%s'", name.c_str());
|
||||
}
|
||||
}
|
||||
@ -576,13 +592,13 @@ int luatpt_set_property(lua_State* l)
|
||||
else
|
||||
t = luaL_optint(l, 2, 0);
|
||||
|
||||
if (byteStringEqualsLiteral(prop, "type") && !luacon_sim->IsElementOrNone(t))
|
||||
if (byteStringEqualsLiteral(prop, "type") && !sd.IsElementOrNone(t))
|
||||
return luaL_error(l, "Unrecognised element number '%d'", t);
|
||||
}
|
||||
else if (lua_isstring(l, 2))
|
||||
{
|
||||
auto name = tpt_lua_checkByteString(l, 2);
|
||||
if ((t = luacon_sim->GetParticleType(name))==-1)
|
||||
if ((t = sd.GetParticleType(name))==-1)
|
||||
return luaL_error(l, "Unrecognised element '%s'", name.c_str());
|
||||
}
|
||||
else
|
||||
@ -1141,12 +1157,15 @@ int luatpt_menu_enabled(lua_State* l)
|
||||
int acount = lua_gettop(l);
|
||||
if (acount == 1)
|
||||
{
|
||||
lua_pushboolean(l, luacon_sim->msections[menusection].doshow);
|
||||
lua_pushboolean(l, SimulationData::CRef().msections[menusection].doshow);
|
||||
return 1;
|
||||
}
|
||||
luaL_checktype(l, 2, LUA_TBOOLEAN);
|
||||
int enabled = lua_toboolean(l, 2);
|
||||
luacon_sim->msections[menusection].doshow = enabled;
|
||||
{
|
||||
auto &sd = SimulationData::Ref();
|
||||
sd.msections[menusection].doshow = enabled;
|
||||
}
|
||||
luacon_model->BuildMenus();
|
||||
return 0;
|
||||
}
|
||||
|
@ -451,11 +451,13 @@ LuaScriptInterface::LuaScriptInterface(GameController * c, GameModel * m):
|
||||
tptPart->Assign(l, -1);
|
||||
lua_pop(l, 1);
|
||||
|
||||
auto &sd = SimulationData::CRef();
|
||||
auto &elements = sd.elements;
|
||||
lua_newtable(l);
|
||||
tptElements = lua_gettop(l);
|
||||
for (int i = 1; i < PT_NUM; i++)
|
||||
{
|
||||
tpt_lua_pushString(l, luacon_sim->elements[i].Name.ToLower());
|
||||
tpt_lua_pushString(l, elements[i].Name.ToLower());
|
||||
lua_newtable(l);
|
||||
currentElement = lua_gettop(l);
|
||||
lua_pushinteger(l, i);
|
||||
@ -475,7 +477,7 @@ LuaScriptInterface::LuaScriptInterface(GameController * c, GameModel * m):
|
||||
tptElementTransitions = lua_gettop(l);
|
||||
for (int i = 1; i < PT_NUM; i++)
|
||||
{
|
||||
tpt_lua_pushString(l, luacon_sim->elements[i].Name.ToLower());
|
||||
tpt_lua_pushString(l, elements[i].Name.ToLower());
|
||||
lua_newtable(l);
|
||||
currentElement = lua_gettop(l);
|
||||
lua_newtable(l);
|
||||
@ -536,14 +538,15 @@ LuaScriptInterface::LuaScriptInterface(GameController * c, GameModel * m):
|
||||
|
||||
void LuaScriptInterface::custom_init_can_move()
|
||||
{
|
||||
luacon_sim->init_can_move();
|
||||
auto &sd = SimulationData::Ref();
|
||||
sd.init_can_move();
|
||||
for (auto moving = 0; moving < PT_NUM; ++moving)
|
||||
{
|
||||
for (auto into = 0; into < PT_NUM; ++into)
|
||||
{
|
||||
if (custom_can_move[moving][into] & 0x80)
|
||||
{
|
||||
luacon_sim->can_move[moving][into] = custom_can_move[moving][into] & 0x7F;
|
||||
sd.can_move[moving][into] = custom_can_move[moving][into] & 0x7F;
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -1112,6 +1115,8 @@ int simulation_deletesign(lua_State *l)
|
||||
|
||||
void LuaScriptInterface::initSimulationAPI()
|
||||
{
|
||||
auto &sd = SimulationData::CRef();
|
||||
|
||||
//Methods
|
||||
struct luaL_Reg simulationAPIMethods [] = {
|
||||
{"partNeighbours", simulation_partNeighbours},
|
||||
@ -1227,7 +1232,7 @@ void LuaScriptInterface::initSimulationAPI()
|
||||
SETCONST(l, TOOL_NGRV);
|
||||
SETCONST(l, TOOL_MIX);
|
||||
SETCONST(l, TOOL_CYCL);
|
||||
lua_pushinteger(l, luacon_sim->tools.size()); lua_setfield(l, -2, "TOOL_WIND");
|
||||
lua_pushinteger(l, sd.tools.size()); lua_setfield(l, -2, "TOOL_WIND");
|
||||
|
||||
SETCONST(l, DECO_DRAW);
|
||||
SETCONST(l, DECO_CLEAR);
|
||||
@ -1266,12 +1271,12 @@ void LuaScriptInterface::initSimulationAPI()
|
||||
lua_newtable(l);
|
||||
for (int i = 0; i < UI_WALLCOUNT; i++)
|
||||
{
|
||||
tpt_lua_pushByteString(l, luacon_sim->wtypes[i].identifier);
|
||||
tpt_lua_pushByteString(l, sd.wtypes[i].identifier);
|
||||
lua_pushinteger(l, i);
|
||||
lua_settable(l, -3);
|
||||
|
||||
lua_pushinteger(l, i);
|
||||
tpt_lua_pushByteString(l, luacon_sim->wtypes[i].identifier);
|
||||
tpt_lua_pushByteString(l, sd.wtypes[i].identifier);
|
||||
lua_settable(l, -3);
|
||||
}
|
||||
lua_setfield(l, -2, "walls");
|
||||
@ -1898,6 +1903,7 @@ int LuaScriptInterface::simulation_floodWalls(lua_State * l)
|
||||
|
||||
int LuaScriptInterface::simulation_toolBrush(lua_State * l)
|
||||
{
|
||||
auto &sd = SimulationData::CRef();
|
||||
int x = luaL_optint(l,1,-1);
|
||||
int y = luaL_optint(l,2,-1);
|
||||
int rx = luaL_optint(l,3,5);
|
||||
@ -1905,12 +1911,12 @@ int LuaScriptInterface::simulation_toolBrush(lua_State * l)
|
||||
int tool = luaL_optint(l,5,0);
|
||||
int brushID = luaL_optint(l,6,CIRCLE_BRUSH);
|
||||
float strength = luaL_optnumber(l,7,1.0f);
|
||||
if (tool == (int)luacon_sim->tools.size())
|
||||
if (tool == (int)sd.tools.size())
|
||||
{
|
||||
lua_pushinteger(l, 0);
|
||||
return 1;
|
||||
}
|
||||
else if (tool < 0 || tool > (int)luacon_sim->tools.size())
|
||||
else if (tool < 0 || tool > (int)sd.tools.size())
|
||||
return luaL_error(l, "Invalid tool id '%d'", tool);
|
||||
|
||||
Brush *brush = luacon_model->GetBrushByID(brushID);
|
||||
@ -1926,6 +1932,7 @@ int LuaScriptInterface::simulation_toolBrush(lua_State * l)
|
||||
|
||||
int LuaScriptInterface::simulation_toolLine(lua_State * l)
|
||||
{
|
||||
auto &sd = SimulationData::CRef();
|
||||
int x1 = luaL_optint(l,1,-1);
|
||||
int y1 = luaL_optint(l,2,-1);
|
||||
int x2 = luaL_optint(l,3,-1);
|
||||
@ -1938,7 +1945,7 @@ int LuaScriptInterface::simulation_toolLine(lua_State * l)
|
||||
|
||||
if (x1 < 0 || x2 < 0 || x1 >= XRES || x2 >= XRES || y1 < 0 || y2 < 0 || y1 >= YRES || y2 >= YRES)
|
||||
return luaL_error(l, "coordinates out of range (%d,%d),(%d,%d)", x1, y1, x2, y2);
|
||||
if (tool < 0 || tool >= (int)luacon_sim->tools.size()+1)
|
||||
if (tool < 0 || tool >= (int)sd.tools.size()+1)
|
||||
return luaL_error(l, "Invalid tool id '%d'", tool);
|
||||
|
||||
Brush *brush = luacon_model->GetBrushByID(brushID);
|
||||
@ -1947,7 +1954,7 @@ int LuaScriptInterface::simulation_toolLine(lua_State * l)
|
||||
auto newBrush = brush->Clone();
|
||||
newBrush->SetRadius(ui::Point(rx, ry));
|
||||
|
||||
if (tool == (int)luacon_sim->tools.size())
|
||||
if (tool == (int)sd.tools.size())
|
||||
{
|
||||
Tool *windTool = luacon_model->GetToolFromIdentifier("DEFAULT_UI_WIND");
|
||||
float oldStrength = windTool->Strength;
|
||||
@ -1962,6 +1969,7 @@ int LuaScriptInterface::simulation_toolLine(lua_State * l)
|
||||
|
||||
int LuaScriptInterface::simulation_toolBox(lua_State * l)
|
||||
{
|
||||
auto &sd = SimulationData::CRef();
|
||||
int x1 = luaL_optint(l,1,-1);
|
||||
int y1 = luaL_optint(l,2,-1);
|
||||
int x2 = luaL_optint(l,3,-1);
|
||||
@ -1970,12 +1978,12 @@ int LuaScriptInterface::simulation_toolBox(lua_State * l)
|
||||
return luaL_error(l, "coordinates out of range (%d,%d),(%d,%d)", x1, y1, x2, y2);
|
||||
int tool = luaL_optint(l,5,0);
|
||||
float strength = luaL_optnumber(l,6,1.0f);
|
||||
if (tool == (int)luacon_sim->tools.size())
|
||||
if (tool == (int)sd.tools.size())
|
||||
{
|
||||
lua_pushinteger(l, 0);
|
||||
return 1;
|
||||
}
|
||||
else if (tool < 0 || tool >= (int)luacon_sim->tools.size())
|
||||
else if (tool < 0 || tool >= (int)sd.tools.size())
|
||||
return luaL_error(l, "Invalid tool id '%d'", tool);
|
||||
|
||||
luacon_sim->ToolBox(x1, y1, x2, y2, tool, strength);
|
||||
@ -2110,12 +2118,14 @@ int LuaScriptInterface::simulation_clearRect(lua_State * l)
|
||||
|
||||
int LuaScriptInterface::simulation_resetTemp(lua_State * l)
|
||||
{
|
||||
auto &sd = SimulationData::CRef();
|
||||
auto &elements = sd.elements;
|
||||
bool onlyConductors = luaL_optint(l, 1, 0);
|
||||
for (int i = 0; i < luacon_sim->parts_lastActiveIndex; i++)
|
||||
{
|
||||
if (luacon_sim->parts[i].type && (luacon_sim->elements[luacon_sim->parts[i].type].HeatConduct || !onlyConductors))
|
||||
if (luacon_sim->parts[i].type && (elements[luacon_sim->parts[i].type].HeatConduct || !onlyConductors))
|
||||
{
|
||||
luacon_sim->parts[i].temp = luacon_sim->elements[luacon_sim->parts[i].type].DefaultProperties.temp;
|
||||
luacon_sim->parts[i].temp = elements[luacon_sim->parts[i].type].DefaultProperties.temp;
|
||||
}
|
||||
}
|
||||
return 0;
|
||||
@ -2427,14 +2437,16 @@ int LuaScriptInterface::simulation_canMove(lua_State * l)
|
||||
|
||||
if (lua_gettop(l) < 3)
|
||||
{
|
||||
lua_pushnumber(l, luacon_sim->can_move[movingElement][destinationElement]);
|
||||
auto &sd = SimulationData::CRef();
|
||||
lua_pushnumber(l, sd.can_move[movingElement][destinationElement]);
|
||||
return 1;
|
||||
}
|
||||
else
|
||||
{
|
||||
int setting = luaL_checkint(l, 3) & 0x7F;
|
||||
luacon_ci->custom_can_move[movingElement][destinationElement] = setting | 0x80;
|
||||
luacon_sim->can_move[movingElement][destinationElement] = setting;
|
||||
auto &sd = SimulationData::Ref();
|
||||
sd.can_move[movingElement][destinationElement] = setting;
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
@ -2684,9 +2696,10 @@ int LuaScriptInterface::simulation_replaceModeFlags(lua_State *l)
|
||||
|
||||
int LuaScriptInterface::simulation_listCustomGol(lua_State *l)
|
||||
{
|
||||
auto &sd = SimulationData::CRef();
|
||||
int i = 0;
|
||||
lua_newtable(l);
|
||||
for (auto &cgol : luacon_sim->GetCustomGol())
|
||||
for (auto &cgol : sd.GetCustomGol())
|
||||
{
|
||||
lua_newtable(l);
|
||||
tpt_lua_pushString(l, cgol.nameString);
|
||||
@ -2706,6 +2719,7 @@ int LuaScriptInterface::simulation_listCustomGol(lua_State *l)
|
||||
|
||||
int LuaScriptInterface::simulation_addCustomGol(lua_State *l)
|
||||
{
|
||||
auto &sd = SimulationData::CRef();
|
||||
int rule;
|
||||
String ruleString;
|
||||
if (lua_isnumber(l, 1))
|
||||
@ -2727,7 +2741,7 @@ int LuaScriptInterface::simulation_addCustomGol(lua_State *l)
|
||||
return luaL_error(l, "Invalid name provided");
|
||||
if (rule == -1)
|
||||
return luaL_error(l, "Invalid rule provided");
|
||||
if (luacon_sim->GetCustomGOLByRule(rule))
|
||||
if (sd.GetCustomGOLByRule(rule))
|
||||
return luaL_error(l, "This Custom GoL rule already exists");
|
||||
|
||||
if (!AddCustomGol(ruleString, nameString, color1, color2))
|
||||
@ -3145,15 +3159,17 @@ void LuaScriptInterface::initElementsAPI()
|
||||
SETCONST(l, SC_DECO);
|
||||
|
||||
//Element identifiers
|
||||
auto &sd = SimulationData::CRef();
|
||||
auto &elements = sd.elements;
|
||||
for(int i = 0; i < PT_NUM; i++)
|
||||
{
|
||||
if(luacon_sim->elements[i].Enabled)
|
||||
if(elements[i].Enabled)
|
||||
{
|
||||
tpt_lua_pushByteString(l, luacon_sim->elements[i].Identifier);
|
||||
tpt_lua_pushByteString(l, elements[i].Identifier);
|
||||
lua_pushinteger(l, i);
|
||||
lua_settable(l, -3);
|
||||
ByteString realIdentifier = ByteString::Build("DEFAULT_PT_", luacon_sim->elements[i].Name.ToUtf8());
|
||||
if (i != 0 && i != PT_NBHL && i != PT_NWHL && luacon_sim->elements[i].Identifier != realIdentifier)
|
||||
ByteString realIdentifier = ByteString::Build("DEFAULT_PT_", elements[i].Name.ToUtf8());
|
||||
if (i != 0 && i != PT_NBHL && i != PT_NWHL && elements[i].Identifier != realIdentifier)
|
||||
{
|
||||
tpt_lua_pushByteString(l, realIdentifier);
|
||||
lua_pushinteger(l, i);
|
||||
@ -3270,52 +3286,58 @@ void LuaScriptInterface::LuaSetParticleProperty(lua_State* l, int particleID, St
|
||||
|
||||
int LuaScriptInterface::elements_loadDefault(lua_State * l)
|
||||
{
|
||||
auto &sd = SimulationData::Ref();
|
||||
std::unique_lock lk(sd.elementGraphicsMx);
|
||||
auto &elements = sd.elements;
|
||||
auto &builtinElements = GetElements();
|
||||
auto *luacon_ci = static_cast<LuaScriptInterface *>(commandInterface);
|
||||
int args = lua_gettop(l);
|
||||
if (args)
|
||||
{
|
||||
luaL_checktype(l, 1, LUA_TNUMBER);
|
||||
int id = lua_tointeger(l, 1);
|
||||
if (id < 0 || id >= PT_NUM)
|
||||
return luaL_error(l, "Invalid element");
|
||||
|
||||
lua_getglobal(l, "elements");
|
||||
tpt_lua_pushByteString(l, luacon_sim->elements[id].Identifier);
|
||||
lua_pushnil(l);
|
||||
lua_settable(l, -3);
|
||||
|
||||
auto const &elementList = GetElements();
|
||||
if (id < (int)elementList.size())
|
||||
luacon_sim->elements[id] = elementList[id];
|
||||
else
|
||||
luacon_sim->elements[id] = Element();
|
||||
|
||||
tpt_lua_pushByteString(l, luacon_sim->elements[id].Identifier);
|
||||
lua_pushinteger(l, id);
|
||||
lua_settable(l, -3);
|
||||
lua_pop(l, 1);
|
||||
}
|
||||
else
|
||||
{
|
||||
auto const &elementList = GetElements();
|
||||
for (int i = 0; i < PT_NUM; i++)
|
||||
int args = lua_gettop(l);
|
||||
if (args)
|
||||
{
|
||||
if (i < (int)elementList.size())
|
||||
luacon_sim->elements[i] = elementList[i];
|
||||
luaL_checktype(l, 1, LUA_TNUMBER);
|
||||
int id = lua_tointeger(l, 1);
|
||||
if (id < 0 || id >= PT_NUM)
|
||||
return luaL_error(l, "Invalid element");
|
||||
|
||||
lua_getglobal(l, "elements");
|
||||
ByteString identifier = SimulationData::CRef().elements[id].Identifier;
|
||||
tpt_lua_pushByteString(l, identifier);
|
||||
lua_pushnil(l);
|
||||
lua_settable(l, -3);
|
||||
|
||||
if (id < (int)builtinElements.size())
|
||||
elements[id] = builtinElements[id];
|
||||
else
|
||||
luacon_sim->elements[i] = Element();
|
||||
elements[id] = Element();
|
||||
|
||||
tpt_lua_pushByteString(l, identifier);
|
||||
lua_pushinteger(l, id);
|
||||
lua_settable(l, -3);
|
||||
lua_pop(l, 1);
|
||||
}
|
||||
lua_pushnil(l);
|
||||
lua_setglobal(l, "elements");
|
||||
lua_pushnil(l);
|
||||
lua_setglobal(l, "elem");
|
||||
else
|
||||
{
|
||||
for (int i = 0; i < PT_NUM; i++)
|
||||
{
|
||||
if (i < (int)builtinElements.size())
|
||||
elements[i] = builtinElements[i];
|
||||
else
|
||||
elements[i] = Element();
|
||||
}
|
||||
|
||||
lua_getglobal(l, "package");
|
||||
lua_getfield(l, -1, "loaded");
|
||||
lua_pushnil(l);
|
||||
lua_setfield(l, -2, "elements");
|
||||
lua_pushnil(l);
|
||||
lua_setglobal(l, "elements");
|
||||
lua_pushnil(l);
|
||||
lua_setglobal(l, "elem");
|
||||
|
||||
luacon_ci->initElementsAPI();
|
||||
lua_getglobal(l, "package");
|
||||
lua_getfield(l, -1, "loaded");
|
||||
lua_pushnil(l);
|
||||
lua_setfield(l, -2, "elements");
|
||||
|
||||
luacon_ci->initElementsAPI();
|
||||
}
|
||||
}
|
||||
|
||||
luacon_model->BuildMenus();
|
||||
@ -3327,8 +3349,7 @@ int LuaScriptInterface::elements_loadDefault(lua_State * l)
|
||||
}
|
||||
}
|
||||
luacon_ci->custom_init_can_move();
|
||||
std::fill(luacon_ren->graphicscache, luacon_ren->graphicscache+PT_NUM, gcache_item());
|
||||
SaveRenderer::Ref().Flush(0, PT_NUM);
|
||||
sd.graphicscache = std::array<gcache_item, PT_NUM>();
|
||||
return 0;
|
||||
}
|
||||
|
||||
@ -3355,40 +3376,49 @@ int LuaScriptInterface::elements_allocate(lua_State * l)
|
||||
|
||||
auto identifier = group + "_PT_" + id;
|
||||
|
||||
for(int i = 0; i < PT_NUM; i++)
|
||||
{
|
||||
if(luacon_sim->elements[i].Enabled && ByteString(luacon_sim->elements[i].Identifier) == identifier)
|
||||
return luaL_error(l, "Element identifier already in use");
|
||||
}
|
||||
|
||||
int newID = -1;
|
||||
// Start out at 255 so that lua element IDs are still one byte (better save compatibility)
|
||||
for (int i = PT_NUM >= 255 ? 255 : PT_NUM; i >= 0; i--)
|
||||
{
|
||||
if (!luacon_sim->elements[i].Enabled)
|
||||
auto &sd = SimulationData::CRef();
|
||||
auto &elements = sd.elements;
|
||||
for(int i = 0; i < PT_NUM; i++)
|
||||
{
|
||||
newID = i;
|
||||
break;
|
||||
if(elements[i].Enabled && ByteString(elements[i].Identifier) == identifier)
|
||||
return luaL_error(l, "Element identifier already in use");
|
||||
}
|
||||
}
|
||||
// If not enough space, then we start with the new maimum ID
|
||||
if (newID == -1)
|
||||
{
|
||||
for (int i = PT_NUM-1; i >= 255; i--)
|
||||
|
||||
// Start out at 255 so that lua element IDs are still one byte (better save compatibility)
|
||||
for (int i = PT_NUM >= 255 ? 255 : PT_NUM; i >= 0; i--)
|
||||
{
|
||||
if (!luacon_sim->elements[i].Enabled)
|
||||
if (!elements[i].Enabled)
|
||||
{
|
||||
newID = i;
|
||||
break;
|
||||
}
|
||||
}
|
||||
// If not enough space, then we start with the new maimum ID
|
||||
if (newID == -1)
|
||||
{
|
||||
for (int i = PT_NUM-1; i >= 255; i--)
|
||||
{
|
||||
if (!elements[i].Enabled)
|
||||
{
|
||||
newID = i;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (newID != -1)
|
||||
{
|
||||
luacon_sim->elements[newID] = Element();
|
||||
luacon_sim->elements[newID].Enabled = true;
|
||||
luacon_sim->elements[newID].Identifier = identifier;
|
||||
{
|
||||
auto &sd = SimulationData::Ref();
|
||||
std::unique_lock lk(sd.elementGraphicsMx);
|
||||
auto &elements = sd.elements;
|
||||
elements[newID] = Element();
|
||||
elements[newID].Enabled = true;
|
||||
elements[newID].Identifier = identifier;
|
||||
}
|
||||
|
||||
lua_getglobal(l, "elements");
|
||||
tpt_lua_pushByteString(l, identifier);
|
||||
@ -3411,8 +3441,13 @@ int LuaScriptInterface::elements_allocate(lua_State * l)
|
||||
|
||||
static int luaUpdateWrapper(UPDATE_FUNC_ARGS)
|
||||
{
|
||||
if (!sim->useLuaCallbacks)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
auto *luacon_ci = static_cast<LuaScriptInterface *>(commandInterface);
|
||||
auto *builtinUpdate = GetElements()[parts[i].type].Update;
|
||||
auto &builtinElements = GetElements();
|
||||
auto *builtinUpdate = builtinElements[parts[i].type].Update;
|
||||
if (builtinUpdate && lua_el_mode[parts[i].type] == 1)
|
||||
{
|
||||
if (builtinUpdate(UPDATE_FUNC_SUBCALL_ARGS))
|
||||
@ -3455,11 +3490,21 @@ static int luaUpdateWrapper(UPDATE_FUNC_ARGS)
|
||||
|
||||
static int luaGraphicsWrapper(GRAPHICS_FUNC_ARGS)
|
||||
{
|
||||
if (!gfctx.sim->useLuaCallbacks)
|
||||
{
|
||||
return Element::defaultGraphics(GRAPHICS_FUNC_SUBCALL_ARGS);
|
||||
}
|
||||
auto *luacon_ci = static_cast<LuaScriptInterface *>(commandInterface);
|
||||
if (lua_gr_func[cpart->type])
|
||||
{
|
||||
auto *pipeSubcallWcpart = gfctx.pipeSubcallCpart ? luacon_sim->parts + (gfctx.pipeSubcallCpart - gfctx.sim->parts) : nullptr;
|
||||
if (pipeSubcallWcpart)
|
||||
{
|
||||
std::swap(*pipeSubcallWcpart, *gfctx.pipeSubcallTpart);
|
||||
cpart = pipeSubcallWcpart;
|
||||
}
|
||||
int cache = 0, callret;
|
||||
int i = cpart - ren->sim->parts; // pointer arithmetic be like
|
||||
int i = cpart - gfctx.sim->parts; // pointer arithmetic be like
|
||||
lua_rawgeti(luacon_ci->l, LUA_REGISTRYINDEX, lua_gr_func[cpart->type]);
|
||||
lua_pushinteger(luacon_ci->l, i);
|
||||
lua_pushinteger(luacon_ci->l, *colr);
|
||||
@ -3495,6 +3540,10 @@ static int luaGraphicsWrapper(GRAPHICS_FUNC_ARGS)
|
||||
}
|
||||
lua_pop(luacon_ci->l, 10);
|
||||
}
|
||||
if (pipeSubcallWcpart)
|
||||
{
|
||||
std::swap(*pipeSubcallWcpart, *gfctx.pipeSubcallTpart);
|
||||
}
|
||||
return cache;
|
||||
}
|
||||
return 0;
|
||||
@ -3502,6 +3551,10 @@ static int luaGraphicsWrapper(GRAPHICS_FUNC_ARGS)
|
||||
|
||||
static void luaCreateWrapper(ELEMENT_CREATE_FUNC_ARGS)
|
||||
{
|
||||
if (!sim->useLuaCallbacks)
|
||||
{
|
||||
return;
|
||||
}
|
||||
auto *luacon_ci = static_cast<LuaScriptInterface *>(commandInterface);
|
||||
if (luaCreateHandlers[sim->parts[i].type])
|
||||
{
|
||||
@ -3521,6 +3574,13 @@ static void luaCreateWrapper(ELEMENT_CREATE_FUNC_ARGS)
|
||||
|
||||
static bool luaCreateAllowedWrapper(ELEMENT_CREATE_ALLOWED_FUNC_ARGS)
|
||||
{
|
||||
if (!sim->useLuaCallbacks)
|
||||
{
|
||||
// Nothing really bad can happen, no callbacks are allowed anyway. The worst thing that can happen
|
||||
// is that a well-crafted save looks odd in previews because it has multiple Element::defaultGraphics-rendered
|
||||
// instances of something that should be limited to one instance.
|
||||
return 1;
|
||||
}
|
||||
auto *luacon_ci = static_cast<LuaScriptInterface *>(commandInterface);
|
||||
bool ret = false;
|
||||
if (luaCreateAllowedHandlers[t])
|
||||
@ -3547,6 +3607,10 @@ static bool luaCreateAllowedWrapper(ELEMENT_CREATE_ALLOWED_FUNC_ARGS)
|
||||
|
||||
static void luaChangeTypeWrapper(ELEMENT_CHANGETYPE_FUNC_ARGS)
|
||||
{
|
||||
if (!sim->useLuaCallbacks)
|
||||
{
|
||||
return;
|
||||
}
|
||||
auto *luacon_ci = static_cast<LuaScriptInterface *>(commandInterface);
|
||||
if (luaChangeTypeHandlers[sim->parts[i].type])
|
||||
{
|
||||
@ -3566,6 +3630,10 @@ static void luaChangeTypeWrapper(ELEMENT_CHANGETYPE_FUNC_ARGS)
|
||||
|
||||
static bool luaCtypeDrawWrapper(CTYPEDRAW_FUNC_ARGS)
|
||||
{
|
||||
if (!sim->useLuaCallbacks)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
auto *luacon_ci = static_cast<LuaScriptInterface *>(commandInterface);
|
||||
bool ret = false;
|
||||
if (luaCtypeDrawHandlers[sim->parts[i].type])
|
||||
@ -3591,133 +3659,140 @@ static bool luaCtypeDrawWrapper(CTYPEDRAW_FUNC_ARGS)
|
||||
|
||||
int LuaScriptInterface::elements_element(lua_State * l)
|
||||
{
|
||||
auto &builtinElements = GetElements();
|
||||
auto *luacon_ci = static_cast<LuaScriptInterface *>(commandInterface);
|
||||
int id = luaL_checkinteger(l, 1);
|
||||
if (!luacon_sim->IsElementOrNone(id))
|
||||
if (!SimulationData::CRef().IsElementOrNone(id))
|
||||
{
|
||||
return luaL_error(l, "Invalid element");
|
||||
}
|
||||
|
||||
if (lua_gettop(l) > 1)
|
||||
{
|
||||
luaL_checktype(l, 2, LUA_TTABLE);
|
||||
//Write values from native data to a table
|
||||
for (auto &prop : Element::GetProperties())
|
||||
{
|
||||
tpt_lua_pushByteString(l, prop.Name);
|
||||
lua_gettable(l, -2);
|
||||
if (lua_type(l, -1) != LUA_TNIL)
|
||||
auto &sd = SimulationData::Ref();
|
||||
std::unique_lock lk(sd.elementGraphicsMx);
|
||||
auto &elements = sd.elements;
|
||||
luaL_checktype(l, 2, LUA_TTABLE);
|
||||
//Write values from native data to a table
|
||||
for (auto &prop : Element::GetProperties())
|
||||
{
|
||||
intptr_t propertyAddress = (intptr_t)(((unsigned char*)&luacon_sim->elements[id]) + prop.Offset);
|
||||
LuaSetProperty(l, prop, propertyAddress, -1);
|
||||
tpt_lua_pushByteString(l, prop.Name);
|
||||
lua_gettable(l, -2);
|
||||
if (lua_type(l, -1) != LUA_TNIL)
|
||||
{
|
||||
intptr_t propertyAddress = (intptr_t)(((unsigned char*)&elements[id]) + prop.Offset);
|
||||
LuaSetProperty(l, prop, propertyAddress, -1);
|
||||
}
|
||||
lua_pop(l, 1);
|
||||
}
|
||||
|
||||
lua_getfield(l, -1, "Update");
|
||||
if (lua_type(l, -1) == LUA_TFUNCTION)
|
||||
{
|
||||
lua_el_func[id].Assign(l, -1);
|
||||
lua_el_mode[id] = 1;
|
||||
elements[id].Update = luaUpdateWrapper;
|
||||
}
|
||||
else if (lua_type(l, -1) == LUA_TBOOLEAN && !lua_toboolean(l, -1))
|
||||
{
|
||||
lua_el_func[id].Clear();
|
||||
lua_el_mode[id] = 0;
|
||||
elements[id].Update = builtinElements[id].Update;
|
||||
}
|
||||
lua_pop(l, 1);
|
||||
}
|
||||
|
||||
lua_getfield(l, -1, "Update");
|
||||
if (lua_type(l, -1) == LUA_TFUNCTION)
|
||||
{
|
||||
lua_el_func[id].Assign(l, -1);
|
||||
lua_el_mode[id] = 1;
|
||||
luacon_sim->elements[id].Update = luaUpdateWrapper;
|
||||
}
|
||||
else if (lua_type(l, -1) == LUA_TBOOLEAN && !lua_toboolean(l, -1))
|
||||
{
|
||||
lua_el_func[id].Clear();
|
||||
lua_el_mode[id] = 0;
|
||||
luacon_sim->elements[id].Update = GetElements()[id].Update;
|
||||
}
|
||||
lua_pop(l, 1);
|
||||
lua_getfield(l, -1, "Graphics");
|
||||
if (lua_type(l, -1) == LUA_TFUNCTION)
|
||||
{
|
||||
lua_gr_func[id].Assign(l, -1);
|
||||
elements[id].Graphics = luaGraphicsWrapper;
|
||||
}
|
||||
else if (lua_type(l, -1) == LUA_TBOOLEAN && !lua_toboolean(l, -1))
|
||||
{
|
||||
lua_gr_func[id].Clear();
|
||||
elements[id].Graphics = builtinElements[id].Graphics;
|
||||
}
|
||||
lua_pop(l, 1);
|
||||
|
||||
lua_getfield(l, -1, "Graphics");
|
||||
if (lua_type(l, -1) == LUA_TFUNCTION)
|
||||
{
|
||||
lua_gr_func[id].Assign(l, -1);
|
||||
luacon_sim->elements[id].Graphics = luaGraphicsWrapper;
|
||||
}
|
||||
else if (lua_type(l, -1) == LUA_TBOOLEAN && !lua_toboolean(l, -1))
|
||||
{
|
||||
lua_gr_func[id].Clear();
|
||||
luacon_sim->elements[id].Graphics = GetElements()[id].Graphics;
|
||||
}
|
||||
lua_pop(l, 1);
|
||||
lua_getfield(l, -1, "Create");
|
||||
if (lua_type(l, -1) == LUA_TFUNCTION)
|
||||
{
|
||||
luaCreateHandlers[id].Assign(l, -1);
|
||||
elements[id].Create = luaCreateWrapper;
|
||||
}
|
||||
else if (lua_type(l, -1) == LUA_TBOOLEAN && !lua_toboolean(l, -1))
|
||||
{
|
||||
luaCreateHandlers[id].Clear();
|
||||
elements[id].Create = builtinElements[id].Create;
|
||||
}
|
||||
lua_pop(l, 1);
|
||||
|
||||
lua_getfield(l, -1, "Create");
|
||||
if (lua_type(l, -1) == LUA_TFUNCTION)
|
||||
{
|
||||
luaCreateHandlers[id].Assign(l, -1);
|
||||
luacon_sim->elements[id].Create = luaCreateWrapper;
|
||||
}
|
||||
else if (lua_type(l, -1) == LUA_TBOOLEAN && !lua_toboolean(l, -1))
|
||||
{
|
||||
luaCreateHandlers[id].Clear();
|
||||
luacon_sim->elements[id].Create = GetElements()[id].Create;
|
||||
}
|
||||
lua_pop(l, 1);
|
||||
lua_getfield(l, -1, "CreateAllowed");
|
||||
if (lua_type(l, -1) == LUA_TFUNCTION)
|
||||
{
|
||||
luaCreateAllowedHandlers[id].Assign(l, -1);
|
||||
elements[id].CreateAllowed = luaCreateAllowedWrapper;
|
||||
}
|
||||
else if (lua_type(l, -1) == LUA_TBOOLEAN && !lua_toboolean(l, -1))
|
||||
{
|
||||
luaCreateAllowedHandlers[id].Clear();
|
||||
elements[id].CreateAllowed = builtinElements[id].CreateAllowed;
|
||||
}
|
||||
lua_pop(l, 1);
|
||||
|
||||
lua_getfield(l, -1, "CreateAllowed");
|
||||
if (lua_type(l, -1) == LUA_TFUNCTION)
|
||||
{
|
||||
luaCreateAllowedHandlers[id].Assign(l, -1);
|
||||
luacon_sim->elements[id].CreateAllowed = luaCreateAllowedWrapper;
|
||||
}
|
||||
else if (lua_type(l, -1) == LUA_TBOOLEAN && !lua_toboolean(l, -1))
|
||||
{
|
||||
luaCreateAllowedHandlers[id].Clear();
|
||||
luacon_sim->elements[id].CreateAllowed = GetElements()[id].CreateAllowed;
|
||||
}
|
||||
lua_pop(l, 1);
|
||||
lua_getfield(l, -1, "ChangeType");
|
||||
if (lua_type(l, -1) == LUA_TFUNCTION)
|
||||
{
|
||||
luaChangeTypeHandlers[id].Assign(l, -1);
|
||||
elements[id].ChangeType = luaChangeTypeWrapper;
|
||||
}
|
||||
else if (lua_type(l, -1) == LUA_TBOOLEAN && !lua_toboolean(l, -1))
|
||||
{
|
||||
luaChangeTypeHandlers[id].Clear();
|
||||
elements[id].ChangeType = builtinElements[id].ChangeType;
|
||||
}
|
||||
lua_pop(l, 1);
|
||||
|
||||
lua_getfield(l, -1, "ChangeType");
|
||||
if (lua_type(l, -1) == LUA_TFUNCTION)
|
||||
{
|
||||
luaChangeTypeHandlers[id].Assign(l, -1);
|
||||
luacon_sim->elements[id].ChangeType = luaChangeTypeWrapper;
|
||||
}
|
||||
else if (lua_type(l, -1) == LUA_TBOOLEAN && !lua_toboolean(l, -1))
|
||||
{
|
||||
luaChangeTypeHandlers[id].Clear();
|
||||
luacon_sim->elements[id].ChangeType = GetElements()[id].ChangeType;
|
||||
}
|
||||
lua_pop(l, 1);
|
||||
lua_getfield(l, -1, "CtypeDraw");
|
||||
if (lua_type(l, -1) == LUA_TFUNCTION)
|
||||
{
|
||||
luaCtypeDrawHandlers[id].Assign(l, -1);
|
||||
elements[id].CtypeDraw = luaCtypeDrawWrapper;
|
||||
}
|
||||
else if (lua_type(l, -1) == LUA_TBOOLEAN && !lua_toboolean(l, -1))
|
||||
{
|
||||
luaCtypeDrawHandlers[id].Clear();
|
||||
elements[id].CtypeDraw = builtinElements[id].CtypeDraw;
|
||||
}
|
||||
lua_pop(l, 1);
|
||||
|
||||
lua_getfield(l, -1, "CtypeDraw");
|
||||
if (lua_type(l, -1) == LUA_TFUNCTION)
|
||||
{
|
||||
luaCtypeDrawHandlers[id].Assign(l, -1);
|
||||
luacon_sim->elements[id].CtypeDraw = luaCtypeDrawWrapper;
|
||||
}
|
||||
else if (lua_type(l, -1) == LUA_TBOOLEAN && !lua_toboolean(l, -1))
|
||||
{
|
||||
luaCtypeDrawHandlers[id].Clear();
|
||||
luacon_sim->elements[id].CtypeDraw = GetElements()[id].CtypeDraw;
|
||||
}
|
||||
lua_pop(l, 1);
|
||||
|
||||
lua_getfield(l, -1, "DefaultProperties");
|
||||
SetDefaultProperties(l, id, lua_gettop(l));
|
||||
lua_pop(l, 1);
|
||||
lua_getfield(l, -1, "DefaultProperties");
|
||||
SetDefaultProperties(l, id, lua_gettop(l));
|
||||
lua_pop(l, 1);
|
||||
|
||||
sd.graphicscache[id].isready = 0;
|
||||
}
|
||||
luacon_model->BuildMenus();
|
||||
luacon_ci->custom_init_can_move();
|
||||
luacon_ren->graphicscache[id].isready = 0;
|
||||
SaveRenderer::Ref().Flush(id, id + 1);
|
||||
|
||||
return 0;
|
||||
}
|
||||
else
|
||||
{
|
||||
auto &sd = SimulationData::CRef();
|
||||
auto &elements = sd.elements;
|
||||
//Write values from native data to a table
|
||||
lua_newtable(l);
|
||||
for (auto &prop : Element::GetProperties())
|
||||
{
|
||||
tpt_lua_pushByteString(l, prop.Name);
|
||||
intptr_t propertyAddress = (intptr_t)(((unsigned char*)&luacon_sim->elements[id]) + prop.Offset);
|
||||
intptr_t propertyAddress = (intptr_t)(((unsigned char*)&elements[id]) + prop.Offset);
|
||||
LuaGetProperty(l, prop, propertyAddress);
|
||||
lua_settable(l, -3);
|
||||
}
|
||||
|
||||
tpt_lua_pushByteString(l, luacon_sim->elements[id].Identifier);
|
||||
tpt_lua_pushByteString(l, elements[id].Identifier);
|
||||
lua_setfield(l, -2, "Identifier");
|
||||
|
||||
GetDefaultProperties(l, id);
|
||||
@ -3729,10 +3804,12 @@ int LuaScriptInterface::elements_element(lua_State * l)
|
||||
|
||||
void LuaScriptInterface::GetDefaultProperties(lua_State * l, int id)
|
||||
{
|
||||
auto &sd = SimulationData::CRef();
|
||||
auto &elements = sd.elements;
|
||||
lua_newtable(l);
|
||||
for (auto &prop : Particle::GetProperties())
|
||||
{
|
||||
auto propertyAddress = reinterpret_cast<intptr_t>((reinterpret_cast<unsigned char*>(&luacon_sim->elements[id].DefaultProperties)) + prop.Offset);
|
||||
auto propertyAddress = reinterpret_cast<intptr_t>((reinterpret_cast<const unsigned char*>(&elements[id].DefaultProperties)) + prop.Offset);
|
||||
tpt_lua_pushByteString(l, prop.Name);
|
||||
LuaGetProperty(l, prop, propertyAddress);
|
||||
lua_settable(l, -3);
|
||||
@ -3748,6 +3825,8 @@ void LuaScriptInterface::GetDefaultProperties(lua_State * l, int id)
|
||||
|
||||
void LuaScriptInterface::SetDefaultProperties(lua_State * l, int id, int stackPos)
|
||||
{
|
||||
auto &sd = SimulationData::Ref();
|
||||
auto &elements = sd.elements;
|
||||
if (lua_type(l, stackPos) == LUA_TTABLE)
|
||||
{
|
||||
for (auto &prop : Particle::GetProperties())
|
||||
@ -3768,7 +3847,7 @@ void LuaScriptInterface::SetDefaultProperties(lua_State * l, int id, int stackPo
|
||||
}
|
||||
if (lua_type(l, -1) != LUA_TNIL)
|
||||
{
|
||||
auto propertyAddress = reinterpret_cast<intptr_t>((reinterpret_cast<unsigned char*>(&luacon_sim->elements[id].DefaultProperties)) + prop.Offset);
|
||||
auto propertyAddress = reinterpret_cast<intptr_t>((reinterpret_cast<unsigned char*>(&elements[id].DefaultProperties)) + prop.Offset);
|
||||
LuaSetProperty(l, prop, propertyAddress, -1);
|
||||
}
|
||||
lua_pop(l, 1);
|
||||
@ -3778,9 +3857,10 @@ void LuaScriptInterface::SetDefaultProperties(lua_State * l, int id, int stackPo
|
||||
|
||||
int LuaScriptInterface::elements_property(lua_State * l)
|
||||
{
|
||||
auto &builtinElements = GetElements();
|
||||
auto *luacon_ci = static_cast<LuaScriptInterface *>(commandInterface);
|
||||
int id = luaL_checkinteger(l, 1);
|
||||
if (!luacon_sim->IsElementOrNone(id))
|
||||
if (!SimulationData::CRef().IsElementOrNone(id))
|
||||
{
|
||||
return luaL_error(l, "Invalid element");
|
||||
}
|
||||
@ -3793,6 +3873,9 @@ int LuaScriptInterface::elements_property(lua_State * l)
|
||||
|
||||
if (lua_gettop(l) > 2)
|
||||
{
|
||||
auto &sd = SimulationData::Ref();
|
||||
std::unique_lock lk(sd.elementGraphicsMx);
|
||||
auto &elements = sd.elements;
|
||||
if (prop != properties.end())
|
||||
{
|
||||
if (lua_type(l, 3) != LUA_TNIL)
|
||||
@ -3800,20 +3883,17 @@ int LuaScriptInterface::elements_property(lua_State * l)
|
||||
if (prop->Type == StructProperty::TransitionType)
|
||||
{
|
||||
int type = luaL_checkinteger(l, 3);
|
||||
if (!luacon_sim->IsElementOrNone(type) && type != NT && type != ST)
|
||||
if (!SimulationData::CRef().IsElementOrNone(type) && type != NT && type != ST)
|
||||
{
|
||||
return luaL_error(l, "Invalid element");
|
||||
}
|
||||
}
|
||||
|
||||
intptr_t propertyAddress = (intptr_t)(((unsigned char*)&luacon_sim->elements[id]) + prop->Offset);
|
||||
intptr_t propertyAddress = (intptr_t)(((unsigned char*)&elements[id]) + prop->Offset);
|
||||
LuaSetProperty(l, *prop, propertyAddress, 3);
|
||||
luacon_model->BuildMenus();
|
||||
luacon_ci->custom_init_can_move();
|
||||
sd.graphicscache[id].isready = 0;
|
||||
}
|
||||
|
||||
luacon_model->BuildMenus();
|
||||
luacon_ci->custom_init_can_move();
|
||||
luacon_ren->graphicscache[id].isready = 0;
|
||||
SaveRenderer::Ref().Flush(id, id + 1);
|
||||
}
|
||||
else if (propertyName == "Update")
|
||||
{
|
||||
@ -3834,13 +3914,13 @@ int LuaScriptInterface::elements_property(lua_State * l)
|
||||
break;
|
||||
}
|
||||
lua_el_func[id].Assign(l, 3);
|
||||
luacon_sim->elements[id].Update = luaUpdateWrapper;
|
||||
elements[id].Update = luaUpdateWrapper;
|
||||
}
|
||||
else if (lua_type(l, 3) == LUA_TBOOLEAN && !lua_toboolean(l, 3))
|
||||
{
|
||||
lua_el_func[id].Clear();
|
||||
lua_el_mode[id] = 0;
|
||||
luacon_sim->elements[id].Update = GetElements()[id].Update;
|
||||
elements[id].Update = builtinElements[id].Update;
|
||||
}
|
||||
}
|
||||
else if (propertyName == "Graphics")
|
||||
@ -3848,27 +3928,26 @@ int LuaScriptInterface::elements_property(lua_State * l)
|
||||
if (lua_type(l, 3) == LUA_TFUNCTION)
|
||||
{
|
||||
lua_gr_func[id].Assign(l, 3);
|
||||
luacon_sim->elements[id].Graphics = luaGraphicsWrapper;
|
||||
elements[id].Graphics = luaGraphicsWrapper;
|
||||
}
|
||||
else if (lua_type(l, 3) == LUA_TBOOLEAN && !lua_toboolean(l, 3))
|
||||
{
|
||||
lua_gr_func[id].Clear();
|
||||
luacon_sim->elements[id].Graphics = GetElements()[id].Graphics;
|
||||
elements[id].Graphics = builtinElements[id].Graphics;
|
||||
}
|
||||
luacon_ren->graphicscache[id].isready = 0;
|
||||
SaveRenderer::Ref().Flush(id, id + 1);
|
||||
sd.graphicscache[id].isready = 0;
|
||||
}
|
||||
else if (propertyName == "Create")
|
||||
{
|
||||
if (lua_type(l, 3) == LUA_TFUNCTION)
|
||||
{
|
||||
luaCreateHandlers[id].Assign(l, 3);
|
||||
luacon_sim->elements[id].Create = luaCreateWrapper;
|
||||
elements[id].Create = luaCreateWrapper;
|
||||
}
|
||||
else if (lua_type(l, 3) == LUA_TBOOLEAN && !lua_toboolean(l, 3))
|
||||
{
|
||||
luaCreateHandlers[id].Clear();
|
||||
luacon_sim->elements[id].Create = GetElements()[id].Create;
|
||||
elements[id].Create = builtinElements[id].Create;
|
||||
}
|
||||
}
|
||||
else if (propertyName == "CreateAllowed")
|
||||
@ -3876,12 +3955,12 @@ int LuaScriptInterface::elements_property(lua_State * l)
|
||||
if (lua_type(l, 3) == LUA_TFUNCTION)
|
||||
{
|
||||
luaCreateAllowedHandlers[id].Assign(l, 3);
|
||||
luacon_sim->elements[id].CreateAllowed = luaCreateAllowedWrapper;
|
||||
elements[id].CreateAllowed = luaCreateAllowedWrapper;
|
||||
}
|
||||
else if (lua_type(l, 3) == LUA_TBOOLEAN && !lua_toboolean(l, 3))
|
||||
{
|
||||
luaCreateAllowedHandlers[id].Clear();
|
||||
luacon_sim->elements[id].CreateAllowed = GetElements()[id].CreateAllowed;
|
||||
elements[id].CreateAllowed = builtinElements[id].CreateAllowed;
|
||||
}
|
||||
}
|
||||
else if (propertyName == "ChangeType")
|
||||
@ -3889,12 +3968,12 @@ int LuaScriptInterface::elements_property(lua_State * l)
|
||||
if (lua_type(l, 3) == LUA_TFUNCTION)
|
||||
{
|
||||
luaChangeTypeHandlers[id].Assign(l, 3);
|
||||
luacon_sim->elements[id].ChangeType = luaChangeTypeWrapper;
|
||||
elements[id].ChangeType = luaChangeTypeWrapper;
|
||||
}
|
||||
else if (lua_type(l, 3) == LUA_TBOOLEAN && !lua_toboolean(l, 3))
|
||||
{
|
||||
luaChangeTypeHandlers[id].Clear();
|
||||
luacon_sim->elements[id].ChangeType = GetElements()[id].ChangeType;
|
||||
elements[id].ChangeType = builtinElements[id].ChangeType;
|
||||
}
|
||||
}
|
||||
else if (propertyName == "CtypeDraw")
|
||||
@ -3902,12 +3981,12 @@ int LuaScriptInterface::elements_property(lua_State * l)
|
||||
if (lua_type(l, 3) == LUA_TFUNCTION)
|
||||
{
|
||||
luaCtypeDrawHandlers[id].Assign(l, 3);
|
||||
luacon_sim->elements[id].CtypeDraw = luaCtypeDrawWrapper;
|
||||
elements[id].CtypeDraw = luaCtypeDrawWrapper;
|
||||
}
|
||||
else if (lua_type(l, 3) == LUA_TBOOLEAN && !lua_toboolean(l, 3))
|
||||
{
|
||||
luaCtypeDrawHandlers[id].Clear();
|
||||
luacon_sim->elements[id].CtypeDraw = GetElements()[id].CtypeDraw;
|
||||
elements[id].CtypeDraw = builtinElements[id].CtypeDraw;
|
||||
}
|
||||
}
|
||||
else if (propertyName == "DefaultProperties")
|
||||
@ -3922,15 +4001,17 @@ int LuaScriptInterface::elements_property(lua_State * l)
|
||||
}
|
||||
else
|
||||
{
|
||||
auto &sd = SimulationData::CRef();
|
||||
auto &elements = sd.elements;
|
||||
if (prop != properties.end())
|
||||
{
|
||||
intptr_t propertyAddress = (intptr_t)(((unsigned char*)&luacon_sim->elements[id]) + prop->Offset);
|
||||
intptr_t propertyAddress = (intptr_t)(((const unsigned char*)&elements[id]) + prop->Offset);
|
||||
LuaGetProperty(l, *prop, propertyAddress);
|
||||
return 1;
|
||||
}
|
||||
else if (propertyName == "Identifier")
|
||||
{
|
||||
tpt_lua_pushByteString(l, luacon_sim->elements[id].Identifier);
|
||||
tpt_lua_pushByteString(l, elements[id].Identifier);
|
||||
return 1;
|
||||
}
|
||||
else if (propertyName == "DefaultProperties")
|
||||
@ -3948,18 +4029,26 @@ int LuaScriptInterface::elements_property(lua_State * l)
|
||||
int LuaScriptInterface::elements_free(lua_State * l)
|
||||
{
|
||||
int id = luaL_checkinteger(l, 1);
|
||||
if (!luacon_sim->IsElement(id))
|
||||
ByteString identifier;
|
||||
{
|
||||
return luaL_error(l, "Invalid element");
|
||||
auto &sd = SimulationData::CRef();
|
||||
if (!sd.IsElement(id))
|
||||
{
|
||||
return luaL_error(l, "Invalid element");
|
||||
}
|
||||
|
||||
identifier = sd.elements[id].Identifier;
|
||||
if (identifier.BeginsWith("DEFAULT_PT_"))
|
||||
{
|
||||
return luaL_error(l, "Cannot free default elements");
|
||||
}
|
||||
}
|
||||
|
||||
ByteString identifier = luacon_sim->elements[id].Identifier;
|
||||
if (identifier.BeginsWith("DEFAULT_PT_"))
|
||||
{
|
||||
return luaL_error(l, "Cannot free default elements");
|
||||
auto &sd = SimulationData::Ref();
|
||||
std::unique_lock lk(sd.elementGraphicsMx);
|
||||
sd.elements[id].Enabled = false;
|
||||
}
|
||||
|
||||
luacon_sim->elements[id].Enabled = false;
|
||||
luacon_model->BuildMenus();
|
||||
|
||||
lua_getglobal(l, "elements");
|
||||
@ -3973,7 +4062,8 @@ int LuaScriptInterface::elements_free(lua_State * l)
|
||||
|
||||
int LuaScriptInterface::elements_exists(lua_State * l)
|
||||
{
|
||||
lua_pushboolean(l, luacon_sim->IsElement(luaL_checkinteger(l, 1)));
|
||||
auto &sd = SimulationData::CRef();
|
||||
lua_pushboolean(l, sd.IsElement(luaL_checkinteger(l, 1)));
|
||||
return 1;
|
||||
}
|
||||
|
||||
|
@ -244,6 +244,7 @@ String TPTScriptInterface::FormatCommand(String command)
|
||||
|
||||
AnyType TPTScriptInterface::tptS_set(std::deque<String> * words)
|
||||
{
|
||||
auto &sd = SimulationData::CRef();
|
||||
//Arguments from stack
|
||||
StringType property = eval(words);
|
||||
AnyType selector = eval(words);
|
||||
@ -300,7 +301,7 @@ AnyType TPTScriptInterface::tptS_set(std::deque<String> * words)
|
||||
}
|
||||
else
|
||||
{
|
||||
newValue = m->GetSimulation()->GetParticleType(((StringType)value).Value().ToUtf8());
|
||||
newValue = sd.GetParticleType(((StringType)value).Value().ToUtf8());
|
||||
if (newValue < 0 || newValue >= PT_NUM)
|
||||
{
|
||||
// TODO: add element CAKE to invalidate this
|
||||
@ -312,7 +313,7 @@ AnyType TPTScriptInterface::tptS_set(std::deque<String> * words)
|
||||
}
|
||||
else
|
||||
throw GeneralException("Invalid value for assignment");
|
||||
if (property.Value() == "type" && (newValue < 0 || newValue >= PT_NUM || !sim->elements[newValue].Enabled))
|
||||
if (property.Value() == "type" && (newValue < 0 || newValue >= PT_NUM || !sd.elements[newValue].Enabled))
|
||||
throw GeneralException("Invalid element");
|
||||
|
||||
if (selector.GetType() == TypePoint || selector.GetType() == TypeNumber)
|
||||
@ -390,7 +391,7 @@ AnyType TPTScriptInterface::tptS_set(std::deque<String> * words)
|
||||
if (selector.GetType() == TypeNumber)
|
||||
type = ((NumberType)selector).Value();
|
||||
else if (selector.GetType() == TypeString)
|
||||
type = m->GetSimulation()->GetParticleType(((StringType)selector).Value().ToUtf8());
|
||||
type = sd.GetParticleType(((StringType)selector).Value().ToUtf8());
|
||||
|
||||
if (type<0 || type>=PT_NUM)
|
||||
throw GeneralException("Invalid particle type");
|
||||
@ -439,6 +440,7 @@ AnyType TPTScriptInterface::tptS_set(std::deque<String> * words)
|
||||
|
||||
AnyType TPTScriptInterface::tptS_create(std::deque<String> * words)
|
||||
{
|
||||
auto &sd = SimulationData::CRef();
|
||||
//Arguments from stack
|
||||
AnyType createType = eval(words);
|
||||
PointType position = eval(words);
|
||||
@ -449,7 +451,7 @@ AnyType TPTScriptInterface::tptS_create(std::deque<String> * words)
|
||||
if(createType.GetType() == TypeNumber)
|
||||
type = ((NumberType)createType).Value();
|
||||
else if(createType.GetType() == TypeString)
|
||||
type = m->GetSimulation()->GetParticleType(((StringType)createType).Value().ToUtf8());
|
||||
type = sd.GetParticleType(((StringType)createType).Value().ToUtf8());
|
||||
else
|
||||
throw GeneralException("Invalid type");
|
||||
|
||||
@ -549,6 +551,7 @@ AnyType TPTScriptInterface::tptS_bubble(std::deque<String> * words)
|
||||
|
||||
AnyType TPTScriptInterface::tptS_reset(std::deque<String> * words)
|
||||
{
|
||||
auto &sd = SimulationData::CRef();
|
||||
//Arguments from stack
|
||||
StringType reset = eval(words);
|
||||
String resetStr = reset.Value();
|
||||
@ -582,7 +585,7 @@ AnyType TPTScriptInterface::tptS_reset(std::deque<String> * words)
|
||||
{
|
||||
if (sim->parts[i].type)
|
||||
{
|
||||
sim->parts[i].temp = sim->elements[sim->parts[i].type].DefaultProperties.temp;
|
||||
sim->parts[i].temp = sd.elements[sim->parts[i].type].DefaultProperties.temp;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -354,6 +354,8 @@ void Air::Invert()
|
||||
// called when loading saves / stamps to ensure nothing "leaks" the first frame
|
||||
void Air::ApproximateBlockAirMaps()
|
||||
{
|
||||
auto &sd = SimulationData::CRef();
|
||||
auto &elements = sd.elements;
|
||||
for (int i = 0; i <= sim.parts_lastActiveIndex; i++)
|
||||
{
|
||||
int type = sim.parts[i].type;
|
||||
@ -372,7 +374,7 @@ void Air::ApproximateBlockAirMaps()
|
||||
}
|
||||
}
|
||||
// mostly accurate insulator blocking, besides checking GEL
|
||||
else if ((type == PT_HSWC && sim.parts[i].life != 10) || sim.elements[type].HeatConduct <= (sim.rng()%250))
|
||||
else if ((type == PT_HSWC && sim.parts[i].life != 10) || elements[type].HeatConduct <= (sim.rng()%250))
|
||||
{
|
||||
int x = ((int)(sim.parts[i].x+0.5f))/CELL, y = ((int)(sim.parts[i].y+0.5f))/CELL;
|
||||
if (InBounds(x, y) && !(bmap_blockairh[y][x]&0x8))
|
||||
|
@ -8,7 +8,8 @@ struct BuiltinGOL
|
||||
String name;
|
||||
int oldtype;
|
||||
int ruleset;
|
||||
RGB<uint8_t> colour, colour2;
|
||||
RGB<uint8_t> colour = RGB<uint8_t>(0, 0, 0);
|
||||
RGB<uint8_t> colour2 = RGB<uint8_t>(0, 0, 0);
|
||||
int goltype;
|
||||
String description;
|
||||
};
|
||||
|
@ -13,7 +13,7 @@
|
||||
#include <iostream>
|
||||
#include <cmath>
|
||||
|
||||
std::unique_ptr<Snapshot> Simulation::CreateSnapshot()
|
||||
std::unique_ptr<Snapshot> Simulation::CreateSnapshot() const
|
||||
{
|
||||
auto snap = std::make_unique<Snapshot>();
|
||||
snap->AirPressure .insert (snap->AirPressure .begin(), &pv [0][0] , &pv [0][0] + NCELL);
|
||||
@ -188,7 +188,8 @@ int Simulation::Tool(int x, int y, int tool, int brushX, int brushY, float stren
|
||||
cpart = &(parts[ID(r)]);
|
||||
else if ((r = photons[y][x]))
|
||||
cpart = &(parts[ID(r)]);
|
||||
return tools[tool].Perform(this, cpart, x, y, brushX, brushY, strength);
|
||||
auto &sd = SimulationData::CRef();
|
||||
return sd.tools[tool].Perform(this, cpart, x, y, brushX, brushY, strength);
|
||||
}
|
||||
|
||||
int Simulation::CreateWalls(int x, int y, int rx, int ry, int wall, Brush const *cBrush)
|
||||
@ -428,27 +429,6 @@ int Simulation::CreatePartFlags(int x, int y, int c, int flags)
|
||||
return 0;
|
||||
}
|
||||
|
||||
int Simulation::GetParticleType(ByteString type)
|
||||
{
|
||||
type = type.ToUpper();
|
||||
|
||||
// alternative names for some elements
|
||||
if (byteStringEqualsLiteral(type, "C4"))
|
||||
return PT_PLEX;
|
||||
else if (byteStringEqualsLiteral(type, "C5"))
|
||||
return PT_C5;
|
||||
else if (byteStringEqualsLiteral(type, "NONE"))
|
||||
return PT_NONE;
|
||||
for (int i = 1; i < PT_NUM; i++)
|
||||
{
|
||||
if (elements[i].Name.size() && elements[i].Enabled && type == elements[i].Name.ToUtf8().ToUpper())
|
||||
{
|
||||
return i;
|
||||
}
|
||||
}
|
||||
return -1;
|
||||
}
|
||||
|
||||
void Simulation::ApplyDecoration(int x, int y, int colR_, int colG_, int colB_, int colA_, int mode)
|
||||
{
|
||||
int rp;
|
||||
@ -1058,6 +1038,8 @@ int Simulation::FloodParts(int x, int y, int fullc, int cm, int flags)
|
||||
coord_stack[coord_stack_size][1] = y;
|
||||
coord_stack_size++;
|
||||
|
||||
auto &sd = SimulationData::CRef();
|
||||
auto &elements = sd.elements;
|
||||
do
|
||||
{
|
||||
coord_stack_size--;
|
||||
|
@ -29,6 +29,7 @@ Element::Element():
|
||||
Weight(50),
|
||||
|
||||
HeatConduct(128),
|
||||
LatentHeat(0),
|
||||
Description("No description"),
|
||||
|
||||
Properties(TYPE_SOLID),
|
||||
@ -54,45 +55,58 @@ Element::Element():
|
||||
|
||||
std::vector<StructProperty> const &Element::GetProperties()
|
||||
{
|
||||
static std::vector<StructProperty> properties = {
|
||||
{ "Name", StructProperty::String, offsetof(Element, Name ) },
|
||||
{ "Colour", StructProperty::Colour, offsetof(Element, Colour ) },
|
||||
{ "Color", StructProperty::Colour, offsetof(Element, Colour ) },
|
||||
{ "MenuVisible", StructProperty::Integer, offsetof(Element, MenuVisible ) },
|
||||
{ "MenuSection", StructProperty::Integer, offsetof(Element, MenuSection ) },
|
||||
{ "Enabled", StructProperty::Integer, offsetof(Element, Enabled ) },
|
||||
{ "Advection", StructProperty::Float, offsetof(Element, Advection ) },
|
||||
{ "AirDrag", StructProperty::Float, offsetof(Element, AirDrag ) },
|
||||
{ "AirLoss", StructProperty::Float, offsetof(Element, AirLoss ) },
|
||||
{ "Loss", StructProperty::Float, offsetof(Element, Loss ) },
|
||||
{ "Collision", StructProperty::Float, offsetof(Element, Collision ) },
|
||||
{ "Gravity", StructProperty::Float, offsetof(Element, Gravity ) },
|
||||
{ "NewtonianGravity", StructProperty::Float, offsetof(Element, NewtonianGravity ) },
|
||||
{ "Diffusion", StructProperty::Float, offsetof(Element, Diffusion ) },
|
||||
{ "HotAir", StructProperty::Float, offsetof(Element, HotAir ) },
|
||||
{ "Falldown", StructProperty::Integer, offsetof(Element, Falldown ) },
|
||||
{ "Flammable", StructProperty::Integer, offsetof(Element, Flammable ) },
|
||||
{ "Explosive", StructProperty::Integer, offsetof(Element, Explosive ) },
|
||||
{ "Meltable", StructProperty::Integer, offsetof(Element, Meltable ) },
|
||||
{ "Hardness", StructProperty::Integer, offsetof(Element, Hardness ) },
|
||||
{ "PhotonReflectWavelengths", StructProperty::UInteger, offsetof(Element, PhotonReflectWavelengths ) },
|
||||
{ "CarriesTypeIn", StructProperty::UInteger, offsetof(Element, CarriesTypeIn ) },
|
||||
{ "Weight", StructProperty::Integer, offsetof(Element, Weight ) },
|
||||
{ "Temperature", StructProperty::Float, offsetof(Element, DefaultProperties.temp ) },
|
||||
{ "HeatConduct", StructProperty::UChar, offsetof(Element, HeatConduct ) },
|
||||
{ "Description", StructProperty::String, offsetof(Element, Description ) },
|
||||
{ "State", StructProperty::Removed, 0 },
|
||||
{ "Properties", StructProperty::Integer, offsetof(Element, Properties ) },
|
||||
{ "LowPressure", StructProperty::Float, offsetof(Element, LowPressure ) },
|
||||
{ "LowPressureTransition", StructProperty::TransitionType, offsetof(Element, LowPressureTransition ) },
|
||||
{ "HighPressure", StructProperty::Float, offsetof(Element, HighPressure ) },
|
||||
{ "HighPressureTransition", StructProperty::TransitionType, offsetof(Element, HighPressureTransition ) },
|
||||
{ "LowTemperature", StructProperty::Float, offsetof(Element, LowTemperature ) },
|
||||
{ "LowTemperatureTransition", StructProperty::TransitionType, offsetof(Element, LowTemperatureTransition ) },
|
||||
{ "HighTemperature", StructProperty::Float, offsetof(Element, HighTemperature ) },
|
||||
{ "HighTemperatureTransition", StructProperty::TransitionType, offsetof(Element, HighTemperatureTransition) }
|
||||
struct DoOnce
|
||||
{
|
||||
std::vector<StructProperty> properties;
|
||||
|
||||
DoOnce()
|
||||
{
|
||||
properties = {
|
||||
{ "Name", StructProperty::String, offsetof(Element, Name ) },
|
||||
{ "Colour", StructProperty::Colour, offsetof(Element, Colour ) },
|
||||
{ "Color", StructProperty::Colour, offsetof(Element, Colour ) },
|
||||
{ "MenuVisible", StructProperty::Integer, offsetof(Element, MenuVisible ) },
|
||||
{ "MenuSection", StructProperty::Integer, offsetof(Element, MenuSection ) },
|
||||
{ "Enabled", StructProperty::Integer, offsetof(Element, Enabled ) },
|
||||
{ "Advection", StructProperty::Float, offsetof(Element, Advection ) },
|
||||
{ "AirDrag", StructProperty::Float, offsetof(Element, AirDrag ) },
|
||||
{ "AirLoss", StructProperty::Float, offsetof(Element, AirLoss ) },
|
||||
{ "Loss", StructProperty::Float, offsetof(Element, Loss ) },
|
||||
{ "Collision", StructProperty::Float, offsetof(Element, Collision ) },
|
||||
{ "Gravity", StructProperty::Float, offsetof(Element, Gravity ) },
|
||||
{ "NewtonianGravity", StructProperty::Float, offsetof(Element, NewtonianGravity ) },
|
||||
{ "Diffusion", StructProperty::Float, offsetof(Element, Diffusion ) },
|
||||
{ "HotAir", StructProperty::Float, offsetof(Element, HotAir ) },
|
||||
{ "Falldown", StructProperty::Integer, offsetof(Element, Falldown ) },
|
||||
{ "Flammable", StructProperty::Integer, offsetof(Element, Flammable ) },
|
||||
{ "Explosive", StructProperty::Integer, offsetof(Element, Explosive ) },
|
||||
{ "Meltable", StructProperty::Integer, offsetof(Element, Meltable ) },
|
||||
{ "Hardness", StructProperty::Integer, offsetof(Element, Hardness ) },
|
||||
{ "PhotonReflectWavelengths", StructProperty::UInteger, offsetof(Element, PhotonReflectWavelengths ) },
|
||||
{ "CarriesTypeIn", StructProperty::UInteger, offsetof(Element, CarriesTypeIn ) },
|
||||
{ "Weight", StructProperty::Integer, offsetof(Element, Weight ) },
|
||||
{ "Temperature", StructProperty::Float, offsetof(Element, DefaultProperties.temp ) },
|
||||
{ "HeatConduct", StructProperty::UChar, offsetof(Element, HeatConduct ) },
|
||||
{ "Description", StructProperty::String, offsetof(Element, Description ) },
|
||||
{ "State", StructProperty::Removed, 0 },
|
||||
{ "Properties", StructProperty::Integer, offsetof(Element, Properties ) },
|
||||
{ "LowPressure", StructProperty::Float, offsetof(Element, LowPressure ) },
|
||||
{ "LowPressureTransition", StructProperty::TransitionType, offsetof(Element, LowPressureTransition ) },
|
||||
{ "HighPressure", StructProperty::Float, offsetof(Element, HighPressure ) },
|
||||
{ "HighPressureTransition", StructProperty::TransitionType, offsetof(Element, HighPressureTransition ) },
|
||||
{ "LowTemperature", StructProperty::Float, offsetof(Element, LowTemperature ) },
|
||||
{ "LowTemperatureTransition", StructProperty::TransitionType, offsetof(Element, LowTemperatureTransition ) },
|
||||
{ "HighTemperature", StructProperty::Float, offsetof(Element, HighTemperature ) },
|
||||
{ "HighTemperatureTransition", StructProperty::TransitionType, offsetof(Element, HighTemperatureTransition) }
|
||||
};
|
||||
if constexpr (LATENTHEAT)
|
||||
{
|
||||
properties.push_back({ "LatentHeat", StructProperty::UInteger, offsetof(Element, LatentHeat) });
|
||||
}
|
||||
}
|
||||
};
|
||||
return properties;
|
||||
static DoOnce doOnce;
|
||||
return doOnce.properties;
|
||||
}
|
||||
|
||||
int Element::legacyUpdate(UPDATE_FUNC_ARGS) {
|
||||
@ -216,14 +230,16 @@ int Element::legacyUpdate(UPDATE_FUNC_ARGS) {
|
||||
|
||||
int Element::defaultGraphics(GRAPHICS_FUNC_ARGS)
|
||||
{
|
||||
auto &sd = SimulationData::CRef();
|
||||
auto &elements = sd.elements;
|
||||
int t = cpart->type;
|
||||
//Property based defaults
|
||||
if(ren->sim->elements[t].Properties & PROP_RADIOACTIVE) *pixel_mode |= PMODE_GLOW;
|
||||
if(ren->sim->elements[t].Properties & TYPE_LIQUID)
|
||||
if(elements[t].Properties & PROP_RADIOACTIVE) *pixel_mode |= PMODE_GLOW;
|
||||
if(elements[t].Properties & TYPE_LIQUID)
|
||||
{
|
||||
*pixel_mode |= PMODE_BLUR;
|
||||
}
|
||||
if(ren->sim->elements[t].Properties & TYPE_GAS)
|
||||
if(elements[t].Properties & TYPE_GAS)
|
||||
{
|
||||
*pixel_mode &= ~PMODE;
|
||||
*pixel_mode |= FIRE_BLEND;
|
||||
@ -238,7 +254,9 @@ int Element::defaultGraphics(GRAPHICS_FUNC_ARGS)
|
||||
|
||||
bool Element::basicCtypeDraw(CTYPEDRAW_FUNC_ARGS)
|
||||
{
|
||||
if (sim->parts[i].type == t || sim->elements[t].Properties & PROP_NOCTYPEDRAW)
|
||||
auto &sd = SimulationData::CRef();
|
||||
auto &elements = sd.elements;
|
||||
if (sim->parts[i].type == t || elements[t].Properties & PROP_NOCTYPEDRAW)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
@ -8,6 +8,7 @@
|
||||
|
||||
class Simulation;
|
||||
class Renderer;
|
||||
struct GraphicsFuncContext;
|
||||
class VideoBuffer;
|
||||
struct Particle;
|
||||
class Element
|
||||
@ -38,6 +39,7 @@ public:
|
||||
unsigned int PhotonReflectWavelengths;
|
||||
int Weight;
|
||||
unsigned char HeatConduct;
|
||||
unsigned int LatentHeat;
|
||||
String Description;
|
||||
unsigned int Properties;
|
||||
unsigned int CarriesTypeIn;
|
||||
|
@ -1,12 +1,12 @@
|
||||
#include "ElementCommon.h"
|
||||
|
||||
std::vector<Element> const &GetElements()
|
||||
std::array<Element, PT_NUM> const &GetElements()
|
||||
{
|
||||
struct DoOnce
|
||||
{
|
||||
std::vector<Element> elements;
|
||||
std::array<Element, PT_NUM> elements;
|
||||
|
||||
DoOnce() : elements(PT_NUM)
|
||||
DoOnce()
|
||||
{
|
||||
#define ELEMENT_NUMBERS_CALL
|
||||
#include "ElementNumbers.h"
|
||||
|
@ -1,5 +1,5 @@
|
||||
#pragma once
|
||||
#include <vector>
|
||||
#include <array>
|
||||
|
||||
#include "SimulationData.h"
|
||||
#include "Element.h"
|
||||
@ -8,4 +8,4 @@
|
||||
#include "ElementNumbers.h"
|
||||
#undef ELEMENT_NUMBERS_ENUMERATE
|
||||
|
||||
std::vector<Element> const &GetElements();
|
||||
std::array<Element, PT_NUM> const &GetElements();
|
||||
|
@ -8,6 +8,7 @@
|
||||
#include "Particle.h"
|
||||
#include "ElementGraphics.h"
|
||||
#include "Simulation.h"
|
||||
#include "SimulationData.h"
|
||||
#include "graphics/Renderer.h"
|
||||
#include <algorithm>
|
||||
#include <cmath>
|
||||
|
@ -42,8 +42,8 @@ constexpr auto FLAG_PHOTDECO = UINT32_C(0x00000008); // compatibility with
|
||||
#define UPDATE_FUNC_ARGS Simulation* sim, int i, int x, int y, int surround_space, int nt, Particle *parts, int pmap[YRES][XRES]
|
||||
#define UPDATE_FUNC_SUBCALL_ARGS sim, i, x, y, surround_space, nt, parts, pmap
|
||||
|
||||
#define GRAPHICS_FUNC_ARGS Renderer * ren, Particle *cpart, int nx, int ny, int *pixel_mode, int* cola, int *colr, int *colg, int *colb, int *firea, int *firer, int *fireg, int *fireb
|
||||
#define GRAPHICS_FUNC_SUBCALL_ARGS ren, cpart, nx, ny, pixel_mode, cola, colr, colg, colb, firea, firer, fireg, fireb
|
||||
#define GRAPHICS_FUNC_ARGS GraphicsFuncContext &gfctx, const Particle *cpart, int nx, int ny, int *pixel_mode, int* cola, int *colr, int *colg, int *colb, int *firea, int *firer, int *fireg, int *fireb
|
||||
#define GRAPHICS_FUNC_SUBCALL_ARGS gfctx, cpart, nx, ny, pixel_mode, cola, colr, colg, colb, firea, firer, fireg, fireb
|
||||
|
||||
#define ELEMENT_CREATE_FUNC_ARGS Simulation *sim, int i, int x, int y, int t, int v
|
||||
|
||||
|
@ -6,22 +6,23 @@
|
||||
#include "graphics/Renderer.h"
|
||||
|
||||
#include "Simulation.h"
|
||||
#include "SimulationData.h"
|
||||
|
||||
SaveRenderer::SaveRenderer(){
|
||||
sim = new Simulation();
|
||||
ren = new Renderer(sim);
|
||||
SaveRenderer::SaveRenderer()
|
||||
{
|
||||
sim = std::make_unique<Simulation>();
|
||||
ren = std::make_unique<Renderer>(sim.get());
|
||||
ren->decorations_enable = true;
|
||||
ren->blackDecorations = true;
|
||||
}
|
||||
|
||||
void SaveRenderer::Flush(int begin, int end)
|
||||
{
|
||||
std::lock_guard<std::mutex> gx(renderMutex);
|
||||
std::fill(ren->graphicscache + begin, ren->graphicscache + end, gcache_item());
|
||||
}
|
||||
SaveRenderer::~SaveRenderer() = default;
|
||||
|
||||
std::pair<std::unique_ptr<VideoBuffer>, MissingElements> SaveRenderer::Render(const GameSave *save, bool decorations, bool fire, Renderer *renderModeSource)
|
||||
std::unique_ptr<VideoBuffer> SaveRenderer::Render(const GameSave *save, bool decorations, bool fire, Renderer *renderModeSource)
|
||||
{
|
||||
// this function usually runs on a thread different from where element info in SimulationData may be written, so we acquire a read-only lock on it
|
||||
auto &sd = SimulationData::CRef();
|
||||
std::shared_lock lk(sd.elementGraphicsMx);
|
||||
std::lock_guard<std::mutex> gx(renderMutex);
|
||||
|
||||
ren->ResetModes();
|
||||
@ -34,7 +35,7 @@ std::pair<std::unique_ptr<VideoBuffer>, MissingElements> SaveRenderer::Render(co
|
||||
|
||||
sim->clear_sim();
|
||||
|
||||
auto missingElementTypes = sim->Load(save, true, { 0, 0 });
|
||||
sim->Load(save, true, { 0, 0 });
|
||||
ren->decorations_enable = true;
|
||||
ren->blackDecorations = !decorations;
|
||||
ren->ClearAccumulation();
|
||||
@ -58,11 +59,5 @@ std::pair<std::unique_ptr<VideoBuffer>, MissingElements> SaveRenderer::Render(co
|
||||
auto tempThumb = std::make_unique<VideoBuffer>(save->blockSize * CELL);
|
||||
tempThumb->BlendImage(ren->Data(), 0xFF, ren->Size().OriginRect());
|
||||
|
||||
return { std::move(tempThumb), missingElementTypes };
|
||||
}
|
||||
|
||||
SaveRenderer::~SaveRenderer()
|
||||
{
|
||||
delete ren;
|
||||
delete sim;
|
||||
return tempThumb;
|
||||
}
|
||||
|
@ -5,21 +5,20 @@
|
||||
#include <vector>
|
||||
#include "common/ExplicitSingleton.h"
|
||||
#include "common/String.h"
|
||||
#include "MissingElements.h"
|
||||
|
||||
class GameSave;
|
||||
class VideoBuffer;
|
||||
class Graphics;
|
||||
class Simulation;
|
||||
class Renderer;
|
||||
|
||||
class SaveRenderer: public ExplicitSingleton<SaveRenderer> {
|
||||
Simulation * sim;
|
||||
Renderer * ren;
|
||||
class SaveRenderer: public ExplicitSingleton<SaveRenderer>
|
||||
{
|
||||
std::unique_ptr<Simulation> sim;
|
||||
std::unique_ptr<Renderer> ren;
|
||||
std::mutex renderMutex;
|
||||
|
||||
public:
|
||||
SaveRenderer();
|
||||
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();
|
||||
~SaveRenderer();
|
||||
std::unique_ptr<VideoBuffer> Render(const GameSave *save, bool decorations = true, bool fire = true, Renderer *renderModeSource = nullptr);
|
||||
};
|
||||
|
@ -1,7 +1,8 @@
|
||||
#include "Sign.h"
|
||||
|
||||
#include "graphics/Graphics.h"
|
||||
#include "simulation/Simulation.h"
|
||||
#include "Simulation.h"
|
||||
#include "SimulationData.h"
|
||||
|
||||
sign::sign(String text_, int x_, int y_, Justification justification_):
|
||||
x(x_),
|
||||
@ -11,8 +12,9 @@ sign::sign(String text_, int x_, int y_, Justification justification_):
|
||||
{
|
||||
}
|
||||
|
||||
String sign::getDisplayText(Simulation *sim, int &x0, int &y0, int &w, int &h, bool colorize, bool *v95) const
|
||||
String sign::getDisplayText(const Simulation *sim, int &x0, int &y0, int &w, int &h, bool colorize, bool *v95) const
|
||||
{
|
||||
auto &sd = SimulationData::CRef();
|
||||
String drawable_text;
|
||||
auto si = std::make_pair(0, Type::Normal);
|
||||
if (text.find('{') == text.npos)
|
||||
@ -79,13 +81,13 @@ String sign::getDisplayText(Simulation *sim, int &x0, int &y0, int &w, int &h, b
|
||||
}
|
||||
else if (between_curlies == "type")
|
||||
{
|
||||
formatted_text << (part ? sim->BasicParticleInfo(*part) : (formatted_text.Size() ? String::Build("empty") : String::Build("Empty")));
|
||||
formatted_text << (part ? sd.BasicParticleInfo(*part) : (formatted_text.Size() ? String::Build("empty") : String::Build("Empty")));
|
||||
if (v95)
|
||||
*v95 = true;
|
||||
}
|
||||
else if (between_curlies == "ctype")
|
||||
{
|
||||
formatted_text << (part ? (sim->IsElementOrNone(part->ctype) ? sim->ElementResolve(part->ctype, -1) : String::Build(part->ctype)) : (formatted_text.Size() ? String::Build("empty") : String::Build("Empty")));
|
||||
formatted_text << (part ? (sd.IsElementOrNone(part->ctype) ? sd.ElementResolve(part->ctype, -1) : String::Build(part->ctype)) : (formatted_text.Size() ? String::Build("empty") : String::Build("Empty")));
|
||||
if (v95)
|
||||
*v95 = true;
|
||||
}
|
||||
|
@ -28,6 +28,6 @@ struct sign
|
||||
String text;
|
||||
|
||||
sign(String text_, int x_, int y_, Justification justification_);
|
||||
String getDisplayText(Simulation *sim, int &x, int &y, int &w, int &h, bool colorize = true, bool *v95 = nullptr) const;
|
||||
String getDisplayText(const Simulation *sim, int &x, int &y, int &w, int &h, bool colorize = true, bool *v95 = nullptr) const;
|
||||
std::pair<int, Type> split() const;
|
||||
};
|
||||
|
File diff suppressed because it is too large
Load Diff
@ -11,7 +11,6 @@
|
||||
#include "common/tpt-rand.h"
|
||||
#include "Element.h"
|
||||
#include "SimulationConfig.h"
|
||||
#include "MissingElements.h"
|
||||
#include <cstring>
|
||||
#include <cstddef>
|
||||
#include <vector>
|
||||
@ -22,7 +21,6 @@
|
||||
constexpr int CHANNELS = int(MAX_TEMP - 73) / 100 + 2;
|
||||
|
||||
class Snapshot;
|
||||
class SimTool;
|
||||
class Brush;
|
||||
class SimulationSample;
|
||||
struct matrix2d;
|
||||
@ -37,24 +35,17 @@ class GameSave;
|
||||
class Simulation
|
||||
{
|
||||
public:
|
||||
|
||||
GravityPtr grav;
|
||||
Air * air;
|
||||
std::unique_ptr<Air> air;
|
||||
RNG rng;
|
||||
|
||||
std::vector<sign> signs;
|
||||
std::array<Element, PT_NUM> elements;
|
||||
//Element * elements;
|
||||
std::vector<SimTool> tools;
|
||||
std::vector<unsigned int> platent;
|
||||
std::vector<wall_type> wtypes;
|
||||
std::vector<menu_section> msections;
|
||||
|
||||
int currentTick;
|
||||
int replaceModeSelected;
|
||||
int replaceModeFlags;
|
||||
|
||||
char can_move[PT_NUM][PT_NUM];
|
||||
int debug_nextToUpdate;
|
||||
int debug_mostRecentlyUpdated = -1; // -1 when between full update loops
|
||||
int parts_lastActiveIndex;
|
||||
@ -122,41 +113,37 @@ public:
|
||||
uint64_t frameCount;
|
||||
bool ensureDeterminism;
|
||||
|
||||
MissingElements Load(const GameSave *save, bool includePressure, Vec2<int> blockP); // block coordinates
|
||||
void 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);
|
||||
|
||||
std::unique_ptr<Snapshot> CreateSnapshot();
|
||||
std::unique_ptr<Snapshot> CreateSnapshot() const;
|
||||
void Restore(const Snapshot &snap);
|
||||
|
||||
int is_blocking(int t, int x, int y);
|
||||
int is_boundary(int pt, int x, int y);
|
||||
int find_next_boundary(int pt, int *x, int *y, int dm, int *em, bool reverse);
|
||||
int is_blocking(int t, int x, int y) const;
|
||||
int is_boundary(int pt, int x, int y) const;
|
||||
int find_next_boundary(int pt, int *x, int *y, int dm, int *em, bool reverse) const;
|
||||
void photoelectric_effect(int nx, int ny);
|
||||
int do_move(int i, int x, int y, float nxf, float nyf);
|
||||
bool move(int i, int x, int y, float nxf, float nyf);
|
||||
int try_move(int i, int x, int y, int nx, int ny);
|
||||
int eval_move(int pt, int nx, int ny, unsigned *rr) const;
|
||||
|
||||
struct PlanMoveResult
|
||||
{
|
||||
int fin_x, fin_y, clear_x, clear_y;
|
||||
float fin_xf, fin_yf, clear_xf, clear_yf;
|
||||
float vx, vy;
|
||||
};
|
||||
PlanMoveResult PlanMove(int i, int x, int y, bool update_emap);
|
||||
void init_can_move();
|
||||
template<bool UpdateEmap, class Sim>
|
||||
static PlanMoveResult PlanMove(Sim &sim, int i, int x, int y);
|
||||
|
||||
bool IsWallBlocking(int x, int y, int type) const;
|
||||
bool IsElement(int type) const {
|
||||
return (type > 0 && type < PT_NUM && elements[type].Enabled);
|
||||
}
|
||||
bool IsElementOrNone(int type) const {
|
||||
return (type >= 0 && type < PT_NUM && elements[type].Enabled);
|
||||
}
|
||||
void create_cherenkov_photon(int pp);
|
||||
void create_gain_photon(int pp);
|
||||
void kill_part(int i);
|
||||
bool FloodFillPmapCheck(int x, int y, int type);
|
||||
bool FloodFillPmapCheck(int x, int y, int type) const;
|
||||
int flood_prop(int x, int y, StructProperty prop, PropertyValue propvalue);
|
||||
bool flood_water(int x, int y, int i);
|
||||
int FloodINST(int x, int y);
|
||||
@ -177,7 +164,6 @@ public:
|
||||
void CheckStacking();
|
||||
void BeforeSim();
|
||||
void AfterSim();
|
||||
void rotate_area(int area_x, int area_y, int area_w, int area_h, int invert);
|
||||
void clear_area(int area_x, int area_y, int area_w, int area_h);
|
||||
|
||||
void SetEdgeMode(int newEdgeMode);
|
||||
@ -212,13 +198,8 @@ public:
|
||||
void CreateBox(int x1, int y1, int x2, int y2, int c, int flags = -1);
|
||||
int FloodParts(int x, int y, int c, int cm, int flags = -1);
|
||||
|
||||
|
||||
void GetGravityField(int x, int y, float particleGrav, float newtonGrav, float & pGravX, float & pGravY);
|
||||
|
||||
int GetParticleType(ByteString type);
|
||||
|
||||
void orbitalparts_get(int block1, int block2, int resblock1[], int resblock2[]);
|
||||
void orbitalparts_set(int *block1, int *block2, int resblock1[], int resblock2[]);
|
||||
int get_wavelength_bin(int *wm);
|
||||
struct GetNormalResult
|
||||
{
|
||||
@ -226,38 +207,14 @@ public:
|
||||
float nx, ny;
|
||||
int lx, ly, rx, ry;
|
||||
};
|
||||
GetNormalResult get_normal(int pt, int x, int y, float dx, float dy);
|
||||
GetNormalResult get_normal_interp(int pt, float x0, float y0, float dx, float dy);
|
||||
GetNormalResult get_normal(int pt, int x, int y, float dx, float dy) const;
|
||||
template<bool PhotoelectricEffect, class Sim>
|
||||
static GetNormalResult get_normal_interp(Sim &sim, int pt, float x0, float y0, float dx, float dy);
|
||||
void clear_sim();
|
||||
Simulation();
|
||||
~Simulation();
|
||||
|
||||
// These don't really belong anywhere at the moment, so go here for loop edge mode
|
||||
static int remainder_p(int x, int y);
|
||||
static float remainder_p(float x, float y);
|
||||
|
||||
String ElementResolve(int type, int ctype) const;
|
||||
String BasicParticleInfo(Particle const &sample_part) const;
|
||||
|
||||
|
||||
struct CustomGOLData
|
||||
{
|
||||
int rule, colour1, colour2;
|
||||
String nameString, ruleString;
|
||||
|
||||
inline bool operator <(const CustomGOLData &other) const
|
||||
{
|
||||
return rule < other.rule;
|
||||
}
|
||||
};
|
||||
|
||||
private:
|
||||
std::vector<CustomGOLData> customGol;
|
||||
|
||||
public:
|
||||
const CustomGOLData *GetCustomGOLByRule(int rule) const;
|
||||
const std::vector<CustomGOLData> GetCustomGol() { return customGol; }
|
||||
void SetCustomGOL(std::vector<CustomGOLData> newCustomGol);
|
||||
bool useLuaCallbacks = false;
|
||||
|
||||
private:
|
||||
CoordStack& getCoordStackSingleton();
|
||||
|
@ -1,16 +1,16 @@
|
||||
#include "SimulationData.h"
|
||||
|
||||
#include "ElementGraphics.h"
|
||||
#include "ElementDefs.h"
|
||||
#include "ElementClasses.h"
|
||||
|
||||
#include "GOLString.h"
|
||||
#include "BuiltinGOL.h"
|
||||
#include "WallType.h"
|
||||
#include "MenuSection.h"
|
||||
|
||||
#include "ToolClasses.h"
|
||||
#include "Misc.h"
|
||||
#include "graphics/Renderer.h"
|
||||
|
||||
const BuiltinGOL builtinGol[NGOL] = {
|
||||
const std::array<BuiltinGOL, NGOL> SimulationData::builtinGol = {{
|
||||
// * Ruleset:
|
||||
// * bits x = 8..0: stay if x neighbours present
|
||||
// * bits x = 16..9: begin if x-8 neighbours present
|
||||
@ -45,9 +45,9 @@ const BuiltinGOL builtinGol[NGOL] = {
|
||||
{ "STAR", GT_STAR, 0x98478, 0x000040_rgb, 0x0000E6_rgb, NGT_STAR, String("Like Star Wars rule: B278/S3456/6") },
|
||||
{ "FROG", GT_FROG, 0x21806, 0x006400_rgb, 0x00FF00_rgb, NGT_FROG, String("Frogs: B34/S12/3") },
|
||||
{ "BRAN", GT_BRAN, 0x25440, 0xFFFF00_rgb, 0x969600_rgb, NGT_BRAN, String("Brian 6: B246/S6/3" )}
|
||||
};
|
||||
}};
|
||||
|
||||
std::vector<wall_type> LoadWalls()
|
||||
static std::vector<wall_type> LoadWalls()
|
||||
{
|
||||
return
|
||||
std::vector<wall_type>{
|
||||
@ -73,7 +73,7 @@ std::vector<wall_type> LoadWalls()
|
||||
};
|
||||
}
|
||||
|
||||
std::vector<menu_section> LoadMenus()
|
||||
static std::vector<menu_section> LoadMenus()
|
||||
{
|
||||
return
|
||||
std::vector<menu_section>{
|
||||
@ -98,170 +98,244 @@ std::vector<menu_section> LoadMenus()
|
||||
};
|
||||
}
|
||||
|
||||
std::vector<unsigned int> LoadLatent()
|
||||
void SimulationData::init_can_move()
|
||||
{
|
||||
return
|
||||
std::vector<unsigned int>{
|
||||
/* NONE */ 0,
|
||||
/* DUST */ 0,
|
||||
/* WATR */ 7500,
|
||||
/* OIL */ 0,
|
||||
/* FIRE */ 0,
|
||||
/* STNE */ 0,
|
||||
/* LAVA */ 0,
|
||||
/* GUN */ 0,
|
||||
/* NITR */ 0,
|
||||
/* CLNE */ 0,
|
||||
/* GAS */ 0,
|
||||
/* C-4 */ 0,
|
||||
/* GOO */ 0,
|
||||
/* ICE */ 1095,
|
||||
/* METL */ 919,
|
||||
/* SPRK */ 0,
|
||||
/* SNOW */ 1095,
|
||||
/* WOOD */ 0,
|
||||
/* NEUT */ 0,
|
||||
/* PLUT */ 0,
|
||||
/* PLNT */ 0,
|
||||
/* ACID */ 0,
|
||||
/* VOID */ 0,
|
||||
/* WTRV */ 0,
|
||||
/* CNCT */ 0,
|
||||
/* DSTW */ 7500,
|
||||
/* SALT */ 0,
|
||||
/* SLTW */ 7500,
|
||||
/* DMND */ 0,
|
||||
/* BMTL */ 0,
|
||||
/* BRMT */ 0,
|
||||
/* PHOT */ 0,
|
||||
/* URAN */ 0,
|
||||
/* WAX */ 0,
|
||||
/* MWAX */ 0,
|
||||
/* PSCN */ 0,
|
||||
/* NSCN */ 0,
|
||||
/* LN2 */ 0,
|
||||
/* INSL */ 0,
|
||||
/* VACU */ 0,
|
||||
/* VENT */ 0,
|
||||
/* RBDM */ 0,
|
||||
/* LRBD */ 0,
|
||||
/* NTCT */ 0,
|
||||
/* SAND */ 0,
|
||||
/* GLAS */ 0,
|
||||
/* PTCT */ 0,
|
||||
/* BGLA */ 0,
|
||||
/* THDR */ 0,
|
||||
/* PLSM */ 0,
|
||||
/* ETRD */ 0,
|
||||
/* NICE */ 0,
|
||||
/* NBLE */ 0,
|
||||
/* BTRY */ 0,
|
||||
/* LCRY */ 0,
|
||||
/* STKM */ 0,
|
||||
/* SWCH */ 0,
|
||||
/* SMKE */ 0,
|
||||
/* DESL */ 0,
|
||||
/* COAL */ 0,
|
||||
/* LO2 */ 0,
|
||||
/* O2 */ 0,
|
||||
/* INWR */ 0,
|
||||
/* YEST */ 0,
|
||||
/* DYST */ 0,
|
||||
/* THRM */ 0,
|
||||
/* GLOW */ 0,
|
||||
/* BRCK */ 0,
|
||||
/* CFLM */ 0,
|
||||
/* FIRW */ 0,
|
||||
/* FUSE */ 0,
|
||||
/* FSEP */ 0,
|
||||
/* AMTR */ 0,
|
||||
/* BCOL */ 0,
|
||||
/* PCLN */ 0,
|
||||
/* HSWC */ 0,
|
||||
/* IRON */ 0,
|
||||
/* MORT */ 0,
|
||||
/* LIFE */ 0,
|
||||
/* DLAY */ 0,
|
||||
/* CO2 */ 0,
|
||||
/* DRIC */ 0,
|
||||
/* CBNW */ 7500,
|
||||
/* STOR */ 0,
|
||||
/* STOR */ 0,
|
||||
/* FREE */ 0,
|
||||
/* FREE */ 0,
|
||||
/* FREE */ 0,
|
||||
/* FREE */ 0,
|
||||
/* FREE */ 0,
|
||||
/* SPNG */ 0,
|
||||
/* RIME */ 0,
|
||||
/* FOG */ 0,
|
||||
/* BCLN */ 0,
|
||||
/* LOVE */ 0,
|
||||
/* DEUT */ 0,
|
||||
/* WARP */ 0,
|
||||
/* PUMP */ 0,
|
||||
/* FWRK */ 0,
|
||||
/* PIPE */ 0,
|
||||
/* FRZZ */ 0,
|
||||
/* FRZW */ 0,
|
||||
/* GRAV */ 0,
|
||||
/* BIZR */ 0,
|
||||
/* BIZRG*/ 0,
|
||||
/* BIZRS*/ 0,
|
||||
/* INST */ 0,
|
||||
/* ISOZ */ 0,
|
||||
/* ISZS */ 0,
|
||||
/* PRTI */ 0,
|
||||
/* PRTO */ 0,
|
||||
/* PSTE */ 0,
|
||||
/* PSTS */ 0,
|
||||
/* ANAR */ 0,
|
||||
/* VINE */ 0,
|
||||
/* INVS */ 0,
|
||||
/* EQVE */ 0,
|
||||
/* SPWN2*/ 0,
|
||||
/* SPAWN*/ 0,
|
||||
/* SHLD1*/ 0,
|
||||
/* SHLD2*/ 0,
|
||||
/* SHLD3*/ 0,
|
||||
/* SHLD4*/ 0,
|
||||
/* LOlZ */ 0,
|
||||
/* WIFI */ 0,
|
||||
/* FILT */ 0,
|
||||
/* ARAY */ 0,
|
||||
/* BRAY */ 0,
|
||||
/* STKM2*/ 0,
|
||||
/* BOMB */ 0,
|
||||
/* C-5 */ 0,
|
||||
/* SING */ 0,
|
||||
/* QRTZ */ 0,
|
||||
/* PQRT */ 0,
|
||||
/* EMP */ 0,
|
||||
/* BREL */ 0,
|
||||
/* ELEC */ 0,
|
||||
/* ACEL */ 0,
|
||||
/* DCEL */ 0,
|
||||
/* TNT */ 0,
|
||||
/* IGNP */ 0,
|
||||
/* BOYL */ 0,
|
||||
/* GEL */ 0,
|
||||
/* FREE */ 0,
|
||||
/* FREE */ 0,
|
||||
/* FREE */ 0,
|
||||
/* FREE */ 0,
|
||||
/* WIND */ 0,
|
||||
/* H2 */ 0,
|
||||
/* SOAP */ 0,
|
||||
/* NBHL */ 0,
|
||||
/* NWHL */ 0,
|
||||
/* MERC */ 0,
|
||||
/* PBCN */ 0,
|
||||
/* GPMP */ 0,
|
||||
/* CLST */ 0,
|
||||
/* WIRE */ 0,
|
||||
/* GBMB */ 0,
|
||||
/* FIGH */ 0,
|
||||
/* FRAY */ 0,
|
||||
/* REPL */ 0,
|
||||
};
|
||||
int movingType, destinationType;
|
||||
// can_move[moving type][type at destination]
|
||||
// 0 = No move/Bounce
|
||||
// 1 = Swap
|
||||
// 2 = Both particles occupy the same space.
|
||||
// 3 = Varies, go run some extra checks
|
||||
|
||||
//particles that don't exist shouldn't move...
|
||||
for (destinationType = 0; destinationType < PT_NUM; destinationType++)
|
||||
can_move[0][destinationType] = 0;
|
||||
|
||||
//initialize everything else to swapping by default
|
||||
for (movingType = 1; movingType < PT_NUM; movingType++)
|
||||
for (destinationType = 0; destinationType < PT_NUM; destinationType++)
|
||||
can_move[movingType][destinationType] = 1;
|
||||
|
||||
//photons go through everything by default
|
||||
for (destinationType = 1; destinationType < PT_NUM; destinationType++)
|
||||
can_move[PT_PHOT][destinationType] = 2;
|
||||
|
||||
for (movingType = 1; movingType < PT_NUM; movingType++)
|
||||
{
|
||||
for (destinationType = 1; destinationType < PT_NUM; destinationType++)
|
||||
{
|
||||
//weight check, also prevents particles of same type displacing each other
|
||||
if (elements[movingType].Weight <= elements[destinationType].Weight || destinationType == PT_GEL)
|
||||
can_move[movingType][destinationType] = 0;
|
||||
|
||||
//other checks for NEUT and energy particles
|
||||
if (movingType == PT_NEUT && (elements[destinationType].Properties&PROP_NEUTPASS))
|
||||
can_move[movingType][destinationType] = 2;
|
||||
if (movingType == PT_NEUT && (elements[destinationType].Properties&PROP_NEUTABSORB))
|
||||
can_move[movingType][destinationType] = 1;
|
||||
if (movingType == PT_NEUT && (elements[destinationType].Properties&PROP_NEUTPENETRATE))
|
||||
can_move[movingType][destinationType] = 1;
|
||||
if (destinationType == PT_NEUT && (elements[movingType].Properties&PROP_NEUTPENETRATE))
|
||||
can_move[movingType][destinationType] = 0;
|
||||
if ((elements[movingType].Properties&TYPE_ENERGY) && (elements[destinationType].Properties&TYPE_ENERGY))
|
||||
can_move[movingType][destinationType] = 2;
|
||||
}
|
||||
}
|
||||
for (destinationType = 0; destinationType < PT_NUM; destinationType++)
|
||||
{
|
||||
//set what stickmen can move through
|
||||
int stkm_move = 0;
|
||||
if (elements[destinationType].Properties & (TYPE_LIQUID | TYPE_GAS))
|
||||
stkm_move = 2;
|
||||
if (!destinationType || destinationType == PT_PRTO || destinationType == PT_SPAWN || destinationType == PT_SPAWN2)
|
||||
stkm_move = 2;
|
||||
can_move[PT_STKM][destinationType] = stkm_move;
|
||||
can_move[PT_STKM2][destinationType] = stkm_move;
|
||||
can_move[PT_FIGH][destinationType] = stkm_move;
|
||||
|
||||
//spark shouldn't move
|
||||
can_move[PT_SPRK][destinationType] = 0;
|
||||
}
|
||||
for (movingType = 1; movingType < PT_NUM; movingType++)
|
||||
{
|
||||
//everything "swaps" with VACU and BHOL to make them eat things
|
||||
can_move[movingType][PT_BHOL] = 1;
|
||||
can_move[movingType][PT_NBHL] = 1;
|
||||
//nothing goes through stickmen
|
||||
can_move[movingType][PT_STKM] = 0;
|
||||
can_move[movingType][PT_STKM2] = 0;
|
||||
can_move[movingType][PT_FIGH] = 0;
|
||||
//INVS behaviour varies with pressure
|
||||
can_move[movingType][PT_INVIS] = 3;
|
||||
//stop CNCT from being displaced by other particles
|
||||
can_move[movingType][PT_CNCT] = 0;
|
||||
//VOID and PVOD behaviour varies with powered state and ctype
|
||||
can_move[movingType][PT_PVOD] = 3;
|
||||
can_move[movingType][PT_VOID] = 3;
|
||||
//nothing moves through EMBR (not sure why, but it's killed when it touches anything)
|
||||
can_move[movingType][PT_EMBR] = 0;
|
||||
can_move[PT_EMBR][movingType] = 0;
|
||||
//Energy particles move through VIBR and BVBR, so it can absorb them
|
||||
if (elements[movingType].Properties & TYPE_ENERGY)
|
||||
{
|
||||
can_move[movingType][PT_VIBR] = 1;
|
||||
can_move[movingType][PT_BVBR] = 1;
|
||||
}
|
||||
|
||||
//SAWD cannot be displaced by other powders
|
||||
if (elements[movingType].Properties & TYPE_PART)
|
||||
can_move[movingType][PT_SAWD] = 0;
|
||||
}
|
||||
//a list of lots of things PHOT can move through
|
||||
// TODO: replace with property
|
||||
for (destinationType = 0; destinationType < PT_NUM; destinationType++)
|
||||
{
|
||||
if (destinationType == PT_GLAS || destinationType == PT_PHOT || destinationType == PT_FILT || destinationType == PT_INVIS
|
||||
|| destinationType == PT_CLNE || destinationType == PT_PCLN || destinationType == PT_BCLN || destinationType == PT_PBCN
|
||||
|| destinationType == PT_WATR || destinationType == PT_DSTW || destinationType == PT_SLTW || destinationType == PT_GLOW
|
||||
|| destinationType == PT_ISOZ || destinationType == PT_ISZS || destinationType == PT_QRTZ || destinationType == PT_PQRT
|
||||
|| destinationType == PT_H2 || destinationType == PT_BGLA || destinationType == PT_C5)
|
||||
can_move[PT_PHOT][destinationType] = 2;
|
||||
if (destinationType != PT_DMND && destinationType != PT_INSL && destinationType != PT_VOID && destinationType != PT_PVOD && destinationType != PT_VIBR && destinationType != PT_BVBR && destinationType != PT_PRTI && destinationType != PT_PRTO)
|
||||
{
|
||||
can_move[PT_PROT][destinationType] = 2;
|
||||
can_move[PT_GRVT][destinationType] = 2;
|
||||
}
|
||||
}
|
||||
|
||||
//other special cases that weren't covered above
|
||||
can_move[PT_DEST][PT_DMND] = 0;
|
||||
can_move[PT_DEST][PT_CLNE] = 0;
|
||||
can_move[PT_DEST][PT_PCLN] = 0;
|
||||
can_move[PT_DEST][PT_BCLN] = 0;
|
||||
can_move[PT_DEST][PT_PBCN] = 0;
|
||||
can_move[PT_DEST][PT_ROCK] = 0;
|
||||
|
||||
can_move[PT_NEUT][PT_INVIS] = 2;
|
||||
can_move[PT_ELEC][PT_LCRY] = 2;
|
||||
can_move[PT_ELEC][PT_EXOT] = 2;
|
||||
can_move[PT_ELEC][PT_GLOW] = 2;
|
||||
can_move[PT_PHOT][PT_LCRY] = 3; //varies according to LCRY life
|
||||
can_move[PT_PHOT][PT_GPMP] = 3;
|
||||
|
||||
can_move[PT_PHOT][PT_BIZR] = 2;
|
||||
can_move[PT_ELEC][PT_BIZR] = 2;
|
||||
can_move[PT_PHOT][PT_BIZRG] = 2;
|
||||
can_move[PT_ELEC][PT_BIZRG] = 2;
|
||||
can_move[PT_PHOT][PT_BIZRS] = 2;
|
||||
can_move[PT_ELEC][PT_BIZRS] = 2;
|
||||
can_move[PT_BIZR][PT_FILT] = 2;
|
||||
can_move[PT_BIZRG][PT_FILT] = 2;
|
||||
|
||||
can_move[PT_ANAR][PT_WHOL] = 1; //WHOL eats ANAR
|
||||
can_move[PT_ANAR][PT_NWHL] = 1;
|
||||
can_move[PT_ELEC][PT_DEUT] = 1;
|
||||
can_move[PT_THDR][PT_THDR] = 2;
|
||||
can_move[PT_EMBR][PT_EMBR] = 2;
|
||||
can_move[PT_TRON][PT_SWCH] = 3;
|
||||
can_move[PT_SOAP][PT_OIL] = 0;
|
||||
can_move[PT_OIL][PT_SOAP] = 1;
|
||||
}
|
||||
|
||||
const CustomGOLData *SimulationData::GetCustomGOLByRule(int rule) const
|
||||
{
|
||||
// * Binary search. customGol is already sorted, see SetCustomGOL.
|
||||
auto it = std::lower_bound(customGol.begin(), customGol.end(), rule, [](const CustomGOLData &item, int rule) {
|
||||
return item.rule < rule;
|
||||
});
|
||||
if (it != customGol.end() && !(rule < it->rule))
|
||||
{
|
||||
return &*it;
|
||||
}
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
void SimulationData::SetCustomGOL(std::vector<CustomGOLData> newCustomGol)
|
||||
{
|
||||
std::sort(newCustomGol.begin(), newCustomGol.end());
|
||||
customGol = newCustomGol;
|
||||
}
|
||||
|
||||
String SimulationData::ElementResolve(int type, int ctype) const
|
||||
{
|
||||
if (type == PT_LIFE)
|
||||
{
|
||||
if (ctype >= 0 && ctype < NGOL)
|
||||
{
|
||||
return builtinGol[ctype].name;
|
||||
}
|
||||
auto *cgol = GetCustomGOLByRule(ctype);
|
||||
if (cgol)
|
||||
{
|
||||
return cgol->nameString;
|
||||
}
|
||||
return SerialiseGOLRule(ctype);
|
||||
}
|
||||
else if (type >= 0 && type < PT_NUM)
|
||||
return elements[type].Name;
|
||||
return "Empty";
|
||||
}
|
||||
|
||||
String SimulationData::BasicParticleInfo(Particle const &sample_part) const
|
||||
{
|
||||
StringBuilder sampleInfo;
|
||||
int type = sample_part.type;
|
||||
int ctype = sample_part.ctype;
|
||||
int storedCtype = sample_part.tmp4;
|
||||
if (type == PT_LAVA && IsElement(ctype))
|
||||
{
|
||||
sampleInfo << "Molten " << ElementResolve(ctype, -1);
|
||||
}
|
||||
else if ((type == PT_PIPE || type == PT_PPIP) && IsElement(ctype))
|
||||
{
|
||||
if (ctype == PT_LAVA && IsElement(storedCtype))
|
||||
{
|
||||
sampleInfo << ElementResolve(type, -1) << " with molten " << ElementResolve(storedCtype, -1);
|
||||
}
|
||||
else
|
||||
{
|
||||
sampleInfo << ElementResolve(type, -1) << " with " << ElementResolve(ctype, storedCtype);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
sampleInfo << ElementResolve(type, ctype);
|
||||
}
|
||||
return sampleInfo.Build();
|
||||
}
|
||||
|
||||
int SimulationData::GetParticleType(ByteString type) const
|
||||
{
|
||||
type = type.ToUpper();
|
||||
|
||||
// alternative names for some elements
|
||||
if (byteStringEqualsLiteral(type, "C4"))
|
||||
{
|
||||
return PT_PLEX;
|
||||
}
|
||||
else if (byteStringEqualsLiteral(type, "C5"))
|
||||
{
|
||||
return PT_C5;
|
||||
}
|
||||
else if (byteStringEqualsLiteral(type, "NONE"))
|
||||
{
|
||||
return PT_NONE;
|
||||
}
|
||||
for (int i = 1; i < PT_NUM; i++)
|
||||
{
|
||||
if (elements[i].Name.size() && elements[i].Enabled && type == elements[i].Name.ToUtf8().ToUpper())
|
||||
{
|
||||
return i;
|
||||
}
|
||||
}
|
||||
return -1;
|
||||
}
|
||||
|
||||
SimulationData::SimulationData()
|
||||
{
|
||||
init_can_move();
|
||||
msections = LoadMenus();
|
||||
wtypes = LoadWalls();
|
||||
elements = GetElements();
|
||||
tools = GetTools();
|
||||
}
|
||||
|
@ -1,8 +1,19 @@
|
||||
#pragma once
|
||||
#include "SimulationConfig.h"
|
||||
#include "ElementDefs.h"
|
||||
#include "common/ExplicitSingleton.h"
|
||||
#include "common/String.h"
|
||||
#include "MenuSection.h"
|
||||
#include "BuiltinGOL.h"
|
||||
#include "SimTool.h"
|
||||
#include "Element.h"
|
||||
#include "Particle.h"
|
||||
#include "WallType.h"
|
||||
#include "graphics/gcache_item.h"
|
||||
#include <cstdint>
|
||||
#include <vector>
|
||||
#include <array>
|
||||
#include <shared_mutex>
|
||||
|
||||
constexpr int SC_WALL = 0;
|
||||
constexpr int SC_ELEC = 1;
|
||||
@ -148,20 +159,61 @@ enum GravityMode
|
||||
GRAV_VERTICAL, GRAV_OFF, GRAV_RADIAL, GRAV_CUSTOM, NUM_GRAV_MODES
|
||||
};
|
||||
|
||||
struct part_type;
|
||||
struct part_transition;
|
||||
struct CustomGOLData
|
||||
{
|
||||
int rule, colour1, colour2;
|
||||
String nameString, ruleString;
|
||||
|
||||
struct wall_type;
|
||||
struct BuiltinGOL;
|
||||
struct menu_section;
|
||||
inline bool operator <(const CustomGOLData &other) const
|
||||
{
|
||||
return rule < other.rule;
|
||||
}
|
||||
};
|
||||
|
||||
class SimTool;
|
||||
class Element;
|
||||
class SimulationData : public ExplicitSingleton<SimulationData>
|
||||
{
|
||||
public:
|
||||
std::array<Element, PT_NUM> elements;
|
||||
std::array<gcache_item, PT_NUM> graphicscache;
|
||||
std::vector<SimTool> tools;
|
||||
std::vector<wall_type> wtypes;
|
||||
std::vector<menu_section> msections;
|
||||
char can_move[PT_NUM][PT_NUM];
|
||||
static const std::array<BuiltinGOL, NGOL> builtinGol;
|
||||
|
||||
extern const BuiltinGOL builtinGol[];
|
||||
// Element properties that enable basic graphics (i.e. every property that has to do with graphics other than
|
||||
// the graphics callback itself) are only ever written by the main thread, but they are read by some other
|
||||
// threads that use Renderer to render thumbnails and such. Take this std::shared_mutex with an std::unique_lock
|
||||
// when writing such properties in the main thread, and with an std::shared_lock when reading such properties
|
||||
// in these secondary Renderer threads. Don't take it with an std::shared_lock when reading such properties in
|
||||
// the main thread; the main thread doesn't race with itself.
|
||||
mutable std::shared_mutex elementGraphicsMx;
|
||||
|
||||
std::vector<wall_type> LoadWalls();
|
||||
private:
|
||||
std::vector<CustomGOLData> customGol;
|
||||
|
||||
std::vector<menu_section> LoadMenus();
|
||||
public:
|
||||
SimulationData();
|
||||
void InitElements();
|
||||
|
||||
std::vector<unsigned int> LoadLatent();
|
||||
void init_can_move();
|
||||
|
||||
const CustomGOLData *GetCustomGOLByRule(int rule) const;
|
||||
const std::vector<CustomGOLData> &GetCustomGol() const { return customGol; }
|
||||
void SetCustomGOL(std::vector<CustomGOLData> newCustomGol);
|
||||
|
||||
String ElementResolve(int type, int ctype) const;
|
||||
String BasicParticleInfo(Particle const &sample_part) const;
|
||||
int GetParticleType(ByteString type) const;
|
||||
|
||||
bool IsElement(int type) const
|
||||
{
|
||||
return (type > 0 && type < PT_NUM && elements[type].Enabled);
|
||||
}
|
||||
|
||||
bool IsElementOrNone(int type) const
|
||||
{
|
||||
return (type >= 0 && type < PT_NUM && elements[type].Enabled);
|
||||
}
|
||||
|
||||
};
|
||||
|
@ -49,6 +49,8 @@ void Element::Element_ACEL()
|
||||
|
||||
static int update(UPDATE_FUNC_ARGS)
|
||||
{
|
||||
auto &sd = SimulationData::CRef();
|
||||
auto &elements = sd.elements;
|
||||
float multiplier;
|
||||
if (parts[i].life!=0)
|
||||
{
|
||||
@ -71,7 +73,7 @@ static int update(UPDATE_FUNC_ARGS)
|
||||
r = sim->photons[y+ry][x+rx];
|
||||
if (!r)
|
||||
continue;
|
||||
if(sim->elements[TYP(r)].Properties & (TYPE_PART | TYPE_LIQUID | TYPE_GAS | TYPE_ENERGY))
|
||||
if(elements[TYP(r)].Properties & (TYPE_PART | TYPE_LIQUID | TYPE_GAS | TYPE_ENERGY))
|
||||
{
|
||||
parts[ID(r)].vx *= multiplier;
|
||||
parts[ID(r)].vy *= multiplier;
|
||||
|
@ -52,6 +52,8 @@ void Element::Element_ACID()
|
||||
|
||||
static int update(UPDATE_FUNC_ARGS)
|
||||
{
|
||||
auto &sd = SimulationData::CRef();
|
||||
auto &elements = sd.elements;
|
||||
for (auto rx = -2; rx <= 2; rx++)
|
||||
{
|
||||
for (auto ry = -2; ry <= 2; ry++)
|
||||
@ -80,11 +82,11 @@ static int update(UPDATE_FUNC_ARGS)
|
||||
sim->kill_part(ID(r));
|
||||
}
|
||||
}
|
||||
else if (rt != PT_CLNE && rt != PT_PCLN && parts[i].life >= 50 && sim->rng.chance(sim->elements[rt].Hardness, 1000))
|
||||
else if (rt != PT_CLNE && rt != PT_PCLN && parts[i].life >= 50 && sim->rng.chance(elements[rt].Hardness, 1000))
|
||||
{
|
||||
if (sim->parts_avg(i, ID(r),PT_GLAS)!= PT_GLAS)//GLAS protects stuff from acid
|
||||
{
|
||||
float newtemp = ((60.0f-(float)sim->elements[rt].Hardness))*7.0f;
|
||||
float newtemp = ((60.0f-(float)elements[rt].Hardness))*7.0f;
|
||||
if(newtemp < 0){
|
||||
newtemp = 0;
|
||||
}
|
||||
|
@ -1,4 +1,5 @@
|
||||
#include "simulation/ElementCommon.h"
|
||||
#include "FILT.h"
|
||||
|
||||
static int update(UPDATE_FUNC_ARGS);
|
||||
|
||||
@ -47,6 +48,8 @@ void Element::Element_ARAY()
|
||||
|
||||
static int update(UPDATE_FUNC_ARGS)
|
||||
{
|
||||
auto &sd = SimulationData::CRef();
|
||||
auto &elements = sd.elements;
|
||||
int short_bray_life = parts[i].life > 0 ? parts[i].life : 30;
|
||||
int long_bray_life = parts[i].life > 0 ? parts[i].life : 1020;
|
||||
for (int rx = -1; rx <= 1; rx++)
|
||||
@ -128,7 +131,6 @@ static int update(UPDATE_FUNC_ARGS)
|
||||
{
|
||||
if (parts[r].tmp != 6)
|
||||
{
|
||||
int Element_FILT_interactWavelengths(Simulation *sim, Particle* cpart, int origWl);
|
||||
colored = Element_FILT_interactWavelengths(sim, &parts[r], colored);
|
||||
if (!colored)
|
||||
break;
|
||||
@ -170,7 +172,7 @@ static int update(UPDATE_FUNC_ARGS)
|
||||
if (nyy!=0 || nxx!=0)
|
||||
sim->create_part(-1, x+nxi+nxx, y+nyi+nyy, PT_SPRK);
|
||||
|
||||
if (!(nostop && parts[r].type==PT_SPRK && parts[r].ctype >= 0 && parts[r].ctype < PT_NUM && (sim->elements[parts[r].ctype].Properties&PROP_CONDUCTS)))
|
||||
if (!(nostop && parts[r].type==PT_SPRK && parts[r].ctype >= 0 && parts[r].ctype < PT_NUM && (elements[parts[r].ctype].Properties&PROP_CONDUCTS)))
|
||||
docontinue = 0;
|
||||
else
|
||||
docontinue = 1;
|
||||
|
@ -51,6 +51,8 @@ constexpr float ADVECTION = 0.1f;
|
||||
|
||||
static int update(UPDATE_FUNC_ARGS)
|
||||
{
|
||||
auto &sd = SimulationData::CRef();
|
||||
auto &elements = sd.elements;
|
||||
if (!parts[i].life && sim->pv[y/CELL][x/CELL]>4.0f)
|
||||
parts[i].life = sim->rng.between(80, 119);
|
||||
if (parts[i].life)
|
||||
@ -58,7 +60,7 @@ static int update(UPDATE_FUNC_ARGS)
|
||||
parts[i].vx += ADVECTION*sim->vx[y/CELL][x/CELL];
|
||||
parts[i].vy += ADVECTION*sim->vy[y/CELL][x/CELL];
|
||||
}
|
||||
if (parts[i].ctype<=0 || parts[i].ctype>=PT_NUM || !sim->elements[parts[i].ctype].Enabled)
|
||||
if (parts[i].ctype<=0 || parts[i].ctype>=PT_NUM || !elements[parts[i].ctype].Enabled)
|
||||
{
|
||||
for (auto rx = -1; rx <= 1; rx++)
|
||||
{
|
||||
@ -90,7 +92,7 @@ static int update(UPDATE_FUNC_ARGS)
|
||||
int np = sim->create_part(-1, x + sim->rng.between(-1, 1), y + sim->rng.between(-1, 1), TYP(parts[i].ctype));
|
||||
if (np>=0)
|
||||
{
|
||||
if (parts[i].ctype==PT_LAVA && parts[i].tmp>0 && parts[i].tmp<PT_NUM && sim->elements[parts[i].tmp].HighTemperatureTransition==PT_LAVA)
|
||||
if (parts[i].ctype==PT_LAVA && parts[i].tmp>0 && parts[i].tmp<PT_NUM && elements[parts[i].tmp].HighTemperatureTransition==PT_LAVA)
|
||||
parts[np].ctype = parts[i].tmp;
|
||||
}
|
||||
}
|
||||
|
@ -1,7 +1,5 @@
|
||||
#include "simulation/ElementCommon.h"
|
||||
|
||||
int Element_COAL_update(UPDATE_FUNC_ARGS);
|
||||
int Element_COAL_graphics(GRAPHICS_FUNC_ARGS);
|
||||
#include "COAL.h"
|
||||
|
||||
void Element::Element_BCOL()
|
||||
{
|
||||
|
@ -1,7 +1,5 @@
|
||||
#include "simulation/ElementCommon.h"
|
||||
|
||||
int Element_BIZR_update(UPDATE_FUNC_ARGS);
|
||||
int Element_BIZR_graphics(GRAPHICS_FUNC_ARGS);
|
||||
#include "BIZR.h"
|
||||
|
||||
void Element::Element_BIZR()
|
||||
{
|
||||
|
5
src/simulation/elements/BIZR.h
Normal file
5
src/simulation/elements/BIZR.h
Normal file
@ -0,0 +1,5 @@
|
||||
#pragma once
|
||||
#include "simulation/ElementDefs.h"
|
||||
|
||||
int Element_BIZR_graphics(GRAPHICS_FUNC_ARGS);
|
||||
int Element_BIZR_update(UPDATE_FUNC_ARGS);
|
@ -1,7 +1,5 @@
|
||||
#include "simulation/ElementCommon.h"
|
||||
|
||||
int Element_BIZR_update(UPDATE_FUNC_ARGS);
|
||||
int Element_BIZR_graphics(GRAPHICS_FUNC_ARGS);
|
||||
#include "BIZR.h"
|
||||
|
||||
void Element::Element_BIZRG()
|
||||
{
|
||||
|
@ -1,7 +1,5 @@
|
||||
#include "simulation/ElementCommon.h"
|
||||
|
||||
int Element_BIZR_update(UPDATE_FUNC_ARGS);
|
||||
int Element_BIZR_graphics(GRAPHICS_FUNC_ARGS);
|
||||
#include "BIZR.h"
|
||||
|
||||
void Element::Element_BIZRS()
|
||||
{
|
||||
|
@ -47,6 +47,8 @@ void Element::Element_BTRY()
|
||||
|
||||
static int update(UPDATE_FUNC_ARGS)
|
||||
{
|
||||
auto &sd = SimulationData::CRef();
|
||||
auto &elements = sd.elements;
|
||||
for (auto rx = -2; rx <= 2; rx++)
|
||||
{
|
||||
for (auto ry = -2; ry <= 2; ry++)
|
||||
@ -59,7 +61,7 @@ static int update(UPDATE_FUNC_ARGS)
|
||||
auto rt = TYP(r);
|
||||
if (sim->parts_avg(i,ID(r),PT_INSL) != PT_INSL)
|
||||
{
|
||||
if ((sim->elements[rt].Properties&PROP_CONDUCTS) && !(rt==PT_WATR||rt==PT_SLTW||rt==PT_NTCT||rt==PT_PTCT||rt==PT_INWR) && parts[ID(r)].life==0)
|
||||
if ((elements[rt].Properties&PROP_CONDUCTS) && !(rt==PT_WATR||rt==PT_SLTW||rt==PT_NTCT||rt==PT_PTCT||rt==PT_INWR) && parts[ID(r)].life==0)
|
||||
{
|
||||
parts[ID(r)].life = 4;
|
||||
parts[ID(r)].ctype = rt;
|
||||
|
@ -1,7 +1,5 @@
|
||||
#include "simulation/ElementCommon.h"
|
||||
|
||||
int Element_VIBR_update(UPDATE_FUNC_ARGS);
|
||||
int Element_VIBR_graphics(GRAPHICS_FUNC_ARGS);
|
||||
#include "VIBR.h"
|
||||
|
||||
void Element::Element_BVBR()
|
||||
{
|
||||
|
@ -49,6 +49,8 @@ void Element::Element_C5()
|
||||
|
||||
static int update(UPDATE_FUNC_ARGS)
|
||||
{
|
||||
auto &sd = SimulationData::CRef();
|
||||
auto &elements = sd.elements;
|
||||
for (auto rx = -2; rx <= 2; rx++)
|
||||
{
|
||||
for (auto ry = -2; ry <= 2; ry++)
|
||||
@ -58,7 +60,7 @@ static int update(UPDATE_FUNC_ARGS)
|
||||
auto r = pmap[y+ry][x+rx];
|
||||
if (!r)
|
||||
continue;
|
||||
if ((TYP(r)!=PT_C5 && parts[ID(r)].temp<100 && sim->elements[TYP(r)].HeatConduct && (TYP(r)!=PT_HSWC||parts[ID(r)].life==10)) || TYP(r)==PT_CFLM)
|
||||
if ((TYP(r)!=PT_C5 && parts[ID(r)].temp<100 && elements[TYP(r)].HeatConduct && (TYP(r)!=PT_HSWC||parts[ID(r)].life==10)) || TYP(r)==PT_CFLM)
|
||||
{
|
||||
if (sim->rng.chance(1, 6))
|
||||
{
|
||||
|
@ -49,6 +49,8 @@ void Element::Element_CAUS()
|
||||
|
||||
static int update(UPDATE_FUNC_ARGS)
|
||||
{
|
||||
auto &sd = SimulationData::CRef();
|
||||
auto &elements = sd.elements;
|
||||
for (int rx = -2; rx <= 2; rx++)
|
||||
{
|
||||
for (int ry = -2; ry <= 2; ry++)
|
||||
@ -68,12 +70,12 @@ static int update(UPDATE_FUNC_ARGS)
|
||||
}
|
||||
else if (TYP(r) != PT_ACID && TYP(r) != PT_CAUS && TYP(r) != PT_RFRG && TYP(r) != PT_RFGL)
|
||||
{
|
||||
if ((TYP(r) != PT_CLNE && TYP(r) != PT_PCLN && sim->rng.chance(sim->elements[TYP(r)].Hardness, 1000)) && parts[i].life >= 50)
|
||||
if ((TYP(r) != PT_CLNE && TYP(r) != PT_PCLN && sim->rng.chance(elements[TYP(r)].Hardness, 1000)) && parts[i].life >= 50)
|
||||
{
|
||||
// GLAS protects stuff from acid
|
||||
if (sim->parts_avg(i, ID(r),PT_GLAS) != PT_GLAS)
|
||||
{
|
||||
float newtemp = ((60.0f - (float)sim->elements[TYP(r)].Hardness)) * 7.0f;
|
||||
float newtemp = ((60.0f - (float)elements[TYP(r)].Hardness)) * 7.0f;
|
||||
if (newtemp < 0)
|
||||
newtemp = 0;
|
||||
parts[i].temp += newtemp;
|
||||
|
@ -31,6 +31,7 @@ void Element::Element_CBNW()
|
||||
|
||||
DefaultProperties.temp = R_TEMP - 2.0f + 273.15f;
|
||||
HeatConduct = 29;
|
||||
LatentHeat = 7500;
|
||||
Description = "Carbonated water. Slowly releases CO2.";
|
||||
|
||||
Properties = TYPE_LIQUID|PROP_CONDUCTS|PROP_LIFE_DEC|PROP_NEUTPENETRATE;
|
||||
@ -50,6 +51,8 @@ void Element::Element_CBNW()
|
||||
|
||||
static int update(UPDATE_FUNC_ARGS)
|
||||
{
|
||||
auto &sd = SimulationData::CRef();
|
||||
auto &elements = sd.elements;
|
||||
if (sim->pv[y/CELL][x/CELL]<=3)
|
||||
{
|
||||
if (sim->pv[y/CELL][x/CELL] <= -0.5 || sim->rng.chance(1, 4000))
|
||||
@ -87,12 +90,12 @@ static int update(UPDATE_FUNC_ARGS)
|
||||
auto r = pmap[y+ry][x+rx];
|
||||
if (!r)
|
||||
continue;
|
||||
if ((sim->elements[TYP(r)].Properties&TYPE_PART) && parts[i].tmp == 0 && sim->rng.chance(1, 83))
|
||||
if ((elements[TYP(r)].Properties&TYPE_PART) && parts[i].tmp == 0 && sim->rng.chance(1, 83))
|
||||
{
|
||||
//Start explode
|
||||
parts[i].tmp = sim->rng.between(0, 24);
|
||||
}
|
||||
else if((sim->elements[TYP(r)].Properties&TYPE_SOLID) && TYP(r)!=PT_DMND && TYP(r)!=PT_GLAS && parts[i].tmp == 0 && sim->rng.chance(int(2 - sim->pv[y/CELL][x/CELL]), 6667))
|
||||
else if((elements[TYP(r)].Properties&TYPE_SOLID) && TYP(r)!=PT_DMND && TYP(r)!=PT_GLAS && parts[i].tmp == 0 && sim->rng.chance(int(2 - sim->pv[y/CELL][x/CELL]), 6667))
|
||||
{
|
||||
sim->part_change_type(i,x,y,PT_CO2);
|
||||
parts[i].ctype = 5;
|
||||
|
@ -49,7 +49,9 @@ void Element::Element_CLNE()
|
||||
|
||||
static int update(UPDATE_FUNC_ARGS)
|
||||
{
|
||||
if (parts[i].ctype<=0 || parts[i].ctype>=PT_NUM || !sim->elements[parts[i].ctype].Enabled)
|
||||
auto &sd = SimulationData::CRef();
|
||||
auto &elements = sd.elements;
|
||||
if (parts[i].ctype<=0 || parts[i].ctype>=PT_NUM || !elements[parts[i].ctype].Enabled)
|
||||
{
|
||||
for (auto rx = -1; rx <= 1; rx++)
|
||||
{
|
||||
@ -81,7 +83,7 @@ static int update(UPDATE_FUNC_ARGS)
|
||||
int np = sim->create_part(-1, x + sim->rng.between(-1, 1), y + sim->rng.between(-1, 1), TYP(parts[i].ctype));
|
||||
if (np>=0)
|
||||
{
|
||||
if (parts[i].ctype==PT_LAVA && parts[i].tmp>0 && parts[i].tmp<PT_NUM && sim->elements[parts[i].tmp].HighTemperatureTransition==PT_LAVA)
|
||||
if (parts[i].ctype==PT_LAVA && parts[i].tmp>0 && parts[i].tmp<PT_NUM && elements[parts[i].tmp].HighTemperatureTransition==PT_LAVA)
|
||||
parts[np].ctype = parts[i].tmp;
|
||||
}
|
||||
}
|
||||
|
@ -1,7 +1,5 @@
|
||||
#include "simulation/ElementCommon.h"
|
||||
|
||||
int Element_COAL_update(UPDATE_FUNC_ARGS);
|
||||
int Element_COAL_graphics(GRAPHICS_FUNC_ARGS);
|
||||
#include "COAL.h"
|
||||
|
||||
void Element::Element_COAL()
|
||||
{
|
||||
|
5
src/simulation/elements/COAL.h
Normal file
5
src/simulation/elements/COAL.h
Normal file
@ -0,0 +1,5 @@
|
||||
#pragma once
|
||||
#include "simulation/ElementDefs.h"
|
||||
|
||||
int Element_COAL_graphics(GRAPHICS_FUNC_ARGS);
|
||||
int Element_COAL_update(UPDATE_FUNC_ARGS);
|
@ -49,8 +49,10 @@ void Element::Element_CONV()
|
||||
|
||||
static int update(UPDATE_FUNC_ARGS)
|
||||
{
|
||||
auto &sd = SimulationData::CRef();
|
||||
auto &elements = sd.elements;
|
||||
int ctype = TYP(parts[i].ctype);
|
||||
if (ctype<=0 || ctype>=PT_NUM || !sim->elements[ctype].Enabled || ctype==PT_CONV)
|
||||
if (ctype<=0 || ctype>=PT_NUM || !elements[ctype].Enabled || ctype==PT_CONV)
|
||||
{
|
||||
for (auto rx = -1; rx <= 1; rx++)
|
||||
{
|
||||
@ -76,7 +78,7 @@ static int update(UPDATE_FUNC_ARGS)
|
||||
}
|
||||
else
|
||||
{
|
||||
int restrictElement = sim->IsElement(parts[i].tmp) ? parts[i].tmp : 0;
|
||||
int restrictElement = sd.IsElement(parts[i].tmp) ? parts[i].tmp : 0;
|
||||
for (auto rx = -1; rx <= 1; rx++)
|
||||
{
|
||||
for (auto ry = -1; ry <= 1; ry++)
|
||||
|
@ -1,4 +1,5 @@
|
||||
#include "simulation/ElementCommon.h"
|
||||
#include "FILT.h"
|
||||
|
||||
static int update(UPDATE_FUNC_ARGS);
|
||||
static bool ctypeDraw(CTYPEDRAW_FUNC_ARGS);
|
||||
@ -51,9 +52,11 @@ void Element::Element_CRAY()
|
||||
|
||||
static int update(UPDATE_FUNC_ARGS)
|
||||
{
|
||||
auto &sd = SimulationData::CRef();
|
||||
auto &elements = sd.elements;
|
||||
int nxx, nyy, docontinue, nxi, nyi;
|
||||
// set ctype to things that touch it if it doesn't have one already
|
||||
if (parts[i].ctype<=0 || !sim->elements[TYP(parts[i].ctype)].Enabled)
|
||||
if (parts[i].ctype<=0 || !elements[TYP(parts[i].ctype)].Enabled)
|
||||
{
|
||||
for (int rx = -1; rx <= 1; rx++)
|
||||
{
|
||||
@ -114,7 +117,6 @@ static int update(UPDATE_FUNC_ARGS)
|
||||
colored = 0xFF000000;
|
||||
else if (parts[ID(r)].tmp==0)
|
||||
{
|
||||
int Element_FILT_getWavelengths(Particle* cpart);
|
||||
colored = wavelengthToDecoColour(Element_FILT_getWavelengths(&parts[ID(r)]));
|
||||
}
|
||||
else if (colored==0xFF000000)
|
||||
@ -166,6 +168,8 @@ static unsigned int wavelengthToDecoColour(int wavelength)
|
||||
|
||||
static bool ctypeDraw(CTYPEDRAW_FUNC_ARGS)
|
||||
{
|
||||
auto &sd = SimulationData::CRef();
|
||||
auto &elements = sd.elements;
|
||||
if (!Element::ctypeDrawVInCtype(CTYPEDRAW_FUNC_SUBCALL_ARGS))
|
||||
{
|
||||
return false;
|
||||
@ -174,6 +178,6 @@ static bool ctypeDraw(CTYPEDRAW_FUNC_ARGS)
|
||||
{
|
||||
sim->parts[i].ctype |= PMAPID(30);
|
||||
}
|
||||
sim->parts[i].temp = sim->elements[t].DefaultProperties.temp;
|
||||
sim->parts[i].temp = elements[t].DefaultProperties.temp;
|
||||
return true;
|
||||
}
|
||||
|
@ -49,6 +49,8 @@ void Element::Element_DCEL()
|
||||
|
||||
static int update(UPDATE_FUNC_ARGS)
|
||||
{
|
||||
auto &sd = SimulationData::CRef();
|
||||
auto &elements = sd.elements;
|
||||
float multiplier = 1.0f/1.1f;
|
||||
if (parts[i].life!=0)
|
||||
{
|
||||
@ -66,7 +68,7 @@ static int update(UPDATE_FUNC_ARGS)
|
||||
r = sim->photons[y+ry][x+rx];
|
||||
if (!r)
|
||||
continue;
|
||||
if (sim->elements[TYP(r)].Properties & (TYPE_PART | TYPE_LIQUID | TYPE_GAS | TYPE_ENERGY))
|
||||
if (elements[TYP(r)].Properties & (TYPE_PART | TYPE_LIQUID | TYPE_GAS | TYPE_ENERGY))
|
||||
{
|
||||
parts[ID(r)].vx *= multiplier;
|
||||
parts[ID(r)].vy *= multiplier;
|
||||
|
@ -49,6 +49,8 @@ void Element::Element_DEST()
|
||||
|
||||
static int update(UPDATE_FUNC_ARGS)
|
||||
{
|
||||
auto &sd = SimulationData::CRef();
|
||||
auto &elements = sd.elements;
|
||||
int rx = sim->rng.between(-2, 2);
|
||||
int ry = sim->rng.between(-2, 2);
|
||||
int r = pmap[y+ry][x+rx];
|
||||
@ -81,11 +83,11 @@ static int update(UPDATE_FUNC_ARGS)
|
||||
else if (sim->rng.chance(1, 3))
|
||||
{
|
||||
sim->kill_part(ID(r));
|
||||
parts[i].life -= 4*((sim->elements[rt].Properties&TYPE_SOLID)?3:1);
|
||||
parts[i].life -= 4*((elements[rt].Properties&TYPE_SOLID)?3:1);
|
||||
if (parts[i].life<=0)
|
||||
parts[i].life=1;
|
||||
}
|
||||
else if (sim->elements[rt].HeatConduct)
|
||||
else if (elements[rt].HeatConduct)
|
||||
parts[ID(r)].temp = MAX_TEMP;
|
||||
parts[i].temp=MAX_TEMP;
|
||||
sim->pv[y/CELL][x/CELL]+=80.0f;
|
||||
|
@ -50,6 +50,8 @@ void Element::Element_DMG()
|
||||
|
||||
static int update(UPDATE_FUNC_ARGS)
|
||||
{
|
||||
auto &sd = SimulationData::CRef();
|
||||
auto &elements = sd.elements;
|
||||
int rad = 25;
|
||||
for (auto rx = -1; rx <= 1; rx++)
|
||||
{
|
||||
@ -84,8 +86,8 @@ static int update(UPDATE_FUNC_ARGS)
|
||||
sim->vy[(y+nxj)/CELL][(x+nxi)/CELL] += fy;
|
||||
sim->pv[(y+nxj)/CELL][(x+nxi)/CELL] += 1.0f;
|
||||
auto t = TYP(rr);
|
||||
if (t && sim->elements[t].HighPressureTransition>-1 && sim->elements[t].HighPressureTransition<PT_NUM)
|
||||
sim->part_change_type(ID(rr), x+nxi, y+nxj, sim->elements[t].HighPressureTransition);
|
||||
if (t && elements[t].HighPressureTransition>-1 && elements[t].HighPressureTransition<PT_NUM)
|
||||
sim->part_change_type(ID(rr), x+nxi, y+nxj, elements[t].HighPressureTransition);
|
||||
else if (t == PT_BMTL)
|
||||
sim->part_change_type(ID(rr), x+nxi, y+nxj, PT_BRMT);
|
||||
else if (t == PT_GLAS)
|
||||
|
@ -50,6 +50,8 @@ void Element::Element_DRAY()
|
||||
|
||||
static int update(UPDATE_FUNC_ARGS)
|
||||
{
|
||||
auto &sd = SimulationData::CRef();
|
||||
auto &elements = sd.elements;
|
||||
int ctype = TYP(parts[i].ctype), ctypeExtra = ID(parts[i].ctype), copyLength = parts[i].tmp, copySpaces = parts[i].tmp2;
|
||||
if (copySpaces < 0)
|
||||
copySpaces = parts[i].tmp2 = 0;
|
||||
@ -98,7 +100,7 @@ static int update(UPDATE_FUNC_ARGS)
|
||||
foundParticle = true;
|
||||
}
|
||||
// now that it knows what kind of particle it is copying, do some extra stuff here so we can determine when to stop
|
||||
if ((ctype && sim->elements[ctype].Properties&TYPE_ENERGY) || isEnergy)
|
||||
if ((ctype && elements[ctype].Properties&TYPE_ENERGY) || isEnergy)
|
||||
rr = sim->photons[yCurrent][xCurrent];
|
||||
else
|
||||
rr = pmap[yCurrent][xCurrent];
|
||||
|
@ -30,6 +30,7 @@ void Element::Element_DSTW()
|
||||
|
||||
DefaultProperties.temp = R_TEMP - 2.0f + 273.15f;
|
||||
HeatConduct = 23;
|
||||
LatentHeat = 7500;
|
||||
Description = "Distilled water, does not conduct electricity.";
|
||||
|
||||
Properties = TYPE_LIQUID|PROP_NEUTPASS;
|
||||
|
@ -51,6 +51,8 @@ void Element::Element_DTEC()
|
||||
|
||||
static int update(UPDATE_FUNC_ARGS)
|
||||
{
|
||||
auto &sd = SimulationData::CRef();
|
||||
auto &elements = sd.elements;
|
||||
int rd = parts[i].tmp2;
|
||||
if (rd > 25) parts[i].tmp2 = rd = 25;
|
||||
if (parts[i].life)
|
||||
@ -68,7 +70,7 @@ static int update(UPDATE_FUNC_ARGS)
|
||||
auto rt = TYP(r);
|
||||
if (sim->parts_avg(i,ID(r),PT_INSL) != PT_INSL)
|
||||
{
|
||||
if ((sim->elements[rt].Properties&PROP_CONDUCTS) && !(rt==PT_WATR||rt==PT_SLTW||rt==PT_NTCT||rt==PT_PTCT||rt==PT_INWR) && parts[ID(r)].life==0)
|
||||
if ((elements[rt].Properties&PROP_CONDUCTS) && !(rt==PT_WATR||rt==PT_SLTW||rt==PT_NTCT||rt==PT_PTCT||rt==PT_INWR) && parts[ID(r)].life==0)
|
||||
{
|
||||
parts[ID(r)].life = 4;
|
||||
parts[ID(r)].ctype = rt;
|
||||
|
@ -52,6 +52,8 @@ void Element::Element_ELEC()
|
||||
|
||||
static int update(UPDATE_FUNC_ARGS)
|
||||
{
|
||||
auto &sd = SimulationData::CRef();
|
||||
auto &elements = sd.elements;
|
||||
for (auto rx = -2; rx <= 2; rx++)
|
||||
{
|
||||
for (auto ry = -2; ry <= 2; ry++)
|
||||
@ -118,7 +120,7 @@ static int update(UPDATE_FUNC_ARGS)
|
||||
case PT_NONE: //seems to speed up ELEC even if it isn't used
|
||||
break;
|
||||
default:
|
||||
if ((sim->elements[rt].Properties & PROP_CONDUCTS) && (rt!=PT_NBLE||parts[i].temp<2273.15))
|
||||
if ((elements[rt].Properties & PROP_CONDUCTS) && (rt!=PT_NBLE||parts[i].temp<2273.15))
|
||||
{
|
||||
sim->create_part(-1, x+rx, y+ry, PT_SPRK);
|
||||
sim->kill_part(i);
|
||||
|
@ -52,6 +52,8 @@ void Element::Element_EMBR()
|
||||
|
||||
static int update(UPDATE_FUNC_ARGS)
|
||||
{
|
||||
auto &sd = SimulationData::CRef();
|
||||
auto &elements = sd.elements;
|
||||
for (auto rx = -1; rx <= 1; rx++)
|
||||
{
|
||||
for (auto ry = -1; ry <= 1; ry++)
|
||||
@ -61,7 +63,7 @@ static int update(UPDATE_FUNC_ARGS)
|
||||
auto r = pmap[y+ry][x+rx];
|
||||
if (!r)
|
||||
continue;
|
||||
if ((sim->elements[TYP(r)].Properties & (TYPE_SOLID | TYPE_PART | TYPE_LIQUID)) && !(sim->elements[TYP(r)].Properties & PROP_SPARKSETTLE))
|
||||
if ((elements[TYP(r)].Properties & (TYPE_SOLID | TYPE_PART | TYPE_LIQUID)) && !(elements[TYP(r)].Properties & PROP_SPARKSETTLE))
|
||||
{
|
||||
sim->kill_part(i);
|
||||
return 1;
|
||||
@ -98,9 +100,9 @@ static int graphics(GRAPHICS_FUNC_ARGS)
|
||||
}
|
||||
|
||||
bool deco = false;
|
||||
if (ren->decorations_enable && cpart->dcolour && (cpart->dcolour&0xFF000000))
|
||||
if (gfctx.ren->decorations_enable && cpart->dcolour && (cpart->dcolour&0xFF000000))
|
||||
{
|
||||
if (!ren->blackDecorations) // if blackDecorations is off, always show deco
|
||||
if (!gfctx.ren->blackDecorations) // if blackDecorations is off, always show deco
|
||||
deco = true;
|
||||
else if (((cpart->dcolour>>24)&0xFF) >= 250 && ((cpart->dcolour>>16)&0xFF) <= 5 && ((cpart->dcolour>>8)&0xFF) <= 5 && ((cpart->dcolour)&0xFF) <= 5) // else only render black deco
|
||||
deco = true;
|
||||
|
4
src/simulation/elements/EMP.h
Normal file
4
src/simulation/elements/EMP.h
Normal file
@ -0,0 +1,4 @@
|
||||
#pragma once
|
||||
#include "simulation/ElementDefs.h"
|
||||
|
||||
void Element_EMP_Trigger(Simulation *sim, int triggerCount);
|
4
src/simulation/elements/ETRD.h
Normal file
4
src/simulation/elements/ETRD.h
Normal file
@ -0,0 +1,4 @@
|
||||
#pragma once
|
||||
#include "simulation/ElementDefs.h"
|
||||
|
||||
int Element_ETRD_nearestSparkablePart(Simulation *sim, int targetId);
|
@ -196,7 +196,7 @@ static int graphics(GRAPHICS_FUNC_ARGS)
|
||||
auto c = cpart->tmp2;
|
||||
if (cpart->life < 1001)
|
||||
{
|
||||
if (ren->rng.chance(cpart->tmp2 - 1, 1000))
|
||||
if (gfctx.rng.chance(cpart->tmp2 - 1, 1000))
|
||||
{
|
||||
float frequency = 0.04045f;
|
||||
*colr = int(sin(frequency*c + 4) * 127 + 150);
|
||||
|
@ -1,15 +1,10 @@
|
||||
#include "simulation/ElementCommon.h"
|
||||
#include "STKM.h"
|
||||
|
||||
static int update(UPDATE_FUNC_ARGS);
|
||||
static bool createAllowed(ELEMENT_CREATE_ALLOWED_FUNC_ARGS);
|
||||
static void changeType(ELEMENT_CHANGETYPE_FUNC_ARGS);
|
||||
static void Free(Simulation *sim, unsigned char i);
|
||||
bool Element_FIGH_CanAlloc(Simulation *sim);
|
||||
int Element_FIGH_Alloc(Simulation *sim);
|
||||
void Element_FIGH_NewFighter(Simulation *sim, int fighterID, int i, int elem);
|
||||
int Element_STKM_graphics(GRAPHICS_FUNC_ARGS);
|
||||
void Element_STKM_init_legs(Simulation * sim, playerst *playerp, int i);
|
||||
int Element_STKM_run_stickman(playerst *playerp, UPDATE_FUNC_ARGS);
|
||||
|
||||
void Element::Element_FIGH()
|
||||
{
|
||||
@ -64,6 +59,8 @@ void Element::Element_FIGH()
|
||||
|
||||
static int update(UPDATE_FUNC_ARGS)
|
||||
{
|
||||
auto &sd = SimulationData::CRef();
|
||||
auto &elements = sd.elements;
|
||||
if (parts[i].tmp < 0 || parts[i].tmp >= MAX_FIGHTERS)
|
||||
{
|
||||
sim->kill_part(i);
|
||||
@ -104,8 +101,8 @@ static int update(UPDATE_FUNC_ARGS)
|
||||
if ((pow(float(tarx-x), 2) + pow(float(tary-y), 2))<600)
|
||||
{
|
||||
if (figh->elem == PT_LIGH || figh->elem == PT_NEUT
|
||||
|| sim->elements[figh->elem].Properties & (PROP_DEADLY | PROP_RADIOACTIVE)
|
||||
|| sim->elements[figh->elem].DefaultProperties.temp >= 323 || sim->elements[figh->elem].DefaultProperties.temp <= 243)
|
||||
|| elements[figh->elem].Properties & (PROP_DEADLY | PROP_RADIOACTIVE)
|
||||
|| elements[figh->elem].DefaultProperties.temp >= 323 || elements[figh->elem].DefaultProperties.temp <= 243)
|
||||
figh->comm = (int)figh->comm | 0x08;
|
||||
}
|
||||
else if (tarx<x)
|
||||
|
@ -1,9 +1,8 @@
|
||||
#include "simulation/ElementCommon.h"
|
||||
#include "FILT.h"
|
||||
|
||||
static int graphics(GRAPHICS_FUNC_ARGS);
|
||||
static void create(ELEMENT_CREATE_FUNC_ARGS);
|
||||
int Element_FILT_interactWavelengths(Simulation *sim, Particle* cpart, int origWl);
|
||||
int Element_FILT_getWavelengths(Particle* cpart);
|
||||
|
||||
void Element::Element_FILT()
|
||||
{
|
||||
@ -135,7 +134,7 @@ int Element_FILT_interactWavelengths(Simulation *sim, Particle* cpart, int origW
|
||||
}
|
||||
}
|
||||
|
||||
int Element_FILT_getWavelengths(Particle* cpart)
|
||||
int Element_FILT_getWavelengths(const Particle* cpart)
|
||||
{
|
||||
if (cpart->ctype&0x3FFFFFFF)
|
||||
{
|
||||
|
5
src/simulation/elements/FILT.h
Normal file
5
src/simulation/elements/FILT.h
Normal file
@ -0,0 +1,5 @@
|
||||
#pragma once
|
||||
#include "simulation/ElementDefs.h"
|
||||
|
||||
int Element_FILT_getWavelengths(const Particle* cpart);
|
||||
int Element_FILT_interactWavelengths(Simulation *sim, Particle* cpart, int origWl);
|
@ -1,7 +1,7 @@
|
||||
#include "simulation/ElementCommon.h"
|
||||
#include "FIRE.h"
|
||||
#include <algorithm>
|
||||
|
||||
int Element_FIRE_update(UPDATE_FUNC_ARGS);
|
||||
static int updateLegacy(UPDATE_FUNC_ARGS);
|
||||
static int graphics(GRAPHICS_FUNC_ARGS);
|
||||
static void create(ELEMENT_CREATE_FUNC_ARGS);
|
||||
@ -54,6 +54,8 @@ void Element::Element_FIRE()
|
||||
|
||||
int Element_FIRE_update(UPDATE_FUNC_ARGS)
|
||||
{
|
||||
auto &sd = SimulationData::CRef();
|
||||
auto &elements = sd.elements;
|
||||
int t = parts[i].type;
|
||||
switch (t)
|
||||
{
|
||||
@ -131,7 +133,7 @@ int Element_FIRE_update(UPDATE_FUNC_ARGS)
|
||||
}
|
||||
}
|
||||
}
|
||||
else if ((parts[i].ctype == PT_STNE || !parts[i].ctype) && pres >= 30.0f && (parts[i].temp > sim->elements[PT_ROCK].HighTemperature || pres < sim->elements[PT_ROCK].HighPressure)) // Form ROCK with pressure, if it will stay molten or not immediately break
|
||||
else if ((parts[i].ctype == PT_STNE || !parts[i].ctype) && pres >= 30.0f && (parts[i].temp > elements[PT_ROCK].HighTemperature || pres < elements[PT_ROCK].HighPressure)) // Form ROCK with pressure, if it will stay molten or not immediately break
|
||||
{
|
||||
parts[i].tmp2 = sim->rng.between(0, 10); // Provide tmp2 for color noise
|
||||
parts[i].ctype = PT_ROCK;
|
||||
@ -207,7 +209,7 @@ int Element_FIRE_update(UPDATE_FUNC_ARGS)
|
||||
if (parts[i].ctype == PT_QRTZ && rt == PT_LAVA && parts[ID(r)].ctype == PT_CLST)
|
||||
{
|
||||
float pres = std::max(sim->pv[y/CELL][x/CELL]*10.0f, 0.0f);
|
||||
if (parts[i].temp >= pres+sim->elements[PT_CRMC].HighTemperature+50.0f)
|
||||
if (parts[i].temp >= pres+elements[PT_CRMC].HighTemperature+50.0f)
|
||||
{
|
||||
parts[i].ctype = PT_CRMC;
|
||||
parts[ID(r)].ctype = PT_CRMC;
|
||||
@ -224,7 +226,7 @@ int Element_FIRE_update(UPDATE_FUNC_ARGS)
|
||||
case 1:
|
||||
parts[i].ctype = PT_CLST;
|
||||
// avoid creating CRMC.
|
||||
if (parts[i].temp >= sim->elements[PT_PQRT].HighTemperature * 3)
|
||||
if (parts[i].temp >= elements[PT_PQRT].HighTemperature * 3)
|
||||
{
|
||||
parts[i].ctype = PT_PQRT;
|
||||
}
|
||||
@ -246,7 +248,7 @@ int Element_FIRE_update(UPDATE_FUNC_ARGS)
|
||||
}
|
||||
else if (rt == PT_HEAC && parts[i].ctype == PT_HEAC)
|
||||
{
|
||||
if (parts[ID(r)].temp > sim->elements[PT_HEAC].HighTemperature)
|
||||
if (parts[ID(r)].temp > elements[PT_HEAC].HighTemperature)
|
||||
{
|
||||
sim->part_change_type(ID(r), x+rx, y+ry, PT_LAVA);
|
||||
parts[ID(r)].ctype = PT_HEAC;
|
||||
@ -265,18 +267,18 @@ int Element_FIRE_update(UPDATE_FUNC_ARGS)
|
||||
}
|
||||
}
|
||||
|
||||
if ((surround_space || sim->elements[rt].Explosive) &&
|
||||
sim->elements[rt].Flammable && sim->rng.chance(int(sim->elements[rt].Flammable + (sim->pv[(y+ry)/CELL][(x+rx)/CELL] * 10.0f)), 1000) &&
|
||||
if ((surround_space || elements[rt].Explosive) &&
|
||||
elements[rt].Flammable && sim->rng.chance(int(elements[rt].Flammable + (sim->pv[(y+ry)/CELL][(x+rx)/CELL] * 10.0f)), 1000) &&
|
||||
//exceptions, t is the thing causing the spark and rt is what's burning
|
||||
(t != PT_SPRK || (rt != PT_RBDM && rt != PT_LRBD && rt != PT_INSL)) &&
|
||||
(t != PT_PHOT || rt != PT_INSL) &&
|
||||
(rt != PT_SPNG || parts[ID(r)].life == 0))
|
||||
{
|
||||
sim->part_change_type(ID(r), x+rx, y+ry, PT_FIRE);
|
||||
parts[ID(r)].temp = restrict_flt(sim->elements[PT_FIRE].DefaultProperties.temp + (sim->elements[rt].Flammable/2), MIN_TEMP, MAX_TEMP);
|
||||
parts[ID(r)].temp = restrict_flt(elements[PT_FIRE].DefaultProperties.temp + (elements[rt].Flammable/2), MIN_TEMP, MAX_TEMP);
|
||||
parts[ID(r)].life = sim->rng.between(180, 259);
|
||||
parts[ID(r)].tmp = parts[ID(r)].ctype = 0;
|
||||
if (sim->elements[rt].Explosive)
|
||||
if (elements[rt].Explosive)
|
||||
sim->pv[y/CELL][x/CELL] += 0.25f * CFDS;
|
||||
}
|
||||
}
|
||||
@ -289,6 +291,8 @@ int Element_FIRE_update(UPDATE_FUNC_ARGS)
|
||||
|
||||
static int updateLegacy(UPDATE_FUNC_ARGS)
|
||||
{
|
||||
auto &sd = SimulationData::CRef();
|
||||
auto &elements = sd.elements;
|
||||
int t = parts[i].type;
|
||||
for (auto rx = -2; rx <= 2; rx++)
|
||||
{
|
||||
@ -305,10 +309,10 @@ static int updateLegacy(UPDATE_FUNC_ARGS)
|
||||
|
||||
auto lpv = (int)sim->pv[(y+ry)/CELL][(x+rx)/CELL];
|
||||
if (lpv < 1) lpv = 1;
|
||||
if (sim->elements[rt].Meltable &&
|
||||
if (elements[rt].Meltable &&
|
||||
((rt!=PT_RBDM && rt!=PT_LRBD) || t!=PT_SPRK)
|
||||
&& ((t!=PT_FIRE&&t!=PT_PLSM) || (rt!=PT_METL && rt!=PT_IRON && rt!=PT_ETRD && rt!=PT_PSCN && rt!=PT_NSCN && rt!=PT_NTCT && rt!=PT_PTCT && rt!=PT_BMTL && rt!=PT_BRMT && rt!=PT_SALT && rt!=PT_INWR))
|
||||
&& sim->rng.chance(sim->elements[rt].Meltable*lpv, 1000))
|
||||
&& sim->rng.chance(elements[rt].Meltable*lpv, 1000))
|
||||
{
|
||||
if (t!=PT_LAVA || parts[i].life>0)
|
||||
{
|
||||
|
4
src/simulation/elements/FIRE.h
Normal file
4
src/simulation/elements/FIRE.h
Normal file
@ -0,0 +1,4 @@
|
||||
#pragma once
|
||||
#include "simulation/ElementDefs.h"
|
||||
|
||||
int Element_FIRE_update(UPDATE_FUNC_ARGS);
|
@ -49,6 +49,8 @@ void Element::Element_FIRW()
|
||||
|
||||
static int update(UPDATE_FUNC_ARGS)
|
||||
{
|
||||
auto &sd = SimulationData::CRef();
|
||||
auto &elements = sd.elements;
|
||||
if (parts[i].tmp<=0)
|
||||
{
|
||||
for (auto rx = -1; rx <= 1; rx++)
|
||||
@ -64,12 +66,12 @@ static int update(UPDATE_FUNC_ARGS)
|
||||
if (rt==PT_FIRE||rt==PT_PLSM||rt==PT_THDR)
|
||||
{
|
||||
float gx, gy, multiplier;
|
||||
sim->GetGravityField(x, y, sim->elements[PT_FIRW].Gravity, 1.0f, gx, gy);
|
||||
sim->GetGravityField(x, y, elements[PT_FIRW].Gravity, 1.0f, gx, gy);
|
||||
if (gx*gx+gy*gy < 0.001f)
|
||||
{
|
||||
float angle = sim->rng.between(0, 6283) * 0.001f;//(in radians, between 0 and 2*pi)
|
||||
gx += sinf(angle)*sim->elements[PT_FIRW].Gravity*0.5f;
|
||||
gy += cosf(angle)*sim->elements[PT_FIRW].Gravity*0.5f;
|
||||
gx += sinf(angle)*elements[PT_FIRW].Gravity*0.5f;
|
||||
gy += cosf(angle)*elements[PT_FIRW].Gravity*0.5f;
|
||||
}
|
||||
parts[i].tmp = 1;
|
||||
parts[i].life = sim->rng.between(20, 29);
|
||||
|
@ -48,6 +48,8 @@ void Element::Element_FOG()
|
||||
|
||||
static int update(UPDATE_FUNC_ARGS)
|
||||
{
|
||||
auto &sd = SimulationData::CRef();
|
||||
auto &elements = sd.elements;
|
||||
for (auto rx = -1; rx <= 1; rx++)
|
||||
{
|
||||
for (auto ry = -1; ry <= 1; ry++)
|
||||
@ -57,7 +59,7 @@ static int update(UPDATE_FUNC_ARGS)
|
||||
auto r = pmap[y+ry][x+rx];
|
||||
if (!r)
|
||||
continue;
|
||||
if ((sim->elements[TYP(r)].Properties&TYPE_SOLID) && sim->rng.chance(1, 10) && parts[i].life==0 && !(TYP(r)==PT_CLNE || TYP(r)==PT_PCLN)) // TODO: should this also exclude BCLN?
|
||||
if ((elements[TYP(r)].Properties&TYPE_SOLID) && sim->rng.chance(1, 10) && parts[i].life==0 && !(TYP(r)==PT_CLNE || TYP(r)==PT_PCLN)) // TODO: should this also exclude BCLN?
|
||||
{
|
||||
sim->part_change_type(i,x,y,PT_RIME);
|
||||
}
|
||||
|
@ -48,6 +48,8 @@ void Element::Element_FRAY()
|
||||
|
||||
static int update(UPDATE_FUNC_ARGS)
|
||||
{
|
||||
auto &sd = SimulationData::CRef();
|
||||
auto &elements = sd.elements;
|
||||
int curlen;
|
||||
if (parts[i].tmp > 0)
|
||||
curlen = parts[i].tmp;
|
||||
@ -73,7 +75,7 @@ static int update(UPDATE_FUNC_ARGS)
|
||||
r = pmap[y+nyi+nyy][x+nxi+nxx];
|
||||
if (!r)
|
||||
r = sim->photons[y+nyi+nyy][x+nxi+nxx];
|
||||
if (r && !(sim->elements[TYP(r)].Properties & TYPE_SOLID)){
|
||||
if (r && !(elements[TYP(r)].Properties & TYPE_SOLID)){
|
||||
parts[ID(r)].vx += nxi*((parts[i].temp-273.15f)/10.0f);
|
||||
parts[ID(r)].vy += nyi*((parts[i].temp-273.15f)/10.0f);
|
||||
}
|
||||
|
@ -48,16 +48,18 @@ void Element::Element_FWRK()
|
||||
|
||||
static int update(UPDATE_FUNC_ARGS)
|
||||
{
|
||||
auto &sd = SimulationData::CRef();
|
||||
auto &elements = sd.elements;
|
||||
if (parts[i].life == 0 && ((surround_space && parts[i].temp>400 && sim->rng.chance(int(9+parts[i].temp/40), 100000)) || parts[i].ctype == PT_DUST))
|
||||
{
|
||||
float gx, gy, multiplier, gmax;
|
||||
int randTmp;
|
||||
sim->GetGravityField(x, y, sim->elements[PT_FWRK].Gravity, 1.0f, gx, gy);
|
||||
sim->GetGravityField(x, y, elements[PT_FWRK].Gravity, 1.0f, gx, gy);
|
||||
if (gx*gx+gy*gy < 0.001f)
|
||||
{
|
||||
float angle = sim->rng.between(0, 6283) * 0.001f;//(in radians, between 0 and 2*pi)
|
||||
gx += sinf(angle)*sim->elements[PT_FWRK].Gravity*0.5f;
|
||||
gy += cosf(angle)*sim->elements[PT_FWRK].Gravity*0.5f;
|
||||
gx += sinf(angle)*elements[PT_FWRK].Gravity*0.5f;
|
||||
gy += cosf(angle)*elements[PT_FWRK].Gravity*0.5f;
|
||||
}
|
||||
gmax = std::max(fabsf(gx), fabsf(gy));
|
||||
if (sim->eval_move(PT_FWRK, (int)(x-(gx/gmax)+0.5f), (int)(y-(gy/gmax)+0.5f), NULL))
|
||||
|
@ -50,6 +50,8 @@ void Element::Element_GEL()
|
||||
|
||||
static int update(UPDATE_FUNC_ARGS)
|
||||
{
|
||||
auto &sd = SimulationData::CRef();
|
||||
auto &elements = sd.elements;
|
||||
if (parts[i].tmp > 100)
|
||||
parts[i].tmp = 100;
|
||||
if (parts[i].tmp < 0)
|
||||
@ -133,17 +135,17 @@ static int update(UPDATE_FUNC_ARGS)
|
||||
dy = parts[i].y - parts[ID(r)].y;
|
||||
|
||||
//Stickiness
|
||||
if ((dx*dx + dy*dy)>1.5 && (gel || !sim->elements[rt].Falldown || (fabs((float)rx)<2 && fabs((float)ry)<2)))
|
||||
if ((dx*dx + dy*dy)>1.5 && (gel || !elements[rt].Falldown || (fabs((float)rx)<2 && fabs((float)ry)<2)))
|
||||
{
|
||||
float per, nd;
|
||||
nd = dx*dx + dy*dy - 0.5;
|
||||
per = 5*(1 - parts[i].tmp/100)*(nd/(dx*dx + dy*dy + nd) - 0.5);
|
||||
if (sim->elements[rt].Properties&TYPE_LIQUID)
|
||||
if (elements[rt].Properties&TYPE_LIQUID)
|
||||
per *= 0.1f;
|
||||
dx *= per; dy *= per;
|
||||
parts[i].vx += dx;
|
||||
parts[i].vy += dy;
|
||||
if ((sim->elements[rt].Properties&TYPE_PART) || rt==PT_GOO)
|
||||
if ((elements[rt].Properties&TYPE_PART) || rt==PT_GOO)
|
||||
{
|
||||
parts[ID(r)].vx -= dx;
|
||||
parts[ID(r)].vy -= dy;
|
||||
|
@ -90,7 +90,7 @@ static int graphics(GRAPHICS_FUNC_ARGS)
|
||||
*colg = int(restrict_flt(64.0f+cpart->ctype, 0, 255));
|
||||
*colb = int(restrict_flt(64.0f+cpart->tmp, 0, 255));
|
||||
|
||||
int rng = ren->rng.between(1, 32); //
|
||||
int rng = gfctx.rng.between(1, 32); //
|
||||
if(((*colr) + (*colg) + (*colb)) > (256 + rng)) {
|
||||
*colr -= 54;
|
||||
*colg -= 54;
|
||||
|
@ -99,7 +99,7 @@ static int update(UPDATE_FUNC_ARGS)
|
||||
|
||||
static int graphics(GRAPHICS_FUNC_ARGS)
|
||||
{
|
||||
int rndstore = ren->rng.gen();
|
||||
int rndstore = gfctx.rng.gen();
|
||||
*colr += (rndstore % 10) - 5;
|
||||
rndstore >>= 4;
|
||||
*colg += (rndstore % 10)- 5;
|
||||
|
@ -63,12 +63,12 @@ static int graphics(GRAPHICS_FUNC_ARGS)
|
||||
{
|
||||
int GRAV_R, GRAV_B, GRAV_G, GRAV_R2, GRAV_B2, GRAV_G2;
|
||||
|
||||
GRAV_R = std::abs((ren->sim->currentTick%120)-60);
|
||||
GRAV_G = std::abs(((ren->sim->currentTick+60)%120)-60);
|
||||
GRAV_B = std::abs(((ren->sim->currentTick+120)%120)-60);
|
||||
GRAV_R2 = std::abs((ren->sim->currentTick%60)-30);
|
||||
GRAV_G2 = std::abs(((ren->sim->currentTick+30)%60)-30);
|
||||
GRAV_B2 = std::abs(((ren->sim->currentTick+60)%60)-30);
|
||||
GRAV_R = std::abs((gfctx.sim->currentTick%120)-60);
|
||||
GRAV_G = std::abs(((gfctx.sim->currentTick+60)%120)-60);
|
||||
GRAV_B = std::abs(((gfctx.sim->currentTick+120)%120)-60);
|
||||
GRAV_R2 = std::abs((gfctx.sim->currentTick%60)-30);
|
||||
GRAV_G2 = std::abs(((gfctx.sim->currentTick+30)%60)-30);
|
||||
GRAV_B2 = std::abs(((gfctx.sim->currentTick+60)%60)-30);
|
||||
|
||||
|
||||
*colr = 20;
|
||||
|
@ -47,6 +47,8 @@ void Element::Element_H2()
|
||||
|
||||
static int update(UPDATE_FUNC_ARGS)
|
||||
{
|
||||
auto &sd = SimulationData::CRef();
|
||||
auto &can_move = sd.can_move;
|
||||
for (auto rx = -2; rx <= 2; rx++)
|
||||
{
|
||||
for (auto ry = -2; ry <= 2; ry++)
|
||||
@ -119,7 +121,7 @@ static int update(UPDATE_FUNC_ARGS)
|
||||
parts[j].tmp = 0x1;
|
||||
}
|
||||
auto rx = x + sim->rng.between(-1, 1), ry = y + sim->rng.between(-1, 1), rt = TYP(pmap[ry][rx]);
|
||||
if (sim->can_move[PT_PLSM][rt] || rt == PT_H2)
|
||||
if (can_move[PT_PLSM][rt] || rt == PT_H2)
|
||||
{
|
||||
j = sim->create_part(-3,rx,ry,PT_PLSM);
|
||||
if (j>-1)
|
||||
|
@ -48,7 +48,8 @@ void Element::Element_HEAC()
|
||||
}
|
||||
|
||||
static const auto isInsulator = [](Simulation* a, int b) -> bool {
|
||||
return b && (a->elements[TYP(b)].HeatConduct == 0 || (TYP(b) == PT_HSWC && a->parts[ID(b)].life != 10));
|
||||
auto &sd = SimulationData::CRef();
|
||||
return b && (sd.elements[TYP(b)].HeatConduct == 0 || (TYP(b) == PT_HSWC && a->parts[ID(b)].life != 10));
|
||||
};
|
||||
|
||||
// If this is used elsewhere (GOLD), it should be moved into Simulation.h
|
||||
@ -118,6 +119,8 @@ bool CheckLine(Simulation* sim, int x1, int y1, int x2, int y2, BinaryPredicate
|
||||
|
||||
static int update(UPDATE_FUNC_ARGS)
|
||||
{
|
||||
auto &sd = SimulationData::CRef();
|
||||
auto &elements = sd.elements;
|
||||
const int rad = 4;
|
||||
int rry, rrx, r, count = 0;
|
||||
float tempAgg = 0;
|
||||
@ -130,13 +133,13 @@ static int update(UPDATE_FUNC_ARGS)
|
||||
if (x+rrx >= 0 && x+rrx < XRES && y+rry >= 0 && y+rry < YRES && !CheckLine(sim, x, y, x+rrx, y+rry, isInsulator))
|
||||
{
|
||||
r = pmap[y+rry][x+rrx];
|
||||
if (r && sim->elements[TYP(r)].HeatConduct > 0 && (TYP(r) != PT_HSWC || parts[ID(r)].life == 10))
|
||||
if (r && elements[TYP(r)].HeatConduct > 0 && (TYP(r) != PT_HSWC || parts[ID(r)].life == 10))
|
||||
{
|
||||
count++;
|
||||
tempAgg += parts[ID(r)].temp;
|
||||
}
|
||||
r = sim->photons[y+rry][x+rrx];
|
||||
if (r && sim->elements[TYP(r)].HeatConduct > 0 && (TYP(r) != PT_HSWC || parts[ID(r)].life == 10))
|
||||
if (r && elements[TYP(r)].HeatConduct > 0 && (TYP(r) != PT_HSWC || parts[ID(r)].life == 10))
|
||||
{
|
||||
count++;
|
||||
tempAgg += parts[ID(r)].temp;
|
||||
@ -158,12 +161,12 @@ static int update(UPDATE_FUNC_ARGS)
|
||||
if (x+rrx >= 0 && x+rrx < XRES && y+rry >= 0 && y+rry < YRES && !CheckLine(sim, x, y, x+rrx, y+rry, isInsulator))
|
||||
{
|
||||
r = pmap[y+rry][x+rrx];
|
||||
if (r && sim->elements[TYP(r)].HeatConduct > 0 && (TYP(r) != PT_HSWC || parts[ID(r)].life == 10))
|
||||
if (r && elements[TYP(r)].HeatConduct > 0 && (TYP(r) != PT_HSWC || parts[ID(r)].life == 10))
|
||||
{
|
||||
parts[ID(r)].temp = parts[i].temp;
|
||||
}
|
||||
r = sim->photons[y+rry][x+rrx];
|
||||
if (r && sim->elements[TYP(r)].HeatConduct > 0 && (TYP(r) != PT_HSWC || parts[ID(r)].life == 10))
|
||||
if (r && elements[TYP(r)].HeatConduct > 0 && (TYP(r) != PT_HSWC || parts[ID(r)].life == 10))
|
||||
{
|
||||
parts[ID(r)].temp = parts[i].temp;
|
||||
}
|
||||
|
@ -30,6 +30,7 @@ void Element::Element_ICEI()
|
||||
|
||||
DefaultProperties.temp = R_TEMP - 50.0f + 273.15f;
|
||||
HeatConduct = 46;
|
||||
LatentHeat = 1095;
|
||||
Description = "Crushes under pressure. Cools down air.";
|
||||
|
||||
Properties = TYPE_SOLID|PROP_LIFE_DEC|PROP_NEUTPASS;
|
||||
@ -50,6 +51,8 @@ void Element::Element_ICEI()
|
||||
|
||||
static int update(UPDATE_FUNC_ARGS)
|
||||
{
|
||||
auto &sd = SimulationData::CRef();
|
||||
auto &elements = sd.elements;
|
||||
if (parts[i].ctype==PT_FRZW)//get colder if it is from FRZW
|
||||
{
|
||||
parts[i].temp = restrict_flt(parts[i].temp-1.0f, MIN_TEMP, MAX_TEMP);
|
||||
@ -65,7 +68,7 @@ static int update(UPDATE_FUNC_ARGS)
|
||||
continue;
|
||||
if (TYP(r)==PT_SALT || TYP(r)==PT_SLTW)
|
||||
{
|
||||
if (parts[i].temp > sim->elements[PT_SLTW].LowTemperature && sim->rng.chance(1, 200))
|
||||
if (parts[i].temp > elements[PT_SLTW].LowTemperature && sim->rng.chance(1, 200))
|
||||
{
|
||||
sim->part_change_type(i,x,y,PT_SLTW);
|
||||
sim->part_change_type(ID(r),x+rx,y+ry,PT_SLTW);
|
||||
|
@ -1,6 +1,6 @@
|
||||
#include "simulation/ElementCommon.h"
|
||||
#include "FIRE.h"
|
||||
|
||||
int Element_FIRE_update(UPDATE_FUNC_ARGS);
|
||||
static int graphics(GRAPHICS_FUNC_ARGS);
|
||||
static void create(ELEMENT_CREATE_FUNC_ARGS);
|
||||
|
||||
|
@ -107,9 +107,9 @@ static int update(UPDATE_FUNC_ARGS)
|
||||
static int graphics(GRAPHICS_FUNC_ARGS)
|
||||
{
|
||||
bool deco = false;
|
||||
if (ren->decorations_enable && cpart->dcolour && (cpart->dcolour&0xFF000000))
|
||||
if (gfctx.ren->decorations_enable && cpart->dcolour && (cpart->dcolour&0xFF000000))
|
||||
{
|
||||
if (!ren->blackDecorations) // if blackDecorations is off, always show deco
|
||||
if (!gfctx.ren->blackDecorations) // if blackDecorations is off, always show deco
|
||||
deco = true;
|
||||
else if(((cpart->dcolour>>24)&0xFF) >= 250 && ((cpart->dcolour>>16)&0xFF) <= 5 && ((cpart->dcolour>>8)&0xFF) <= 5 && ((cpart->dcolour)&0xFF) <= 5) // else only render black deco
|
||||
deco = true;
|
||||
|
@ -1,5 +1,5 @@
|
||||
#include "simulation/ElementCommon.h"
|
||||
#include <iostream>
|
||||
#include "FILT.h"
|
||||
|
||||
static int update(UPDATE_FUNC_ARGS);
|
||||
|
||||
@ -74,8 +74,10 @@ static bool phot_data_type(int rt)
|
||||
*/
|
||||
static bool accepted_conductor(Simulation* sim, int r)
|
||||
{
|
||||
auto &sd = SimulationData::CRef();
|
||||
auto &elements = sd.elements;
|
||||
int rt = TYP(r);
|
||||
return (sim->elements[rt].Properties & PROP_CONDUCTS) &&
|
||||
return (elements[rt].Properties & PROP_CONDUCTS) &&
|
||||
!(rt == PT_WATR || rt == PT_SLTW || rt == PT_NTCT ||
|
||||
rt == PT_PTCT || rt == PT_INWR) &&
|
||||
sim->parts[ID(r)].life == 0;
|
||||
@ -149,7 +151,6 @@ static int update(UPDATE_FUNC_ARGS)
|
||||
continue;
|
||||
|
||||
int nx = x + rx, ny = y + ry;
|
||||
int Element_FILT_getWavelengths(Particle* cpart);
|
||||
int photonWl = TYP(rr) == PT_FILT ?
|
||||
Element_FILT_getWavelengths(&parts[ID(rr)]) :
|
||||
parts[ID(rr)].ctype;
|
||||
|
@ -50,6 +50,7 @@ void Element::Element_LIFE()
|
||||
|
||||
static int graphics(GRAPHICS_FUNC_ARGS)
|
||||
{
|
||||
auto &builtinGol = SimulationData::builtinGol;
|
||||
auto colour1 = RGB<uint8_t>::Unpack(cpart->dcolour);
|
||||
auto colour2 = RGB<uint8_t>::Unpack(cpart->tmp);
|
||||
if (!cpart->dcolour)
|
||||
@ -57,10 +58,10 @@ static int graphics(GRAPHICS_FUNC_ARGS)
|
||||
colour1 = 0xFFFFFF_rgb;
|
||||
}
|
||||
auto ruleset = cpart->ctype;
|
||||
bool renderDeco = !ren->blackDecorations;
|
||||
bool renderDeco = !gfctx.ren->blackDecorations;
|
||||
if (ruleset >= 0 && ruleset < NGOL)
|
||||
{
|
||||
if (!renderDeco || !ren->decorations_enable)
|
||||
if (!renderDeco || !gfctx.ren->decorations_enable)
|
||||
{
|
||||
colour1 = builtinGol[ruleset].colour;
|
||||
colour2 = builtinGol[ruleset].colour2;
|
||||
@ -91,6 +92,8 @@ static int graphics(GRAPHICS_FUNC_ARGS)
|
||||
|
||||
static void create(ELEMENT_CREATE_FUNC_ARGS)
|
||||
{
|
||||
auto &sd = SimulationData::CRef();
|
||||
auto &builtinGol = sd.builtinGol;
|
||||
if (v == -1)
|
||||
v = 0;
|
||||
// * 0x200000: No need to look for colours, they'll be set later anyway.
|
||||
@ -105,7 +108,7 @@ static void create(ELEMENT_CREATE_FUNC_ARGS)
|
||||
}
|
||||
else if (!skipLookup)
|
||||
{
|
||||
auto *cgol = sim->GetCustomGOLByRule(v);
|
||||
auto *cgol = sd.GetCustomGOLByRule(v);
|
||||
if (cgol)
|
||||
{
|
||||
sim->parts[i].dcolour = cgol->colour1;
|
||||
|
@ -79,6 +79,8 @@ static int update(UPDATE_FUNC_ARGS)
|
||||
sim->hv[y/CELL][x/CELL] = MAX_TEMP;
|
||||
}
|
||||
|
||||
auto &sd = SimulationData::CRef();
|
||||
auto &elements = sd.elements;
|
||||
for (auto rx = -2; rx <= 2; rx++)
|
||||
{
|
||||
for (auto ry = -2; ry <= 2; ry++)
|
||||
@ -89,15 +91,15 @@ static int update(UPDATE_FUNC_ARGS)
|
||||
if (!r)
|
||||
continue;
|
||||
auto rt = TYP(r);
|
||||
if ((surround_space || sim->elements[rt].Explosive) &&
|
||||
if ((surround_space || elements[rt].Explosive) &&
|
||||
(rt!=PT_SPNG || parts[ID(r)].life==0) &&
|
||||
sim->elements[rt].Flammable && sim->rng.chance(sim->elements[rt].Flammable + int(sim->pv[(y+ry)/CELL][(x+rx)/CELL] * 10.0f), 1000))
|
||||
elements[rt].Flammable && sim->rng.chance(elements[rt].Flammable + int(sim->pv[(y+ry)/CELL][(x+rx)/CELL] * 10.0f), 1000))
|
||||
{
|
||||
sim->part_change_type(ID(r),x+rx,y+ry,PT_FIRE);
|
||||
parts[ID(r)].temp = restrict_flt(sim->elements[PT_FIRE].DefaultProperties.temp + (sim->elements[rt].Flammable/2), MIN_TEMP, MAX_TEMP);
|
||||
parts[ID(r)].temp = restrict_flt(elements[PT_FIRE].DefaultProperties.temp + (elements[rt].Flammable/2), MIN_TEMP, MAX_TEMP);
|
||||
parts[ID(r)].life = sim->rng.between(180, 259);
|
||||
parts[ID(r)].tmp = parts[ID(r)].ctype = 0;
|
||||
if (sim->elements[rt].Explosive)
|
||||
if (elements[rt].Explosive)
|
||||
sim->pv[y/CELL][x/CELL] += 0.25f * CFDS;
|
||||
}
|
||||
switch (rt)
|
||||
@ -138,7 +140,7 @@ static int update(UPDATE_FUNC_ARGS)
|
||||
break;
|
||||
case PT_HEAC:
|
||||
parts[ID(r)].temp = restrict_flt(parts[ID(r)].temp+powderful/10, MIN_TEMP, MAX_TEMP);
|
||||
if (parts[ID(r)].temp > sim->elements[PT_HEAC].HighTemperature)
|
||||
if (parts[ID(r)].temp > elements[PT_HEAC].HighTemperature)
|
||||
{
|
||||
sim->part_change_type(ID(r), x+rx, y+ry, PT_LAVA);
|
||||
parts[ID(r)].ctype = PT_HEAC;
|
||||
@ -147,10 +149,10 @@ static int update(UPDATE_FUNC_ARGS)
|
||||
default:
|
||||
break;
|
||||
}
|
||||
if ((sim->elements[TYP(r)].Properties&PROP_CONDUCTS) && parts[ID(r)].life==0)
|
||||
if ((elements[TYP(r)].Properties&PROP_CONDUCTS) && parts[ID(r)].life==0)
|
||||
sim->create_part(ID(r),x+rx,y+ry,PT_SPRK);
|
||||
sim->pv[y/CELL][x/CELL] += powderful/400;
|
||||
if (sim->elements[TYP(r)].HeatConduct) parts[ID(r)].temp = restrict_flt(parts[ID(r)].temp+powderful/1.3, MIN_TEMP, MAX_TEMP);
|
||||
if (elements[TYP(r)].HeatConduct) parts[ID(r)].temp = restrict_flt(parts[ID(r)].temp+powderful/1.3, MIN_TEMP, MAX_TEMP);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -257,7 +257,7 @@ static int graphics(GRAPHICS_FUNC_ARGS)
|
||||
// Charged lith
|
||||
else if (cpart->ctype > 0)
|
||||
{
|
||||
int mult = ren->rng.between(cpart->ctype / 3, cpart->ctype) / 15;
|
||||
int mult = gfctx.rng.between(cpart->ctype / 3, cpart->ctype) / 15;
|
||||
mult = std::min(6, mult);
|
||||
*colr -= 30 * mult;
|
||||
*colb += 20 * mult;
|
||||
|
7
src/simulation/elements/LOLZ.h
Normal file
7
src/simulation/elements/LOLZ.h
Normal file
@ -0,0 +1,7 @@
|
||||
#pragma once
|
||||
#include "simulation/ElementDefs.h"
|
||||
|
||||
extern int Element_LOLZ_RuleTable[9][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];
|
@ -50,6 +50,8 @@ void Element::Element_LSNS()
|
||||
|
||||
static int update(UPDATE_FUNC_ARGS)
|
||||
{
|
||||
auto &sd = SimulationData::CRef();
|
||||
auto &elements = sd.elements;
|
||||
int rd = parts[i].tmp2;
|
||||
if (rd > 25) parts[i].tmp2 = rd = 25;
|
||||
if (parts[i].life)
|
||||
@ -69,7 +71,7 @@ static int update(UPDATE_FUNC_ARGS)
|
||||
int rt = TYP(r);
|
||||
if (sim->parts_avg(i, ID(r), PT_INSL) != PT_INSL)
|
||||
{
|
||||
if ((sim->elements[rt].Properties&PROP_CONDUCTS) && !(rt == PT_WATR || rt == PT_SLTW || rt == PT_NTCT || rt == PT_PTCT || rt == PT_INWR) && parts[ID(r)].life == 0)
|
||||
if ((elements[rt].Properties&PROP_CONDUCTS) && !(rt == PT_WATR || rt == PT_SLTW || rt == PT_NTCT || rt == PT_PTCT || rt == PT_INWR) && parts[ID(r)].life == 0)
|
||||
{
|
||||
parts[ID(r)].life = 4;
|
||||
parts[ID(r)].ctype = rt;
|
||||
|
@ -27,6 +27,7 @@ void Element::Element_METL()
|
||||
Weight = 100;
|
||||
|
||||
HeatConduct = 251;
|
||||
LatentHeat = 919;
|
||||
Description = "The basic conductor. Meltable.";
|
||||
|
||||
Properties = TYPE_SOLID|PROP_CONDUCTS|PROP_LIFE_DEC|PROP_HOT_GLOW;
|
||||
|
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user