Merge branch 'main' of https://github.com/R74nCom/sandboxels
This commit is contained in:
commit
ae0c0d4687
|
|
@ -0,0 +1,291 @@
|
|||
const settingType = {
|
||||
COLOR: [0, "#ff0000"],
|
||||
TEXT: [1, ""],
|
||||
NUMBER: [2, 0],
|
||||
BOOLEAN: [3, false],
|
||||
SELECT: [4, null]
|
||||
}
|
||||
class Setting {
|
||||
constructor (name, storageName, type, disabled = false, defaultValue = null) {
|
||||
this.tabName = null;
|
||||
this.name = name;
|
||||
this.storageName = storageName;
|
||||
this.type = type[0];
|
||||
this.disabled = disabled;
|
||||
this.defaultValue = defaultValue ?? type[1];
|
||||
}
|
||||
|
||||
set(value) {
|
||||
this.value = value;
|
||||
const settings = JSON.parse(localStorage.getItem(`${this.tabName}/settings`)) ?? {};
|
||||
settings[this.name] = value;
|
||||
localStorage.setItem(`${this.tabName}/settings`, JSON.stringify(settings));
|
||||
}
|
||||
|
||||
update() {
|
||||
this.value = (JSON.parse(localStorage.getItem(`${this.tabName}/settings`)) ?? {})[this.name] ?? this.defaultValue;
|
||||
}
|
||||
|
||||
get() {
|
||||
this.update();
|
||||
return this.value;
|
||||
}
|
||||
|
||||
enable() {
|
||||
this.disabled = false;
|
||||
}
|
||||
|
||||
disable() {
|
||||
this.disabled = true;
|
||||
}
|
||||
|
||||
#parseColor(colorString) {
|
||||
if (colorString instanceof Array) return parseColor(colorString[0]);
|
||||
if (typeof colorString != "string") return "#ffffff";
|
||||
if (colorString.startsWith("rgb(")) {
|
||||
const color = colorString.replace("rgb(", "").replace(")", "");
|
||||
return `#${color.split(",").map(a => parseInt(a).toString(16)).join("")}`;
|
||||
} else {
|
||||
if (colorString.startsWith("#")) {
|
||||
const color = colorString.slice(1);
|
||||
if (color.length == 3) return `#${color.repeat(2)}`;
|
||||
else if (color.length == 2) return `#${color.repeat(3)}`;
|
||||
else if (color.length >= 6) return `#${color.slice(0, 6)}`;
|
||||
else return `#${color}`;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
build() {
|
||||
const value = this.get();
|
||||
const id = "betterSettings/" + this.modName + "/" + this.storageName;
|
||||
const span = document.createElement("span");
|
||||
span.className = "setting-span";
|
||||
span.title = 'Default: "' + this.defaultValue + '"' + (this.disabled ? ". This setting is disabled." : "");
|
||||
span.innerText = this.name + " ";
|
||||
const element = document.createElement("input");
|
||||
switch (this.type) {
|
||||
case 0: {
|
||||
element.type = "color";
|
||||
element.disabled = this.disabled;
|
||||
element.id = id;
|
||||
element.value = value;
|
||||
element.onchange = (ev) => {
|
||||
this.set(this.#parseColor(ev.target.value));
|
||||
}
|
||||
break;
|
||||
}
|
||||
case 1: {
|
||||
element.type = "text";
|
||||
element.disabled = this.disabled;
|
||||
element.id = id;
|
||||
element.value = value;
|
||||
element.onchange = (ev) => {
|
||||
this.set(ev.target.value);
|
||||
}
|
||||
break;
|
||||
}
|
||||
case 2: {
|
||||
element.type = "number";
|
||||
element.disabled = this.disabled;
|
||||
element.id = id;
|
||||
element.value = value;
|
||||
element.onchange = (ev) => {
|
||||
this.set(parseFloat(ev.target.value));
|
||||
}
|
||||
break;
|
||||
}
|
||||
case 3: {
|
||||
element.type = "input";
|
||||
element.className = "toggleInput";
|
||||
element.disabled = this.disabled;
|
||||
element.id = id;
|
||||
element.value = value ? "ON" : "OFF";
|
||||
element.setAttribute("state", value ? "1" : "0");
|
||||
element.onclick = (ev) => {
|
||||
ev.target.value = ev.target.value == "ON" ? "OFF" : "ON";
|
||||
ev.target.setAttribute("state", ev.target.getAttribute("state") == "1" ? "0" : "1");
|
||||
this.set(ev.target.value == "ON");
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
span.appendChild(element);
|
||||
return span;
|
||||
}
|
||||
}
|
||||
|
||||
class SelectSetting extends Setting {
|
||||
constructor (name, storageName, values, disabled = false, defaultValue = null) {
|
||||
super(name, storageName, settingType.SELECT, disabled, defaultValue ?? values[0][1]);
|
||||
this.values = values;
|
||||
}
|
||||
|
||||
build() {
|
||||
const value = this.get();
|
||||
const id = "betterSettings/" + this.modName + "/" + this.storageName;
|
||||
let selected = false;
|
||||
const span = document.createElement("span");
|
||||
span.className = "setting-span";
|
||||
span.title = "Default: " + this.defaultValue;
|
||||
span.innerText = this.name;
|
||||
const element = document.createElement("select");
|
||||
element.id = id;
|
||||
for (const val of this.values) {
|
||||
const option = document.createElement("option");
|
||||
option.value = val[0];
|
||||
option.innerText = val[1];
|
||||
if (val[0] == value && !selected) {
|
||||
option.selected = true;
|
||||
selected = true;
|
||||
}
|
||||
element.appendChild(option);
|
||||
}
|
||||
element.onchange = (ev) => {
|
||||
this.set(ev.target.value);
|
||||
}
|
||||
span.appendChild(element);
|
||||
return span;
|
||||
}
|
||||
}
|
||||
|
||||
class SettingsTab {
|
||||
constructor (tabName) {
|
||||
this.categories = new Map();
|
||||
this.registry = new Map();
|
||||
this.tabName = tabName;
|
||||
}
|
||||
|
||||
registerSetting(setting, category = "General") {
|
||||
setting.tabName = this.tabName.toLowerCase().replace(/ /, "_");
|
||||
setting.update();
|
||||
if (this.categories.has(category)) this.categories.get(category).push(setting);
|
||||
else this.categories.set(category, [setting]);
|
||||
this.registry.set(setting.storageName, setting);
|
||||
}
|
||||
|
||||
registerSettings(category = "General", ...settings) {
|
||||
for (const setting of settings) {
|
||||
this.registerSetting(setting, category);
|
||||
}
|
||||
}
|
||||
|
||||
set(name, value) {
|
||||
this.registry.get(name)?.set(value);
|
||||
}
|
||||
|
||||
get(name) {
|
||||
return this.registry.get(name)?.get();
|
||||
}
|
||||
|
||||
build() {
|
||||
const result = document.createElement("div");
|
||||
for (const key of this.categories.keys()) {
|
||||
const category = document.createElement("div");
|
||||
const title = document.createElement("span");
|
||||
title.innerText = key;
|
||||
title.className = "betterSettings-categoryTitle";
|
||||
category.appendChild(title);
|
||||
for (const setting of this.categories.get(key)) {
|
||||
if (setting instanceof Setting) category.appendChild(setting.build());
|
||||
}
|
||||
result.append(category, document.createElement("br"));
|
||||
}
|
||||
return result;
|
||||
}
|
||||
}
|
||||
|
||||
class SettingsManager {
|
||||
constructor () {
|
||||
this.settings = new Map();
|
||||
}
|
||||
|
||||
registerTab(settingsTab) {
|
||||
this.settings.set(settingsTab.tabName, settingsTab);
|
||||
}
|
||||
|
||||
getSettings() {
|
||||
return this.settings;
|
||||
}
|
||||
}
|
||||
|
||||
const settingsManager = new SettingsManager();
|
||||
{
|
||||
const injectCss = () => {
|
||||
const css = `.modSelectSettingsButton {
|
||||
padding: 10px;
|
||||
cursor: pointer;
|
||||
}
|
||||
.modSelectSettingsButton[current=true] {
|
||||
background-color: rgb(71, 71, 71);
|
||||
}
|
||||
.modSelectSettingsButton:hover {
|
||||
background-color: rgb(51, 51, 51);
|
||||
}
|
||||
#modSelectControls {
|
||||
margin-bottom: 10px;
|
||||
position: relative;
|
||||
display: flex;
|
||||
overflow-x: scroll;
|
||||
}
|
||||
.betterSettings-categoryTitle {
|
||||
font-size: 1.25em;
|
||||
}`;
|
||||
const style = document.createElement("style");
|
||||
style.innerHTML = css;
|
||||
document.head.appendChild(style);
|
||||
}
|
||||
|
||||
const inject = () => {
|
||||
const settingsMenu = document.getElementById("settingsMenu");
|
||||
const menuText = settingsMenu.querySelector(".menuText");
|
||||
const menuTextChildren = menuText.children;
|
||||
const generalDiv = document.createElement("div");
|
||||
generalDiv.id = "betterSettings/div/general";
|
||||
while (menuTextChildren.length > 0) {
|
||||
generalDiv.appendChild(menuTextChildren[0]);
|
||||
}
|
||||
menuText.appendChild(generalDiv);
|
||||
const controls = document.createElement("div");
|
||||
controls.id = "modSelectControls";
|
||||
const generalButton = document.createElement("button");
|
||||
generalButton.setAttribute("current", true);
|
||||
generalButton.id = "betterSettings/button/general";
|
||||
generalButton.className = "modSelectSettingsButton";
|
||||
generalButton.innerText = "General";
|
||||
generalButton.onclick = (ev) => {
|
||||
for (const element of controls.children) {
|
||||
element.setAttribute("current", false);
|
||||
document.getElementById(element.id.replace("button", "div")).style.display = "none";
|
||||
}
|
||||
ev.target.setAttribute("current", true);
|
||||
document.getElementById("betterSettings/div/general").style.display = "";
|
||||
}
|
||||
controls.appendChild(generalButton);
|
||||
const wrapper = document.createElement("div");
|
||||
wrapper.appendChild(generalDiv);
|
||||
for (const mod of settingsManager.getSettings().keys()) {
|
||||
const modButton = document.createElement("button");
|
||||
modButton.setAttribute("current", false);
|
||||
modButton.id = "betterSettings/button/" + mod;
|
||||
modButton.className = "modSelectSettingsButton";
|
||||
modButton.innerText = mod;
|
||||
modButton.onclick = (ev) => {
|
||||
for (const element of controls.children) {
|
||||
element.setAttribute("current", false);
|
||||
document.getElementById(element.id.replace("button", "div")).style.display = "none";
|
||||
}
|
||||
ev.target.setAttribute("current", true);
|
||||
document.getElementById("betterSettings/div/" + mod).style.display = "";
|
||||
}
|
||||
controls.appendChild(modButton);
|
||||
const modDiv = document.createElement("div");
|
||||
modDiv.style.display = "none";
|
||||
modDiv.id = "betterSettings/div/" + mod;
|
||||
modDiv.appendChild(settingsManager.getSettings().get(mod).build());
|
||||
wrapper.appendChild(modDiv);
|
||||
}
|
||||
menuText.append(controls, wrapper);
|
||||
}
|
||||
runAfterLoadList.push(inject, injectCss);
|
||||
}
|
||||
|
|
@ -0,0 +1,608 @@
|
|||
if (!enabledMods.includes("mods/betterSettings.js")) { enabledMods.unshift("mods/betterSettings.js"); localStorage.setItem("enabledMods", JSON.stringify(enabledMods)); window.location.reload() };
|
||||
|
||||
const settingsTab = new SettingsTab("Edit tools");
|
||||
|
||||
const element = new Setting("Element", "element", settingType.TEXT, false, "wall");
|
||||
const replace = new Setting("Replace pixels", "replace", settingType.BOOLEAN, false, true);
|
||||
|
||||
const filter = new Setting("Filter", "filter", settingType.BOOLEAN, false, false);
|
||||
const filteredElement = new Setting("Filtered Element", "filterElement", settingType.TEXT, false, "");
|
||||
|
||||
const transparentSelection = new Setting("Transparent selection", "transparentSelection", settingType.BOOLEAN, false, true);
|
||||
|
||||
settingsTab.registerSettings("Box tools", element, replace);
|
||||
settingsTab.registerSettings("Filter settings", filter, filteredElement);
|
||||
settingsTab.registerSettings("Selection settings", transparentSelection);
|
||||
|
||||
settingsManager.registerTab(settingsTab);
|
||||
|
||||
// current selection
|
||||
let selection_ = {
|
||||
start: {},
|
||||
end: {}
|
||||
}
|
||||
// selection position, used for moveSelection
|
||||
let selectionPosition = {};
|
||||
// copy of the selection that is being moved (pixels), used for moveSelection
|
||||
let selectionMoved = [];
|
||||
// offsets of the mouse relative to selection position, used for moveSelection
|
||||
let selectionOffsets = {};
|
||||
|
||||
// current box, used in box and rectangle
|
||||
let box = {
|
||||
start: {},
|
||||
end: {}
|
||||
}
|
||||
|
||||
// whether the next mouseUp even should trigger
|
||||
let skip = false;
|
||||
// whether user is currently holding
|
||||
let holding = false;
|
||||
// mobile device shift equivalent
|
||||
let lockSelection = false;
|
||||
|
||||
// current clipboard, used for cutting, copying and pasting
|
||||
let clipboard = [];
|
||||
|
||||
// createPixel but with color argument
|
||||
const createPixelColor = (element, x, y, color) => {
|
||||
const pixel = new Pixel(x, y, element);
|
||||
pixel.color = color;
|
||||
currentPixels.push(pixel);
|
||||
checkUnlock(element);
|
||||
}
|
||||
|
||||
// replaces a pixel at x, y position with replacement element specified in the settings
|
||||
const replacePixel = (x, y) => {
|
||||
if (outOfBounds(x, y)) return;
|
||||
if (pixelMap[x][y]) {
|
||||
if (!replace.get()) return;
|
||||
deletePixel(x, y);
|
||||
}
|
||||
createPixel(element.get(), x, y);
|
||||
}
|
||||
|
||||
// checks whether position pos is in bounds
|
||||
const inBounds = (bounds, pos) => {
|
||||
bounds = {
|
||||
start: {
|
||||
x: Math.min(bounds.start.x, bounds.end.x),
|
||||
y: Math.min(bounds.start.y, bounds.end.y)
|
||||
},
|
||||
end: {
|
||||
x: Math.max(bounds.start.x, bounds.end.x),
|
||||
y: Math.max(bounds.start.y, bounds.end.y)
|
||||
}
|
||||
}
|
||||
return pos.x >= bounds.start.x && pos.x <= bounds.end.x && pos.y >= bounds.start.y && pos.y <= bounds.end.y;
|
||||
}
|
||||
|
||||
// generates a selection based on start and end positions
|
||||
const select = (start, end) => {
|
||||
const res = [];
|
||||
for (let i = 0; i <= end.x - start.x; i++) {
|
||||
res[i] = [];
|
||||
for (let j = 0; j <= end.y - start.y; j++) {
|
||||
res[i][j] = pixelMap[i + start.x][j + start.y];
|
||||
}
|
||||
}
|
||||
return res;
|
||||
}
|
||||
|
||||
elements.select = {
|
||||
name: "Select",
|
||||
category: "editTools",
|
||||
maxSize: 1,
|
||||
onMouseDown: () => {
|
||||
if (outOfBounds(mousePos.x, mousePos.y)) {
|
||||
skip = true;
|
||||
return;
|
||||
}
|
||||
skip = false;
|
||||
holding = true;
|
||||
selection_.start = mousePos;
|
||||
},
|
||||
onMouseUp: () => {
|
||||
if (skip) return;
|
||||
selection_.end = mousePos;
|
||||
if (selection_.start == selection_.end) selection_ = {};
|
||||
holding = false;
|
||||
},
|
||||
tool: (_) => {},
|
||||
perTick: () => {
|
||||
if (!selection_ || !selection_.start || !selection_.end) return;
|
||||
if (holding) {
|
||||
selection_.end = mousePos;
|
||||
}
|
||||
const canvas = document.getElementById("game");
|
||||
const ctx = canvas.getContext("2d");
|
||||
const start = {
|
||||
x: Math.round(selection_.start.x * pixelSize),
|
||||
y: Math.round(selection_.start.y * pixelSize)
|
||||
}
|
||||
const end = {
|
||||
x: Math.round(selection_.end.x * pixelSize),
|
||||
y: Math.round((selection_.end.y + 1) * pixelSize)
|
||||
}
|
||||
const {strokeStyle, lineWidth} = ctx;
|
||||
ctx.setLineDash([8, 8]);
|
||||
ctx.lineWidth = 2;
|
||||
ctx.strokeStyle = "white";
|
||||
ctx.globalCompositeOperation = "destination-over";
|
||||
ctx.strokeRect(start.x, start.y, end.x - start.x, end.y - start.y);
|
||||
ctx.strokeStyle = strokeStyle;
|
||||
ctx.lineWidth = lineWidth;
|
||||
ctx.setLineDash([]);
|
||||
}
|
||||
}
|
||||
|
||||
elements.box = {
|
||||
name: "Box",
|
||||
category: "editTools",
|
||||
onMouseDown: () => {
|
||||
if (outOfBounds(mousePos.x, mousePos.y) || showingMenu) {
|
||||
skip = true;
|
||||
return;
|
||||
}
|
||||
skip = false;
|
||||
holding = true;
|
||||
box.start = mousePos;
|
||||
},
|
||||
onMouseUp: () => {
|
||||
if (skip) return;
|
||||
box.end = mousePos;
|
||||
holding = false;
|
||||
for (let i = -Math.floor(mouseSize / 2); i < Math.abs(box.start.x - box.end.x) + Math.floor(mouseSize / 2); i++) {
|
||||
const x = Math.min(box.start.x, box.end.x) + i;
|
||||
for (let j = -Math.floor(mouseSize / 2); j <= Math.floor(mouseSize / 2); j++) {
|
||||
replacePixel(x, box.start.y + (box.start.y > box.end.y ? -j : j));
|
||||
replacePixel(x, box.end.y + (box.end.y > box.start.y ? -j : j));
|
||||
}
|
||||
}
|
||||
for (let i = -Math.floor(mouseSize / 2); i <= Math.abs(box.start.y - box.end.y) + Math.floor(mouseSize / 2); i++) {
|
||||
const y = Math.min(box.start.y, box.end.y) + i;
|
||||
for (let j = -Math.floor(mouseSize / 2); j <= Math.floor(mouseSize / 2); j++) {
|
||||
replacePixel(box.start.x + (box.start.x > box.end.x ? -j : j), y);
|
||||
replacePixel(box.end.x + (box.end.x > box.start.x ? -j : j), y);
|
||||
}
|
||||
}
|
||||
},
|
||||
tool: (_) => {},
|
||||
perTick: () => {
|
||||
if (holding) {
|
||||
if (shiftDown || lockSelection) {
|
||||
box.end = {
|
||||
y: mousePos.y,
|
||||
x: box.start.x + Math.abs(mousePos.y - box.start.y) * (box.start.x > mousePos.x ? -1 : 1)
|
||||
};
|
||||
mousePos = box.end;
|
||||
} else {
|
||||
box.end = mousePos;
|
||||
}
|
||||
const canvas = document.getElementById("game");
|
||||
const ctx = canvas.getContext("2d");
|
||||
const start = {
|
||||
x: Math.round(box.start.x * pixelSize),
|
||||
y: Math.round(box.start.y * pixelSize)
|
||||
}
|
||||
const end = {
|
||||
x: Math.round(box.end.x * pixelSize),
|
||||
y: Math.round((box.end.y + 1) * pixelSize)
|
||||
}
|
||||
const {strokeStyle, lineWidth} = ctx;
|
||||
ctx.setLineDash([8, 8]);
|
||||
ctx.lineWidth = 2;
|
||||
ctx.strokeStyle = "yellow";
|
||||
ctx.strokeRect(start.x, start.y, end.x - start.x, end.y - start.y);
|
||||
ctx.strokeStyle = strokeStyle;
|
||||
ctx.lineWidth = lineWidth;
|
||||
ctx.setLineDash([]);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
elements.cut = {
|
||||
name: "Cut",
|
||||
category: "editTools",
|
||||
maxSize: 0,
|
||||
tool: (_) => {},
|
||||
onSelect: () => {
|
||||
if (!selection_.start || !selection_.end) return alert("No selection made");
|
||||
const selected = select({
|
||||
x: Math.min(selection_.start.x, selection_.end.x),
|
||||
y: Math.min(selection_.start.y, selection_.end.y)
|
||||
}, {
|
||||
x: Math.max(selection_.start.x, selection_.end.x),
|
||||
y: Math.max(selection_.start.y, selection_.end.y)
|
||||
})
|
||||
clipboard = selected;
|
||||
for (const i of selected) {
|
||||
for (const pixel of i) {
|
||||
if (!pixel) continue;
|
||||
deletePixel(pixel.x, pixel.y);
|
||||
}
|
||||
}
|
||||
selectElement("unknown");
|
||||
}
|
||||
}
|
||||
elements.copy = {
|
||||
name: "Copy",
|
||||
category: "editTools",
|
||||
maxSize: 0,
|
||||
tool: (_) => {},
|
||||
onSelect: () => {
|
||||
if (!selection_.start || !selection_.end) return alert("No selection made");
|
||||
const selected = select({
|
||||
x: Math.min(selection_.start.x, selection_.end.x),
|
||||
y: Math.min(selection_.start.y, selection_.end.y)
|
||||
}, {
|
||||
x: Math.max(selection_.start.x, selection_.end.x),
|
||||
y: Math.max(selection_.start.y, selection_.end.y)
|
||||
})
|
||||
clipboard = selected;
|
||||
selectElement("unknown");
|
||||
}
|
||||
}
|
||||
|
||||
elements.selectionMove = {
|
||||
name: "Move selection",
|
||||
category: "editTools",
|
||||
maxSize: 0,
|
||||
tool: (_) => {},
|
||||
onMouseDown: () => {
|
||||
if (outOfBounds(mousePos.x, mousePos.y)) return;
|
||||
if (!selection_.start || !selection_.end) return;
|
||||
if (!inBounds(selection_, mousePos)) return;
|
||||
selectionOffsets = {
|
||||
x: mousePos.x - Math.min(selection_.start.x, selection_.end.x),
|
||||
y: mousePos.y - Math.min(selection_.start.y, selection_.end.y)
|
||||
}
|
||||
const selected = select({
|
||||
x: Math.min(selection_.start.x, selection_.end.x),
|
||||
y: Math.min(selection_.start.y, selection_.end.y)
|
||||
}, {
|
||||
x: Math.max(selection_.start.x, selection_.end.x),
|
||||
y: Math.max(selection_.start.y, selection_.end.y)
|
||||
})
|
||||
selectionPosition = {
|
||||
x: selection_.start.x,
|
||||
y: selection_.start.y
|
||||
}
|
||||
for (const i of selected) {
|
||||
for (const pixel of i) {
|
||||
if (!pixel) continue;
|
||||
deletePixel(pixel.x, pixel.y);
|
||||
}
|
||||
}
|
||||
selectionMoved = selected;
|
||||
},
|
||||
perTick: () => {
|
||||
const canvas = document.getElementById("game");
|
||||
const ctx = canvas.getContext("2d");
|
||||
ctx.globalAlpha = 1;
|
||||
const start = {
|
||||
x: Math.round(selection_.start.x * pixelSize),
|
||||
y: Math.round(selection_.start.y * pixelSize)
|
||||
}
|
||||
const end = {
|
||||
x: Math.round(selection_.end.x * pixelSize),
|
||||
y: Math.round((selection_.end.y + 1) * pixelSize)
|
||||
}
|
||||
const {strokeStyle, lineWidth} = ctx;
|
||||
ctx.setLineDash([8, 8]);
|
||||
ctx.lineWidth = 2;
|
||||
ctx.strokeStyle = "white";
|
||||
ctx.strokeRect(start.x, start.y, end.x - start.x, end.y - start.y);
|
||||
ctx.strokeStyle = strokeStyle;
|
||||
ctx.lineWidth = lineWidth;
|
||||
ctx.setLineDash([]);
|
||||
if (!selectionMoved || selectionMoved.length == 0) return;
|
||||
selectionPosition = {
|
||||
x: mousePos.x - selectionOffsets.x,
|
||||
y: mousePos.y - selectionOffsets.y
|
||||
}
|
||||
selection_ = {
|
||||
start: {
|
||||
x: selectionPosition.x,
|
||||
y: selectionPosition.y
|
||||
},
|
||||
end: {
|
||||
x: selectionPosition.x + selectionMoved.length - 1,
|
||||
y: selectionPosition.y + selectionMoved[0].length - 1
|
||||
}
|
||||
}
|
||||
ctx.globalAlpha = 0.5;
|
||||
for (let i = 0; i < selectionMoved.length; i++) {
|
||||
for (let j = 0; j < selectionMoved[i].length; j++) {
|
||||
const x = selectionPosition.x + i;
|
||||
const y = selectionPosition.y + j;
|
||||
if (!selectionMoved[i][j]) continue;
|
||||
ctx.globalCompositeOperation = 'destination-over';
|
||||
ctx.fillStyle = selectionMoved[i][j].color;
|
||||
ctx.fillRect(x * pixelSize, y * pixelSize, pixelSize, pixelSize);
|
||||
}
|
||||
}
|
||||
},
|
||||
onMouseUp: () => {
|
||||
if (outOfBounds(mousePos.x, mousePos.y)) return;
|
||||
for (let i = 0; i < selectionMoved.length; i++) {
|
||||
for (let j = 0; j < selectionMoved[i].length; j++) {
|
||||
const x = selectionPosition.x + i;
|
||||
const y = selectionPosition.y + j;
|
||||
if (!selectionMoved[i][j] && transparentSelection.get()) continue;
|
||||
if (pixelMap[x][y]) deletePixel(x, y);
|
||||
if (selectionMoved[i][j]) createPixelColor(selectionMoved[i][j].element, x, y, selectionMoved[i][j].color);
|
||||
}
|
||||
}
|
||||
selectionMoved = [];
|
||||
}
|
||||
}
|
||||
|
||||
elements.paste = {
|
||||
name: "Paste",
|
||||
category: "editTools",
|
||||
tool: (_) => {},
|
||||
maxSize: 1,
|
||||
onMouseDown: () => {
|
||||
if (!clipboard) return alert("Nothing left to paste");
|
||||
for (let i = 0; i < clipboard.length; i++) {
|
||||
for (let j = 0; j < clipboard[i].length; j++) {
|
||||
const x = mousePos.x + i;
|
||||
const y = mousePos.y + j;
|
||||
if (outOfBounds(x, y) || (!clipboard[i][j] && transparentSelection.get())) continue;
|
||||
if (!clipboard[i][j]) {
|
||||
if (pixelMap[x][y]) deletePixel(x, y);
|
||||
continue;
|
||||
}
|
||||
if (!pixelMap[x][y]) createPixelColor(clipboard[i][j].element, x, y, clipboard[i][j].color);
|
||||
else {
|
||||
deletePixel(x, y);
|
||||
createPixelColor(clipboard[i][j].element, x, y, clipboard[i][j].color);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
elements.rectangle = {
|
||||
name: "Rectangle",
|
||||
category: "editTools",
|
||||
onMouseDown: () => {
|
||||
if (outOfBounds(mousePos.x, mousePos.y)) {
|
||||
skip = true;
|
||||
return;
|
||||
}
|
||||
skip = false;
|
||||
holding = true;
|
||||
box.start = mousePos;
|
||||
},
|
||||
onMouseUp: () => {
|
||||
if (skip) return;
|
||||
box.end = mousePos;
|
||||
holding = false;
|
||||
for (let i = -Math.floor(mouseSize / 2); i <= Math.abs(box.start.x - box.end.x) + Math.floor(mouseSize / 2); i++) {
|
||||
for (let j = -Math.floor(mouseSize / 2); j <= Math.abs(box.start.y - box.end.y) + Math.floor(mouseSize / 2); j++) {
|
||||
replacePixel(Math.min(box.start.x, box.end.x) + i, Math.min(box.start.y, box.end.y) + j);
|
||||
}
|
||||
}
|
||||
},
|
||||
tool: (_) => {},
|
||||
perTick: () => {
|
||||
if (holding) {
|
||||
if (shiftDown || lockSelection) {
|
||||
box.end = {
|
||||
y: mousePos.y,
|
||||
x: box.start.x + Math.abs(mousePos.y - box.start.y) * (box.start.x > mousePos.x ? -1 : 1)
|
||||
};
|
||||
mousePos = box.end;
|
||||
} else {
|
||||
box.end = mousePos;
|
||||
}
|
||||
const canvas = document.getElementById("game");
|
||||
const ctx = canvas.getContext("2d");
|
||||
const start = {
|
||||
x: Math.round(box.start.x * pixelSize),
|
||||
y: Math.round(box.start.y * pixelSize)
|
||||
}
|
||||
const end = {
|
||||
x: Math.round(box.end.x * pixelSize),
|
||||
y: Math.round((box.end.y + 1) * pixelSize)
|
||||
}
|
||||
const {strokeStyle, lineWidth} = ctx;
|
||||
ctx.setLineDash([8, 8]);
|
||||
ctx.lineWidth = 2;
|
||||
ctx.strokeStyle = "yellow";
|
||||
ctx.strokeRect(start.x, start.y, end.x - start.x, end.y - start.y);
|
||||
ctx.strokeStyle = strokeStyle;
|
||||
ctx.lineWidth = lineWidth;
|
||||
ctx.setLineDash([]);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Ellipse Midpoint Algorithm
|
||||
// https://stackoverflow.com/questions/15474122/is-there-a-midpoint-ellipse-algorithm
|
||||
// https://web.archive.org/web/20160305234351/http://geofhagopian.net/sablog/Slog-october/slog-10-25-05.htm
|
||||
function ellipsePlotPoints(xc, yc, x, y) {
|
||||
replacePixel(xc + x, yc + y);
|
||||
replacePixel(xc - x, yc + y);
|
||||
replacePixel(xc + x, yc - y);
|
||||
replacePixel(xc - x, yc - y);
|
||||
}
|
||||
|
||||
function ellipse(xc, yc, w, h) {
|
||||
const a2 = Math.pow(w, 2);
|
||||
const b2 = Math.pow(h, 2);
|
||||
const twoa2 = 2 * a2;
|
||||
const twob2 = 2 * b2;
|
||||
let p;
|
||||
let x = 0;
|
||||
let y = h;
|
||||
let px = 0;
|
||||
let py = twoa2 * y;
|
||||
|
||||
/* Plot the initial point in each quadrant. */
|
||||
ellipsePlotPoints(xc, yc, x, y);
|
||||
|
||||
p = Math.round(b2 - (a2 * b) + (0.25 * a2));
|
||||
while (px < py) {
|
||||
x++;
|
||||
px += twob2;
|
||||
if (p < 0) p += b2 + px;
|
||||
else {
|
||||
y--;
|
||||
py -= twoa2;
|
||||
p += b2 + px - py;
|
||||
}
|
||||
ellipsePlotPoints(xc, yc, x, y);
|
||||
}
|
||||
|
||||
p = Math.round(b2 * (x + 0.5) * (x + 0.5) + a2 * (y - 1) * (y - 1) - a2 * b2);
|
||||
while (y > 0) {
|
||||
y--;
|
||||
py -= twoa2;
|
||||
if (p > 0) p += a2 - py;
|
||||
else {
|
||||
x++;
|
||||
px += twob2;
|
||||
p += a2 - py + px;
|
||||
}
|
||||
ellipsePlotPoints(xc, yc, x, y);
|
||||
}
|
||||
}
|
||||
|
||||
elements.ellipse = {
|
||||
name: "Ellipse",
|
||||
category: "editTools",
|
||||
tool: (_) => {},
|
||||
maxSize: 1,
|
||||
onMouseDown: () => {
|
||||
if (outOfBounds(mousePos.x, mousePos.y)) {
|
||||
skip = true;
|
||||
return;
|
||||
}
|
||||
skip = false;
|
||||
holding = true;
|
||||
box.start = mousePos;
|
||||
},
|
||||
onMouseUp: () => {
|
||||
if (skip) return;
|
||||
box.end = mousePos;
|
||||
holding = false;
|
||||
const w = Math.abs(box.end.x - box.start.x);
|
||||
const h = Math.abs(box.end.y - box.start.y);
|
||||
const x = Math.min(box.start.x, box.end.x) + Math.floor(w / 2);
|
||||
const y = Math.min(box.start.y, box.end.y) + Math.floor(h / 2);
|
||||
ellipse(x, y, Math.floor(w / 2), Math.floor(h / 2));
|
||||
},
|
||||
tool: (_) => {},
|
||||
perTick: () => {
|
||||
if (holding) {
|
||||
if (shiftDown || lockSelection) {
|
||||
box.end = {
|
||||
y: mousePos.y,
|
||||
x: box.start.x + Math.abs(mousePos.y - box.start.y) * (box.start.x > mousePos.x ? -1 : 1)
|
||||
};
|
||||
mousePos = box.end;
|
||||
} else {
|
||||
box.end = mousePos;
|
||||
}
|
||||
const canvas = document.getElementById("game");
|
||||
const ctx = canvas.getContext("2d");
|
||||
const start = {
|
||||
x: Math.round(box.start.x * pixelSize),
|
||||
y: Math.round(box.start.y * pixelSize)
|
||||
}
|
||||
const end = {
|
||||
x: Math.round(box.end.x * pixelSize),
|
||||
y: Math.round((box.end.y + 1) * pixelSize)
|
||||
}
|
||||
const {strokeStyle, lineWidth} = ctx;
|
||||
ctx.setLineDash([8, 8]);
|
||||
ctx.lineWidth = 2;
|
||||
ctx.strokeStyle = "yellow";
|
||||
ctx.strokeRect(start.x, start.y, end.x - start.x, end.y - start.y);
|
||||
ctx.strokeStyle = strokeStyle;
|
||||
ctx.lineWidth = lineWidth;
|
||||
ctx.setLineDash([]);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
document.addEventListener("mousedown", (ev) => {
|
||||
if (elements[currentElement].onMouseDown) {
|
||||
elements[currentElement].onMouseDown();
|
||||
}
|
||||
})
|
||||
|
||||
// mouse2 overwrite for delete filter
|
||||
// no mouse1 overwrite for replace functionality, I don't think I should be overwriting such big functions
|
||||
// maybe in a future update
|
||||
mouse2Action = (e,mouseX=undefined,mouseY=undefined,startPos) => {
|
||||
// Erase pixel at mouse position
|
||||
if (mouseX == undefined && mouseY == undefined) {
|
||||
var canvas = document.getElementById("game");
|
||||
var ctx = canvas.getContext("2d");
|
||||
lastPos = mousePos;
|
||||
mousePos = getMousePos(canvas, e);
|
||||
var mouseX = mousePos.x;
|
||||
var mouseY = mousePos.y;
|
||||
}
|
||||
// If the current element is "pick" or "lookup", coords = [mouseX,mouseY]
|
||||
if (currentElement == "pick" || currentElement == "lookup") {
|
||||
var coords = [[mouseX,mouseY]];
|
||||
}
|
||||
else if (!isMobile) {
|
||||
startPos = startPos || lastPos
|
||||
var coords = lineCoords(startPos.x,startPos.y,mouseX,mouseY);
|
||||
}
|
||||
else {
|
||||
var coords = mouseRange(mouseX,mouseY);
|
||||
}
|
||||
// For each x,y in coords
|
||||
for (var i = 0; i < coords.length; i++) {
|
||||
var x = coords[i][0];
|
||||
var y = coords[i][1];
|
||||
|
||||
if (!isEmpty(x, y)) {
|
||||
if (outOfBounds(x,y)) {
|
||||
continue
|
||||
}
|
||||
var pixel = pixelMap[x][y];
|
||||
// filter
|
||||
if (filter.get() && pixel.element != filteredElement.get()) continue;
|
||||
delete pixelMap[x][y];
|
||||
// Remove pixel from currentPixels
|
||||
for (var j = 0; j < currentPixels.length; j++) {
|
||||
if (currentPixels[j].x == x && currentPixels[j].y == y) {
|
||||
currentPixels.splice(j, 1);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Mobile check
|
||||
// https://stackoverflow.com/questions/11381673/detecting-a-mobile-browser
|
||||
// http://detectmobilebrowsers.com/
|
||||
window.mobileAndTabletCheck = () => {
|
||||
let check = false;
|
||||
(function(a){if(/(android|bb\d+|meego).+mobile|avantgo|bada\/|blackberry|blazer|compal|elaine|fennec|hiptop|iemobile|ip(hone|od)|iris|kindle|lge |maemo|midp|mmp|mobile.+firefox|netfront|opera m(ob|in)i|palm( os)?|phone|p(ixi|re)\/|plucker|pocket|psp|series(4|6)0|symbian|treo|up\.(browser|link)|vodafone|wap|windows ce|xda|xiino|android|ipad|playbook|silk/i.test(a)||/1207|6310|6590|3gso|4thp|50[1-6]i|770s|802s|a wa|abac|ac(er|oo|s\-)|ai(ko|rn)|al(av|ca|co)|amoi|an(ex|ny|yw)|aptu|ar(ch|go)|as(te|us)|attw|au(di|\-m|r |s )|avan|be(ck|ll|nq)|bi(lb|rd)|bl(ac|az)|br(e|v)w|bumb|bw\-(n|u)|c55\/|capi|ccwa|cdm\-|cell|chtm|cldc|cmd\-|co(mp|nd)|craw|da(it|ll|ng)|dbte|dc\-s|devi|dica|dmob|do(c|p)o|ds(12|\-d)|el(49|ai)|em(l2|ul)|er(ic|k0)|esl8|ez([4-7]0|os|wa|ze)|fetc|fly(\-|_)|g1 u|g560|gene|gf\-5|g\-mo|go(\.w|od)|gr(ad|un)|haie|hcit|hd\-(m|p|t)|hei\-|hi(pt|ta)|hp( i|ip)|hs\-c|ht(c(\-| |_|a|g|p|s|t)|tp)|hu(aw|tc)|i\-(20|go|ma)|i230|iac( |\-|\/)|ibro|idea|ig01|ikom|im1k|inno|ipaq|iris|ja(t|v)a|jbro|jemu|jigs|kddi|keji|kgt( |\/)|klon|kpt |kwc\-|kyo(c|k)|le(no|xi)|lg( g|\/(k|l|u)|50|54|\-[a-w])|libw|lynx|m1\-w|m3ga|m50\/|ma(te|ui|xo)|mc(01|21|ca)|m\-cr|me(rc|ri)|mi(o8|oa|ts)|mmef|mo(01|02|bi|de|do|t(\-| |o|v)|zz)|mt(50|p1|v )|mwbp|mywa|n10[0-2]|n20[2-3]|n30(0|2)|n50(0|2|5)|n7(0(0|1)|10)|ne((c|m)\-|on|tf|wf|wg|wt)|nok(6|i)|nzph|o2im|op(ti|wv)|oran|owg1|p800|pan(a|d|t)|pdxg|pg(13|\-([1-8]|c))|phil|pire|pl(ay|uc)|pn\-2|po(ck|rt|se)|prox|psio|pt\-g|qa\-a|qc(07|12|21|32|60|\-[2-7]|i\-)|qtek|r380|r600|raks|rim9|ro(ve|zo)|s55\/|sa(ge|ma|mm|ms|ny|va)|sc(01|h\-|oo|p\-)|sdk\/|se(c(\-|0|1)|47|mc|nd|ri)|sgh\-|shar|sie(\-|m)|sk\-0|sl(45|id)|sm(al|ar|b3|it|t5)|so(ft|ny)|sp(01|h\-|v\-|v )|sy(01|mb)|t2(18|50)|t6(00|10|18)|ta(gt|lk)|tcl\-|tdg\-|tel(i|m)|tim\-|t\-mo|to(pl|sh)|ts(70|m\-|m3|m5)|tx\-9|up(\.b|g1|si)|utst|v400|v750|veri|vi(rg|te)|vk(40|5[0-3]|\-v)|vm40|voda|vulc|vx(52|53|60|61|70|80|81|83|85|98)|w3c(\-| )|webc|whit|wi(g |nc|nw)|wmlb|wonu|x700|yas\-|your|zeto|zte\-/i.test(a.substr(0,4))) check = true;})(navigator.userAgent||navigator.vendor||window.opera);
|
||||
return check;
|
||||
};
|
||||
|
||||
// if user is on mobile, add lock selection tool
|
||||
if (window.mobileAndTabletCheck()) {
|
||||
elements.lockSelection = {
|
||||
name: "Lock selection",
|
||||
category: "editTools",
|
||||
tool: (_) => {},
|
||||
onSelect: () => {
|
||||
// unselect so you can click it multiple times
|
||||
selectElement("unknown");
|
||||
document.getElementById("elementButton-lockSelection").innerText = lockSelection ? "Lock selection" : "Unlock selection";
|
||||
lockSelection = !lockSelection;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -30,54 +30,51 @@ elements.ketchup.reactions = {
|
|||
"mayonnaise": { "elem1": null, "elem2": "fry_sauce" },
|
||||
"plague": { "elem1": "poisoned_ketchup", "elem2": null},
|
||||
"infection": { "elem1": "poisoned_ketchup", "elem2": null},
|
||||
"radiation": { "elem1": "poisoned_ketchup", chance:025},
|
||||
"fallout": { "elem1": "poisoned_ketchup", chance:025},
|
||||
"fallout": { "elem1": "poisoned_ketchup", "chance":25},
|
||||
"gloomwind": { "elem1": "poisoned_ketchup", "elem2": null},
|
||||
};
|
||||
};
|
||||
|
||||
// making ketchup dirty
|
||||
elements.dirt.reactions = {
|
||||
"ketchup": { "elem1": null, "elem2": "dirty_ketchup", "oneway":true},
|
||||
};
|
||||
elements.ash.reactions = {
|
||||
"ketchup": { "elem1": null, "elem2": "dirty_ketchup", "oneway":true},
|
||||
"steam": { "elem1": "pyrocumulus", "chance":0.08, "y":[0,15] },
|
||||
"rain_cloud": { "elem1": "pyrocumulus", "chance":0.08, "y":[0,15] },
|
||||
"snow_cloud": { "elem1": "pyrocumulus", "chance":0.08, "y":[0,15] },
|
||||
"acid_cloud": { "elem1": "pyrocumulus", "chance":0.05, "y":[0,15] },
|
||||
"pyrocumulus": { "elem1": "pyrocumulus", "chance":0.08, "y":[0,15] },
|
||||
};
|
||||
elements.ash.reactions.ketchup = { "elem1": null, "elem2": "dirty_ketchup", "oneway":true},
|
||||
elements.dust.reactions = {
|
||||
"ketchup": { "elem1": null, "elem2": "dirty_ketchup", "oneway":true},
|
||||
};
|
||||
|
||||
// making it so ketchup clouds can react with smoke to make pyrocumulus
|
||||
elements.smoke.reactions = {
|
||||
"steam": { "elem1": "pyrocumulus", "chance":0.08, "y":[0,15] },
|
||||
"rain_cloud": { "elem1": "pyrocumulus", "chance":0.08, "y":[0,15] },
|
||||
"snow_cloud": { "elem1": "pyrocumulus", "chance":0.08, "y":[0,15] },
|
||||
"acid_cloud": { "elem1": "pyrocumulus", "chance":0.05, "y":[0,15] },
|
||||
"fire_cloud": { "elem1": "pyrocumulus", "chance":0.05, "y":[0,15] },
|
||||
"pyrocumulus": { "elem1": "pyrocumulus", "chance":0.08, "y":[0,15] },
|
||||
"ketchup_cloud": { "elem1": "pyrocumulus", "chance":0.08, "y":[0.15] },
|
||||
"poisoned_ketchup_cloud": { "elem1": "pyrocumulus", "chance":0.08, "y":[0.15] },
|
||||
};
|
||||
// pyrocumulus reactions
|
||||
elements.smoke.reactions.ketchup_cloud = { "elem1": "pyrocumulus", "chance":0.08, "y":[0,15], "setting":"clouds" },
|
||||
elements.smoke.reactions.poisoned_ketchup_cloud = { "elem1": "pyrocumulus", "chance":0.08, "y":[0,15], "setting":"clouds" },
|
||||
elements.smoke.reactions.ketchup_snow_cloud = { "elem1": "pyrocumulus", "chance":0.08, "y":[0,15], "setting":"clouds" },
|
||||
elements.smoke.reactions.poisoned_ketchup_snow_cloud = { "elem1": "pyrocumulus", "chance":0.08, "y":[0,15], "setting":"clouds" },
|
||||
elements.smoke.reactions.ketchup_rain_cloud = { "elem1": "pyrocumulus", "chance":0.08, "y":[0,15], "setting":"clouds" },
|
||||
elements.smoke.reactions.poisoned_ketchup_rain_cloud = { "elem1": "pyrocumulus", "chance":0.08, "y":[0,15], "setting":"clouds" },
|
||||
elements.ash.reactions.ketchup_cloud = { "elem1": "pyrocumulus", "chance":0.08, "y":[0,15], "setting":"clouds" },
|
||||
elements.ash.reactions.poisoned_ketchup_cloud = { "elem1": "pyrocumulus", "chance":0.08, "y":[0,15], "setting":"clouds" },
|
||||
elements.ash.reactions.ketchup_snow_cloud = { "elem1": "pyrocumulus", "chance":0.08, "y":[0,15], "setting":"clouds" },
|
||||
elements.ash.reactions.poisoned_ketchup_snow_cloud = { "elem1": "pyrocumulus", "chance":0.08, "y":[0,15], "setting":"clouds" },
|
||||
elements.ash.reactions.ketchup_rain_cloud = { "elem1": "pyrocumulus", "chance":0.08, "y":[0,15], "setting":"clouds" },
|
||||
elements.ash.reactions.poisoned_ketchup_rain_cloud = { "elem1": "pyrocumulus", "chance":0.08, "y":[0,15], "setting":"clouds" },
|
||||
|
||||
// fixing radiation reactions
|
||||
elements.radiation.reactions.ketchup = { "elem1": null, "elem2": "poisoned_ketchup", "chance":25}
|
||||
|
||||
// elements
|
||||
elements.frozen_ketchup = {
|
||||
color: "#d44737",
|
||||
behavior: behaviors.WALL,
|
||||
temp: 0,
|
||||
temp: -5,
|
||||
category:"solids",
|
||||
tempHigh: -3,
|
||||
tempHigh: 5,
|
||||
stateHigh: "ketchup",
|
||||
state: "solid",
|
||||
density: 917,
|
||||
reactions: {
|
||||
"plague": { "elem1": "frozen_poisoned_ketchup", "elem2": null},
|
||||
"infection": { "elem1": "frozen_poisoned_ketchup", "elem2": null},
|
||||
"radiation": { "elem1": "frozen_poisoned_ketchup", chance:025},
|
||||
"fallout": { "elem1": "frozen_poisoned_ketchup", chance:025},
|
||||
"radiation": { "elem1": "frozen_poisoned_ketchup", "chance":25},
|
||||
"fallout": { "elem1": "frozen_poisoned_ketchup", "chance":25},
|
||||
"gloomwind": { "elem1": "frozen_poisoned_ketchup", "elem2": null},
|
||||
},
|
||||
};
|
||||
|
|
@ -92,13 +89,14 @@ elements.poisoned_ketchup = {
|
|||
category:"liquids",
|
||||
state: "liquid",
|
||||
density: 1140,
|
||||
stain: 0.05,
|
||||
};
|
||||
elements.frozen_poisoned_ketchup = {
|
||||
color: "#d43754",
|
||||
behavior: behaviors.POISONED_WALL,
|
||||
temp: 0,
|
||||
temp: -5,
|
||||
category:"solids",
|
||||
tempHigh: 3,
|
||||
tempHigh: 5,
|
||||
stateHigh: "poisoned_ketchup",
|
||||
state: "solid",
|
||||
density: 917,
|
||||
|
|
@ -113,56 +111,98 @@ elements.ketchup_spout = {
|
|||
category:"special",
|
||||
};
|
||||
elements.ketchup_cloud = {
|
||||
color: "#6e413b",
|
||||
color: "#ad655c",
|
||||
behavior: [
|
||||
"XX|XX|XX",
|
||||
"M1%5|XX|M1%5",
|
||||
"XX|CR:ketchup%1|XX",
|
||||
"XX|CO:1%5|M1%2.5 AND BO",
|
||||
"XX|XX|XX",
|
||||
],
|
||||
category:"gases",
|
||||
temp: 80,
|
||||
tempLow: 0,
|
||||
stateLow: "ketchup_snow_cloud",
|
||||
temp: 110,
|
||||
tempLow: 100,
|
||||
stateLow: "ketchup_rain_cloud",
|
||||
state: "gas",
|
||||
density: 1,
|
||||
density: 0.5,
|
||||
reactions: {
|
||||
"plague": { "elem1": "poisoned_ketchup_cloud", "elem2": null},
|
||||
"infection": { "elem1": "poisoned_ketchup_cloud"},
|
||||
"radiation": { "elem1": "poisoned_ketchup_cloud", chance:025},
|
||||
"fallout": { "elem1": "poisoned_ketchup_cloud", chance:025},
|
||||
"radiation": { "elem1": "poisoned_ketchup_cloud", "chance":25},
|
||||
"fallout": { "elem1": "poisoned_ketchup_cloud", "chance":25},
|
||||
"gloomwind": { "elem1": "poisoned_ketchup_cloud", "elem2": null},
|
||||
"ketchup_rain_cloud": { "elem1":"ketchup_rain_cloud", "temp1":-20 },
|
||||
},
|
||||
conduct: 0.03,
|
||||
ignoreAir: true,
|
||||
};
|
||||
elements.ketchup_rain_cloud = {
|
||||
color: "#6e413b",
|
||||
behavior: [
|
||||
"XX|XX|XX",
|
||||
"XX|CH:ketchup%0.05|M1%2.5 AND BO",
|
||||
"XX|XX|XX|",
|
||||
],
|
||||
category: "gases",
|
||||
temp: 70,
|
||||
tempHigh: 100,
|
||||
stateHigh: "ketchup_cloud",
|
||||
tempLow: 0,
|
||||
stateLow: "ketchup_snow_cloud",
|
||||
state: "gas",
|
||||
density: "0.5",
|
||||
ignoreAir: true,
|
||||
conduct: 0.03,
|
||||
};
|
||||
elements.poisoned_ketchup_cloud = {
|
||||
color: "#a8596b",
|
||||
behavior: [
|
||||
"XX|XX|XX",
|
||||
"XX|CO:1%5|M1%2.5 AND BO",
|
||||
"XX|XX|XX",
|
||||
],
|
||||
reactions: {
|
||||
"poisoned_ketchup_rain_cloud": { "elem1":"poisoned_ketchup_rain_cloud", "temp1": -20 },
|
||||
},
|
||||
category: "gases",
|
||||
temp: 110,
|
||||
tempLow: 100,
|
||||
stateLow: "poisoned_ketchup_rain_cloud",
|
||||
state: "gas",
|
||||
density: 0.5,
|
||||
conduct: 0.03,
|
||||
ignoreAir: true,
|
||||
};
|
||||
elements.poisoned_ketchup_rain_cloud = {
|
||||
color: "#633640",
|
||||
behavior: [
|
||||
"XX|XX|XX",
|
||||
"M1%5|XX|M1%5",
|
||||
"XX|CR:poisoned_ketchup%1|XX",
|
||||
"XX|CH:poisoned_ketchup%0.05|M1%2.5 AND BO",
|
||||
"XX|XX|XX",
|
||||
],
|
||||
category:"gases",
|
||||
temp: 80,
|
||||
category: "gases",
|
||||
temp: 70,
|
||||
tempHigh: 100,
|
||||
stateHigh: "poisoned_ketchup_cloud",
|
||||
tempLow: 0,
|
||||
stateLow: "poisoned_ketchup_snow_cloud",
|
||||
state: "gas",
|
||||
density: 1,
|
||||
density: 0.5,
|
||||
ignoreAir: true,
|
||||
conduct: 0.03,
|
||||
};
|
||||
elements.ketchup_snow = {
|
||||
color: "#ed7a6d",
|
||||
behavior: behaviors.POWDER,
|
||||
temp: 0,
|
||||
tempHigh: 5,
|
||||
temp: -5,
|
||||
tempHigh: 18,
|
||||
stateHigh: "ketchup",
|
||||
category: "land",
|
||||
category: "land",
|
||||
state: "solid",
|
||||
density: "100",
|
||||
density: 100,
|
||||
reactions: {
|
||||
"plague": { "elem1": "poisoned_ketchup_snow", "elem2": null},
|
||||
"infection": { "elem1": "poisoned_ketchup_snow", "elem2": null},
|
||||
"radiation": { "elem1": "poisoned_ketchup_snow", chance:025},
|
||||
"fallout": { "elem1": "poisoned_ketchup_snow", chance:025},
|
||||
"radiation": { "elem1": "poisoned_ketchup_snow", chance:25},
|
||||
"fallout": { "elem1": "poisoned_ketchup_snow", chance:25},
|
||||
"gloomwind": { "elem1": "poisoned_ketchup_snow", "elem2": null},
|
||||
},
|
||||
};
|
||||
|
|
@ -170,7 +210,7 @@ elements.ketchup_snow_cloud = {
|
|||
color: "#755652",
|
||||
behavior: [
|
||||
"XX|XX|XX",
|
||||
"M1%5|CH:ketchup_snow%0.05|M1%5",
|
||||
"XX|CH:ketchup_snow%0.05|M1%2.5 AND BO",
|
||||
"XX|XX|XX",
|
||||
],
|
||||
category:"gases",
|
||||
|
|
@ -178,30 +218,31 @@ elements.ketchup_snow_cloud = {
|
|||
tempHigh: 30,
|
||||
stateHigh: "ketchup_cloud",
|
||||
state: "gas",
|
||||
density: 2,
|
||||
density: 0.55,
|
||||
reactions: {
|
||||
"plague": { "elem1": "poisoned_ketchup_snow_cloud", "elem2": null},
|
||||
"infection": { "elem1": "poisoned_ketchup_snow_cloud"},
|
||||
"radiation": { "elem1": "poisoned_ketchup_snow_cloud", chance:025},
|
||||
"fallout": { "elem1": "poisoned_ketchup_snow_cloud", chance:025},
|
||||
"radiation": { "elem1": "poisoned_ketchup_snow_cloud", chance:25},
|
||||
"fallout": { "elem1": "poisoned_ketchup_snow_cloud", chance:25},
|
||||
"gloomwind": { "elem1": "poisoned_ketchup_snow_cloud", "elem2": null},
|
||||
},
|
||||
ignoreAir: true,
|
||||
};
|
||||
elements.poisoned_ketchup_snow = {
|
||||
color: "#d1697f",
|
||||
behavior: behaviors.POISONED_POWDER,
|
||||
temp: 0,
|
||||
tempHigh: 5,
|
||||
temp: -5,
|
||||
tempHigh: 18,
|
||||
stateHigh: "poisoned_ketchup",
|
||||
category: "land",
|
||||
state: "solid",
|
||||
density: "100",
|
||||
density: 100,
|
||||
};
|
||||
elements.poisoned_ketchup_snow_cloud = {
|
||||
color: "#6e4e55",
|
||||
behavior: [
|
||||
"XX|XX|XX",
|
||||
"M1%5|CH:poisoned_ketchup_snow%0.05|M1%5",
|
||||
"XX|CH:poisoned_ketchup_snow%0.05|M1%2.5 AND BO",
|
||||
"XX|XX|XX",
|
||||
],
|
||||
category:"gases",
|
||||
|
|
@ -209,7 +250,8 @@ elements.poisoned_ketchup_snow_cloud = {
|
|||
tempHigh: 30,
|
||||
stateHigh: "poisoned_ketchup_cloud",
|
||||
state: "gas",
|
||||
density: 2,
|
||||
density: 0.55,
|
||||
ignoreAir: true,
|
||||
};
|
||||
elements.mayonnaise = {
|
||||
color: "#F2EEE9",
|
||||
|
|
@ -218,6 +260,8 @@ elements.mayonnaise = {
|
|||
category:"liquids",
|
||||
state: "liquid",
|
||||
density: 1000,
|
||||
stain: 0.05,
|
||||
isFood: true,
|
||||
};
|
||||
elements.mustard = {
|
||||
color: "#D8AD01",
|
||||
|
|
@ -226,34 +270,42 @@ elements.mustard = {
|
|||
category:"liquids",
|
||||
state: "liquid",
|
||||
density: 1052,
|
||||
stain: 0.05,
|
||||
isFood: true,
|
||||
};
|
||||
elements.ketchup_gas = {
|
||||
color: "#ffb5ad",
|
||||
behavior: behaviors.GAS,
|
||||
temp: 150,
|
||||
density: 0.6,
|
||||
state: "gas",
|
||||
tempLow: 100,
|
||||
tempLow: 95,
|
||||
stateLow: "ketchup",
|
||||
category: "gases",
|
||||
reactions: {
|
||||
"plague": { "elem1": "poisoned_ketchup_gas", "elem2": null},
|
||||
"ketchup_gas": { "elem1": null, "elem2": "ketchup_cloud", "chance":0.3, "y":[0,15] },
|
||||
"ketchup_gas": { "elem1": null, "elem2": "ketchup_cloud", "chance":0.3, "y":[0,15], "setting":"clouds" },
|
||||
"ketchup_cloud": { "elem1": "ketchup_cloud", "chance":0.4, "y":[0, 12], "setting":"clouds" },
|
||||
"ketchup_rain_cloud": { "elem1": "ketchup_rain_cloud", "chance":0.4, "y":[0, 12], "setting":"clouds" },
|
||||
"infection": { "elem1": "poisoned_ketchup_gas"},
|
||||
"radiation": { "elem1": "poisoned_ketchup_gas", chance:025},
|
||||
"fallout": { "elem1": "poisoned_ketchup_gas", chance:025},
|
||||
"radiation": { "elem1": "poisoned_ketchup_gas", chance:25},
|
||||
"fallout": { "elem1": "poisoned_ketchup_gas", chance:25},
|
||||
"gloomwind": { "elem1": "poisoned_ketchup_gas", "elem2": null},
|
||||
},
|
||||
};
|
||||
elements.poisoned_ketchup_gas = {
|
||||
color: "#e096a6",
|
||||
behavior: behaviors.POISONED_GAS,
|
||||
temp: 150,
|
||||
density: 0.6,
|
||||
state: "gas",
|
||||
tempLow: 100,
|
||||
tempLow: 95,
|
||||
stateLow: "poisoned_ketchup",
|
||||
category: "gases",
|
||||
reactions: {
|
||||
"poisoned_ketchup_gas": { "elem1": null, "elem2": "poisoned_ketchup_cloud", "chance":0.3, "y":[0,15] },
|
||||
"poisoned_ketchup_gas": { "elem1": null, "elem2": "poisoned_ketchup_cloud", "chance":0.3, "y":[0,15], "setting":"clouds" },
|
||||
"poisoned_ketchup_cloud": { "elem1": "poisoned_ketchup_cloud", "chance":0.4, "y":[0, 12], "setting":"clouds" },
|
||||
"ketchup_rain_cloud": { "elem1": "poisoned_ketchup_rain_cloud", "chance":0.4, "y":[0, 12], "setting":"clouds" },
|
||||
},
|
||||
};
|
||||
elements.fry_sauce = {
|
||||
|
|
@ -263,6 +315,8 @@ elements.fry_sauce = {
|
|||
category: "liquids",
|
||||
state: "liquid",
|
||||
density: 1149,
|
||||
stain: 0.05,
|
||||
isFood: true,
|
||||
};
|
||||
elements.ketchup_powder = {
|
||||
color: "#E06320",
|
||||
|
|
@ -271,12 +325,13 @@ elements.ketchup_powder = {
|
|||
reactions: {
|
||||
"plague": { "elem1": "poisoned_ketchup_powder", "elem2": null},
|
||||
"infection": { "elem1": "poisoned_ketchup_powder", "elem2": null},
|
||||
"radiation": { "elem1": "poisoned_ketchup_powder", chance:025},
|
||||
"fallout": { "elem1": "poisoned_ketchup_powder", chance:025},
|
||||
"radiation": { "elem1": "poisoned_ketchup_powder", chance:25},
|
||||
"fallout": { "elem1": "poisoned_ketchup_powder", chance:25},
|
||||
"gloomwind": { "elem1": "poisoned_ketchup_powder", "elem2": null},
|
||||
},
|
||||
state: "solid",
|
||||
category: "powders",
|
||||
isFood: true,
|
||||
};
|
||||
elements.poisoned_ketchup_powder = {
|
||||
color: "#e0204a",
|
||||
|
|
@ -285,44 +340,6 @@ elements.poisoned_ketchup_powder = {
|
|||
state: "solid",
|
||||
category: "powders",
|
||||
};
|
||||
elements.tomato = {
|
||||
color: "#B11E0C",
|
||||
behavior: behaviors.STURDYPOWDER,
|
||||
category: "food",
|
||||
density: 470,
|
||||
state: "solid",
|
||||
tempHigh: 400,
|
||||
stateHigh: "ash",
|
||||
reactions: {
|
||||
"rock": { "elem1": "tomato_sauce", "elem2": "rock" },
|
||||
},
|
||||
burn: 40,
|
||||
burnTime: 30,
|
||||
burnInto: "ash",
|
||||
};
|
||||
elements.tomato_sauce = {
|
||||
color: "#B72003",
|
||||
behavior: behaviors.LIQUID,
|
||||
category: "liquids",
|
||||
density: 1031,
|
||||
state: "liquid",
|
||||
reactions: {
|
||||
"sugar": { "elem1": "sugary_tomato_sauce", "elem2": null },
|
||||
},
|
||||
viscosity: 25000,
|
||||
};
|
||||
elements.sugary_tomato_sauce = {
|
||||
color: "#b53921",
|
||||
behavior: behaviors.LIQUID,
|
||||
category: "liquids",
|
||||
density: 1031,
|
||||
state: "liquid",
|
||||
reactions: {
|
||||
"vinegar": { "elem1": "ketchup", "elem2": null },
|
||||
},
|
||||
viscosity: 25000,
|
||||
hidden: true,
|
||||
};
|
||||
elements.cumin = {
|
||||
color: "#8B7778",
|
||||
behavior: behaviors.POWDER,
|
||||
|
|
@ -334,6 +351,7 @@ elements.cumin = {
|
|||
burn: 40,
|
||||
burnTime: 40,
|
||||
burnInto: "ash",
|
||||
isFood: true,
|
||||
};
|
||||
elements.eketchup_spout = {
|
||||
name: "E-Ketchup Spout",
|
||||
|
|
@ -364,6 +382,7 @@ elements.antiketchup = {
|
|||
category:"special",
|
||||
state: "liquid",
|
||||
density: 1092,
|
||||
stain: 0.05,
|
||||
};
|
||||
elements.dirty_ketchup = {
|
||||
color: "#851a0d",
|
||||
|
|
@ -377,6 +396,7 @@ elements.dirty_ketchup = {
|
|||
stateLow: "frozen_ketchup",
|
||||
density: 1140,
|
||||
hidden: true,
|
||||
stain: 0.05,
|
||||
};
|
||||
elements.ketchup_gold = {
|
||||
color: ["#eb8a8a", "#bf3939", "#ff6161"],
|
||||
|
|
@ -444,8 +464,24 @@ runAfterLoad(function() {
|
|||
|
||||
/*
|
||||
Changelog
|
||||
Mod made primarily by Nubo318. Contributors include deviantEquinox and Lily129.
|
||||
Version 1.3.1
|
||||
Mod made by Nubo318. Contributors include DeviantEquinox and An Orbit.
|
||||
Version 1.3.3
|
||||
|
||||
Version 1.3.3 (23rd of August 2023)
|
||||
+ All liquids added on this mod can now stain stuff, with the exception of molten metals
|
||||
+ Certain elements can now be mixed with dough and batter
|
||||
~ Fixed reactions that turned clouds into pyrocumulus when in contact with with smoke or ash
|
||||
~ Optimized the way in which new reactions of vanilla elements are coded
|
||||
~ Changed the initial temperature of multiple elements
|
||||
~ Fixed a bug that caused Ketchup Snow and its poisoned variant to not display their info properly
|
||||
~ Ketchup clouds now work more similarly to vanilla clouds
|
||||
|
||||
Version 1.3.2 (22nd of August 2023)
|
||||
- Removed some elements due to their inclusion or some form of it in the vanilla game, including:
|
||||
- Tomato
|
||||
- Tomato Sauce
|
||||
- Sugary Tomato Sauce
|
||||
- Removed a vanilla reaction which turned ketchup into sauce when exposed to radiation
|
||||
|
||||
Version 1.3.1 (20th of January 2022)
|
||||
~ Ketchup fairies are now killed by iron and silver
|
||||
|
|
|
|||
|
|
@ -0,0 +1,214 @@
|
|||
{
|
||||
const inject = () => {
|
||||
const gameDiv = document.getElementById("gameDiv");
|
||||
const parent = document.createElement("div");
|
||||
parent.id = "popUpParent";
|
||||
parent.style.display = "none";
|
||||
const inner = document.createElement("div");
|
||||
inner.className = "popUp";
|
||||
inner.id = "petaPopup";
|
||||
const title = document.createElement("span");
|
||||
title.id = "popUpTitle";
|
||||
title.style.fontSize = "1.5em";
|
||||
title.innerText = "title";
|
||||
inner.appendChild(title);
|
||||
const closeButton = document.createElement("button");
|
||||
closeButton.innerText = "-";
|
||||
closeButton.id = "popUpCloseButton";
|
||||
closeButton.className = "XButton";
|
||||
closeButton.onclick = () => {
|
||||
closePopUp();
|
||||
}
|
||||
inner.appendChild(closeButton);
|
||||
const text = document.createElement("div");
|
||||
text.id = "popUpText";
|
||||
text.style.marginTop = "20px";
|
||||
text.style.lineHeight = "1.5em";
|
||||
inner.appendChild(text);
|
||||
const progress = document.createElement("div");
|
||||
progress.className = "progressBar";
|
||||
const progressInner = document.createElement("div");
|
||||
progressInner.className = "progressBarInside";
|
||||
progressInner.id = "popUpProgressBar";
|
||||
progress.appendChild(progressInner);
|
||||
inner.appendChild(progress);
|
||||
parent.appendChild(inner);
|
||||
gameDiv.appendChild(parent);
|
||||
}
|
||||
|
||||
const injectCss = () => {
|
||||
const style = `.popUp {
|
||||
position: absolute;
|
||||
border: 1px solid #fff;
|
||||
left: 50%;
|
||||
top: 20%;
|
||||
transform: translate(-50%, 0%);
|
||||
width: 70%;
|
||||
height: 30%;
|
||||
padding: 10px;
|
||||
background-color: rgb(31, 31, 31);
|
||||
overflow-x: hidden;
|
||||
z-index: 12;
|
||||
}
|
||||
.progressBar {
|
||||
width: 100%;
|
||||
position: absolute;
|
||||
bottom: 0;
|
||||
left: 0;
|
||||
height: 20px;
|
||||
}
|
||||
.progressBarInside {
|
||||
width: 100%;
|
||||
height: 20px;
|
||||
background-color: white;
|
||||
}`;
|
||||
const styleElement = document.createElement("style");
|
||||
styleElement.innerHTML = style;
|
||||
document.head.appendChild(styleElement);
|
||||
}
|
||||
|
||||
function closePopUp() {
|
||||
const popUp = document.getElementById("popUpParent");
|
||||
let alpha = 100;
|
||||
const interval = setInterval(frame, 5);
|
||||
function frame() {
|
||||
if (alpha <= 0) {
|
||||
clearInterval(interval);
|
||||
popUp.style.display = "none";
|
||||
popUp.style.opacity = 1;
|
||||
} else {
|
||||
popUp.style.opacity = alpha / 100;
|
||||
alpha -= 5;
|
||||
}
|
||||
}
|
||||
showingPopUp = false;
|
||||
}
|
||||
|
||||
let intervalTime = 30;
|
||||
|
||||
function destroyGame() {
|
||||
selectElement("unknown");
|
||||
for (const i of pixelMap) {
|
||||
for (const pixel of i) {
|
||||
if (pixel) {
|
||||
deletePixel(pixel.x, pixel.y);
|
||||
}
|
||||
}
|
||||
}
|
||||
for (const element of Object.keys(elements)) {
|
||||
delete elements[element];
|
||||
const elem = document.getElementById("elementButton-" + element);
|
||||
if (elem) elem.remove();
|
||||
}
|
||||
for (let j = 0; j < document.getElementById("categoryControls").children.length; j++) {
|
||||
const i = parseInt(j);
|
||||
document.getElementById("categoryControls").children.item(i).innerText = ["DONT", "MESS", "WITH", "PETA"][i % 4];
|
||||
}
|
||||
document.getElementById("toolControls").remove();
|
||||
// breaks stuff
|
||||
mouse1Action = () => {};
|
||||
mouseAction = () => {};
|
||||
updateStats = () => {};
|
||||
pixelMap = [];
|
||||
document.getElementById('stats').innerHTML = "<span>xNONE,yNONE Pxls:-8 -Infinity tps NONE NO_VIEW THAT'S WHAT YOU GET";
|
||||
}
|
||||
|
||||
let showingPopUp = false;
|
||||
|
||||
function showPopUp(text, title) {
|
||||
const titleElement = document.getElementById("popUpTitle");
|
||||
titleElement.innerText = title;
|
||||
const textElement = document.getElementById("popUpText");
|
||||
textElement.innerText = text;
|
||||
const popUp = document.getElementById("popUpParent");
|
||||
popUp.style.display = "block";
|
||||
let width = 100;
|
||||
showingPopUp = true;
|
||||
const progressBar = document.getElementById("popUpProgressBar");
|
||||
const interval = setInterval(frame, intervalTime);
|
||||
function frame() {
|
||||
if (width <= 0 || !showingPopUp) {
|
||||
clearInterval(interval);
|
||||
setTimeout(() => {
|
||||
closePopUp();
|
||||
}, intervalTime);
|
||||
progressBar.style.width = "0%";
|
||||
} else {
|
||||
width--;
|
||||
progressBar.style.width = width + "%";
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
let warnings = 0;
|
||||
let happened = false;
|
||||
const forbiddenElements = ["meat", "rotten_meat", "cooked_meat", "frozen_meat", "milk", "cream", "fruit_milk", "pilk", "yogurt", "frozen_yogurt", "ice_cream", "egg", "yolk", "hard_yolk", "chocolate_milk", "eggnog"]
|
||||
|
||||
const messages = ["What are you trying to do?! That behavior is unnacceptable. Those animals didn't do anything to deserve this. You have {warning} warnings left before we delete half of your elements.",
|
||||
"You really think we can't do anything huh? Fuck around and find out. {warning} warnings left",
|
||||
"We have no words for you, how dare you?! {warning} warnings left",
|
||||
"That is completely unbelievable. {warning} warnings left",
|
||||
"That is your last chance. If you try it one more time, we WILL remove half of your elements. Do you really want to do it?",
|
||||
"You already lost half of your elements. Can't you just leave animals alone and use vegan products instead? We are left with no choice, we have to give you a warning. {warning} warnings remaining.",
|
||||
"You are leaving us with no choice. If you continue this behavior we will make your game completely unplayable. Do you really want to do this? {warning} warnings remaing.",
|
||||
"Are you even listening? Or are you just skipping our messages like there's nothing there. We are increasing the pop-up length and removing the close button, maybe now you will listen to us. {warning} warnings remaining.",
|
||||
"You only ever think about yourself, don't you? Do you really think that what you're doing currently is morally justifiable? You are just a coward, you can't admit that what you are doing is evil. Disgusting behavior. {warning} warnings remaining.",
|
||||
"That is your last chance. It's completely impossible to educate you, so if you try it one more time WE WILL TAKE ACTION! DO YOU UNDERSTAND THAT?!"];
|
||||
|
||||
selectElement = (element) => {
|
||||
if (showingPopUp) return;
|
||||
if (forbiddenElements.includes(element)) {
|
||||
console.log(warnings)
|
||||
if (warnings == 5 && !happened) {
|
||||
showPopUp("As you wish.", "From PETA");
|
||||
happened = true;
|
||||
let possibleElements = Object.keys(elements).filter(e => !forbiddenElements.includes(e) && currentElement != e);
|
||||
const initialLength = Math.floor(possibleElements.length / 2);
|
||||
while (possibleElements.length > initialLength) {
|
||||
const max = possibleElements.length;
|
||||
const randomElement = Math.floor(Math.random() * max);
|
||||
const element_ = possibleElements[randomElement];
|
||||
const elem = document.getElementById("elementButton-" + element_);
|
||||
if (elem) elem.remove();
|
||||
possibleElements = possibleElements.filter(e => e != element_);
|
||||
}
|
||||
} else if (warnings == 10) {
|
||||
destroyGame();
|
||||
} else {
|
||||
if (warnings == 7) {
|
||||
document.getElementById("popUpCloseButton").remove();
|
||||
intervalTime = 60;
|
||||
}
|
||||
showPopUp(messages[warnings].replace("{warning}", happened ? 10 - (warnings) : 5 - warnings), "From PETA");
|
||||
warnings++;
|
||||
}
|
||||
return;
|
||||
}
|
||||
if (elements[currentElement].onUnselect) {
|
||||
elements[currentElement].onUnselect();
|
||||
}
|
||||
var e1 = document.getElementById("elementButton-"+currentElement);
|
||||
if (e1 != null) { e1.setAttribute("current","false"); }
|
||||
currentElement = element;
|
||||
if (elements[element].customColor) {
|
||||
// show the colorSelector
|
||||
document.getElementById("colorSelector").style.display = "block";
|
||||
}
|
||||
else {
|
||||
// hide the colorSelector
|
||||
document.getElementById("colorSelector").style.display = "none";
|
||||
}
|
||||
if (elements[element].onSelect) {
|
||||
elements[element].onSelect();
|
||||
}
|
||||
var e2 = document.getElementById("elementButton-"+element);
|
||||
if (!e2) { return; }
|
||||
e2.setAttribute("current","true");
|
||||
// if e2 has the class "notify", remove it
|
||||
if (e2.classList.contains("notify")) {
|
||||
e2.classList.remove("notify");
|
||||
}
|
||||
}
|
||||
|
||||
runAfterLoadList.push(inject, injectCss);
|
||||
}
|
||||
Loading…
Reference in New Issue