7599 lines
312 KiB
HTML
7599 lines
312 KiB
HTML
<!DOCTYPE html>
|
||
<html>
|
||
|
||
<head>
|
||
<meta charset="utf-8">
|
||
<title>Sandboxels</title>
|
||
<meta name="description" content="A falling sand simulation game, with heat transfer, electricity, density, fire, explosions, and more.">
|
||
<meta name="keywords" content="falling sand, elements, pixel art, simulator, powder">
|
||
<meta name="author" content="R74n">
|
||
<meta name="copyright" content="R74n">
|
||
<link href="https://fonts.googleapis.com/css?family=Press+Start+2P" rel="stylesheet">
|
||
<meta name="viewport" content="width=device-width, initial-scale=1">
|
||
<meta name="robots" content="follow">
|
||
|
||
<!--Favicons-->
|
||
<link rel="apple-touch-icon" sizes="180x180" href="icons/apple-touch-icon.png?v=2">
|
||
<link rel="icon" type="image/png" sizes="32x32" href="icons/favicon-32x32.png?v=2">
|
||
<link rel="icon" type="image/png" sizes="16x16" href="icons/favicon-16x16.png?v=2">
|
||
<link rel="manifest" href="manifest.json">
|
||
<link rel="mask-icon" href="icons/safari-pinned-tab.svg?v=2" color="#2167ff">
|
||
<link rel="shortcut icon" href="icons/favicon.ico?v=2">
|
||
<meta name="msapplication-TileColor" content="#e6d577">
|
||
<meta name="theme-color" content="#000000">
|
||
|
||
<!--OpenGraph-->
|
||
<meta property="og:locale" content="en_US">
|
||
<meta property="og:type" content="website">
|
||
<meta property="og:title" content="Sandboxels">
|
||
<meta property="og:description" content="A falling sand simulation game, with heat transfer, electricity, density, fire, explosions, and more.">
|
||
<meta property="og:url" content="https://sandboxels.r74n.com">
|
||
<meta property="og:site_name" content="Sandboxels">
|
||
<meta property="og:image" content="https://sandboxels.r74n.com/icons/wallpaper.png">
|
||
<meta property="og:image:width" content="1980">
|
||
<meta property="og:image:height" content="971">
|
||
<meta property="og:image:type" content="image/png">
|
||
<meta property="og:image:alt" content="A rainforest made in Sandboxels">
|
||
|
||
<!--Twitter-->
|
||
<meta name="twitter:card" content="summary_large_image">
|
||
<meta name="twitter:description" content="A falling sand simulation game, with heat transfer, electricity, density, fire, explosions, and more.">
|
||
<meta name="twitter:title" content="Sandboxels">
|
||
<meta name="twitter:site:id" content="1436857621827530753">
|
||
<meta name="twitter:image" content="https://sandboxels.r74n.com/icons/card.png">
|
||
<meta name="twitter:image:alt" content="A rainforest made in Sandboxels">
|
||
<meta name="twitter:creator:id" content="1436857621827530753">
|
||
|
||
<!-- Schema -->
|
||
<script type="application/ld+json">
|
||
{
|
||
"@context": "https://schema.org",
|
||
"@type": ["VideoGame","MobileApplication","WebApplication"],
|
||
"gamePlatform":"Web Browser",
|
||
"image":"https://sandboxels.r74n.com/icons/icon.png",
|
||
"url": "https://sandboxels.r74n.com",
|
||
"name":"Sandboxels",
|
||
"author":"R74n",
|
||
"creator":"R74n",
|
||
"description":"Sandboxels is an in-browser falling sand simulation game, with mechanics such as heat simulation, electricity, density, chemical reactions, fire, and over 200 unique elements to play with.",
|
||
"offers":{
|
||
"@type":"Offer",
|
||
"price":"0",
|
||
"priceCurrency":"USD",
|
||
"availability":"https://schema.org/InStock"
|
||
},
|
||
"genre": "Falling-sand game",
|
||
"softwareVersion":"1.2",
|
||
"datePublished":"2021-12-15",
|
||
"dateCreated":"2021-12-15",
|
||
"gameTip":"https://sandboxels.r74n.com/controls.txt",
|
||
"screenshot": "https://sandboxels.r74n.com/icons/wallpaper.png",
|
||
"softwareRequirements": "HTML5",
|
||
"archivedAt": "https://web.archive.org/web/20211230010640000/https://sandboxels.r74n.com/",
|
||
"copyrightYear": 2022
|
||
}</script>
|
||
|
||
<script src="https://R74n.com/load.js"></script>
|
||
|
||
<style>
|
||
html, body {
|
||
width: 100%;
|
||
height: 100%;
|
||
margin: 0;
|
||
}
|
||
body {
|
||
font-family: 'Press Start 2P';
|
||
background-color: #000000;
|
||
color: #ffffff;
|
||
}
|
||
.pagetitle {
|
||
padding: 10px;
|
||
padding-bottom: 0px;
|
||
font-size: 0.75em;
|
||
position: absolute;
|
||
top: 0;
|
||
left: 0;
|
||
}
|
||
a {color: rgb(255, 0, 255);text-decoration: none;}
|
||
a:hover {color: rgb(255, 121, 255);}
|
||
a:active, a:hover:active {color: rgb(255, 179, 255);}
|
||
#gameDiv { /*game canvas*/
|
||
border: 1px solid #ffffff;
|
||
position: absolute;
|
||
left: 50%;
|
||
transform: translate(-50%, -0%);
|
||
-webkit-touch-callout: none; /* iOS Safari */
|
||
-webkit-user-select: none; /* Safari */
|
||
-khtml-user-select: none; /* Konqueror HTML */
|
||
-moz-user-select: none; /* Old versions of Firefox */
|
||
-ms-user-select: none; /* Internet Explorer/Edge */
|
||
user-select: none;
|
||
margin-top: 15px;
|
||
}
|
||
#infoParent, #modParent, #settingsParent {
|
||
display: none;
|
||
}
|
||
#infoScreen, #modManager, #settingsMenu {
|
||
border: 1px solid #ffffff;
|
||
position: absolute;
|
||
left: 50%;
|
||
transform: translate(-50%, 28%);
|
||
width: 95%;
|
||
height: 50%;
|
||
max-width: 700px;
|
||
padding: 10px;
|
||
background-color: rgb(31, 31, 31);
|
||
overflow-x: hidden;
|
||
}
|
||
.menuTitle {
|
||
font-size: 1.5em;
|
||
text-decoration: underline;
|
||
}
|
||
.menuText {
|
||
margin-top: 5px;
|
||
line-height: 1.5em;
|
||
}
|
||
#infoText {
|
||
white-space: pre-wrap;
|
||
}
|
||
.XButton {
|
||
position: absolute;
|
||
right: 0px;
|
||
top: 0px;
|
||
font-size: 2em;
|
||
background-color: rgb(100, 33, 33);
|
||
padding:5px;
|
||
text-align:center;
|
||
border: 1px solid #ffffff;
|
||
}
|
||
.XButton:hover {
|
||
background-color: rgb(200, 33, 33);
|
||
}
|
||
#infoSearch, #modManagerUrl {
|
||
position: absolute;
|
||
bottom: 50%;
|
||
width: 95%;
|
||
max-width: 700px;
|
||
height: 50px;
|
||
left: 50%;
|
||
transform: translate(-50%, 198.5%);
|
||
background-color: rgb(66, 66, 66);
|
||
color: white;
|
||
font-size: 1.5em;
|
||
padding: 8px;
|
||
font-family: 'Press Start 2P';
|
||
}
|
||
#infoSearch:focus, #modManagerUrl:focus {
|
||
outline: none;
|
||
}
|
||
/*#modManagerAdd {
|
||
position: absolute;
|
||
bottom: 25%;
|
||
right: 25%;
|
||
height: 50px;
|
||
width: 50px;
|
||
transform: translate(-25%, -25%);
|
||
background-color: rgb(0, 190, 32);
|
||
color: white;
|
||
font-size: 2em;
|
||
padding: 10px;
|
||
font-family: 'Press Start 2P';
|
||
}*/
|
||
#modManagerList {
|
||
margin-top: 20px;
|
||
}
|
||
#modManagerList li {
|
||
list-style-type: none;
|
||
position: relative;
|
||
}
|
||
#modManagerList li::before {
|
||
content: '•';
|
||
position: absolute;
|
||
left: -1.5em;
|
||
font-size: 1em;
|
||
font-family: 'Press Start 2P';
|
||
}
|
||
.removeModX {
|
||
color: red;
|
||
cursor: pointer;
|
||
}
|
||
.removeModX:hover {
|
||
color: rgb(255, 107, 107);
|
||
}
|
||
.infoLink {
|
||
color: rgb(116, 140, 221);
|
||
cursor: pointer;
|
||
text-decoration: underline;
|
||
}
|
||
button, input[type="submit"], input[type="reset"] {
|
||
background: none;
|
||
color: inherit;
|
||
border: none;
|
||
padding: 0;
|
||
font: inherit;
|
||
cursor: pointer;
|
||
}
|
||
.usingTab button:focus {
|
||
filter: brightness(75%);
|
||
outline: none;
|
||
}
|
||
#underBox {
|
||
position: absolute;
|
||
left: 50%;
|
||
transform: translate(-50%, -0%);
|
||
margin-top: 10px;
|
||
width: 100%;
|
||
}
|
||
#controls button {
|
||
padding: 5px 10px;
|
||
border-radius: 5px;
|
||
font-size: 1em;
|
||
text-shadow: 0.5px 1px 4px #000000;
|
||
color: rgba(255, 255, 255, 0.75);
|
||
border: 1px solid #797979;
|
||
margin: 0px 5px 5px 5px;
|
||
font-variant: small-caps;
|
||
}
|
||
#controls button.bright {
|
||
text-shadow: 0.5px 1px 4px #ffffff;
|
||
color: rgba(0, 0, 0, 0.75);
|
||
}
|
||
/*Darken when active*/
|
||
#controls button:active, #controls button:active:hover {
|
||
filter: brightness(60%);
|
||
}
|
||
#controls button:hover {
|
||
filter: brightness(90%);
|
||
}
|
||
#controls button:disabled {
|
||
cursor: not-allowed;
|
||
}
|
||
#controls button[current="true"], #controls button[on="true"] {
|
||
border: 1px solid #ffffff;
|
||
filter: brightness(110%);
|
||
box-shadow: 0 5px 15px rgba(255, 255, 255, .4);
|
||
color: rgba(255, 255, 255, 1);
|
||
}
|
||
#controls button.bright[current="true"] {
|
||
color: rgba(0, 0, 0, 1);
|
||
}
|
||
#controls button[on="true"] {
|
||
border-color:lime;
|
||
color:lime;
|
||
}
|
||
#controls div {
|
||
display:block;
|
||
}
|
||
.stat {
|
||
margin-right: 25px;
|
||
margin-bottom: 5px;
|
||
float:right;
|
||
}
|
||
#stats {
|
||
margin: 0px 5px 5px 5px;
|
||
font-size: 0.75em;
|
||
height: 2em;
|
||
width:100%;
|
||
}
|
||
/* screen size < 700px */
|
||
@media screen and (max-width: 700px) {
|
||
#stats {padding-bottom:2em;}
|
||
.pagetitle {
|
||
font-size: 1em;
|
||
padding-left: 0.25em;
|
||
}
|
||
}
|
||
/* screen size > 1325px, h1::after {content:" Sandboxels"} */
|
||
@media screen and (min-width: 1325px) {
|
||
.pagetitle::after {content:" Sandboxels"}
|
||
}
|
||
#stat-pos, #stat-pixels, #stat-shift, #stat-tps, #stat-ticks, #stat-view {
|
||
float:left;
|
||
}
|
||
.categoryName {
|
||
font-size: 0.75em;
|
||
text-transform: uppercase;
|
||
margin-left: 5px;
|
||
vertical-align: middle;
|
||
}
|
||
#extraInfo {
|
||
margin:5px
|
||
}
|
||
#toolControls, #category-tools {
|
||
white-space: nowrap;
|
||
overflow-x: auto;
|
||
overflow-y: hidden;
|
||
width: 100%;
|
||
position: absolute;
|
||
}
|
||
#toolControls {
|
||
margin-top: -3.5em;
|
||
z-index: 3;
|
||
}
|
||
#category-tools {
|
||
margin-top: -1.5em;
|
||
z-index: 2;
|
||
}
|
||
.category {
|
||
padding-top: 3em;
|
||
}
|
||
#categoryControls {
|
||
margin-top: 0.5em;
|
||
margin-bottom: 5px;
|
||
background-color: rgba(255, 255, 255, 0.125);
|
||
white-space: nowrap;
|
||
overflow-x: auto;
|
||
overflow-y: hidden;
|
||
width: 100%;
|
||
position: absolute;
|
||
z-index: 1;
|
||
padding-bottom:1px;
|
||
scrollbar-color: rgba(255, 255, 255, 0.25) rgba(255, 255, 255, 0.15);
|
||
scrollbar-width: thin;
|
||
}
|
||
#categoryControls button {
|
||
/* Borderless buttons */
|
||
border: none;
|
||
border-radius: 0;
|
||
padding-right: 8px;
|
||
margin: 0;
|
||
padding-top: 5px;
|
||
padding-bottom: 5px;
|
||
display: inline-block;
|
||
position: relative;
|
||
z-index:0;
|
||
}
|
||
#categoryControls button:not(:last-child) {
|
||
border-right: 1px solid rgba(255, 255, 255, 0.4);
|
||
}
|
||
#categoryControls button[current="true"] {
|
||
border: none;
|
||
background-color: rgba(255, 255, 255, 0.4);
|
||
}
|
||
/* Dark Gray X Scrollbar for categoryControls */
|
||
#categoryControls::-webkit-scrollbar {
|
||
width: 5px;
|
||
height: 8px;
|
||
background-color: rgba(255, 255, 255, 0.15);
|
||
}
|
||
#categoryControls::-webkit-scrollbar-thumb {
|
||
background-color: rgba(255, 255, 255, 0.25);
|
||
border-radius: 5px;
|
||
}
|
||
#categoryControls::-webkit-scrollbar-track {
|
||
box-shadow: inset 0 0 5px rgba(255, 255, 255, 0.15);
|
||
border-radius: 10px;
|
||
}
|
||
#categoryControls::-webkit-scrollbar-thumb:hover {
|
||
background-color: rgba(255, 255, 255, 0.3);
|
||
}
|
||
.category {
|
||
margin-top:3.1em;
|
||
position:relative;
|
||
display:flex;
|
||
flex-direction: column;
|
||
flex-wrap:wrap;
|
||
text-align:center;
|
||
}
|
||
button, input { /*Disable double tap zoom on mobile devices*/
|
||
touch-action: manipulation;
|
||
}
|
||
select {
|
||
background-color: black;
|
||
vertical-align: middle;
|
||
margin-left: 5px;
|
||
margin-right: 5px;
|
||
border: white 0.5px solid;
|
||
border-radius: 20px;
|
||
padding: 0.5em;
|
||
color: white;
|
||
}
|
||
</style>
|
||
|
||
<script>
|
||
// replaceAll polyfill
|
||
if (!String.prototype.replaceAll) {String.prototype.replaceAll = function(str, newStr){if (Object.prototype.toString.call(str).toLowerCase() === '[object regexp]') {return this.replace(str, newStr);}return this.replace(new RegExp(str, 'g'), newStr);};}
|
||
// requestFullScreen
|
||
function requestFullScreen(element) { /* Supports most browsers and their versions.*/ var requestMethod = element.requestFullScreen || element.webkitRequestFullScreen || element.mozRequestFullScreen || element.msRequestFullScreen; if (requestMethod) { /*Native full screen.*/ requestMethod.call(element); } else if (typeof window.ActiveXObject !== "undefined") { /*Older IE.*/ var wscript = new ActiveXObject("WScript.Shell"); if (wscript !== null) { wscript.SendKeys("{F11}"); } } }
|
||
</script>
|
||
|
||
<script> // Mod Loader
|
||
runAfterLoadList = [];
|
||
// runAfterLoad() takes a function and adds it to the runAfterLoadList.
|
||
function runAfterLoad(func) {
|
||
runAfterLoadList.push(func);
|
||
}
|
||
// If the localStorage key "enabledMods" exists, load it as an array.
|
||
// If it doesn't exist, create an empty array.
|
||
enabledMods = localStorage.getItem("enabledMods") ? JSON.parse(localStorage.getItem("enabledMods")) : [];
|
||
// Run all scripts in the enabledMods array, if it fails print to console
|
||
for (var i = 0; i < enabledMods.length; i++) {
|
||
try {
|
||
var script = document.createElement('script');
|
||
var src = enabledMods[i];
|
||
script.src = src;
|
||
document.head.appendChild(script);
|
||
} catch (e) {
|
||
console.log("Error in mod: " + enabledMods[i]);
|
||
console.log(e);
|
||
}
|
||
}
|
||
</script>
|
||
|
||
<script>
|
||
// If settings is in localStorage, load it. If not, create an empty object.
|
||
settings = localStorage.getItem("settings") ? JSON.parse(localStorage.getItem("settings")) : {};
|
||
function saveSettings() {
|
||
localStorage.setItem("settings", JSON.stringify(settings));
|
||
}
|
||
window.addEventListener("load", function() {
|
||
// Loop through all the elements with setting-span class.
|
||
// If the span's setting attribute is in settings, set the first select or input to the value of the setting.
|
||
var settingSpans = document.getElementsByClassName("setting-span");
|
||
for (var i = 0; i < settingSpans.length; i++) {
|
||
var setting = settingSpans[i].getAttribute("setting");
|
||
if (setting in settings) {
|
||
var settingValue = settings[setting];
|
||
var settingElements = settingSpans[i].getElementsByTagName("select") || settingSpans[i].getElementsByTagName("input");
|
||
if (settingElements.length > 0) {
|
||
settingElements[0].value = settingValue;
|
||
}
|
||
}
|
||
}
|
||
});
|
||
|
||
behaviors = {
|
||
POWDER: [
|
||
"XX|XX|XX",
|
||
"XX|XX|XX",
|
||
"M2|M1|M2",
|
||
],
|
||
AGPOWDER: [
|
||
"M2|M1|M2",
|
||
"XX|XX|XX",
|
||
"XX|XX|XX",
|
||
],
|
||
LIQUID: [
|
||
"XX|XX|XX",
|
||
"M2|XX|M2",
|
||
"M1|M1|M1",
|
||
],
|
||
SLIDE: [
|
||
"XX|XX|XX",
|
||
"XX|XX|M2 AND BO",
|
||
"XX|M1|M1",
|
||
],
|
||
AGLIQUID: [
|
||
"M1|M1|M1",
|
||
"M2|XX|M2",
|
||
"XX|XX|XX",
|
||
],
|
||
WALL: [
|
||
"XX|XX|XX",
|
||
"XX|XX|XX",
|
||
"XX|XX|XX",
|
||
],
|
||
UL_UR: [
|
||
"M1|M1|M1",
|
||
"M2|XX|M2",
|
||
"XX|M2|XX",
|
||
],
|
||
GAS: [
|
||
"M2|M1|M2",
|
||
"M1|XX|M1",
|
||
"M2|M1|M2",
|
||
],
|
||
DGAS: [
|
||
"M2|M1|M2",
|
||
"M1|DL%5|M1",
|
||
"M2|M1|M2",
|
||
],
|
||
SUPPORT: [
|
||
"XX|XX|XX",
|
||
"SP|XX|SP",
|
||
"XX|M1|XX",
|
||
],
|
||
SUPPORTPOWDER: [
|
||
"XX|XX|XX",
|
||
"SP|XX|SP",
|
||
"M2|M1|M2",
|
||
],
|
||
DELETE: [
|
||
"XX|DL|XX",
|
||
"DL|XX|DL",
|
||
"XX|DL|XX",
|
||
],
|
||
FILL: [
|
||
"XX|CL|XX",
|
||
"CL|XX|CL",
|
||
"XX|CL|XX",
|
||
],
|
||
CLONER: [
|
||
"XX|CF|XX",
|
||
"CF|XX|CF",
|
||
"XX|CF|XX",
|
||
],
|
||
STURDYPOWDER: [
|
||
"XX|XX|XX",
|
||
"XX|XX|XX",
|
||
"XX|M1|XX",
|
||
],
|
||
SELFDELETE: [
|
||
"XX|XX|XX",
|
||
"XX|DL|XX",
|
||
"XX|XX|XX",
|
||
],
|
||
FOAM: [
|
||
"XX|XX|XX",
|
||
"XX|DL%5|XX",
|
||
"M2%25|M1%25|M2%25",
|
||
],
|
||
BUBBLE: [
|
||
"XX|XX|XX",
|
||
"XX|DL%0.25 AND FX%1|M1%5",
|
||
"XX|M1%1|M1%2",
|
||
],
|
||
STICKY: [
|
||
"XX|ST|XX",
|
||
"ST|XX|ST",
|
||
"XX|ST AND M1|XX",
|
||
],
|
||
MOLTEN: [
|
||
"XX|CR:fire%2.5|XX",
|
||
"M2|XX|M2",
|
||
"M1|M1|M1",
|
||
],
|
||
RADPOWDER: [
|
||
"XX|CR:radiation%2|XX",
|
||
"CR:radiation%2|XX|CR:radiation%2",
|
||
"M2|M1|M2",
|
||
],
|
||
RADMOLTEN: [
|
||
"XX|CR:fire,radiation%4.5|XX",
|
||
"M2 AND CR:radiation%2|XX|M2 AND CR:radiation%2",
|
||
"M1|M1|M1",
|
||
],
|
||
RADLIQUID: [
|
||
"XX|CR:radiation%2|XX",
|
||
"M2 AND CR:radiation%2|XX|M2 AND CR:radiation%2",
|
||
"M1|M1|M1",
|
||
],
|
||
}
|
||
eLists = {
|
||
"ANIMAL": ["flea","ant","fly","firefly","bee","frog","fish","worm","termite","rat","slug","snail"],
|
||
"CLEANANIMAL": ["ant","firefly","bee","frog","fish"],
|
||
}
|
||
|
||
//airDensity = 1.225; // kg/m^3
|
||
airTemp = 20; // Celsius
|
||
|
||
// Element Properties
|
||
// name - display name of the element [optional]
|
||
// color - color of the element's pixel
|
||
// behavior - behavior of the element
|
||
// ignore - elements to ignore in behavior [must be an array]
|
||
// category - category in which the element will show up in
|
||
// density - density of the element [only used for movable elements] (kg/m^3)
|
||
// state - solid, liquid, or gas [only used for movable elements]
|
||
// reactions - instructions for when elements attempt to move onto each other (object)
|
||
// conduct - conductivity of the element (0-1)
|
||
// behaviorOn - behavior to override when powered
|
||
// colorOn - color to change to when powered
|
||
// temp - default temperature of the element (Celsius)
|
||
// tempHigh - highest temperature before state change (Celsius)
|
||
// tempLow - lowest temperature before state change (Celsius)
|
||
// stateHigh - element transformed into when tempHigh is reached
|
||
// stateLow - element transformed into when tempLow is reached
|
||
// viscosity - how slow a liquid will move (higher = slower) (cps)
|
||
// burn - chance of burning per tick (0-100) (%)
|
||
// burnTime - time to burn (ticks)
|
||
// burnInto - element to turn into after burning
|
||
// fireColor - color of the flame given off when burning
|
||
// burning - whether the element is burning on creation
|
||
// charge - charge of the element on creation
|
||
// hardness - chance of resisting damage (0-1)
|
||
elements = {
|
||
"heat": { //hard-coded
|
||
color: "#ff0000",
|
||
behavior: [
|
||
"HT:2|HT:2|HT:2",
|
||
"HT:2|HT:2|HT:2",
|
||
"HT:2|HT:2|HT:2",
|
||
],
|
||
temp: 2,
|
||
category: "tools",
|
||
insulate:true,
|
||
},
|
||
"cool": { //hard-coded
|
||
color: "#0000ff",
|
||
behavior: [
|
||
"CO:2|CO:2|CO:2",
|
||
"CO:2|CO:2|CO:2",
|
||
"CO:2|CO:2|CO:2",
|
||
],
|
||
temp: -2,
|
||
category: "tools",
|
||
insulate:true,
|
||
},
|
||
"erase": { //hard-coded
|
||
color: "#fdb5ff",
|
||
behavior: [
|
||
"DL|DL|DL",
|
||
"DL|DL|DL",
|
||
"DL|DL|DL",
|
||
],
|
||
category: "tools",
|
||
},
|
||
"pick": { //hard-coded
|
||
color: ["#fa9b9b","#fae99b","#9bfab7","#9b9dfa"],
|
||
behavior: [
|
||
"CF|CF|CF",
|
||
"CF|DL%5|CF",
|
||
"CF|CF|CF",
|
||
],
|
||
category: "tools",
|
||
},
|
||
"mix": { //hard-coded
|
||
color: ["#fff4b5","#a6a6a6"],
|
||
behavior: [
|
||
"SW|SW|SW",
|
||
"SW|DL%5|SW",
|
||
"SW|SW|SW",
|
||
],
|
||
category: "tools",
|
||
},
|
||
"lookup": { //hard-coded
|
||
color: ["#919c9c","#72abab","#919c9c"],
|
||
behavior: behaviors.WALL,
|
||
category: "tools",
|
||
},
|
||
"shock": { //hard-coded
|
||
color: "#ffff00",
|
||
behavior: [
|
||
"SH|SH|SH",
|
||
"SH|DL%5|SH",
|
||
"SH|SH|SH",
|
||
],
|
||
category: "tools",
|
||
},
|
||
"sand": {
|
||
color: "#e6d577",
|
||
behavior: behaviors.POWDER,
|
||
tempHigh: 1700,
|
||
stateHigh: "molten_glass",
|
||
category: "land",
|
||
state: "solid",
|
||
density: 1602,
|
||
},
|
||
/* Tick Examples
|
||
"tick_sand": {
|
||
color: "#e6d577",
|
||
tick: function(pixel) {
|
||
tryMove(pixel, pixel.x, pixel.y+1);
|
||
doHeat(pixel);
|
||
},
|
||
tempHigh: 1700,
|
||
stateHigh: "molten_glass",
|
||
category: "land",
|
||
state: "solid",
|
||
density: 1602,
|
||
hidden: true,
|
||
category: "land",
|
||
},
|
||
"tick_wood": {
|
||
color: "#a0522d",
|
||
tick: function(pixel) {
|
||
doBurning(pixel);
|
||
doHeat(pixel);
|
||
},
|
||
tempHigh: 400,
|
||
stateHigh: "fire",
|
||
category: "solids",
|
||
burn: 5,
|
||
burnTime: 300,
|
||
burnInto: ["ash","charcoal","fire"],
|
||
state: "solid",
|
||
hardness: 0.15,
|
||
breakInto: "sawdust",
|
||
hidden: true,
|
||
category: "solids",
|
||
},
|
||
"tick_wall": {
|
||
color: "#808080",
|
||
category: "solids",
|
||
hidden: true,
|
||
},
|
||
"tick_props": {
|
||
color: "#ffffff",
|
||
tick: function(pixel) {
|
||
if (tryMove(pixel, pixel.x, pixel.y+1)) {
|
||
pixel.moves += 1;
|
||
}
|
||
pixel.age += 1;
|
||
if (pixel.moves > 20) { // This pixel will delete itself if it moves 20 times
|
||
deletePixel(pixel.x, pixel.y);
|
||
}
|
||
},
|
||
properties: { // Default properties to set when the pixel is created:
|
||
"moves": 0,
|
||
"age": 0,
|
||
},
|
||
category: "powders",
|
||
hidden: true,
|
||
},
|
||
*/
|
||
"water": {
|
||
color: "#2167ff",
|
||
behavior: behaviors.LIQUID,
|
||
tempHigh: 100,
|
||
stateHigh: "steam",
|
||
tempLow: 0,
|
||
stateLow: "ice",
|
||
viscosity: 1,
|
||
category: "liquids",
|
||
reactions: {
|
||
"dirt": { // React with (water reacts with dirt to make mud)
|
||
"elem1": null, // First element transforms into; in this case, water deletes itself
|
||
"elem2": "mud", // Second element transforms into; in this case, dirt turns to mud
|
||
},
|
||
"sand": { "elem1": null, "elem2": "wet_sand", },
|
||
"salt": { "elem1": "salt_water", "elem2": null, },
|
||
"sugar": { "elem1": "sugar_water", "elem2": null, },
|
||
"dust": { "elem1": "dirty_water", "elem2": null, },
|
||
"ash": { "elem1": "dirty_water", "elem2": null, },
|
||
"cyanide": { "elem1": "dirty_water", "elem2": null, },
|
||
"carbon_dioxide": { "elem1": "dirty_water", "elem2": null, },
|
||
"sulfur": { "elem1": "dirty_water", "elem2": null, },
|
||
"rat": { "elem1": "dirty_water", chance:0.005 },
|
||
"plague": { "elem1": "dirty_water", "elem2": null, },
|
||
"rust": { "elem1": "dirty_water", chance:0.005 },
|
||
"fallout": { "elem1": "dirty_water", chance:0.25 },
|
||
"radiation": { "elem1": "dirty_water", chance:0.25 },
|
||
"quicklime": { "elem1": null, "elem2": "slaked_lime", },
|
||
"rock": { "elem2": "wet_sand", "chance": 0.00035 },
|
||
"ruins": { "elem2": "rock", "chance": 0.00035 },
|
||
},
|
||
state: "liquid",
|
||
density: 997,
|
||
conduct: 0.02,
|
||
},
|
||
"salt_water": {
|
||
color: "#4d85ff",
|
||
behavior: behaviors.LIQUID,
|
||
tempHigh: 102,
|
||
stateHigh: ["steam","salt"],
|
||
tempLow: -2,
|
||
stateLow: "ice",
|
||
viscosity: 2,
|
||
category: "liquids",
|
||
reactions: {
|
||
"dirt": { "elem1": null, "elem2": "mud" },
|
||
"sand": { "elem1": null, "elem2": "wet_sand", },
|
||
"dust": { "elem1": "dirty_water", "elem2": null, },
|
||
"ash": { "elem1": "dirty_water", "elem2": null, },
|
||
"carbon_dioxide": { "elem1": "dirty_water", "elem2": null, },
|
||
"sulfur": { "elem1": "dirty_water", "elem2": null, },
|
||
"charcoal": { "elem1": "dirty_water", chance:0.005 },
|
||
"rat": { "elem1": "dirty_water", chance:0.005 },
|
||
"plague": { "elem1": "dirty_water", "elem2": null, },
|
||
"fallout": { "elem1": "dirty_water", chance:0.25 },
|
||
"radiation": { "elem1": "dirty_water", chance:0.25 },
|
||
"rust": { "elem1": "dirty_water", chance:0.005 },
|
||
"quicklime": { "elem1": null, "elem2": "slaked_lime", },
|
||
"rock": { "elem2": "wet_sand", "chance": 0.0005 },
|
||
},
|
||
state: "liquid",
|
||
density: 1026,
|
||
conduct: 0.1,
|
||
},
|
||
"sugar_water": {
|
||
color: "#8eaae6",
|
||
behavior: behaviors.LIQUID,
|
||
tempHigh: 105,
|
||
stateHigh: ["steam","sugar"],
|
||
tempLow: -5,
|
||
stateLow: "ice",
|
||
viscosity: 5,
|
||
category: "liquids",
|
||
reactions: {
|
||
"dirt": { "elem1": null, "elem2": "mud" },
|
||
"sand": { "elem1": null, "elem2": "wet_sand", },
|
||
"dust": { "elem1": "dirty_water", "elem2": null, },
|
||
"ash": { "elem1": "dirty_water", "elem2": null, },
|
||
"carbon_dioxide": { "elem1": "dirty_water", "elem2": null, },
|
||
"sulfur": { "elem1": "dirty_water", "elem2": null, },
|
||
"charcoal": { "elem1": "dirty_water", chance:0.005 },
|
||
"rat": { "elem1": "dirty_water", chance:0.005 },
|
||
"plague": { "elem1": "dirty_water", "elem2": null, },
|
||
"fallout": { "elem1": "dirty_water", chance:0.25 },
|
||
"radiation": { "elem1": "dirty_water", chance:0.25 },
|
||
"rust": { "elem1": "dirty_water", chance:0.005 },
|
||
"rock": { "elem2": "wet_sand", "chance": 0.0004 },
|
||
},
|
||
hidden: true,
|
||
state: "liquid",
|
||
density: 1026,
|
||
conduct: 0.05,
|
||
},
|
||
"dirty_water": {
|
||
color: ["#0e824e","#07755a","#0c6934"],
|
||
behavior: behaviors.LIQUID,
|
||
tempHigh: 105,
|
||
stateHigh: ["steam","carbon_dioxide"],
|
||
tempLow: -5,
|
||
stateLow: "ice",
|
||
viscosity: 10,
|
||
category: "liquids",
|
||
reactions: {
|
||
"dirt": { "elem1": null, "elem2": "mud" },
|
||
"sand": { "elem1": null, "elem2": "wet_sand", },
|
||
"rock": { "elem2": "wet_sand", "chance": 0.0004 },
|
||
"plant": { "elem1":"water", "chance":0.05 },
|
||
"algae": { "elem1":"water", "chance":0.05 },
|
||
"charcoal": { "elem1":"water", "chance":0.02 },
|
||
"gravel": { "elem1":"water", "chance":0.01 },
|
||
},
|
||
hidden: true,
|
||
state: "liquid",
|
||
density: 1050,
|
||
conduct: 0.1,
|
||
},
|
||
"dirt": {
|
||
color: ["#9e6b4b","#9e6b4b","#9e6b4b","#9e6b4b","#9e6b4b","#9e6b4b","#9e6b4b","#9e6b4b","#9e6b4b","#9e6b4b","#9e6b4b","#9e6b4b","#9e6b4b","#9e6b4b","#a88c7b"],
|
||
behavior: behaviors.POWDER,
|
||
tempHigh:1200,
|
||
tempLow: -50,
|
||
stateLow: "permafrost",
|
||
category:"land",
|
||
state: "solid",
|
||
density: 1220,
|
||
},
|
||
"mud": {
|
||
color: "#382417",
|
||
behavior: behaviors.STURDYPOWDER,
|
||
reactions: {
|
||
"dirt": { "elem1":"dirt", "elem2":"mud", "chance":0.0005, "oneway":true },
|
||
"sand": { "elem1":"dirt", "elem2":"wet_sand", "chance":0.0005, "oneway":true },
|
||
},
|
||
tempHigh: 100,
|
||
stateHigh: "mudstone",
|
||
tempLow: -50,
|
||
stateLow: "permafrost",
|
||
category: "land",
|
||
state: "solid",
|
||
density: 1730,
|
||
},
|
||
"wet_sand": {
|
||
color: ["#a19348","#b5a85e"],
|
||
behavior: behaviors.STURDYPOWDER,
|
||
reactions: {
|
||
"sand": { "elem1":"sand", "elem2":"wet_sand", "chance":0.0005, "oneway":true },
|
||
"dirt": { "elem1":"sand", "elem2":"mud", "chance":0.0005, "oneway":true },
|
||
},
|
||
tempHigh: 100,
|
||
stateHigh: "packed_sand",
|
||
category: "land",
|
||
state: "solid",
|
||
density: 1905,
|
||
},
|
||
"rock": {
|
||
color: ["#808080","#4f4f4f","#949494"],
|
||
behavior: behaviors.POWDER,
|
||
tempHigh: 950,
|
||
stateHigh: "magma",
|
||
category: "land",
|
||
state: "solid",
|
||
density: 2550,
|
||
hardness: 0.5,
|
||
breakInto: ["sand","gravel"],
|
||
},
|
||
"mudstone": {
|
||
color: "#4a341e",
|
||
behavior: behaviors.SUPPORT,
|
||
tempHigh:1200,
|
||
stateHigh: "molten_dirt",
|
||
category: "land",
|
||
state: "solid",
|
||
density: 1250,
|
||
breakInto: "dirt",
|
||
},
|
||
"packed_sand": {
|
||
color: "#948b5a",
|
||
behavior: behaviors.SUPPORT,
|
||
tempHigh:1700,
|
||
stateHigh: "molten_glass",
|
||
category: "land",
|
||
state: "solid",
|
||
density: 1682,
|
||
breakInto: "sand",
|
||
},
|
||
"plant": {
|
||
color: "#00bf00",
|
||
behavior: behaviors.WALL,
|
||
category:"life",
|
||
tempHigh: 100,
|
||
stateHigh: "dead_plant",
|
||
tempLow: -1.66,
|
||
stateLow: "frozen_plant",
|
||
burn:65,
|
||
burnTime:60,
|
||
burnInto: "dead_plant",
|
||
state: "solid",
|
||
density: 1050,
|
||
},
|
||
"dead_plant": {
|
||
color: ["#826521","#826021","#825321","#70360c"],
|
||
behavior: [
|
||
"XX|XX|XX",
|
||
"XX|XX|XX",
|
||
"M2|M1|M2",
|
||
],
|
||
category:"life",
|
||
tempHigh: 300,
|
||
stateHigh: "fire",
|
||
tempLow: -2,
|
||
stateLow: "frozen_plant",
|
||
burn:85,
|
||
burnTime:45,
|
||
state: "solid",
|
||
density: 1050,
|
||
hidden: true,
|
||
},
|
||
"frozen_plant": {
|
||
color: "#00bf8c",
|
||
behavior: behaviors.WALL,
|
||
category:"life",
|
||
tempHigh: 7,
|
||
stateHigh: "dead_plant",
|
||
state: "solid",
|
||
density: 1050,
|
||
hidden: true,
|
||
},
|
||
"grass": {
|
||
color: ["#439809","#258B08","#118511","#127B12","#136D14"],
|
||
behavior: [
|
||
"XX|XX|XX",
|
||
"XX|XX|XX",
|
||
"XX|M1|XX",
|
||
],
|
||
tempHigh: 100,
|
||
stateHigh: "dead_plant",
|
||
tempLow: -2,
|
||
stateLow: "frozen_plant",
|
||
burn:50,
|
||
burnTime:20,
|
||
category:"life",
|
||
state: "solid",
|
||
density: 1400,
|
||
},
|
||
"algae": {
|
||
color: ["#395706","#6F9315","#9DCA19"],
|
||
behavior: [
|
||
"XX|XX|XX",
|
||
"SW:water,salt_water,sugar_water,dirty_water%1|XX|SW:water,salt_water,sugar_water,dirty_water%1",
|
||
"SW:water,salt_water,sugar_water,dirty_water%10|M1|SW:water,salt_water,sugar_water,dirty_water%10",
|
||
],
|
||
reactions: {
|
||
"wood": { "elem1":"lichen" }
|
||
},
|
||
category:"life",
|
||
tempHigh: 225,
|
||
stateHigh: "fire",
|
||
burn:95,
|
||
burnTime:20,
|
||
state: "solid",
|
||
density: 920,
|
||
},
|
||
"concrete": {
|
||
color: "#ababab",
|
||
behavior: behaviors.SUPPORT,
|
||
tempHigh: 1500,
|
||
stateHigh: "magma",
|
||
category: "powders",
|
||
state: "solid",
|
||
density: 2400,
|
||
hardness: 0.5,
|
||
breakInto: "dust",
|
||
},
|
||
"wall": {
|
||
color: "#808080",
|
||
behavior: behaviors.WALL,
|
||
category: "solids",
|
||
insulate: true,
|
||
hardness: 1,
|
||
},
|
||
"fire": {
|
||
color: ["#ff6b21","#ffa600","#ff4000"],
|
||
behavior: behaviors.UL_UR,
|
||
reactions: {
|
||
"water": { "elem1": "smoke" },
|
||
},
|
||
temp:600,
|
||
tempLow:100,
|
||
stateLow: "smoke",
|
||
tempHigh: 7000,
|
||
stateHigh: "plasma",
|
||
category: "energy",
|
||
burning: true,
|
||
burnTime: 25,
|
||
burnInto: "smoke",
|
||
state: "gas",
|
||
density: 0.1,
|
||
},
|
||
"bomb": {
|
||
color: "#524c41",
|
||
behavior: [
|
||
"XX|EX:10|XX",
|
||
"XX|XX|XX",
|
||
"M2|M1 AND EX:10|M2",
|
||
],
|
||
category: "weapons",
|
||
state: "solid",
|
||
density: 1300,
|
||
excludeRandom: true,
|
||
},
|
||
"steam": {
|
||
color: "#abd6ff",
|
||
behavior: behaviors.GAS,
|
||
reactions: {
|
||
"steam": { "elem1": null, "elem2": "rain_cloud", "chance":0.3, "y":[0,15] },
|
||
"rain_cloud": { "elem1": "rain_cloud", "chance":0.4, "y":[0,15] },
|
||
"snow_cloud": { "elem1": "rain_cloud", "chance":0.4, "y":[0,15] },
|
||
"pyrocumulus": { "elem1": "rain_cloud", "chance":0.4, "y":[0,15] },
|
||
"fire_cloud": { "elem1": "rain_cloud", "elem2": "pyrocumulus", "chance":0.4, "y":[0,15] },
|
||
},
|
||
temp: 100,
|
||
tempLow: 95,
|
||
stateLow: "water",
|
||
category: "gases",
|
||
state: "gas",
|
||
density: 0.6,
|
||
},
|
||
"ice": {
|
||
color: "#c5e9f0",
|
||
behavior: behaviors.WALL,
|
||
temp: 0,
|
||
tempHigh: 5,
|
||
stateHigh: "water",
|
||
category: "solids",
|
||
state: "solid",
|
||
density: 917,
|
||
breakInto: "snow",
|
||
},
|
||
"snow": {
|
||
color: "#e1f8fc",
|
||
behavior: behaviors.POWDER,
|
||
temp: 0,
|
||
tempHigh: 5,
|
||
stateHigh: "water",
|
||
category: "land",
|
||
state: "solid",
|
||
density: 100,
|
||
},
|
||
"packed_snow": {
|
||
color: "#bcdde3",
|
||
behavior: behaviors.SUPPORTPOWDER,
|
||
temp: 0,
|
||
tempHigh: 20,
|
||
stateHigh: "water",
|
||
category: "land",
|
||
state: "solid",
|
||
density: 400,
|
||
},
|
||
"wood": {
|
||
color: "#a0522d",
|
||
behavior: behaviors.WALL,
|
||
tempHigh: 400,
|
||
stateHigh: "fire",
|
||
category: "solids",
|
||
burn: 5,
|
||
burnTime: 300,
|
||
burnInto: ["ember","charcoal","fire"],
|
||
state: "solid",
|
||
hardness: 0.15,
|
||
breakInto: "sawdust",
|
||
},
|
||
"smoke": {
|
||
color: "#383838",
|
||
behavior: behaviors.DGAS,
|
||
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] },
|
||
},
|
||
temp: 114,
|
||
tempHigh: 605,
|
||
stateHigh: "fire",
|
||
category: "gases",
|
||
state: "gas",
|
||
density: 1180,
|
||
},
|
||
"magma": {
|
||
color: ["#ff6f00","#ff8c00","#ff4d00"],
|
||
behavior: behaviors.MOLTEN,
|
||
reactions: {
|
||
"ice": { "elem1": "basalt" },
|
||
},
|
||
temp: 950,
|
||
tempLow: 800,
|
||
stateLow: ["basalt","basalt","basalt","rock"],
|
||
viscosity: 10000,
|
||
category: "liquids",
|
||
state: "liquid",
|
||
density: 2725,
|
||
},
|
||
"plasma": {
|
||
color: ["#8800ff","#b184d9","#8800ff"],
|
||
behavior: behaviors.DGAS,
|
||
behaviorOn: [
|
||
"M2|M1|M2",
|
||
"CL%5 AND M1|XX|CL%5 AND M1",
|
||
"M2|M1|M2",
|
||
],
|
||
temp:7065,
|
||
tempLow:5000,
|
||
stateLow: "fire",
|
||
category: "energy",
|
||
state: "gas",
|
||
density: 1,
|
||
charge: 0.5,
|
||
conduct: 1,
|
||
},
|
||
"cold_fire": {
|
||
color: ["#21cbff","#006aff","#00ffff"],
|
||
behavior: [
|
||
"M1|M1|M1",
|
||
"M2|CH:smoke%8|M2",
|
||
"XX|M2|XX",
|
||
],
|
||
reactions: {
|
||
"fire": { "elem1": "smoke", "elem2": "smoke" },
|
||
"plasma": { "elem1": "light", "elem2": "light" },
|
||
},
|
||
temp:-200,
|
||
tempHigh:0,
|
||
stateHigh: "smoke",
|
||
category: "energy",
|
||
state: "gas",
|
||
density: 0.2,
|
||
},
|
||
"glass": {
|
||
color: ["#5e807d","#679e99"],
|
||
behavior: behaviors.WALL,
|
||
tempHigh: 1500,
|
||
category: "solids",
|
||
state: "solid",
|
||
density: 2500,
|
||
breakInto: "glass_shard",
|
||
},
|
||
"meat": {
|
||
color: ["#9E4839","#BA6449","#D2856C","#A14940"],
|
||
behavior: [
|
||
"XX|XX|XX",
|
||
"SP|CH:rotten_meat%0.00025|SP",
|
||
"XX|M1|XX",
|
||
],
|
||
tempHigh: 80,
|
||
stateHigh: "cooked_meat",
|
||
tempLow: -18,
|
||
stateLow: "frozen_meat",
|
||
category:"food",
|
||
burn:25,
|
||
burnTime:200,
|
||
burnInto:"cooked_meat",
|
||
state: "solid",
|
||
density: 1019.5,
|
||
conduct: 0.2,
|
||
},
|
||
"rotten_meat": {
|
||
color: ["#9ab865","#b8b165","#b89765"],
|
||
behavior: [
|
||
"XX|CR:plague%0.25|XX",
|
||
"SP|XX|SP",
|
||
"XX|M1|XX",
|
||
],
|
||
tempHigh: 120,
|
||
stateHigh: "plague",
|
||
category:"food",
|
||
hidden: true,
|
||
burn:25,
|
||
burnTime:200,
|
||
burnInto:"plague",
|
||
state: "solid",
|
||
density: 1005,
|
||
conduct: 0.1,
|
||
},
|
||
"cooked_meat": {
|
||
color: ["#AE7D5B","#9B6D54","#7E4D31"],
|
||
behavior: behaviors.STURDYPOWDER,
|
||
tempHigh: 150,
|
||
stateHigh: "ash",
|
||
category:"food",
|
||
hidden:true,
|
||
burn:25,
|
||
burnTime:200,
|
||
burnInto: "ash",
|
||
state: "solid",
|
||
density: 1005,
|
||
},
|
||
"frozen_meat": {
|
||
color: "#65b8aa",
|
||
behavior: behaviors.STURDYPOWDER,
|
||
temp: -18,
|
||
tempHigh: 0,
|
||
stateHigh: "meat",
|
||
category:"food",
|
||
hidden:true,
|
||
state: "solid",
|
||
density: 1067.5,
|
||
},
|
||
"chocolate": {
|
||
color: "#4d2818",
|
||
behavior: behaviors.STURDYPOWDER,
|
||
tempHigh: 31,
|
||
stateHigh: "chocolate_syrup",
|
||
category: "food",
|
||
state: "solid",
|
||
density: 1325,
|
||
},
|
||
"cloner": {
|
||
color: "#dddd00",
|
||
behavior: behaviors.CLONER,
|
||
ignore: ["ecloner","slow_cloner","clone_powder","floating_cloner"],
|
||
category:"machines",
|
||
insulate:true,
|
||
hardness: 1,
|
||
},
|
||
"ecloner": {
|
||
name: "e-cloner",
|
||
color: "#dddd00",
|
||
behavior: behaviors.WALL,
|
||
behaviorOn: behaviors.CLONER,
|
||
ignore: ["cloner","slow_cloner","clone_powder","floating_cloner"],
|
||
category:"machines",
|
||
insulate:true,
|
||
conduct: 1,
|
||
hardness: 1,
|
||
},
|
||
"slow_cloner": {
|
||
color: "#888800",
|
||
behavior: [
|
||
"XX|CF%10|XX",
|
||
"CF%10|XX|CF%10",
|
||
"XX|CF%10|XX",
|
||
],
|
||
ignore: ["cloner","ecloner","clone_powder","floating_cloner"],
|
||
category:"machines",
|
||
insulate:true,
|
||
hardness: 1,
|
||
},
|
||
"wire": {
|
||
color: "#4d0a03",
|
||
behavior: behaviors.WALL,
|
||
category: "machines",
|
||
insulate: true,
|
||
conduct: 1,
|
||
},
|
||
"random": { //hard-coded
|
||
color: ["#3e5f8a","#a334ec","#ea96f9","#a6ecf6","#70ebc8","#d9286b","#7eed91","#a18b30"],
|
||
behavior: behaviors.WALL,
|
||
category: "special",
|
||
excludeRandom: true,
|
||
},
|
||
"filler": {
|
||
color: "#ae4cd9",
|
||
behavior: behaviors.FILL,
|
||
category:"special",
|
||
excludeRandom: true,
|
||
},
|
||
"lattice": {
|
||
color: "#cb4cd9",
|
||
behavior: [
|
||
"CL|XX|CL",
|
||
"XX|XX|XX",
|
||
"CL|XX|CL",
|
||
],
|
||
hidden: true,
|
||
category:"special",
|
||
excludeRandom: true,
|
||
},
|
||
"gravel": {
|
||
color: ["#E3E0DF","#B1ABA3","#74736D","#524B47"],
|
||
behavior: behaviors.POWDER,
|
||
category:"land",
|
||
tempHigh: 950,
|
||
stateHigh: "magma",
|
||
state: "solid",
|
||
density: 1680,
|
||
hardness: 0.2,
|
||
},
|
||
"slime": {
|
||
color: "#81cf63",
|
||
behavior: behaviors.LIQUID,
|
||
reactions: {
|
||
"bomb": { "elem2":"sticky_bomb", "elem2":null },
|
||
},
|
||
viscosity: 5000,
|
||
tempHigh: 120,
|
||
stateHigh: "steam",
|
||
category:"liquids",
|
||
state: "liquid",
|
||
density: 1450,
|
||
},
|
||
"dust": {
|
||
color: "#666666",
|
||
behavior: behaviors.POWDER,
|
||
category: "powders",
|
||
burn: 10,
|
||
burnTime: 1,
|
||
state: "solid",
|
||
density: 1490,
|
||
},
|
||
"void": {
|
||
color: "#262626",
|
||
behavior: behaviors.DELETE,
|
||
category:"special",
|
||
hardness: 1,
|
||
},
|
||
"cell": {
|
||
color: ["#00ee00","#83ee00","#d6ee00"],
|
||
behavior: [
|
||
"XX|CL%0.5|XX",
|
||
"CL%0.5|XX|CL%0.5",
|
||
"M2%10|M1|M2%10",
|
||
],
|
||
reactions: {
|
||
"infection": { "elem1":"cancer", "chance":0.01 },
|
||
"blood": { "elem1":"blood", "chance":0.01 },
|
||
"antibody": { "elem1":"antibody", "chance":0.01 },
|
||
},
|
||
tempHigh: 102,
|
||
stateHigh: "steam",
|
||
tempLow: -2,
|
||
stateLow: "ice",
|
||
state: "solid",
|
||
density: 1000.1,
|
||
category: "life",
|
||
},
|
||
"cancer": {
|
||
color: ["#300b29","#5c114e","#870c71"],
|
||
behavior: [
|
||
"XX|CL%1|XX",
|
||
"CL%1|XX|CL%1",
|
||
"M2%2|M1|M2%2",
|
||
],
|
||
reactions: {
|
||
"cell": { "elem2":"cancer", "chance":0.005 },
|
||
"frog": { "elem2":"cancer", "chance":0.005 },
|
||
"fish": { "elem2":"cancer", "chance":0.005 },
|
||
"rat": { "elem2":"cancer", "chance":0.005 },
|
||
},
|
||
tempHigh: 202,
|
||
stateHigh: "plague",
|
||
state: "solid",
|
||
density: 1000.2,
|
||
category: "life",
|
||
},
|
||
"plague": {
|
||
color: "#36005c",
|
||
behavior: behaviors.GAS,
|
||
reactions: {
|
||
"frog": { "elem2":"plague", "chance":0.05 },
|
||
"ant": { "elem2":"plague", "chance":0.05 },
|
||
"bee": { "elem2":"plague", "chance":0.05 },
|
||
"fish": { "elem2":"plague", "chance":0.05 },
|
||
"firefly": { "elem2":"plague", "chance":0.05 },
|
||
},
|
||
category: "life",
|
||
state: "gas",
|
||
density: 600,
|
||
},
|
||
"flea": {
|
||
color: "#9e4732",
|
||
behavior: [
|
||
"M2|XX|M2",
|
||
"XX|XX|XX",
|
||
"M2|M1|M2",
|
||
],
|
||
reactions: {
|
||
"blood": { "elem2":null, "chance":0.1875 },
|
||
"infection": { "elem2":null, "chance":0.1875 },
|
||
"antibody": { "elem2":null, "chance":0.1875 },
|
||
},
|
||
tempHigh: 35,
|
||
stateHigh: "ash",
|
||
category:"life",
|
||
burn:95,
|
||
burnTime:25,
|
||
state: "solid",
|
||
density: 400,
|
||
conduct: 0.15,
|
||
},
|
||
"termite": {
|
||
color: "#f5a056",
|
||
behavior: [
|
||
"XX|XX|SW:wood,tree_branch%5",
|
||
"XX|FX%3|M2%15 AND BO",
|
||
"XX|M1|SW:wood,tree_branch%5",
|
||
],
|
||
reactions: {
|
||
"wood": { "elem2":null, chance:0.04 },
|
||
"tree_branch": { "elem2":null, chance:0.02 },
|
||
"cellulose": { "elem2":null, chance:0.04 },
|
||
"paper": { "elem2":null, chance:0.04 },
|
||
"bamboo": { "elem2":null, chance:0.03 },
|
||
"bamboo_plant": { "elem2":null, chance:0.04 },
|
||
"sapling": { "elem2":null, chance:0.025 },
|
||
},
|
||
tempHigh: 37.78,
|
||
stateHigh: "ash",
|
||
category:"life",
|
||
burn:95,
|
||
burnTime:25,
|
||
state: "solid",
|
||
conduct: 0.15,
|
||
},
|
||
"ant": {
|
||
color: "#4a0903",
|
||
behavior: [
|
||
"SW:dirt,sand,gravel%5|XX|SW:dirt,sand,gravel%5",
|
||
"M2|XX|M2",
|
||
"SW:dirt,sand,gravel%5|M1|SW:dirt,sand,gravel%5",
|
||
],
|
||
tempHigh: 53.7,
|
||
stateHigh: "ash",
|
||
category:"life",
|
||
burn:95,
|
||
burnTime:25,
|
||
state: "solid",
|
||
density: 500,
|
||
conduct: 0.15,
|
||
},
|
||
"worm": {
|
||
color: "#402208",
|
||
behavior: [
|
||
"SW:dirt,sand,gravel,ash,mycelium,mud,wet_sand,clay_soil%3|XX|SW:dirt,sand,gravel,ash,mycelium,mud,wet_sand,clay_soil%3",
|
||
"M2%10|XX|M2%10",
|
||
"SW:dirt,sand,gravel,ash,mycelium,mud,wet_sand,clay_soil%3|M1|SW:dirt,sand,gravel,ash,mycelium,mud,wet_sand,clay_soil%3",
|
||
],
|
||
reactions: {
|
||
"ash": { "elem2":null, "chance":0.1 },
|
||
"root": { "elem2":"dirt", "chance":0.1 },
|
||
"hyphae": { "elem2":"mycelium", "chance":0.1 },
|
||
"plant": { "elem2":"root", "chance":0.1 },
|
||
"grass": { "elem2":"dirt", "chance":0.1 },
|
||
"limestone": { "elem2":"calcium", "chance":0.1 },
|
||
"quicklime": { "elem2":"calcium", "chance":0.1 },
|
||
"slaked_lime": { "elem2":"calcium", "chance":0.1 },
|
||
"salt": { "elem1": "slime", "elem2": null },
|
||
"potassium_salt": { "elem1": "slime", "elem2": null },
|
||
"epsom_salt": { "elem1": "slime", "elem2": null },
|
||
},
|
||
tempHigh: 40,
|
||
stateHigh: "ash",
|
||
category:"life",
|
||
burn:95,
|
||
burnTime:25,
|
||
state: "solid",
|
||
conduct: 0.17,
|
||
},
|
||
"fly": {
|
||
color: "#303012",
|
||
behavior: [
|
||
"XX|M2|M1",
|
||
"XX|FX%2|BO",
|
||
"XX|M2|M1",
|
||
],
|
||
reactions: {
|
||
"plant": { "elem2":null, chance:0.5 },
|
||
"meat": { "elem2":null, chance:0.5 },
|
||
"cooked_meat": { "elem2":null, chance:0.5 },
|
||
"rotten_meat": { "elem2":null, chance:0.5 },
|
||
"vine": { "elem2":null, chance:0.5 },
|
||
"corn": { "elem2":null, chance:0.5 },
|
||
"potato": { "elem2":null, chance:0.5 },
|
||
"wheat": { "elem2":null, chance:0.5 },
|
||
"yeast": { "elem2":null, chance:0.5 },
|
||
"caramel": { "elem2":null, chance:0.5 },
|
||
"bread": { "elem2":null, chance:0.5 },
|
||
},
|
||
tempHigh: 47,
|
||
stateHigh: "ash",
|
||
category:"life",
|
||
burn:95,
|
||
burnTime:25,
|
||
state: "solid",
|
||
density: 600,
|
||
conduct: 0.15,
|
||
},
|
||
"firefly": {
|
||
color: ["#310D09","#310D09","#d9d950","#310D09","#310D09"],
|
||
behavior: [
|
||
"XX|M2|M1",
|
||
"XX|CC:310D09,310D09,310D09,310D09,d9d950%10 AND FX%2|BO",
|
||
"XX|M2|M1",
|
||
],
|
||
reactions: {
|
||
"pollen": { "elem2":null, chance:0.5 },
|
||
"honey": { "elem2":null, chance:0.5 },
|
||
"firefly": { "elem2":null, chance:0.01 },
|
||
"sugar_water": { "elem2":null, chance:0.5 },
|
||
"sugar": { "elem2":null, chance:0.25 },
|
||
},
|
||
tempHigh: 47,
|
||
stateHigh: "ash",
|
||
category:"life",
|
||
burn:95,
|
||
burnTime:25,
|
||
state: "solid",
|
||
density: 600,
|
||
conduct: 0.15,
|
||
},
|
||
"bee": {
|
||
color: "#c4b100",
|
||
behavior: [
|
||
"XX|M2|M1",
|
||
"XX|FX%2|M1 AND BO",
|
||
"XX|CR:pollen%0.025 AND M2|M1",
|
||
],
|
||
reactions: {
|
||
"sugar_water": { "elem2":null, chance:0.5 },
|
||
"sugar": { "elem2":null, chance:0.25 },
|
||
"caramel": { "elem2":null, chance:0.5 },
|
||
"candy": { "elem2":null, chance:0.05 },
|
||
},
|
||
tempHigh: 47,
|
||
stateHigh: "ash",
|
||
category:"life",
|
||
burn:95,
|
||
burnTime:25,
|
||
state: "solid",
|
||
density: 600,
|
||
conduct: 0.15,
|
||
},
|
||
"human": {
|
||
color: ["#f5eac6","#d4c594","#a89160","#7a5733","#523018","#361e0e"],
|
||
category: "life",
|
||
properties: {
|
||
dead: false,
|
||
dir: 1,
|
||
panic: 0,
|
||
},
|
||
tick: function(pixel) {
|
||
if (isEmpty(pixel.x, pixel.y+1)) {
|
||
createPixel("body", pixel.x, pixel.y+1);
|
||
pixel.element = "head";
|
||
}
|
||
else if (isEmpty(pixel.x, pixel.y-1)) {
|
||
createPixel("head", pixel.x, pixel.y-1);
|
||
pixelMap[pixel.x][pixel.y-1].color = pixel.color;
|
||
pixel.element = "body";
|
||
pixel.color = pixelColorPick(pixel)
|
||
}
|
||
else {
|
||
deletePixel(pixel.x, pixel.y);
|
||
}
|
||
},
|
||
},
|
||
"body": {
|
||
color: ["#049699","#638A61"],
|
||
category: "life",
|
||
hidden: true,
|
||
density: 1500,
|
||
state: "solid",
|
||
conduct: 25,
|
||
tempHigh: 250,
|
||
stateHigh: "cooked_meat",
|
||
tempLow: -30,
|
||
stateLow: "frozen_meat",
|
||
burn: 10,
|
||
burnTime: 250,
|
||
burnInto: "cooked_meat",
|
||
breakInto: "blood",
|
||
reactions: {
|
||
"cancer": { "elem1":"cancer", "chance":0.005 },
|
||
"radiation": { "elem1":["ash","meat","rotten_meat","cooked_meat"], "chance":0.4 },
|
||
"plague": { "elem1":"plague", "chance":0.05 },
|
||
},
|
||
properties: {
|
||
dead: false,
|
||
dir: 1,
|
||
panic: 0,
|
||
},
|
||
tick: function(pixel) {
|
||
if (tryMove(pixel, pixel.x, pixel.y+1)) { // Fall
|
||
if (!isEmpty(pixel.x, pixel.y-2, true)) { // Drag head down
|
||
var headpixel = pixelMap[pixel.x][pixel.y-2];
|
||
if (headpixel.element == "head") {
|
||
if (isEmpty(pixel.x, pixel.y-1)) {
|
||
movePixel(pixelMap[pixel.x][pixel.y-2], pixel.x, pixel.y-1);
|
||
}
|
||
else {
|
||
swapPixels(pixelMap[pixel.x][pixel.y-2], pixelMap[pixel.x][pixel.y-1]);
|
||
}
|
||
}
|
||
}
|
||
}
|
||
doHeat(pixel);
|
||
doBurning(pixel);
|
||
doElectricity(pixel);
|
||
if (pixel.dead) {
|
||
// Turn into rotten_meat if pixelTicks-dead > 500
|
||
if (pixelTicks-pixel.dead > 200) {
|
||
pixel.element = "rotten_meat";
|
||
pixel.color = pixelColorPick(pixel);
|
||
}
|
||
return
|
||
}
|
||
|
||
// Find the head
|
||
if (!isEmpty(pixel.x, pixel.y-1, true) && pixelMap[pixel.x][pixel.y-1].element == "head") {
|
||
var head = pixelMap[pixel.x][pixel.y-1];
|
||
if (head.dead) { // If head is dead, kill body
|
||
pixel.dead = head.dead;
|
||
}
|
||
}
|
||
else { var head = null }
|
||
|
||
if (isEmpty(pixel.x, pixel.y-1)) {
|
||
// create blood if decapitated 10% chance
|
||
if (Math.random() < 0.1) {
|
||
createPixel("blood", pixel.x, pixel.y-1);
|
||
// set dead to true 15% chance
|
||
if (Math.random() < 0.15) {
|
||
pixel.dead = pixelTicks;
|
||
}
|
||
}
|
||
}
|
||
else if (head == null) { return }
|
||
else if (Math.random() < 0.1) { // Move 10% chance
|
||
var movesToTry = [
|
||
[1*pixel.dir,0],
|
||
[1*pixel.dir,-1],
|
||
];
|
||
// While movesToTry is not empty, tryMove(pixel, x, y) with a random move, then remove it. if tryMove returns true, break.
|
||
while (movesToTry.length > 0) {
|
||
var move = movesToTry.splice(Math.floor(Math.random() * movesToTry.length), 1)[0];
|
||
if (isEmpty(pixel.x+move[0], pixel.y+move[1]-1)) {
|
||
if (tryMove(pixel, pixel.x+move[0], pixel.y+move[1])) {
|
||
movePixel(head, head.x+move[0], head.y+move[1]);
|
||
break;
|
||
}
|
||
}
|
||
}
|
||
// 15% chance to change direction
|
||
if (Math.random() < 0.15) {
|
||
pixel.dir *= -1;
|
||
}
|
||
}
|
||
|
||
},
|
||
},
|
||
"head": {
|
||
color: ["#f5eac6","#d4c594","#a89160","#7a6433","#524018"],
|
||
category: "life",
|
||
hidden: true,
|
||
density: 1080,
|
||
state: "solid",
|
||
conduct: 25,
|
||
tempHigh: 250,
|
||
stateHigh: "cooked_meat",
|
||
tempLow: -30,
|
||
stateLow: "frozen_meat",
|
||
burn: 10,
|
||
burnTime: 250,
|
||
burnInto: "cooked_meat",
|
||
breakInto: "blood",
|
||
reactions: {
|
||
"cancer": { "elem1":"cancer", "chance":0.005 },
|
||
"radiation": { "elem1":["ash","meat","rotten_meat","cooked_meat"], "chance":0.4 },
|
||
"plague": { "elem1":"plague", "chance":0.05 },
|
||
},
|
||
properties: {
|
||
dead: false
|
||
},
|
||
tick: function(pixel) {
|
||
doHeat(pixel);
|
||
doBurning(pixel);
|
||
doElectricity(pixel);
|
||
if (pixel.dead) {
|
||
// Turn into rotten_meat if pixelTicks-dead > 500
|
||
if (pixelTicks-pixel.dead > 200) {
|
||
pixel.element = "rotten_meat";
|
||
pixel.color = pixelColorPick(pixel);
|
||
return
|
||
}
|
||
}
|
||
|
||
// Find the body
|
||
if (!isEmpty(pixel.x, pixel.y+1, true) && pixelMap[pixel.x][pixel.y+1].element == "body") {
|
||
var body = pixelMap[pixel.x][pixel.y+1];
|
||
if (body.dead) { // If body is dead, kill head
|
||
pixel.dead = body.dead;
|
||
}
|
||
}
|
||
else { var body = null }
|
||
|
||
if (isEmpty(pixel.x, pixel.y+1)) {
|
||
tryMove(pixel, pixel.x, pixel.y+1);
|
||
// create blood if severed 10% chance
|
||
if (isEmpty(pixel.x, pixel.y+1) && !pixel.dead && Math.random() < 0.1) {
|
||
createPixel("blood", pixel.x, pixel.y+1);
|
||
// set dead to true 15% chance
|
||
if (Math.random() < 0.15) {
|
||
pixel.dead = pixelTicks;
|
||
}
|
||
}
|
||
}
|
||
}
|
||
},
|
||
"rat": {
|
||
color: ["#A698A9","#8C7D82","#CCC3CF"],
|
||
behavior: [
|
||
"XX|CR:plague%0.05 AND M2%1.5|M2%5",
|
||
"XX|FX%2|M2 AND BO",
|
||
"XX|M1|M2",
|
||
],
|
||
reactions: {
|
||
"meat": { "elem2":null, "chance":0.5 },
|
||
"cooked_meat": { "elem2":null, "chance":0.5 },
|
||
"rotten_meat": { "elem2":null, "chance":0.5 },
|
||
"plant": { "elem2":null, "chance":0.5 },
|
||
"algae": { "elem2":null, "chance":0.5 },
|
||
"grass_seed": { "elem2":null, "chance":0.5 },
|
||
"wheat_seed": { "elem2":null, "chance":0.5 },
|
||
"wheat": { "elem2":null, "chance":0.5 },
|
||
"potato_seed": { "elem2":null, "chance":0.5 },
|
||
"potato": { "elem2":null, "chance":0.5 },
|
||
"corn_seed": { "elem2":null, "chance":0.5 },
|
||
"corn": { "elem2":null, "chance":0.5 },
|
||
"flower_seed": { "elem2":null, "chance":0.5 },
|
||
"flour": { "elem2":null, "chance":0.5 },
|
||
"dough": { "elem2":null, "chance":0.5 },
|
||
"bread": { "elem2":null, "chance":0.5 },
|
||
"toast": { "elem2":null, "chance":0.5 },
|
||
"salt": { "elem2":null, "chance":0.5 },
|
||
"sugar": { "elem2":null, "chance":0.5 },
|
||
"salt_water": { "elem2":"dirty_water", "chance":0.5 },
|
||
"sugar_water": { "elem2":"dirty_water", "chance":0.5 },
|
||
"water": { "elem2":"dirty_water", "chance":0.5 },
|
||
"popcorn": { "elem2":null, "chance":0.5 },
|
||
"candy": { "elem2":null, "chance":0.5 },
|
||
"caramel": { "elem2":null, "chance":0.5 },
|
||
},
|
||
category: "life",
|
||
tempHigh: 50,
|
||
stateHigh: "rotten_meat",
|
||
tempLow: 15,
|
||
stateLow: "frozen_meat",
|
||
burn:80,
|
||
burnTime:150,
|
||
state: "solid",
|
||
conduct: 0.25,
|
||
},
|
||
"frog": {
|
||
color: "#607300",
|
||
behavior: [
|
||
"XX|XX|M2%3",
|
||
"XX|FX%0.5|CR:slime%0.01 AND BO",
|
||
"XX|M1|XX",
|
||
],
|
||
reactions: {
|
||
"fly": { "elem2":null, chance:0.5 },
|
||
"firefly": { "elem2":null, chance:0.5 },
|
||
"snail": { "elem2":"calcium", chance:0.1 },
|
||
"slug": { "elem2":null, chance:0.2 },
|
||
"worm": { "elem2":null, chance:0.2 },
|
||
"algae": { "elem2":null, chance:0.5 },
|
||
"oxygen": { "elem2":"carbon_dioxide", chance:0.5 },
|
||
},
|
||
temp: 19.1,
|
||
tempHigh: 41,
|
||
stateHigh: "meat",
|
||
tempLow: -18,
|
||
stateLow: "frozen_frog",
|
||
category:"life",
|
||
burn:75,
|
||
burnTime:30,
|
||
state: "solid",
|
||
density: 1450,
|
||
conduct: 0.2,
|
||
},
|
||
"frozen_frog": {
|
||
color: "#007349",
|
||
behavior: behaviors.STURDYPOWDER,
|
||
temp: -18,
|
||
tempHigh: 0,
|
||
stateHigh: "frog",
|
||
tempLow: -18,
|
||
stateLow: "frozen_frog",
|
||
category:"life",
|
||
hidden: true,
|
||
state: "solid",
|
||
density: 1500,
|
||
},
|
||
"fish": {
|
||
color: "#ac8650",
|
||
behavior: [
|
||
"XX|M2%5|SW:water,salt_water,sugar_water,dirty_water%7",
|
||
"XX|FX%1|BO",
|
||
"XX|M1|SW:water,salt_water,sugar_water,dirty_water%8",
|
||
],
|
||
reactions: {
|
||
"algae": { "elem2":null, chance:0.5 },
|
||
"plant": { "elem2":null, chance:0.125 },
|
||
"fly": { "elem2":null, chance:0.5 },
|
||
"firefly": { "elem2":null, chance:0.5 },
|
||
"worm": { "elem2":null, chance:0.25 },
|
||
"oxygen": { "elem2":"carbon_dioxide", chance:0.5 },
|
||
},
|
||
temp: 20,
|
||
tempHigh: 32,
|
||
stateHigh: "meat",
|
||
tempLow: -20,
|
||
stateLow: "frozen_meat",
|
||
category:"life",
|
||
burn:40,
|
||
burnTime:100,
|
||
state: "solid",
|
||
density: 1080,
|
||
conduct: 0.2,
|
||
},
|
||
"slug": {
|
||
color: ["#997e12","#403314","#997e12","#403314","#997e12","#403314","#997e12","#403314","#997e12","#403314","#997e12","#403314","#124a44"],
|
||
behavior: [
|
||
"XX|XX|XX",
|
||
"XX|FX%0.25|M2%0.5 AND BO",
|
||
"XX|M1|XX",
|
||
],
|
||
reactions: {
|
||
"salt": { "elem1": "slime", "elem2": null },
|
||
"potassium_salt": { "elem1": "slime", "elem2": null },
|
||
"epsom_salt": { "elem1": "slime", "elem2": null },
|
||
"plant": { "elem2":null, "chance":0.05 },
|
||
"worm": { "elem2":null, "chance":0.01 },
|
||
"mushroom_spore": { "elem2":null, "chance":0.05 },
|
||
"grass": { "elem2":null, "chance":0.05 },
|
||
"grass_seed": { "elem2":null, "chance":0.05 },
|
||
"algae": { "elem2":null, "chance":0.05 },
|
||
"mushroom_cap": { "elem2":null, "chance":0.05 },
|
||
"mushroom_stalk": { "elem2":null, "chance":0.05 },
|
||
"mushroom_gill": { "elem2":null, "chance":0.05 },
|
||
"hyphae": { "elem2":"dirt", "chance":0.05 },
|
||
"mycelium": { "elem2":"dirt", "chance":0.05 },
|
||
},
|
||
tempLow: 5,
|
||
stateLow: "slime",
|
||
tempHigh: 40,
|
||
stateHigh: "slime",
|
||
category: "life",
|
||
state: "solid",
|
||
density: 1450,
|
||
conduct: 0.17,
|
||
},
|
||
"snail": {
|
||
color: "#5c3104",
|
||
behavior: [
|
||
"XX|XX|XX",
|
||
"XX|FX%0.25|M2%0.5 AND BO",
|
||
"XX|M1|XX",
|
||
],
|
||
reactions: {
|
||
"salt": { "elem1": "calcium", "elem2": null },
|
||
"potassium_salt": { "elem1": "calcium", "elem2": null },
|
||
"epsom_salt": { "elem1": "calcium", "elem2": null },
|
||
"plant": { "elem2":null, "chance":0.05 },
|
||
"worm": { "elem2":null, "chance":0.01 },
|
||
"mushroom_spore": { "elem2":null, "chance":0.05 },
|
||
"grass": { "elem2":null, "chance":0.05 },
|
||
"grass_seed": { "elem2":null, "chance":0.05 },
|
||
"algae": { "elem2":null, "chance":0.05 },
|
||
"mushroom_cap": { "elem2":null, "chance":0.05 },
|
||
"mushroom_stalk": { "elem2":null, "chance":0.05 },
|
||
"mushroom_gill": { "elem2":null, "chance":0.05 },
|
||
"hyphae": { "elem2":"dirt", "chance":0.05 },
|
||
"mycelium": { "elem2":"dirt", "chance":0.05 },
|
||
},
|
||
tempLow: -6.4,
|
||
stateLow: "calcium",
|
||
tempHigh: 100,
|
||
stateHigh: "calcium",
|
||
category: "life",
|
||
state: "solid",
|
||
density: 1500,
|
||
conduct: 0.16,
|
||
},
|
||
"heater": {
|
||
color: "#881111",
|
||
behavior: [
|
||
"XX|HT:2|XX",
|
||
"HT:2|XX|HT:2",
|
||
"XX|HT:2|XX",
|
||
],
|
||
category:"machines",
|
||
insulate:true,
|
||
},
|
||
"cooler": {
|
||
color: "#111188",
|
||
behavior: [
|
||
"XX|CO:2|XX",
|
||
"CO:2|XX|CO:2",
|
||
"XX|CO:2|XX",
|
||
],
|
||
category:"machines",
|
||
insulate:true,
|
||
},
|
||
"superheater": {
|
||
color: "#dd1111",
|
||
behavior: [
|
||
"XX|HT:10|XX",
|
||
"HT:10|XX|HT:10",
|
||
"XX|HT:10|XX",
|
||
],
|
||
category:"machines",
|
||
insulate:true,
|
||
},
|
||
"freezer": {
|
||
color: "#1111dd",
|
||
behavior: [
|
||
"XX|CO:10|XX",
|
||
"CO:10|XX|CO:10",
|
||
"XX|CO:10|XX",
|
||
],
|
||
category:"machines",
|
||
insulate:true,
|
||
},
|
||
"torch": {
|
||
color: "#d68542",
|
||
behavior: [
|
||
"XX|CR:fire|XX",
|
||
"XX|XX|XX",
|
||
"XX|XX|XX",
|
||
],
|
||
reactions: {
|
||
"water": { "elem1":"wood" },
|
||
},
|
||
temp:600,
|
||
category:"special",
|
||
},
|
||
"spout": {
|
||
color: "#606378",
|
||
behavior: [
|
||
"XX|CR:water|XX",
|
||
"CR:water|XX|CR:water",
|
||
"XX|CR:water|XX",
|
||
],
|
||
category:"special",
|
||
tempHigh: 1455.5,
|
||
stateHigh: "molten_steel",
|
||
conduct: 0.42,
|
||
},
|
||
"udder": {
|
||
color: "#ecb3f5",
|
||
behavior: [
|
||
"XX|XX|XX",
|
||
"XX|XX|XX",
|
||
"XX|CR:milk%2.5|XX",
|
||
],
|
||
tempHigh: 80,
|
||
stateHigh: "cooked_meat",
|
||
tempLow: -18,
|
||
stateLow: "frozen_meat",
|
||
category:"special",
|
||
},
|
||
"bone_marrow": {
|
||
color: "#c97265",
|
||
behavior: [
|
||
"XX|CR:blood,bone,bone%5|XX",
|
||
"CR:blood,bone,bone%5|XX|CR:blood,bone,bone%5",
|
||
"XX|CR:blood,bone,bone%5|XX",
|
||
],
|
||
category:"life",
|
||
tempHigh: 750,
|
||
stateHigh: "calcium",
|
||
hidden: true,
|
||
},
|
||
"bone": {
|
||
color: "#d9d9d9",
|
||
behavior: behaviors.SUPPORT,
|
||
category:"life",
|
||
tempHigh: 760,
|
||
stateHigh: "calcium",
|
||
state: "solid",
|
||
density: 1900,
|
||
hardness: 0.5,
|
||
breakInto: "calcium",
|
||
},
|
||
"antipowder": {
|
||
color: "#ebd1d8",
|
||
behavior: behaviors.AGPOWDER,
|
||
category:"special",
|
||
tempHigh: 1850,
|
||
stateHigh: "antimolten",
|
||
state: "solid",
|
||
density: 1850,
|
||
},
|
||
"antimolten": {
|
||
color: ["#ffb5b5","#ffd0b5","#ffd0b5"],
|
||
behavior: [
|
||
"M1|M1|M1",
|
||
"M2|XX|M2",
|
||
"XX|CR:antifire%2.5|XX",
|
||
],
|
||
temp: 1850,
|
||
tempLow: 1750,
|
||
stateLow: "antipowder",
|
||
viscosity: 10000,
|
||
hidden: true,
|
||
state: "liquid",
|
||
density: 1000,
|
||
category: "special",
|
||
},
|
||
"antifire": {
|
||
color: ["#ffc3a6","#ffdfa3","#ffb69e"],
|
||
behavior: [
|
||
"XX|M2|XX",
|
||
"M2|XX|M2",
|
||
"M1|M1|M1",
|
||
],
|
||
reactions: {
|
||
"antiliquid": { "elem1": "antigas" },
|
||
},
|
||
temp:600,
|
||
tempLow:100,
|
||
stateLow: "antigas",
|
||
tempHigh: 7000,
|
||
stateHigh: "plasma",
|
||
category: "special",
|
||
burning: true,
|
||
burnTime: 25,
|
||
burnInto: "antigas",
|
||
hidden: true,
|
||
state: "gas",
|
||
density: 0.2,
|
||
},
|
||
"antifluid": {
|
||
color: "#d1dbeb",
|
||
behavior: behaviors.AGLIQUID,
|
||
category:"special",
|
||
tempHigh: 100,
|
||
stateHigh: "antigas",
|
||
state: "liquid",
|
||
density: 1000,
|
||
},
|
||
"antigas": {
|
||
color: "#e6fffc",
|
||
behavior: behaviors.GAS,
|
||
category:"special",
|
||
tempLow: 100,
|
||
stateLow: "antifluid",
|
||
hidden: true,
|
||
state: "gas",
|
||
density: 0.1,
|
||
},
|
||
"vertical": {
|
||
color: "#d9d9d9",
|
||
behavior: [
|
||
"XX|M1|XX",
|
||
"CR:wall|XX|CR:wall",
|
||
"XX|XX|XX",
|
||
],
|
||
category:"special",
|
||
hidden:true,
|
||
excludeRandom: true,
|
||
},
|
||
"horizontal": {
|
||
color: "#d9d9d9",
|
||
behavior: [
|
||
"XX|CR:wall|XX",
|
||
"XX|XX|M1",
|
||
"XX|CR:wall|XX",
|
||
],
|
||
category:"special",
|
||
hidden:true,
|
||
excludeRandom: true,
|
||
},
|
||
"rocket": {
|
||
color: "#ff0000",
|
||
behavior: [
|
||
"XX|M1|XX",
|
||
"XX|DL%1|XX",
|
||
"CR:smoke|CR:fire|CR:smoke",
|
||
],
|
||
category: "special",
|
||
hidden:true,
|
||
state: "solid",
|
||
temp:700,
|
||
density: 7300,
|
||
conduct: 0.73,
|
||
tempHigh: 1455.5,
|
||
stateHigh: "molten_steel",
|
||
},
|
||
"ash": {
|
||
color: ["#8c8c8c","#9c9c9c"],
|
||
behavior: behaviors.POWDER,
|
||
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] },
|
||
"pyrocumulus": { "elem1": "pyrocumulus", "chance":0.08, "y":[0,15] },
|
||
},
|
||
category:"powders",
|
||
state: "solid",
|
||
density: 700,
|
||
},
|
||
"light": {
|
||
color: "#ffffa8",
|
||
behavior: [
|
||
"XX|XX|XX",
|
||
"XX|DL%5|M1 AND BO",
|
||
"XX|XX|XX",
|
||
],
|
||
rotatable: true,
|
||
temp: 40,
|
||
category: "energy",
|
||
},
|
||
"laser": {
|
||
color: "#ff0000",
|
||
behavior: [
|
||
"XX|XX|XX",
|
||
"XX|DL%0.25|M1 AND BO:1,2,3",
|
||
"XX|XX|XX",
|
||
],
|
||
rotatable: true,
|
||
temp: 40,
|
||
category: "energy",
|
||
},
|
||
"ball": {
|
||
color: "#e35693",
|
||
behavior: [
|
||
"XX|XX|XX",
|
||
"XX|FY:0%5|XX",
|
||
"XX|M1 AND BO|XX",
|
||
],
|
||
category: "energy",
|
||
flipY: false,
|
||
flippableY: true,
|
||
hidden: true,
|
||
},
|
||
"pointer": {
|
||
color: "#ff0000",
|
||
behavior: behaviors.SELFDELETE,
|
||
category:"tools",
|
||
hidden:true,
|
||
},
|
||
"charcoal": {
|
||
color: "#2b2b2b",
|
||
behavior: behaviors.POWDER,
|
||
burn: 25,
|
||
burnTime: 1000,
|
||
burnInto: "carbon_dioxide",
|
||
category: "powders",
|
||
state: "solid",
|
||
density: 208,
|
||
breakInto: ["ash","ash","carbon_dioxide"],
|
||
},
|
||
"tinder": {
|
||
color: ["#917256","#87684F","#735F4A","#5D4C3E","#4B3A2E"],
|
||
behavior: behaviors.STURDYPOWDER,
|
||
category: "powders",
|
||
tempHigh: 400,
|
||
stateHigh: "fire",
|
||
burn: 50,
|
||
burnTime: 100,
|
||
state: "solid",
|
||
density: 23,
|
||
},
|
||
"sawdust": {
|
||
color: ["#dec150","#c7b15a"],
|
||
behavior: behaviors.POWDER,
|
||
tempHigh: 400,
|
||
stateHigh: "fire",
|
||
category: "powders",
|
||
burn: 25,
|
||
burnTime: 150,
|
||
burnInto: ["ash","fire","fire","fire"],
|
||
state: "solid",
|
||
density: 393,
|
||
},
|
||
"hydrogen": {
|
||
color: "#558bcf",
|
||
behavior: behaviors.GAS,
|
||
reactions: {
|
||
"oxygen": { "elem1":null, "elem2":"steam" },
|
||
},
|
||
category: "gases",
|
||
burn: 100,
|
||
burnTime: 2,
|
||
tempLow: -252.8,
|
||
stateLow: "liquid_hydrogen",
|
||
state: "gas",
|
||
density: 0.08375,
|
||
},
|
||
"oxygen": {
|
||
color: "#99c7ff",
|
||
behavior: behaviors.GAS,
|
||
reactions: {
|
||
"copper": { "elem2":"oxidized_copper", chance:0.05 },
|
||
"iron": { "elem2":"rust", chance:0.025 },
|
||
},
|
||
category: "gases",
|
||
burn: 100,
|
||
burnTime: 2,
|
||
tempLow: -183.94,
|
||
stateLow: "liquid_oxygen",
|
||
state: "gas",
|
||
density: 1.292,
|
||
},
|
||
"nitrogen": {
|
||
color: "#b8d1d4",
|
||
behavior: behaviors.GAS,
|
||
reactions: {
|
||
"oxygen": { "elem1":null, "elem2":"anesthesia" },
|
||
"hydrogen": { "elem1":null, "elem2":"ammonia" },
|
||
},
|
||
category: "gases",
|
||
tempLow: -195.8,
|
||
stateLow: "liquid_nitrogen",
|
||
state: "gas",
|
||
density: 1.165,
|
||
},
|
||
"helium": {
|
||
color: "#a69494",
|
||
behavior: behaviors.GAS,
|
||
category: "gases",
|
||
tempLow: -272.20,
|
||
stateLow: "liquid_helium",
|
||
state: "gas",
|
||
density: 0.1786,
|
||
},
|
||
"anesthesia": {
|
||
color: "#d3e1e3",
|
||
behavior: behaviors.GAS,
|
||
category: "gases",
|
||
tempLow: -88.48,
|
||
stateLow: ["nitrogen","oxygen"],
|
||
hidden: true,
|
||
state: "liquid",
|
||
density: 1.9781,
|
||
},
|
||
"ammonia": {
|
||
color: "#bab6a9",
|
||
behavior: behaviors.GAS,
|
||
reactions: {
|
||
"methane": { "elem1":null, "elem2":"cyanide", "chance":0.25 },
|
||
"plant": { "elem1":"plant", "chance":0.05 },
|
||
"wheat_seed": { "elem1":"wheat", "chance":0.05 },
|
||
"grass": { "elem1":"grass", "chance":0.05 },
|
||
"grass_seed": { "elem1":"grass", "chance":0.05 },
|
||
"bamboo_plant": { "elem1":"bamboo", "chance":0.05 },
|
||
"flower_seed": { "elem1":"flower_seed", "chance":0.05 },
|
||
"petal": { "elem1":"flower_seed", "chance":0.05 },
|
||
"vine": { "elem1":"vine", "chance":0.05 },
|
||
"sapling": { "elem1":"tree_branch", "chance":0.05 },
|
||
"tree_branch": { "elem1":"tree_branch", "chance":0.05 },
|
||
"corn_seed": { "elem1":"corn", "chance":0.05 },
|
||
"root": { "elem1":"root", "chance":0.05 },
|
||
"dirt": { "elem1":"grass", "chance":0.05 },
|
||
"mud": { "elem1":"grass", "chance":0.05 },
|
||
"potato_seed": { "elem1":"potato", "chance":0.05 },
|
||
"yeast": { "elem1":"yeast", "chance":0.05 },
|
||
"fish": { "elem2":"meat" },
|
||
"frog": { "elem2":"meat" },
|
||
},
|
||
tempLow: -150,
|
||
stateLow: ["nitrogen","hydrogen"],
|
||
category: "gases",
|
||
state: "gas",
|
||
density: 0.73,
|
||
},
|
||
"carbon_dioxide": {
|
||
color: "#2f2f2f",
|
||
behavior: behaviors.GAS,
|
||
reactions: {
|
||
"plant": { "elem1":"oxygen" },
|
||
"algae": { "elem1":"oxygen" },
|
||
},
|
||
category: "gases",
|
||
tempLow: -78.5,
|
||
stateLow: "dry_ice",
|
||
state: "gas",
|
||
density: 1.977,
|
||
},
|
||
"oil": {
|
||
color: "#470e00",
|
||
behavior: behaviors.LIQUID,
|
||
reactions: {
|
||
"dirt": { "elem2":"mud" },
|
||
"sand": { "elem2":"wet_sand" },
|
||
},
|
||
category: "liquids",
|
||
tempHigh: 400,
|
||
stateHigh: "fire",
|
||
burn: 100,
|
||
burnTime: 30,
|
||
burnInto: ["carbon_dioxide","fire"],
|
||
viscosity: 250,
|
||
state: "liquid",
|
||
density: 825,
|
||
},
|
||
"lamp_oil": {
|
||
color: "#b3b38b",
|
||
behavior: behaviors.LIQUID,
|
||
category: "liquids",
|
||
tempHigh: 2100,
|
||
stateHigh: "fire",
|
||
burn: 95,
|
||
burnTime: 2000,
|
||
burnInto: ["carbon_dioxide","fire"],
|
||
viscosity: 3,
|
||
state: "liquid",
|
||
density: 850,
|
||
},
|
||
"propane": {
|
||
color: "#cfcfcf",
|
||
behavior: behaviors.GAS,
|
||
category: "gases",
|
||
tempHigh: 400,
|
||
stateHigh: "fire",
|
||
burn: 100,
|
||
burnTime: 5,
|
||
fireColor: ["#00ffff","#00ffdd"],
|
||
state: "gas",
|
||
density: 2.0098,
|
||
},
|
||
"methane": {
|
||
color: "#9f9f9f",
|
||
behavior: behaviors.GAS,
|
||
category: "gases",
|
||
tempHigh: 400,
|
||
stateHigh: "fire",
|
||
burn: 85,
|
||
burnTime: 5,
|
||
fireColor: ["#00ffff","#00ffdd"],
|
||
state: "gas",
|
||
density: 0.554,
|
||
},
|
||
"color_sand": {
|
||
color: ["#ff4d4d","#ffac4d","#ffff4d","#4dff4d","#4dffff","#4d4dff","#ff4dff"],
|
||
behavior: behaviors.POWDER,
|
||
tick: function(pixel) {
|
||
if (pixel.start === pixelTicks) {
|
||
pixel.color = "hsl(" + pixel.start + ",100%,65%)";
|
||
pixel.colorstart = pixel.start;
|
||
}
|
||
},
|
||
tempHigh: 1700,
|
||
stateHigh: "molten_stained_glass",
|
||
category: "powders",
|
||
state: "solid",
|
||
density: 1602,
|
||
},
|
||
"stained_glass": {
|
||
color: ["#ff4d4d","#ffac4d","#ffff4d","#4dff4d","#4dffff","#4d4dff","#ff4dff"],
|
||
behavior: behaviors.WALL,
|
||
tick: function(pixel) {
|
||
if (pixel.start-1 < pixelTicks) {
|
||
pixel.color = "hsl(" + (pixel.colorstart || pixel.start) + ",40%,30%)";
|
||
}
|
||
},
|
||
tempHigh: 1500,
|
||
category: "solids",
|
||
state: "solid",
|
||
density: 2500,
|
||
breakInto: "color_sand",
|
||
},
|
||
"molten_stained_glass": {
|
||
tick: function(pixel) {
|
||
if (pixel.start-1 < pixelTicks) {
|
||
pixel.color = "hsl(" + (pixel.colorstart || pixel.start) + ",40%,60%)";
|
||
}
|
||
}
|
||
},
|
||
"rainbow": {
|
||
color: ["#ff0000","#ff8800","#ffff00","#00ff00","#00ffff","#0000ff","#ff00ff"],
|
||
tick: function(pixel) {
|
||
var t = pixelTicks+pixel.x+pixel.y;
|
||
var r = Math.floor(127*(1-Math.cos(t*Math.PI/90)));
|
||
var g = Math.floor(127*(1-Math.cos(t*Math.PI/90+2*Math.PI/3)));
|
||
var b = Math.floor(127*(1-Math.cos(t*Math.PI/90+4*Math.PI/3)));
|
||
pixel.color = "rgb("+r+","+g+","+b+")";
|
||
},
|
||
category: "special",
|
||
},
|
||
"static": {
|
||
color: ["#ffffff","#888888","#000000"],
|
||
behavior: [
|
||
"XX|XX|XX",
|
||
"XX|CC:ffffff,9c9c9c,454545|XX",
|
||
"XX|XX|XX",
|
||
],
|
||
category: "special",
|
||
},
|
||
"border": {
|
||
color: "#00ffff",
|
||
tick: function(pixel) {
|
||
var t = pixelTicks/2+pixel.x+pixel.y;
|
||
var r = Math.floor(127*Math.sin(t/1.5));
|
||
pixel.color = "rgba("+r+","+r*2+","+r*2+","+r/127+")";
|
||
},
|
||
category: "special",
|
||
hardness: 1,
|
||
insulate: true,
|
||
},
|
||
"clay": {
|
||
color: "#d4c59c",
|
||
behavior: behaviors.SUPPORT,
|
||
tempHigh: 135,
|
||
stateHigh: "baked_clay",
|
||
category: "land",
|
||
state: "solid",
|
||
density: 1760,
|
||
},
|
||
"clay_soil": {
|
||
color: ["#F49A6F","#AB7160","#B56C52"],
|
||
behavior: [
|
||
"XX|XX|XX",
|
||
"XX|XX|XX",
|
||
"M2%25|M1|M2%25",
|
||
],
|
||
reactions: {
|
||
"water": { "elem1":"clay", "elem2":null },
|
||
},
|
||
tempHigh: 140,
|
||
stateHigh: "baked_clay",
|
||
category: "land",
|
||
state: "solid",
|
||
density: 1600,
|
||
},
|
||
"baked_clay": {
|
||
color: "#b85746",
|
||
behavior: behaviors.SUPPORT,
|
||
category: "powders",
|
||
state: "solid",
|
||
density: 2000,
|
||
},
|
||
"brick": {
|
||
color: "#cb4141",
|
||
behavior: behaviors.WALL,
|
||
category: "solids",
|
||
tempHigh: 1540,
|
||
state: "solid",
|
||
density: 1650,
|
||
hardness: 0.33,
|
||
breakInto: "brick_rubble",
|
||
},
|
||
"brick_rubble": {
|
||
color: ["#cb4141","#ab4d4d","#872626"],
|
||
behavior: behaviors.POWDER,
|
||
category: "powders",
|
||
tempHigh: 1540,
|
||
stateHigh: "molten_brick",
|
||
state: "solid",
|
||
density: 1650,
|
||
hardness: 0.25,
|
||
breakInto: "dust",
|
||
hidden: true,
|
||
},
|
||
"ruins": {
|
||
color: "#5c5c5c",
|
||
behavior: [
|
||
"XX|SP|XX",
|
||
"XX|XX|XX",
|
||
"M2%1|M1|M2%1"
|
||
],
|
||
tempHigh: 1500,
|
||
stateHigh: "magma",
|
||
category:"solids",
|
||
state: "solid",
|
||
density: 2400,
|
||
hardness: 0.33,
|
||
breakInto: "dust",
|
||
},
|
||
"sapling": {
|
||
color: "#3e9c3e",
|
||
behavior: [
|
||
"XX|M2%2|XX",
|
||
"XX|L2:wood,tree_branch%80|XX",
|
||
"XX|M1|XX",
|
||
],
|
||
tempHigh: 100,
|
||
stateHigh: "dead_plant",
|
||
tempLow: -2,
|
||
stateLow: "frozen_plant",
|
||
burn: 65,
|
||
burnTime: 15,
|
||
category: "life",
|
||
state: "solid",
|
||
density: 1500,
|
||
},
|
||
"seeds": {
|
||
color: ["#359100","#74b332","#b9d461","#dede7a"],
|
||
tick: function(pixel) {
|
||
// Choose randomly grass_seed, wheat_seed, flower_seed, bamboo_plant, mushroom_spore, corn_seed, potato_seed
|
||
pixel.element = ["grass_seed","wheat_seed","flower_seed","bamboo_plant","mushroom_spore","corn_seed","potato_seed"][Math.floor(Math.random()*7)];
|
||
pixel.color = pixelColorPick(pixel);
|
||
},
|
||
category: "life",
|
||
},
|
||
"grass_seed": {
|
||
color: ["#439809","#258B08","#118511","#127B12","#136D14"],
|
||
behavior: [
|
||
"XX|M2%0.05|XX",
|
||
"XX|L2:grass|XX",
|
||
"XX|M1|XX",
|
||
],
|
||
tempHigh: 100,
|
||
stateHigh: "dead_plant",
|
||
tempLow: -2,
|
||
stateLow: "frozen_plant",
|
||
burn: 50,
|
||
burnTime: 20,
|
||
category: "life",
|
||
state: "solid",
|
||
density: 1400,
|
||
},
|
||
"wheat_seed": {
|
||
color: "#b6c981",
|
||
behavior: [
|
||
"XX|M2%0.25|XX",
|
||
"XX|L2:wheat AND C2:wheat%30|XX",
|
||
"XX|M1|XX",
|
||
],
|
||
tempHigh: 400,
|
||
stateHigh: "fire",
|
||
burn: 50,
|
||
burnTime: 20,
|
||
category: "life",
|
||
state: "solid",
|
||
density: 769,
|
||
},
|
||
"wheat": {
|
||
color: "#c9bc81",
|
||
behavior: behaviors.WALL,
|
||
reactions: {
|
||
"rock": { "elem1":"flour", "elem2":"rock" }
|
||
},
|
||
tempHigh: 100,
|
||
stateHigh: "dead_plant",
|
||
tempLow: -2,
|
||
stateLow: "frozen_plant",
|
||
burn:40,
|
||
burnTime:25,
|
||
category:"life",
|
||
hidden:true,
|
||
state: "solid",
|
||
density: 769,
|
||
},
|
||
"straw": {
|
||
color: ["#E9D391","#A3835E","#B79A73"],
|
||
behavior: behaviors.WALL,
|
||
tempHigh: 400,
|
||
stateHigh: "fire",
|
||
burn: 60,
|
||
burnTime: 40,
|
||
category: "solids",
|
||
state: "solid",
|
||
density: 67.5,
|
||
},
|
||
"pollen": {
|
||
color: "#ffffc0",
|
||
behavior: [
|
||
"XX|XX|XX",
|
||
"XX|CH:flower_seed%0.01|XX",
|
||
"M2|M1|M2",
|
||
],
|
||
reactions: {
|
||
"sugar_water": { "elem1": null, "elem2": "honey" },
|
||
},
|
||
category:"life",
|
||
tempHigh: 400,
|
||
stateHigh: "ash",
|
||
burn:50,
|
||
burnTime:20,
|
||
state: "solid",
|
||
density: 1435,
|
||
},
|
||
"flower_seed": {
|
||
color: "#0e990e",
|
||
behavior: [
|
||
"XX|M2%1.5|XX",
|
||
"XX|L2:grass AND C2:pistil%30|XX",
|
||
"XX|M1|XX",
|
||
],
|
||
tempHigh: 100,
|
||
stateHigh: "dead_plant",
|
||
tempLow: -2,
|
||
stateLow: "frozen_plant",
|
||
burn:50,
|
||
burnTime:20,
|
||
category:"life",
|
||
state: "solid",
|
||
density: 1400,
|
||
},
|
||
"pistil": {
|
||
color: "#734e39",
|
||
behavior: [
|
||
"XX|CR:petal%10|XX",
|
||
"CR:petal%10|XX|CR:petal%10",
|
||
"XX|XX|XX",
|
||
],
|
||
tempHigh: 100,
|
||
stateHigh: "dead_plant",
|
||
tempLow: -2,
|
||
stateLow: "frozen_plant",
|
||
burn:50,
|
||
burnTime:20,
|
||
category:"life",
|
||
hidden: true,
|
||
state: "solid",
|
||
density: 1400,
|
||
},
|
||
"petal": {
|
||
color: "#ff0000",
|
||
behavior: behaviors.WALL,
|
||
tempHigh: 100,
|
||
stateHigh: "dead_plant",
|
||
tempLow: -2,
|
||
stateLow: "frozen_plant",
|
||
burn:50,
|
||
burnTime:20,
|
||
category:"life",
|
||
hidden: true,
|
||
state: "solid",
|
||
density: 1400,
|
||
},
|
||
"tree_branch": {
|
||
color: "#a0522d",
|
||
behavior: [
|
||
"CR:plant,tree_branch%2|CR:plant,plant,plant,tree_branch%2|CR:plant,tree_branch%2",
|
||
"XX|XX|XX",
|
||
"XX|XX|XX",
|
||
],
|
||
tempHigh: 400,
|
||
stateHigh: "fire",
|
||
tempLow: -30,
|
||
stateLow: "wood",
|
||
category: "solids",
|
||
burn: 40,
|
||
burnTime: 50,
|
||
burnInto: ["ember","charcoal","fire"],
|
||
hidden: true,
|
||
state: "solid",
|
||
density: 1500,
|
||
hardness: 0.15,
|
||
breakInto: "sawdust",
|
||
},
|
||
"vine": {
|
||
color: "#005900",
|
||
behavior: [
|
||
"XX|SP|XX",
|
||
"XX|XX|XX",
|
||
"XX|CL%1 AND M1|XX",
|
||
],
|
||
tempHigh: 100,
|
||
stateHigh: "dead_plant",
|
||
tempLow: -2,
|
||
stateLow: "frozen_plant",
|
||
burn: 35,
|
||
burnTime: 100,
|
||
category: "life",
|
||
state: "solid",
|
||
density: 1050,
|
||
},
|
||
"bamboo": {
|
||
color: ["#7CC00C","#77A012"],
|
||
behavior: behaviors.WALL,
|
||
tempHigh: 380,
|
||
stateHigh: "fire",
|
||
burn: 10,
|
||
burnTime: 200,
|
||
category: "life",
|
||
state: "solid",
|
||
density: 686,
|
||
breakInto: "sawdust",
|
||
},
|
||
"bamboo_plant": {
|
||
color: ["#FBC882","#DFAD64"],
|
||
behavior: [
|
||
"XX|M2%0.25|XX",
|
||
"XX|L2:bamboo AND C2:bamboo%10|XX",
|
||
"XX|M1|XX",
|
||
],
|
||
tempHigh: 100,
|
||
stateHigh: "dead_plant",
|
||
tempLow: -2,
|
||
stateLow: "bamboo",
|
||
burn: 30,
|
||
burnTime: 100,
|
||
category: "life",
|
||
state: "solid",
|
||
density: 686,
|
||
breakInto: "sawdust",
|
||
},
|
||
"burner": {
|
||
color: "#d6baa9",
|
||
behavior: [
|
||
"CR:propane|CR:propane|CR:propane",
|
||
"XX|XX|XX",
|
||
"XX|XX|XX",
|
||
],
|
||
category: "machines",
|
||
conduct: 0.73,
|
||
},
|
||
"foam": {
|
||
color: "#cad2e3",
|
||
behavior: behaviors.FOAM,
|
||
category: "liquids",
|
||
state: "gas",
|
||
density: 40,
|
||
},
|
||
"bubble": {
|
||
color: "#afc7fa",
|
||
behavior: behaviors.BUBBLE,
|
||
category: "liquids",
|
||
state: "gas",
|
||
density: 1.294,
|
||
},
|
||
"acid": {
|
||
color: ["#b5cf91","#a1ff5e","#288f2a"],
|
||
behavior: [
|
||
"XX|DB%5|XX",
|
||
"DB%5 AND M2|XX|DB%5 AND M2",
|
||
"DB%5 AND M2|DB%10 AND M1|DB%5 AND M2",
|
||
],
|
||
ignore: ["glass","glass_shard","stained_glass","baked_clay","acid_gas","neutral_acid","acid_cloud"],
|
||
reactions: {
|
||
"ash": { "elem1":"neutral_acid", "elem2":null },
|
||
"limestone": { "elem1":"neutral_acid", "elem2":null },
|
||
"quicklime": { "elem1":"neutral_acid", "elem2":null },
|
||
"slaked_lime": { "elem1":"neutral_acid", "elem2":null },
|
||
"borax": { "elem1":"neutral_acid", "elem2":null },
|
||
"ammonia": { "elem1":"neutral_acid", "elem2":null },
|
||
},
|
||
category: "liquids",
|
||
tempHigh: 400,
|
||
stateHigh: "fire",
|
||
burn: 30,
|
||
burnTime: 1,
|
||
state: "liquid",
|
||
density: 1049,
|
||
},
|
||
"neutral_acid": {
|
||
color: ["#c8d9b0","#c1d9b0","#b8dbb9"],
|
||
behavior: behaviors.LIQUID,
|
||
category: "liquids",
|
||
state: "liquid",
|
||
density: 1020,
|
||
hidden: true,
|
||
},
|
||
"acid_gas": {
|
||
color: ["#c0d1a7","#c2ff96","#58a659"],
|
||
behavior: [
|
||
"M1|DB%5 AND M1|M1",
|
||
"DB%5 AND M1|XX|DB%5 AND M1",
|
||
"DB%5 AND M1|DB%10 AND M1|DB%5 AND M1",
|
||
],
|
||
ignore: ["glass","glass_shard","stained_glass","baked_clay","acid","neutral_acid","acid_cloud"],
|
||
reactions: {
|
||
"acid_gas": { "elem1": null, "elem2": "acid_cloud", "chance":0.3, "y":[0,15] },
|
||
"rain_cloud": { "elem1": null, "elem2": "acid_cloud", "chance":0.4, "y":[0,15] },
|
||
"snow_cloud": { "elem1": null, "elem2": "acid_cloud", "chance":0.4, "y":[0,15] },
|
||
"pyrocumulus": { "elem1": null, "elem2": "acid_cloud", "chance":0.4, "y":[0,15] },
|
||
"fire_cloud": { "elem1": null, "elem2": "acid_cloud", "chance":0.4, "y":[0,15] },
|
||
"ash": { "elem1":"hydrogen", "elem2":null, "chance":0.05 },
|
||
"limestone": { "elem1":"hydrogen", "elem2":null, "chance":0.05 },
|
||
"quicklime": { "elem1":"hydrogen", "elem2":null, "chance":0.05 },
|
||
"slaked_lime": { "elem1":"hydrogen", "elem2":null, "chance":0.05 },
|
||
"borax": { "elem1":"hydrogen", "elem2":null, "chance":0.05 },
|
||
"ammonia": { "elem1":"hydrogen", "elem2":null, "chance":0.05 },
|
||
},
|
||
category: "gases",
|
||
tempHigh: 400,
|
||
stateHigh: "fire",
|
||
burn: 30,
|
||
burnTime: 1,
|
||
state: "gas",
|
||
density: 1.63,
|
||
},
|
||
"glue": {
|
||
color: "#f0f0f0",
|
||
behavior: behaviors.STICKY,
|
||
tempHigh: 475,
|
||
stateHigh: ["cyanide","dioxin"],
|
||
category: "liquids",
|
||
state: "liquid",
|
||
density: 1300,
|
||
},
|
||
"gray_goo": {
|
||
color: "#c0c0c0",
|
||
behavior: [
|
||
"XX|CH:gray_goo|XX",
|
||
"M2%5 AND CH:gray_goo|DL%5|M2%5 AND CH:gray_goo",
|
||
"XX|CH:gray_goo AND M1|XX",
|
||
],
|
||
ignore: ["fire","smoke"],
|
||
category: "special",
|
||
state: "solid",
|
||
density: 21450,
|
||
excludeRandom: true,
|
||
},
|
||
"clone_powder": {
|
||
color: "#f0f000",
|
||
behavior: [
|
||
"XX|CF|XX",
|
||
"CF|XX|CF",
|
||
"M2|CF AND M1|M2",
|
||
],
|
||
ignore: ["cloner","ecloner","slow_cloner","floating_cloner"],
|
||
category:"machines",
|
||
insulate:true,
|
||
state:"solid",
|
||
density:2710,
|
||
hardness: 1,
|
||
},
|
||
"floating_cloner": {
|
||
color: "#c7c787",
|
||
behavior: [
|
||
"XX|CF%3 AND M1%10|XX",
|
||
"CF%3 AND M1%10|XX|CF%3 AND M1%10",
|
||
"XX|CF%3 AND M1%10|XX",
|
||
],
|
||
ignore: ["cloner","ecloner","slow_cloner","clone_powder"],
|
||
category:"machines",
|
||
insulate:true,
|
||
state:"solid",
|
||
density:1355,
|
||
hardness: 1,
|
||
},
|
||
"virus": {
|
||
color: "#cc00ff",
|
||
behavior: [
|
||
"XX|CH:virus%25|XX",
|
||
"CH:virus%25|XX|CH:virus%25",
|
||
"XX|CH:virus%25 AND M1|XX",
|
||
],
|
||
ignore: ["fire","smoke","soap","plague","cancer"],
|
||
category: "special",
|
||
state: "solid",
|
||
density: 600,
|
||
excludeRandom: true,
|
||
},
|
||
"permafrost": {
|
||
color: ["#557d65","#557d79"],
|
||
behavior: behaviors.SUPPORT,
|
||
temp: -50,
|
||
tempHigh: 0,
|
||
stateHigh: "mud",
|
||
category: "land",
|
||
state: "solid",
|
||
density: 700,
|
||
},
|
||
"cheese": {
|
||
color: "#fcba03",
|
||
behavior: behaviors.STURDYPOWDER,
|
||
tempHigh: 54,
|
||
stateHigh: "melted_cheese",
|
||
category: "food",
|
||
state: "solid",
|
||
density: 1153,
|
||
},
|
||
"melted_cheese": {
|
||
color: "#fcdb53",
|
||
behavior: behaviors.LIQUID,
|
||
tempLow: 0,
|
||
stateLow: "cheese",
|
||
category: "liquids",
|
||
viscosity: 112,
|
||
hidden: true,
|
||
state: "liquid",
|
||
density: 1153,
|
||
},
|
||
"mushroom_spore": {
|
||
color: ["#d1d1d1","#d4cfa9","#b4d4ae","#b98aba","#805236"],
|
||
behavior: [
|
||
"XX|M2%1.5|XX",
|
||
"XX|L2:mushroom_stalk AND C2:mushroom_gill%20|XX",
|
||
"XX|M1|XX",
|
||
],
|
||
reactions: {
|
||
"wood": { "elem2":"dirt", "chance":0.04 },
|
||
"tree_brake": { "elem2":"dirt", "chance":0.04 },
|
||
"plant": { "elem2":"dirt", "chance":0.07 },
|
||
"root": { "elem2":"dirt", "chance":0.07 },
|
||
"grass": { "elem2":"dirt", "chance":0.08 },
|
||
"grass_seed": { "elem2":"dirt", "chance":0.08 },
|
||
},
|
||
category: "life",
|
||
tempHigh: 225,
|
||
stateHigh: "fire",
|
||
burn: 10,
|
||
burnTime: 20,
|
||
state: "solid",
|
||
density: 123.6,
|
||
},
|
||
"mushroom_stalk": {
|
||
color: "#d1d1d1",
|
||
behavior: [
|
||
"XX|XX|XX",
|
||
"XX|XX|XX",
|
||
"XX|CH:dirt>hyphae%1 AND M1|XX",
|
||
],
|
||
reactions: {
|
||
"wood": { "elem2":"dirt", "chance":0.04 },
|
||
"tree_brake": { "elem2":"dirt", "chance":0.04 },
|
||
"plant": { "elem2":"dirt", "chance":0.07 },
|
||
"root": { "elem2":"dirt", "chance":0.07 },
|
||
"grass": { "elem2":"dirt", "chance":0.08 },
|
||
"grass_seed": { "elem2":"dirt", "chance":0.08 },
|
||
"ash": { "elem2":"dirt", "chance":0.04 },
|
||
},
|
||
category: "life",
|
||
hidden: true,
|
||
tempHigh: 225,
|
||
stateHigh: "fire",
|
||
burn: 10,
|
||
burnTime: 65,
|
||
state: "solid",
|
||
density: 90.445,
|
||
},
|
||
"mushroom_gill": {
|
||
color: "#d4cfa9",
|
||
behavior: [
|
||
"XX|CR:mushroom_cap%10|XX",
|
||
"CR:mushroom_gill,mushroom_cap%2|XX|CR:mushroom_gill,mushroom_cap%2",
|
||
"XX|XX|XX",
|
||
],
|
||
category: "life",
|
||
hidden: true,
|
||
tempHigh: 225,
|
||
stateHigh: "fire",
|
||
burn: 10,
|
||
burnTime: 65,
|
||
burnInto: "mushroom_spore",
|
||
state: "solid",
|
||
density: 90.445,
|
||
},
|
||
"mushroom_cap": {
|
||
color: ["#c74442","#c74442","#c74442","#c74442","#c74442","#c74442","#cfb4b4"],
|
||
behavior: behaviors.WALL,
|
||
category: "life",
|
||
hidden: true,
|
||
tempHigh: 225,
|
||
stateHigh: "fire",
|
||
burn: 10,
|
||
burnTime: 65,
|
||
burnInto: "mushroom_spore",
|
||
state: "solid",
|
||
density: 90.445,
|
||
},
|
||
"hyphae": {
|
||
color: "#c79789",
|
||
behavior: [
|
||
"CH:dirt>hyphae,hyphae,mycelium%0.5|CR:mushroom_spore%0.5|CH:dirt>hyphae,hyphae,mycelium%0.5",
|
||
"CH:mycelium%0.5|XX|CH:mycelium%0.5",
|
||
"CH:dirt>hyphae,hyphae,mycelium%0.5|XX|CH:dirt>hyphae,hyphae,mycelium%0.5",
|
||
],
|
||
reactions: {
|
||
"wood": { "elem2":"dirt", "chance":0.04 },
|
||
"tree_brake": { "elem2":"dirt", "chance":0.04 },
|
||
"plant": { "elem2":"dirt", "chance":0.07 },
|
||
"root": { "elem2":"dirt", "chance":0.07 },
|
||
"grass": { "elem2":"dirt", "chance":0.08 },
|
||
"grass_seed": { "elem2":"dirt", "chance":0.08 },
|
||
"ash": { "elem2":"dirt", "chance":0.04 },
|
||
},
|
||
category: "life",
|
||
hidden: true,
|
||
tempHigh: 225,
|
||
stateHigh: "fire",
|
||
burn: 30,
|
||
burnTime: 20,
|
||
state: "solid",
|
||
density: 462,
|
||
},
|
||
"mycelium": {
|
||
color: ["#734d5e","#b5949f","#734d53"],
|
||
behavior: behaviors.POWDER,
|
||
tempHigh:225,
|
||
stateHigh: "dirt",
|
||
tempLow: -50,
|
||
stateLow: "permafrost",
|
||
burn: 20,
|
||
burnTime: 40,
|
||
burnInto: "dirt",
|
||
category:"land",
|
||
state: "solid",
|
||
density: 462,
|
||
},
|
||
"lichen": {
|
||
color: ["#b6d6c3","#769482"],
|
||
behavior: [
|
||
"XX|ST:wood AND M2%0.1|XX",
|
||
"ST:wood AND M2%0.1|L2:lichen|ST:wood AND M2%0.1",
|
||
"XX|M1 AND M2%0.1|XX",
|
||
],
|
||
tempHigh: 400,
|
||
stateHigh: "fire",
|
||
burn: 50,
|
||
burnTime: 20,
|
||
category: "life",
|
||
state: "solid",
|
||
density: 1.5,
|
||
},
|
||
"antimatter": {
|
||
color: "#a89ba8",
|
||
behavior: [
|
||
"M2|DB%50 AND M2 AND EX:5|M2",
|
||
"M1|XX|M1",
|
||
"M1|DB%50 AND M1 AND EX:5|M1",
|
||
],
|
||
ignore: ["antimatter_bomb"],
|
||
category: "special",
|
||
state: "gas",
|
||
density: 0.1,
|
||
},
|
||
"plastic": {
|
||
color: "#c5dede",
|
||
behavior: behaviors.WALL,
|
||
tempHigh: 250,
|
||
burn: 10,
|
||
burnTime: 200,
|
||
burnInto: "dioxin",
|
||
category: "solids",
|
||
state: "solid",
|
||
density: 1052,
|
||
},
|
||
"molten_plastic": {
|
||
color: "#a4b3b3",
|
||
behavior: behaviors.LIQUID,
|
||
viscosity: 20,
|
||
},
|
||
"paper": {
|
||
color: "#f0f0f0",
|
||
behavior: behaviors.STURDYPOWDER,
|
||
reactions: {
|
||
"water": { "elem1":"cellulose", "elem2":null },
|
||
"dirty_water": { "elem1":"cellulose", "elem2":null },
|
||
"salt_water": { "elem1":"cellulose", "elem2":null },
|
||
"sugar_water": { "elem1":"cellulose", "elem2":null },
|
||
"blood": { "elem1":"cellulose", "elem2":null },
|
||
"foam": { "elem1":"cellulose", "elem2":null },
|
||
"bubble": { "elem1":"cellulose", "elem2":null },
|
||
"oil": { "elem1":"cellulose", "elem2":null },
|
||
"alcohol": { "elem1":"cellulose", "elem2":null },
|
||
"vinegar": { "elem1":"cellulose", "elem2":null },
|
||
},
|
||
tempHigh: 248,
|
||
stateHigh: "fire",
|
||
burn: 70,
|
||
burnTime: 300,
|
||
category: "powders",
|
||
state: "solid",
|
||
density: 1201,
|
||
},
|
||
"cellulose": {
|
||
color: "#c7d4c9",
|
||
behavior: behaviors.LIQUID,
|
||
tempHigh: 124,
|
||
stateHigh: "steam",
|
||
burn: 35,
|
||
burnTime: 300,
|
||
category: "life",
|
||
state: "solid",
|
||
density: 65,
|
||
viscosity: 2500,
|
||
},
|
||
"fuse": {
|
||
color: "#825d38",
|
||
behavior: behaviors.WALL,
|
||
tempHigh: 500,
|
||
stateHigh: "fire",
|
||
burn: 100,
|
||
burnTime: 1,
|
||
category: "solids",
|
||
state: "solid",
|
||
density: 1000,
|
||
},
|
||
"dioxin": {
|
||
color: "#b8b8b8",
|
||
behavior: behaviors.GAS,
|
||
reactions: {
|
||
"cell": { "elem2":"cancer", "chance":0.0015 },
|
||
"blood": { "elem2":"infection", "chance":0.01 },
|
||
"antibody": { "elem2":"blood", "chance":0.025 },
|
||
"frog": { "elem2":"meat", "chance":0.05 },
|
||
"fish": { "elem2":"meat", "chance":0.05 },
|
||
"rat": { "elem2":"rotten_meat", "chance":0.05 },
|
||
},
|
||
category: "gases",
|
||
state: "gas",
|
||
density: 1830,
|
||
},
|
||
"insulation": {
|
||
color: "#b8aea5",
|
||
behavior: behaviors.WALL,
|
||
category: "solids",
|
||
insulate: true,
|
||
state: "solid",
|
||
},
|
||
"iron": {
|
||
color: ["#cbcdcd","#bdbdbd"],
|
||
behavior: behaviors.WALL,
|
||
reactions: {
|
||
"water": { "elem1":"rust", chance:0.0025 },
|
||
"salt_water": { "elem1":"rust", chance:0.005 },
|
||
"dirty_water": { "elem1":"rust", chance:0.04 },
|
||
"sugar_water": { "elem1":"rust", chance:0.0035 },
|
||
},
|
||
tempHigh: 1538,
|
||
category: "solids",
|
||
density: 7860,
|
||
conduct: 0.47,
|
||
},
|
||
"rust": {
|
||
color: ["#AE551C","#BC6E39","#925F49"],
|
||
behavior: behaviors.SUPPORT,
|
||
tempHigh: 1538,
|
||
stateHigh: "molten_iron",
|
||
category: "solids",
|
||
state: "solid",
|
||
density: 5250,
|
||
conduct: 0.37,
|
||
},
|
||
"copper": {
|
||
color: ["#A95232","#BE4322","#C76035"],
|
||
behavior: [
|
||
"XX|XX|XX",
|
||
"XX|CH:oxidized_copper%0.001|XX",
|
||
"XX|XX|XX",
|
||
],
|
||
reactions: {
|
||
"water": { "elem1":"oxidized_copper", chance:0.0025 },
|
||
"salt_water": { "elem1":"oxidized_copper", chance:0.005 },
|
||
"dirty_water": { "elem1":"oxidized_copper", chance:0.04 },
|
||
"sugar_water": { "elem1":"oxidized_copper", chance:0.0035 },
|
||
},
|
||
category: "solids",
|
||
tempHigh: 1085,
|
||
density: 8960,
|
||
conduct: 0.95,
|
||
},
|
||
"oxidized_copper": {
|
||
color: ["#406555","#42564A","#517364"],
|
||
behavior: [
|
||
"XX|XX|XX",
|
||
"XX|XX|XX",
|
||
"XX|XX|XX",
|
||
],
|
||
category: "solids",
|
||
hidden: true,
|
||
tempHigh: 1085,
|
||
stateHigh: "molten_copper",
|
||
density: 8960,
|
||
conduct: 0.85,
|
||
},
|
||
"zinc": {
|
||
color: ["#7C7A7B","#9D9D9F","#F8F8F3"],
|
||
behavior: behaviors.WALL,
|
||
tempHigh: 419.53,
|
||
category: "solids",
|
||
density: 7068,
|
||
conduct: 0.53,
|
||
},
|
||
"tin": {
|
||
color: ["#9E9D98","#AEADA4"],
|
||
behavior: behaviors.WALL,
|
||
tempHigh: 231.9,
|
||
category: "solids",
|
||
density: 7260,
|
||
conduct: 0.45,
|
||
},
|
||
"nickel": {
|
||
color: "#727472",
|
||
behavior: behaviors.WALL,
|
||
tempHigh: 1455,
|
||
category: "solids",
|
||
density: 8900,
|
||
conduct: 0.51,
|
||
},
|
||
"silver": {
|
||
color: "#CACACA",
|
||
behavior: behaviors.WALL,
|
||
tempHigh: 961.8,
|
||
category: "solids",
|
||
density: 10497,
|
||
conduct: 0.99,
|
||
},
|
||
"gold": {
|
||
color: ["#FFF0B5","#986A1A","#F0BB62"],
|
||
behavior: behaviors.WALL,
|
||
tempHigh: 1064,
|
||
category: "solids",
|
||
density: 19300,
|
||
conduct: 0.81,
|
||
},
|
||
"gold_coin": {
|
||
color: ["#FFF0B5","#986A1A","#F0BB62"],
|
||
behavior: behaviors.POWDER,
|
||
tempHigh: 1064,
|
||
stateHigh: "molten_gold",
|
||
category: "powders",
|
||
state: "solid",
|
||
density: 19300,
|
||
conduct: 0.78,
|
||
},
|
||
"aluminum": {
|
||
color: ["#D1C6BE","#B5C0AD","#B9B8BC"],
|
||
behavior: behaviors.WALL,
|
||
tempHigh: 660.3,
|
||
category: "solids",
|
||
density: 2710,
|
||
conduct: 0.73,
|
||
},
|
||
"lead": {
|
||
color: "#6c6c6a",
|
||
behavior: behaviors.WALL,
|
||
tempHigh: 327.5,
|
||
category: "solids",
|
||
density: 11343,
|
||
conduct: 0.41,
|
||
},
|
||
"tungsten": {
|
||
color: ["#D4D3CD","#C3C0B8","#BCBAAE","#625950"],
|
||
behavior: behaviors.WALL,
|
||
tempHigh: 3422,
|
||
category: "solids",
|
||
density: 19300,
|
||
conduct: 0.65,
|
||
},
|
||
"molten_tungsten": {
|
||
color: ['#ffff67', '#ffd367', '#ff9e00', '#d1ff5c', '#5cffb0', '#0073ff', '#ca57ff', '#ffba57', '#ff8c00', '#c46f28', '#c45928', '#c44300']
|
||
},
|
||
"brass": {
|
||
color: ["#cb9e5d","#865e39"],
|
||
behavior: behaviors.WALL,
|
||
tempHigh: 927,
|
||
category: "solids",
|
||
density: 8550,
|
||
conduct: 0.52,
|
||
},
|
||
"bronze": {
|
||
color: "#cd7f32",
|
||
behavior: behaviors.WALL,
|
||
tempHigh: 913,
|
||
category: "solids",
|
||
density: 8150,
|
||
conduct: 0.44,
|
||
},
|
||
"sterling": {
|
||
color: ["#858478","#eae8e2","#bfbcb7"],
|
||
behavior: behaviors.WALL,
|
||
tempHigh: 802,
|
||
category: "solids",
|
||
density: 10375.25,
|
||
conduct: 0.95,
|
||
},
|
||
"steel": {
|
||
color: "#71797E",
|
||
behavior: behaviors.WALL,
|
||
tempHigh: 1455.5,
|
||
category: "solids",
|
||
density: 7850,
|
||
conduct: 0.42,
|
||
hardness: 0.8,
|
||
},
|
||
"rose_gold": {
|
||
color: ["#B76E79","#a1334d","#f06283"],
|
||
behavior: behaviors.WALL,
|
||
tempHigh: 897,
|
||
category: "solids",
|
||
density: 12900,
|
||
conduct: 0.87,
|
||
},
|
||
"solder": {
|
||
color: "#a1a19d",
|
||
behavior: behaviors.WALL,
|
||
tempHigh: 200,
|
||
category: "solids",
|
||
density: 8885,
|
||
conduct: 0.43,
|
||
},
|
||
"molten_copper": {
|
||
reactions: {
|
||
"molten_zinc": { "elem1": null, "elem2": "molten_brass" },
|
||
"molten_tin": { "elem1": null, "elem2": "molten_bronze" },
|
||
"molten_silver": { "elem1": null, "elem2": "molten_sterling" },
|
||
"molten_gold": { "elem1": null, "elem2": "molten_rose_gold" },
|
||
}
|
||
},
|
||
"molten_iron": {
|
||
reactions: {
|
||
"charcoal": { "elem1": "molten_steel", "elem2": null },
|
||
"diamond": { "elem1": "molten_steel", "elem2": null },
|
||
"carbon_dioxide": { "elem1": "molten_steel", "elem2": null },
|
||
}
|
||
},
|
||
"molten_tin": {
|
||
reactions: {
|
||
"molten_lead": { "elem1": null, "elem2": "molten_solder" },
|
||
}
|
||
},
|
||
|
||
"milk": {
|
||
color: "#fafafa",
|
||
behavior: behaviors.LIQUID,
|
||
tempHigh: 93,
|
||
stateHigh: "yogurt",
|
||
viscosity: 1.5,
|
||
category: "liquids",
|
||
state: "liquid",
|
||
density: 1036.86,
|
||
},
|
||
"yogurt": {
|
||
color: "#f0efe6",
|
||
behavior: behaviors.STURDYPOWDER,
|
||
category: "food",
|
||
state: "liquid",
|
||
density: 820.33,
|
||
},
|
||
"vinegar": {
|
||
color: "#ffecb3",
|
||
behavior: behaviors.LIQUID,
|
||
reactions: {
|
||
"milk": { "elem1": null, "elem2": "cheese" },
|
||
"baking_soda": { "elem1": "carbon_dioxide", "elem2": "sodium_acetate" },
|
||
"rust": { "elem2":"iron", chance:0.05 },
|
||
"oxidized_copper": { "elem2":"copper", chance:0.05 },
|
||
},
|
||
viscosity: 12,
|
||
tempHigh: 100.6,
|
||
stateHigh: "steam",
|
||
category: "liquids",
|
||
state: "liquid",
|
||
density: 1006,
|
||
},
|
||
"baking_soda": {
|
||
color: "#ededed",
|
||
behavior: behaviors.POWDER,
|
||
category: "powders",
|
||
state: "solid",
|
||
density: 1000,
|
||
},
|
||
"sodium_acetate": {
|
||
color: ["#ededed","#dbdbdb"],
|
||
behavior: behaviors.POWDER,
|
||
hidden: true,
|
||
state: "solid",
|
||
density: 900,
|
||
category: "powders",
|
||
},
|
||
"yeast": {
|
||
color: ["#AD9166","#9A7F4E","#D8BB8D"],
|
||
behavior: [
|
||
"XX|CL:50%20|XX",
|
||
"CL:50%20 AND SW:bread%30|XX|CL:50%20 AND SW:bread%30",
|
||
"XX|M1|XX",
|
||
],
|
||
reactions: {
|
||
"bread": { "elem1": "bread" },
|
||
"sugar": { "elem2": "alcohol" },
|
||
"potato": { "elem2": "alcohol" },
|
||
},
|
||
tempHigh: 100,
|
||
stateHigh: "bread",
|
||
burn: 50,
|
||
burnTime: 20,
|
||
burnInto: "ash",
|
||
category: "food",
|
||
state: "solid",
|
||
density: 1180,
|
||
},
|
||
"corn": {
|
||
color: ["#F8D223","#D6BA2A","#f7f5ba","#DBD281","#CDB12D"],
|
||
behavior: behaviors.WALL,
|
||
category: "food",
|
||
burn: 10,
|
||
burnTime: 200,
|
||
tempHigh: 180,
|
||
stateHigh: "popcorn",
|
||
state: "solid",
|
||
density: 721,
|
||
},
|
||
"popcorn": {
|
||
color: ["#a6a076","#ebe4ab","#ebe4ab","#ebe4ab","#ebe4ab","#ebe4ab","#ebe4ab","#c99947"],
|
||
behavior: behaviors.POWDER,
|
||
category: "food",
|
||
tempHigh: 500,
|
||
stateHigh: "ash",
|
||
burn: 20,
|
||
burnTime: 200,
|
||
burnInto: ["fire","ash"],
|
||
state: "solid",
|
||
density: 360.5,
|
||
},
|
||
"corn_seed": {
|
||
color: ["#F2B813","#F9E3BA"],
|
||
behavior: [
|
||
"XX|M2%0.25|XX",
|
||
"XX|L2:plant,corn AND C2:corn%30|XX",
|
||
"XX|M1|XX",
|
||
],
|
||
tempHigh: 400,
|
||
stateHigh: "fire",
|
||
burn: 50,
|
||
burnTime: 20,
|
||
category: "life",
|
||
state: "solid",
|
||
density: 721,
|
||
},
|
||
"potato_seed": {
|
||
color: ["#CDA57F","#AA7437","#BC9563"],
|
||
behavior: [
|
||
"XX|CH:dirt>root|XX",
|
||
"CH:dirt>potato%5|CH:potato%1|CH:dirt>potato%5",
|
||
"XX|SW:dirt%3 AND M1|XX",
|
||
],
|
||
tempHigh: 400,
|
||
stateHigh: "fire",
|
||
burn: 50,
|
||
burnTime: 20,
|
||
category: "life",
|
||
state: "solid",
|
||
density: 675,
|
||
},
|
||
"potato": {
|
||
color: ["#d99857","#d98757","#a66933"],
|
||
behavior: behaviors.STURDYPOWDER,
|
||
tempHigh: 400,
|
||
stateHigh: "ash",
|
||
burn: 50,
|
||
burnTime: 20,
|
||
burnInto: "ash",
|
||
category: "food",
|
||
state: "solid",
|
||
density: 675,
|
||
},
|
||
"root": {
|
||
color: "#7B6F6B",
|
||
behavior: behaviors.WALL,
|
||
reactions: {
|
||
"rock": { "elem2":"sand", "chance":0.0004 },
|
||
},
|
||
tempHigh: 100,
|
||
stateHigh: "dead_plant",
|
||
tempLow: -2,
|
||
stateLow: "frozen_plant",
|
||
burn: 50,
|
||
burnTime: 20,
|
||
burnInto: "dirt",
|
||
category: "life",
|
||
state: "solid",
|
||
density: 1250,
|
||
},
|
||
"bread": {
|
||
color: "#F2CF99",
|
||
behavior: behaviors.STURDYPOWDER,
|
||
tempHigh: 176,
|
||
stateHigh: "toast",
|
||
category: "food",
|
||
burn: 30,
|
||
burnTime: 200,
|
||
burnInto: "ash",
|
||
state: "solid",
|
||
density: 233.96,
|
||
},
|
||
"toast": {
|
||
color: "#C08655",
|
||
behavior: behaviors.STURDYPOWDER,
|
||
tempHigh: 500,
|
||
stateHigh: "ash",
|
||
category: "food",
|
||
burn: 50,
|
||
burnTime: 170,
|
||
burnInto: "ash",
|
||
state: "solid",
|
||
density: 233.96,
|
||
},
|
||
"flour": {
|
||
color: "#F0E2B7",
|
||
behavior: behaviors.POWDER,
|
||
reactions: {
|
||
"water": { "elem1": "dough", "elem2": null },
|
||
},
|
||
category: "powders",
|
||
tempHigh: 400,
|
||
stateHigh: "fire",
|
||
burn:40,
|
||
burnTime:25,
|
||
state: "solid",
|
||
density: 600,
|
||
},
|
||
"dough": {
|
||
color: "#EDD8BA",
|
||
behavior: behaviors.SUPPORT,
|
||
category: "food",
|
||
tempHigh: 94,
|
||
stateHigh: "bread",
|
||
burn:40,
|
||
burnTime:25,
|
||
burnInto:"ash",
|
||
state: "solid",
|
||
density: 526.9,
|
||
},
|
||
"salt": {
|
||
color: ["#f2f2f2","#e0e0e0"],
|
||
behavior: behaviors.POWDER,
|
||
reactions: {
|
||
"ice": { "elem1":null, "elem2":"salt_water", "chance":0.1 },
|
||
"snow": { "elem1":null, "elem2":"salt_water", "chance":0.25 },
|
||
"packed_snow": { "elem1":null, "elem2":"salt_water", "chance":0.05 },
|
||
"packed_ice": { "elem1":null, "elem2":"salt_water", "chance":0.01 },
|
||
},
|
||
category: "powders",
|
||
tempHigh: 801,
|
||
state: "solid",
|
||
density: 2160,
|
||
},
|
||
"sugar": {
|
||
color: "#f2f2f2",
|
||
behavior: behaviors.POWDER,
|
||
category: "powders",
|
||
tempHigh: 186,
|
||
stateHigh: "caramel",
|
||
state: "solid",
|
||
density: 1590,
|
||
},
|
||
"candy": {
|
||
color: "#e6cab1",
|
||
behavior: behaviors.WALL,
|
||
tempHigh: 186,
|
||
stateHigh: "caramel",
|
||
category: "food",
|
||
state: "solid",
|
||
density: 900,
|
||
},
|
||
"dry_ice": {
|
||
color: "#e6e6e6",
|
||
behavior: behaviors.WALL,
|
||
category: "solids",
|
||
temp: -78.5,
|
||
tempHigh: -78.5,
|
||
stateHigh: "carbon_dioxide",
|
||
state: "solid",
|
||
density: 1562,
|
||
},
|
||
"nitrogen_ice": {
|
||
color: "#e6e6e6",
|
||
behavior: behaviors.WALL,
|
||
category: "solids",
|
||
temp: -259.86,
|
||
tempHigh: -209.86,
|
||
stateHigh: "liquid_nitrogen",
|
||
state: "solid",
|
||
density: 1562,
|
||
hidden: true,
|
||
},
|
||
"alcohol": {
|
||
color: "#c9c5b1",
|
||
behavior: behaviors.LIQUID,
|
||
reactions: {
|
||
"virus": { "elem2":null },
|
||
"plague": { "elem2":null },
|
||
},
|
||
viscosity: 1,
|
||
tempHigh: 78,
|
||
stateHigh: ["steam","carbon_dioxide"],
|
||
burn: 100,
|
||
burnTime: 3,
|
||
fireColor: ["#80ACF0","#96CDFE","#bee6d4"],
|
||
category: "liquids",
|
||
state: "liquid",
|
||
density: 785.1,
|
||
},
|
||
"basalt": {
|
||
color: ["#2e2e2e","#333333","#3d3d3d"],
|
||
behavior: behaviors.STURDYPOWDER,
|
||
tempHigh: 1262.5,
|
||
stateHigh: "magma",
|
||
category: "land",
|
||
state: "solid",
|
||
density: 3000,
|
||
hardness: 0.65,
|
||
breakInto: "gravel",
|
||
},
|
||
"soap": {
|
||
color: "#f2f2f2",
|
||
behavior: [
|
||
"XX|CR:bubble%0.25|XX",
|
||
"M2|XX|M2",
|
||
"M2|M1|M2",
|
||
],
|
||
reactions: {
|
||
"rust": { "elem2": "iron" },
|
||
"oxidized_copper": { "elem2": "copper" },
|
||
"blood": { "elem2": "water" },
|
||
"dirty_water": { "elem2": "water" },
|
||
"salt_water": { "elem2": "water" },
|
||
"oxygen": { "elem2": "bubble" },
|
||
"plague": { "elem2": null },
|
||
"virus": { "elem2": null },
|
||
"infection": { "elem2": null },
|
||
"mushroom_spore": { "elem2": null },
|
||
"lichen": { "elem2": null },
|
||
"rotten_meat": { "elem2": "meat" },
|
||
"acid_gas": { "elem2": "hydrogen" },
|
||
"carbon_dioxide": { "elem2": "oxygen" },
|
||
"acid": { "elem2": "hydrogen" },
|
||
"acid_cloud": { "elem2": "rain_cloud" },
|
||
},
|
||
tempHigh: 100,
|
||
stateHigh: "bubble",
|
||
viscosity: 500,
|
||
state: "liquid",
|
||
category:"liquids",
|
||
density: 1055,
|
||
},
|
||
"blood": {
|
||
color: "#ff0000",
|
||
behavior: behaviors.LIQUID,
|
||
reactions: {
|
||
"vaccine": { "elem1":"antibody", "elem2":null },
|
||
"plague": { "elem1":"infection", "elem2":null },
|
||
"virus": { "elem1":"infection", "elem2":null },
|
||
"cancer": { "elem1":"infection" },
|
||
"cyanide": { "elem1":"infection", "elem2":null },
|
||
"mushroom_spore": { "elem1":"infection", "elem2":null },
|
||
"dirty_water": { "elem1":"infection", "elem2":null },
|
||
"rust": { "elem1":"infection", "chance":0.05 },
|
||
"oxidized_copper": { "elem1":"infection", "chance":0.05 },
|
||
"rat": { "elem1":"infection", "chance":0.075 },
|
||
"flea": { "elem1":"infection", "chance":0.03 },
|
||
"dirt": { "elem2":"mud" },
|
||
"sand": { "elem2":"wet_sand" },
|
||
},
|
||
viscosity: 10,
|
||
tempHigh: 124.55,
|
||
stateHigh: ["steam","salt","oxygen"],
|
||
category:"liquids",
|
||
state: "liquid",
|
||
density: 1060,
|
||
},
|
||
"vaccine": {
|
||
color: "#e0d0ad",
|
||
behavior: behaviors.LIQUID,
|
||
reactions: {
|
||
"infection": { "elem1":null, "elem2":"antibody", "chance":0.1 },
|
||
"antibody": { "elem1":null, "chance":0.0025 },
|
||
"plague": { "elem2":null, "chance":0.1 },
|
||
"virus": { "elem2":null, "chance":0.1 },
|
||
"cancer": { "elem2":null, "chance":0.01 },
|
||
},
|
||
viscosity: 2.6,
|
||
tempHigh: 124.55,
|
||
stateHigh: "steam",
|
||
category:"liquids",
|
||
state: "liquid",
|
||
density: 1125,
|
||
},
|
||
"antibody": {
|
||
color: "#ff4040",
|
||
behavior: behaviors.LIQUID,
|
||
reactions: {
|
||
"blood": { "elem2":"antibody", "chance":0.01 },
|
||
"infection": { "elem2":"antibody", "chance":0.1 },
|
||
"cancer": { "elem2":null, "chance":0.01 },
|
||
},
|
||
viscosity: 6.3,
|
||
tempHigh: 124.55,
|
||
stateHigh: ["steam","salt","oxygen"],
|
||
category:"liquids",
|
||
hidden: true,
|
||
state: "liquid",
|
||
density: 1060,
|
||
},
|
||
"infection": {
|
||
color: "#cf005d",
|
||
behavior: behaviors.LIQUID,
|
||
reactions: {
|
||
"blood": { "elem2":"infection", "chance":0.01 },
|
||
"frog": { "elem2":"rotten_meat", "chance":0.005 },
|
||
"fish": { "elem2":"rotten_meat", "chance":0.005 },
|
||
"meat": { "elem2":"rotten_meat", "chance":0.005 },
|
||
},
|
||
viscosity: 15,
|
||
tempHigh: 124.55,
|
||
stateHigh: ["plague","plague","plague","salt","oxygen"],
|
||
category:"liquids",
|
||
hidden: true,
|
||
state: "liquid",
|
||
density: 1060,
|
||
},
|
||
"poison": {
|
||
color: "#00ff00",
|
||
behavior: behaviors.LIQUID,
|
||
reactions: {
|
||
"blood": { "elem1":null, "elem2":"infection" },
|
||
"water": { "elem1":null, "elem2":"dirty_water" },
|
||
"soap": { "elem1":null, "chance":0.02 },
|
||
"plant": { "elem1":null, "elem2":"dead_plant" },
|
||
"grass": { "elem1":null, "elem2":"dead_plant" },
|
||
"algae": { "elem1":null, "elem2":null },
|
||
"mushroom_spore": { "elem1":null, "elem2":null },
|
||
"lichen": { "elem1":null, "elem2":null },
|
||
"rat": { "elem1":null, "elem2":"rotten_meat" },
|
||
"frog": { "elem1":null, "elem2":"rotten_meat" },
|
||
"fish": { "elem1":null, "elem2":"rotten_meat" },
|
||
"head": { "elem1":null, "elem2":"rotten_meat" },
|
||
"body": { "elem1":null, "elem2":"rotten_meat" },
|
||
"ant": { "elem1":null, "elem2":null },
|
||
"worm": { "elem1":null, "elem2":null },
|
||
"fly": { "elem1":null, "elem2":null },
|
||
"firefly": { "elem1":null, "elem2":null },
|
||
"bee": { "elem1":null, "elem2":null },
|
||
"slug": { "elem1":null, "elem2":"slime" },
|
||
"snail": { "elem1":null, "elem2":"calcium" },
|
||
"sapling": { "elem1":null, "elem2":"dead_plant" },
|
||
"root": { "elem1":null, "elem2":"dead_plant" },
|
||
"flower_seed": { "elem1":null, "elem2":"dead_plant" },
|
||
"pistil": { "elem1":null, "elem2":"dead_plant" },
|
||
"petal": { "elem1":null, "elem2":"dead_plant" },
|
||
"grass_seed": { "elem1":null, "elem2":"dead_plant" },
|
||
"meat": { "elem1":null, "elem2":"rotten_meat" },
|
||
},
|
||
viscosity: 2,
|
||
tempHigh: 400,
|
||
stateHigh: "plague",
|
||
category:"liquids",
|
||
state: "liquid",
|
||
density: 1060,
|
||
},
|
||
"antidote": {
|
||
color: "#c9b836",
|
||
behavior: behaviors.LIQUID,
|
||
reactions: {
|
||
"poison": { "elem1":null, "elem2":null },
|
||
},
|
||
viscosity: 2,
|
||
tempHigh: 400,
|
||
stateHigh: "plague",
|
||
category:"liquids",
|
||
state: "liquid",
|
||
density: 1060,
|
||
},
|
||
"honey": {
|
||
color: ["#F6CE1A","#E79001","#BB5503"],
|
||
behavior: behaviors.LIQUID,
|
||
viscosity: 10000,
|
||
tempHigh: 71.11,
|
||
stateHigh: "caramel",
|
||
category:"liquids",
|
||
state: "liquid",
|
||
density: 1420,
|
||
},
|
||
"caramel": {
|
||
color: "#e89a51",
|
||
behavior: behaviors.LIQUID,
|
||
reactions: {
|
||
"fire": { "elem1": "molasses" },
|
||
},
|
||
viscosity: 500,
|
||
temp: 40,
|
||
tempLow: 24,
|
||
stateLow: "candy",
|
||
tempHigh: 204.44,
|
||
stateHigh: "fire",
|
||
category: "liquids",
|
||
state: "liquid",
|
||
density: 850,
|
||
},
|
||
"molasses": {
|
||
color: ["#210c06","#170804"],
|
||
behavior: behaviors.LIQUID,
|
||
viscosity: 7500,
|
||
tempHigh: 1000,
|
||
stateHigh: ["fire","sugar","steam"],
|
||
category:"liquids",
|
||
state: "liquid",
|
||
density: 1600,
|
||
},
|
||
"ketchup": {
|
||
color: "#ff3119",
|
||
behavior: behaviors.LIQUID,
|
||
viscosity: 50000,
|
||
tempHigh: 260,
|
||
stateHigh: ["vinegar","steam","salt","sugar"],
|
||
category:"liquids",
|
||
state: "liquid",
|
||
density: 1235,
|
||
},
|
||
"chocolate_syrup": {
|
||
color: "#3b160b",
|
||
behavior: behaviors.LIQUID,
|
||
tempLow: 0,
|
||
stateLow: "chocolate",
|
||
tempHigh: 99,
|
||
stateHigh: ["steam","sugar"],
|
||
category: "liquids",
|
||
viscosity: 40,
|
||
state: "liquid",
|
||
density: 1325,
|
||
hidden: true,
|
||
},
|
||
"liquid_hydrogen": {
|
||
color: "#97afcf",
|
||
behavior: behaviors.LIQUID,
|
||
reactions: {
|
||
"liquid_oxygen": { "elem1":"ice", "elem2":null },
|
||
"oxygen": { "elem1":"ice", "elem2":null },
|
||
},
|
||
category: "liquids",
|
||
burn: 100,
|
||
burnTime: 2,
|
||
temp:-259.16,
|
||
tempHigh: -252.879,
|
||
stateHigh: "hydrogen",
|
||
state: "liquid",
|
||
density: 71,
|
||
},
|
||
"liquid_oxygen": {
|
||
color: "#00ad99",
|
||
behavior: behaviors.LIQUID,
|
||
reactions: {
|
||
"hydrogen": { "elem1":"ice", "elem2":null },
|
||
},
|
||
category: "liquids",
|
||
burn: 100,
|
||
burnTime: 2,
|
||
temp:-218.79,
|
||
tempHigh: -182.962,
|
||
stateHigh: "oxygen",
|
||
state: "liquid",
|
||
density: 1141,
|
||
},
|
||
"liquid_nitrogen": {
|
||
color: "#d3e1e3",
|
||
behavior: behaviors.LIQUID,
|
||
category: "liquids",
|
||
temp:-209.86,
|
||
tempHigh: -195.795,
|
||
stateHigh: "nitrogen",
|
||
tempLow: -259.86,
|
||
stateLow: "nitrogen_ice",
|
||
state: "liquid",
|
||
density: 804,
|
||
},
|
||
"liquid_helium": {
|
||
color: "#e3d3d3",
|
||
behavior: behaviors.LIQUID,
|
||
category: "liquids",
|
||
temp:-272.20,
|
||
tempHigh: -268.928,
|
||
stateHigh: "helium",
|
||
state: "liquid",
|
||
density: 145,
|
||
hidden: true,
|
||
},
|
||
"calcium": {
|
||
color: ["#515053","#7a787d","#748193","#FEF9FF","#748193","#7a787d","#515053"],
|
||
behavior: behaviors.POWDER,
|
||
tempHigh: 842,
|
||
category: "powders",
|
||
state: "solid",
|
||
density: 1550,
|
||
conduct: 0.40,
|
||
},
|
||
"limestone": {
|
||
color: ["#C5B79C","#D9CCB2","#F8F1DB","#FCFAEB"],
|
||
behavior: behaviors.STURDYPOWDER,
|
||
tempHigh: 825,
|
||
stateHigh: "quicklime",
|
||
category: "land",
|
||
state: "solid",
|
||
density: 2100,
|
||
hardness: 0.4,
|
||
breakInto: ["quicklime","calcium","dust"],
|
||
},
|
||
"quicklime": {
|
||
color: "#E9EBE7",
|
||
behavior: behaviors.POWDER,
|
||
tempHigh: 4662,
|
||
stateHigh: "molten_calcium",
|
||
category: "land",
|
||
state: "solid",
|
||
density: 1025,
|
||
hardness: 0.33,
|
||
breakInto: ["calcium","dust"],
|
||
},
|
||
"slaked_lime": {
|
||
color: "#adb8b5",
|
||
behavior: behaviors.STURDYPOWDER,
|
||
tempHigh: 580,
|
||
stateHigh: "quicklime",
|
||
category: "land",
|
||
hidden: true,
|
||
state: "solid",
|
||
density: 2211,
|
||
hardness: 0.2,
|
||
breakInto: ["calcium","dust"],
|
||
},
|
||
"metal_scrap": {
|
||
color: ["#b0afb4","#8c8f98","#cbcdcd","#6c6c6a","#fef9ff"],
|
||
behavior: behaviors.POWDER,
|
||
tempHigh: 1538,
|
||
stateHigh: ["molten_iron","molten_aluminum","molten_tin"],
|
||
category: "powders",
|
||
density: 2720,
|
||
state: "solid",
|
||
conduct: 0.43,
|
||
},
|
||
"slag": {
|
||
color: ["#4B3A2D","#6A5447","#6B5B53","#675851","#78756E"],
|
||
behavior: behaviors.POWDER,
|
||
tempHigh: 1780,
|
||
category: "powders",
|
||
density: 2400,
|
||
state: "solid",
|
||
conduct: 0.03,
|
||
},
|
||
"neon": {
|
||
color: "#bababa",
|
||
behavior: behaviors.GAS,
|
||
behaviorOn: [
|
||
"M2|M1|M2",
|
||
"M1|CC:#ff0000|M1",
|
||
"M2|M1|M2",
|
||
],
|
||
tempLow: -248.59,
|
||
stateLow: "liquid_neon",
|
||
category: "gases",
|
||
density: 0.9002,
|
||
state: "gas",
|
||
conduct: 0.86,
|
||
},
|
||
"liquid_neon": {
|
||
color: "#d1d1d1",
|
||
behavior: behaviors.LIQUID,
|
||
behaviorOn: [
|
||
"XX|XX|XX",
|
||
"M2|CC:#ff0000|M2",
|
||
"M1|M1|M1",
|
||
],
|
||
temp: -258.59,
|
||
tempHigh: -248.59,
|
||
stateHigh: "neon",
|
||
category: "liquids",
|
||
hidden: true,
|
||
density: 1207,
|
||
state: "liquid",
|
||
conduct: 0.83,
|
||
},
|
||
"rain_cloud": {
|
||
color: "#636b78",
|
||
behavior: [
|
||
"XX|XX|XX",
|
||
"M1%5|CH:water%0.05|M1%5",
|
||
"CR:electric%0.05|CR:electric%0.05|CR:electric%0.05",
|
||
],
|
||
category:"gases",
|
||
temp: 80,
|
||
tempLow: 0,
|
||
stateLow: "snow_cloud",
|
||
state: "gas",
|
||
density: 0.5,
|
||
conduct: 0.03,
|
||
},
|
||
"snow_cloud": {
|
||
color: "#7e8691",
|
||
behavior: [
|
||
"XX|XX|XX",
|
||
"M1%5|CH:snow%0.05|M1%5",
|
||
"XX|XX|XX",
|
||
],
|
||
category:"gases",
|
||
temp: -10,
|
||
tempHigh: 30,
|
||
stateHigh: "rain_cloud",
|
||
state: "gas",
|
||
density: 0.55,
|
||
conduct: 0.01,
|
||
},
|
||
"acid_cloud": {
|
||
color: "#637865",
|
||
behavior: [
|
||
"XX|XX|XX",
|
||
"M1%5|CH:acid%0.05|M1%5",
|
||
"XX|XX|XX",
|
||
],
|
||
reactions: {
|
||
"ash": { "elem1":"rain_cloud", "elem2":null, "chance":0.05 },
|
||
"limestone": { "elem1":"rain_cloud", "elem2":null, "chance":0.05 },
|
||
"quicklime": { "elem1":"rain_cloud", "elem2":null, "chance":0.05 },
|
||
"slaked_lime": { "elem1":"rain_cloud", "elem2":null, "chance":0.05 },
|
||
"borax": { "elem1":"rain_cloud", "elem2":null, "chance":0.05 },
|
||
"ammonia": { "elem1":"rain_cloud", "elem2":null, "chance":0.05 },
|
||
},
|
||
category:"gases",
|
||
burn: 15,
|
||
burnTime: 5,
|
||
state: "gas",
|
||
density: 0.575,
|
||
},
|
||
"pyrocumulus": {
|
||
color: "#2e2e2e",
|
||
behavior: [
|
||
"XX|XX|XX",
|
||
"M1%5|CH:ash%0.075|M1%5",
|
||
"XX|XX|XX",
|
||
],
|
||
reactions: {
|
||
"fireball": { "elem1":null, "elem2":"fire_cloud", "chance":0.25 },
|
||
},
|
||
category:"gases",
|
||
hidden: true,
|
||
state: "gas",
|
||
density: 0.58,
|
||
},
|
||
"fire_cloud": {
|
||
color: ["#332424","#473431","#473931"],
|
||
behavior: [
|
||
"XX|XX|XX",
|
||
"M1%5|CH:fireball%0.02|M1%5",
|
||
"XX|XX|XX",
|
||
],
|
||
reactions: {
|
||
"rain_cloud": { "elem1": "pyrocumulus", "elem2": "pyrocumulus" },
|
||
"snow_cloud": { "elem1": "pyrocumulus", "elem2": "rain_cloud" },
|
||
"acid_cloud": { "elem1": "fire", "elem2": "electric" },
|
||
},
|
||
temp: 500,
|
||
tempLow: 100,
|
||
stateLow: "pyrocumulus",
|
||
category:"gases",
|
||
state: "gas",
|
||
density: 0.59,
|
||
},
|
||
"battery": {
|
||
color: "#9c6c25",
|
||
behavior: [
|
||
"XX|SH|XX", // shocks (adds charge)
|
||
"SH|XX|SH",
|
||
"XX|SH|XX",
|
||
],
|
||
category: "machines",
|
||
tempHigh: 1455.5,
|
||
stateHigh: "molten_steel",
|
||
},
|
||
"led_r": {
|
||
behavior: behaviors.WALL,
|
||
color: "#660000",
|
||
colorOn: "#ff0000",
|
||
category: "machines",
|
||
tempHigh: 1500,
|
||
stateHigh: "molten_glass",
|
||
conduct: 1,
|
||
},
|
||
"led_g": {
|
||
behavior: behaviors.WALL,
|
||
color: "#006600",
|
||
colorOn: "#00ff00",
|
||
category: "machines",
|
||
tempHigh: 1500,
|
||
stateHigh: "molten_glass",
|
||
conduct: 1,
|
||
},
|
||
"led_b": {
|
||
behavior: behaviors.WALL,
|
||
color: "#000066",
|
||
colorOn: "#0000ff",
|
||
category: "machines",
|
||
tempHigh: 1500,
|
||
stateHigh: "molten_glass",
|
||
conduct: 1,
|
||
},
|
||
"sulfur": {
|
||
color: ["#E9D74C","#89761B","#DDC56B"],
|
||
behavior: behaviors.POWDER,
|
||
category: "powders",
|
||
tempHigh: 115.21,
|
||
burn: 25,
|
||
burnTime: 207,
|
||
fireColor: ["#8180CC","#7F84E6"],
|
||
state: "solid",
|
||
density: 2070,
|
||
},
|
||
"molten_sulfur": {
|
||
reactions: {
|
||
"molten_copper": { "elem1": null, "elem2": "molten_copper_sulfate" },
|
||
},
|
||
density: 1819,
|
||
burn: 25,
|
||
burnTime: 507,
|
||
fireColor: ["#8180CC","#7F84E6"],
|
||
},
|
||
"copper_sulfate": {
|
||
color: ["#4391FD","#004CFE"],
|
||
behavior: behaviors.POWDER,
|
||
tempHigh: 110,
|
||
burn: 10,
|
||
burnTime: 1007,
|
||
fireColor: ["#91D106","#FEFF97","#248E01"],
|
||
state: "solid",
|
||
density: 3600,
|
||
hidden: true,
|
||
category: "powders",
|
||
},
|
||
"diamond": {
|
||
color: ["#03fcec","#03c6fc","#b3eeff","#8ab0e6"],
|
||
behavior: behaviors.POWDER,
|
||
category: "powders",
|
||
tempHigh: 900,
|
||
stateHigh: "carbon_dioxide",
|
||
state: "solid",
|
||
density: 3515,
|
||
hardness: 1,
|
||
},
|
||
"glitter": {
|
||
color: ["#ACE4FB","#D9FCFF","#8F6EB2","#FDEAFC","#180E1C","#6B2778"],
|
||
behavior: behaviors.POWDER,
|
||
category: "powders",
|
||
tempHigh: 100,
|
||
stateHigh: ["fire","fire","dioxin"],
|
||
state: "solid",
|
||
density: 1450,
|
||
burn: 50,
|
||
burnTime: 50,
|
||
burnInto: ["smoke","smoke","dioxin"],
|
||
},
|
||
"electric": {
|
||
color: "#dddd00",
|
||
behavior: [
|
||
"CL%5|CL%5 AND SH|CL%5",
|
||
"CL%5 AND SH|SH%5 AND DL%50|CL%5 AND SH",
|
||
"M1%15 AND CL%6|M1%50 AND CL%13 AND SH|M1%15 AND CL%6",
|
||
],
|
||
charge: 3,
|
||
category: "energy",
|
||
state: "solid",
|
||
density: 2.1,
|
||
},
|
||
"snake": {
|
||
color: "#00bf00",
|
||
behavior: [
|
||
"XX|XX|XX",
|
||
"XX|LB:plant AND RT%5|M1 AND BO:1,2,3",
|
||
"XX|XX|XX",
|
||
],
|
||
rotatable: true,
|
||
category: "special",
|
||
excludeRandom: true,
|
||
},
|
||
"loopy": {
|
||
color: "#eb3474",
|
||
behavior: [
|
||
"XX|M2|M1",
|
||
"XX|RT%20|M2",
|
||
"CR:smoke|XX|XX",
|
||
],
|
||
rotatable: true,
|
||
category: "special",
|
||
},
|
||
"cyanide": {
|
||
color: "#b6ccb6",
|
||
behavior: behaviors.GAS,
|
||
reactions: {
|
||
"frog": { "elem2":"meat" },
|
||
"ant": { "elem2":null },
|
||
"bee": { "elem2":null },
|
||
"fish": { "elem2":"meat" },
|
||
"firefly": { "elem2":null },
|
||
},
|
||
tempHigh: 550,
|
||
stateHigh: "fire",
|
||
burn: 100,
|
||
burnTime: 1,
|
||
state: "gas",
|
||
density: 687,
|
||
category: "gases",
|
||
},
|
||
"radiation": {
|
||
color: ["#00ff00","#6fff00"],
|
||
behavior: [
|
||
"XX|M1%0.5 AND HT|XX",
|
||
"M1%7 AND HT|DL%3|M1%7 AND HT",
|
||
"XX|M1%1 AND HT|XX",
|
||
],
|
||
reactions: {
|
||
"water": { "elem2":"rad_steam", "chance":0.4 },
|
||
"steam": { "elem2":"rad_steam", "chance":0.4 },
|
||
"salt_water": { "elem2":"rad_steam", "chance":0.4 },
|
||
"sugar_water": { "elem2":"rad_steam", "chance":0.4 },
|
||
"dirty_water": { "elem2":"rad_steam", "chance":0.4 },
|
||
"bubble": { "elem2":"rad_steam", "chance":0.4 },
|
||
"foam": { "elem2":"rad_steam", "chance":0.4 },
|
||
"ice": { "elem2":"rad_steam", "chance":0.4 },
|
||
"snow": { "elem2":"rad_steam", "chance":0.4 },
|
||
"packed_snow": { "elem2":"rad_steam", "chance":0.4 },
|
||
"slime": { "elem2":"rad_steam", "chance":0.4 },
|
||
"milk": { "elem2":"cheese", "chance":0.4 },
|
||
"permafrost": { "elem1":"rad_steam", "elem2":"dirt", "chance":0.4 },
|
||
"mud": { "elem1":"rad_steam", "elem2":"dirt", "chance":0.4 },
|
||
"wet_sand": { "elem1":"rad_steam", "elem2":"sand", "chance":0.4 },
|
||
"clay": { "elem1":"rad_steam", "elem2":"clay_soil", "chance":0.4 },
|
||
"slaked_lime": { "elem1":"rad_steam", "elem2":"limestone", "chance":0.4 },
|
||
"rain_cloud": { "elem2":"rad_cloud", "chance":0.4 },
|
||
"snow_cloud": { "elem2":"rad_cloud", "chance":0.4 },
|
||
"plant": { "elem2":"dead_plant", "chance":0.4 },
|
||
"frozen_plant": { "elem2":"dead_plant", "chance":0.4 },
|
||
"grass": { "elem2":["dead_plant","straw","grass_seed","wheat_seed"], "chance":0.4 },
|
||
"algae": { "elem2":["mushroom_spore","lichen","yeast"], "chance":0.4 },
|
||
"mushroom_spore": { "elem2":["lichen","yeast"], "chance":0.4 },
|
||
"mushroom_cap": { "elem2":["lichen","plant"], "chance":0.4 },
|
||
"mushroom_stalk": { "elem2":["lichen","yeast"], "chance":0.4 },
|
||
"mushroom_gill": { "elem2":["lichen","yeast"], "chance":0.4 },
|
||
"flea": { "elem2":["ash","ant","termite"], "chance":0.4 },
|
||
"ant": { "elem2":["ash","flea","termite"], "chance":0.4 },
|
||
"termite": { "elem2":["ash","flea","ant"], "chance":0.4 },
|
||
"fly": { "elem2":["ash","firefly","bee"], "chance":0.4 },
|
||
"bee": { "elem2":["ash","firefly","fly"], "chance":0.4 },
|
||
"firefly": { "elem2":["ash","bee","fly"], "chance":0.4 },
|
||
"frog": { "elem2":["ash","meat","rotten_meat","cooked_meat"], "chance":0.4 },
|
||
"fish": { "elem2":["ash","meat","rotten_meat","cooked_meat"], "chance":0.4 },
|
||
"rat": { "elem2":["ash","meat","rotten_meat","cooked_meat","plague"], "chance":0.4 },
|
||
"bone": { "elem2":["calcium","calcium","calcium","cancer"], "chance":0.4 },
|
||
"meat": { "elem2":["ash","rotten_meat","cooked_meat"], "chance":0.4 },
|
||
"rotten_meat": { "elem2":["ash","meat","cooked_meat"], "chance":0.4 },
|
||
"cooked_meat": { "elem2":["ash","rotten_meat"], "chance":0.4 },
|
||
"bamboo": { "elem2":["wood","plant","bamboo_plant"], "chance":0.4 },
|
||
"bamboo_plant": { "elem2":["wood","plant","bamboo"], "chance":0.4 },
|
||
"sapling": { "elem2":["wood","plant","tree_branch"], "chance":0.4 },
|
||
"tree_branch": { "elem2":["wood","plant","sapling"], "chance":0.4 },
|
||
"grass_seed": { "elem2":["straw","wheat_seed"], "chance":0.4 },
|
||
"lichen": { "elem2":"algae", "chance":0.4 },
|
||
"yeast": { "elem2":["algae","mushroom_spore","lichen"], "chance":0.4 },
|
||
"wheat_seed": { "elem2":["straw","wheat","grass_seed"], "chance":0.4 },
|
||
"flower_seed": { "elem2":["straw","grass","pistil","petal"], "chance":0.4 },
|
||
"pistil": { "elem2":["straw","grass","flower_seed","petal"], "chance":0.4 },
|
||
"petal": { "elem2":["straw","grass","flower_seed","pistil"], "chance":0.4 },
|
||
"vine": { "elem1":["vine"], "chance":0.4 },
|
||
"worm": { "elem2":"ash", "chance":0.4 },
|
||
"corn": { "elem2":"corn_seed", "chance":0.4 },
|
||
"corn_seed": { "elem2":"corn", "chance":0.4 },
|
||
"potato": { "elem2":"potato_seed", "chance":0.4 },
|
||
"potato_seed": { "elem2":"potato", "chance":0.4 },
|
||
"slug": { "elem2":"slime", "chance":0.4 },
|
||
"snail": { "elem2":"slime", "chance":0.4 },
|
||
"cell": { "elem2":"cancer", "chance":0.4 },
|
||
"blood": { "elem2":["infection","cancer"], "chance":0.4 },
|
||
"antibody": { "elem2":"cancer", "chance":0.4 },
|
||
"infection": { "elem2":"cancer", "chance":0.4 },
|
||
"cancer": { "elem2":null, "chance":0.1 },
|
||
|
||
},
|
||
state: "gas",
|
||
density: 0.2,
|
||
category: "energy",
|
||
},
|
||
"rad_steam": {
|
||
color: "#abffe4",
|
||
behavior: [
|
||
"M1%10|M1%10|M1%10",
|
||
"M2%10|XX|M2%10",
|
||
"XX|M2%10|XX",
|
||
],
|
||
reactions: {
|
||
"rad_steam": { "elem1": null, "elem2": "rad_cloud", "chance":0.3, "y":[0,15] },
|
||
"steam": { "elem1": null, "elem2": "rad_cloud", "chance":0.3, "y":[0,15] },
|
||
"rain_cloud": { "elem1": "rad_cloud", "chance":0.4, "y":[0,15] },
|
||
"snow_cloud": { "elem1": "rad_cloud", "chance":0.4, "y":[0,15] },
|
||
"pyrocumulus": { "elem1": "rad_cloud", "chance":0.4, "y":[0,15] },
|
||
"rad_cloud": { "elem1": "rad_cloud", "chance":0.3, "y":[0,15] },
|
||
},
|
||
tempLow: 10,
|
||
stateLow: "fallout",
|
||
category: "gases",
|
||
hidden: true,
|
||
state: "gas",
|
||
density: 0.7,
|
||
},
|
||
"rad_cloud": {
|
||
color: ["#2d7528","#557528"],
|
||
behavior: [
|
||
"XX|XX|XX",
|
||
"M1%5|CH:fallout,radiation%0.025|M1%5",
|
||
"CR:radiation%0.05|CR:radiation%0.05|CR:radiation%0.05",
|
||
],
|
||
category:"gases",
|
||
hidden: true,
|
||
state: "gas",
|
||
density: 0.55,
|
||
},
|
||
"fallout": {
|
||
color: ["#63b85a","#448044","#598044","#7bb85a"],
|
||
behavior: [
|
||
"XX|CR:radiation%2|XX",
|
||
"CR:radiation%2|CH:radiation%0.5|CR:radiation%2",
|
||
"M2|M1 AND CR:radiation%2|M2",
|
||
],
|
||
category:"energy",
|
||
hidden: true,
|
||
state: "solid",
|
||
density: 1490,
|
||
},
|
||
"uranium": {
|
||
color: ["#599e61","#364d3c","#494D4A","#6c8a42","#798d65","#b5e089"],
|
||
behavior: behaviors.RADPOWDER,
|
||
tempHigh: 1132.2,
|
||
category: "powders",
|
||
state: "solid",
|
||
density: 19100,
|
||
},
|
||
"molten_uranium": {
|
||
behavior: behaviors.RADMOLTEN,
|
||
},
|
||
"glass_shard": {
|
||
color: ["#5e807d","#679e99","#596b6e"],
|
||
behavior: behaviors.POWDER,
|
||
tempHigh: 1500,
|
||
stateHigh: "molten_glass",
|
||
category: "powders",
|
||
state: "solid",
|
||
density: 2500,
|
||
},
|
||
"bead": {
|
||
color: ["#ff5e5e","#ffcc5e","#76ff5e","#5ed4ff","#5e61ff","#cf5eff"],
|
||
behavior: behaviors.POWDER,
|
||
category: "powders",
|
||
tempHigh: 185,
|
||
stateHigh: "molten_plastic",
|
||
burn: 10,
|
||
burnTime: 400,
|
||
burnInto: "dioxin",
|
||
state: "solid",
|
||
density: 1052,
|
||
},
|
||
"borax": {
|
||
color: "#ffffff",
|
||
behavior: behaviors.POWDER,
|
||
category: "powders",
|
||
burn: 15,
|
||
burnTime: 200,
|
||
fireColor: ["#34eb67","#5ceb34"],
|
||
tempHigh: 743,
|
||
state: "solid",
|
||
density: 1730,
|
||
},
|
||
"epsom_salt": {
|
||
color: ["#f2f2f2","#e0e0e0"],
|
||
behavior: behaviors.POWDER,
|
||
category: "powders",
|
||
burn: 40,
|
||
burnTime: 200,
|
||
fireColor: ["#ffffff","#fcf0f0"],
|
||
tempHigh: 1124,
|
||
state: "solid",
|
||
density: 1680,
|
||
},
|
||
"potassium_salt": {
|
||
color: ["#f2f2f2","#e0e0e0"],
|
||
behavior: behaviors.POWDER,
|
||
category: "powders",
|
||
burn: 40,
|
||
burnTime: 200,
|
||
fireColor: ["#ff00ee","#ff6bf5"],
|
||
tempHigh: 292,
|
||
state: "solid",
|
||
density: 3980,
|
||
},
|
||
"explosion": {
|
||
color: ["#ffb48f","#ffd991","#ffad91"],
|
||
behavior: [
|
||
"XX|XX|XX",
|
||
"XX|EX:10|XX",
|
||
"XX|XX|XX",
|
||
],
|
||
temp: 300,
|
||
category: "energy",
|
||
state: "gas",
|
||
density: 1000,
|
||
excludeRandom: true,
|
||
},
|
||
"tnt": {
|
||
color: "#c92a2a",
|
||
behavior: behaviors.WALL,
|
||
behaviorOn: [
|
||
"XX|XX|XX",
|
||
"XX|EX:10|XX",
|
||
"XX|XX|XX",
|
||
],
|
||
conduct: 1,
|
||
category: "weapons",
|
||
burn: 100,
|
||
burnTime: 1,
|
||
burnInto: "explosion",
|
||
tempHigh: 600,
|
||
stateHigh: "explosion",
|
||
state: "solid",
|
||
density: 1630,
|
||
excludeRandom: true,
|
||
},
|
||
"c4": {
|
||
name: "C-4",
|
||
color: ["#D7C1A1","#C8A77C"],
|
||
behavior: behaviors.STURDYPOWDER,
|
||
behaviorOn: [
|
||
"XX|XX|XX",
|
||
"XX|EX:10|XX",
|
||
"XX|M1|XX",
|
||
],
|
||
conduct: 1,
|
||
category: "weapons",
|
||
burn: 100,
|
||
burnTime: 1,
|
||
burnInto: "explosion",
|
||
tempHigh: 600,
|
||
stateHigh: "explosion",
|
||
state: "solid",
|
||
density: 1630,
|
||
excludeRandom: true,
|
||
},
|
||
"grenade": {
|
||
color: "#5e5c57",
|
||
behavior: [
|
||
"XX|EX:6>metal_scrap,fire,fire,fire%1|XX",
|
||
"XX|XX|XX",
|
||
"M2|M1 AND EX:6>metal_scrap,fire,fire,fire%1|M2",
|
||
],
|
||
category: "weapons",
|
||
state: "solid",
|
||
density: 1300,
|
||
tempHigh: 1455.5,
|
||
stateHigh: "molten_steel",
|
||
excludeRandom: true,
|
||
},
|
||
"dynamite": {
|
||
color: ["#de5050","#c92a2a","#a61919"],
|
||
behavior: [
|
||
"XX|EX:15%1|XX",
|
||
"XX|XX|XX",
|
||
"M2|M1 AND EX:15%1|M2",
|
||
],
|
||
category: "weapons",
|
||
state: "solid",
|
||
density: 1300,
|
||
tempHigh: 600,
|
||
stateHigh: "explosion",
|
||
breakInto: "explosion",
|
||
excludeRandom: true,
|
||
},
|
||
"gunpowder": {
|
||
color: ["#929980","#757767","#423D43"],
|
||
behavior: behaviors.POWDER,
|
||
category: "weapons",
|
||
burn: 100,
|
||
burnTime: 1,
|
||
burnInto: "explosion",
|
||
tempHigh: 600,
|
||
stateHigh: "explosion",
|
||
state: "solid",
|
||
density: 1700,
|
||
excludeRandom: true,
|
||
},
|
||
"ember": {
|
||
color: ["#ffe985","#ffd885","#ffc285"],
|
||
behavior: [
|
||
"XX|M1|M1",
|
||
"XX|XX|XX",
|
||
"XX|XX|XX",
|
||
],
|
||
flippableX: true,
|
||
category: "energy",
|
||
burn: 10,
|
||
burnTime: 10,
|
||
burnInto: "ash",
|
||
burning: true,
|
||
state: "gas",
|
||
density: 700,
|
||
hidden: true,
|
||
},
|
||
"firework": {
|
||
color: "#c44f45",
|
||
tick: function(pixel) {
|
||
if (pixel.burning) {
|
||
if (!tryMove(pixel, pixel.x, pixel.y-1)) {
|
||
// tryMove again to the top left or top right
|
||
tryMove(pixel, pixel.x+(Math.random() < 0.5 ? -1 : 1), pixel.y-1);
|
||
}
|
||
if (pixelTicks-pixel.burnStart > 50 && Math.random() < 0.1) {
|
||
explodeAt(pixel.x, pixel.y, 10, "fw_ember");
|
||
}
|
||
}
|
||
else {
|
||
if (!tryMove(pixel, pixel.x, pixel.y+1)) {
|
||
// tryMove again to the bottom left or bottom right
|
||
tryMove(pixel, pixel.x+(Math.random() < 0.5 ? -1 : 1), pixel.y+1);
|
||
}
|
||
}
|
||
},
|
||
burn: 90,
|
||
burnTime: 100,
|
||
density: 2000,
|
||
category: "weapons",
|
||
},
|
||
"fw_ember": {
|
||
color: ["#ff7a70","#ff9b70","#ffe270","#94ff70","#00ffff","#9b70ff","#ffa8d2"],
|
||
behavior: [
|
||
"XX|XX|XX",
|
||
"XX|DL%25|M2",
|
||
"XX|M2|M1",
|
||
],
|
||
name: "firework ember",
|
||
burning: true,
|
||
burnInto: "ash",
|
||
rotatable: true,
|
||
temp: 649,
|
||
category: "energy",
|
||
hidden: true,
|
||
},
|
||
"nuke": {
|
||
color: "#534636",
|
||
behavior: [
|
||
"XX|EX:60>plasma,plasma,plasma,plasma,radiation,rad_steam|XX",
|
||
"XX|XX|XX",
|
||
"M2|M1 AND EX:60>plasma,plasma,plasma,plasma,radiation,rad_steam|M2",
|
||
],
|
||
category: "weapons",
|
||
state: "solid",
|
||
density: 1500,
|
||
excludeRandom: true,
|
||
},
|
||
"dirty_bomb": {
|
||
color: "#415336",
|
||
behavior: [
|
||
"XX|EX:40>radiation,radiation,radiation,rad_steam|XX",
|
||
"XX|XX|XX",
|
||
"M2|M1 AND EX:40>radiation,radiation,radiation,rad_steam|M2",
|
||
],
|
||
category: "weapons",
|
||
state: "solid",
|
||
density: 1500,
|
||
excludeRandom: true,
|
||
},
|
||
"nitroglycerin": {
|
||
color: "#47c900",
|
||
behavior: behaviors.LIQUID,
|
||
behaviorOn: [
|
||
"XX|XX|XX",
|
||
"XX|EX:10|XX",
|
||
"XX|XX|XX",
|
||
],
|
||
conduct: 1,
|
||
category: "weapons",
|
||
tempHigh: 600,
|
||
stateHigh: "fire",
|
||
burn: 100,
|
||
burnTime: 1,
|
||
burnInto: "explosion",
|
||
viscosity: 36,
|
||
state: "liquid",
|
||
density: 1600,
|
||
excludeRandom: true,
|
||
},
|
||
"greek_fire": {
|
||
color: ["#4a3923","#594933","#78654a"],
|
||
behavior: behaviors.LIQUID,
|
||
category: "weapons",
|
||
tempHigh: 4000,
|
||
stateHigh: "fire",
|
||
burn: 100,
|
||
burnTime: 1500,
|
||
burnInto: "fire",
|
||
burning: true,
|
||
temp: 500,
|
||
insulate: true,
|
||
viscosity: 2,
|
||
state: "liquid",
|
||
density: 498.5,
|
||
excludeRandom: true,
|
||
},
|
||
"sticky_bomb": {
|
||
color: "#233096",
|
||
behavior: [
|
||
"XX|ST AND EX:10%2|XX",
|
||
"ST AND EX:10%2|XX|ST AND EX:10%2",
|
||
"XX|M1 AND ST AND EX:10%2|XX",
|
||
],
|
||
category: "weapons",
|
||
state: "solid",
|
||
density: 1300,
|
||
tempHigh: 1455.5,
|
||
stateHigh: ["molten_steel","slime"],
|
||
excludeRandom: true,
|
||
},
|
||
"cold_bomb": {
|
||
color: "#43646e",
|
||
behavior: [
|
||
"XX|EX:10>cold_fire|XX",
|
||
"XX|XX|XX",
|
||
"M2|M1 AND EX:10>cold_fire|M2",
|
||
],
|
||
category: "weapons",
|
||
state: "solid",
|
||
density: 1300,
|
||
tempHigh: 1455.5,
|
||
stateHigh: "molten_steel",
|
||
excludeRandom: true,
|
||
},
|
||
"hot_bomb": {
|
||
color: "#6c436e",
|
||
behavior: [
|
||
"XX|EX:10>plasma|XX",
|
||
"XX|XX|XX",
|
||
"M2|M1 AND EX:10>plasma|M2",
|
||
],
|
||
temp: 7065,
|
||
category: "weapons",
|
||
state: "solid",
|
||
density: 1300,
|
||
tempHigh: 10455.5,
|
||
stateHigh: "molten_steel",
|
||
excludeRandom: true,
|
||
},
|
||
"electro_bomb": {
|
||
color: "#6e6d43",
|
||
behavior: [
|
||
"XX|EX:10>electric|XX",
|
||
"XX|XX|XX",
|
||
"M2|M1 AND EX:10>electric|M2",
|
||
],
|
||
category: "weapons",
|
||
state: "solid",
|
||
density: 1300,
|
||
tempHigh: 1655.5,
|
||
stateHigh: "molten_steel",
|
||
excludeRandom: true,
|
||
},
|
||
"water_bomb": {
|
||
color: "#34599e",
|
||
behavior: [
|
||
"XX|EX:10>water|XX",
|
||
"XX|XX|XX",
|
||
"M2|M1 AND EX:10>water|M2",
|
||
],
|
||
category: "weapons",
|
||
state: "solid",
|
||
density: 1300,
|
||
tempHigh: 1455.5,
|
||
stateHigh: "molten_steel",
|
||
excludeRandom: true,
|
||
},
|
||
"antimatter_bomb": {
|
||
color: "#6e4343",
|
||
behavior: [
|
||
"XX|EX:20>antimatter|XX",
|
||
"XX|XX|XX",
|
||
"M2|M1 AND EX:20>antimatter|M2",
|
||
],
|
||
category: "weapons",
|
||
state: "solid",
|
||
density: 1300,
|
||
tempHigh: 10455.5,
|
||
stateHigh: "molten_steel",
|
||
excludeRandom: true,
|
||
},
|
||
"flashbang": {
|
||
color: "#65665c",
|
||
behavior: [
|
||
"XX|EX:20>flash%1|XX",
|
||
"XX|XX|XX",
|
||
"M2|M1 AND EX:20>flash%1|M2",
|
||
],
|
||
category: "weapons",
|
||
state: "solid",
|
||
density: 1300,
|
||
tempHigh: 1455.5,
|
||
stateHigh: "molten_steel",
|
||
excludeRandom: true,
|
||
},
|
||
"flash": {
|
||
color: "#ffffa8",
|
||
behavior: [
|
||
"XX|XX|XX",
|
||
"XX|DL%75|XX",
|
||
"XX|XX|XX",
|
||
],
|
||
category: "energy",
|
||
state: "gas",
|
||
density: 1,
|
||
tempLow: -270,
|
||
stateLow: "light",
|
||
hidden: true,
|
||
},
|
||
"smoke_grenade": {
|
||
color: "#65665c",
|
||
behavior: [
|
||
"XX|CR:smoke|XX",
|
||
"XX|EX:4>smoke%1|XX",
|
||
"M2|M1|M2",
|
||
],
|
||
category: "weapons",
|
||
state: "solid",
|
||
density: 7300,
|
||
conduct: 0.73,
|
||
tempHigh: 1455.5,
|
||
stateHigh: "molten_steel",
|
||
excludeRandom: true,
|
||
},
|
||
"fireball": {
|
||
color: ["#782828","#783b28","#784b28"],
|
||
behavior: [
|
||
"XX|CR:fire%25|XX",
|
||
"XX|CC:782828,783b28,784b28%25|XX",
|
||
"M2|M1 AND EX:8|M2",
|
||
],
|
||
reactions: {
|
||
"water": { "elem1":"rock", "elem2":"steam" }
|
||
},
|
||
category: "weapons",
|
||
temp:600,
|
||
tempHigh: 1900,
|
||
stateHigh: "magma",
|
||
tempLow: -100,
|
||
stateLow: "rock",
|
||
burning: true,
|
||
burnInto: ["rock","rock","steam"],
|
||
burnTime: 170,
|
||
burn: 100,
|
||
state: "solid",
|
||
density: 1600,
|
||
excludeRandom: true,
|
||
},
|
||
"landmine": {
|
||
color: "#856C7D",
|
||
behavior: [
|
||
"XX|EX:20|XX",
|
||
"XX|XX|XX",
|
||
"XX|M1|XX",
|
||
],
|
||
category: "weapons",
|
||
state: "solid",
|
||
density: 1300,
|
||
tempHigh: 1455.5,
|
||
stateHigh: "molten_steel",
|
||
excludeRandom: true,
|
||
},
|
||
"cluster_bomb": {
|
||
color: "#7d776d",
|
||
behavior: [
|
||
"XX|EX:10>smoke,smoke,smoke,smoke,smoke,grenade|XX",
|
||
"XX|XX|XX",
|
||
"M2|M1 AND EX:10>smoke,smoke,smoke,smoke,smoke,grenade|M2",
|
||
],
|
||
category: "weapons",
|
||
state: "solid",
|
||
density: 1300,
|
||
tempHigh: 1455.5,
|
||
stateHigh: "molten_steel",
|
||
excludeRandom: true,
|
||
},
|
||
"armageddon": {
|
||
color: "#a62900",
|
||
behavior: [
|
||
"XX|XX|XX",
|
||
"XX|EX:10>armageddon,fire,fire,fire,fire,fire,fire,fire,fire,fire,fire,fire,fire%25 AND DL%10|XX",
|
||
"M2|M1|M2",
|
||
],
|
||
category: "weapons",
|
||
state: "solid",
|
||
density: 1300,
|
||
hidden: true,
|
||
excludeRandom: true,
|
||
excludeRandom: true,
|
||
},
|
||
"tesla_coil": {
|
||
color: "#725C38",
|
||
behavior: behaviors.WALL,
|
||
behaviorOn: [
|
||
"XX|CR:plasma|XX",
|
||
"CR:plasma|XX|CR:plasma",
|
||
"XX|CR:plasma|XX",
|
||
],
|
||
category: "machines",
|
||
conduct: 1,
|
||
insulate: true,
|
||
temp: 7065,
|
||
},
|
||
"light_bulb": {
|
||
color: "#a8a897",
|
||
behavior: behaviors.WALL,
|
||
behaviorOn: [
|
||
"XX|CR:light|XX",
|
||
"CR:light|XX|CR:light",
|
||
"XX|CR:light|XX",
|
||
],
|
||
colorOn: "#ebebc3",
|
||
category: "machines",
|
||
tempHigh: 1500,
|
||
stateHigh: ["molten_glass","molten_glass","molten_copper"],
|
||
conduct: 1,
|
||
},
|
||
"shocker": {
|
||
color: "#78784c",
|
||
behavior: behaviors.WALL,
|
||
behaviorOn: [
|
||
"XX|CR:electric AND SH|XX",
|
||
"CR:electric AND SH|XX|CR:electric AND SH",
|
||
"XX|CR:electric AND SH|XX",
|
||
],
|
||
colorOn: "#ffff59",
|
||
category: "machines",
|
||
conduct: 1,
|
||
},
|
||
"pressure_plate": {
|
||
color: "#8a8a84",
|
||
tick: function(pixel) {
|
||
if (!isEmpty(pixel.x, pixel.y-1)){
|
||
if (pixelMap[pixel.x][pixel.y-1].element != "pressure_plate" || pixelMap[pixel.x][pixel.y-1].on) {
|
||
pixel.on = true;
|
||
var coordsToShock = [
|
||
[pixel.x, pixel.y+1],
|
||
[pixel.x+1, pixel.y],
|
||
[pixel.x-1, pixel.y],
|
||
]
|
||
for (var i = 0; i < coordsToShock.length; i++) {
|
||
var x = coordsToShock[i][0];
|
||
var y = coordsToShock[i][1];
|
||
if (!isEmpty(x,y,true)) {
|
||
var newpixel = pixelMap[x][y];
|
||
if (elements[newpixel.element].conduct) {
|
||
newpixel.charge = 1;
|
||
}
|
||
}
|
||
}
|
||
}
|
||
}
|
||
else if (pixel.on) {
|
||
pixel.on = false;
|
||
}
|
||
tryMove(pixel, pixel.x, pixel.y+1);
|
||
},
|
||
category: "machines",
|
||
},
|
||
"primordial_soup": {
|
||
color: ["#501F24","#6D2E1D"],
|
||
behavior: [
|
||
"XX|CR:foam%2|XX",
|
||
"M2|CH:algae,cell,mushroom_spore,lichen,yeast,antibody,cellulose%0.005|M2",
|
||
"M1|M1|M1",
|
||
],
|
||
reactions: {
|
||
"cancer": { "elem1":"dirty_water" },
|
||
"cyanide": { "elem1":"dirty_water" },
|
||
"infection": { "elem1":"dirty_water" },
|
||
"plague": { "elem1":"dirty_water" },
|
||
"ammonia": { "elem1":["algae","cell","mushroom_spore","lichen","yeast","antibody"], "chance":0.05 },
|
||
"radiation": { "elem1":["algae","cell","mushroom_spore","lichen","yeast","antibody"], "chance":0.15 },
|
||
"light": { "elem1":["algae","cell","mushroom_spore","lichen","yeast","antibody"], "chance":0.5 },
|
||
"oxygen": { "elem1":["algae","cell","mushroom_spore","lichen","yeast","antibody"], "chance":0.02 },
|
||
},
|
||
category: "life",
|
||
tempHigh: 100,
|
||
stateHigh: "steam",
|
||
conduct: 0.33,
|
||
state: "liquid",
|
||
density: 955,
|
||
},
|
||
|
||
|
||
};
|
||
|
||
function hexToRGB(hex) {
|
||
var result = /^#?([a-f\d]{2})([a-f\d]{2})([a-f\d]{2})$/i.exec(hex);
|
||
return result ? {
|
||
r: parseInt(result[1], 16),
|
||
g: parseInt(result[2], 16),
|
||
b: parseInt(result[3], 16)
|
||
} : null;
|
||
}
|
||
|
||
currentPixels = [];
|
||
//currentID = 0;
|
||
// Pixel class, with attributes such as x, y, and element
|
||
class Pixel {
|
||
constructor(x, y, element) {
|
||
this.x = x;
|
||
this.y = y;
|
||
this.element = element;
|
||
var elementInfo = elements[element];
|
||
this.color = pixelColorPick(this);
|
||
// If element doesn't have temp attribute, set temp to airTemp
|
||
if (elementInfo.temp==undefined) {
|
||
this.temp = airTemp;
|
||
} else {
|
||
this.temp = elementInfo.temp;
|
||
}
|
||
this.start = pixelTicks;
|
||
//this.id = currentID;
|
||
//currentID++;
|
||
if (elementInfo.burning) {
|
||
this.burning = true;
|
||
this.burnStart = pixelTicks;
|
||
}
|
||
else {
|
||
this.burning = false;
|
||
}
|
||
if (elementInfo.charge) {
|
||
this.charge = elementInfo.charge;
|
||
}
|
||
// If elementInfo.flippableX, set it to true or false randomly
|
||
if (elementInfo.flipX !== undefined) { this.flipX = elementInfo.flipX }
|
||
else if (elementInfo.flippableX) {
|
||
this.flipX = Math.random() >= 0.5;
|
||
}
|
||
// If elementInfo.flippableY, set it to true or false randomly
|
||
if (elementInfo.flipY !== undefined) { this.flipY = elementInfo.flipY }
|
||
else if (elementInfo.flippableY) {
|
||
this.flipY = Math.random() >= 0.5;
|
||
}
|
||
// If elementInfo.rotatable, set it to a number between 0 and 3
|
||
if (elementInfo.r !== undefined) { this.r = elementInfo.r }
|
||
else if (elementInfo.rotatable) {
|
||
this.r = Math.floor(Math.random() * 4);
|
||
}
|
||
// If elementInfo.properties, set each key to its value
|
||
if (elementInfo.properties !== undefined) {
|
||
for (var key in elementInfo.properties) {
|
||
// If it is an array or object, make a copy of it
|
||
if (typeof elementInfo.properties[key] == "object") {
|
||
this[key] = JSON.parse(JSON.stringify(elementInfo.properties[key]));
|
||
}
|
||
else {
|
||
this[key] = elementInfo.properties[key];
|
||
}
|
||
}
|
||
}
|
||
pixelMap[x][y] = this;
|
||
}
|
||
}
|
||
// If the screen size is under 768px, set pixelSize to 5, otherwise 6
|
||
if (window.innerWidth < 700) {
|
||
pixelSize = 5;
|
||
} else {
|
||
pixelSize = 6;
|
||
}
|
||
|
||
function outOfBounds(x,y) {
|
||
// Returns true if the pixel is out of bounds
|
||
return y > height-1 || y < 1 || x > width-1 || x < 1
|
||
}
|
||
function isEmpty(x, y, ignoreBounds=false) {
|
||
if (outOfBounds(x,y)) {
|
||
return ignoreBounds;
|
||
}
|
||
return pixelMap[x][y] == undefined;
|
||
}
|
||
function canMove(pixel,x,y) {
|
||
if (isEmpty(x,y)) {
|
||
return true;
|
||
}
|
||
}
|
||
function movePixel(pixel,x,y,leaveBehind=null) {
|
||
// Delete the pixel from the old position
|
||
delete pixelMap[pixel.x][pixel.y];
|
||
if (leaveBehind != null && isEmpty(pixel.x,pixel.y)) { createPixel(leaveBehind,pixel.x,pixel.y); }
|
||
pixel.x = x;
|
||
pixel.y = y;
|
||
pixelMap[x][y] = pixel;
|
||
}
|
||
function clonePixel(pixel,x,y) {
|
||
currentPixels.push(new Pixel(x, y, pixel.element));
|
||
}
|
||
function createPixel(element,x,y) {
|
||
currentPixels.push(new Pixel(x, y, element));
|
||
}
|
||
function deletePixel(x,y) {
|
||
// remove pixelMap[x][y] from currentPixels
|
||
currentPixels.splice(currentPixels.indexOf(pixelMap[x][y]),1);
|
||
if (pixelMap[x][y]) {pixelMap[x][y].del = true;}
|
||
delete pixelMap[x][y];
|
||
/*for (var i = 0; i < currentPixels.length; i++) {
|
||
if (currentPixels[i].x == x && currentPixels[i].y == y) {
|
||
currentPixels.splice(i, 1);
|
||
break;
|
||
}
|
||
}*/
|
||
/*if (id != null) {
|
||
for (var i = 0; i < currentPixels.length; i++) {
|
||
if (currentPixels[i].id == id) {
|
||
currentPixels.splice(i, 1);
|
||
return;
|
||
}
|
||
}
|
||
}*/
|
||
}
|
||
function swapPixels(pixel1,pixel2) {
|
||
var tempX = pixel1.x;
|
||
var tempY = pixel1.y;
|
||
pixel1.x = pixel2.x;
|
||
pixel1.y = pixel2.y;
|
||
pixel2.x = tempX;
|
||
pixel2.y = tempY;
|
||
pixelMap[pixel1.x][pixel1.y] = pixel1;
|
||
pixelMap[pixel2.x][pixel2.y] = pixel2;
|
||
}
|
||
|
||
function reactPixels(pixel1,pixel2) {
|
||
var r = elements[pixel1.element].reactions[pixel2.element];
|
||
if (r.chance !== undefined && Math.random() > r.chance) {
|
||
return false;
|
||
}
|
||
// r has the attribute "y" which is a range between two y values
|
||
// r.y example: [10,30]
|
||
// return false if y is defined and pixel1's y is not in the range
|
||
if (r.y !== undefined && (pixel1.y < r.y[0] || pixel1.y > r.y[1])) {
|
||
return false;
|
||
}
|
||
if (r.elem1 !== undefined) {
|
||
// if r.elem1 is an array, set elem1 to a random element from the array, otherwise set it to r.elem1
|
||
if (Array.isArray(r.elem1)) {
|
||
var elem1 = r.elem1[Math.floor(Math.random() * r.elem1.length)];
|
||
} else { var elem1 = r.elem1; }
|
||
|
||
if (elem1 == null) {
|
||
deletePixel(pixel1.x,pixel1.y);
|
||
}
|
||
else {
|
||
pixel1.element = elem1;
|
||
pixel1.color = pixelColorPick(pixel1);
|
||
pixel1.start = pixelTicks;
|
||
if (elements[elem1].burning == true) {
|
||
pixel1.burning = true;
|
||
pixel1.burnStart = pixelTicks;
|
||
}
|
||
else if (pixel1.burning && !elements[elem1].burn) {
|
||
pixel1.burning = false;
|
||
delete pixel.burnStart;
|
||
}
|
||
}
|
||
}
|
||
if (r.elem2 !== undefined) {
|
||
// if r.elem2 is an array, set elem2 to a random element from the array, otherwise set it to r.elem2
|
||
if (Array.isArray(r.elem2)) {
|
||
var elem2 = r.elem2[Math.floor(Math.random() * r.elem2.length)];
|
||
} else { var elem2 = r.elem2; }
|
||
|
||
if (elem2 == null) {
|
||
deletePixel(pixel2.x,pixel2.y);
|
||
}
|
||
else {
|
||
pixel2.element = elem2;
|
||
pixel2.color = pixelColorPick(pixel2);
|
||
pixel2.start = pixelTicks;
|
||
if (elements[elem2].burning == true) {
|
||
pixel2.burning = true;
|
||
pixel2.burnStart = pixelTicks;
|
||
}
|
||
else if (pixel2.burning && !elements[elem2].burn) {
|
||
pixel2.burning = false;
|
||
delete pixel.burnStart;
|
||
}
|
||
}
|
||
}
|
||
return true;
|
||
}
|
||
|
||
|
||
validDensitySwaps = ["solid>liquid","liquid>gas","liquid>liquid","gas>gas","solid>gas"];
|
||
function tryMove(pixel,nx,ny,leaveBehind=undefined) {
|
||
var info = elements[pixel.element];
|
||
if (isEmpty(nx,ny)) { // If coords is empty, move to coords
|
||
movePixel(pixel,nx,ny,leaveBehind);
|
||
return true;
|
||
}
|
||
else {
|
||
if (!outOfBounds(nx,ny)) {
|
||
// Reactions
|
||
newPixel = pixelMap[nx][ny];
|
||
if (info.reactions != undefined && info.reactions[newPixel.element] != undefined) {
|
||
if (reactPixels(pixel,newPixel)) {
|
||
return true;
|
||
}
|
||
}
|
||
else if (elements[newPixel.element].reactions != undefined && elements[newPixel.element].reactions[pixel.element] != undefined && !elements[newPixel.element].reactions[pixel.element].oneway) {
|
||
if (reactPixels(newPixel,pixel)) {
|
||
return true;
|
||
}
|
||
}
|
||
// Density
|
||
if (pixel.element != newPixel.element) {
|
||
if (elements[newPixel.element].density != undefined && info.density != undefined) {
|
||
// if the pixel's state + ">" + newPixel's state is in validDensitySwaps, and the pixel's density is larger than the newPixel's density, swap the pixels
|
||
if (validDensitySwaps.includes(info.state+">"+elements[newPixel.element].state) && info.density >= elements[newPixel.element].density) {
|
||
// chance depending on the difference in density
|
||
if (Math.random() < (info.density - elements[newPixel.element].density)/(info.density + elements[newPixel.element].density)) {
|
||
swapPixels(pixel,newPixel);
|
||
return true;
|
||
}
|
||
}
|
||
}
|
||
}
|
||
|
||
}
|
||
|
||
}
|
||
return false;
|
||
}
|
||
function behaviorCoords(x,y,bx,by) {
|
||
return {x:x+bx-1,y:y+by-1};
|
||
}
|
||
function relativeCoords(x,y,bx,by) {
|
||
return {x:bx-1,y:by-1};
|
||
}
|
||
/* Behavior Example (Sand)
|
||
[
|
||
["XX","XX","XX"],
|
||
["XX","XX","XX"],
|
||
["M2","M1","M2"]
|
||
] */
|
||
behaviorCache = {};
|
||
function rotateBehavior(behavior,rotation) {
|
||
// returns rotated 2D array counter-clockwise depending on rotation 1, 2, or 3
|
||
// if the rotation is under 0, subtract it from 3
|
||
if (rotation < 0) {
|
||
rotation = 4 + rotation;
|
||
}
|
||
var check = behaviorCache[behavior.toString()+rotation];
|
||
if (check != undefined) { return check; }
|
||
|
||
var newBehavior = []
|
||
if (rotation == 1) {
|
||
// rotate counter-clockwise 90 degrees
|
||
for (var i = 0; i < behavior.length; i++) {
|
||
newBehavior[i] = [];
|
||
for (var j = 0; j < behavior[i].length; j++) {
|
||
newBehavior[i][j] = behavior[j][behavior.length-1-i];
|
||
}}
|
||
}
|
||
else if (rotation == 2) {
|
||
// rotate counter-clockwise 180 degrees
|
||
for (var i = 0; i < behavior.length; i++) {
|
||
newBehavior[i] = [];
|
||
for (var j = 0; j < behavior[i].length; j++) {
|
||
newBehavior[i][j] = behavior[behavior.length-1-i][behavior[i].length-1-j];
|
||
}}
|
||
}
|
||
else if (rotation == 3) {
|
||
// rotate counter-clockwise 270 degrees
|
||
for (var i = 0; i < behavior.length; i++) {
|
||
newBehavior[i] = [];
|
||
for (var j = 0; j < behavior[i].length; j++) {
|
||
newBehavior[i][j] = behavior[behavior[i].length-1-j][i];}
|
||
}
|
||
}
|
||
else {
|
||
// no rotation
|
||
return behavior;
|
||
}
|
||
|
||
behaviorCache[behavior.toString()+rotation] = newBehavior;
|
||
return newBehavior;
|
||
}
|
||
function flipBehavior(behavior,axis) {
|
||
// returns flipped 2D array depending on axis "x" or "y"
|
||
var check = behaviorCache[behavior.toString()+axis];
|
||
if (check != undefined) { return check; }
|
||
|
||
if (axis === "x") {
|
||
var newBehavior = [];
|
||
for (var i = 0; i < behavior.length; i++) {
|
||
newBehavior[i] = [];
|
||
for (var j = 0; j < behavior[i].length; j++) {
|
||
newBehavior[i][j] = behavior[i][behavior[i].length-1-j];
|
||
}}
|
||
behaviorCache[behavior.toString()+axis] = newBehavior;
|
||
return newBehavior;
|
||
}
|
||
else { // axis === y
|
||
newBehavior = behavior.slice().reverse();
|
||
behaviorCache[behavior.toString()+axis] = newBehavior;
|
||
return newBehavior;
|
||
}
|
||
|
||
return behavior;
|
||
}
|
||
|
||
/* Behavior Rules
|
||
XX = Ignore
|
||
M1 = Move (First Priority)
|
||
M2 = Move (Second Priority)
|
||
SP = Support (Doesn't move if all aren't empty)
|
||
SA = Support Any (Doesn't move if any aren't empty)
|
||
DL = Delete
|
||
DB = Delete Both (Self and target)
|
||
CL = Clone
|
||
CF = Clone first touched
|
||
CH = Change
|
||
C2 = Change Self after M2
|
||
CR:element_name = Create a pixel of element_name
|
||
LB:element_name = Leave behind a pixel of element_name when moved (Must be center cell)
|
||
L1:element_name = Leave behind only on M1 moves
|
||
L2:element_name = Leave behind only on M2 moves
|
||
SW = Swap
|
||
HT = Heat
|
||
CO = Cool
|
||
CC = Change Color (Hexadecimal)
|
||
ST = Stick
|
||
SH = Shock with electricity
|
||
FX = Flip X
|
||
FY = Flip Y
|
||
RT = Rotate
|
||
BO = Bounce off of
|
||
EX:radius>fire substitute = Explode on touch
|
||
%number = Chance of rule happening
|
||
*/
|
||
function pixelTick(pixel,custom=null) {
|
||
if (pixel.start === pixelTicks) {return}
|
||
var info = elements[pixel.element];
|
||
if (custom) { var behavior = custom; }
|
||
else if (pixel.charge && info.behaviorOn) { var behavior = info.behaviorOn; }
|
||
else { var behavior = info.behavior; }
|
||
if (pixel.flipX) { behavior = flipBehavior(behavior,"x"); }
|
||
if (pixel.flipY) { behavior = flipBehavior(behavior,"y"); }
|
||
if (pixel.r) { behavior = rotateBehavior(behavior,pixel.r); }
|
||
var x = pixel.x;
|
||
var y = pixel.y;
|
||
var move1Spots = [];
|
||
var move2Spots = [];
|
||
var supportSpots = [];
|
||
var swapSpots = [];
|
||
var leaveBehind = null;
|
||
var leaveBehind1 = null;
|
||
var leaveBehind2 = null;
|
||
var move = true;
|
||
// Parse behavior
|
||
for (var by = 0; by < behavior.length; by++) {
|
||
var behaviorby = behavior[by];
|
||
for (var bx = 0; bx < behaviorby.length; bx++) {
|
||
var b0 = behaviorby[bx];
|
||
if (b0 === "XX") {continue}
|
||
//if (b.includes(" OR ")) {
|
||
// b = b.split(" OR ")[Math.floor(Math.random()*b.split(" OR ").length)];
|
||
//}
|
||
// Loop through b0.split(" AND ")
|
||
if (b0.includes(" AND ")) { var andsplit = b0.split(" AND "); }
|
||
else { var andsplit = [b0]; }
|
||
for (var i = 0; i < andsplit.length; i++) {
|
||
var b = andsplit[i];
|
||
if (b.includes(":")) {
|
||
var arg = b.split(":")[1].split(/[\:\%]/)[0];
|
||
if (!b.includes("%")) {
|
||
b = b.split(/[\:\%]/)[0];
|
||
}
|
||
}
|
||
else { var arg = null;}
|
||
// If b has "%" followed by a number in it, it's a chance to move
|
||
if (b.includes("%")) {
|
||
// Split the string at the "%" and use the second half as the chance (float)
|
||
var chance = parseFloat(b.split("%")[1]);
|
||
//console.log(b+": "+(Math.random()*100 < chance));
|
||
b = b.split(/[\:\%]/)[0];
|
||
}
|
||
else { var chance = 100; }
|
||
if (chance==100 || Math.random()*100 < chance) {
|
||
var newCoords = behaviorCoords(x,y,bx,by);
|
||
if (b == "M1") {
|
||
if (info.viscosity != undefined) {
|
||
if (!((Math.random()*100) < 100 / ((info.viscosity) ** 0.25))) {
|
||
newCoords.x = x;
|
||
}
|
||
}
|
||
move1Spots.push(newCoords);
|
||
}
|
||
else if (b == "M2") {
|
||
if (info.viscosity != undefined) {
|
||
if (!((Math.random()*100) < 100 / ((info.viscosity) ** 0.25))) {
|
||
newCoords.x = x;
|
||
}
|
||
}
|
||
move2Spots.push(newCoords);
|
||
}
|
||
else if (b == "SP") {
|
||
supportSpots.push({x:newCoords.x,y:newCoords.y,arg:arg});
|
||
}
|
||
else if (b == "SA") {
|
||
if (!isEmpty(newCoords.x,newCoords.y,true)) {
|
||
move = false;
|
||
}
|
||
}
|
||
else if (b == "DL") {
|
||
if (!isEmpty(newCoords.x,newCoords.y,true)) {
|
||
// if the pixel at newCoords is the same element as the pixel, ignore
|
||
newPixel = pixelMap[newCoords.x][newCoords.y];
|
||
// if info.ignore exists and newPixel.element is in it
|
||
if (info.ignore && info.ignore.includes(newPixel.element)) {
|
||
continue;
|
||
}
|
||
if ((!(newPixel.element == pixel.element)) || (newCoords.x == x && newCoords.y == y)) {
|
||
if (arg != null) { var args = arg.split(","); }
|
||
if (arg == null || args.includes(newPixel.element)) {
|
||
if (!elements[newPixel.element].hardness || Math.random() > elements[newPixel.element].hardness) {
|
||
deletePixel(newCoords.x,newCoords.y);
|
||
if (newCoords.x == x && newCoords.y == y) {
|
||
var deleted = true;
|
||
}
|
||
swapSpots = [];
|
||
}
|
||
}
|
||
}
|
||
}
|
||
}
|
||
else if (b == "DB") { // Delete Both
|
||
if (!isEmpty(newCoords.x,newCoords.y,true)) {
|
||
// if the pixel at newCoords is the same element as the pixel, ignore
|
||
newPixel = pixelMap[newCoords.x][newCoords.y];
|
||
// if info.ignore exists and newPixel.element is in it
|
||
if (info.ignore && info.ignore.includes(newPixel.element)) {
|
||
continue;
|
||
}
|
||
if (!(newPixel.element == pixel.element)) {
|
||
if (arg != null) { var args = arg.split(","); }
|
||
if (arg == null || args.includes(newPixel.element)) {
|
||
if (!elements[newPixel.element].hardness || Math.random() > elements[newPixel.element].hardness) {
|
||
deletePixel(newCoords.x,newCoords.y);
|
||
if (pixelMap[pixel.x][pixel.y] != undefined) {
|
||
deletePixel(pixel.x,pixel.y);
|
||
}
|
||
var deleted = true;
|
||
swapSpots = [];
|
||
}
|
||
}
|
||
}
|
||
}
|
||
}
|
||
//Change pixel
|
||
else if (b == "CH") {
|
||
if (!isEmpty(newCoords.x,newCoords.y,true)) {
|
||
var newPixel = pixelMap[newCoords.x][newCoords.y];
|
||
if (info.ignore && info.ignore.includes(newPixel.element)) {
|
||
continue;
|
||
}
|
||
if (!elements[newPixel.element].hardness || Math.random() > elements[newPixel.element].hardness) {
|
||
if (arg.includes(">")) {
|
||
var argfrom = arg.split(">")[0];
|
||
var argto = arg.split(">")[1];
|
||
}
|
||
else {
|
||
var argfrom = null;
|
||
var argto = arg;
|
||
}
|
||
if (argto.includes(",")) {
|
||
var argto = argto.split(",")[Math.floor(Math.random()*argto.split(",").length)];
|
||
}
|
||
if (elements[argto]) {
|
||
if ((newPixel.element != argto) && (argfrom == null || argfrom == newPixel.element)) {
|
||
newPixel.element = argto;
|
||
newPixel.color = pixelColorPick(newPixel);
|
||
newPixel.start = pixelTicks;
|
||
if (elements[argto].burning != true) {
|
||
newPixel.burning = false;
|
||
}
|
||
else {
|
||
newPixel.burning = true;
|
||
newPixel.burnStart = pixelTicks;
|
||
}
|
||
if (newPixel.r && !elements[argto].rotatable) {
|
||
newPixel.r = false;
|
||
}
|
||
if (newPixel.flipX && !elements[argto].flippableX) {
|
||
newPixel.flipX = false;
|
||
}
|
||
if (newPixel.flipY && !elements[argto].flippableY) {
|
||
newPixel.flipY = false;
|
||
}
|
||
}
|
||
}
|
||
}
|
||
}
|
||
}
|
||
//Swap
|
||
else if (b == "SW") {
|
||
if (!isEmpty(newCoords.x,newCoords.y,true)) {
|
||
var newPixel = pixelMap[newCoords.x][newCoords.y];
|
||
if (arg != null) { var args = arg.split(","); }
|
||
if (arg == null || args.includes(newPixel.element)) {
|
||
if (!elements[newPixel.element].hardness || Math.random() > elements[newPixel.element].hardness) {
|
||
swapSpots.push({x:newCoords.x,y:newCoords.y});
|
||
}
|
||
}
|
||
}
|
||
}
|
||
//Create pixel
|
||
else if (b == "CR") {
|
||
if (isEmpty(newCoords.x,newCoords.y)) {
|
||
if (arg == null) {
|
||
arg = pixel.element;
|
||
}
|
||
else if (arg.includes(",")) {
|
||
arg = arg.split(",")[Math.floor(Math.random()*arg.split(",").length)];
|
||
}
|
||
if (elements[arg]) {
|
||
createPixel(arg,newCoords.x,newCoords.y);
|
||
pixelMap[newCoords.x][newCoords.y].temp = pixel.temp
|
||
}
|
||
}
|
||
}
|
||
// Clone self
|
||
else if (b == "CL") {
|
||
if (isEmpty(newCoords.x,newCoords.y)) {
|
||
if (arg == null || pixel.temp >= parseFloat(arg)) {
|
||
clonePixel(pixel,newCoords.x,newCoords.y);
|
||
}
|
||
}
|
||
}
|
||
// Clone first touched
|
||
else if (b == "CF") {
|
||
if (pixel.clone) {
|
||
if (isEmpty(newCoords.x,newCoords.y)) {
|
||
createPixel(pixel.clone,newCoords.x,newCoords.y);
|
||
pixelMap[newCoords.x][newCoords.y].temp = pixel.temp;
|
||
}
|
||
}
|
||
else {
|
||
if (!isEmpty(newCoords.x,newCoords.y,true)) {
|
||
newPixel = pixelMap[newCoords.x][newCoords.y];
|
||
if (info.ignore && info.ignore.includes(newPixel.element)) {
|
||
continue;
|
||
}
|
||
if (newPixel.element != pixel.element && newPixel.element != "wire") {
|
||
pixel.clone = newPixel.element;
|
||
pixel.temp = newPixel.temp;
|
||
}
|
||
else if (newPixel.clone) {
|
||
pixel.clone = newPixel.clone;
|
||
pixel.temp = newPixel.temp;
|
||
}
|
||
}
|
||
}
|
||
}
|
||
else if (b=="SH") {
|
||
if (!isEmpty(newCoords.x,newCoords.y,true)) {
|
||
var newPixel = pixelMap[newCoords.x][newCoords.y];
|
||
var con = elements[newPixel.element].conduct;
|
||
if (con != undefined) {
|
||
if (Math.random() < con) { // If random number is less than conductivity
|
||
if (!newPixel.charge && !newPixel.chargeCD) {
|
||
newPixel.charge = (parseFloat(arg) || 1);
|
||
if (elements[newPixel.element].colorOn) {
|
||
newPixel.color = pixelColorPick(newPixel);
|
||
}
|
||
}
|
||
}
|
||
}
|
||
}
|
||
}
|
||
//Stick
|
||
else if (b=="ST") {
|
||
if (!isEmpty(newCoords.x,newCoords.y,true)) {
|
||
var newPixel = pixelMap[newCoords.x][newCoords.y];
|
||
if (newPixel.element != pixel.element && (arg == null || newPixel.element == arg)) {
|
||
var sticking = true
|
||
}
|
||
}
|
||
}
|
||
//Leave behind element
|
||
else if (b == "LB" || b == "L1" || b == "L2") {
|
||
if (arg != null && arg.includes(",")) {
|
||
arg = arg.split(",")[Math.floor(Math.random()*arg.split(",").length)];
|
||
}
|
||
if (elements[arg]) {
|
||
if (b=="LB") {leaveBehind = arg;}
|
||
else if (b=="L1") {leaveBehind1 = arg;}
|
||
else if (b=="L2") {leaveBehind2 = arg;}
|
||
}
|
||
}
|
||
//Change color
|
||
else if (b == "CC") {
|
||
if (!isEmpty(newCoords.x,newCoords.y,true)) {
|
||
var newPixel = pixelMap[newCoords.x][newCoords.y];
|
||
if (arg == null) {arg = newPixel.colorObject}
|
||
else {
|
||
if (arg.includes(",")) {
|
||
arg = arg.split(",")[Math.floor(Math.random()*arg.split(",").length)];
|
||
}
|
||
if (!arg.startsWith("#")) {
|
||
arg = "#" + arg;
|
||
}
|
||
}
|
||
newPixel.color = pixelColorPick(newPixel,arg);
|
||
}
|
||
}
|
||
//Heat
|
||
else if (b == "HT") {
|
||
if (!isEmpty(newCoords.x,newCoords.y,true)) {
|
||
var newPixel = pixelMap[newCoords.x][newCoords.y];
|
||
// if the element isn't the same or the coords ARE the same
|
||
if (!(newPixel.element == pixel.element) || (newCoords.x == pixel.x && newCoords.y == pixel.y)) {
|
||
if (arg != null) {arg = parseFloat(arg)}
|
||
else {arg = 1}
|
||
if (isNaN(arg)) {arg = 1}
|
||
newPixel.temp += arg;
|
||
pixelTempCheck(newPixel);
|
||
}
|
||
}
|
||
}
|
||
//Cool
|
||
else if (b == "CO") {
|
||
if (!isEmpty(newCoords.x,newCoords.y,true)) {
|
||
var newPixel = pixelMap[newCoords.x][newCoords.y];
|
||
if (!(newPixel.element == pixel.element) || (newCoords.x == pixel.x && newCoords.y == pixel.y)) {
|
||
if (arg != null) {arg = parseFloat(arg)}
|
||
else {arg = 1}
|
||
if (isNaN(arg)) {arg = 1}
|
||
newPixel.temp -= arg;
|
||
pixelTempCheck(newPixel);
|
||
}
|
||
}
|
||
}
|
||
|
||
// Flip X
|
||
else if (b == "FX") {
|
||
if (!isEmpty(newCoords.x,newCoords.y,true)) {
|
||
var newPixel = pixelMap[newCoords.x][newCoords.y];
|
||
if (elements[newPixel.element].flippableX) {
|
||
if (arg === "0") { newPixel.flipX = false; }
|
||
else if (arg === "1") { newPixel.flipX = true; }
|
||
newPixel.flipX = !newPixel.flipX;
|
||
}
|
||
}
|
||
}
|
||
// Flip Y
|
||
else if (b == "FY") {
|
||
if (!isEmpty(newCoords.x,newCoords.y,true)) {
|
||
var newPixel = pixelMap[newCoords.x][newCoords.y];
|
||
if (elements[newPixel.element].flippableY) {
|
||
if (arg === "0") { newPixel.flipY = false; }
|
||
else if (arg === "1") { newPixel.flipY = true; }
|
||
else { newPixel.flipY = !newPixel.flipY; }
|
||
}
|
||
}
|
||
}
|
||
// Rotate
|
||
else if (b == "RT") {
|
||
if (!isEmpty(newCoords.x,newCoords.y,true)) {
|
||
var newPixel = pixelMap[newCoords.x][newCoords.y];
|
||
// If arg isn't null, set arg to a random choice from arg.split(",")
|
||
if (arg != null && arg.includes(",")) {
|
||
arg = arg.split(",")[Math.floor(Math.random()*arg.split(",").length)];
|
||
}
|
||
if (elements[newPixel.element].rotatable) {
|
||
newPixel.r = ((newPixel.r||0) + (parseInt(arg)||1)) % 4;
|
||
}
|
||
}
|
||
}
|
||
// Bounce
|
||
else if (b == "BO") {
|
||
if (!isEmpty(newCoords.x,newCoords.y)) {
|
||
if (info.flippableX) {
|
||
pixel.flipX = !pixel.flipX;
|
||
}
|
||
if (info.flippableY) {
|
||
pixel.flipY = !pixel.flipY;
|
||
}
|
||
if (info.rotatable) {
|
||
// If arg isn't null, set arg to a random choice from arg.split(",")
|
||
if (arg != null && arg.includes(",")) {
|
||
arg = arg.split(",")[Math.floor(Math.random()*arg.split(",").length)];
|
||
}
|
||
if (pixel.r !== undefined) {
|
||
pixel.r = (pixel.r + (parseInt(arg)||2)) % 4;
|
||
}
|
||
else { pixel.r = (parseInt(arg)||2); }
|
||
}
|
||
}
|
||
}
|
||
// Change When M2
|
||
else if (b == "C2") {
|
||
if (arg.includes(",")) {
|
||
arg = arg.split(",")[Math.floor(Math.random()*arg.split(",").length)];
|
||
}
|
||
var C2 = arg;
|
||
}
|
||
// Explode
|
||
else if (b == "EX") {
|
||
if (!isEmpty(newCoords.x,newCoords.y)) {
|
||
if (outOfBounds(newCoords.x,newCoords.y) || (newCoords.x == x && newCoords.y == y) || (pixel.element !== pixelMap[newCoords.x][newCoords.y].element && elements[pixelMap[newCoords.x][newCoords.y].element].state !== "gas")) {
|
||
// if arg contains ">", var fire = everything after it, arg = everything before it
|
||
if (arg.includes(">")) {
|
||
var fire = arg.split(">")[1];
|
||
arg = arg.split(">")[0];
|
||
}
|
||
else { var fire = "fire" }
|
||
// arg = a number
|
||
if (arg != null) {
|
||
arg = parseInt(arg);
|
||
if (isNaN(arg)) {arg = 3}
|
||
}
|
||
else {arg = 3}
|
||
explodeAt(x,y,arg,fire);
|
||
if (!pixel.del && info.hardness !== 1) {
|
||
deletePixel(x,y);
|
||
var deleted = true;
|
||
}
|
||
swapSpots = [];
|
||
}
|
||
}
|
||
}
|
||
|
||
|
||
}
|
||
}
|
||
}
|
||
}
|
||
if (typeof deleted !== "undefined") {return;}
|
||
if (supportSpots.length > 0) {
|
||
var supportCount = 0;
|
||
var allEmpty = true;
|
||
for (var i = 0; i < supportSpots.length; i++) {
|
||
var bx = supportSpots[i].x;
|
||
var by = supportSpots[i].y;
|
||
var arg = supportSpots[i].arg;
|
||
if (!isEmpty(bx,by,true)) {
|
||
if ((arg == null && !validDensitySwaps.includes(info.state+">"+elements[pixelMap[bx][by].element].state)) || pixelMap[bx][by].element == arg) {
|
||
supportCount++;
|
||
}
|
||
}
|
||
}
|
||
if (supportCount == supportSpots.length) {
|
||
move = false;
|
||
}
|
||
}
|
||
|
||
var moved = false;
|
||
|
||
if (swapSpots.length > 0) {
|
||
var coords = swapSpots[Math.floor(Math.random()*swapSpots.length)];
|
||
if (pixelMap[coords.x][coords.y] != undefined) {
|
||
swapPixels(pixel,pixelMap[coords.x][coords.y]);
|
||
move = false;
|
||
moved = true;
|
||
}
|
||
}
|
||
|
||
if (typeof sticking !== "undefined") {
|
||
move = false;
|
||
}
|
||
|
||
// Move First Priority
|
||
if (move) {
|
||
if (move1Spots.length > 0) {
|
||
// While move1Spots is not empty
|
||
while (move1Spots.length > 0) {
|
||
// coords = random item of move1Spots
|
||
var coords = move1Spots[Math.floor(Math.random()*move1Spots.length)];
|
||
var nx = coords.x;
|
||
var ny = coords.y;
|
||
moved = tryMove(pixel,nx,ny,leaveBehind1 || leaveBehind);
|
||
if (moved) {
|
||
break;
|
||
}
|
||
else {
|
||
// remove coords from move1Spots
|
||
move1Spots.splice(move1Spots.indexOf(coords),1);
|
||
}
|
||
|
||
|
||
}
|
||
}
|
||
// Move Second Priority
|
||
if (!moved && move2Spots.length > 0) {
|
||
// While move2Spots is not empty
|
||
while (move2Spots.length > 0) {
|
||
// coords = random item of move2Spots
|
||
var coords = move2Spots[Math.floor(Math.random()*move2Spots.length)];
|
||
var nx = coords.x;
|
||
var ny = coords.y;
|
||
moved = tryMove(pixel,nx,ny,leaveBehind2 || leaveBehind);
|
||
if (moved) {
|
||
if (typeof C2 !== "undefined" && elements[C2]) {
|
||
pixel.element = C2;
|
||
pixel.color = pixelColorPick(pixel);
|
||
pixel.start = pixelTicks;
|
||
if (elements[C2].burning != true) {
|
||
pixel.burning = false;
|
||
}
|
||
else {
|
||
pixel.burning = true;
|
||
pixel.burnStart = pixelTicks;
|
||
}
|
||
}
|
||
break;
|
||
}
|
||
else {
|
||
// remove coords from move2Spots
|
||
move2Spots.splice(move2Spots.indexOf(coords),1);
|
||
}
|
||
}
|
||
}
|
||
}
|
||
|
||
|
||
// Change tempearture if needed (unused)
|
||
/*if (info.tempChange != undefined) {
|
||
pixel.temp += info.tempChange;
|
||
pixelTempCheck(pixel);
|
||
}*/
|
||
|
||
// Burning
|
||
doBurning(pixel);
|
||
|
||
// Heat Transfer
|
||
if (info.insulate != true) {
|
||
doHeat(pixel);
|
||
}
|
||
|
||
// Electricity Transfer
|
||
doElectricity(pixel);
|
||
|
||
|
||
}
|
||
|
||
function doBurning(pixel) {
|
||
if (pixel.burning) { // Burning
|
||
var info = elements[pixel.element];
|
||
pixel.temp += 1;
|
||
pixelTempCheck(pixel);
|
||
var burnSpots = [
|
||
{x:pixel.x+1,y:pixel.y},
|
||
{x:pixel.x-1,y:pixel.y},
|
||
{x:pixel.x,y:pixel.y+1},
|
||
{x:pixel.x,y:pixel.y-1},
|
||
];
|
||
// loop through burnspots
|
||
for (var i = 0; i < burnSpots.length; i++) {
|
||
var burnSpot = burnSpots[i];
|
||
if (!isEmpty(burnSpot.x,burnSpot.y,true)) {
|
||
var newPixel = pixelMap[burnSpot.x][burnSpot.y];
|
||
if (elements[newPixel.element].burn && !newPixel.burning) {
|
||
if (Math.floor(Math.random()*100) < elements[newPixel.element].burn) {
|
||
newPixel.burning = true;
|
||
newPixel.burnStart = pixelTicks;
|
||
}
|
||
}
|
||
}
|
||
}
|
||
|
||
if ((pixelTicks - pixel.burnStart > (info.burnTime || 200)) && Math.floor(Math.random()*100)<(info.burn || 10)) {
|
||
var burnInto = info.burnInto;
|
||
if (burnInto == undefined) {
|
||
burnInto = 'fire';
|
||
}
|
||
else if (burnInto instanceof Array) {
|
||
burnInto = burnInto[Math.floor(Math.random()*burnInto.length)];
|
||
}
|
||
pixel.element = burnInto;
|
||
if (info.fireColor != undefined && burnInto == "fire") {
|
||
pixel.color = pixelColorPick(pixel,info.fireColor);
|
||
}
|
||
else {
|
||
pixel.color = pixelColorPick(pixel)
|
||
}
|
||
pixel.start = pixelTicks;
|
||
if (elements[burnInto].burning != true) {
|
||
pixel.burning = false;
|
||
delete pixel.burnStart;
|
||
}
|
||
else {
|
||
pixel.burning = true;
|
||
pixel.burnStart = pixelTicks;
|
||
}
|
||
if (elements[burnInto].temp != undefined) {
|
||
pixel.temp = elements[burnInto].temp;
|
||
pixelTempCheck(pixel)
|
||
}
|
||
}
|
||
else if (pixel.element != "fire" && isEmpty(pixel.x,pixel.y-1) && Math.floor(Math.random()*100)<10) {
|
||
createPixel("fire",pixel.x,pixel.y-1);
|
||
pixelMap[pixel.x][pixel.y-1].temp = pixel.temp//+(pixelTicks - (pixel.burnStart || 0));
|
||
if (info.fireColor != undefined) {
|
||
pixelMap[pixel.x][pixel.y-1].color = pixelColorPick(pixelMap[pixel.x][pixel.y-1],info.fireColor);
|
||
}
|
||
}
|
||
|
||
}
|
||
}
|
||
|
||
function doHeat(pixel) {
|
||
// Check right and bottom adjacent pixels
|
||
var coordsToCheck = [
|
||
{x:pixel.x+1,y:pixel.y},
|
||
{x:pixel.x,y:pixel.y+1},
|
||
];
|
||
for (var i = 0; i < coordsToCheck.length; i++) {
|
||
var coords = coordsToCheck[i];
|
||
if (!isEmpty(coords.x,coords.y,true)) {
|
||
var newPixel = pixelMap[coords.x][coords.y];
|
||
// Skip if both temperatures are the same
|
||
if (pixel.temp == newPixel.temp || elements[newPixel.element].insulate == true) {
|
||
continue;
|
||
}
|
||
// Set both pixel temperatures to their average
|
||
var avg = (pixel.temp + newPixel.temp)/2;
|
||
pixel.temp = avg;
|
||
newPixel.temp = avg;
|
||
pixelTempCheck(pixel);
|
||
pixelTempCheck(newPixel);
|
||
}
|
||
}
|
||
}
|
||
|
||
function doElectricity(pixel) {
|
||
if (pixel.charge) {
|
||
// Check each adjacent pixel, if that pixel's charge is false, set it to the same charge
|
||
var coordsToCheck = [
|
||
{x:pixel.x+1,y:pixel.y},
|
||
{x:pixel.x-1,y:pixel.y},
|
||
{x:pixel.x,y:pixel.y+1},
|
||
{x:pixel.x,y:pixel.y-1},
|
||
];
|
||
for (var i = 0; i < coordsToCheck.length; i++) {
|
||
var coords = coordsToCheck[i];
|
||
if (!isEmpty(coords.x,coords.y,true)) {
|
||
var newPixel = pixelMap[coords.x][coords.y];
|
||
var con = elements[newPixel.element].conduct;
|
||
if (con == undefined) {continue}
|
||
if (Math.random() < con) { // If random number is less than conductivity
|
||
if (!newPixel.charge && !newPixel.chargeCD) {
|
||
newPixel.charge = 1;
|
||
if (elements[newPixel.element].colorOn) {
|
||
newPixel.color = pixelColorPick(newPixel);
|
||
}
|
||
}
|
||
}
|
||
else if (elements[newPixel.element].insulate != true) { // Otherwise heat the pixel (Resistance simulation)
|
||
newPixel.temp += pixel.charge/4;
|
||
pixelTempCheck(newPixel);
|
||
}
|
||
}
|
||
}
|
||
pixel.charge -= 0.25;
|
||
if (pixel.charge <= 0) {
|
||
delete pixel.charge;
|
||
pixel.chargeCD = 4;
|
||
if (elements[pixel.element].colorOn) {
|
||
pixel.color = pixelColorPick(pixel);
|
||
}
|
||
}
|
||
}
|
||
// Lower charge cooldown
|
||
else if (pixel.chargeCD) {
|
||
pixel.chargeCD -= 1;
|
||
if (pixel.chargeCD <= 0) {
|
||
delete pixel.chargeCD;
|
||
}
|
||
}
|
||
}
|
||
|
||
function pixelColorPick(pixel,customColor=null) {
|
||
var element = pixel.element;
|
||
var elementInfo = elements[element];
|
||
//if (elementInfo.behavior instanceof Array) {
|
||
|
||
if (pixel.charge && elementInfo.colorOn) {
|
||
customColor = elementInfo.colorOn;
|
||
}
|
||
if (customColor != null) {
|
||
if (Array.isArray(customColor)) {
|
||
customColor = customColor[Math.floor(Math.random() * customColor.length)];
|
||
}
|
||
if (customColor.startsWith("#")) {
|
||
customColor = hexToRGB(customColor);
|
||
}
|
||
var rgb = customColor;
|
||
}
|
||
else {
|
||
var rgb = elements[element].colorObject; // {r, g, b}
|
||
// If rgb is an array, choose a random item
|
||
if (Array.isArray(rgb)) {
|
||
rgb = rgb[Math.floor(Math.random() * rgb.length)];
|
||
}
|
||
}
|
||
// Randomly darken or lighten the RGB color
|
||
var coloroffset = Math.floor(Math.random() * (Math.random() > 0.5 ? -1 : 1) * Math.random() * 15);
|
||
var r = rgb.r + coloroffset;
|
||
var g = rgb.g + coloroffset;
|
||
var b = rgb.b + coloroffset;
|
||
// Make sure the color is within the RGB range
|
||
r = Math.max(0, Math.min(255, r));
|
||
g = Math.max(0, Math.min(255, g));
|
||
b = Math.max(0, Math.min(255, b));
|
||
var color = "rgb("+r+","+g+","+b+")";
|
||
|
||
/*}
|
||
else {
|
||
var color = elementInfo.color;
|
||
if (Array.isArray(color)) {
|
||
color = color[Math.floor(Math.random() * color.length)];
|
||
}
|
||
}*/
|
||
return color;
|
||
}
|
||
function pixelTempCheck(pixel) {
|
||
var elementInfo = elements[pixel.element];
|
||
if (pixel.temp < -273.15) { // Absolute Zero
|
||
pixel.temp = -273.15;
|
||
}
|
||
// If the pixel's temp >= the elementInfo tempHigh, change pixel.element to elementInfo.stateHigh
|
||
if (pixel.temp >= elementInfo.tempHigh) {
|
||
var result = elementInfo.stateHigh;
|
||
// If result is an array, choose a random item
|
||
if (Array.isArray(result)) {
|
||
result = result[Math.floor(Math.random() * result.length)];
|
||
}
|
||
pixel.element = result;
|
||
pixel.color = pixelColorPick(pixel);
|
||
pixel.start = pixelTicks;
|
||
if (pixel.burning) {
|
||
pixel.burning = false;
|
||
delete pixel.burnStart;
|
||
}
|
||
if (elements[result].burning == true) {
|
||
pixel.burning = true;
|
||
pixel.burnStart = pixelTicks;
|
||
}
|
||
}
|
||
// If the pixel's temp <= the elementInfo tempLow, change pixel.element to elementInfo.stateLow
|
||
else if (pixel.temp <= elementInfo.tempLow) {
|
||
var result = elementInfo.stateLow;
|
||
// If result is an array, choose a random item
|
||
if (Array.isArray(result)) {
|
||
result = result[Math.floor(Math.random() * result.length)];
|
||
}
|
||
pixel.element = result;
|
||
pixel.color = pixelColorPick(pixel);
|
||
pixel.start = pixelTicks;
|
||
if (pixel.burning) {
|
||
pixel.burning = false;
|
||
delete pixel.burnStart;
|
||
}
|
||
if (elements[result].burning) {
|
||
pixel.burning = true;
|
||
pixel.burnStart = pixelTicks;
|
||
}
|
||
}
|
||
}
|
||
function getNeighbors(pixel) {
|
||
var neighbors = [];
|
||
var x = pixel.x;
|
||
var y = pixel.y;
|
||
if (!isEmpty(x-1,y,true)) { neighbors.push(pixelMap[x-1][y]); }
|
||
if (!isEmpty(x+1,y,true)) { neighbors.push(pixelMap[x+1][y]); }
|
||
if (!isEmpty(x,y-1,true)) { neighbors.push(pixelMap[x][y-1]); }
|
||
if (!isEmpty(x,y+1,true)) { neighbors.push(pixelMap[x][y+1]); }
|
||
return neighbors;
|
||
}
|
||
|
||
function circleCoords(x,y,radius) {
|
||
var coords = [];
|
||
for (var i = x - radius; i <= x + radius; i++) {
|
||
for (var j = y - radius; j <= y + radius; j++) {
|
||
if (Math.pow(i-x,2) + Math.pow(j-y,2) <= Math.pow(radius,2)) {
|
||
coords.push({x:i,y:j});
|
||
}
|
||
}
|
||
}
|
||
return coords;
|
||
}
|
||
function drawCirclePixels(x,y,radius) {
|
||
var coords = circleCoords(x,y,radius);
|
||
for (var i = 0; i < coords.length; i++) {
|
||
if (isEmpty(coords[i].x,coords[i].y)) {
|
||
createPixel(currentElement,coords[i].x,coords[i].y);
|
||
}
|
||
}
|
||
}
|
||
// pixelMap is a 2D array of pixels.
|
||
// function to get a new 2D array of pixels from a rectangular area
|
||
function selection(x1,y1,x2,y2) {
|
||
var selection = [];
|
||
for (var i = x1; i <= x2; i++) {
|
||
selection[i] = [];
|
||
for (var j = y1; j <= y2; j++) {
|
||
selection[i][j] = pixelMap[i][j];
|
||
}
|
||
}
|
||
return selection;
|
||
}
|
||
unicodeSkips = {
|
||
0: 65, // null -> 0
|
||
58: 65, // : -> A
|
||
91: 97, // [ -> a
|
||
123: 192, // { -> À
|
||
215: 216, // × -> Ø
|
||
247: 248, // ÷ -> ø
|
||
688: 880,
|
||
884: 886,
|
||
888: 891,
|
||
894: 895,
|
||
896: 902,
|
||
903: 904,
|
||
907: 908,
|
||
909: 910,
|
||
930: 931,
|
||
1155: 1162,
|
||
1328: 1329,
|
||
1367: 1376,
|
||
1417: 1488,
|
||
1514: 12448,
|
||
12544: 13312
|
||
};
|
||
// version;codes;pixels;
|
||
function generateSave(pixelarray=null) {
|
||
if (pixelarray == null) {
|
||
pixelarray = pixelMap;
|
||
}
|
||
var n = 65;
|
||
var codes = "";
|
||
var codelist = {" ":" "};
|
||
var save = "";
|
||
// Add char*the number of consecutive pixels with the same element
|
||
var lastelem = "";
|
||
var samecount = 0;
|
||
for (var i = 0; i < pixelarray.length; i++) {
|
||
for (var j = 0; j < pixelarray[i].length; j++) {
|
||
var pixel = pixelarray[i][j];
|
||
if (pixel) {
|
||
if (codelist[pixel.element] == undefined) {
|
||
var char = String.fromCharCode(n);
|
||
codelist[pixel.element] = char;
|
||
codes += char+"="+pixel.element+",";
|
||
n++;
|
||
}
|
||
if (pixel.element == lastelem) {
|
||
samecount++;
|
||
}
|
||
else {
|
||
if (samecount > 0) {
|
||
save += codelist[lastelem]+"*"+samecount;
|
||
}
|
||
samecount = 1;
|
||
lastelem = pixel.element;
|
||
}
|
||
}
|
||
else {
|
||
// use " " for empty pixels
|
||
if (lastelem == " ") {
|
||
samecount++;
|
||
}
|
||
else {
|
||
if (samecount > 0) {
|
||
save += codelist[lastelem]+"*"+samecount
|
||
}
|
||
samecount = 1;
|
||
lastelem = " ";
|
||
}
|
||
}
|
||
}
|
||
save += "|";
|
||
}
|
||
// save = codes(without the last character) + save
|
||
save = codes.slice(0,-1)+";"+save;
|
||
return save;
|
||
}
|
||
function explodeAt(x,y,radius,fire="fire") {
|
||
// if fire contains , split it into an array
|
||
if (fire.includes(",")) {
|
||
fire = fire.split(",");
|
||
}
|
||
var coords = circleCoords(x,y,radius);
|
||
var power = radius/10;
|
||
//for (var p = 0; p < Math.round(radius/10+1); p++) {
|
||
for (var i = 0; i < coords.length; i++) {
|
||
// damage value is based on distance from x and y
|
||
var damage = Math.random() + (Math.floor(Math.sqrt(Math.pow(coords[i].x-x,2) + Math.pow(coords[i].y-y,2)))) / radius;
|
||
// invert
|
||
damage = 1 - damage;
|
||
if (damage < 0) { damage = 0; }
|
||
damage *= power;
|
||
if (isEmpty(coords[i].x,coords[i].y)) {
|
||
// create smoke or fire depending on the damage if empty
|
||
if (damage < 0.02) { } // do nothing
|
||
else if (damage < 0.2) {
|
||
createPixel("smoke",coords[i].x,coords[i].y);
|
||
}
|
||
else {
|
||
// if fire is an array, choose a random item
|
||
if (Array.isArray(fire)) {
|
||
createPixel(fire[Math.floor(Math.random() * fire.length)],coords[i].x,coords[i].y);
|
||
}
|
||
else {
|
||
createPixel(fire,coords[i].x,coords[i].y);
|
||
}
|
||
}
|
||
}
|
||
else if (!outOfBounds(coords[i].x,coords[i].y)) {
|
||
// damage the pixel
|
||
var pixel = pixelMap[coords[i].x][coords[i].y];
|
||
var info = elements[pixel.element];
|
||
if (info.hardness) { // lower damage depending on hardness(0-1)
|
||
if (info.hardness < 1) {
|
||
damage = damage * ((1 - info.hardness)*10);
|
||
}
|
||
else { damage = 0; }
|
||
}
|
||
if (damage > 0.25) {
|
||
if (info.breakInto) {
|
||
// if it is an array, choose a random item, else just use the value
|
||
if (Array.isArray(info.breakInto)) {
|
||
var result = info.breakInto[Math.floor(Math.random() * info.breakInto.length)];
|
||
}
|
||
else {
|
||
var result = info.breakInto;
|
||
}
|
||
// change the pixel to the result
|
||
pixel.element = result;
|
||
pixel.color = pixelColorPick(pixel);
|
||
if (elements[result].burning) {
|
||
pixel.burning = true;
|
||
pixel.burnStart = pixelTicks;
|
||
}
|
||
else if (pixel.burning && !elements[result].burn) {
|
||
pixel.burning = false;
|
||
delete pixel.burnStart;
|
||
}
|
||
}
|
||
else {
|
||
if (Array.isArray(fire)) {
|
||
var newfire = fire[Math.floor(Math.random() * fire.length)];
|
||
}
|
||
else {
|
||
var newfire = fire;
|
||
}
|
||
pixel.element = newfire;
|
||
pixel.color = pixelColorPick(pixel);
|
||
if (elements[newfire].burning) {
|
||
pixel.burning = true;
|
||
pixel.burnStart = pixelTicks;
|
||
}
|
||
else if (pixel.burning && !elements[newfire].burn) {
|
||
pixel.burning = false;
|
||
delete pixel.burnStart;
|
||
}
|
||
}
|
||
}
|
||
if (damage > 0.75) {
|
||
if (info.burn) {
|
||
pixel.burning = true;
|
||
pixel.burnStart = pixelTicks;
|
||
}
|
||
}
|
||
pixel.temp += damage*radius*power;
|
||
pixelTempCheck(pixel);
|
||
}
|
||
}
|
||
}
|
||
|
||
function drawPixels(forceTick=false) {
|
||
// newCurrentPixels = shuffled currentPixels
|
||
var newCurrentPixels = currentPixels.slice();
|
||
newCurrentPixels.sort(function() {return 0.5 - Math.random()});
|
||
for (var i = 0; i < newCurrentPixels.length; i++) {
|
||
pixel = newCurrentPixels[i];
|
||
//if (pixelMap[pixel.x][pixel.y] == undefined || currentPixels.indexOf(pixel) == -1) {continue}
|
||
if (pixel.del) {continue}
|
||
if ((!paused) || forceTick) {
|
||
if (elements[pixel.element].tick) { // Run tick function if it exists
|
||
elements[pixel.element].tick(pixel);
|
||
}
|
||
if (elements[pixel.element].behavior) { // Parse behavior if it exists
|
||
pixelTick(pixel);
|
||
}
|
||
};
|
||
}
|
||
// Draw the current pixels
|
||
var canvas = document.getElementById("game");
|
||
var ctx = canvas.getContext("2d");
|
||
for (var i = 0; i < newCurrentPixels.length; i++) {
|
||
pixel = newCurrentPixels[i];
|
||
if (pixelMap[pixel.x][pixel.y] == undefined) {continue}
|
||
if (view===null) {
|
||
ctx.fillStyle = pixel.color;
|
||
}
|
||
else if (view === "thermal") {
|
||
// set the color to pixel.temp, from hottest at 0 hue to coldest 225 hue, with the minimum being -273, max being 6000
|
||
var temp = pixel.temp;
|
||
if (temp < -273) {temp = -273}
|
||
if (temp > 6000) {temp = 6000}
|
||
var hue = 225 - (temp/6000)*225;
|
||
if (hue < 0) {hue = 0}
|
||
if (hue > 225) {hue = 225}
|
||
ctx.fillStyle = "hsl("+hue+",100%,50%)";
|
||
}
|
||
ctx.fillRect(pixel.x*pixelSize, pixel.y*pixelSize, pixelSize, pixelSize);
|
||
if (pixel.charge) { // Yellow glow on charge
|
||
if (!elements[pixel.element].colorOn) {
|
||
ctx.fillStyle = "rgba(255,255,0,0.5)";
|
||
ctx.fillRect(pixel.x*pixelSize, pixel.y*pixelSize, pixelSize, pixelSize);
|
||
}
|
||
}
|
||
}
|
||
if ((!paused) || forceTick) {pixelTicks++};
|
||
}
|
||
function tick() {
|
||
// If mouseIsDown, do mouseAction
|
||
if (mouseIsDown) {
|
||
mouseAction(null,mousePos.x,mousePos.y);
|
||
}
|
||
// Get the canvas
|
||
var canvas = document.getElementById("game");
|
||
var ctx = canvas.getContext("2d");
|
||
// Clear the canvas
|
||
if (!settings["bg"]) {ctx.clearRect(0, 0, canvas.width, canvas.height)}
|
||
else {
|
||
ctx.fillStyle = settings["bg"];
|
||
ctx.fillRect(0, 0, canvas.width, canvas.height);
|
||
}
|
||
drawPixels();
|
||
|
||
if (currentElement == "pick" || currentElement == "lookup") {
|
||
var mouseOffset = 0;
|
||
}
|
||
else {
|
||
var mouseOffset = Math.trunc(mouseSize/2);
|
||
}
|
||
var topLeft = [mousePos.x-mouseOffset,mousePos.y-mouseOffset];
|
||
var bottomRight = [mousePos.x+mouseOffset,mousePos.y+mouseOffset];
|
||
// Draw a rectangle around the mouse
|
||
ctx.strokeStyle = "white";
|
||
ctx.strokeRect(topLeft[0]*pixelSize,topLeft[1]*pixelSize,(bottomRight[0]-topLeft[0]+1)*pixelSize,(bottomRight[1]-topLeft[1]+1)*pixelSize);
|
||
updateStats();
|
||
//ticks ++;
|
||
}
|
||
|
||
currentElement = "sand";
|
||
mouseIsDown = false;
|
||
mouseType = null;
|
||
function mouseClick(e) {
|
||
mouseIsDown = true;
|
||
// If it's a left click
|
||
if (e.button == 0) {
|
||
mouseType = "left";
|
||
}
|
||
else if (e.button == 2) {
|
||
mouseType = "right";
|
||
}
|
||
// middle click
|
||
else if (e.button == 1) {
|
||
mouseType = "middle";
|
||
}
|
||
else {
|
||
mouseType = "left";
|
||
}
|
||
mouseMove(e);
|
||
return false;
|
||
}
|
||
function mouseUp(e) {
|
||
mouseIsDown = false;
|
||
}
|
||
|
||
function getMousePos(canvas, evt) {
|
||
// If evt.touches is defined, use the first touch
|
||
if (evt.touches) {
|
||
evt.preventDefault();
|
||
evt = evt.touches[0];
|
||
}
|
||
var rect = canvas.getBoundingClientRect();
|
||
return {
|
||
// Round to nearest pixel
|
||
x: Math.round((evt.clientX - rect.left)/pixelSize-0.5),
|
||
y: Math.round((evt.clientY - rect.top)/pixelSize-0.5)
|
||
};
|
||
}
|
||
function mouseMove(e) {
|
||
if (mouseIsDown) {
|
||
mouseAction(e);
|
||
}
|
||
else {
|
||
var canvas = document.getElementById("game");
|
||
mousePos = getMousePos(canvas, e);
|
||
}
|
||
}
|
||
function mouseAction(e,mouseX=undefined,mouseY=undefined) {
|
||
if (showingMenu && currentElement != "lookup") {
|
||
closeMenu();
|
||
}
|
||
if (mouseType == "left") { mouse1Action(e,mouseX,mouseY); }
|
||
else if (mouseType == "right") { mouse2Action(e,mouseX,mouseY); }
|
||
else if (mouseType == "middle") { mouseMiddleAction(e,mouseX,mouseY); }
|
||
}
|
||
mouseSize = 5;
|
||
mousePos = {x:0,y:0};
|
||
function mouseRange(mouseX,mouseY) {
|
||
var coords = [];
|
||
var mouseOffset = Math.trunc(mouseSize/2);
|
||
var topLeft = [mouseX-mouseOffset,mouseY-mouseOffset];
|
||
var bottomRight = [mouseX+mouseOffset,mouseY+mouseOffset];
|
||
// Starting at the top left, go through each pixel
|
||
for (var x = topLeft[0]; x <= bottomRight[0]; x++) {
|
||
for (var y = topLeft[1]; y <= bottomRight[1]; y++) {
|
||
// If the pixel is empty, add it to coords
|
||
coords.push([x,y]);
|
||
}
|
||
}
|
||
return coords;
|
||
}
|
||
function mouse1Action(e,mouseX=undefined,mouseY=undefined) {
|
||
if (currentElement == "erase") { mouse2Action(e,mouseX,mouseY); return; }
|
||
else if (currentElement == "pick") { mouseMiddleAction(e,mouseX,mouseY); return; }
|
||
// If x and y are undefined, get the mouse position
|
||
if (mouseX == undefined && mouseY == undefined) {
|
||
var canvas = document.getElementById("game");
|
||
var ctx = canvas.getContext("2d");
|
||
mousePos = getMousePos(canvas, e);
|
||
var mouseX = mousePos.x;
|
||
var mouseY = mousePos.y;
|
||
}
|
||
if (currentElement == "lookup") {
|
||
if (!isEmpty(mouseX,mouseY,true)) {
|
||
showInfo(pixelMap[mouseX][mouseY].element);
|
||
}
|
||
return;
|
||
}
|
||
var coords = mouseRange(mouseX,mouseY);
|
||
var element = elements[currentElement];
|
||
var mixList = [];
|
||
// 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 element name is heat or cool
|
||
if (currentElement == "heat" || currentElement == "cool") {
|
||
if (!isEmpty(x,y,false)) {
|
||
if (outOfBounds(x,y)) {
|
||
continue;
|
||
}
|
||
var pixel = pixelMap[x][y];
|
||
if (shiftDown) {pixel.temp += element.temp+(Math.random()*element.temp*1.5)*20;}
|
||
else {pixel.temp += element.temp+(Math.random()*element.temp*1.5);}
|
||
pixelTempCheck(pixel);
|
||
}
|
||
}
|
||
else if (currentElement == "mix") {
|
||
if (!isEmpty(x,y,true)) {
|
||
var pixel = pixelMap[x][y];
|
||
if ((pixel.element != "fire" && pixel.element != "smoke") || shiftDown) {
|
||
mixList.push(pixel);
|
||
}
|
||
}
|
||
}
|
||
else if (currentElement == "shock") {
|
||
if (!isEmpty(x,y,true)) {
|
||
// One loop that repeats 5 times if shiftDown else 1 time
|
||
for (var j = 0; j < (shiftDown ? 5 : 1); j++) {
|
||
var pixel = pixelMap[x][y];
|
||
var con = elements[pixel.element].conduct;
|
||
if (con == undefined) {continue}
|
||
if (Math.random() < con) { // If random number is less than conductivity
|
||
if (!pixel.charge && !pixel.chargeCD) {
|
||
pixel.charge = 1;
|
||
if (elements[pixel.element].colorOn) {
|
||
pixel.color = pixelColorPick(pixel);
|
||
}
|
||
}
|
||
}
|
||
else if (elements[pixel.element].insulate != true) { // Otherwise heat the pixel (Resistance simulation)
|
||
pixel.temp += 0.25;
|
||
pixelTempCheck(pixel);
|
||
}
|
||
}
|
||
}
|
||
}
|
||
else if (currentElement == "random" && isEmpty(x, y)) {
|
||
// create pixel with random element from "randomChoices" array
|
||
currentPixels.push(new Pixel(x, y, randomChoices[Math.floor(Math.random() * randomChoices.length)]));
|
||
}
|
||
else if (mode == "replace") {
|
||
if (outOfBounds(x,y)) {
|
||
continue;
|
||
}
|
||
// Remove pixel at position from currentPixels
|
||
var index = currentPixels.indexOf(pixelMap[x][y]);
|
||
if (index > -1) {
|
||
currentPixels.splice(index, 1);
|
||
}
|
||
if (currentElement == "random") {
|
||
currentPixels.push(new Pixel(x, y, randomChoices[Math.floor(Math.random() * randomChoices.length)]));
|
||
}
|
||
else {
|
||
currentPixels.push(new Pixel(x, y, currentElement));
|
||
}
|
||
}
|
||
else if (isEmpty(x, y)) {
|
||
currentPixels.push(new Pixel(x, y, currentElement));
|
||
}
|
||
}
|
||
if (currentElement == "mix") {
|
||
// 1. repeat for each pixel in mixList
|
||
// 2. choose 2 random pixels and swap their x and y
|
||
// 3. remove pixel from mixList
|
||
for (var i = 0; i < mixList.length; i++) {
|
||
var pixel1 = mixList[Math.floor(Math.random()*mixList.length)];
|
||
var pixel2 = mixList[Math.floor(Math.random()*mixList.length)];
|
||
swapPixels(pixel1,pixel2);
|
||
mixList.splice(mixList.indexOf(pixel1),1);
|
||
mixList.splice(mixList.indexOf(pixel2),1);
|
||
}
|
||
|
||
}
|
||
}
|
||
function mouse2Action(e,mouseX=undefined,mouseY=undefined) {
|
||
// Erase pixel at mouse position
|
||
if (mouseX == undefined && mouseY == undefined) {
|
||
var canvas = document.getElementById("game");
|
||
var ctx = canvas.getContext("2d");
|
||
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 {
|
||
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];
|
||
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;
|
||
}
|
||
}
|
||
}
|
||
}
|
||
}
|
||
function mouseMiddleAction(e, mouseX=undefined, mouseY=undefined) {
|
||
if (mouseX == undefined && mouseY == undefined) {
|
||
var canvas = document.getElementById("game");
|
||
var ctx = canvas.getContext("2d");
|
||
mousePos = getMousePos(canvas, e);
|
||
var mouseX = mousePos.x;
|
||
var mouseY = mousePos.y;
|
||
}
|
||
if (!isEmpty(mouseX, mouseY,true)) {
|
||
selectElement(pixelMap[mouseX][mouseY].element);
|
||
mouseIsDown = false;
|
||
}
|
||
}
|
||
function wheelHandle(e) {
|
||
e.preventDefault();
|
||
var deltaY = e.deltaY*0.1;
|
||
if (Math.round(deltaY) == 0) {
|
||
if (deltaY > 0) { deltaY = 1; }
|
||
else { deltaY = -1; }
|
||
}
|
||
mouseSize += Math.round(deltaY*2);
|
||
if (mouseSize < 1) { mouseSize = 1; }
|
||
if (mouseSize > (height > width ? height : width)) { mouseSize = (height > width ? height : width); }
|
||
}
|
||
function chooseElementPrompt() {
|
||
var e = prompt("Enter the element's ID")
|
||
if (elements[e] != undefined) {
|
||
e = e.replace(/ /g,"_");
|
||
selectElement(e);
|
||
var btn = document.getElementById("elementButton-"+e);
|
||
if (btn != null) {
|
||
btn.setAttribute("current","true");
|
||
}
|
||
};
|
||
}
|
||
function togglePause() {
|
||
paused = !paused;
|
||
if (paused) {
|
||
document.getElementById("pauseButton").setAttribute("on","true");
|
||
}
|
||
else {
|
||
document.getElementById("pauseButton").setAttribute("on","false");
|
||
}
|
||
}
|
||
function doFrame() {
|
||
if (!paused) {
|
||
paused = true;
|
||
document.getElementById("pauseButton").setAttribute("on","true");
|
||
}
|
||
drawPixels(true);
|
||
}
|
||
|
||
function selectElement(element) {
|
||
var e1 = document.getElementById("elementButton-"+currentElement);
|
||
if (e1 != null) { e1.setAttribute("current","false"); }
|
||
currentElement = element;
|
||
var e2 = document.getElementById("elementButton-"+element);
|
||
if (e2 != null) { e2.setAttribute("current","true"); }
|
||
}
|
||
function selectCategory(category) {
|
||
var categoryButton = document.getElementById("categoryButton-"+category);
|
||
var categoryDiv = document.getElementById("category-"+category);
|
||
// Show this categoryDiv and hide all others
|
||
for (var i = 0; i < categoryButton.parentNode.children.length; i++) {
|
||
var e = categoryDiv.parentNode.children[i];
|
||
e.style.display = "none";
|
||
// Set the categoryButton of categoryDiv's category attribute to current=false
|
||
document.getElementById("categoryButton-"+e.getAttribute("category")).setAttribute("current",false);
|
||
}
|
||
categoryDiv.style.display = "block";
|
||
categoryButton.setAttribute("current", true);
|
||
}
|
||
function setView(n) {
|
||
// 2 for thermal
|
||
if (n == 2) {
|
||
view = "thermal";
|
||
}
|
||
else { // reset view
|
||
view = null;
|
||
}
|
||
}
|
||
function clearAll() {
|
||
currentPixels = [];
|
||
pixelMap = [];
|
||
for (var i = 0; i < width; i++) {
|
||
pixelMap[i] = [];
|
||
for (var j = 0; j < height; j++) {
|
||
pixelMap[i][j] = undefined;
|
||
}
|
||
}
|
||
pixelTicks = 0;
|
||
}
|
||
|
||
// Update stats
|
||
function updateStats() {
|
||
var statsDiv = document.getElementById("stats");
|
||
var stats = "<span id='stat-pos' class='stat'>x"+mousePos.x+",y"+mousePos.y+"</span>";
|
||
stats += "<span id='stat-pixels' class='stat'>Pxls:" + currentPixels.length+"</span>";
|
||
stats += "<span id='stat-tps' class='stat'>" + tps+"tps</span>";
|
||
stats += "<span id='stat-ticks' class='stat'>" + pixelTicks+"</span>";
|
||
if (typeof pixelMap == 'undefined') { return; }
|
||
if (pixelMap[mousePos.x] != undefined) {
|
||
var currentPixel = pixelMap[mousePos.x][mousePos.y];
|
||
if (currentPixel != undefined) {
|
||
stats += "<span id='stat-element' class='stat'>Elem:"+(elements[currentPixel.element].name || currentPixel.element).toUpperCase()+"</span>";
|
||
stats += "<span id='stat-temperature' class='stat'>Temp:"+formatTemp(currentPixel.temp)+"</span>";
|
||
if (currentPixel.charge) {
|
||
stats += "<span id='stat-charge' class='stat'>C"+currentPixel.charge+"</span>";
|
||
}
|
||
if (currentPixel.burning) {
|
||
stats += "<span id='stat-burning' class='stat'>Burning</span>";
|
||
}
|
||
}
|
||
}
|
||
if (shiftDown) {
|
||
if (shiftDown==1) {stats += "<span id='stat-shift' class='stat'>[↑ ]</span>";}
|
||
else if (shiftDown==2) {stats += "<span id='stat-shift' class='stat'>[A ]</span>";}
|
||
else if (shiftDown==3) {stats += "<span id='stat-shift' class='stat'>[ ↑]</span>";}
|
||
else if (shiftDown==4) {stats += "<span id='stat-shift' class='stat'>[ A]</span>";}
|
||
}
|
||
// If the view is not null, show the view in all caps
|
||
if (view != null) {
|
||
stats += "<span id='stat-view' class='stat'>"+view.toUpperCase()+"</span>";
|
||
}
|
||
statsDiv.innerHTML = stats;
|
||
}
|
||
|
||
function formatTemp(temp) { // temp is Celcius
|
||
if (!settings["units"] || settings["units"] === "m") { // Celsius
|
||
return Math.round(temp)+"°C"
|
||
}
|
||
else if (settings["units"] === "i") { // Fahrenheit
|
||
return Math.round(temp*1.8+32)+"°F"
|
||
}
|
||
else if (settings["units"] === "s") { // Kelvin
|
||
return Math.round(temp+273.15)+"K"
|
||
}
|
||
}
|
||
function formatDensity(density) { // temp is kg/m3
|
||
// default/metric = kg/m3, imperial = lb/ft3, si = g/cm3
|
||
if (!settings["units"] || settings["units"] === "m") { // kg/m3
|
||
return Math.round(density)+" kg⁄m<sup>3</sup>"
|
||
}
|
||
else if (settings["units"] === "i") { // lb/ft3
|
||
return Math.round(density/16.018)+" lb⁄ft<sup>3</sup>"
|
||
}
|
||
else if (settings["units"] === "s") { // g/cm3
|
||
// round to 2 decimal places
|
||
return Math.round(density/10)/100+" g⁄cm<sup>3</sup>"
|
||
}
|
||
}
|
||
|
||
showingMenu = false;
|
||
function infoLink(l) {
|
||
if (l instanceof Array) {
|
||
var newtext = "";
|
||
for (var i = 0; i < l.length; i++) {
|
||
var element = l[i];
|
||
// add to newtext a span with the element's name and its onclick to showInfo(element)
|
||
if (element=="pixels" || element=="itself") { newtext += element+", "}
|
||
else { newtext += "<span class='infoLink' onclick='showInfo(\""+element+"\")'>"+(elements[element].name || element).toUpperCase().replace(/_/g," ")+"</span>, ";}
|
||
}
|
||
// remove the last comma and space
|
||
newtext = newtext.substring(0, newtext.length-2);
|
||
return newtext
|
||
}
|
||
else {
|
||
if (l=="pixels" || l=="[???]" || l=="itself") {return l}
|
||
else {return "<span class='infoLink' onclick='showInfo(\""+l+"\")'>"+l.toUpperCase().replace(/_/g," ")+"</span>";}
|
||
}
|
||
}
|
||
function showInfo(element) { // this is such a mess please don't look at it
|
||
showingMenu = "info";
|
||
var infoParent = document.getElementById("infoParent");
|
||
infoParent.style.display = "block";
|
||
var infoSearch = document.getElementById("infoSearch");
|
||
infoSearch.focus();
|
||
var infoTitle = document.getElementById("infoTitle");
|
||
var infoText = document.getElementById("infoText");
|
||
if (element != undefined) {
|
||
// replace all spaces with underscores
|
||
element = element.replace(/ /g,"_");
|
||
infoSearch.value = element;
|
||
info = elements[element];
|
||
if (info) {
|
||
infoTitle.innerHTML = info.name || element.replace(/_/g," ");
|
||
infoTitle.innerHTML = infoTitle.innerHTML.replace(/\w\S*/g, function(txt){return txt.charAt(0).toUpperCase() + txt.substr(1).toLowerCase();});
|
||
infoText.innerHTML = "";
|
||
infoSearch.style.backgroundColor = "rgb(66, 66, 66)";
|
||
if (info.color) {
|
||
if (!(info.color instanceof Array)) {
|
||
infoText.innerHTML += "\nColor: <span style='background-color:"+info.color+"'> </span>";
|
||
}
|
||
else {
|
||
//gradient
|
||
var gradient = info.color;
|
||
var gradientString = "linear-gradient(to right";
|
||
for (var i = 0; i < gradient.length; i++) {
|
||
gradientString += ", "+gradient[i]+" "+(i*100/gradient.length)+"%";
|
||
}
|
||
gradientString += ")";
|
||
infoText.innerHTML += "\nColor: <span style='background:"+gradientString+"'> </span>";
|
||
}
|
||
}
|
||
|
||
var moves = false;
|
||
var deletes = [];
|
||
var swaps = [];
|
||
var creates = [];
|
||
var heats = false;
|
||
var cools = false;
|
||
var clones = false;
|
||
var explodes = false;
|
||
var sticks = [];
|
||
if (info.behavior) {
|
||
// for x and y in behavior array
|
||
for (var i = 0; i < info.behavior.length; i++) {
|
||
for (var j = 0; j < info.behavior[i][1].length; j++) {
|
||
var b0 = info.behavior[i][j];
|
||
if (!b0) { continue; }
|
||
for (var k = 0; k < b0.split(" AND ").length; k++) {
|
||
var b = b0.split(" AND ")[k];
|
||
// remove everything after %
|
||
b = b.split("%")[0];
|
||
if (b.indexOf(":") != -1) {
|
||
var arg = b.split(":")[1];
|
||
}
|
||
else { var arg = undefined }
|
||
var b = b.split(":")[0];
|
||
if (b == "M1" || b == "M2") {
|
||
moves = true;
|
||
}
|
||
else if (b == "DL") {
|
||
if (i==1 && j==1) { arg = "itself" }
|
||
else if (!arg) { arg = "pixels" }
|
||
if (deletes.indexOf(arg) == -1) { deletes = deletes.concat(arg.split(",")); }
|
||
}
|
||
else if (b == "SW") {
|
||
if (!arg) { arg = "pixels" }
|
||
if (swaps.indexOf(arg) == -1) { swaps = swaps.concat(arg.split(",")); }
|
||
}
|
||
else if (b == "CL") {
|
||
clones = true;
|
||
}
|
||
else if (b == "CR" || b == "CH" || b == "LB" || b == "L1" || b == "L2") {
|
||
if (!arg) { arg = "[???]" }
|
||
else if (arg.indexOf(">") != -1) { arg = arg.split(">")[1]; }
|
||
if (creates.indexOf(arg) == -1) { creates = creates.concat(arg.split(",")); }
|
||
}
|
||
else if (b == "HT") {
|
||
heats = true;
|
||
}
|
||
else if (b == "CO") {
|
||
cools = true;
|
||
}
|
||
else if (b == "ST") {
|
||
if (!arg) { arg = "pixels" }
|
||
if (sticks.indexOf(arg) == -1) { sticks = sticks.concat(arg.split(",")); }
|
||
}
|
||
else if (b == "EX") {
|
||
explodes = true;
|
||
}
|
||
|
||
|
||
}}}}
|
||
// make sure deletes, swaps, creates, and sticks have no duplicate items
|
||
deletes = deletes.filter(function(item, pos) {return deletes.indexOf(item) == pos;});
|
||
swaps = swaps.filter(function(item, pos) {return swaps.indexOf(item) == pos;});
|
||
creates = creates.filter(function(item, pos) {return creates.indexOf(item) == pos;});
|
||
sticks = sticks.filter(function(item, pos) {return sticks.indexOf(item) == pos;});
|
||
if (info.category == "tools") { infoText.innerHTML += "\nTool."}
|
||
else {
|
||
if (!moves && info.behavior) { infoText.innerHTML += "\nStationary."; }
|
||
if (info.category) { infoText.innerHTML += "\nCategory: "+info.category.toUpperCase()+"."; }
|
||
if (info.conduct) { infoText.innerHTML += "\nConducts electricity."; }
|
||
if (swaps.length > 0) { infoText.innerHTML += "\nMoves through "+infoLink(swaps)+"."; }
|
||
if (creates.length > 0) { infoText.innerHTML += "\nMakes "+infoLink(creates)+"."; }
|
||
if (clones) { infoText.innerHTML += "\nClones self." }
|
||
if (deletes.length > 0) { infoText.innerHTML += "\nDeletes "+infoLink(deletes)+"."; }
|
||
if (heats) { infoText.innerHTML += "\nHeats pixels." }
|
||
if (cools) { infoText.innerHTML += "\nCools pixels." }
|
||
if (sticks.length > 0) { infoText.innerHTML += "\nSticks to "+infoLink(sticks)+"."; }
|
||
if (explodes) { infoText.innerHTML += "\nExplodes." }
|
||
if (!settings["unhide"] && info.hidden) { infoText.innerHTML += "\nHidden from toolbar."; }
|
||
if (info.density != undefined) { infoText.innerHTML += "\nDensity: "+formatDensity(info.density)+"."; }
|
||
if (info.tempHigh != undefined) {
|
||
infoText.innerHTML += "\nTurns into "+infoLink(info.stateHigh || "[???]")+" above "+formatTemp(info.tempHigh)+".";
|
||
}
|
||
if (info.tempLow != undefined) {
|
||
infoText.innerHTML += "\nTurns into "+infoLink(info.stateLow || "[???]")+" below "+formatTemp(info.tempLow)+".";
|
||
}
|
||
if (info.burn != undefined) { infoText.innerHTML += "\nFlammability: "+info.burn+"%."; }
|
||
if (info.burnTime != undefined) {
|
||
infoText.innerHTML += "\nBurns for "+info.burnTime+" tick";
|
||
if (info.burnTime != 1) { infoText.innerHTML += "s"; }
|
||
infoText.innerHTML += ".";
|
||
}
|
||
if (info.burnInto) { infoText.innerHTML += "\nBurns into "+infoLink(info.burnInto)+"."; }
|
||
if (info.fireColor) {
|
||
if (!(info.fireColor instanceof Array)) {
|
||
infoText.innerHTML += "\nFlame Color: <span style='background-color:"+info.fireColor+"'> </span>";
|
||
}
|
||
else {
|
||
//gradient
|
||
var gradient = info.fireColor;
|
||
var gradientString = "linear-gradient(to right";
|
||
for (var i = 0; i < gradient.length; i++) {
|
||
gradientString += ", "+gradient[i]+" "+(i*100/gradient.length)+"%";
|
||
}
|
||
gradientString += ")";
|
||
infoText.innerHTML += "\nFlame Color: <span style='background:"+gradientString+"'> </span>";
|
||
}
|
||
}
|
||
if (info.breakInto) { infoText.innerHTML += "\nBreaks into "+infoLink(info.breakInto)+"."; }
|
||
if (info.reactions) {
|
||
infoText.innerHTML += "\nReacts with " + infoLink(Object.keys(info.reactions)) + ".";
|
||
}
|
||
}
|
||
infoText.innerHTML += "\n\n\n\n"
|
||
}
|
||
else {
|
||
infoTitle.innerHTML = "";
|
||
infoText.innerHTML = "";
|
||
// infoSearch red background
|
||
infoSearch.style.backgroundColor = "rgb(100, 33, 33)";
|
||
}
|
||
}
|
||
else {
|
||
infoTitle.innerHTML = "";
|
||
infoText.innerHTML = "";
|
||
infoSearch.style.backgroundColor = "rgb(66, 66, 66)";
|
||
}
|
||
}
|
||
function closeMenu() {
|
||
if (!showingMenu) { return; }
|
||
if (showingMenu == "info") {
|
||
var infoParent = document.getElementById("infoParent");
|
||
var infoSearch = document.getElementById("infoSearch");
|
||
infoParent.style.display = "none";
|
||
infoSearch.value = "";
|
||
showingMenu = false;
|
||
}
|
||
else if (showingMenu == "mods") {
|
||
var modParent = document.getElementById("modParent");
|
||
var modManagerUrl = document.getElementById("modManagerUrl");
|
||
modParent.style.display = "none";
|
||
modManagerUrl.value = "";
|
||
showingMenu = false;
|
||
}
|
||
else if (showingMenu == "settings") {
|
||
var settingsParent = document.getElementById("settingsParent");
|
||
settingsParent.style.display = "none";
|
||
showingMenu = false;
|
||
}
|
||
}
|
||
function showModManager() {
|
||
var modParent = document.getElementById("modParent");
|
||
var modManagerUrl = document.getElementById("modManagerUrl");
|
||
modParent.style.display = "block";
|
||
modManagerUrl.focus();
|
||
showingMenu = "mods";
|
||
}
|
||
function addMod(url) {
|
||
// remove trailing slashes
|
||
while (url.charAt(url.length-1) == "/") { url = url.substring(0, url.length-1); }
|
||
// if the mod is in enabledMods, return
|
||
for (var i = 0; i < enabledMods.length; i++) {
|
||
if (enabledMods[i] == url) { return; }
|
||
}
|
||
// if the url doesn't have a slash or a dot, alert
|
||
if (url.indexOf("/") == -1 && url.indexOf(".") == -1) {
|
||
alert("Invalid mod URL.");
|
||
return;
|
||
}
|
||
// if the url doesn't start with http, add "mods/" to the beginning
|
||
if (url.indexOf("http") == -1) { url = "mods/"+url; }
|
||
// add it to enabledMods and set the localStorage
|
||
enabledMods.push(url);
|
||
localStorage.setItem("enabledMods", JSON.stringify(enabledMods));
|
||
// add to modManagerList
|
||
var modManagerList = document.getElementById("modManagerList");
|
||
var modName = url.split("/").pop();
|
||
modManagerList.innerHTML += "<li><a href='" + url + "' target='_blank'>" + modName + "</a> <span class='removeModX' onclick='removeMod(\"" + url + "\")'>X</span></li>";
|
||
alert("Added mod. Refresh the page to see changes.");
|
||
}
|
||
function removeMod(url) {
|
||
// remove url from enabledMods and set the localStorage
|
||
for (var i = 0; i < enabledMods.length; i++) {
|
||
if (enabledMods[i] == url) {
|
||
enabledMods.splice(i, 1);
|
||
break;
|
||
}
|
||
}
|
||
localStorage.setItem("enabledMods", JSON.stringify(enabledMods));
|
||
// remove from modManagerList by href
|
||
var modManagerList = document.getElementById("modManagerList");
|
||
var modManagerListLinks = modManagerList.getElementsByTagName("a");
|
||
for (var i = 0; i < modManagerListLinks.length; i++) {
|
||
if (modManagerListLinks[i].href.endsWith(url)) {
|
||
modManagerListLinks[i].parentNode.remove();
|
||
break;
|
||
}
|
||
}
|
||
alert("Removed mod. Refresh the page to see changes.");
|
||
}
|
||
function showSettings() {
|
||
var settingsParent = document.getElementById("settingsParent");
|
||
settingsParent.style.display = "block";
|
||
showingMenu = "settings";
|
||
}
|
||
function setSetting(setting,value) {
|
||
settings[setting] = value;
|
||
saveSettings();
|
||
}
|
||
|
||
// On window load, run tick() 20 times per second
|
||
tps = 30;
|
||
tickInterval = window.setInterval(tick, 1000/tps);
|
||
function resetInterval(newtps=30) {
|
||
window.clearInterval(tickInterval);
|
||
tickInterval = window.setInterval(tick, 1000/newtps);
|
||
}
|
||
//ticks = 0;
|
||
pixelTicks = 0;
|
||
|
||
mode = null;
|
||
view = null;
|
||
paused = false;
|
||
function focusGame() { document.getElementById("game").focus(); if(showingMenu) { closeMenu(); } }
|
||
//on window load
|
||
window.onload = function() {
|
||
// If the browser is Firefox, set #categoryControls padding-bottom:11px;
|
||
if (navigator.userAgent.toLowerCase().indexOf('firefox') > -1) {
|
||
document.getElementById("categoryControls").style.paddingBottom = "11px";
|
||
}
|
||
|
||
// Loop through runAfterLoadList and run each function
|
||
for (var i = 0; i < runAfterLoadList.length; i++) {
|
||
runAfterLoadList[i]();
|
||
}
|
||
|
||
// Loop through behaviors and each behavior, if it is a string, split the items and replace the value with the array
|
||
for (var behavior in behaviors) {
|
||
if (typeof behaviors[behavior][0] === "string") {
|
||
var newbehavior = [];
|
||
for (var i = 0; i < behaviors[behavior].length; i++) {
|
||
newbehavior.push(behaviors[behavior][i].split("|"));
|
||
}
|
||
behaviors[behavior] = newbehavior;
|
||
}
|
||
}
|
||
|
||
// convert every color in the elements object to rgb
|
||
for (var key in elements) {
|
||
if (elements.hasOwnProperty(key)) {
|
||
// if the element has no color, skip it
|
||
if (elements[key].color === undefined) {
|
||
continue;
|
||
}
|
||
// if the color is an array, loop over each one
|
||
if (elements[key].color instanceof Array) {
|
||
var rgbs = [];
|
||
var rgbos = [];
|
||
for (var i = 0; i < elements[key].color.length; i++) {
|
||
var c = elements[key].color[i];
|
||
if (c.startsWith("#")) {
|
||
var rgb = hexToRGB(c);
|
||
rgbs.push("rgb("+rgb.r+","+rgb.g+","+rgb.b+")");
|
||
rgbos.push(rgb);
|
||
}
|
||
else {
|
||
rgbs.push(c);
|
||
}
|
||
}
|
||
elements[key].color = rgbs;
|
||
elements[key].colorObject = rgbos;
|
||
} else {
|
||
// if elements[key].color starts with #
|
||
if (elements[key].color.startsWith("#")) {
|
||
var rgb = hexToRGB(elements[key].color);
|
||
elements[key].color = "rgb("+rgb.r+","+rgb.g+","+rgb.b+")";
|
||
elements[key].colorObject = rgb;
|
||
}
|
||
}
|
||
}
|
||
}
|
||
|
||
// Automatic molten element generation
|
||
// Loop through each element. If it has a tempHigh, but not a stateHigh, create a new molten element
|
||
for (element in elements) {
|
||
if (elements[element].tempHigh && !elements[element].stateHigh) {
|
||
var newname = "molten_"+element;
|
||
elements[element].stateHigh = newname;
|
||
var newcolor = elements[element].colorObject;
|
||
var colorList = [];
|
||
var colorObjectList = [];
|
||
// if newcolor is not an array, put it in an array
|
||
if (!(newcolor instanceof Array)) {
|
||
newcolor = [newcolor];
|
||
}
|
||
// for every color in the newcolor array, add a new color with the same value, but with the r and g values increased
|
||
for (var i = 0; i < newcolor.length; i++) {
|
||
var c = newcolor[i];
|
||
r = c.r * 2;
|
||
g = c.g * 1.25;
|
||
b = c.b * 0.5;
|
||
if (r > 255) {r = 255;}
|
||
if (g > 255) {g = 255;}
|
||
colorList.push("rgb("+r+","+g+","+b+")");
|
||
colorObjectList.push({r:r,g:g,b:b});
|
||
|
||
r = c.r * 2;
|
||
g = c.g;
|
||
b = c.b * 0.5;
|
||
if (r > 255) {r = 255;}
|
||
if (g > 255) {g = 255;}
|
||
colorList.push("rgb("+r+","+g+","+b+")");
|
||
colorObjectList.push({r:r,g:g,b:b});
|
||
|
||
r = c.r * 2;
|
||
g = c.g * 0.75;
|
||
b = 0;
|
||
if (r > 255) {r = 255;}
|
||
if (g > 255) {g = 255;}
|
||
colorList.push("rgb("+r+","+g+","+b+")");
|
||
colorObjectList.push({r:r,g:g,b:b});
|
||
}
|
||
var newmolten = {
|
||
//"name": newname.replaceAll("_"," "),
|
||
color: colorList,
|
||
colorObject: colorObjectList,
|
||
behavior: behaviors.MOLTEN,
|
||
temp: elements[element].tempHigh,
|
||
tempLow: elements[element].tempHigh-100,
|
||
stateLow: element,
|
||
viscosity: elements[element].viscosity || 10000,
|
||
hidden: true,
|
||
state: "liquid",
|
||
category: "molten",
|
||
}
|
||
// If the element has a density, add it to the new molten element * 0.9
|
||
if (elements[element].density) { newmolten.density = Math.round(elements[element].density * 0.9 * 10) / 10; }
|
||
// If the element has a conductivity, add it to the new molten element * 1.1
|
||
if (elements[element].conduct) { newmolten.conductivity = Math.round(elements[element].conduct * 1.1 * 10) / 10; }
|
||
// Same for burn, burnTime, burnInto, and fireColor
|
||
if (elements[element].burn) { newmolten.burn = Math.round(elements[element].burn * 1.1 * 10) / 10; }
|
||
if (elements[element].burnTime) { newmolten.burnTime = Math.round(elements[element].burnTime * 1.1 * 10) / 10; }
|
||
if (elements[element].burnInto) { newmolten.burnInto = elements[element].burnInto; }
|
||
if (elements[element].fireColor) { newmolten.fireColor = elements[element].fireColor; }
|
||
// If the new element doesn't exist, add it
|
||
if (!elements[newname]) { elements[newname] = newmolten; }
|
||
else {
|
||
// Loop through newmolten's keys and values, copy them to the new element if they are not already defined
|
||
for (var key in newmolten) {
|
||
if (elements[newname][key] == undefined) {
|
||
elements[newname][key] = newmolten[key];
|
||
}
|
||
}
|
||
}
|
||
// Slag reactions
|
||
// If the element doesn't have reactions, set it to {}
|
||
if (!elements[newname].reactions) {
|
||
elements[newname].reactions = {};
|
||
}
|
||
elements[newname].reactions.ash = { "elem1":null, "elem2":"molten_slag" };
|
||
elements[newname].reactions.dust = { "elem1":null, "elem2":"molten_slag" };
|
||
if (newname != "molten_slag") {elements[newname].reactions.magma = { "elem1":null, "elem2":"molten_slag" }};
|
||
}
|
||
if (elements[element].behavior && typeof elements[element].behavior[0] === "string") {
|
||
var newbehavior = [];
|
||
for (var i = 0; i < elements[element].behavior.length; i++) {
|
||
newbehavior.push(elements[element].behavior[i].split("|"));
|
||
}
|
||
elements[element].behavior = newbehavior;
|
||
}
|
||
if (elements[element].behaviorOn && typeof elements[element].behaviorOn[0] === "string") {
|
||
var newbehavior = [];
|
||
for (var i = 0; i < elements[element].behaviorOn.length; i++) {
|
||
newbehavior.push(elements[element].behaviorOn[i].split("|"));
|
||
}
|
||
elements[element].behaviorOn = newbehavior;
|
||
}
|
||
}
|
||
|
||
// Loop through each element, final checks
|
||
for (key in elements) {
|
||
// If the element has no behavior, set it to behaviors.WALL
|
||
if (!elements[key].behavior && !elements[key].tick) {
|
||
elements[key].tick = function(pixel) {};
|
||
}
|
||
// If the element has no color, set it to white
|
||
if (elements[key].color === undefined) {
|
||
elements[key].color = "rgb(255,255,255)";
|
||
elements[key].colorObject = {r:255,g:255,b:255};
|
||
}
|
||
if (elements[key].behavior) {
|
||
// If the element's behavior[1][1] includes "FX", set it's flippableX to true
|
||
if (elements[key].behavior[1][1].includes("FX")) {
|
||
elements[key].flippableX = true;
|
||
}
|
||
// If the element's behavior[1][1] includes "FY", set it's flippableY to true
|
||
if (elements[key].behavior[1][1].includes("FY")) {
|
||
elements[key].flippableY = true;
|
||
}
|
||
|
||
// If the element's behavior stringified includes "BO", loop through the behavior
|
||
if (elements[key].behavior.toString().includes("BO") && !elements[key].rotatable) {
|
||
for (var i = 0; i < elements[key].behavior.length; i++) {
|
||
// Loop through each array in the behavior
|
||
for (var j = 0; j < elements[key].behavior[i].length; j++) {
|
||
// If the behavior includes "BO", set the behaviorOn to the behavior
|
||
if (elements[key].behavior[i][j].includes("BO")) {
|
||
if ((i==0 && j==0) || (i==0 && j==2) || (i==2 && j==0) && (i==2 && j==2)) {
|
||
elements[key].flippableX = true;
|
||
elements[key].flippableY = true;
|
||
}
|
||
else if (i==0 || i==2) {
|
||
elements[key].flippableY = true;
|
||
}
|
||
else if (j==0 || j==2) {
|
||
elements[key].flippableX = true;
|
||
}
|
||
}
|
||
}
|
||
}
|
||
}
|
||
|
||
// If the element's behavior[1][1] includes "RT", set it's rotatable to "true"
|
||
if (elements[key].behavior[1][1].includes("RT")) {
|
||
elements[key].rotatable = true;
|
||
}
|
||
}
|
||
|
||
// If the element has reactions, loop through each one (it is an object), if the value for elem1 or elem2 is not an element and is not null, remove that key
|
||
if (elements[key].reactions) {
|
||
for (var reaction in elements[key].reactions) {
|
||
// If elem1 exists
|
||
if (elements[key].reactions[reaction].elem1) {
|
||
// If elem1 is an array, loop through each element, else check once. Don't delete if it === null
|
||
if (Array.isArray(elements[key].reactions[reaction].elem1)) {
|
||
for (var i = 0; i < elements[key].reactions[reaction].elem1.length; i++) {
|
||
if (elements[key].reactions[reaction].elem1[i] && !elements[elements[key].reactions[reaction].elem1[i]]) {
|
||
elements[key].reactions[reaction].elem1.splice(i,1);
|
||
}
|
||
}
|
||
}
|
||
else if (elements[key].reactions[reaction].elem1 && !elements[elements[key].reactions[reaction].elem1]) {
|
||
delete elements[key].reactions[reaction].elem1;
|
||
}
|
||
}
|
||
// If elem2 exists
|
||
if (elements[key].reactions[reaction].elem2) {
|
||
// If elem2 is an array, loop through each element, else check once. Don't delete if it === null
|
||
if (Array.isArray(elements[key].reactions[reaction].elem2)) {
|
||
for (var i = 0; i < elements[key].reactions[reaction].elem2.length; i++) {
|
||
if (elements[key].reactions[reaction].elem2[i] && !elements[elements[key].reactions[reaction].elem2[i]]) {
|
||
elements[key].reactions[reaction].elem2.splice(i,1);
|
||
}
|
||
}
|
||
}
|
||
else if (elements[key].reactions[reaction].elem2 && !elements[elements[key].reactions[reaction].elem2]) {
|
||
delete elements[key].reactions[reaction].elem2;
|
||
}
|
||
}
|
||
}
|
||
}
|
||
|
||
// If the element's stateHigh or stateLow is not an element, remove it and tempHigh/Low
|
||
if (elements[key].stateHigh) {
|
||
// If it's an array, do it for each item, otherwise, just do it once
|
||
if (Array.isArray(elements[key].stateHigh)) {
|
||
for (var i = 0; i < elements[key].stateHigh.length; i++) {
|
||
if (!elements[elements[key].stateHigh[i]]) {
|
||
elements[key].stateHigh.splice(i,1);
|
||
}
|
||
}
|
||
if (elements[key].stateHigh.length == 0) {
|
||
delete elements[key].stateHigh;
|
||
delete elements[key].tempHigh;
|
||
}
|
||
}
|
||
else {
|
||
if (!elements[elements[key].stateHigh]) {
|
||
delete elements[key].stateHigh;
|
||
delete elements[key].tempHigh;
|
||
}
|
||
}
|
||
}
|
||
if (elements[key].stateLow) {
|
||
if (Array.isArray(elements[key].stateLow)) {
|
||
for (var i = 0; i < elements[key].stateLow.length; i++) {
|
||
if (!elements[elements[key].stateLow[i]]) {
|
||
elements[key].stateLow.splice(i,1);
|
||
}
|
||
}
|
||
if (elements[key].stateLow.length == 0) {
|
||
delete elements[key].stateLow;
|
||
delete elements[key].tempLow;
|
||
}
|
||
}
|
||
else {
|
||
if (!elements[elements[key].stateLow]) {
|
||
delete elements[key].stateLow;
|
||
delete elements[key].tempLow;
|
||
}
|
||
}
|
||
}
|
||
// same for burnInto
|
||
if (elements[key].burnInto) {
|
||
if (Array.isArray(elements[key].burnInto)) {
|
||
for (var i = 0; i < elements[key].burnInto.length; i++) {
|
||
if (!elements[elements[key].burnInto[i]]) {
|
||
delete elements[key].burnInto[i];
|
||
}
|
||
}
|
||
if (elements[key].burnInto.length == 0) {
|
||
delete elements[key].burnInto;
|
||
}
|
||
}
|
||
else {
|
||
if (!elements[elements[key].burnInto]) {
|
||
delete elements[key].burnInto;
|
||
}
|
||
}
|
||
}
|
||
|
||
|
||
}
|
||
|
||
// While the mouse is down, run mouseDown()
|
||
var gameCanvas = document.getElementById("game");
|
||
// Get context
|
||
var ctx = gameCanvas.getContext("2d");
|
||
var newWidth = Math.ceil(window.innerWidth*0.9 / pixelSize) * pixelSize;
|
||
var newHeight = Math.ceil(window.innerHeight*0.675 / pixelSize) * pixelSize;
|
||
// If the new width is greater than 800, set it to 800
|
||
if (newWidth > 1000) { newWidth = 1000; }
|
||
// If we are on a desktop and the new height is greater than 600, set it to 600
|
||
if (window.innerWidth > 1000 && newHeight > 500) { newHeight = 500; }
|
||
ctx.canvas.width = newWidth;
|
||
ctx.canvas.height = newHeight;
|
||
|
||
width = Math.round(newWidth/pixelSize)-1;
|
||
height = Math.round(newHeight/pixelSize)-1;
|
||
// Object with width arrays of pixels starting at 0
|
||
pixelMap = [];
|
||
for (var i = 0; i < width; i++) {
|
||
pixelMap[i] = [];
|
||
}
|
||
// randomChoices = the keys of "elements" with any element with the category "tools" or the property excludeRandom set to true removed
|
||
randomChoices = Object.keys(elements).filter(function(e) {
|
||
return elements[e].excludeRandom != true && elements[e].category != "tools";
|
||
});
|
||
//...drawing code...
|
||
gameCanvas.addEventListener("mousedown", mouseClick);
|
||
gameCanvas.addEventListener("touchstart", mouseClick, { passive: false });
|
||
window.addEventListener("mouseup", mouseUp);
|
||
window.addEventListener("touchend", mouseUp, { passive: false });
|
||
window.addEventListener("mousemove", mouseMove);
|
||
gameCanvas.addEventListener("touchmove", mouseMove, { passive: false });
|
||
gameCanvas.addEventListener("wheel", wheelHandle);
|
||
gameCanvas.ontouchstart = function(e) {
|
||
if (e.touches) e = e.touches[0];
|
||
return false;
|
||
}
|
||
window.onbeforeunload = function(){ // Confirm leaving page if there are pixels on-screen
|
||
if (currentPixels.length > 0){
|
||
return 'Are you sure you want to leave?';
|
||
}
|
||
};
|
||
// If enabledMods has items, add an li to modManagerList for each item with the href to the item, target blank, and the item's name, with "<span class="removeModX" onclick='removeMod('>X</span>" after the link
|
||
if (enabledMods.length > 0) {
|
||
modManagerList = document.getElementById("modManagerList");
|
||
for (var i = 0; i < enabledMods.length; i++) {
|
||
var mod = enabledMods[i];
|
||
// modName is the last part of the mod's path
|
||
var modName = mod.split("/").pop();
|
||
modManagerList.innerHTML += "<li><a href='" + mod + "' target='_blank'>" + modName + "</a> <span class='removeModX' onclick='removeMod(\"" + mod + "\")'>X</span></li>";
|
||
}
|
||
}
|
||
shiftDown = 0;
|
||
// If the user presses [ or -, decrease the mouse size by 2
|
||
document.addEventListener("keydown", function(e) {
|
||
if (e.ctrlKey || e.metaKey) {
|
||
return
|
||
}
|
||
// else if tab, set document.body.class to "usingTab"
|
||
else if (e.keyCode == 9) {
|
||
document.body.classList.add("usingTab");
|
||
}
|
||
// F1 = hide #underDiv, #infoParent, #modParent, #pagetitle if they aren't hidden, otherwise show them
|
||
if (e.keyCode == 112) {
|
||
e.preventDefault();
|
||
if (document.getElementById("underDiv").style.display == "none") {
|
||
document.getElementById("underDiv").style.display = "block";
|
||
document.getElementById("pagetitle").style.display = "block";
|
||
} else {
|
||
document.getElementById("underDiv").style.display = "none";
|
||
if (showingMenu) {
|
||
closeMenu()
|
||
};
|
||
document.getElementById("pagetitle").style.display = "none";
|
||
}
|
||
}
|
||
if (showingMenu) {
|
||
// esc or / or tab / or \ (while in settings) to close
|
||
if (e.keyCode == 27 || (e.keyCode == 191 && showingMenu=="info") || e.keyCode == 9 || (e.keyCode == 220 && showingMenu=="settings")) {
|
||
e.preventDefault();
|
||
closeMenu();
|
||
}
|
||
// enter to clear infoSearch
|
||
else if (e.keyCode == 13 && showingMenu == "info") {
|
||
var infoSearch = document.getElementById("infoSearch");
|
||
infoSearch.value = "";
|
||
showInfo();
|
||
}
|
||
return;
|
||
}
|
||
if (e.keyCode == 219 || e.keyCode == 189) {
|
||
if (shiftDown) {mouseSize = 1}
|
||
else {
|
||
mouseSize -= 2;
|
||
if (mouseSize < 1) { mouseSize = 1; }
|
||
}
|
||
}
|
||
// If the user presses ] or =, increase the mouse size by 2
|
||
if (e.keyCode == 221 || e.keyCode == 187) {
|
||
if (shiftDown) {mouseSize = (mouseSize+15)-((mouseSize+15) % 15)}
|
||
else {mouseSize += 2;}
|
||
// if height>width and mouseSize>height, set mouseSize to height, if width>height and mouseSize>width, set mouseSize to width
|
||
if (mouseSize > (height > width ? height : width)) { mouseSize = (height > width ? height : width); }
|
||
}
|
||
// User presses shift
|
||
else if (e.keyCode == 16) {
|
||
if (event.location === KeyboardEvent.DOM_KEY_LOCATION_LEFT) {
|
||
shiftDown = 1;
|
||
} else if (event.location === KeyboardEvent.DOM_KEY_LOCATION_RIGHT) {
|
||
shiftDown = 3;
|
||
}
|
||
}
|
||
// User presses alt
|
||
else if (e.keyCode == 18) {
|
||
if (event.location === KeyboardEvent.DOM_KEY_LOCATION_LEFT) {
|
||
shiftDown = 2;
|
||
} else if (event.location === KeyboardEvent.DOM_KEY_LOCATION_RIGHT) {
|
||
shiftDown = 4;
|
||
}
|
||
}
|
||
// p or spacebar or ` or k = pause
|
||
if (e.keyCode == 80 || e.keyCode == 32 || e.keyCode == 192 || e.keyCode == 75) {
|
||
e.preventDefault();
|
||
togglePause();
|
||
}
|
||
// e = chooseElementPrompt()
|
||
else if (e.keyCode == 69) {
|
||
e.preventDefault();
|
||
chooseElementPrompt();
|
||
}
|
||
// . = doFrame()
|
||
else if (e.keyCode == 190) {
|
||
e.preventDefault();
|
||
doFrame();
|
||
}
|
||
// / or i = showInfo()
|
||
else if (e.keyCode == 191 || e.keyCode == 73) {
|
||
e.preventDefault();
|
||
showInfo();
|
||
}
|
||
// f = full screen
|
||
else if (e.keyCode == 70) {
|
||
e.preventDefault();
|
||
if (document.fullscreenElement) {
|
||
document.exitFullscreen(document.body);
|
||
} else {
|
||
requestFullScreen(document.body);
|
||
}
|
||
}
|
||
// 0-9 = setView(the number)
|
||
else if (e.keyCode >= 48 && e.keyCode <= 57) {
|
||
// if not command or control down, set view to the number
|
||
e.preventDefault();
|
||
setView(e.keyCode-48);
|
||
}
|
||
// right arrow = switch the category to the one after the current category
|
||
else if (e.keyCode == 39) {
|
||
e.preventDefault();
|
||
// in categoryControls, find the button with the class categoryButton and the attribute current="true"
|
||
var currentButton = document.querySelector(".categoryButton[current='true']");
|
||
var currentCategory = currentButton.getAttribute("category");
|
||
// get the categoryButton that is after the current one in the div
|
||
var nextButton = currentButton.nextElementSibling;
|
||
// if there is no next button, go to the first one
|
||
if (nextButton == null) {
|
||
nextButton = document.querySelector(".categoryButton");
|
||
}
|
||
var nextCategory = nextButton.getAttribute("category");
|
||
selectCategory(nextCategory);
|
||
// focus on categoryControls
|
||
document.getElementById("categoryControls").focus();
|
||
}
|
||
// left arrow = switch the category to the one before the current category
|
||
else if (e.keyCode == 37) {
|
||
e.preventDefault();
|
||
// in categoryControls, find the button with the class categoryButton and the attribute current="true"
|
||
var currentButton = document.querySelector(".categoryButton[current='true']");
|
||
var currentCategory = currentButton.getAttribute("category");
|
||
// get the categoryButton that is before the current one in the div
|
||
var prevButton = currentButton.previousElementSibling;
|
||
// if there is no previous button, go to the last one
|
||
if (prevButton == null) {
|
||
prevButton = document.querySelector(".categoryButton:last-child");
|
||
}
|
||
var prevCategory = prevButton.getAttribute("category");
|
||
selectCategory(prevCategory);
|
||
}
|
||
// m = closeMenu() and showModManager()
|
||
else if (e.keyCode == 77) {
|
||
e.preventDefault();
|
||
closeMenu();
|
||
showModManager();
|
||
}
|
||
// \ = closeMenu() and showSettings()
|
||
else if (e.keyCode == 220) {
|
||
e.preventDefault();
|
||
closeMenu();
|
||
showSettings();
|
||
}
|
||
// c or F2 = screenshot
|
||
else if (e.keyCode == 67 || e.keyCode == 113) {
|
||
e.preventDefault();
|
||
var link = document.createElement('a');
|
||
link.setAttribute('download', 'sandboxels-screenshot.png');
|
||
link.setAttribute('href', document.getElementById("game").toDataURL("image/png").replace("image/png", "image/octet-stream"));
|
||
document.body.appendChild(link);
|
||
link.click();
|
||
document.body.removeChild(link);
|
||
}
|
||
|
||
|
||
// x = explodeAt()
|
||
/*else if (e.keyCode == 88) {
|
||
e.preventDefault();
|
||
explodeAt(mousePos.x, mousePos.y, Math.round(mouseSize/2));
|
||
}*/
|
||
|
||
});
|
||
// If the user releases either shift
|
||
document.addEventListener("keyup", function(e) {
|
||
if (e.keyCode == 16 || e.keyCode == 18) { shiftDown = 0; }
|
||
});
|
||
|
||
// Create buttons for elements
|
||
// For each element type in elements, create a button in controls that sets the current element to that type
|
||
// Alphabetically sort and loop through dictionary named "elements"
|
||
elementCount = 0;
|
||
hiddenCount = 0;
|
||
for (var element in elements) {
|
||
elementCount++;
|
||
if (elements[element].hidden && !settings["unhide"]) { hiddenCount++; continue; }
|
||
var category = elements[element].category;
|
||
if (category==null) {category="Other"}
|
||
var categoryDiv = document.getElementById("category-"+category);
|
||
if (categoryDiv == null) {
|
||
categoryButton = document.createElement("button");
|
||
categoryButton.id = "categoryButton-"+category;
|
||
categoryButton.innerHTML = category.replace("."," ").replace(/\w\S*/g, function(txt){return txt.charAt(0).toUpperCase() + txt.substr(1).toLowerCase();}).replace(" ",".").replace(/ /g, "");;
|
||
categoryButton.className = "categoryButton";
|
||
categoryButton.setAttribute("category",category);
|
||
categoryButton.onclick = function() {
|
||
selectCategory(this.getAttribute("category"));
|
||
}
|
||
document.getElementById("categoryControls").appendChild(categoryButton);
|
||
categoryDiv = document.createElement("div");
|
||
//categoryDiv.innerHTML = "<span class='categoryName'>"+category+"</span>";
|
||
categoryDiv.setAttribute("id","category-"+category);
|
||
categoryDiv.setAttribute("category",category);
|
||
categoryDiv.setAttribute("class","category");
|
||
document.getElementById("elementControls").appendChild(categoryDiv);
|
||
}
|
||
var button = document.createElement("button");
|
||
// if the element has the attribute "name", use that as the button's text, otherwise use the element with underscores replaced by spaces
|
||
if (elements[element].name) {
|
||
button.innerHTML = elements[element].name;
|
||
}
|
||
else {
|
||
button.innerHTML = element.replace(/_/g, " ");
|
||
}
|
||
//capitalize first letter of each word
|
||
button.innerHTML = button.innerHTML.replace("."," ").replace(/\w\S*/g, function(txt){return txt.charAt(0).toUpperCase() + txt.substr(1).toLowerCase();}).replace(" ",".").replace(/ /g, "");
|
||
//set attribute of element to the element
|
||
button.setAttribute("element", element);
|
||
button.setAttribute("current", "false");
|
||
button.className = "elementButton";
|
||
//color of the element
|
||
// if the element color is an array, make a gradient background color, otherwise, set the background color to the element color
|
||
if (elements[element].color instanceof Array) {
|
||
button.style.backgroundImage = "linear-gradient(to bottom right, "+elements[element].color.join(", ")+")";
|
||
// choose the middlemost item in array
|
||
var colorObject = elements[element].colorObject[Math.floor(elements[element].colorObject.length/2)];
|
||
if ((colorObject.r+colorObject.g+colorObject.b)/3 > 200) {
|
||
button.className += " bright"
|
||
}
|
||
}
|
||
else {
|
||
button.style.background = elements[element].color;
|
||
var colorObject = elements[element].colorObject;
|
||
if ((colorObject.r+colorObject.g+colorObject.b)/3 > 200) {
|
||
button.className += " bright"
|
||
}
|
||
}
|
||
button.id = "elementButton-" + element;
|
||
button.onclick = function() {
|
||
selectElement(this.getAttribute("element"));
|
||
}
|
||
// on right click, show the element's info
|
||
button.oncontextmenu = function(e) {
|
||
e.preventDefault();
|
||
closeMenu();
|
||
showInfo(this.getAttribute("element"));
|
||
}
|
||
categoryDiv.appendChild(button);
|
||
}
|
||
// Set the first button in categoryControls div to be the current category
|
||
document.getElementById("categoryControls").children[0].click()
|
||
document.getElementById("extraInfo").innerHTML += "<p><small>There are " + elementCount + " elements, including " + hiddenCount + " hidden ones.</small></p>";
|
||
selectElement(currentElement);
|
||
focusGame();
|
||
// For every button element, onkeyup="event.preventDefault()"
|
||
var buttonElements = document.getElementsByTagName("button");
|
||
for (var i = 0; i < buttonElements.length; i++) {
|
||
buttonElements[i].onkeyup = function(e) {
|
||
e.preventDefault();
|
||
}
|
||
}
|
||
|
||
}
|
||
</script>
|
||
</head>
|
||
|
||
<body>
|
||
<h1 class="pagetitle" id="pagetitle"><a href="https://R74n.com" class="backbutton" target="_blank"><</a></h1>
|
||
<div id="gameDiv">
|
||
<canvas id="game" width="800" height="600" oncontextmenu="return false;">
|
||
Your browser does not support the HTML5 canvas tag.<br>
|
||
Please update your browser to the latest version.<br>
|
||
<a href="https://www.google.com/chrome/" tabindex="-1">Chrome</a> 4.0+<br>
|
||
<a href="https://www.mozilla.org/firefox/new/" tabindex="-1">Firefox</a> 2.0+<br>
|
||
<a href="http://www.apple.com/safari/" tabindex="-1">Safari</a> 3.1+<br><br>
|
||
<a href="http://www.opera.com/" tabindex="-1">Opera</a> 9.0+<br>
|
||
<a href="http://www.microsoft.com/windows/internet-explorer/default.aspx" tabindex="-1">Internet Explorer</a> 9.0+<br>
|
||
</canvas>
|
||
<div id="underDiv">
|
||
<div id="stats"></div>
|
||
<div id="controls">
|
||
<div id="toolControls">
|
||
<button id="pauseButton" title="Pause/play the simulation" class="controlButton" onclick='togglePause();focusGame();' on="false">Pause</button><button id="frameButton" title="Pause and play one frame" class="controlButton" onclick='doFrame();focusGame();' on="false">Step</button><button id="sizeDownButton" title="Decrease the brush size" class="controlButton" onclick="mouseSize -= 2;if (mouseSize < 1) { mouseSize = 1; };focusGame();">-</button><button id="sizeUpButton" title="Increase the brush size" class="controlButton" onclick="mouseSize += 2;if (mouseSize > (height > width ? height : width)) { mouseSize = (height > width ? height : width); };focusGame();">+</button><button id="resetButton" title="Clear the entire scene" class="controlButton" onclick="if (confirm('Are you sure you want to clear the whole scene?')) {clearAll();};focusGame();">Reset</button><button id="replaceButton" title="Override existing pixels when placing" class="controlButton" onclick='if (mode == "replace") {mode = null;this.setAttribute("on","false");}else {mode = "replace";this.setAttribute("on","true");};focusGame();' on="false">Replace</button><button id="elemSelectButton" title="Select an element by ID" class="controlButton" onclick='chooseElementPrompt();focusGame();'>E</button><button id="tpsButton" title="Change the simulation Ticks Per Second (TPS)" class="controlButton" onclick='var newtps = prompt("Enter the new simulation Ticks Per Second (TPS). This is how many updates per second the simulation will run.\n\nThe default is 30.\n\nThe current TPS is " + tps + ".");if (newtps !== null) {if (isNaN(newtps) || newtps == "" || newtps == "0") {alert("You did not enter a valid TPS.");}else if (newtps > 1000) {alert("You entered a TPS that is too high. The TPS will be set to the maximum, 1000.");tps = 1000;}else {tps = parseInt(newtps);if (isNaN(tps)) {alert("You did not enter a valid TPS.");tps = 30;}}resetInterval(tps);}focusGame();'>Tps</button><!--<button id="hideButton" title="Stops updating the scene to allow more resources towards simulation" class="controlButton" onclick='if (hiding) {hiding = false;this.setAttribute("on","false");}else {hiding = true;this.setAttribute("on","true");};focusGame();' on="false">Hide</button>--><button id="infoButton" title="Brings up the element info screen" class="controlButton" onclick='if (showingMenu!="info"){closeMenu();showInfo(currentElement)}else{closeMenu()};' on="false">Info</button><button id="modsButton" title="Brings up the Mod Manager" class="controlButton" onclick='if (showingMenu!="mods"){closeMenu();showModManager()}else{closeMenu()};' on="false">Mods</button><button id="settingsButton" title="Brings up the settings screen" class="controlButton" onclick='if (showingMenu!="settings"){closeMenu();showSettings()}else{closeMenu()};' on="false">Settings</button>
|
||
</div>
|
||
<div id="category-tools" category="tools" style="display: block;"></div>
|
||
<div id="categoryControls"></div>
|
||
<div id="elementControls"></div>
|
||
</div>
|
||
<div id="extraInfo"><small><a href="controls.txt" target="_blank">Controls</a> • <a href="changelog.txt" target="_blank">Changelog</a> • <a href="https://docs.google.com/document/d/1R8xljj_J-K5oU-9y4louwplQmM-ZBvUfXmhbgj5LYdk/edit?usp=sharing" target="_blank">Feedback</a></small></div>
|
||
</div>
|
||
</div>
|
||
|
||
<div id="infoParent">
|
||
<div id="infoScreen"> <!--Element Info Page-->
|
||
<button class="XButton" onclick="closeMenu();">-</button>
|
||
<span class="menuTitle" id="infoTitle">Title</span>
|
||
<div class="menuText" id="infoText">Text</div>
|
||
</div>
|
||
<input type="text" id="infoSearch" placeholder="Element..." oninput="showInfo(this.value);"></input>
|
||
</div>
|
||
|
||
<!--Mod Manager Page with the list of current mods and a url input box with a plus button to add it-->
|
||
<div id="modParent">
|
||
<div id="modManager">
|
||
<button class="XButton" onclick="closeMenu();">-</button>
|
||
<span class="menuTitle">Enabled Mods</span>
|
||
<ul class="menuText" id="modManagerList"></ul>
|
||
<br><br><br><br>
|
||
<!--If the key is Enter, addMod -->
|
||
</div>
|
||
<input type="text" id="modManagerUrl" placeholder=".JS URL..." onkeydown="if (event.keyCode == 13) {addMod(this.value);this.value = '';};this.focus();"></input>
|
||
<!-- <button id="modManagerAdd" onclick="addMod(document.getElementById('modManagerUrl').value); document.getElementById('modManagerUrl').value = '';">+</button> -->
|
||
</div>
|
||
|
||
<!--Settings Menu-->
|
||
<div id="settingsParent">
|
||
<div id="settingsMenu">
|
||
<button class="XButton" onclick="closeMenu();">-</button>
|
||
<span class="menuTitle">Settings</span>
|
||
<div class="menuText" style="padding-top:1em">
|
||
<span setting="units" style="display:block;padding-bottom:0.5em" class="setting-span">
|
||
Units <select onchange="setSetting('units',this.value);">
|
||
<option value="m" selected>Metric</option>
|
||
<option value="i">Imperial</option>
|
||
<option value="s">SI</option>
|
||
</select>
|
||
</span>
|
||
<span setting="unhide" style="display:block;padding-bottom:0.5em" class="setting-span">
|
||
Hiding <select onchange="setSetting('unhide',parseInt(this.value));this.nextElementSibling.innerText='Refresh.'">
|
||
<option value="0" selected>Hide Some Elements</option>
|
||
<option value="1">Unhide All Elements</option>
|
||
</select>
|
||
<a onclick="window.location.reload();" style="font-style:italic;cursor:pointer"></a>
|
||
</span>
|
||
<span setting="bg" style="display:block;padding-bottom:0.5em" class="setting-span">
|
||
Background <input onchange="setSetting('bg',this.value);" type="color" value="#000000">
|
||
</span>
|
||
</div>
|
||
<br><br><br><br>
|
||
</div>
|
||
</div>
|
||
|
||
<!-- i like having this but ublock blocks these things anyway -->
|
||
<!-- Global site tag (gtag.js) - Google Analytics -->
|
||
<script async src="https://www.googletagmanager.com/gtag/js?id=G-T6E9BCPM32"></script>
|
||
<script>
|
||
window.dataLayer = window.dataLayer || [];
|
||
function gtag(){dataLayer.push(arguments);}
|
||
gtag('js', new Date());
|
||
|
||
gtag('config', 'G-T6E9BCPM32');
|
||
</script>
|
||
|
||
</body>
|
||
|
||
</html>
|