From 49dafbfd263957631116557ac4fa59429390ebaa Mon Sep 17 00:00:00 2001 From: Simon Robertshaw Date: Tue, 5 Jun 2012 20:08:35 +0100 Subject: Use a different method for decoding saves with uncompressed object in memory for stamps and clipboard, also allows for transformation (rotation), missing failure states and code for loading it into a Simulation diff --git a/src/cat/LuaScriptInterface.cpp b/src/cat/LuaScriptInterface.cpp index 4f36291..cd29ba8 100644 --- a/src/cat/LuaScriptInterface.cpp +++ b/src/cat/LuaScriptInterface.cpp @@ -436,28 +436,28 @@ int luacon_transition_getproperty(char * key, int * format) { int offset; if (strcmp(key, "presHighValue")==0){ - offset = offsetof(part_transition, phv); + offset = offsetof(Element, HighPressure); *format = 1; } else if (strcmp(key, "presHighType")==0){ - offset = offsetof(part_transition, pht); + offset = offsetof(Element, HighPressureTransition); *format = 0; } else if (strcmp(key, "presLowValue")==0){ - offset = offsetof(part_transition, plv); + offset = offsetof(Element, LowPressure); *format = 1; } else if (strcmp(key, "presLowType")==0){ - offset = offsetof(part_transition, plt); + offset = offsetof(Element, LowPressureTransition); *format = 0; } else if (strcmp(key, "tempHighValue")==0){ - offset = offsetof(part_transition, thv); + offset = offsetof(Element, HighTemperature); *format = 1; } else if (strcmp(key, "tempHighType")==0){ - offset = offsetof(part_transition, tht); + offset = offsetof(Element, HighTemperatureTransition); *format = 0; } else if (strcmp(key, "tempLowValue")==0){ - offset = offsetof(part_transition, tlv); + offset = offsetof(Element, LowTemperature); *format = 1; } else if (strcmp(key, "tempLowType")==0){ - offset = offsetof(part_transition, tlt); + offset = offsetof(Element, LowTemperatureTransition); *format = 0; } else { offset = -1; @@ -534,115 +534,115 @@ int luacon_element_getproperty(char * key, int * format, unsigned int * modified { int offset; if (strcmp(key, "name")==0){ - offset = offsetof(part_type, name); + offset = offsetof(Element, Name); *format = 2; } else if (strcmp(key, "color")==0){ - offset = offsetof(part_type, pcolors); + offset = offsetof(Element, Colour); *format = 0; if (modified_stuff) *modified_stuff |= LUACON_EL_MODIFIED_GRAPHICS; } else if (strcmp(key, "colour")==0){ - offset = offsetof(part_type, pcolors); + offset = offsetof(Element, Colour); *format = 0; if (modified_stuff) *modified_stuff |= LUACON_EL_MODIFIED_GRAPHICS; } else if (strcmp(key, "advection")==0){ - offset = offsetof(part_type, advection); + offset = offsetof(Element, Advection); *format = 1; } else if (strcmp(key, "airdrag")==0){ - offset = offsetof(part_type, airdrag); + offset = offsetof(Element, AirDrag); *format = 1; } else if (strcmp(key, "airloss")==0){ - offset = offsetof(part_type, airloss); + offset = offsetof(Element, AirLoss); *format = 1; } else if (strcmp(key, "loss")==0){ - offset = offsetof(part_type, loss); + offset = offsetof(Element, Loss); *format = 1; } else if (strcmp(key, "collision")==0){ - offset = offsetof(part_type, collision); + offset = offsetof(Element, Collision); *format = 1; } else if (strcmp(key, "gravity")==0){ - offset = offsetof(part_type, gravity); + offset = offsetof(Element, Gravity); *format = 1; } else if (strcmp(key, "diffusion")==0){ - offset = offsetof(part_type, diffusion); + offset = offsetof(Element, Diffusion); *format = 1; } else if (strcmp(key, "hotair")==0){ - offset = offsetof(part_type, hotair); + offset = offsetof(Element, HotAir); *format = 1; } else if (strcmp(key, "falldown")==0){ - offset = offsetof(part_type, falldown); + offset = offsetof(Element, Falldown); *format = 0; } else if (strcmp(key, "flammable")==0){ - offset = offsetof(part_type, flammable); + offset = offsetof(Element, Flammable); *format = 0; } else if (strcmp(key, "explosive")==0){ - offset = offsetof(part_type, explosive); + offset = offsetof(Element, Explosive); *format = 0; } else if (strcmp(key, "meltable")==0){ - offset = offsetof(part_type, meltable); + offset = offsetof(Element, Meltable); *format = 0; } else if (strcmp(key, "hardness")==0){ - offset = offsetof(part_type, hardness); + offset = offsetof(Element, Hardness); *format = 0; } else if (strcmp(key, "menu")==0){ - offset = offsetof(part_type, menu); + offset = offsetof(Element, MenuVisible); *format = 0; if (modified_stuff) *modified_stuff |= LUACON_EL_MODIFIED_MENUS; } else if (strcmp(key, "enabled")==0){ - offset = offsetof(part_type, enabled); + offset = offsetof(Element, Enabled); *format = 0; } else if (strcmp(key, "weight")==0){ - offset = offsetof(part_type, weight); + offset = offsetof(Element, Weight); *format = 0; if (modified_stuff) *modified_stuff |= LUACON_EL_MODIFIED_CANMOVE; } else if (strcmp(key, "menusection")==0){ - offset = offsetof(part_type, menusection); + offset = offsetof(Element, MenuSection); *format = 0; if (modified_stuff) *modified_stuff |= LUACON_EL_MODIFIED_MENUS; } else if (strcmp(key, "heat")==0){ - offset = offsetof(part_type, heat); + offset = offsetof(Element, Temperature); *format = 1; } else if (strcmp(key, "hconduct")==0){ - offset = offsetof(part_type, hconduct); + offset = offsetof(Element, HeatConduct); *format = 3; } else if (strcmp(key, "state")==0){ - offset = offsetof(part_type, state); + offset = offsetof(Element, State); *format = 3; } else if (strcmp(key, "properties")==0){ - offset = offsetof(part_type, properties); + offset = offsetof(Element, Properties); *format = 0; if (modified_stuff) *modified_stuff |= LUACON_EL_MODIFIED_GRAPHICS | LUACON_EL_MODIFIED_CANMOVE; } else if (strcmp(key, "description")==0){ - offset = offsetof(part_type, descs); + offset = offsetof(Element, Description); *format = 2; } else { diff --git a/src/client/GameSave.cpp b/src/client/GameSave.cpp new file mode 100644 index 0000000..d2b163e --- /dev/null +++ b/src/client/GameSave.cpp @@ -0,0 +1,1477 @@ +// +// GameSave.cpp +// The Powder Toy +// +// Created by Simon Robertshaw on 04/06/2012. +// Copyright (c) 2012 __MyCompanyName__. All rights reserved. +// + +#include +#include +#include "Config.h" +#include "bson/BSON.h" +#include "GameSave.h" +#include "SimulationData.h" + + +GameSave::GameSave(GameSave & save) : +waterEEnabled(save.waterEEnabled), +legacyEnable(save.legacyEnable), +gravityEnable(save.gravityEnable), +paused(save.paused), +gravityMode(save.gravityMode), +airMode(save.airMode), +signs(save.signs) +{ + setSize(save.width, save.height); + + copy(save.particles, save.particles+NPART, particles); + copy(save.blockMapPtr, save.blockMapPtr+((height/CELL)*(width/CELL)), blockMapPtr); + copy(save.fanVelXPtr, save.fanVelXPtr+((height/CELL)*(width/CELL)), fanVelXPtr); + copy(save.fanVelYPtr, save.fanVelYPtr+((height/CELL)*(width/CELL)), fanVelYPtr); +} + +GameSave::GameSave(int width, int height) +{ + setSize(width, height); +} + +GameSave::GameSave(char * data, int dataSize) +{ + std::cout << readPSv(data, dataSize) << std::endl; +} + +void GameSave::setSize(int newWidth, int newHeight) +{ + this->width = (newWidth/CELL)*CELL; + this->height = (newHeight/CELL)*CELL; + + particles = new Particle[NPART]; + blockMap = new char*[height/CELL]; + blockMapPtr = new char[(height/CELL)*(width/CELL)]; + fill(blockMapPtr, blockMapPtr+((height/CELL)*(width/CELL)), 0); + for(int y = 0; y < height/CELL; y++) + blockMap[y] = &blockMapPtr[y*(width/CELL)]; + fanVelXPtr = new float[(height/CELL)*(width/CELL)]; + fill(fanVelXPtr, fanVelXPtr+((height/CELL)*(width/CELL)), 0); + fanVelX = new float*[height/CELL]; + for(int y = 0; y < height/CELL; y++) + fanVelX[y] = &fanVelXPtr[y*(width/CELL)]; + fanVelYPtr = new float[(height/CELL)*(width/CELL)]; + fill(fanVelYPtr, fanVelYPtr+((height/CELL)*(width/CELL)), 0); + fanVelY = new float*[height/CELL]; + for(int y = 0; y < height/CELL; y++) + fanVelY[y] = &fanVelYPtr[y*(width/CELL)]; +} + +char * GameSave::Serialise(int & dataSize) +{ + return serialiseOPS(dataSize); +} + +void GameSave::Transform(matrix2d transform, vector2d translate) +{ + +} + +GameSave::ParseResult GameSave::readOPS(char * data, int dataLength) +{ + unsigned char * inputData = (unsigned char *)data, *bsonData = NULL, *partsData = NULL, *partsPosData = NULL, *fanData = NULL, *wallData = NULL; + unsigned int inputDataLen = dataLength, bsonDataLen = 0, partsDataLen, partsPosDataLen, fanDataLen, wallDataLen; + int i, freeIndicesCount, x, y, j; + ParseResult returnCode = OK; + int *freeIndices = NULL; + int blockX, blockY, blockW, blockH, fullX, fullY, fullW, fullH; + bson b; + bson_iterator iter; + + //Block sizes + blockX = 0; + blockY = 0; + blockW = inputData[6]; + blockH = inputData[7]; + + //Full size, normalised + fullX = blockX*CELL; + fullY = blockY*CELL; + fullW = blockW*CELL; + fullH = blockH*CELL; + + //From newer version + if(inputData[4] > SAVE_VERSION) + { + fprintf(stderr, "Save from newer version\n"); + return WrongVersion; + } + + //Incompatible cell size + if(inputData[5] > CELL) + { + fprintf(stderr, "Cell size mismatch\n"); + return InvalidDimensions; + } + + //Too large/off screen + if(blockX+blockW > XRES/CELL || blockY+blockH > YRES/CELL) + { + fprintf(stderr, "Save too large\n"); + return InvalidDimensions; + } + + setSize(fullW, fullH); + + bsonDataLen = ((unsigned)inputData[8]); + bsonDataLen |= ((unsigned)inputData[9]) << 8; + bsonDataLen |= ((unsigned)inputData[10]) << 16; + bsonDataLen |= ((unsigned)inputData[11]) << 24; + + bsonData = (unsigned char*)malloc(bsonDataLen+1); + if(!bsonData) + { + fprintf(stderr, "Internal error while parsing save: could not allocate buffer\n"); + return InternalError; + } + //Make sure bsonData is null terminated, since all string functions need null terminated strings + //(bson_iterator_key returns a pointer into bsonData, which is then used with strcmp) + bsonData[bsonDataLen] = 0; + + if (BZ2_bzBuffToBuffDecompress((char*)bsonData, &bsonDataLen, (char*)(inputData+12), inputDataLen-12, 0, 0)) + { + fprintf(stderr, "Unable to decompress\n"); + return Corrupt; + } + + bson_init_data(&b, (char*)bsonData); + bson_iterator_init(&iter, &b); + + std::vector tempSigns; + + while(bson_iterator_next(&iter)) + { + if(strcmp(bson_iterator_key(&iter), "signs")==0) + { + if(bson_iterator_type(&iter)==BSON_ARRAY) + { + bson_iterator subiter; + bson_iterator_subiterator(&iter, &subiter); + while(bson_iterator_next(&subiter)) + { + if(strcmp(bson_iterator_key(&subiter), "sign")==0) + { + if(bson_iterator_type(&subiter)==BSON_OBJECT) + { + bson_iterator signiter; + bson_iterator_subiterator(&subiter, &signiter); + + sign tempSign("", 0, 0, sign::Left); + while(bson_iterator_next(&signiter)) + { + if(strcmp(bson_iterator_key(&signiter), "text")==0 && bson_iterator_type(&signiter)==BSON_STRING) + { + tempSign.text = bson_iterator_string(&signiter); + clean_text((char*)tempSign.text.c_str(), 158-14); + } + else if(strcmp(bson_iterator_key(&signiter), "justification")==0 && bson_iterator_type(&signiter)==BSON_INT) + { + tempSign.ju = (sign::Justification)bson_iterator_int(&signiter); + } + else if(strcmp(bson_iterator_key(&signiter), "x")==0 && bson_iterator_type(&signiter)==BSON_INT) + { + tempSign.x = bson_iterator_int(&signiter)+fullX; + } + else if(strcmp(bson_iterator_key(&signiter), "y")==0 && bson_iterator_type(&signiter)==BSON_INT) + { + tempSign.y = bson_iterator_int(&signiter)+fullY; + } + else + { + fprintf(stderr, "Unknown sign property %s\n", bson_iterator_key(&signiter)); + } + } + tempSigns.push_back(tempSign); + } + else + { + fprintf(stderr, "Wrong type for %s\n", bson_iterator_key(&subiter)); + } + } + } + } + else + { + fprintf(stderr, "Wrong type for %s\n", bson_iterator_key(&iter)); + } + } + else if(strcmp(bson_iterator_key(&iter), "parts")==0) + { + if(bson_iterator_type(&iter)==BSON_BINDATA && ((unsigned char)bson_iterator_bin_type(&iter))==BSON_BIN_USER && (partsDataLen = bson_iterator_bin_len(&iter)) > 0) + { + partsData = (unsigned char*)bson_iterator_bin_data(&iter); + } + else + { + fprintf(stderr, "Invalid datatype of particle data: %d[%d] %d[%d] %d[%d]\n", bson_iterator_type(&iter), bson_iterator_type(&iter)==BSON_BINDATA, (unsigned char)bson_iterator_bin_type(&iter), ((unsigned char)bson_iterator_bin_type(&iter))==BSON_BIN_USER, bson_iterator_bin_len(&iter), bson_iterator_bin_len(&iter)>0); + } + } + if(strcmp(bson_iterator_key(&iter), "partsPos")==0) + { + if(bson_iterator_type(&iter)==BSON_BINDATA && ((unsigned char)bson_iterator_bin_type(&iter))==BSON_BIN_USER && (partsPosDataLen = bson_iterator_bin_len(&iter)) > 0) + { + partsPosData = (unsigned char*)bson_iterator_bin_data(&iter); + } + else + { + fprintf(stderr, "Invalid datatype of particle position data: %d[%d] %d[%d] %d[%d]\n", bson_iterator_type(&iter), bson_iterator_type(&iter)==BSON_BINDATA, (unsigned char)bson_iterator_bin_type(&iter), ((unsigned char)bson_iterator_bin_type(&iter))==BSON_BIN_USER, bson_iterator_bin_len(&iter), bson_iterator_bin_len(&iter)>0); + } + } + else if(strcmp(bson_iterator_key(&iter), "wallMap")==0) + { + if(bson_iterator_type(&iter)==BSON_BINDATA && ((unsigned char)bson_iterator_bin_type(&iter))==BSON_BIN_USER && (wallDataLen = bson_iterator_bin_len(&iter)) > 0) + { + wallData = (unsigned char*)bson_iterator_bin_data(&iter); + } + else + { + fprintf(stderr, "Invalid datatype of wall data: %d[%d] %d[%d] %d[%d]\n", bson_iterator_type(&iter), bson_iterator_type(&iter)==BSON_BINDATA, (unsigned char)bson_iterator_bin_type(&iter), ((unsigned char)bson_iterator_bin_type(&iter))==BSON_BIN_USER, bson_iterator_bin_len(&iter), bson_iterator_bin_len(&iter)>0); + } + } + else if(strcmp(bson_iterator_key(&iter), "fanMap")==0) + { + if(bson_iterator_type(&iter)==BSON_BINDATA && ((unsigned char)bson_iterator_bin_type(&iter))==BSON_BIN_USER && (fanDataLen = bson_iterator_bin_len(&iter)) > 0) + { + fanData = (unsigned char*)bson_iterator_bin_data(&iter); + } + else + { + fprintf(stderr, "Invalid datatype of fan data: %d[%d] %d[%d] %d[%d]\n", bson_iterator_type(&iter), bson_iterator_type(&iter)==BSON_BINDATA, (unsigned char)bson_iterator_bin_type(&iter), ((unsigned char)bson_iterator_bin_type(&iter))==BSON_BIN_USER, bson_iterator_bin_len(&iter), bson_iterator_bin_len(&iter)>0); + } + } + else if(strcmp(bson_iterator_key(&iter), "legacyEnable")==0) + { + if(bson_iterator_type(&iter)==BSON_BOOL) + { + legacyEnable = bson_iterator_bool(&iter); + } + else + { + fprintf(stderr, "Wrong type for %s\n", bson_iterator_key(&iter)); + } + } + else if(strcmp(bson_iterator_key(&iter), "gravityEnable")==0) + { + if(bson_iterator_type(&iter)==BSON_BOOL) + { + gravityEnable = bson_iterator_bool(&iter); + } + else + { + fprintf(stderr, "Wrong type for %s\n", bson_iterator_key(&iter)); + } + } + else if(strcmp(bson_iterator_key(&iter), "waterEEnabled")==0) + { + if(bson_iterator_type(&iter)==BSON_BOOL) + { + waterEEnabled = bson_iterator_bool(&iter); + } + else + { + fprintf(stderr, "Wrong type for %s\n", bson_iterator_key(&iter)); + } + } + else if(strcmp(bson_iterator_key(&iter), "paused")==0) + { + if(bson_iterator_type(&iter)==BSON_BOOL) + { + paused = bson_iterator_bool(&iter); + } + else + { + fprintf(stderr, "Wrong type for %s\n", bson_iterator_key(&iter)); + } + } + else if(strcmp(bson_iterator_key(&iter), "gravityMode")==0) + { + if(bson_iterator_type(&iter)==BSON_INT) + { + gravityMode = bson_iterator_int(&iter); + } + else + { + fprintf(stderr, "Wrong type for %s\n", bson_iterator_key(&iter)); + } + } + else if(strcmp(bson_iterator_key(&iter), "airMode")==0) + { + if(bson_iterator_type(&iter)==BSON_INT) + { + airMode = bson_iterator_int(&iter); + } + else + { + fprintf(stderr, "Wrong type for %s\n", bson_iterator_key(&iter)); + } + } + } + + //Read wall and fan data + if(wallData) + { + j = 0; + if(blockW * blockH > wallDataLen) + { + fprintf(stderr, "Not enough wall data\n"); + goto fail; + } + for(x = 0; x < blockW; x++) + { + for(y = 0; y < blockH; y++) + { + if (wallData[y*blockW+x]) + blockMap[blockY+y][blockX+x] = wallData[y*blockW+x]; + if (wallData[y*blockW+x] == WL_FAN && fanData) + { + if(j+1 >= fanDataLen) + { + fprintf(stderr, "Not enough fan data\n"); + } + fanVelX[blockY+y][blockX+x] = (fanData[j++]-127.0f)/64.0f; + fanVelY[blockY+y][blockX+x] = (fanData[j++]-127.0f)/64.0f; + } + } + } + } + + //Read particle data + if(partsData && partsPosData) + { + int newIndex = 0, fieldDescriptor, tempTemp; + int posCount, posTotal, partsPosDataIndex = 0; + int saved_x, saved_y; + if(fullW * fullH * 3 > partsPosDataLen) + { + fprintf(stderr, "Not enough particle position data\n"); + goto fail; + } + i = 0; + newIndex = 0; + for (saved_y=0; saved_y=NPART) + { + goto fail; + } + + //i+3 because we have 4 bytes of required fields (type (1), descriptor (2), temp (1)) + if (i+3 >= partsDataLen) + goto fail; + x = saved_x + fullX; + y = saved_y + fullY; + fieldDescriptor = partsData[i+1]; + fieldDescriptor |= partsData[i+2] << 8; + if(x >= XRES || x < 0 || y >= YRES || y < 0) + { + fprintf(stderr, "Out of range [%d]: %d %d, [%d, %d], [%d, %d]\n", i, x, y, (unsigned)partsData[i+1], (unsigned)partsData[i+2], (unsigned)partsData[i+3], (unsigned)partsData[i+4]); + goto fail; + } + if(partsData[i] >= PT_NUM) + partsData[i] = PT_DMND; //Replace all invalid elements with diamond + + if(newIndex < 0 || newIndex >= NPART) + goto fail; + + //Clear the particle, ready for our new properties + memset(&(particles[newIndex]), 0, sizeof(Particle)); + + //Required fields + particles[newIndex].type = partsData[i]; + particles[newIndex].x = x; + particles[newIndex].y = y; + i+=3; + + //Read temp + if(fieldDescriptor & 0x01) + { + //Full 16bit int + tempTemp = partsData[i++]; + tempTemp |= (((unsigned)partsData[i++]) << 8); + particles[newIndex].temp = tempTemp; + } + else + { + //1 Byte room temp offset + tempTemp = (char)partsData[i++]; + particles[newIndex].temp = tempTemp+294.15f; + } + + //Read life + if(fieldDescriptor & 0x02) + { + if(i >= partsDataLen) goto fail; + particles[newIndex].life = partsData[i++]; + //Read 2nd byte + if(fieldDescriptor & 0x04) + { + if(i >= partsDataLen) goto fail; + particles[newIndex].life |= (((unsigned)partsData[i++]) << 8); + } + } + + //Read tmp + if(fieldDescriptor & 0x08) + { + if(i >= partsDataLen) goto fail; + particles[newIndex].tmp = partsData[i++]; + //Read 2nd byte + if(fieldDescriptor & 0x10) + { + if(i >= partsDataLen) goto fail; + particles[newIndex].tmp |= (((unsigned)partsData[i++]) << 8); + } + } + + //Read ctype + if(fieldDescriptor & 0x20) + { + if(i >= partsDataLen) goto fail; + particles[newIndex].ctype = partsData[i++]; + //Read additional bytes + if(fieldDescriptor & 0x200) + { + if(i+2 >= partsDataLen) goto fail; + particles[newIndex].ctype |= (((unsigned)partsData[i++]) << 24); + particles[newIndex].ctype |= (((unsigned)partsData[i++]) << 16); + particles[newIndex].ctype |= (((unsigned)partsData[i++]) << 8); + } + } + + //Read dcolour + if(fieldDescriptor & 0x40) + { + if(i+3 >= partsDataLen) goto fail; + particles[newIndex].dcolour = (((unsigned)partsData[i++]) << 24); + particles[newIndex].dcolour |= (((unsigned)partsData[i++]) << 16); + particles[newIndex].dcolour |= (((unsigned)partsData[i++]) << 8); + particles[newIndex].dcolour |= ((unsigned)partsData[i++]); + } + + //Read vx + if(fieldDescriptor & 0x80) + { + if(i >= partsDataLen) goto fail; + particles[newIndex].vx = (partsData[i++]-127.0f)/16.0f; + } + + //Read vy + if(fieldDescriptor & 0x100) + { + if(i >= partsDataLen) goto fail; + particles[newIndex].vy = (partsData[i++]-127.0f)/16.0f; + } + + //Read tmp2 + if(fieldDescriptor & 0x400) + { + if(i >= partsDataLen) goto fail; + particles[newIndex].tmp2 = partsData[i++]; + } + + /*if ((sim->player.spwn == 1 && particles[newIndex].type==PT_STKM) || (sim->player2.spwn == 1 && particles[newIndex].type==PT_STKM2)) + { + particles[newIndex].type = PT_NONE; + } + else if (particles[newIndex].type == PT_STKM) + { + //STKM_init_legs(&player, newIndex); + sim->player.spwn = 1; + sim->player.elem = PT_DUST; + } + else if (particles[newIndex].type == PT_STKM2) + { + //STKM_init_legs(&player2, newIndex); + sim->player2.spwn = 1; + sim->player2.elem = PT_DUST; + } + else if (particles[newIndex].type == PT_FIGH) + { + //TODO: 100 should be replaced with a macro + unsigned char fcount = 0; + while (fcount < 100 && fcount < (sim->fighcount+1) && sim->fighters[fcount].spwn==1) fcount++; + if (fcount < 100 && sim->fighters[fcount].spwn==0) + { + particles[newIndex].tmp = fcount; + sim->fighters[fcount].spwn = 1; + sim->fighters[fcount].elem = PT_DUST; + sim->fighcount++; + //STKM_init_legs(&(sim->fighters[sim->fcount]), newIndex); + } + } + if (!sim->elements[particles[newIndex].type].Enabled) + particles[newIndex].type = PT_NONE;*/ + newIndex++; + } + } + } + } + goto fin; +fail: + //Clean up everything + returnCode = Corrupt; +fin: + bson_destroy(&b); + if(freeIndices) + free(freeIndices); + return returnCode; + +} + +GameSave::ParseResult GameSave::readPSv(char * data, int dataLength) +{ + unsigned char * d = NULL, * c = (unsigned char *)data; + int q,i,j,k,x,y,p=0,*m=NULL, ver, pty, ty, legacy_beta=0, tempGrav = 0; + int bx0=0, by0=0, bw, bh, w, h, y0 = 0, x0 = 0; + int nf=0, new_format = 0, ttv = 0; + int *fp = (int *)malloc(NPART*sizeof(int)); + + std::vector tempSigns; + char tempSignText[255]; + sign tempSign("", 0, 0, sign::Left); + + //Gol data used to read older saves + int goltype[NGOL]; + int grule[NGOL+1][10]; + + int golRulesCount; + int * golRulesT = LoadGOLRules(golRulesCount); + memcpy(grule, golRulesT, sizeof(int) * (golRulesCount*10)); + free(golRulesT); + + int golTypesCount; + int * golTypesT = LoadGOLTypes(golTypesCount); + memcpy(goltype, golTypesT, sizeof(int) * (golTypesCount)); + free(golTypesT); + + vector elements = GetElements(); + + //New file header uses PSv, replacing fuC. This is to detect if the client uses a new save format for temperatures + //This creates a problem for old clients, that display and "corrupt" error instead of a "newer version" error + + if (dataLength<16) + return Corrupt; + if (!(c[2]==0x43 && c[1]==0x75 && c[0]==0x66) && !(c[2]==0x76 && c[1]==0x53 && c[0]==0x50)) + return Corrupt; + if (c[2]==0x76 && c[1]==0x53 && c[0]==0x50) { + new_format = 1; + } + if (c[4]>SAVE_VERSION) + return WrongVersion; + ver = c[4]; + + if (ver<34) + { + legacyEnable = 1; + } + else + { + if (ver>=44) { + legacyEnable = c[3]&0x01; + paused = (c[3]>>1)&0x01; + if (ver>=46) { + gravityMode = ((c[3]>>2)&0x03);// | ((c[3]>>2)&0x01); + airMode = ((c[3]>>4)&0x07);// | ((c[3]>>4)&0x02) | ((c[3]>>4)&0x01); + } + if (ver>=49) { + gravityEnable = ((c[3]>>7)&0x01); + } + } else { + if (c[3]==1||c[3]==0) { + legacyEnable = c[3]; + } else { + legacy_beta = 1; + } + } + } + + bw = c[6]; + bh = c[7]; + if (bx0+bw > XRES/CELL) + bx0 = XRES/CELL - bw; + if (by0+bh > YRES/CELL) + by0 = YRES/CELL - bh; + if (bx0 < 0) + bx0 = 0; + if (by0 < 0) + by0 = 0; + + if (c[5]!=CELL || bx0+bw>XRES/CELL || by0+bh>YRES/CELL) + return InvalidDimensions; + i = (unsigned)c[8]; + i |= ((unsigned)c[9])<<8; + i |= ((unsigned)c[10])<<16; + i |= ((unsigned)c[11])<<24; + d = (unsigned char *)malloc(i); + if (!d) + return Corrupt; + + setSize(bw*CELL, bh*CELL); + + if (BZ2_bzBuffToBuffDecompress((char *)d, (unsigned *)&i, (char *)(c+12), dataLength-12, 0, 0)) + return Corrupt; + dataLength = i; + + if (dataLength < bw*bh) + return Corrupt; + + // normalize coordinates + x0 = bx0*CELL; + y0 = by0*CELL; + w = bw *CELL; + h = bh *CELL; + + if (ver<46) { + gravityMode = 0; + airMode = 0; + } + m = (int *)calloc(XRES*YRES, sizeof(int)); + + // load the required air state + for (y=by0; y= dataLength) + goto corrupt; + fanVelX[y][x] = (d[p++]-127.0f)/64.0f; + } + for (y=by0; y= dataLength) + goto corrupt; + fanVelY[y][x] = (d[p++]-127.0f)/64.0f; + } + + // load the particle map + i = 0; + k = 0; + pty = p; + for (y=y0; y= dataLength) + goto corrupt; + j=d[p++]; + if (j >= PT_NUM) { + //TODO: Possibly some server side translation + j = PT_DUST;//goto corrupt; + } + if (j) + { + memset(particles+k, 0, sizeof(Particle)); + particles[k].type = j; + if (j == PT_COAL) + particles[k].tmp = 50; + if (j == PT_FUSE) + particles[k].tmp = 50; + if (j == PT_PHOT) + particles[k].ctype = 0x3fffffff; + if (j == PT_SOAP) + particles[k].ctype = 0; + if (j==PT_BIZR || j==PT_BIZRG || j==PT_BIZRS) + particles[k].ctype = 0x47FFFF; + particles[k].x = (float)x; + particles[k].y = (float)y; + m[(x-x0)+(y-y0)*w] = k+1; + particlesCount = k++; + } + } + + // load particle properties + for (j=0; j= dataLength) + goto corrupt; + if (i < NPART) + { + particles[i].vx = (d[p++]-127.0f)/16.0f; + particles[i].vy = (d[p++]-127.0f)/16.0f; + } + else + p += 2; + } + } + for (j=0; j=44) { + if (p >= dataLength) { + goto corrupt; + } + if (i <= NPART) { + ttv = (d[p++])<<8; + ttv |= (d[p++]); + particles[i-1].life = ttv; + } else { + p+=2; + } + } else { + if (p >= dataLength) + goto corrupt; + if (i <= NPART) + particles[i-1].life = d[p++]*4; + else + p++; + } + } + } + if (ver>=44) { + for (j=0; j= dataLength) { + goto corrupt; + } + if (i <= NPART) { + ttv = (d[p++])<<8; + ttv |= (d[p++]); + particles[i-1].tmp = ttv; + if (ver<53 && !particles[i-1].tmp) + for (q = 1; q<=NGOLALT; q++) { + if (particles[i-1].type==goltype[q-1] && grule[q][9]==2) + particles[i-1].tmp = grule[q][9]-1; + } + if (ver>=51 && ver<53 && particles[i-1].type==PT_PBCN) + { + particles[i-1].tmp2 = particles[i-1].tmp; + particles[i-1].tmp = 0; + } + } else { + p+=2; + } + } + } + } + if (ver>=53) { + for (j=0; j= dataLength) + goto corrupt; + if (i <= NPART) + particles[i-1].tmp2 = d[p++]; + else + p++; + } + } + } + //Read ALPHA component + for (j=0; j=49) { + if (p >= dataLength) { + goto corrupt; + } + if (i <= NPART) { + particles[i-1].dcolour = d[p++]<<24; + } else { + p++; + } + } + } + } + //Read RED component + for (j=0; j=49) { + if (p >= dataLength) { + goto corrupt; + } + if (i <= NPART) { + particles[i-1].dcolour |= d[p++]<<16; + } else { + p++; + } + } + } + } + //Read GREEN component + for (j=0; j=49) { + if (p >= dataLength) { + goto corrupt; + } + if (i <= NPART) { + particles[i-1].dcolour |= d[p++]<<8; + } else { + p++; + } + } + } + } + //Read BLUE component + for (j=0; j=49) { + if (p >= dataLength) { + goto corrupt; + } + if (i <= NPART) { + particles[i-1].dcolour |= d[p++]; + } else { + p++; + } + } + } + } + for (j=0; j=34&&legacy_beta==0) + { + if (p >= dataLength) + { + goto corrupt; + } + if (i <= NPART) + { + if (ver>=42) { + if (new_format) { + ttv = (d[p++])<<8; + ttv |= (d[p++]); + if (particles[i-1].type==PT_PUMP) { + particles[i-1].temp = ttv + 0.15;//fix PUMP saved at 0, so that it loads at 0. + } else { + particles[i-1].temp = ttv; + } + } else { + particles[i-1].temp = (d[p++]*((MAX_TEMP+(-MIN_TEMP))/255))+MIN_TEMP; + } + } else { + particles[i-1].temp = ((d[p++]*((O_MAX_TEMP+(-O_MIN_TEMP))/255))+O_MIN_TEMP)+273; + } + } + else + { + p++; + if (new_format) { + p++; + } + } + } + else + { + particles[i-1].temp = elements[particles[i-1].type].Temperature; + } + } + } + for (j=0; j=43) || (ty==PT_BCLN && ver>=44) || (ty==PT_SPRK && ver>=21) || (ty==PT_LAVA && ver>=34) || (ty==PT_PIPE && ver>=43) || (ty==PT_LIFE && ver>=51) || (ty==PT_PBCN && ver>=52) || (ty==PT_WIRE && ver>=55) || (ty==PT_STOR && ver>=59) || (ty==PT_CONV && ver>=60))) + { + if (p >= dataLength) + goto corrupt; + if (i <= NPART) + particles[i-1].ctype = d[p++]; + else + p++; + } + //TODO: STKM_init_legs + // no more particle properties to load, so we can change type here without messing up loading + if (i && i<=NPART) + { + if (particles[i-1].type == PT_SPNG) + { + if (fabs(particles[i-1].vx)>0.0f || fabs(particles[i-1].vy)>0.0f) + particles[i-1].flags |= FLAG_MOVABLE; + } + + if (ver<48 && (ty==OLD_PT_WIND || (ty==PT_BRAY&&particles[i-1].life==0))) + { + // Replace invisible particles with something sensible and add decoration to hide it + x = (int)(particles[i-1].x+0.5f); + y = (int)(particles[i-1].y+0.5f); + particles[i-1].dcolour = 0xFF000000; + particles[i-1].type = PT_DMND; + } + if(ver<51 && ((ty>=78 && ty<=89) || (ty>=134 && ty<=146 && ty!=141))){ + //Replace old GOL + particles[i-1].type = PT_LIFE; + for (gnum = 0; gnum=10) + { + particles[i-1].life = 10; + particles[i-1].tmp2 = 10; + particles[i-1].tmp = 3; + } + else if(particles[i-1].life<=0) + { + particles[i-1].life = 0; + particles[i-1].tmp2 = 0; + particles[i-1].tmp = 0; + } + else if(particles[i-1].life < 10 && particles[i-1].life > 0) + { + particles[i-1].tmp = 1; + } + } + else + { + particles[i-1].tmp2 = particles[i-1].life; + } + } + } + } + + if (p >= dataLength) + goto version1; + j = d[p++]; + for (i=0; i dataLength) + goto corrupt; + x = d[p++]; + x |= ((unsigned)d[p++])<<8; + tempSign.x = x+x0; + x = d[p++]; + x |= ((unsigned)d[p++])<<8; + tempSign.y = x+y0; + x = d[p++]; + tempSign.ju = (sign::Justification)x; + x = d[p++]; + if (p+x > dataLength) + goto corrupt; + if(x>254) + x = 254; + memcpy(tempSignText, d+p, x); + tempSignText[x] = 0; + tempSign.text = tempSignText; + tempSigns.push_back(tempSign); + p += x; + } + + for (i = 0; i < tempSigns.size(); i++) + { + if(i == MAXSIGNS) + break; + signs.push_back(tempSigns[i]); + } + +version1: + if (m) free(m); + if (d) free(d); + if (fp) free(fp); + + return OK; + +corrupt: + if (m) free(m); + if (d) free(d); + if (fp) free(fp); + + return Corrupt; + +} + +char * GameSave::serialiseOPS(int & dataLength) +{ + //Particle *particles = sim->parts; + unsigned char *partsData = NULL, *partsPosData = NULL, *fanData = NULL, *wallData = NULL, *finalData = NULL, *outputData = NULL; + unsigned *partsPosLink = NULL, *partsPosFirstMap = NULL, *partsPosCount = NULL, *partsPosLastMap = NULL; + unsigned int partsDataLen, partsPosDataLen, fanDataLen, wallDataLen, finalDataLen, outputDataLen; + int blockX, blockY, blockW, blockH, fullX, fullY, fullW, fullH; + int x, y, i, wallDataFound = 0; + int posCount, signsCount; + bson b; + + //Get coords in blocks + blockX = 0;//orig_x0/CELL; + blockY = 0;//orig_y0/CELL; + + //Snap full coords to block size + fullX = blockX*CELL; + fullY = blockY*CELL; + + //Original size + offset of original corner from snapped corner, rounded up by adding CELL-1 + blockW = (width-fullX+CELL-1)/CELL; + blockH = (height-fullY+CELL-1)/CELL; + fullW = blockW*CELL; + fullH = blockH*CELL; + + //Copy fan and wall data + wallData = (unsigned char*)malloc(blockW*blockH); + wallDataLen = blockW*blockH; + fanData = (unsigned char*)malloc((blockW*blockH)*2); + fanDataLen = 0; + for(x = blockX; x < blockX+blockW; x++) + { + for(y = blockY; y < blockY+blockH; y++) + { + wallData[(y-blockY)*blockW+(x-blockX)] = blockMap[y][x]; + if(blockMap[y][x] && !wallDataFound) + wallDataFound = 1; + if(blockMap[y][x]==WL_FAN) + { + i = (int)(fanVelX[y][x]*64.0f+127.5f); + if (i<0) i=0; + if (i>255) i=255; + fanData[fanDataLen++] = i; + i = (int)(fanVelY[y][x]*64.0f+127.5f); + if (i<0) i=0; + if (i>255) i=255; + fanData[fanDataLen++] = i; + } + } + } + if(!fanDataLen) + { + free(fanData); + fanData = NULL; + } + if(!wallDataFound) + { + free(wallData); + wallData = NULL; + } + + //Index positions of all particles, using linked lists + //partsPosFirstMap is pmap for the first particle in each position + //partsPosLastMap is pmap for the last particle in each position + //partsPosCount is the number of particles in each position + //partsPosLink contains, for each particle, (i<<8)|1 of the next particle in the same position + partsPosFirstMap = (unsigned int *)calloc(fullW*fullH, sizeof(unsigned)); + partsPosLastMap = (unsigned int *)calloc(fullW*fullH, sizeof(unsigned)); + partsPosCount = (unsigned int *)calloc(fullW*fullH, sizeof(unsigned)); + partsPosLink = (unsigned int *)calloc(NPART, sizeof(unsigned)); + for(i = 0; i < NPART; i++) + { + if(particles[i].type) + { + x = (int)(particles[i].x+0.5f); + y = (int)(particles[i].y+0.5f); + //Coordinates relative to top left corner of saved area + x -= fullX; + y -= fullY; + if (!partsPosFirstMap[y*fullW + x]) + { + //First entry in list + partsPosFirstMap[y*fullW + x] = (i<<8)|1; + partsPosLastMap[y*fullW + x] = (i<<8)|1; + } + else + { + //Add to end of list + partsPosLink[partsPosLastMap[y*fullW + x]>>8] = (i<<8)|1;//link to current end of list + partsPosLastMap[y*fullW + x] = (i<<8)|1;//set as new end of list + } + partsPosCount[y*fullW + x]++; + } + } + + //Store number of particles in each position + partsPosData = (unsigned char*)malloc(fullW*fullH*3); + partsPosDataLen = 0; + for (y=0;y>16; + partsPosData[partsPosDataLen++] = (posCount&0x0000FF00)>>8; + partsPosData[partsPosDataLen++] = (posCount&0x000000FF); + } + } + + //Copy parts data + /* Field descriptor format: + | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | + | tmp2 | ctype[2] | vy | vx | dcololour | ctype[1] | tmp[2] | tmp[1] | life[2] | life[1] | temp dbl len| + life[2] means a second byte (for a 16 bit field) if life[1] is present + */ + partsData = (unsigned char *)malloc(NPART * (sizeof(Particle)+1)); + partsDataLen = 0; + for (y=0;y>8; + + //Type (required) + partsData[partsDataLen++] = particles[i].type; + + //Location of the field descriptor + fieldDescLoc = partsDataLen++; + partsDataLen++; + + //Extra Temperature (2nd byte optional, 1st required), 1 to 2 bytes + //Store temperature as an offset of 21C(294.15K) or go into a 16byte int and store the whole thing + if(fabs(particles[i].temp-294.15f)<127) + { + tempTemp = (particles[i].temp-294.15f); + partsData[partsDataLen++] = tempTemp; + } + else + { + fieldDesc |= 1; + tempTemp = particles[i].temp; + partsData[partsDataLen++] = tempTemp; + partsData[partsDataLen++] = tempTemp >> 8; + } + + //Life (optional), 1 to 2 bytes + if(particles[i].life) + { + fieldDesc |= 1 << 1; + partsData[partsDataLen++] = particles[i].life; + if(particles[i].life > 255) + { + fieldDesc |= 1 << 2; + partsData[partsDataLen++] = particles[i].life >> 8; + } + } + + //Tmp (optional), 1 to 2 bytes + if(particles[i].tmp) + { + fieldDesc |= 1 << 3; + partsData[partsDataLen++] = particles[i].tmp; + if(particles[i].tmp > 255) + { + fieldDesc |= 1 << 4; + partsData[partsDataLen++] = particles[i].tmp >> 8; + } + } + + //Ctype (optional), 1 or 4 bytes + if(particles[i].ctype) + { + fieldDesc |= 1 << 5; + partsData[partsDataLen++] = particles[i].ctype; + if(particles[i].ctype > 255) + { + fieldDesc |= 1 << 9; + partsData[partsDataLen++] = (particles[i].ctype&0xFF000000)>>24; + partsData[partsDataLen++] = (particles[i].ctype&0x00FF0000)>>16; + partsData[partsDataLen++] = (particles[i].ctype&0x0000FF00)>>8; + } + } + + //Dcolour (optional), 4 bytes + if(particles[i].dcolour && (particles[i].dcolour & 0xFF000000)) + { + fieldDesc |= 1 << 6; + partsData[partsDataLen++] = (particles[i].dcolour&0xFF000000)>>24; + partsData[partsDataLen++] = (particles[i].dcolour&0x00FF0000)>>16; + partsData[partsDataLen++] = (particles[i].dcolour&0x0000FF00)>>8; + partsData[partsDataLen++] = (particles[i].dcolour&0x000000FF); + } + + //VX (optional), 1 byte + if(fabs(particles[i].vx) > 0.001f) + { + fieldDesc |= 1 << 7; + vTemp = (int)(particles[i].vx*16.0f+127.5f); + if (vTemp<0) vTemp=0; + if (vTemp>255) vTemp=255; + partsData[partsDataLen++] = vTemp; + } + + //VY (optional), 1 byte + if(fabs(particles[i].vy) > 0.001f) + { + fieldDesc |= 1 << 8; + vTemp = (int)(particles[i].vy*16.0f+127.5f); + if (vTemp<0) vTemp=0; + if (vTemp>255) vTemp=255; + partsData[partsDataLen++] = vTemp; + } + + //Tmp2 (optional), 1 byte + if(particles[i].tmp2) + { + fieldDesc |= 1 << 10; + partsData[partsDataLen++] = particles[i].tmp2; + } + + //Write the field descriptor; + partsData[fieldDescLoc] = fieldDesc; + partsData[fieldDescLoc+1] = fieldDesc>>8; + + //Get the pmap entry for the next particle in the same position + i = partsPosLink[i]; + } + } + } + if(!partsDataLen) + { + free(partsData); + partsData = NULL; + } + + bson_init(&b); + bson_append_bool(&b, "waterEEnabled", waterEEnabled); + bson_append_bool(&b, "legacyEnable", legacyEnable); + bson_append_bool(&b, "gravityEnable", gravityEnable); + bson_append_bool(&b, "paused", paused); + bson_append_int(&b, "gravityMode", gravityMode); + bson_append_int(&b, "airMode", airMode); + + //bson_append_int(&b, "leftSelectedElement", sl); + //bson_append_int(&b, "rightSelectedElement", sr); + //bson_append_int(&b, "activeMenu", active_menu); + if(partsData) + bson_append_binary(&b, "parts", BSON_BIN_USER, (const char *)partsData, partsDataLen); + if(partsPosData) + bson_append_binary(&b, "partsPos", BSON_BIN_USER, (const char *)partsPosData, partsPosDataLen); + if(wallData) + bson_append_binary(&b, "wallMap", BSON_BIN_USER, (const char *)wallData, wallDataLen); + if(fanData) + bson_append_binary(&b, "fanMap", BSON_BIN_USER, (const char *)fanData, fanDataLen); + signsCount = 0; + for(i = 0; i < signs.size(); i++) + { + if(signs[i].text.length() && signs[i].x>=0 && signs[i].x<=fullW && signs[i].y>=0 && signs[i].y<=fullH) + { + signsCount++; + } + } + if(signsCount) + { + bson_append_start_array(&b, "signs"); + for(i = 0; i < signs.size(); i++) + { + if(signs[i].text.length() && signs[i].x>=0 && signs[i].x<=fullW && signs[i].y>=0 && signs[i].y<=fullH) + { + bson_append_start_object(&b, "sign"); + bson_append_string(&b, "text", signs[i].text.c_str()); + bson_append_int(&b, "justification", signs[i].ju); + bson_append_int(&b, "x", signs[i].x); + bson_append_int(&b, "y", signs[i].y); + bson_append_finish_object(&b); + } + } + } + bson_append_finish_array(&b); + bson_finish(&b); + bson_print(&b); + + finalData = (unsigned char *)bson_data(&b); + finalDataLen = bson_size(&b); + outputDataLen = finalDataLen*2+12; + outputData = (unsigned char *)malloc(outputDataLen); + + outputData[0] = 'O'; + outputData[1] = 'P'; + outputData[2] = 'S'; + outputData[3] = '1'; + outputData[4] = SAVE_VERSION; + outputData[5] = CELL; + outputData[6] = blockW; + outputData[7] = blockH; + outputData[8] = finalDataLen; + outputData[9] = finalDataLen >> 8; + outputData[10] = finalDataLen >> 16; + outputData[11] = finalDataLen >> 24; + + if (BZ2_bzBuffToBuffCompress((char*)(outputData+12), &outputDataLen, (char*)finalData, bson_size(&b), 9, 0, 0) != BZ_OK) + { + puts("Save Error\n"); + free(outputData); + dataLength = 0; + outputData = NULL; + goto fin; + } + + printf("compressed data: %d\n", outputDataLen); + dataLength = outputDataLen + 12; + +fin: + bson_destroy(&b); + if(partsData) + free(partsData); + if(wallData) + free(wallData); + if(fanData) + free(fanData); + + return (char*)outputData; +} + +GameSave::~GameSave() +{ + if(width && height) + { + /*if(particleMap) + { + for(int y = 0; y < height; y++) + delete[] particleMap[y]; + delete[] particleMap; + }*/ + if(particles) + { + delete[] particles; + } + if(blockMap) + { + delete[] blockMapPtr; + delete[] blockMap; + } + if(fanVelX) + { + delete[] fanVelXPtr; + delete[] fanVelX; + } + if(fanVelY) + { + delete[] fanVelYPtr; + delete[] fanVelY; + } + } +} \ No newline at end of file diff --git a/src/client/GameSave.h b/src/client/GameSave.h new file mode 100644 index 0000000..ccf3690 --- /dev/null +++ b/src/client/GameSave.h @@ -0,0 +1,74 @@ +// +// GameSave.h +// The Powder Toy +// +// Created by Simon Robertshaw on 04/06/2012. +// + +#ifndef The_Powder_Toy_GameSave_h +#define The_Powder_Toy_GameSave_h + +#include +#include "Misc.h" +#include "simulation/StorageClasses.h" + +class GameSave +{ +public: + enum ParseResult { OK = 0, Corrupt, WrongVersion, InvalidDimensions, InternalError, MissingElement }; + + int width, height; + + //Simulation data + //int ** particleMap; + int particlesCount; + Particle * particles; + char ** blockMap; + float ** fanVelX; + float ** fanVelY; + + //Simulation Options + bool waterEEnabled; + bool legacyEnable; + bool gravityEnable; + bool paused; + int gravityMode; + int airMode; + + //Signs + std::vector signs; + + GameSave(GameSave & save); + GameSave(int width, int height); + GameSave(char * data, int dataSize); + ~GameSave(); + void setSize(int width, int height); + char * Serialise(int & dataSize); + void Transform(matrix2d transform, vector2d translate); + + inline GameSave& operator << (Particle v) + { + if(particlesCountGetStamp()) { - gameModel->GetSimulation()->Load(position.X, position.Y, gameModel->GetStamp()->data, gameModel->GetStamp()->dataLength); + gameModel->GetSimulation()->Load(position.X, position.Y, gameModel->GetStamp()); gameModel->SetPaused(gameModel->GetPaused()); } } @@ -181,7 +181,7 @@ void GameController::PlaceClipboard(ui::Point position) { if(gameModel->GetClipboard()) { - gameModel->GetSimulation()->Load(position.X, position.Y, gameModel->GetClipboard()->data, gameModel->GetClipboard()->dataLength); + gameModel->GetSimulation()->Load(position.X, position.Y, gameModel->GetClipboard()); gameModel->SetPaused(gameModel->GetPaused()); } } @@ -316,21 +316,18 @@ void GameController::ToolClick(int toolSelection, ui::Point point) void GameController::StampRegion(ui::Point point1, ui::Point point2) { - int saveSize; - unsigned char * saveData; - saveData = gameModel->GetSimulation()->Save(point1.X, point1.Y, point2.X, point2.Y, saveSize); - if(saveData && saveSize) - gameModel->AddStamp(saveData, saveSize); + GameSave * newSave; + newSave = gameModel->GetSimulation()->Save(point1.X, point1.Y, point2.X, point2.Y); + if(newSave) + gameModel->AddStamp(newSave); } void GameController::CopyRegion(ui::Point point1, ui::Point point2) { - int saveSize; - unsigned char * saveData; - saveData = gameModel->GetSimulation()->Save(point1.X, point1.Y, point2.X, point2.Y, saveSize); - - if(saveData && saveSize) - gameModel->SetClipboard(saveData, saveSize); + GameSave * newSave; + newSave = gameModel->GetSimulation()->Save(point1.X, point1.Y, point2.X, point2.Y); + if(newSave) + gameModel->SetClipboard(newSave); } bool GameController::MouseMove(int x, int y, int dx, int dy) @@ -530,24 +527,25 @@ void GameController::OpenSaveWindow() { if(gameModel->GetUser().ID) { - int tempSaveLength; - unsigned char * tempData = gameModel->GetSimulation()->Save(tempSaveLength); - if(!tempData) + GameSave * tempSave = gameModel->GetSimulation()->Save(); + if(!tempSave) { new ErrorMessage("Error", "Unable to build save."); } else { + int dataSize; + unsigned char * tempData = (unsigned char*)tempSave->Serialise(dataSize); if(gameModel->GetSave()) { Save tempSave(*gameModel->GetSave()); - tempSave.SetData(tempData, tempSaveLength); + tempSave.SetData(tempData, dataSize); ssave = new SSaveController(new SSaveCallback(this), tempSave); } else - { + { Save tempSave(0, 0, 0, 0, gameModel->GetUser().Username, ""); - tempSave.SetData(tempData, tempSaveLength); + tempSave.SetData(tempData, dataSize); ssave = new SSaveController(new SSaveCallback(this), tempSave); } ui::Engine::Ref().ShowWindow(ssave->GetView()); @@ -585,7 +583,10 @@ void GameController::ClearSim() void GameController::ReloadSim() { if(gameModel->GetSave() && gameModel->GetSave()->GetData()) - gameModel->GetSimulation()->Load(gameModel->GetSave()->GetData(), gameModel->GetSave()->GetDataLength()); + { + GameSave * newSave = new GameSave((char*)gameModel->GetSave()->GetData(), gameModel->GetSave()->GetDataLength()); + gameModel->GetSimulation()->Load(newSave); + } } std::string GameController::ElementResolve(int type) diff --git a/src/game/GameModel.cpp b/src/game/GameModel.cpp index ae3b191..08bd0ec 100644 --- a/src/game/GameModel.cpp +++ b/src/game/GameModel.cpp @@ -275,7 +275,8 @@ void GameModel::SetSave(Save * newSave) currentSave = newSave; if(currentSave) { - int returnVal = sim->Load(currentSave->GetData(), currentSave->GetDataLength()); + GameSave * newSave = new GameSave((char*)currentSave->GetData(), currentSave->GetDataLength()); + int returnVal = sim->Load(newSave); if(returnVal){ delete currentSave; currentSave = NULL; @@ -429,46 +430,49 @@ void GameModel::ClearSimulation() sim->clear_sim(); } -void GameModel::AddStamp(unsigned char * saveData, int saveSize) +void GameModel::SetStamp(Save * save) { + if(stamp) + delete stamp; + stamp = new GameSave((char*)save->GetData(), save->GetDataLength()); + notifyStampChanged(); +} + +void GameModel::AddStamp(GameSave * save) +{ + if(stamp) + delete stamp; + stamp = save; + + char * saveData; + int saveSize; + saveData = save->Serialise(saveSize); Save * tempSave = new Save(0, 0, 0, 0, "", ""); - tempSave->SetData(saveData, saveSize); + tempSave->SetData((unsigned char*)saveData, saveSize); Client::Ref().AddStamp(tempSave); delete tempSave; + + notifyClipboardChanged(); } -void GameModel::SetClipboard(unsigned char * saveData, int saveSize) +void GameModel::SetClipboard(GameSave * save) { if(clipboard) delete clipboard; - clipboard = new Save(0, 0, 0, 0, "", ""); - clipboard->SetData(saveData, saveSize); + clipboard = save; notifyClipboardChanged(); } -Save * GameModel::GetClipboard() +GameSave * GameModel::GetClipboard() { return clipboard; } -Save * GameModel::GetStamp() +GameSave * GameModel::GetStamp() { return stamp; } -void GameModel::SetStamp(Save * newStamp) -{ - if(stamp) - delete stamp; - if(newStamp) - { - stamp = new Save(*newStamp); - } - else - stamp = NULL; - notifyStampChanged(); -} - void GameModel::Log(string message) { consoleLog.push_front(message); diff --git a/src/game/GameModel.h b/src/game/GameModel.h index 7dff6f2..c038493 100644 --- a/src/game/GameModel.h +++ b/src/game/GameModel.h @@ -34,8 +34,8 @@ class GameModel private: //int clipboardSize; //unsigned char * clipboardData; - Save * stamp; - Save * clipboard; + GameSave * stamp; + GameSave * clipboard; deque consoleLog; vector observers; vector toolList; @@ -111,12 +111,12 @@ public: void SetZoomWindowPosition(ui::Point position); ui::Point GetZoomWindowPosition(); void SetStamp(Save * newStamp); - void AddStamp(unsigned char * saveData, int saveSize); - void SetClipboard(unsigned char * saveData, int saveSize); + void AddStamp(GameSave * save); + void SetClipboard(GameSave * save); void Log(string message); deque GetLog(); - Save * GetClipboard(); - Save * GetStamp(); + GameSave * GetClipboard(); + GameSave * GetStamp(); }; #endif // GAMEMODEL_H diff --git a/src/game/GameView.cpp b/src/game/GameView.cpp index 9d97a33..adc5883 100644 --- a/src/game/GameView.cpp +++ b/src/game/GameView.cpp @@ -834,7 +834,7 @@ void GameView::NotifyClipboardChanged(GameModel * sender) delete clipboardThumb; if(sender->GetClipboard()) { - clipboardThumb = SaveRenderer::Ref().Render(sender->GetClipboard()->GetData(), sender->GetClipboard()->GetDataLength()); + clipboardThumb = SaveRenderer::Ref().Render(sender->GetClipboard()); } else clipboardThumb = NULL; @@ -847,7 +847,7 @@ void GameView::NotifyStampChanged(GameModel * sender) delete stampThumb; if(sender->GetStamp()) { - stampThumb = SaveRenderer::Ref().Render(sender->GetStamp()->GetData(), sender->GetStamp()->GetDataLength()); + stampThumb = SaveRenderer::Ref().Render(sender->GetStamp()); } else stampThumb = NULL; diff --git a/src/interface/Keys.h b/src/interface/Keys.h index 85d8611..a06b4d7 100644 --- a/src/interface/Keys.h +++ b/src/interface/Keys.h @@ -1,5 +1,6 @@ -#if defined(USES_SDL) +#if defined(USE_SDL) +#include "SDL.h" #define KEY_UP SDLK_UP #define KEY_DOWN SDLK_DOWN #define KEY_RIGHT SDLK_RIGHT diff --git a/src/simulation/GOLMenu.h b/src/simulation/GOLMenu.h new file mode 100644 index 0000000..36bb5dd --- /dev/null +++ b/src/simulation/GOLMenu.h @@ -0,0 +1,20 @@ +// +// GOLMenu.h +// The Powder Toy +// +// Created by Simon Robertshaw on 04/06/2012. +// Copyright (c) 2012 __MyCompanyName__. All rights reserved. +// + +#ifndef The_Powder_Toy_GOLMenu_h +#define The_Powder_Toy_GOLMenu_h + +struct gol_menu +{ + const char *name; + pixel colour; + int goltype; + const char *description; +}; + +#endif diff --git a/src/simulation/MenuSection.h b/src/simulation/MenuSection.h new file mode 100644 index 0000000..b8e16fe --- /dev/null +++ b/src/simulation/MenuSection.h @@ -0,0 +1,20 @@ +// +// MenuSection.h +// The Powder Toy +// +// Created by Simon Robertshaw on 04/06/2012. +// Copyright (c) 2012 __MyCompanyName__. All rights reserved. +// + +#ifndef The_Powder_Toy_MenuSection_h +#define The_Powder_Toy_MenuSection_h + +struct menu_section +{ + char *icon; + const char *name; + int itemcount; + int doshow; +}; + +#endif diff --git a/src/simulation/Particle.h b/src/simulation/Particle.h new file mode 100644 index 0000000..91a1315 --- /dev/null +++ b/src/simulation/Particle.h @@ -0,0 +1,46 @@ +// +// Particle.h +// The Powder Toy +// +// Created by Simon Robertshaw on 04/06/2012. +// Copyright (c) 2012 __MyCompanyName__. All rights reserved. +// + +#ifndef The_Powder_Toy_Particle_h +#define The_Powder_Toy_Particle_h + +#include "StructProperty.h" + +struct Particle +{ + int type; + int life, ctype; + float x, y, vx, vy; + float temp; + float pavg[2]; + int flags; + int tmp; + int tmp2; + unsigned int dcolour; + /** Returns a list of properties, their type and offset within the structure that can be changed + by higher-level processes refering to them by name such as Lua or the property tool **/ + static std::vector GetProperties() + { + std::vector properties; + properties.push_back(StructProperty("type", StructProperty::ParticleType, offsetof(Particle, type))); + properties.push_back(StructProperty("life", StructProperty::ParticleType, offsetof(Particle, life))); + properties.push_back(StructProperty("ctype", StructProperty::ParticleType, offsetof(Particle, ctype))); + properties.push_back(StructProperty("x", StructProperty::Float, offsetof(Particle, x))); + properties.push_back(StructProperty("y", StructProperty::Float, offsetof(Particle, y))); + properties.push_back(StructProperty("vx", StructProperty::Float, offsetof(Particle, vx))); + properties.push_back(StructProperty("vy", StructProperty::Float, offsetof(Particle, vy))); + properties.push_back(StructProperty("temp", StructProperty::Float, offsetof(Particle, temp))); + properties.push_back(StructProperty("flags", StructProperty::UInteger, offsetof(Particle, flags))); + properties.push_back(StructProperty("tmp", StructProperty::Integer, offsetof(Particle, tmp))); + properties.push_back(StructProperty("tmp2", StructProperty::Integer, offsetof(Particle, tmp2))); + properties.push_back(StructProperty("dcolour", StructProperty::UInteger, offsetof(Particle, dcolour))); + return properties; + } +}; + +#endif diff --git a/src/simulation/Player.h b/src/simulation/Player.h new file mode 100644 index 0000000..af2b68e --- /dev/null +++ b/src/simulation/Player.h @@ -0,0 +1,23 @@ +// +// Player.h +// The Powder Toy +// +// Created by Simon Robertshaw on 04/06/2012. +// Copyright (c) 2012 __MyCompanyName__. All rights reserved. +// + +#ifndef The_Powder_Toy_Player_h +#define The_Powder_Toy_Player_h + +struct playerst +{ + char comm; //command cell + char pcomm; //previous command + int elem; //element power + float legs[16]; //legs' positions + float accs[8]; //accelerations + char spwn; //if stick man was spawned + unsigned int frames; //frames since last particle spawn - used when spawning LIGH +}; + +#endif diff --git a/src/simulation/SaveRenderer.cpp b/src/simulation/SaveRenderer.cpp index 7a5f5c2..52dcfaf 100644 --- a/src/simulation/SaveRenderer.cpp +++ b/src/simulation/SaveRenderer.cpp @@ -18,41 +18,48 @@ SaveRenderer::SaveRenderer(){ ren = new Renderer(g, sim); } -Thumbnail * SaveRenderer::Render(unsigned char * data, int dataLength) +Thumbnail * SaveRenderer::Render(GameSave * save) { Thumbnail * tempThumb = NULL; int width, height; + width, height = save->width, save->height; + pixel * pData = NULL; pixel * dst; pixel * src = g->vid; - + g->Clear(); sim->clear_sim(); - if(sim->Load(data, dataLength)) - goto finish; - - if(SaveLoader::Info(data, dataLength, width, height)) + if(sim->Load(save)) goto finish; - + ren->render_parts(); - + dst = pData = (pixel *)malloc(PIXELSIZE * ((width*CELL)*(height*CELL))); - + for(int i = 0; i < height*CELL; i++) { memcpy(dst, src, (width*CELL)*PIXELSIZE); dst+=(width*CELL);///PIXELSIZE; src+=XRES+BARSIZE; } - + tempThumb = new Thumbnail(0, 0, pData, ui::Point(width*CELL, height*CELL)); - + finish: if(pData) free(pData); return tempThumb; } +Thumbnail * SaveRenderer::Render(unsigned char * saveData, int dataSize) +{ + GameSave * tempSave = new GameSave((char*)saveData, dataSize); + Thumbnail * thumb = Render(tempSave); + delete tempSave; + return thumb; +} + SaveRenderer::~SaveRenderer() { // TODO Auto-generated destructor stub } diff --git a/src/simulation/SaveRenderer.h b/src/simulation/SaveRenderer.h index a43f100..22872aa 100644 --- a/src/simulation/SaveRenderer.h +++ b/src/simulation/SaveRenderer.h @@ -10,6 +10,7 @@ #include "Singleton.h" #include "search/Thumbnail.h" +#include "client/GameSave.h" class Graphics; class Simulation; @@ -20,7 +21,8 @@ class SaveRenderer: public Singleton { Renderer * ren; public: SaveRenderer(); - Thumbnail * Render(unsigned char * data, int dataLength); + Thumbnail * Render(GameSave * save); + Thumbnail * Render(unsigned char * saveData, int saveDataSize); virtual ~SaveRenderer(); }; diff --git a/src/simulation/Sign.h b/src/simulation/Sign.h new file mode 100644 index 0000000..1b8a68c --- /dev/null +++ b/src/simulation/Sign.h @@ -0,0 +1,27 @@ +// +// Sign.h +// The Powder Toy +// +// Created by Simon Robertshaw on 04/06/2012. +// Copyright (c) 2012 __MyCompanyName__. All rights reserved. +// + +#ifndef The_Powder_Toy_Sign_h +#define The_Powder_Toy_Sign_h + +class sign +{ +public: + enum Justification { Left = 0, Centre = 1, Right = 2 }; + sign(std::string text_, int x_, int y_, Justification justification_): + text(text_), + x(x_), + y(y_), + ju(justification_) + {} + int x, y; + Justification ju; + std::string text; +}; + +#endif diff --git a/src/simulation/Simulation.cpp b/src/simulation/Simulation.cpp index f4586a4..8fb4394 100644 --- a/src/simulation/Simulation.cpp +++ b/src/simulation/Simulation.cpp @@ -12,7 +12,64 @@ #undef LUACONSOLE //#include "cat/LuaScriptHelper.h" -int Simulation::Load(unsigned char * data, int dataLength) +int Simulation::Load(GameSave * save) +{ + return Load(0, 0, save); +} + +int Simulation::Load(int x, int y, GameSave * save) +{ + for(int i = 0; i < NPART && i < save->particlesCount; i++) + { + parts[i] = save->particles[i]; + } + parts_lastActiveIndex = NPART-1; + for(int i = 0; i < save->signs.size() && signs.size() < MAXSIGNS; i++) + { + signs.push_back(save->signs[i]); + } + for(int x = 0; x < save->width/CELL; x++) + { + for(int y = 0; y < save->height/CELL; y++) + { + bmap[y][x] = save->blockMap[y][x]; + fvx[y][x] = save->fanVelX[y][x]; + fvy[y][x] = save->fanVelY[y][x]; + } + } + return 0; +} + +GameSave * Simulation::Save() +{ + Save(0, 0, XRES, YRES); +} + +GameSave * Simulation::Save(int x1, int y1, int x2, int y2) +{ + GameSave * newSave = new GameSave(abs(x2-x1), abs(y2-y1)); + + for(int i = 0; i < NPART; i++) + { + int x, y; + x = int(parts[i].x + 0.5f); + y = int(parts[i].y + 0.5f); + if(parts[i].type && x >= x1 && y >= y1 && x < x2 && y < y2) + { + *newSave << parts[i]; + } + } + + for(int i = 0; i < MAXSIGNS && i < signs.size(); i++) + { + if(signs[i].text.length() && signs[i].x >= x1 && signs[i].y >= y1 && signs[i].x < x2 && signs[i].y < y2) + { + *newSave << signs[i]; + } + } +} + +/*int Simulation::Load(unsigned char * data, int dataLength) { return SaveLoader::Load(data, dataLength, this, true, 0, 0); } @@ -30,7 +87,7 @@ unsigned char * Simulation::Save(int & dataLength) unsigned char * Simulation::Save(int x1, int y1, int x2, int y2, int & dataLength) { return SaveLoader::Build(dataLength, this, x1, y1, x2-x1, y2-y1); -} +}*/ void Simulation::clear_area(int area_x, int area_y, int area_w, int area_h) { diff --git a/src/simulation/Simulation.h b/src/simulation/Simulation.h index 7760741..883ff57 100644 --- a/src/simulation/Simulation.h +++ b/src/simulation/Simulation.h @@ -12,12 +12,20 @@ #include "Config.h" #include "Renderer.h" #include "Graphics.h" -#include "Elements.h" +//#include "Elements.h" #include "Tools.h" #include "Misc.h" #include "game/Brush.h" #include "Gravity.h" #include "SimulationData.h" +#include "Sign.h" +#include "Particle.h" +#include "StorageClasses.h" +#include "Player.h" +#include "WallType.h" +#include "GOLMenu.h" +#include "MenuSection.h" +#include "client/GameSave.h" #define CHANNELS ((int)(MAX_TEMP-73)/100+2) @@ -25,156 +33,7 @@ class Simulation; class Renderer; class Gravity; class Air; - -//Describes fields in structures such as Particle or Element -struct StructProperty -{ - enum PropertyType { ParticleType, Colour, Integer, UInteger, Float, String }; - std::string Name; - PropertyType Type; - intptr_t Offset; - - StructProperty(std::string name, PropertyType type, intptr_t offset): - Name(name), - Type(type), - Offset(offset) - { - - } -}; - -struct Particle -{ - int type; - int life, ctype; - float x, y, vx, vy; - float temp; - float pavg[2]; - int flags; - int tmp; - int tmp2; - unsigned int dcolour; - /** Returns a list of properties, their type and offset within the structure that can be changed - by higher-level processes refering to them by name such as Lua or the property tool **/ - static std::vector GetProperties() - { - std::vector properties; - properties.push_back(StructProperty("type", StructProperty::ParticleType, offsetof(Particle, type))); - properties.push_back(StructProperty("life", StructProperty::ParticleType, offsetof(Particle, life))); - properties.push_back(StructProperty("ctype", StructProperty::ParticleType, offsetof(Particle, ctype))); - properties.push_back(StructProperty("x", StructProperty::Float, offsetof(Particle, x))); - properties.push_back(StructProperty("y", StructProperty::Float, offsetof(Particle, y))); - properties.push_back(StructProperty("vx", StructProperty::Float, offsetof(Particle, vx))); - properties.push_back(StructProperty("vy", StructProperty::Float, offsetof(Particle, vy))); - properties.push_back(StructProperty("temp", StructProperty::Float, offsetof(Particle, temp))); - properties.push_back(StructProperty("flags", StructProperty::UInteger, offsetof(Particle, flags))); - properties.push_back(StructProperty("tmp", StructProperty::Integer, offsetof(Particle, tmp))); - properties.push_back(StructProperty("tmp2", StructProperty::Integer, offsetof(Particle, tmp2))); - properties.push_back(StructProperty("dcolour", StructProperty::UInteger, offsetof(Particle, dcolour))); - return properties; - } -}; -typedef struct Particle Particle; - -struct part_type -{ - char *name; - pixel pcolors; - float advection; - float airdrag; - float airloss; - float loss; - float collision; - float gravity; - float diffusion; - float hotair; - int falldown; - int flammable; - int explosive; - int meltable; - int hardness; - int menu; - int enabled; - int weight; - int menusection; - float heat; - unsigned char hconduct; - char *descs; - char state; - unsigned int properties; - int (*update_func) (UPDATE_FUNC_ARGS); - int (*graphics_func) (GRAPHICS_FUNC_ARGS); -}; -typedef struct part_type part_type; - -struct part_transition -{ - float plv; // transition occurs if pv is lower than this - int plt; - float phv; // transition occurs if pv is higher than this - int pht; - float tlv; // transition occurs if t is lower than this - int tlt; - float thv; // transition occurs if t is higher than this - int tht; -}; -typedef struct part_transition part_transition; - - -struct wall_type -{ - pixel colour; - pixel eglow; // if emap set, add this to fire glow - int drawstyle; - const char *descs; -}; -typedef struct wall_type wall_type; - -struct gol_menu -{ - const char *name; - pixel colour; - int goltype; - const char *description; -}; -typedef struct gol_menu gol_menu; - -struct menu_section -{ - char *icon; - const char *name; - int itemcount; - int doshow; -}; -typedef struct menu_section menu_section; - -struct sign -{ -public: - enum Justification { Left = 0, Centre = 1, Right = 2 }; - sign(std::string text_, int x_, int y_, Justification justification_): - text(text_), - x(x_), - y(y_), - ju(justification_) - {} - int x, y; - Justification ju; - std::string text; -}; -typedef struct sign sign; - -struct playerst -{ - char comm; //command cell - char pcomm; //previous command - int elem; //element power - float legs[16]; //legs' positions - float accs[8]; //accelerations - char spwn; //if stick man was spawned - unsigned int frames; //frames since last particle spawn - used when spawning LIGH -}; -typedef struct playerst playerst; +class GameSave; //#ifdef _cplusplus class Simulation @@ -253,10 +112,10 @@ public: int sandcolour_g; int sandcolour_b; //TODO: Make a single variable - int Load(unsigned char * data, int dataLength); - int Load(int x, int y, unsigned char * data, int dataLength); - unsigned char * Save(int & dataLength); - unsigned char * Save(int x1, int y1, int x2, int y2, int & dataLength); + int Load(GameSave * save); + int Load(int x, int y, GameSave * save); + GameSave * Save(); + GameSave * Save(int x1, int y1, int x2, int y2); Particle Get(int x, int y); inline int is_blocking(int t, int x, int y); inline int is_boundary(int pt, int x, int y); diff --git a/src/simulation/SimulationData.cpp b/src/simulation/SimulationData.cpp index fd0c4a5..66e39a4 100644 --- a/src/simulation/SimulationData.cpp +++ b/src/simulation/SimulationData.cpp @@ -8,19 +8,6 @@ //#include "ElementFunctions.h" #include "ElementGraphics.h" -std::vector GetDefaultElements() -{ - std::vector elements; - //class Element; - //elements.push_back(dynamic_cast(new NULLElement())); - //elements.push_back(dynamic_cast(new DUSTElement())); - //elements.push_back(dynamic_cast(new WATRElement())); - //for(int i = 3; i < PT_NUM; i++) - // elements.push_back(dynamic_cast(new DUSTElement())); - - return elements; -} - gol_menu * LoadGOLMenu(int & golMenuCount) { gol_menu golMenu[NGOL] = @@ -184,184 +171,6 @@ menu_section * LoadMenus(int & menuCount) return msectionsT; } -part_type * LoadElements(int & elementCount) -{ - part_type ptypes[PT_NUM] = - { - //Name Colour Advec Airdrag Airloss Loss Collid Grav Diffus Hotair Fal Burn Exp Mel Hrd M Use Weight Section H Ins Description - /*{"", PIXPACK(0x000000), 0.0f, 0.00f * CFDS, 1.00f, 0.00f, 0.0f, 0.0f, 0.00f, 0.000f * CFDS, 0, 0, 0, 0, 1, 1, 1, 100, SC_SPECIAL, R_TEMP+0.0f +273.15f, 251, "Erases particles.", ST_NONE, 0, NULL, NULL}, - {"DUST", PIXPACK(0xFFE0A0), 0.7f, 0.02f * CFDS, 0.96f, 0.80f, 0.0f, 0.1f, 0.00f, 0.000f * CFDS, 1, 10, 0, 0, 30, 1, 1, 85, SC_POWDERS, R_TEMP+0.0f +273.15f, 70, "Very light dust. Flammable.", ST_SOLID, TYPE_PART|PROP_LIFE_DEC|PROP_LIFE_KILL_DEC, NULL, &graphics_DUST}, - {"WATR", PIXPACK(0x2030D0), 0.6f, 0.01f * CFDS, 0.98f, 0.95f, 0.0f, 0.1f, 0.00f, 0.000f * CFDS, 2, 0, 0, 0, 20, 1, 1, 30, SC_LIQUID, R_TEMP-2.0f +273.15f, 29, "Liquid. Conducts electricity. Freezes. Extinguishes fires.", ST_LIQUID, TYPE_LIQUID|PROP_CONDUCTS|PROP_LIFE_DEC|PROP_NEUTPENETRATE, &update_WATR, NULL}, - {"OIL", PIXPACK(0x404010), 0.6f, 0.01f * CFDS, 0.98f, 0.95f, 0.0f, 0.1f, 0.00f, 0.000f * CFDS, 2, 20, 0, 0, 5, 1, 1, 20, SC_LIQUID, R_TEMP+0.0f +273.15f, 42, "Liquid. Flammable.", ST_LIQUID, TYPE_LIQUID, NULL, NULL}, -#ifdef REALISTIC - {"FIRE", PIXPACK(0xFF1000), 0.9f, 0.04f * CFDS, 0.97f, 0.20f, 0.0f, -0.1f, 0.00f, 0.001f * CFDS, 1, 0, 0, 0, 1, 1, 1, 2, SC_EXPLOSIVE, R_TEMP+400.0f+273.15f, 1, "Ignites flammable materials. Heats air.", ST_GAS, TYPE_GAS|PROP_LIFE_DEC|PROP_LIFE_KILL, &update_PYRO, &graphics_FIRE}, -#else - {"FIRE", PIXPACK(0xFF1000), 0.9f, 0.04f * CFDS, 0.97f, 0.20f, 0.0f, -0.1f, 0.00f, 0.001f * CFDS, 1, 0, 0, 0, 1, 1, 1, 2, SC_EXPLOSIVE, R_TEMP+400.0f+273.15f, 88, "Ignites flammable materials. Heats air.", ST_GAS, TYPE_GAS|PROP_LIFE_DEC|PROP_LIFE_KILL, &update_PYRO, &graphics_FIRE}, -#endif - {"STNE", PIXPACK(0xA0A0A0), 0.4f, 0.04f * CFDS, 0.94f, 0.95f, -0.1f, 0.3f, 0.00f, 0.000f * CFDS, 1, 0, 0, 5, 1, 1, 1, 90, SC_POWDERS, R_TEMP+0.0f +273.15f, 150, "Heavy particles. Meltable.", ST_SOLID, TYPE_PART, NULL, NULL}, - {"LAVA", PIXPACK(0xE05010), 0.3f, 0.02f * CFDS, 0.95f, 0.80f, 0.0f, 0.15f, 0.00f, 0.0003f * CFDS, 2, 0, 0, 0, 2, 1, 1, 45, SC_LIQUID, R_TEMP+1500.0f+273.15f, 60, "Heavy liquid. Ignites flammable materials. Solidifies when cold.", ST_LIQUID, TYPE_LIQUID|PROP_LIFE_DEC, &update_PYRO, &graphics_LAVA}, - {"GUN", PIXPACK(0xC0C0D0), 0.7f, 0.02f * CFDS, 0.94f, 0.80f, -0.1f, 0.1f, 0.00f, 0.000f * CFDS, 1, 600, 1, 0, 10, 1, 1, 85, SC_EXPLOSIVE, R_TEMP+0.0f +273.15f, 97, "Light dust. Explosive.", ST_SOLID, TYPE_PART, NULL, NULL}, - {"NITR", PIXPACK(0x20E010), 0.5f, 0.02f * CFDS, 0.92f, 0.97f, 0.0f, 0.2f, 0.00f, 0.000f * CFDS, 2, 1000, 2, 0, 3, 1, 1, 23, SC_EXPLOSIVE, R_TEMP+0.0f +273.15f, 50, "Liquid. Pressure sensitive explosive.", ST_LIQUID, TYPE_LIQUID, NULL, NULL}, - {"CLNE", PIXPACK(0xFFD010), 0.0f, 0.00f * CFDS, 0.90f, 0.00f, 0.0f, 0.0f, 0.00f, 0.000f * CFDS, 0, 0, 0, 0, 1, 1, 1, 100, SC_SPECIAL, R_TEMP+0.0f +273.15f, 251, "Solid. Duplicates any particles it touches.", ST_SOLID, TYPE_SOLID, &update_CLNE, NULL}, - {"GAS", PIXPACK(0xE0FF20), 1.0f, 0.01f * CFDS, 0.99f, 0.30f, -0.1f, 0.0f, 0.75f, 0.001f * CFDS, 0, 600, 0, 0, 1, 1, 1, 1, SC_GAS, R_TEMP+2.0f +273.15f, 42, "Gas. Diffuses. Flammable. Liquefies under pressure.", ST_GAS, TYPE_GAS, NULL, NULL}, - {"C-4", PIXPACK(0xD080E0), 0.0f, 0.00f * CFDS, 0.90f, 0.00f, 0.0f, 0.0f, 0.00f, 0.000f * CFDS, 0, 1000, 2, 50, 1, 1, 1, 100, SC_EXPLOSIVE, R_TEMP+0.0f +273.15f, 88, "Solid. Pressure sensitive explosive.", ST_SOLID, TYPE_SOLID | PROP_NEUTPENETRATE, NULL, NULL}, - {"GOO", PIXPACK(0x804000), 0.0f, 0.00f * CFDS, 0.97f, 0.50f, 0.0f, 0.0f, 0.00f, 0.000f * CFDS, 0, 0, 0, 0, 12, 1, 1, 100, SC_SOLIDS, R_TEMP+0.0f +273.15f, 75, "Solid. Deforms and disappears under pressure.", ST_SOLID, TYPE_SOLID | PROP_NEUTPENETRATE|PROP_LIFE_DEC|PROP_LIFE_KILL_DEC, &update_GOO, NULL}, - {"ICE", PIXPACK(0xA0C0FF), 0.0f, 0.00f * CFDS, 0.90f, 0.00f, 0.0f, 0.0f, 0.00f, -0.0003f* CFDS, 0, 0, 0, 0, 20, 1, 1, 100, SC_SOLIDS, R_TEMP-50.0f+273.15f, 46, "Solid. Freezes water. Crushes under pressure. Cools down air.", ST_SOLID, TYPE_SOLID|PROP_LIFE_DEC, &update_ICEI, NULL}, - {"METL", PIXPACK(0x404060), 0.0f, 0.00f * CFDS, 0.90f, 0.00f, 0.0f, 0.0f, 0.00f, 0.000f * CFDS, 0, 0, 0, 1, 1, 1, 1, 100, SC_ELEC, R_TEMP+0.0f +273.15f, 251, "Solid. Conducts electricity. Meltable.", ST_SOLID, TYPE_SOLID|PROP_CONDUCTS|PROP_LIFE_DEC|PROP_HOT_GLOW, NULL, NULL}, - {"SPRK", PIXPACK(0xFFFF80), 0.0f, 0.00f * CFDS, 0.90f, 0.00f, 0.0f, 0.0f, 0.00f, 0.001f * CFDS, 0, 0, 0, 0, 1, 1, 1, 100, SC_ELEC, R_TEMP+0.0f +273.15f, 251, "Electricity. Conducted by metal and water.", ST_SOLID, TYPE_SOLID|PROP_LIFE_DEC, &update_SPRK, &graphics_SPRK}, - {"SNOW", PIXPACK(0xC0E0FF), 0.7f, 0.01f * CFDS, 0.96f, 0.90f, -0.1f, 0.05f, 0.01f, -0.00005f* CFDS,1, 0, 0, 0, 20, 1, 1, 50, SC_POWDERS, R_TEMP-30.0f+273.15f, 46, "Light particles.", ST_SOLID, TYPE_PART|PROP_LIFE_DEC, &update_ICEI, NULL}, - {"WOOD", PIXPACK(0xC0A040), 0.0f, 0.00f * CFDS, 0.90f, 0.00f, 0.0f, 0.0f, 0.00f, 0.000f * CFDS, 0, 20, 0, 0, 15, 1, 1, 100, SC_SOLIDS, R_TEMP+0.0f +273.15f, 164, "Solid. Flammable.", ST_SOLID, TYPE_SOLID | PROP_NEUTPENETRATE, NULL, NULL}, - {"NEUT", PIXPACK(0x20E0FF), 0.0f, 0.00f * CFDS, 1.00f, 1.00f, -0.99f, 0.0f, 0.01f, 0.002f * CFDS, 0, 0, 0, 0, 0, 1, 1, -1, SC_NUCLEAR, R_TEMP+4.0f +273.15f, 60, "Neutrons. Interact with matter in odd ways.", ST_GAS, TYPE_ENERGY|PROP_LIFE_DEC|PROP_LIFE_KILL_DEC, &update_NEUT, &graphics_NEUT}, - {"PLUT", PIXPACK(0x407020), 0.4f, 0.01f * CFDS, 0.99f, 0.95f, 0.0f, 0.4f, 0.00f, 0.000f * CFDS, 1, 0, 0, 0, 0, 1, 1, 90, SC_NUCLEAR, R_TEMP+4.0f +273.15f, 251, "Heavy particles. Fissile. Generates neutrons under pressure.", ST_SOLID, TYPE_PART|PROP_NEUTPENETRATE|PROP_RADIOACTIVE, &update_PLUT, NULL}, - {"PLNT", PIXPACK(0x0CAC00), 0.0f, 0.00f * CFDS, 0.95f, 0.00f, 0.0f, 0.0f, 0.00f, 0.000f * CFDS, 0, 20, 0, 0, 10, 1, 1, 100, SC_SOLIDS, R_TEMP+0.0f +273.15f, 65, "Plant, drinks water and grows.", ST_SOLID, TYPE_SOLID|PROP_NEUTPENETRATE|PROP_LIFE_DEC, &update_PLNT, NULL}, - {"ACID", PIXPACK(0xED55FF), 0.6f, 0.01f * CFDS, 0.98f, 0.95f, 0.0f, 0.1f, 0.00f, 0.000f * CFDS, 2, 40, 0, 0, 1, 1, 1, 10, SC_LIQUID, R_TEMP+0.0f +273.15f, 34, "Dissolves almost everything.", ST_LIQUID, TYPE_LIQUID|PROP_DEADLY, &update_ACID, &graphics_ACID}, - {"VOID", PIXPACK(0x790B0B), 0.0f, 0.00f * CFDS, 1.00f, 0.00f, 0.0f, 0.0f, 0.00f, -0.0003f* CFDS, 0, 0, 0, 0, 0, 1, 1, 100, SC_SPECIAL, R_TEMP+0.0f +273.15f, 251, "Hole, will drain away any particles.", ST_SOLID, TYPE_SOLID, NULL, NULL}, - {"WTRV", PIXPACK(0xA0A0FF), 1.0f, 0.01f * CFDS, 0.99f, 0.30f, -0.1f, -0.1f, 0.75f, 0.0003f * CFDS, 0, 0, 0, 0, 4, 1, 1, 1, SC_GAS, R_TEMP+100.0f+273.15f, 48, "Steam, heats up air, produced from hot water.", ST_GAS, TYPE_GAS, &update_WTRV, NULL}, - {"CNCT", PIXPACK(0xC0C0C0), 0.4f, 0.04f * CFDS, 0.94f, 0.95f, -0.1f, 0.3f, 0.00f, 0.000f * CFDS, 1, 0, 0, 2, 2, 1, 1, 55, SC_POWDERS, R_TEMP+0.0f +273.15f, 100, "Concrete, stronger than stone.", ST_SOLID, TYPE_PART|PROP_HOT_GLOW, NULL, NULL}, - {"DSTW", PIXPACK(0x1020C0), 0.6f, 0.01f * CFDS, 0.98f, 0.95f, 0.0f, 0.1f, 0.00f, 0.000f * CFDS, 2, 0, 0, 0, 20, 1, 1, 30, SC_LIQUID, R_TEMP-2.0f +273.15f, 23, "Distilled water, does not conduct electricity.", ST_LIQUID, TYPE_LIQUID|PROP_NEUTPENETRATE, &update_DSTW, NULL}, - {"SALT", PIXPACK(0xFFFFFF), 0.4f, 0.04f * CFDS, 0.94f, 0.95f, -0.1f, 0.3f, 0.00f, 0.000f * CFDS, 1, 0, 0, 5, 1, 1, 1, 75, SC_POWDERS, R_TEMP+0.0f +273.15f, 110, "Salt, dissolves in water.", ST_SOLID, TYPE_PART, NULL, NULL}, - {"SLTW", PIXPACK(0x4050F0), 0.6f, 0.01f * CFDS, 0.98f, 0.95f, 0.0f, 0.1f, 0.00f, 0.000f * CFDS, 2, 0, 0, 0, 20, 1, 1, 35, SC_LIQUID, R_TEMP+0.0f +273.15f, 75, "Saltwater, conducts electricity, difficult to freeze.", ST_LIQUID, TYPE_LIQUID|PROP_CONDUCTS|PROP_LIFE_DEC|PROP_NEUTPENETRATE, &update_SLTW, NULL}, - {"DMND", PIXPACK(0xCCFFFF), 0.0f, 0.00f * CFDS, 0.90f, 0.00f, 0.0f, 0.0f, 0.00f, 0.000f * CFDS, 0, 0, 0, 0, 0, 1, 1, 100, SC_SOLIDS, R_TEMP+0.0f +273.15f, 186, "Diamond. Indestructible.", ST_SOLID, TYPE_SOLID, NULL, NULL}, - {"BMTL", PIXPACK(0x505070), 0.0f, 0.00f * CFDS, 0.90f, 0.00f, 0.0f, 0.0f, 0.00f, 0.000f * CFDS, 0, 0, 0, 1, 1, 1, 1, 100, SC_SOLIDS, R_TEMP+0.0f +273.15f, 251, "Breakable metal.", ST_SOLID, TYPE_SOLID|PROP_CONDUCTS|PROP_LIFE_DEC|PROP_HOT_GLOW, &update_BMTL, NULL}, - {"BRMT", PIXPACK(0x705060), 0.4f, 0.04f * CFDS, 0.94f, 0.95f, -0.1f, 0.3f, 0.00f, 0.000f * CFDS, 1, 0, 0, 2, 2, 1, 1, 90, SC_POWDERS, R_TEMP+0.0f +273.15f, 211, "Broken metal.", ST_SOLID, TYPE_PART|PROP_CONDUCTS|PROP_LIFE_DEC|PROP_HOT_GLOW, &update_BRMT, NULL}, - {"PHOT", PIXPACK(0xFFFFFF), 0.0f, 0.00f * CFDS, 1.00f, 1.00f, -0.99f, 0.0f, 0.00f, 0.000f * CFDS, 0, 0, 0, 0, 0, 1, 1, -1, SC_NUCLEAR, R_TEMP+900.0f+273.15f, 251, "Photons. Travel in straight lines.", ST_GAS, TYPE_ENERGY|PROP_LIFE_DEC|PROP_LIFE_KILL_DEC, &update_PHOT, &graphics_PHOT}, - {"URAN", PIXPACK(0x707020), 0.4f, 0.01f * CFDS, 0.99f, 0.95f, 0.0f, 0.4f, 0.00f, 0.000f * CFDS, 1, 0, 0, 0, 0, 1, 1, 90, SC_NUCLEAR, R_TEMP+30.0f+273.15f, 251, "Heavy particles. Generates heat under pressure.", ST_SOLID, TYPE_PART | PROP_RADIOACTIVE, &update_URAN, NULL}, - {"WAX", PIXPACK(0xF0F0BB), 0.0f, 0.00f * CFDS, 0.90f, 0.00f, 0.0f, 0.0f, 0.00f, 0.000f * CFDS, 0, 0, 0, 0, 10, 1, 1, 100, SC_SOLIDS, R_TEMP+0.0f +273.15f, 44, "Wax. Melts at moderately high temperatures.", ST_SOLID, TYPE_SOLID, NULL, NULL}, - {"MWAX", PIXPACK(0xE0E0AA), 0.3f, 0.02f * CFDS, 0.95f, 0.80f, 0.0f, 0.15f, 0.00f, 0.000001f* CFDS,2, 5, 0, 0, 2, 1, 1, 25, SC_LIQUID, R_TEMP+28.0f+273.15f, 44, "Liquid Wax.", ST_LIQUID, TYPE_LIQUID, NULL, NULL}, - {"PSCN", PIXPACK(0x805050), 0.0f, 0.00f * CFDS, 0.90f, 0.00f, 0.0f, 0.0f, 0.00f, 0.000f * CFDS, 0, 0, 0, 1, 1, 1, 1, 100, SC_ELEC, R_TEMP+0.0f +273.15f, 251, "P-Type Silicon, Will transfer current to any conductor.", ST_SOLID, TYPE_SOLID|PROP_CONDUCTS|PROP_LIFE_DEC, NULL, NULL}, - {"NSCN", PIXPACK(0x505080), 0.0f, 0.00f * CFDS, 0.90f, 0.00f, 0.0f, 0.0f, 0.00f, 0.000f * CFDS, 0, 0, 0, 1, 1, 1, 1, 100, SC_ELEC, R_TEMP+0.0f +273.15f, 251, "N-Type Silicon, Will not transfer current to P-Type Silicon.", ST_SOLID, TYPE_SOLID|PROP_CONDUCTS|PROP_LIFE_DEC, NULL, NULL}, - {"LN2", PIXPACK(0x80A0DF), 0.6f, 0.01f * CFDS, 0.98f, 0.95f, 0.0f, 0.1f, 0.00f, 0.000f * CFDS, 2, 0, 0, 0, 0, 1, 1, 30, SC_LIQUID, 70.15f, 70, "Liquid Nitrogen. Very cold.", ST_SOLID, TYPE_LIQUID, NULL, NULL}, - {"INSL", PIXPACK(0x9EA3B6), 0.0f, 0.00f * CFDS, 0.95f, 0.00f, 0.0f, 0.0f, 0.00f, 0.000f * CFDS, 0, 7, 0, 0, 10, 1, 1, 100, SC_SPECIAL, R_TEMP+0.0f +273.15f, 0, "Insulator, does not conduct heat or electricity.", ST_SOLID, TYPE_SOLID, NULL, NULL}, - {"VACU", PIXPACK(0x303030), 0.0f, 0.00f * CFDS, 0.95f, 0.00f, 0.0f, 0.0f, 0.00f, -0.01f * CFDS, 0, 0, 0, 0, 0, 1, 1, 100, SC_SPECIAL, R_TEMP+70.0f+273.15f, 255, "Vacuum, sucks in other particles and heats up.", ST_NONE, TYPE_SOLID, NULL, NULL}, - {"VENT", PIXPACK(0xEFEFEF), 0.0f, 0.00f * CFDS, 0.95f, 0.00f, 0.0f, 0.0f, 0.00f, 0.010f * CFDS, 0, 0, 0, 0, 0, 1, 1, 100, SC_SPECIAL, R_TEMP-16.0f+273.15f, 255, "Air vent, creates pressure and pushes other particles away.", ST_NONE, TYPE_SOLID, NULL, NULL}, - {"RBDM", PIXPACK(0xCCCCCC), 0.0f, 0.00f * CFDS, 0.90f, 0.00f, 0.0f, 0.0f, 0.00f, 0.000f * CFDS, 0, 1000, 1, 50, 1, 1, 1, 100, SC_EXPLOSIVE, R_TEMP+0.0f +273.15f, 240, "Rubidium, explosive, especially on contact with water, low melting point", ST_SOLID, TYPE_SOLID|PROP_CONDUCTS|PROP_LIFE_DEC, NULL, NULL}, - {"LRBD", PIXPACK(0xAAAAAA), 0.3f, 0.02f * CFDS, 0.95f, 0.80f, 0.0f, 0.15f, 0.00f, 0.000001f* CFDS,2, 1000, 1, 0, 2, 1, 1, 45, SC_EXPLOSIVE, R_TEMP+45.0f+273.15f, 170, "Liquid Rubidium.", ST_LIQUID, TYPE_LIQUID|PROP_CONDUCTS|PROP_LIFE_DEC, NULL, NULL}, - {"NTCT", PIXPACK(0x505040), 0.0f, 0.00f * CFDS, 0.90f, 0.00f, 0.0f, 0.0f, 0.00f, 0.000f * CFDS, 0, 0, 0, 1, 1, 1, 1, 100, SC_ELEC, R_TEMP+0.0f +273.15f, 251, "Semi-conductor. Only conducts electricity when hot (More than 100C)", ST_SOLID, TYPE_SOLID|PROP_CONDUCTS|PROP_LIFE_DEC, &update_NPTCT, NULL}, - {"SAND", PIXPACK(0xFFD090), 0.4f, 0.04f * CFDS, 0.94f, 0.95f, -0.1f, 0.3f, 0.00f, 0.000f * CFDS, 1, 0, 0, 5, 1, 1, 1, 90, SC_POWDERS, R_TEMP+0.0f +273.15f, 150, "Sand, Heavy particles. Meltable.", ST_SOLID, TYPE_PART, NULL, NULL}, - {"GLAS", PIXPACK(0x404040), 0.0f, 0.00f * CFDS, 0.90f, 0.00f, 0.0f, 0.0f, 0.00f, 0.000f * CFDS, 0, 0, 0, 0, 0, 1, 1, 100, SC_SOLIDS, R_TEMP+0.0f +273.15f, 150, "Solid. Meltable. Shatters under pressure", ST_SOLID, TYPE_SOLID | PROP_NEUTPASS | PROP_HOT_GLOW | PROP_SPARKSETTLE, &update_GLAS, NULL}, - {"PTCT", PIXPACK(0x405050), 0.0f, 0.00f * CFDS, 0.90f, 0.00f, 0.0f, 0.0f, 0.00f, 0.000f * CFDS, 0, 0, 0, 1, 1, 1, 1, 100, SC_ELEC, R_TEMP+0.0f +273.15f, 251, "Semi-conductor. Only conducts electricity when cold (Less than 100C)", ST_SOLID, TYPE_SOLID|PROP_CONDUCTS|PROP_LIFE_DEC, &update_NPTCT, NULL}, - {"BGLA", PIXPACK(0x606060), 0.4f, 0.04f * CFDS, 0.94f, 0.95f, -0.1f, 0.3f, 0.00f, 0.000f * CFDS, 1, 0, 0, 5, 2, 1, 1, 90, SC_POWDERS, R_TEMP+0.0f +273.15f, 150, "Broken Glass, Heavy particles. Meltable. Bagels.", ST_SOLID, TYPE_PART | PROP_HOT_GLOW, NULL, NULL}, - {"THDR", PIXPACK(0xFFFFA0), 0.0f, 0.00f * CFDS, 1.0f, 0.30f, -0.99f, 0.6f, 0.62f, 0.000f * CFDS, 0, 0, 0, 0, 0, 1, 1, 1, SC_EXPLOSIVE, 9000.0f +273.15f, 1, "Lightning! Very hot, inflicts damage upon most materials, transfers current to metals.", ST_NONE, TYPE_ENERGY, &update_THDR, &graphics_THDR}, - {"PLSM", PIXPACK(0xBB99FF), 0.9f, 0.04f * CFDS, 0.97f, 0.20f, 0.0f, -0.1f, 0.30f, 0.001f * CFDS, 0, 0, 0, 0, 0, 1, 1, 1, SC_GAS, 10000.0f +273.15f, 5, "Plasma, extremely hot.", ST_NONE, TYPE_GAS|PROP_LIFE_DEC|PROP_LIFE_KILL, &update_PYRO, &graphics_PLSM}, - {"ETRD", PIXPACK(0x404040), 0.0f, 0.00f * CFDS, 0.90f, 0.00f, 0.0f, 0.0f, 0.00f, 0.000f * CFDS, 0, 0, 0, 1, 1, 1, 1, 100, SC_ELEC, R_TEMP+0.0f +273.15f, 251, "Electrode. Creates a surface that allows Plasma arcs. (Use sparingly)", ST_NONE, TYPE_SOLID|PROP_CONDUCTS|PROP_LIFE_DEC, NULL, NULL}, - {"NICE", PIXPACK(0xC0E0FF), 0.0f, 0.00f * CFDS, 0.90f, 0.00f, 0.0f, 0.0f, 0.00f, -0.0005f* CFDS, 0, 0, 0, 0, 20, 1, 1, 100, SC_SOLIDS, 35.0f, 46, "Nitrogen Ice.", ST_SOLID, TYPE_SOLID, NULL, NULL}, - {"NBLE", PIXPACK(0xEB4917), 1.0f, 0.01f * CFDS, 0.99f, 0.30f, -0.1f, 0.0f, 0.75f, 0.001f * CFDS, 0, 0, 0, 0, 1, 1, 1, 1, SC_GAS, R_TEMP+2.0f +273.15f, 106, "Noble Gas. Diffuses. Conductive. Ionizes into plasma when introduced to electricity", ST_GAS, TYPE_GAS|PROP_CONDUCTS|PROP_LIFE_DEC, &update_NBLE, NULL}, - {"BTRY", PIXPACK(0x858505), 0.0f, 0.00f * CFDS, 0.90f, 0.00f, 0.0f, 0.0f, 0.00f, 0.000f * CFDS, 0, 0, 0, 1, 1, 1, 1, 100, SC_ELEC, R_TEMP+0.0f +273.15f, 251, "Solid. Generates Electricity.", ST_SOLID, TYPE_SOLID, &update_BTRY, NULL}, - {"LCRY", PIXPACK(0x505050), 0.0f, 0.00f * CFDS, 0.90f, 0.00f, 0.0f, 0.0f, 0.00f, 0.000f * CFDS, 0, 0, 0, 1, 1, 1, 1, 100, SC_POWERED, R_TEMP+0.0f +273.15f, 251, "Liquid Crystal. Changes colour when charged. (PSCN Charges, NSCN Discharges)", ST_SOLID, TYPE_SOLID, &update_LCRY, &graphics_LCRY}, - {"STKM", PIXPACK(0x000000), 0.5f, 0.00f * CFDS, 0.2f, 1.0f, 0.0f, 0.0f, 0.0f, 0.00f * CFDS, 0, 0, 0, 0, 0, 1, 1, 50, SC_SPECIAL, R_TEMP+14.6f+273.15f, 0, "Stickman. Don't kill him!", ST_NONE, 0, &update_STKM, &graphics_STKM}, - {"SWCH", PIXPACK(0x103B11), 0.0f, 0.00f * CFDS, 0.90f, 0.00f, 0.0f, 0.0f, 0.00f, 0.000f * CFDS, 0, 0, 0, 0, 1, 1, 1, 100, SC_ELEC, R_TEMP+0.0f +273.15f, 251, "Solid. Only conducts when switched on. (PSCN switches on, NSCN switches off)", ST_SOLID, TYPE_SOLID, &update_SWCH, &graphics_SWCH}, - {"SMKE", PIXPACK(0x222222), 0.9f, 0.04f * CFDS, 0.97f, 0.20f, 0.0f, -0.1f, 0.00f, 0.001f * CFDS, 1, 0, 0, 0, 1, 1, 1, 1, SC_GAS, R_TEMP+320.0f+273.15f, 88, "Smoke", ST_SOLID, TYPE_GAS|PROP_LIFE_DEC|PROP_LIFE_KILL_DEC, NULL, &graphics_SMKE}, - {"DESL", PIXPACK(0x440000), 1.0f, 0.01f * CFDS, 0.98f, 0.95f, 0.0f, 0.1f, 0.0f, 0.0f * CFDS, 2, 2, 0, 0, 5, 1, 1, 15, SC_LIQUID, R_TEMP+0.0f +273.15f, 42, "Liquid. Explodes under high pressure and temperatures", ST_LIQUID, TYPE_LIQUID, NULL, NULL}, - {"COAL", PIXPACK(0x222222), 0.0f, 0.00f * CFDS, 0.90f, 0.00f, 0.0f, 0.0f, 0.0f, 0.0f * CFDS, 0, 0, 0, 0, 20, 1, 1, 100, SC_SOLIDS, R_TEMP+0.0f +273.15f, 200, "Solid. Burns slowly.", ST_SOLID, TYPE_SOLID, &update_COAL, &graphics_COAL}, - {"LOXY", PIXPACK(0x80A0EF), 0.6f, 0.01f * CFDS, 0.98f, 0.95f, 0.0f, 0.1f, 0.00f, 0.000f * CFDS, 2, 5000, 0, 0, 0, 1, 1, 30, SC_LIQUID, 80.0f, 70, "Liquid Oxygen. Very cold. Reacts with fire", ST_LIQUID, TYPE_LIQUID, NULL, NULL}, - {"OXYG", PIXPACK(0x80A0FF), 2.0f, 0.00f * CFDS, 0.99f, 0.30f, -0.1f, 0.0f, 3.0f, 0.000f * CFDS, 0, 0, 0, 0, 0, 1, 1, 1, SC_GAS, R_TEMP+0.0f +273.15f, 70, "Gas. Ignites easily.", ST_GAS, TYPE_GAS, &update_O2, NULL}, - {"INWR", PIXPACK(0x544141), 0.0f, 0.00f * CFDS, 0.90f, 0.00f, 0.0f, 0.0f, 0.00f, 0.000f * CFDS, 0, 0, 0, 1, 1, 1, 1, 100, SC_ELEC, R_TEMP+0.0f +273.15f, 251, "Insulated Wire. Doesn't conduct to metal or semiconductors.", ST_SOLID, TYPE_SOLID|PROP_CONDUCTS|PROP_LIFE_DEC, NULL, NULL}, - {"YEST", PIXPACK(0xEEE0C0), 0.7f, 0.02f * CFDS, 0.96f, 0.80f, 0.0f, 0.1f, 0.00f, 0.000f * CFDS, 1, 15, 0, 0, 30, 1, 1, 80, SC_POWDERS, R_TEMP+0.0f +273.15f, 70, "Yeast, grows when warm (~37C).", ST_SOLID, TYPE_PART, &update_YEST, NULL}, - {"DYST", PIXPACK(0xBBB0A0), 0.7f, 0.02f * CFDS, 0.96f, 0.80f, 0.0f, 0.1f, 0.00f, 0.000f * CFDS, 1, 20, 0, 0, 30, 0, 1, 80, SC_POWDERS, R_TEMP+0.0f +273.15f, 70, "Dead Yeast.", ST_SOLID, TYPE_PART, NULL, NULL}, - {"THRM", PIXPACK(0xA08090), 0.4f, 0.04f * CFDS, 0.94f, 0.95f, -0.1f, 0.3f, 0.00f, 0.000f * CFDS, 1, 0, 0, 2, 2, 1, 1, 90, SC_EXPLOSIVE, R_TEMP+0.0f +273.15f, 211, "Thermite. Burns at extremely high temperature.", ST_SOLID, TYPE_PART, &update_THRM, NULL}, - {"GLOW", PIXPACK(0x445464), 0.3f, 0.02f * CFDS, 0.98f, 0.80f, 0.0f, 0.15f, 0.00f, 0.000f * CFDS, 2, 0, 0, 0, 2, 1, 1, 40, SC_LIQUID, R_TEMP+20.0f+273.15f, 44, "Glow, Glows under pressure", ST_LIQUID, TYPE_LIQUID|PROP_LIFE_DEC, &update_GLOW, &graphics_GLOW}, - {"BRCK", PIXPACK(0x808080), 0.0f, 0.00f * CFDS, 0.90f, 0.00f, 0.0f, 0.0f, 0.00f, 0.000f * CFDS, 0, 0, 0, 0, 1, 1, 1, 100, SC_SOLIDS, R_TEMP+0.0f +273.15f, 251, "Brick, breakable building material.", ST_SOLID, TYPE_SOLID|PROP_HOT_GLOW, NULL, NULL}, - {"CFLM", PIXPACK(0x8080FF), 0.9f, 0.04f * CFDS, 0.97f, 0.20f, 0.0f, -0.1f, 0.00f, 0.0005f * CFDS, 1, 0, 0, 0, 1, 1, 1, 2, SC_EXPLOSIVE, 0.0f, 88, "Sub-zero flame.", ST_LIQUID, TYPE_GAS|PROP_LIFE_DEC|PROP_LIFE_KILL, NULL, &graphics_HFLM}, - {"FIRW", PIXPACK(0xFFA040), 0.7f, 0.02f * CFDS, 0.96f, 0.80f, -0.99f, 0.1f, 0.00f, 0.000f * CFDS, 1, 0, 0, 0, 30, 1, 1, 55, SC_EXPLOSIVE, R_TEMP+0.0f +273.15f, 70, "Fireworks!", ST_SOLID, TYPE_PART|PROP_LIFE_DEC, &update_FIRW, &graphics_FIRW}, - {"FUSE", PIXPACK(0x0A5706), 0.0f, 0.00f * CFDS, 0.90f, 0.00f, 0.0f, 0.0f, 0.0f, 0.0f * CFDS, 0, 0, 0, 0, 20, 1, 1, 100, SC_SOLIDS, R_TEMP+0.0f +273.15f, 200, "Solid. Burns slowly. Ignites at somewhat high temperatures and electricity.", ST_SOLID, TYPE_SOLID, &update_FUSE, NULL}, - {"FSEP", PIXPACK(0x63AD5F), 0.7f, 0.02f * CFDS, 0.96f, 0.80f, 0.0f, 0.1f, 0.00f, 0.000f * CFDS, 1, 0, 0, 0, 30, 1, 1, 70, SC_POWDERS, R_TEMP+0.0f +273.15f, 70, "Fuse Powder. See FUSE.", ST_SOLID, TYPE_PART, &update_FSEP, NULL}, - {"AMTR", PIXPACK(0x808080), 0.7f, 0.02f * CFDS, 0.96f, 0.80f, 0.00f, 0.10f, 1.00f, 0.0000f * CFDS, 0, 0, 0, 0, 0, 1, 1, 100, SC_NUCLEAR, R_TEMP+0.0f +273.15f, 70, "Anti-Matter, Destroys a majority of particles", ST_NONE, TYPE_PART, &update_AMTR, NULL}, //Maybe TYPE_ENERGY? - {"BCOL", PIXPACK(0x333333), 0.4f, 0.04f * CFDS, 0.94f, 0.95f, -0.1f, 0.3f, 0.00f, 0.000f * CFDS, 1, 0, 0, 5, 2, 1, 1, 90, SC_POWDERS, R_TEMP+0.0f +273.15f, 150, "Broken Coal. Heavy particles. See COAL", ST_SOLID, TYPE_PART, &update_BCOL, &graphics_COAL}, - {"PCLN", PIXPACK(0x3B3B0A), 0.0f, 0.00f * CFDS, 0.90f, 0.00f, 0.0f, 0.0f, 0.00f, 0.000f * CFDS, 0, 0, 0, 0, 1, 1, 1, 100, SC_POWERED, R_TEMP+0.0f +273.15f, 251, "Solid. When activated, duplicates any particles it touches.", ST_NONE, TYPE_SOLID, &update_PCLN, &graphics_PCLN}, - {"HSWC", PIXPACK(0x3B0A0A), 0.0f, 0.00f * CFDS, 0.90f, 0.00f, 0.0f, 0.0f, 0.00f, 0.000f * CFDS, 0, 0, 0, 1, 1, 1, 1, 100, SC_POWERED, R_TEMP+0.0f +273.15f, 251, "Heat switch. Conducts Heat only when activated", ST_NONE, TYPE_SOLID, &update_HSWC, &graphics_HSWC}, - {"IRON", PIXPACK(0x707070), 0.0f, 0.00f * CFDS, 0.90f, 0.00f, 0.0f, 0.0f, 0.00f, 0.000f * CFDS, 0, 0, 0, 1, 50, 1, 1, 100, SC_SOLIDS, R_TEMP+0.0f +273.15f, 251, "Rusts with salt, can be used for electrolysis of WATR", ST_SOLID, TYPE_SOLID|PROP_CONDUCTS|PROP_LIFE_DEC|PROP_HOT_GLOW, &update_IRON, NULL}, - {"MORT", PIXPACK(0xE0E0E0), 0.0f, 0.00f * CFDS, 1.00f, 1.00f, -0.99f, 0.0f, 0.01f, 0.002f * CFDS, 0, 0, 0, 0, 0, 1, 1, -1, SC_CRACKER2, R_TEMP+4.0f +273.15f, 60, "Steam Train.", ST_NONE, TYPE_PART, &update_MORT, NULL}, - {"LIFE", PIXPACK(0x0CAC00), 0.0f, 0.00f * CFDS, 0.90f, 0.00f, 0.0f, 0.0f, 0.00f, 0.000f * CFDS, 0, 0, 0, 0, 0, 0, 1, 100, SC_LIFE, 9000.0f, 40, "Game Of Life! B3/S23", ST_NONE, TYPE_SOLID|PROP_LIFE, NULL, &graphics_LIFE}, - {"DLAY", PIXPACK(0x753590), 0.0f, 0.00f * CFDS, 0.90f, 0.00f, 0.0f, 0.0f, 0.00f, 0.000f * CFDS, 0, 0, 0, 1, 1, 1, 1, 100, SC_POWERED, 4.0f+273.15f, 0, "Conducts with temperature-dependent delay. (use HEAT/COOL).", ST_SOLID, TYPE_SOLID, &update_DLAY, &graphics_DLAY}, - {"CO2", PIXPACK(0x666666), 2.0f, 0.00f * CFDS, 0.99f, 0.30f, -0.1f, 0.1f, 1.0f, 0.000f * CFDS, 1, 0, 0, 0, 0, 1, 1, 1, SC_GAS, R_TEMP+273.15f, 88, "Carbon Dioxide", ST_GAS, TYPE_GAS, &update_CO2, NULL}, - {"DRIC", PIXPACK(0xE0E0E0), 0.0f, 0.00f * CFDS, 0.90f, 0.00f, 0.0f, 0.0f, 0.00f, -0.0005f* CFDS, 0, 0, 0, 0, 20, 1, 1, 100, SC_SOLIDS, 172.65f, 2, "Dry Ice.", ST_SOLID, TYPE_SOLID, NULL, NULL}, - {"BUBW", PIXPACK(0x2030D0), 0.6f, 0.01f * CFDS, 0.98f, 0.95f, 0.0f, 0.1f, 0.00f, 0.000f * CFDS, 2, 0, 0, 0, 20, 1, 1, 30, SC_LIQUID, R_TEMP-2.0f +273.15f, 29, "Carbonated water. Conducts electricity. Freezes. Extinguishes fires.", ST_LIQUID, TYPE_LIQUID|PROP_CONDUCTS|PROP_LIFE_DEC|PROP_NEUTPENETRATE, &update_CBNW, &graphics_CBNW}, - {"STOR", PIXPACK(0x50DFDF), 0.0f, 0.00f * CFDS, 0.90f, 0.00f, 0.0f, 0.0f, 0.00f, 0.000f * CFDS, 0, 0, 0, 0, 1, 1, 1, 100, SC_POWERED, R_TEMP+0.0f +273.15f, 251, "Solid. Stores a single particle, releases when charged with PSCN, also passes to PIPE", ST_NONE, TYPE_SOLID, &update_STOR, &graphics_STOR}, - {"PVOD", PIXPACK(0x792020), 0.0f, 0.00f * CFDS, 0.90f, 0.00f, 0.0f, 0.0f, 0.00f, 0.000f * CFDS, 0, 0, 0, 0, 1, 1, 1, 100, SC_POWERED, R_TEMP+0.0f +273.15f, 251, "Solid. When activated, destroys entering particles", ST_NONE, TYPE_SOLID, &update_PVOD, &graphics_PVOD}, - {"CONV", PIXPACK(0x0AAB0A), 0.0f, 0.00f * CFDS, 0.90f, 0.00f, 0.0f, 0.0f, 0.00f, 0.000f * CFDS, 0, 0, 0, 0, 1, 1, 1, 100, SC_SPECIAL, R_TEMP+0.0f +273.15f, 251, "Solid. Converts whatever touches it into its ctype.", ST_NONE, TYPE_SOLID, &update_CONV, NULL}, - {"CAUS", PIXPACK(0x80FFA0), 2.0f, 0.00f * CFDS, 0.99f, 0.30f, -0.1f, 0.0f, 1.50f, 0.000f * CFDS, 0, 0, 0, 0, 0, 1, 1, 1, SC_GAS, R_TEMP+0.0f +273.15f, 70, "Caustic Gas, acts like Acid", ST_GAS, TYPE_GAS|PROP_DEADLY, &update_CAUS, NULL}, - {"LIGH", PIXPACK(0xFFFFC0), 0.0f, 0.00f * CFDS, 0.90f, 0.00f, 0.0f, 0.0f, 0.00f, 0.000f * CFDS, 0, 0, 0, 1, 1, 1, 1, 100, SC_ELEC, R_TEMP+0.0f +273.15f, 0, "More realistic lightning. Set pen size to set the size of the lightning.", ST_SOLID, TYPE_SOLID, &update_LIGH, &graphics_LIGH}, - {"TESC", PIXPACK(0x707040), 0.0f, 0.00f * CFDS, 0.90f, 0.00f, 0.0f, 0.0f, 0.00f, 0.000f * CFDS, 0, 0, 0, 1, 1, 1, 1, 100, SC_ELEC, R_TEMP+0.0f +273.15f, 251, "Tesla coil!", ST_SOLID, TYPE_SOLID|PROP_CONDUCTS|PROP_LIFE_DEC|PROP_HOT_GLOW, NULL, NULL}, - {"DEST", PIXPACK(0xFF3311), -0.05f, 0.00f * CFDS, 0.95f, 0.95f, -0.1f, 0.4f, 0.00f, 0.000f * CFDS, 1, 0, 0, 0, 0, 1, 1, 101, SC_EXPLOSIVE, R_TEMP+0.0f +273.15f, 150, "More destructive Bomb.", ST_SOLID, TYPE_PART|PROP_LIFE_DEC|PROP_LIFE_KILL_DEC, &update_DEST, &graphics_DEST}, - {"SPNG", PIXPACK(0xFFBE30), 0.00f, 0.00f * CFDS, 0.00f, 0.00f, 0.00f, 0.0f, 0.00f, 0.000f * CFDS, 0, 20, 0, 1, 30, 1, 1, 100, SC_SOLIDS, R_TEMP+0.0f +273.15f, 251, "A sponge, absorbs water.", ST_SOLID, TYPE_SOLID, &update_SPNG, &graphics_SPNG}, - {"RIME", PIXPACK(0xCCCCCC), 0.00f, 0.00f * CFDS, 0.00f, 1.00f, 0.00f, 0.0f, 0.00f, 0.000f * CFDS, 0, 0, 0, 0, 30, 1, 1, 100, SC_CRACKER2, 243.15f, 100, "Not quite Ice", ST_SOLID, TYPE_SOLID, &update_RIME, NULL}, - {"FOG", PIXPACK(0xAAAAAA), 0.8f, 0.00f * CFDS, 0.4f, 0.70f, -0.1f, 0.0f, 0.99f, 0.000f * CFDS, 0, 0, 0, 0, 30, 1, 1, 1, SC_CRACKER2, 243.15f, 100, "Not quite Steam", ST_GAS, TYPE_GAS|PROP_LIFE_DEC, &update_FOG, NULL}, - {"BCLN", PIXPACK(0xFFD040), 0.0f, 0.00f * CFDS, 0.97f, 0.50f, 0.0f, 0.0f, 0.00f, 0.000f * CFDS, 0, 0, 0, 0, 12, 1, 1, 100, SC_SPECIAL, R_TEMP+0.0f +273.15f, 251, "Breakable Clone.", ST_NONE, TYPE_SOLID|PROP_LIFE_DEC|PROP_LIFE_KILL_DEC, &update_BCLN, NULL}, - {"LOVE", PIXPACK(0xFF30FF), 0.0f, 0.00f * CFDS, 0.00f, 0.00f, 0.0f, 0.0f, 0.0f, 0.000f * CFDS, 0, 0, 0, 0, 0, 1, 1, 100, SC_CRACKER2, 373.0f, 40, "Love...", ST_GAS, TYPE_SOLID, &update_MISC, NULL}, - {"DEUT", PIXPACK(0x00153F), 0.6f, 0.01f * CFDS, 0.98f, 0.95f, 0.0f, 0.1f, 0.00f, 0.000f * CFDS, 2, 0, 0, 0, 20, 1, 1, 31, SC_NUCLEAR, R_TEMP-2.0f +273.15f, 251, "Deuterium oxide. Volume changes with temp, radioactive with neutrons.", ST_LIQUID, TYPE_LIQUID|PROP_NEUTPENETRATE, &update_DEUT, &graphics_DEUT}, - {"WARP", PIXPACK(0x000000), 0.8f, 0.00f * CFDS, 0.9f, 0.70f, -0.1f, 0.0f, 3.00f, 0.000f * CFDS, 0, 0, 0, 0, 30, 1, 1, 1, SC_NUCLEAR, R_TEMP +273.15f, 100, "Displaces other elements.", ST_GAS, TYPE_GAS|PROP_LIFE_DEC|PROP_LIFE_KILL, &update_WARP, NULL}, - {"PUMP", PIXPACK(0x0A0A3B), 0.0f, 0.00f * CFDS, 0.95f, 0.00f, 0.0f, 0.0f, 0.00f, 0.000f * CFDS, 0, 0, 0, 0, 10, 1, 1, 100, SC_POWERED, 273.15f, 0, "Changes pressure to its temp when activated. (use HEAT/COOL).", ST_SOLID, TYPE_SOLID, &update_PUMP, &graphics_PUMP}, - {"FWRK", PIXPACK(0x666666), 0.4f, 0.01f * CFDS, 0.99f, 0.95f, 0.0f, 0.4f, 0.00f, 0.000f * CFDS, 1, 0, 0, 0, 1, 1, 1, 97, SC_EXPLOSIVE, R_TEMP+0.0f +273.15f, 100, "First fireworks made, activated by heat/neutrons.", ST_SOLID, TYPE_PART|PROP_LIFE_DEC, &update_FWRK, NULL}, - {"PIPE", PIXPACK(0x444444), 0.0f, 0.00f * CFDS, 0.95f, 0.00f, 0.0f, 0.0f, 0.00f, 0.000f * CFDS, 0, 0, 0, 0, 0, 1, 1, 100, SC_SOLIDS, 273.15f, 0, "Moves elements around, read FAQ on website for help.", ST_SOLID, TYPE_SOLID|PROP_LIFE_DEC, &update_PIPE, &graphics_PIPE}, - {"FRZZ", PIXPACK(0xC0E0FF), 0.7f, 0.01f * CFDS, 0.96f, 0.90f, -0.1f, 0.05f, 0.01f, -0.00005f* CFDS,1, 0, 0, 0, 20, 1, 1, 50, SC_POWDERS, 90.0f, 46, "FREEZE", ST_SOLID, TYPE_PART, &update_FRZZ, NULL}, - {"FRZW", PIXPACK(0x1020C0), 0.6f, 0.01f * CFDS, 0.98f, 0.95f, 0.0f, 0.1f, 0.00f, 0.000f * CFDS, 2, 0, 0, 0, 20, 1, 1, 30, SC_CRACKER2, 120.0f, 29, "FREEZE WATER", ST_LIQUID, TYPE_LIQUID||PROP_LIFE_DEC, &update_FRZW, NULL}, - {"GRAV", PIXPACK(0xFFE0A0), 0.7f, 0.00f * CFDS, 1.00f, 1.00f, 0.0f, 0.0f, 0.00f, 0.000f * CFDS, 1, 10, 0, 0, 30, 1, 1, 85, SC_POWDERS, R_TEMP+0.0f +273.15f, 70, "Very light dust. Changes colour based on velocity.", ST_SOLID, TYPE_PART, &update_MISC, &graphics_GRAV}, - {"BIZR", PIXPACK(0x00FF77), 0.6f, 0.01f * CFDS, 0.98f, 0.95f, 0.0f, 0.1f, 0.00f, 0.000f * CFDS, 2, 0, 0, 0, 20, 1, 1, 30, SC_LIQUID, R_TEMP+0.0f +273.15f, 29, "Bizarre... contradicts the normal state changes.", ST_LIQUID, TYPE_LIQUID, &update_BIZR, &graphics_BIZR}, - {"BIZG", PIXPACK(0x00FFBB), 1.0f, 0.01f * CFDS, 0.99f, 0.30f, -0.1f, 0.0f, 2.75f, 0.000f * CFDS, 0, 0, 0, 0, 1, 1, 1, 1, SC_CRACKER2, R_TEMP-200.0f+273.15f, 42, "Bizarre gas", ST_GAS, TYPE_GAS, &update_BIZR, &graphics_BIZR}, - {"BIZS", PIXPACK(0x00E455), 0.0f, 0.00f * CFDS, 0.90f, 0.00f, 0.0f, 0.0f, 0.00f, 0.000f * CFDS, 0, 0, 0, 1, 1, 1, 1, 100, SC_CRACKER2, R_TEMP+300.0f+273.15f, 251, "Bizarre solid", ST_SOLID, TYPE_SOLID, &update_BIZR, &graphics_BIZR}, - {"INST", PIXPACK(0x404039), 0.0f, 0.00f * CFDS, 0.90f, 0.00f, 0.0f, 0.0f, 0.00f, 0.000f * CFDS, 0, 0, 0, 1, 1, 1, 1, 100, SC_ELEC, R_TEMP+0.0f +273.15f, 251, "Instantly conducts, PSCN to charge, NSCN to take.", ST_SOLID, TYPE_SOLID|PROP_LIFE_DEC, NULL, NULL}, - {"ISOZ", PIXPACK(0xAA30D0), 0.6f, 0.01f * CFDS, 0.98f, 0.95f, 0.0f, 0.1f, 0.00f, 0.000f * CFDS, 2, 0, 0, 0, 0, 1, 1, 24, SC_NUCLEAR, R_TEMP-2.0f +273.15f, 29, "Radioactive liquid", ST_LIQUID, TYPE_LIQUID|PROP_NEUTPENETRATE, &update_ISZ, NULL}, - {"ISZS", PIXPACK(0x662089), 0.0f, 0.00f * CFDS, 0.90f, 0.00f, 0.0f, 0.0f, 0.00f, -0.0007f* CFDS, 0, 0, 0, 1, 1, 1, 1, 100, SC_NUCLEAR, 140.00f, 251, "Solid form of ISOZ, slowly decays.", ST_SOLID, TYPE_SOLID, &update_ISZ, NULL}, - {"PRTI", PIXPACK(0xEB5917), 0.0f, 0.00f * CFDS, 0.90f, 0.00f, 0.0f, 0.0f, 0.00f, -0.005f * CFDS, 0, 0, 0, 0, 0, 1, 1, 100, SC_SPECIAL, R_TEMP+0.0f +273.15f, 0, "Portal IN. Things go in here, now with channels (same as WIFI)", ST_SOLID, TYPE_SOLID, &update_PRTI, &graphics_PRTI}, - {"PRTO", PIXPACK(0x0020EB), 0.0f, 0.00f * CFDS, 0.90f, 0.00f, 0.0f, 0.0f, 0.00f, 0.005f * CFDS, 0, 0, 0, 0, 0, 1, 1, 100, SC_SPECIAL, R_TEMP+0.0f +273.15f, 0, "Portal OUT. Things come out here, now with channels (same as WIFI)", ST_SOLID, TYPE_SOLID, &update_PRTO, &graphics_PRTO}, - {"PSTE", PIXPACK(0xAA99AA), 0.6f, 0.01f * CFDS, 0.98f, 0.95f, 0.0f, 0.1f, 0.00f, 0.000f * CFDS, 2, 0, 0, 0, 20, 1, 1, 31, SC_LIQUID, R_TEMP-2.0f +273.15f, 29, "Colloid, Hardens under pressure", ST_LIQUID, TYPE_LIQUID, NULL, NULL}, - {"PSTS", PIXPACK(0x776677), 0.0f, 0.00f * CFDS, 0.00f, 0.00f, 0.0f, 0.0f, 0.00f, 0.000f * CFDS, 0, 0, 0, 0, 20, 0, 1, 100, SC_CRACKER, R_TEMP-2.0f +273.15f, 29, "Solid form of PSTE, temporary", ST_SOLID, TYPE_SOLID, NULL, NULL}, - {"ANAR", PIXPACK(0xFFFFEE), -0.7f, -0.02f * CFDS, 0.96f, 0.80f, 0.1f, -0.1f, 0.00f, 0.000f * CFDS, 1, 0, 0, 0, 30, 1, 1, 85, SC_POWDERS, R_TEMP+0.0f +273.15f, 70, "Very light dust. Behaves opposite gravity", ST_SOLID, TYPE_PART, &update_ANAR, NULL}, - {"VINE", PIXPACK(0x079A00), 0.0f, 0.00f * CFDS, 0.95f, 0.00f, 0.0f, 0.0f, 0.00f, 0.000f * CFDS, 0, 20, 0, 0, 10, 1, 1, 100, SC_SOLIDS, R_TEMP+0.0f +273.15f, 65, "Vine, grows", ST_SOLID, TYPE_SOLID, &update_VINE, NULL}, - {"INVS", PIXPACK(0x00CCCC), 0.0f, 0.00f * CFDS, 0.90f, 0.00f, 0.0f, 0.0f, 0.00f, 0.000f * CFDS, 0, 0, 0, 0, 15, 1, 1, 100, SC_SOLIDS, R_TEMP+0.0f +273.15f, 164, "Invisible to everything while under pressure.", ST_SOLID, TYPE_SOLID | PROP_NEUTPASS, NULL, &graphics_INVS}, - {"EQVE", PIXPACK(0xFFE0A0), 0.7f, 0.02f * CFDS, 0.96f, 0.80f, 0.0f, 0.1f, 0.00f, 0.000f * CFDS, 1, 0, 0, 0, 30, 0, 1, 85, SC_CRACKER2, R_TEMP+0.0f +273.15f, 70, "Shared velocity test", ST_SOLID, TYPE_PART, NULL, NULL}, - {"SPWN2", PIXPACK(0xAAAAAA), 0.0f, 0.00f * CFDS, 1.00f, 0.00f, 0.0f, 0.0f, 0.00f, 0.000f * CFDS, 0, 0, 0, 0, 1, 0, 1, 100, SC_SOLIDS, R_TEMP+0.0f +273.15f, 0, "STK2 spawn point", ST_SOLID, TYPE_SOLID, &update_SPAWN2, NULL}, - {"SPWN", PIXPACK(0xAAAAAA), 0.0f, 0.00f * CFDS, 1.00f, 0.00f, 0.0f, 0.0f, 0.00f, 0.000f * CFDS, 0, 0, 0, 0, 1, 0, 1, 100, SC_SOLIDS, R_TEMP+0.0f +273.15f, 0, "STKM spawn point", ST_SOLID, TYPE_SOLID, &update_SPAWN, NULL}, - {"SHLD", PIXPACK(0xAAAAAA), 0.0f, 0.00f * CFDS, 1.00f, 0.00f, 0.0f, 0.0f, 0.00f, 0.000f * CFDS, 0, 0, 0, 0, 1, 1, 1, 100, SC_SOLIDS, R_TEMP+0.0f +273.15f, 0, "Shield, spark it to grow", ST_SOLID, TYPE_SOLID|PROP_LIFE_DEC, &update_SHLD1, NULL}, - {"SHD2", PIXPACK(0x777777), 0.0f, 0.00f * CFDS, 1.00f, 0.00f, 0.0f, 0.0f, 0.00f, 0.000f * CFDS, 0, 0, 0, 0, 1, 0, 1, 100, SC_CRACKER2, R_TEMP+0.0f +273.15f, 0, "Shield lvl 2", ST_SOLID, TYPE_SOLID|PROP_LIFE_DEC, &update_SHLD2, NULL}, - {"SHD3", PIXPACK(0x444444), 0.0f, 0.00f * CFDS, 1.00f, 0.00f, 0.0f, 0.0f, 0.00f, 0.000f * CFDS, 0, 0, 0, 0, 1, 0, 1, 100, SC_CRACKER2, R_TEMP+0.0f +273.15f, 0, "Shield lvl 3", ST_SOLID, TYPE_SOLID|PROP_LIFE_DEC, &update_SHLD3, NULL}, - {"SHD4", PIXPACK(0x212121), 0.0f, 0.00f * CFDS, 1.00f, 0.00f, 0.0f, 0.0f, 0.00f, 0.000f * CFDS, 0, 0, 0, 0, 1, 0, 1, 100, SC_CRACKER2, R_TEMP+0.0f +273.15f, 0, "Shield lvl 4", ST_SOLID, TYPE_SOLID|PROP_LIFE_DEC, &update_SHLD4, NULL}, - {"LOLZ", PIXPACK(0x569212), 0.0f, 0.00f * CFDS, 0.00f, 0.00f, 0.0f, 0.0f, 0.0f, 0.000f * CFDS, 0, 0, 0, 0, 0, 1, 1, 100, SC_CRACKER2, 373.0f, 40, "Lolz", ST_GAS, TYPE_SOLID, &update_MISC, NULL}, - {"WIFI", PIXPACK(0x40A060), 0.0f, 0.00f * CFDS, 0.90f, 0.00f, 0.0f, 0.0f, 0.00f, 0.000f * CFDS, 0, 0, 0, 1, 2, 1, 1, 100, SC_ELEC, R_TEMP+0.0f +273.15f, 0, "Wireless transmitter, color coded.", ST_SOLID, TYPE_SOLID, &update_WIFI, &graphics_WIFI}, - {"FILT", PIXPACK(0x000056), 0.0f, 0.00f * CFDS, 0.90f, 0.00f, 0.0f, 0.0f, 0.00f, 0.000f * CFDS, 0, 0, 0, 1, 1, 1, 1, 100, SC_SOLIDS, R_TEMP+0.0f +273.15f, 251, "Filter for photons, changes the color.", ST_SOLID, TYPE_SOLID, NULL, &graphics_FILT}, - {"ARAY", PIXPACK(0xFFBB00), 0.0f, 0.00f * CFDS, 0.90f, 0.00f, 0.0f, 0.0f, 0.00f, 0.000f * CFDS, 0, 0, 0, 1, 1, 1, 1, 100, SC_ELEC, R_TEMP+0.0f +273.15f, 0, "Ray Emitter. Rays create points when they collide", ST_SOLID, TYPE_SOLID|PROP_LIFE_DEC, &update_ARAY, NULL}, - {"BRAY", PIXPACK(0xFFFFFF), 0.0f, 0.00f * CFDS, 0.90f, 0.00f, 0.0f, 0.0f, 0.00f, 0.000f * CFDS, 0, 0, 0, 1, 1, 0, 1, 100, SC_ELEC, R_TEMP+0.0f +273.15f, 251, "Ray Point. Rays create points when they collide", ST_SOLID, TYPE_SOLID|PROP_LIFE_DEC|PROP_LIFE_KILL, NULL, &graphics_BRAY}, - {"STK2", PIXPACK(0x000000), 0.5f, 0.00f * CFDS, 0.2f, 1.0f, 0.0f, 0.0f, 0.0f, 0.00f * CFDS, 0, 0, 0, 0, 0, 1, 1, 50, SC_SPECIAL, R_TEMP+14.6f+273.15f, 0, "Stickman. Don't kill him!", ST_NONE, 0, &update_STKM2, &graphics_STKM2}, - {"BOMB", PIXPACK(0xFFF288), 0.6f, 0.01f * CFDS, 0.98f, 0.95f, 0.0f, 0.1f, 0.00f, 0.000f * CFDS, 1, 0, 0, 0, 20, 1, 1, 30, SC_EXPLOSIVE, R_TEMP-2.0f +273.15f, 29, "Bomb.", ST_NONE, TYPE_PART|PROP_LIFE_DEC|PROP_LIFE_KILL_DEC|PROP_SPARKSETTLE, &update_BOMB, &graphics_BOMB}, - {"C-5", PIXPACK(0x2050E0), 0.0f, 0.00f * CFDS, 0.90f, 0.00f, 0.0f, 0.0f, 0.00f, 0.000f * CFDS, 0, 0, 0, 0, 1, 1, 1, 100, SC_EXPLOSIVE, R_TEMP+0.0f +273.15f, 88, "Cold explosive", ST_SOLID, TYPE_SOLID | PROP_NEUTPENETRATE, &update_C5, NULL}, - {"SING", PIXPACK(0x242424), 0.7f, 0.36f * CFDS, 0.96f, 0.80f, 0.1f, 0.12f, 0.00f, -0.001f * CFDS, 1, 0, 0, 0, 0, 1, 1, 86, SC_NUCLEAR, R_TEMP+0.0f +273.15f, 70, "Singularity", ST_SOLID, TYPE_PART|PROP_LIFE_DEC, &update_SING, NULL}, - {"QRTZ", PIXPACK(0xAADDDD), 0.0f, 0.00f * CFDS, 0.90f, 0.00f, 0.0f, 0.0f, 0.00f, 0.000f * CFDS, 0, 0, 0, 0, 0, 1, 1, 100, SC_SOLIDS, R_TEMP+0.0f +273.15f, 3, "Quartz, breakable mineral. Conducts but becomes brittle at lower temperatures.", ST_SOLID, TYPE_SOLID|PROP_HOT_GLOW|PROP_LIFE_DEC, &update_QRTZ, &graphics_QRTZ}, - {"PQRT", PIXPACK(0x88BBBB), 0.4f, 0.04f * CFDS, 0.94f, 0.95f, -0.1f, 0.27f, 0.00f, 0.000f * CFDS, 1, 0, 0, 0, 0, 1, 1, 90, SC_POWDERS, R_TEMP+0.0f +273.15f, 3, "Broken quartz.", ST_SOLID, TYPE_PART| PROP_HOT_GLOW, &update_QRTZ, &graphics_QRTZ}, - {"EMP", PIXPACK(0x66AAFF), 0.0f, 0.00f * CFDS, 0.90f, 0.00f, 0.0f, 0.0f, 0.0f, 0.0f * CFDS, 0, 0, 0, 0, 3, 1, 1, 100, SC_ELEC, R_TEMP+0.0f +273.15f, 121, "Breaks activated electronics.", ST_SOLID, TYPE_SOLID|PROP_LIFE_DEC, &update_EMP, &graphics_EMP}, - {"BREL", PIXPACK(0x707060), 0.4f, 0.04f * CFDS, 0.94f, 0.95f, -0.1f, 0.18f, 0.00f, 0.000f * CFDS, 1, 0, 0, 2, 2, 1, 1, 90, SC_POWDERS, R_TEMP+0.0f +273.15f, 211, "Broken electronics", ST_SOLID, TYPE_PART|PROP_CONDUCTS|PROP_LIFE_DEC|PROP_HOT_GLOW, NULL, NULL}, - {"ELEC", PIXPACK(0xDFEFFF), 0.0f, 0.00f * CFDS, 1.00f, 1.00f, -0.99f, 0.0f, 0.00f, 0.000f * CFDS, 0, 0, 0, 0, 0, 1, 1, -1, SC_NUCLEAR, R_TEMP+200.0f+273.15f, 251, "Electrons", ST_GAS, TYPE_ENERGY|PROP_LIFE_DEC|PROP_LIFE_KILL_DEC, &update_ELEC, &graphics_ELEC}, - {"ACEL", PIXPACK(0x0099CC), 0.0f, 0.00f * CFDS, 0.90f, 0.00f, 0.0f, 0.0f, 0.00f, 0.000f * CFDS, 0, 0, 0, 0, 1, 1, 1, 100, SC_FORCE, R_TEMP+0.0f +273.15f, 251, "Accelerator", ST_NONE, TYPE_SOLID, &update_ACEL, &graphics_ACEL}, - {"DCEL", PIXPACK(0x99CC00), 0.0f, 0.00f * CFDS, 0.90f, 0.00f, 0.0f, 0.0f, 0.00f, 0.000f * CFDS, 0, 0, 0, 0, 1, 1, 1, 100, SC_FORCE, R_TEMP+0.0f +273.15f, 251, "Decelerator", ST_NONE, TYPE_SOLID, &update_DCEL, &graphics_DCEL}, - {"TNT", PIXPACK(0xC05050), 0.0f, 0.00f * CFDS, 0.90f, 0.00f, 0.0f, 0.0f, 0.00f, 0.000f * CFDS, 0, 0, 0, 0, 1, 1, 1, 100, SC_EXPLOSIVE, R_TEMP+0.0f +273.15f, 88, "Explosive.", ST_SOLID, TYPE_SOLID | PROP_NEUTPENETRATE, &update_BANG, NULL}, - {"IGNC", PIXPACK(0xC0B050), 0.0f, 0.00f * CFDS, 0.90f, 0.00f, 0.0f, 0.0f, 0.00f, 0.000f * CFDS, 0, 0, 0, 0, 1, 1, 1, 100, SC_EXPLOSIVE, R_TEMP+0.0f +273.15f, 88, "Ignition cord.", ST_SOLID, TYPE_SOLID | PROP_NEUTPENETRATE | PROP_SPARKSETTLE | PROP_LIFE_KILL, &update_IGNT, NULL}, - {"BOYL", PIXPACK(0x0A3200), 1.0f, 0.01f * CFDS, 0.99f, 0.30f, -0.1f, 0.0f, 0.18f, 0.000f * CFDS, 0, 0, 0, 0, 1, 1, 1, 1, SC_GAS, R_TEMP+2.0f +273.15f, 42, "Boyle, variable pressure gas. Expands when heated.", ST_GAS, TYPE_GAS, &update_BOYL, NULL}, - {"GEL", PIXPACK(0xFF9900), 0.6f, 0.01f * CFDS, 0.98f, 0.95f, 0.0f, 0.1f, 0.00f, 0.000f * CFDS, 2, 0, 0, 0, 20, 1, 1, 35, SC_LIQUID, R_TEMP-2.0f +273.15f, 29, "Gel. A liquid with variable viscosity and heat conductivity", ST_LIQUID, TYPE_LIQUID|PROP_LIFE_DEC|PROP_NEUTPENETRATE, &update_GEL, &graphics_GEL}, - {"TRON", PIXPACK(0x000000), 0.0f, 0.00f * CFDS, 0.90f, 0.00f, 0.0f, 0.0f, 0.00f, 0.000f * CFDS, 0, 0, 0, 0, 0, 1, 1, 100, SC_SPECIAL, 0.0f, 40, "Smart particles, Travels in straight lines and avoids obstacles. Grows with time.", ST_NONE, TYPE_SOLID|PROP_LIFE_DEC|PROP_LIFE_KILL, &update_TRON, &graphics_TRON}, - {"STAR", PIXPACK(0x0000FF), 0.0f, 0.00f * CFDS, 0.90f, 0.00f, 0.0f, 0.0f, 0.00f, 0.000f * CFDS, 0, 0, 0, 0, 0, 0, 0, 100, SC_LIFE, 9000.0f, 40, "Like Star Wars rule S3456/B278/6", ST_NONE, TYPE_SOLID|PROP_LIFE, NULL, NULL}, - {"FROG", PIXPACK(0x00AA00), 0.0f, 0.00f * CFDS, 0.90f, 0.00f, 0.0f, 0.0f, 0.00f, 0.000f * CFDS, 0, 0, 0, 0, 0, 0, 0, 100, SC_LIFE, 9000.0f, 40, "Frogs S12/B34/3", ST_NONE, TYPE_SOLID|PROP_LIFE, NULL, NULL}, - {"BRAN", PIXPACK(0xCCCC00), 0.0f, 0.00f * CFDS, 0.90f, 0.00f, 0.0f, 0.0f, 0.00f, 0.000f * CFDS, 0, 0, 0, 0, 0, 0, 0, 100, SC_LIFE, 9000.0f, 40, "Brian 6 S6/B246/3", ST_NONE, TYPE_SOLID|PROP_LIFE, NULL, NULL}, - {"WIND", PIXPACK(0x101010), 0.0f, 0.00f * CFDS, 0.90f, 0.00f, 0.0f, 0.0f, 0.00f, 0.000f * CFDS, 0, 0, 0, 0, 0, 0, 0, 100, SC_SPECIAL, 0.0f, 40, "", ST_NONE, ST_NONE, NULL, NULL}, - {"HYGN", PIXPACK(0x5070FF), 2.0f, 0.00f * CFDS, 0.99f, 0.30f, -0.10f, 0.00f, 3.00f, 0.000f * CFDS, 0, 0, 0, 0, 0, 1, 1, 1, SC_GAS, R_TEMP+0.0f +273.15f, 251, "Combines with O2 to make WATR", ST_GAS, TYPE_GAS, &update_H2, NULL}, - {"SOAP", PIXPACK(0xF5F5DC), 0.6f, 0.01f * CFDS, 0.98f, 0.95f, 0.0f, 0.1f, 0.00f, 0.000f * CFDS, 2, 0, 0, 0, 20, 1, 1, 35, SC_LIQUID, R_TEMP-2.0f +273.15f, 29, "Soap. Creates bubbles.", ST_LIQUID, TYPE_LIQUID|PROP_NEUTPENETRATE|PROP_LIFE_DEC, &update_SOAP, NULL}, - {"BHOL", PIXPACK(0x202020), 0.0f, 0.00f * CFDS, 0.90f, 0.00f, 0.0f, 0.0f, 0.00f, 0.000f * CFDS, 0, 0, 0, 0, 0, 1, 1, 100, SC_SPECIAL, R_TEMP+0.0f +273.15f, 186, "Black hole (Requires newtonian gravity)", ST_SOLID, TYPE_SOLID, &update_NBHL, NULL}, - {"WHOL", PIXPACK(0xFFFFFF), 0.0f, 0.00f * CFDS, 0.90f, 0.00f, 0.0f, 0.0f, 0.00f, 0.000f * CFDS, 0, 0, 0, 0, 0, 1, 1, 100, SC_SPECIAL, R_TEMP+0.0f +273.15f, 186, "White hole (Requires newtonian gravity)", ST_SOLID, TYPE_SOLID, &update_NWHL, NULL}, - {"MERC", PIXPACK(0x736B6D), 0.4f, 0.04f * CFDS, 0.94f, 0.80f, 0.0f, 0.3f, 0.00f, 0.000f * CFDS, 2, 0, 0, 0, 20, 1, 1, 91, SC_ELEC, R_TEMP+0.0f +273.15f, 251, "Mercury. Volume changes with temperature, Conductive.", ST_LIQUID, TYPE_LIQUID|PROP_CONDUCTS|PROP_NEUTABSORB|PROP_LIFE_DEC, &update_MERC, NULL}, - {"PBCN", PIXPACK(0x3B1D0A), 0.0f, 0.00f * CFDS, 0.97f, 0.50f, 0.0f, 0.0f, 0.00f, 0.000f * CFDS, 0, 0, 0, 0, 12, 1, 1, 100, SC_POWERED, R_TEMP+0.0f +273.15f, 251, "Powered breakable clone", ST_NONE, TYPE_SOLID, &update_PBCN, &graphics_PBCN}, - {"GPMP", PIXPACK(0x0A3B3B), 0.0f, 0.00f * CFDS, 0.90f, 0.00f, 0.0f, 0.0f, 0.00f, 0.000f * CFDS, 0, 0, 0, 1, 1, 1, 1, 100, SC_POWERED, 0.0f +273.15f, 0, "Changes gravity to its temp when activated. (use HEAT/COOL).", ST_NONE, TYPE_SOLID, &update_GPMP, &graphics_GPMP}, - {"CLST", PIXPACK(0xE4A4A4), 0.7f, 0.02f * CFDS, 0.94f, 0.95f, 0.0f, 0.2f, 0.00f, 0.000f * CFDS, 1, 0, 0, 2, 2, 1, 1, 55, SC_POWDERS, R_TEMP+0.0f +273.15f, 70, "Clay dust. Produces paste when mixed with water.", ST_SOLID, TYPE_PART, &update_CLST, &graphics_CLST}, - {"WIRE", PIXPACK(0xFFCC00), 0.0f, 0.00f * CFDS, 0.00f, 0.00f, 0.0f, 0.0f, 0.00f, 0.000f * CFDS, 0, 0, 0, 0, 0, 1, 1, 100, SC_ELEC, R_TEMP+0.0f +273.15f, 250, "WireWorld wires.",ST_SOLID,TYPE_SOLID,&update_WIRE, &graphics_WIRE}, - {"GBMB", PIXPACK(0x1144BB), 0.6f, 0.01f * CFDS, 0.98f, 0.95f, 0.0f, 0.1f, 0.00f, 0.000f * CFDS, 1, 0, 0, 0, 20, 1, 1, 30, SC_EXPLOSIVE, R_TEMP-2.0f +273.15f, 29, "Sticks to first object it touches then produces strong gravity push.", ST_NONE, TYPE_PART|PROP_LIFE_DEC|PROP_LIFE_KILL_DEC, &update_GBMB, &graphics_GBMB}, - {"FIGH", PIXPACK(0x000000), 0.5f, 0.00f * CFDS, 0.2f, 1.0f, 0.0f, 0.0f, 0.0f, 0.00f * CFDS, 0, 0, 0, 0, 0, 1, 1, 50, SC_SPECIAL, R_TEMP+14.6f+273.15f, 0, "Fighter. Tries to kill stickmen.", ST_NONE, 0, &update_FIGH, &graphics_FIGH}, - {"FRAY", PIXPACK(0x00BBFF), 0.0f, 0.00f * CFDS, 0.90f, 0.00f, 0.0f, 0.0f, 0.00f, 0.000f * CFDS, 0, 0, 0, 1, 1, 1, 1, 100, SC_FORCE, 20.0f+0.0f +273.15f, 0, "Force Emitter. Push or pull objects based on temp value, use like ARAY", ST_SOLID, TYPE_SOLID|PROP_LIFE_DEC, &update_FRAY, NULL}, - {"RPEL", PIXPACK(0x99CC00), 0.0f, 0.00f * CFDS, 0.90f, 0.00f, 0.0f, 0.0f, 0.00f, 0.000f * CFDS, 0, 0, 0, 0, 1, 1, 1, 100, SC_FORCE, 20.0f+0.0f +273.15f, 0, "Repel or attract particles based on temp value.", ST_NONE, TYPE_SOLID, &update_REPL, NULL},*/ - //Name Colour Advec Airdrag Airloss Loss Collid Grav Diffus Hotair Fal Burn Exp Mel Hrd M Use Weight Section H Ins Description - }; - elementCount = PT_NUM; - part_type * ptypesT = (part_type*)malloc(PT_NUM*sizeof(part_type)); - memcpy(ptypesT, ptypes, PT_NUM*sizeof(part_type)); - return ptypesT; -} - unsigned int * LoadLatent(int & elementCount) { unsigned int platent[PT_NUM] = @@ -533,190 +342,3 @@ unsigned int * LoadLatent(int & elementCount) memcpy(platentT, platent, PT_NUM*sizeof(unsigned int)); return platentT; } - -part_transition * LoadTransitions(int & transitionCount) -{ - #define IPL -257.0f - #define IPH 257.0f - #define ITL MIN_TEMP-1 - #define ITH MAX_TEMP+1 - // no transition (PT_NONE means kill part) - #define NT -1 - // special transition - lava ctypes etc need extra code, which is only found and run if ST is given - #define ST PT_NUM - part_transition ptransitions[PT_NUM] = - { // if low pressure if high pressure if low temperature if high temperature - // Name plv plt phv pht tlv tlt thv tht - /* NONE */ {IPL, NT, IPH, NT, ITL, NT, ITH, NT}, - /* DUST */ {IPL, NT, IPH, NT, ITL, NT, ITH, NT}, - /* WATR */ {IPL, NT, IPH, NT, 273.15f,PT_ICEI, 373.0f, PT_WTRV}, - /* OIL */ {IPL, NT, IPH, NT, ITL, NT, 333.0f, PT_GAS}, - /* FIRE */ {IPL, NT, IPH, NT, ITL, NT, 2773.0f,PT_PLSM}, - /* STNE */ {IPL, NT, IPH, NT, ITL, NT, 983.0f, PT_LAVA}, - /* LAVA */ {IPL, NT, IPH, NT, 2573.15f,ST, ITH, NT}, // 2573.15f is highest melt pt of possible ctypes - /* GUN */ {IPL, NT, IPH, NT, ITL, NT, 673.0f, PT_FIRE}, - /* NITR */ {IPL, NT, IPH, NT, ITL, NT, 673.0f, PT_FIRE}, - /* CLNE */ {IPL, NT, IPH, NT, ITL, NT, ITH, NT}, - /* GAS */ {IPL, NT, 6.0f, PT_OIL, ITL, NT, 573.0f, PT_FIRE}, - /* C-4 */ {IPL, NT, IPH, NT, ITL, NT, 673.0f, PT_FIRE}, - /* GOO */ {IPL, NT, IPH, NT, ITL, NT, ITH, NT}, - /* ICE */ {IPL, NT, 0.8f, PT_SNOW, ITL, NT, 233.0f, ST}, - /* METL */ {IPL, NT, IPH, NT, ITL, NT, 1273.0f,PT_LAVA}, - /* SPRK */ {IPL, NT, IPH, NT, ITL, NT, ITH, NT}, - /* SNOW */ {IPL, NT, IPH, NT, ITL, NT, 273.0f, PT_WATR}, - /* WOOD */ {IPL, NT, IPH, NT, ITL, NT, 873.0f, PT_FIRE}, - /* NEUT */ {IPL, NT, IPH, NT, ITL, NT, ITH, NT}, - /* PLUT */ {IPL, NT, IPH, NT, ITL, NT, ITH, NT}, - /* PLNT */ {IPL, NT, IPH, NT, ITL, NT, 573.0f, PT_FIRE}, - /* ACID */ {IPL, NT, IPH, NT, ITL, NT, ITH, NT}, - /* VOID */ {IPL, NT, IPH, NT, ITL, NT, ITH, NT}, - /* WTRV */ {IPL, NT, IPH, NT, 371.0f, ST, ITH, NT}, - /* CNCT */ {IPL, NT, IPH, NT, ITL, NT, 1123.0f,PT_LAVA}, - /* DSTW */ {IPL, NT, IPH, NT, 273.15f,PT_ICEI, 373.0f, PT_WTRV}, - /* SALT */ {IPL, NT, IPH, NT, ITL, NT, 1173.0f,PT_LAVA}, - /* SLTW */ {IPL, NT, IPH, NT, 233.0f, PT_ICEI, 483.0f, ST}, - /* DMND */ {IPL, NT, IPH, NT, ITL, NT, ITH, NT}, - /* BMTL */ {IPL, NT, 1.0f, ST, ITL, NT, 1273.0f,PT_LAVA}, - /* BRMT */ {IPL, NT, IPH, NT, ITL, NT, 1273.0f,PT_LAVA}, - /* PHOT */ {IPL, NT, IPH, NT, ITL, NT, ITH, NT}, - /* URAN */ {IPL, NT, IPH, NT, ITL, NT, ITH, NT}, - /* WAX */ {IPL, NT, IPH, NT, ITL, NT, 319.0f, PT_MWAX}, - /* MWAX */ {IPL, NT, IPH, NT, 318.0f, PT_WAX, 673.0f, PT_FIRE}, - /* PSCN */ {IPL, NT, IPH, NT, ITL, NT, 1687.0f,PT_LAVA}, - /* NSCN */ {IPL, NT, IPH, NT, ITL, NT, 1687.0f,PT_LAVA}, - /* LN2 */ {IPL, NT, IPH, NT, 63.0f, PT_NICE, 77.0f, PT_NONE}, - /* INSL */ {IPL, NT, IPH, NT, ITL, NT, ITH, NT}, - /* VACU */ {IPL, NT, IPH, NT, ITL, NT, ITH, NT}, - /* VENT */ {IPL, NT, IPH, NT, ITL, NT, ITH, NT}, - /* RBDM */ {IPL, NT, IPH, NT, ITL, NT, 312.0f, PT_LRBD}, - /* LRBD */ {IPL, NT, IPH, NT, 311.0f, PT_RBDM, 961.0f, PT_FIRE}, - /* NTCT */ {IPL, NT, IPH, NT, ITL, NT, 1687.0f,PT_LAVA}, - /* SAND */ {IPL, NT, IPH, NT, ITL, NT, 1973.0f,PT_LAVA}, - /* GLAS */ {IPL, NT, IPH, NT, ITL, NT, 1973.0f,PT_LAVA}, - /* PTCT */ {IPL, NT, IPH, NT, ITL, NT, 1414.0f,PT_LAVA}, - /* BGLA */ {IPL, NT, IPH, NT, ITL, NT, 1973.0f,PT_LAVA}, - /* THDR */ {IPL, NT, IPH, NT, ITL, NT, ITH, NT}, - /* PLSM */ {IPL, NT, IPH, NT, ITL, NT, ITH, NT}, - /* ETRD */ {IPL, NT, IPH, NT, ITL, NT, ITH, NT}, - /* NICE */ {IPL, NT, IPH, NT, ITL, NT, 63.1f, PT_LNTG}, - /* NBLE */ {IPL, NT, IPH, NT, ITL, NT, ITH, NT}, - /* BTRY */ {IPL, NT, IPH, NT, ITL, NT, 2273.0f,PT_PLSM}, - /* LCRY */ {IPL, NT, IPH, NT, ITL, NT, 1273.0f,PT_BGLA}, - /* STKM */ {IPL, NT, IPH, NT, ITL, NT, 620.0f, PT_FIRE}, - /* SWCH */ {IPL, NT, IPH, NT, ITL, NT, ITH, NT}, - /* SMKE */ {IPL, NT, IPH, NT, ITL, NT, 625.0f, PT_FIRE}, - /* DESL */ {IPL, NT, 5.0f, PT_FIRE, ITL, NT, 335.0f, PT_FIRE}, - /* COAL */ {IPL, NT, IPH, NT, ITL, NT, ITH, NT}, - /* LO2 */ {IPL, NT, IPH, NT, ITL, NT, 90.1f, PT_O2}, - /* O2 */ {IPL, NT, IPH, NT, 90.0f, PT_LO2, ITH, NT}, - /* INWR */ {IPL, NT, IPH, NT, ITL, NT, 1687.0f,PT_LAVA}, - /* YEST */ {IPL, NT, IPH, NT, ITL, NT, 373.0f, PT_DYST}, - /* DYST */ {IPL, NT, IPH, NT, ITL, NT, 473.0f, PT_DUST}, - /* THRM */ {IPL, NT, IPH, NT, ITL, NT, ITH, NT}, - /* GLOW */ {IPL, NT, IPH, NT, ITL, NT, ITH, NT}, - /* BRCK */ {IPL, NT, 8.8f, PT_STNE, ITL, NT, 1223.0f,PT_LAVA}, - /* CFLM */ {IPL, NT, IPH, NT, ITL, NT, ITH, NT}, - /* FIRW */ {IPL, NT, IPH, NT, ITL, NT, ITH, NT}, - /* FUSE */ {IPL, NT, IPH, NT, ITL, NT, ITH, NT}, - /* FSEP */ {IPL, NT, IPH, NT, ITL, NT, ITH, NT}, - /* AMTR */ {IPL, NT, IPH, NT, ITL, NT, ITH, NT}, - /* BCOL */ {IPL, NT, IPH, NT, ITL, NT, ITH, NT}, - /* PCLN */ {IPL, NT, IPH, NT, ITL, NT, ITH, NT}, - /* HSWC */ {IPL, NT, IPH, NT, ITL, NT, ITH, NT}, - /* IRON */ {IPL, NT, IPH, NT, ITL, NT, 1687.0f,PT_LAVA}, - /* MORT */ {IPL, NT, IPH, NT, ITL, NT, ITH, NT}, - /* LIFE */ {IPL, NT, IPH, NT, ITL, NT, ITH, NT}, - /* DLAY */ {IPL, NT, IPH, NT, ITL, NT, ITH, NT}, - /* CO2 */ {IPL, NT, IPH, NT, 194.65f,PT_DRIC, ITH, NT}, - /* DRIC */ {IPL, NT, IPH, NT, ITL, NT, 195.65f,PT_CO2}, - /* CBNW */ {IPL, NT, IPH, NT, 273.15f,PT_ICEI, 373.0f, PT_WTRV}, - /* STOR */ {IPL, NT, IPH, NT, ITL, NT, ITH, NT}, - /* STOR */ {IPL, NT, IPH, NT, ITL, NT, ITH, NT}, - /*FREE*//* GOL */ {IPL, NT, IPH, NT, ITL, NT, ITH, NT}, - /*FREE*//* GOL */ {IPL, NT, IPH, NT, ITL, NT, ITH, NT}, - /*FREE*//* GOL */ {IPL, NT, IPH, NT, ITL, NT, ITH, NT}, - /*FREE*//* GOL */ {IPL, NT, IPH, NT, ITL, NT, ITH, NT}, - /*FREE*//* GOL */ {IPL, NT, IPH, NT, ITL, NT, ITH, NT}, - /* SPNG */ {IPL, NT, IPH, NT, ITL, NT, 2730.0f,PT_FIRE}, - /* RIME */ {IPL, NT, IPH, NT, ITL, NT, 273.15f,PT_WATR}, - /* FOG */ {IPL, NT, IPH, NT, ITL, NT, 373.15f,PT_WTRV}, - /* BCLN */ {IPL, NT, IPH, NT, ITL, NT, ITH, NT}, - /* LOVE */ {IPL, NT, IPH, NT, ITL, NT, ITH, NT}, - /* DEUT */ {IPL, NT, IPH, NT, ITL, NT, ITH, NT}, - /* WARP */ {IPL, NT, IPH, NT, ITL, NT, ITH, NT}, - /* PUMP */ {IPL, NT, IPH, NT, ITL, NT, ITH, NT}, - /* FWRK */ {IPL, NT, IPH, NT, ITL, NT, ITH, NT}, - /* PIPE */ {IPL, NT, 10.0f, PT_BRMT, ITL, NT, ITH, NT}, - /* FRZZ */ {IPL, NT, IPH, NT, ITL, NT, ITH, NT}, - /* FRZW */ {IPL, NT, IPH, NT, ITL, NT, 53.0f, PT_ICEI}, - /* GRAV */ {IPL, NT, IPH, NT, ITL, NT, ITH, NT}, - /* BIZR */ {IPL, NT, IPH, NT, 100.0f, PT_BIZRG, 400.0f, PT_BIZRS}, - /* BIZRG*/ {IPL, NT, IPH, NT, ITL, NT, 100.0f, PT_BIZR},//, 400.0f, PT_BIZRS}, - /* BIZRS*/ {IPL, NT, IPH, NT, 400.0f, PT_BIZR, ITH, NT},// 100.0f, PT_BIZRG}, - /* INST */ {IPL, NT, IPH, NT, ITL, NT, ITH, NT}, - /* ISOZ */ {IPL, NT, IPH, NT, 160.0f, PT_ISZS, ITH, NT}, - /* ISZS */ {IPL, NT, IPH, NT, ITL, NT, 300.0f, PT_ISOZ}, - /* PRTI */ {IPL, NT, IPH, NT, ITL, NT, ITH, NT}, - /* PRTO */ {IPL, NT, IPH, NT, ITL, NT, ITH, NT}, - /* PSTE */ {IPL, NT, 0.5f, PT_PSTS, ITL, NT, 747.0f, PT_BRCK}, - /* PSTS */ {0.5f, PT_PSTE, IPH, NT, ITL, NT, ITH, NT}, - /* ANAR */ {IPL, NT, IPH, NT, ITL, NT, ITH, NT}, - /* VINE */ {IPL, NT, IPH, NT, ITL, NT, 573.0f, PT_FIRE}, - /* INVS */ {IPL, NT, IPH, NT, ITL, NT, ITH, NT}, - /* EQVE */ {IPL, NT, IPH, NT, ITL, NT, ITH, NT}, - /* SPWN2*/ {IPL, NT, IPH, NT, ITL, NT, ITH, NT}, - /* SPAWN*/ {IPL, NT, IPH, NT, ITL, NT, ITH, NT}, - /* SHLD1*/ {IPL, NT, 7.0f, PT_NONE, ITL, NT, ITH, NT}, - /* SHLD2*/ {IPL, NT, 15.0f, PT_NONE, ITL, NT, ITH, NT}, - /* SHLD3*/ {IPL, NT, 25.0f, PT_NONE, ITL, NT, ITH, NT}, - /* SHLD4*/ {IPL, NT, 40.0f, PT_NONE, ITL, NT, ITH, NT}, - /* LOlZ */ {IPL, NT, IPH, NT, ITL, NT, ITH, NT}, - /* WIFI */ {IPL, NT, 15.0f, PT_BRMT, ITL, NT, ITH, NT}, - /* FILT */ {IPL, NT, IPH, NT, ITL, NT, ITH, NT}, - /* ARAY */ {IPL, NT, IPH, NT, ITL, NT, ITH, NT}, - /* BRAY */ {IPL, NT, IPH, NT, ITL, NT, ITH, NT}, - /* STKM2*/ {IPL, NT, IPH, NT, ITL, NT, 620.0f, PT_FIRE}, - /* BOMB */ {IPL, NT, IPH, NT, ITL, NT, ITH, NT}, - /* C-5 */ {IPL, NT, IPH, NT, ITL, NT, ITH, NT}, - /* SING */ {IPL, NT, IPH, NT, ITL, NT, ITH, NT}, - /* QRTZ */ {IPL, NT, IPH, NT, ITL, NT, 2573.15f,PT_LAVA}, - /* PQRT */ {IPL, NT, IPH, NT, ITL, NT, 2573.15f,PT_LAVA}, - /* EMP */ {IPL, NT, IPH, NT, ITL, NT, ITH, NT}, - /* BREL */ {IPL, NT, IPH, NT, ITL, NT, ITH, NT}, - /* ELEC */ {IPL, NT, IPH, NT, ITL, NT, ITH, NT}, - /* ACEL */ {IPL, NT, IPH, NT, ITL, NT, ITH, NT}, - /* DCEL */ {IPL, NT, IPH, NT, ITL, NT, ITH, NT}, - /* TNT */ {IPL, NT, IPH, NT, ITL, NT, ITH, NT}, - /* IGNP */ {IPL, NT, IPH, NT, ITL, NT, 673.0f, PT_FIRE}, - /* BOYL */ {IPL, NT, IPH, NT, ITL, NT, ITH, NT}, - /* GEL */ {IPL, NT, IPH, NT, ITL, NT, ITH, NT}, - /* TRON */ {IPL, NT, IPH, NT, ITL, NT, ITH, NT}, - /*FREE*//* GOL */ {IPL, NT, IPH, NT, ITL, NT, ITH, NT}, - /*FREE*//* GOL */ {IPL, NT, IPH, NT, ITL, NT, ITH, NT}, - /*FREE*//* GOL */ {IPL, NT, IPH, NT, ITL, NT, ITH, NT}, - /* WIND */ {IPL, NT, IPH, NT, ITL, NT, ITH, NT}, - /* H2 */ {IPL, NT, IPH, NT, ITL, NT, ITH, NT}, - /* SOAP */ {IPL, NT, IPH, NT, ITL, NT, ITL, NT}, - /* NBHL */ {IPL, NT, IPH, NT, ITL, NT, ITH, NT}, - /* NWHL */ {IPL, NT, IPH, NT, ITL, NT, ITH, NT}, - /* MERC */ {IPL, NT, IPH, NT, ITL, NT, ITH, NT}, - /* PBCN */ {IPL, NT, IPH, NT, ITL, NT, ITH, NT}, - /* GPMP */ {IPL, NT, IPH, NT, ITL, NT, ITH, NT}, - /* CLST */ {IPL, NT, IPH, NT, ITL, NT, 1256.0f, PT_LAVA}, - /* WIRE */ {IPL, NT, IPH, NT, ITL, NT, ITH, NT}, - /* GBMB */ {IPL, NT, IPH, NT, ITL, NT, ITH, NT}, - /* FIGH */ {IPL, NT, IPH, NT, ITL, NT, 620.0f, PT_FIRE}, - /* FRAY */ {IPL, NT, IPH, NT, ITL, NT, ITH, NT}, - /* REPL */ {IPL, NT, IPH, NT, ITL, NT, ITH, NT}, - }; - #undef IPL - #undef IPH - #undef ITL - #undef ITH - #undef NT - #undef ST - transitionCount = PT_NUM; - part_transition * ptransitionsT = (part_transition*)malloc(PT_NUM*sizeof(part_transition)); - memcpy(ptransitionsT, ptransitions, PT_NUM*sizeof(part_transition)); - return ptransitionsT; -} diff --git a/src/simulation/SimulationData.h b/src/simulation/SimulationData.h index c24ce39..72a8e58 100644 --- a/src/simulation/SimulationData.h +++ b/src/simulation/SimulationData.h @@ -160,8 +160,6 @@ class SimTool; class Element; -std::vector GetDefaultElements(); - gol_menu * LoadGOLMenu(int & golMenuCount); int * LoadGOLTypes(int & golTypeCount); @@ -172,10 +170,6 @@ wall_type * LoadWalls(int & wallCount); menu_section * LoadMenus(int & menuCount); -part_type * LoadElements(int & elementCount); - unsigned int * LoadLatent(int & elementCount); -part_transition * LoadTransitions(int & transitionCount); - #endif /* SIMULATIONDATA_H_ */ diff --git a/src/simulation/StorageClasses.h b/src/simulation/StorageClasses.h new file mode 100644 index 0000000..45b9b00 --- /dev/null +++ b/src/simulation/StorageClasses.h @@ -0,0 +1,54 @@ +#ifndef STORAGECLASSES_H_ +#define STORAGECLASSES_H_ + +#include +#include "Elements.h" + +class Renderer; +class Simulation; + +/*struct part_type +{ + char *name; + pixel pcolors; + float advection; + float airdrag; + float airloss; + float loss; + float collision; + float gravity; + float diffusion; + float hotair; + int falldown; + int flammable; + int explosive; + int meltable; + int hardness; + int menu; + int enabled; + int weight; + int menusection; + float heat; + unsigned char hconduct; + char *descs; + char state; + unsigned int properties; + int (*update_func) (UPDATE_FUNC_ARGS); + int (*graphics_func) (GRAPHICS_FUNC_ARGS); +}; +typedef struct part_type part_type;*/ + +/*struct part_transition +{ + float plv; // transition occurs if pv is lower than this + int plt; + float phv; // transition occurs if pv is higher than this + int pht; + float tlv; // transition occurs if t is lower than this + int tlt; + float thv; // transition occurs if t is higher than this + int tht; +}; +typedef struct part_transition part_transition;*/ + +#endif \ No newline at end of file diff --git a/src/simulation/StructProperty.h b/src/simulation/StructProperty.h new file mode 100644 index 0000000..ddea96b --- /dev/null +++ b/src/simulation/StructProperty.h @@ -0,0 +1,28 @@ +// +// StructProperty.h +// The Powder Toy +// +// Created by Simon Robertshaw on 04/06/2012. +// Copyright (c) 2012 __MyCompanyName__. All rights reserved. +// + +#ifndef The_Powder_Toy_StructProperty_h +#define The_Powder_Toy_StructProperty_h + +struct StructProperty +{ + enum PropertyType { ParticleType, Colour, Integer, UInteger, Float, String }; + std::string Name; + PropertyType Type; + intptr_t Offset; + + StructProperty(std::string name, PropertyType type, intptr_t offset): + Name(name), + Type(type), + Offset(offset) + { + + } +}; + +#endif diff --git a/src/simulation/WallType.h b/src/simulation/WallType.h new file mode 100644 index 0000000..bd453d8 --- /dev/null +++ b/src/simulation/WallType.h @@ -0,0 +1,20 @@ +// +// WallType.h +// The Powder Toy +// +// Created by Simon Robertshaw on 04/06/2012. +// Copyright (c) 2012 __MyCompanyName__. All rights reserved. +// + +#ifndef The_Powder_Toy_WallType_h +#define The_Powder_Toy_WallType_h + +struct wall_type +{ + pixel colour; + pixel eglow; // if emap set, add this to fire glow + int drawstyle; + const char *descs; +}; + +#endif -- cgit v0.9.2-21-gd62e