This repository has been archived on 2025-03-20. You can view files and clone it, but cannot push or open issues or pull requests.
The-Powder-Toy/src/simulation/GOLString.cpp
jacob1 44590d82e9
Add a few more Lua functions
sim.replaceModeFlags
sim.listCustomGol
sim.addCustomGol
sim.removeCustomGol
tpt.perfectCircleBrush
sim.floodDeco
2021-08-27 23:57:55 -04:00

124 lines
2.4 KiB
C++

#include "GOLString.h"
#include "client/Client.h"
int ParseGOLString(const String &value)
{
// * Most likely a GOL string.
auto it = value.begin() + 1;
auto begin = 0U;
auto stay = 0U;
auto states = 2U;
// Scan 'B' section, must be between 1 and 8
for (; it != value.end() && it[0] >= '1' && it[0] <= '8'; ++it)
{
begin |= 1U << (it[0] - '0');
}
if (!begin)
{
return -1;
}
// Must have a /S immediately afterwards
if (it < value.end() - 1 && it[0] == '/' && it[1] == 'S')
{
it += 2;
}
else
{
return -1;
}
// Scan 'S' section, must be between 0 and 8
for (; it != value.end() && it[0] >= '0' && it[0] <= '8'; ++it)
{
stay |= 1U << (it[0] - '0');
}
// Optionally can have a 3rd section, with the number of frames to remain after dying
if (it != value.end())
{
if (it[0] == '/')
{
it += 1;
}
else
{
return -1;
}
states = String(it, value.end()).ToNumber<unsigned int>(true);
if (states < 2 || states > 17)
{
return -1;
}
}
return stay | (begin << 8) | ((states - 2) << 17);
}
bool ValidateGOLName(const String &value)
{
bool nameOk = true;
for (auto ch : value)
{
if (!((ch >= '0' && ch < '9') || (ch >= 'A' && ch <= 'Z') || (ch >= 'a' && ch <= 'z') || (ch == '-')))
{
nameOk = false;
}
}
return nameOk;
}
String SerialiseGOLRule(int rule)
{
StringBuilder golName;
golName << "B";
for (int i = 1; i < 9; ++i)
{
if ((rule >> (i + 8)) & 1)
{
golName << char('0' + i);
}
}
golName << "/S";
for (int i = 0; i < 9; ++i)
{
if ((rule >> i) & 1)
{
golName << char('0' + i);
}
}
if ((rule >> 17) & 0xF)
{
golName << "/" << ((rule >> 17) & 0xF) + 2;
}
return golName.Build();
}
bool AddCustomGol(String ruleString, String nameString, unsigned int highColor, unsigned int lowColor)
{
auto customGOLTypes = Client::Ref().GetPrefByteStringArray("CustomGOL.Types");
Json::Value newCustomGOLTypes(Json::arrayValue);
bool nameTaken = false;
for (auto gol : customGOLTypes)
{
auto parts = gol.FromUtf8().PartitionBy(' ');
if (parts.size())
{
if (parts[0] == nameString)
{
nameTaken = true;
}
}
newCustomGOLTypes.append(gol);
}
if (nameTaken)
return false;
StringBuilder sb;
sb << nameString << " " << ruleString << " " << highColor << " " << lowColor;
newCustomGOLTypes.append(sb.Build().ToUtf8());
Client::Ref().SetPref("CustomGOL.Types", newCustomGOLTypes);
return true;
}