summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--src/cat/LegacyLuaAPI.cpp2
-rw-r--r--src/cat/TPTScriptInterface.cpp25
-rw-r--r--src/client/GameSave.cpp35
-rw-r--r--src/graphics/Graphics.cpp13
-rw-r--r--src/graphics/Graphics.h2
-rw-r--r--src/gui/game/GameController.cpp12
-rw-r--r--src/gui/game/GameController.h1
-rw-r--r--src/gui/game/GameView.cpp26
-rw-r--r--src/simulation/Simulation.cpp230
-rw-r--r--src/simulation/Simulation.h1
-rw-r--r--src/simulation/elements/ACID.cpp10
-rw-r--r--src/simulation/elements/ARAY.cpp2
-rw-r--r--src/simulation/elements/BCOL.cpp2
-rw-r--r--src/simulation/elements/CRAY.cpp5
-rw-r--r--src/simulation/elements/DTEC.cpp26
-rw-r--r--src/simulation/elements/ELEC.cpp3
-rw-r--r--src/simulation/elements/EXOT.cpp58
-rw-r--r--src/simulation/elements/FILT.cpp75
-rw-r--r--src/simulation/elements/PHOT.cpp5
-rw-r--r--src/simulation/elements/PIPE.cpp4
-rw-r--r--src/simulation/elements/PROT.cpp153
-rw-r--r--src/simulation/elements/PRTO.cpp4
-rw-r--r--src/simulation/elements/PSTN.cpp7
-rw-r--r--src/simulation/elements/QRTZ.cpp36
-rw-r--r--src/simulation/elements/SOAP.cpp2
-rw-r--r--src/simulation/elements/VIRS.cpp145
-rw-r--r--src/simulation/elements/VRSG.cpp49
-rw-r--r--src/simulation/elements/VRSS.cpp49
28 files changed, 808 insertions, 174 deletions
diff --git a/src/cat/LegacyLuaAPI.cpp b/src/cat/LegacyLuaAPI.cpp
index 293d45e..9c32ad5 100644
--- a/src/cat/LegacyLuaAPI.cpp
+++ b/src/cat/LegacyLuaAPI.cpp
@@ -1100,7 +1100,7 @@ int luatpt_reset_spark(lua_State* l)
if (luacon_sim->parts[i].ctype >= 0 && luacon_sim->parts[i].ctype < PT_NUM)
{
luacon_sim->parts[i].type = luacon_sim->parts[i].ctype;
- luacon_sim->parts[i].life = 0;
+ luacon_sim->parts[i].life = luacon_sim->parts[i].ctype = 0;
}
else
luacon_sim->kill_part(i);
diff --git a/src/cat/TPTScriptInterface.cpp b/src/cat/TPTScriptInterface.cpp
index 21e93ab..e821559 100644
--- a/src/cat/TPTScriptInterface.cpp
+++ b/src/cat/TPTScriptInterface.cpp
@@ -255,16 +255,29 @@ AnyType TPTScriptInterface::tptS_set(std::deque<std::string> * words)
//Selector
int newValue;
if(value.GetType() == TypeNumber)
+ {
newValue = ((NumberType)value).Value();
+ }
else if(value.GetType() == TypeString)
{
- newValue = GetParticleType(((StringType)value).Value());
- if (newValue < 0 || newValue >= PT_NUM)
+ if (property.Value() == "temp")
{
- // TODO: add element CAKE to invalidate this
- if (!strcasecmp(((StringType)value).Value().c_str(),"cake"))
- throw GeneralException("Cake is a lie, not an element");
- throw GeneralException("Invalid element");
+ std::string newString = ((StringType)value).Value();
+ if (newString.at(newString.length()-1) == 'C')
+ newValue = atoi(newString.substr(0, newString.length()-1).c_str())+273;
+ else if (newString.at(newString.length()-1) == 'F')
+ newValue = (int)((atoi(newString.substr(0, newString.length()-1).c_str())-32.0f)*5/9+273.15f);
+ }
+ else
+ {
+ newValue = GetParticleType(((StringType)value).Value());
+ if (newValue < 0 || newValue >= PT_NUM)
+ {
+ // TODO: add element CAKE to invalidate this
+ if (!strcasecmp(((StringType)value).Value().c_str(),"cake"))
+ throw GeneralException("Cake is a lie, not an element");
+ throw GeneralException("Invalid element");
+ }
}
}
else
diff --git a/src/client/GameSave.cpp b/src/client/GameSave.cpp
index 52ad64b..ddb4ef4 100644
--- a/src/client/GameSave.cpp
+++ b/src/client/GameSave.cpp
@@ -960,12 +960,32 @@ void GameSave::readOPS(char * data, int dataLength)
case PT_PSTN:
if (savedVersion < 87 && particles[newIndex].ctype)
particles[newIndex].life = 1;
+ break;
case PT_STKM:
case PT_STKM2:
case PT_FIGH:
if (savedVersion < 88 && particles[newIndex].ctype == OLD_SPC_AIR)
particles[newIndex].ctype = SPC_AIR;
+ break;
+ case PT_FILT:
+ if (savedVersion < 89)
+ {
+ if (particles[newIndex].tmp<0 || particles[newIndex].tmp>3)
+ particles[newIndex].tmp = 6;
+ particles[newIndex].ctype = 0;
+ }
+ break;
+ case PT_QRTZ:
+ case PT_PQRT:
+ if (savedVersion < 89)
+ {
+ particles[newIndex].tmp2 = particles[newIndex].tmp;
+ particles[newIndex].tmp = particles[newIndex].ctype;
+ particles[newIndex].ctype = 0;
+ }
+ break;
}
+ //note: PSv was used in version 77.0 and every version before, add something in PSv too if the element is that old
newIndex++;
}
}
@@ -1587,6 +1607,21 @@ void GameSave::readPSv(char * data, int dataLength)
if (ver < 88) //fix air blowing stickmen
if ((particles[i-1].type == PT_STKM || particles[i-1].type == PT_STKM2 || particles[i-1].type == PT_FIGH) && particles[i-1].ctype == OLD_SPC_AIR)
particles[i-1].ctype == SPC_AIR;
+ if (ver < 89)
+ {
+ if (particles[i-1].type == PT_FILT)
+ {
+ if (particles[i-1].tmp<0 || particles[i-1].tmp>3)
+ particles[i-1].tmp = 6;
+ particles[i-1].ctype = 0;
+ }
+ else if (particles[i-1].type == PT_QRTZ || particles[i-1].type == PT_PQRT)
+ {
+ particles[i-1].tmp2 = particles[i-1].tmp;
+ particles[i-1].tmp = particles[i-1].ctype;
+ particles[i-1].ctype = 0;
+ }
+ }
}
}
diff --git a/src/graphics/Graphics.cpp b/src/graphics/Graphics.cpp
index d4e2956..c70344b 100644
--- a/src/graphics/Graphics.cpp
+++ b/src/graphics/Graphics.cpp
@@ -67,13 +67,10 @@ void VideoBuffer::Resize(int width, int height, bool resample, bool fixedRatio)
else if(fixedRatio)
{
//Force proportions
- float scaleFactor = 1.0f;
- if(Height > newHeight)
- scaleFactor = ((float)newHeight)/((float)Height);
- if(Width > newWidth)
- scaleFactor = ((float)newWidth)/((float)Width);
- newWidth = ((float)Width)*scaleFactor;
- newHeight = ((float)Height)*scaleFactor;
+ if(newWidth*Height > newHeight*Width) // same as nW/W > nH/H
+ newWidth = (int)(Width * (newHeight/(float)Height));
+ else
+ newHeight = (int)(Height * (newWidth/(float)Width));
}
if(resample)
newBuffer = Graphics::resample_img(Buffer, Width, Height, newWidth, newHeight);
@@ -589,7 +586,7 @@ int Graphics::textwidth(const char *s)
return x-1;
}
-int Graphics::CharWidth(char c)
+int Graphics::CharWidth(unsigned char c)
{
return font_data[font_ptrs[(int)c]];
}
diff --git a/src/graphics/Graphics.h b/src/graphics/Graphics.h
index 580f2c0..de1c2e8 100644
--- a/src/graphics/Graphics.h
+++ b/src/graphics/Graphics.h
@@ -203,7 +203,7 @@ public:
//Font/text metrics
static int CharIndexAtPosition(char *s, int positionX, int positionY);
static int PositionAtCharIndex(char *s, int charIndex, int & positionX, int & positionY);
- static int CharWidth(char c);
+ static int CharWidth(unsigned char c);
static int textnwidth(char *s, int n);
static void textnpos(char *s, int n, int w, int *cx, int *cy);
static int textwidthx(char *s, int w);
diff --git a/src/gui/game/GameController.cpp b/src/gui/game/GameController.cpp
index b6d0560..a114b82 100644
--- a/src/gui/game/GameController.cpp
+++ b/src/gui/game/GameController.cpp
@@ -749,7 +749,7 @@ void GameController::ResetSpark()
if (sim->parts[i].ctype >= 0 && sim->parts[i].ctype < PT_NUM && sim->elements[sim->parts[i].ctype].Enabled)
{
sim->parts[i].type = sim->parts[i].ctype;
- sim->parts[i].life = 0;
+ sim->parts[i].ctype = sim->parts[i].life = 0;
}
else
sim->kill_part(i);
@@ -1389,6 +1389,16 @@ std::string GameController::ElementResolve(int type, int ctype)
return "";
}
+bool GameController::IsValidElement(int type)
+{
+ if(gameModel && gameModel->GetSimulation())
+ {
+ return (type > 0 && type < PT_NUM && gameModel->GetSimulation()->elements[type].Enabled);
+ }
+ else
+ return false;
+}
+
std::string GameController::WallName(int type)
{
if(gameModel && gameModel->GetSimulation() && gameModel->GetSimulation()->wtypes && type >= 0 && type < UI_WALLCOUNT)
diff --git a/src/gui/game/GameController.h b/src/gui/game/GameController.h
index d723ccb..b2a7d99 100644
--- a/src/gui/game/GameController.h
+++ b/src/gui/game/GameController.h
@@ -137,6 +137,7 @@ public:
ui::Point PointTranslate(ui::Point point);
ui::Point NormaliseBlockCoord(ui::Point point);
std::string ElementResolve(int type, int ctype);
+ bool IsValidElement(int type);
std::string WallName(int type);
void ResetAir();
diff --git a/src/gui/game/GameView.cpp b/src/gui/game/GameView.cpp
index f7fa6f5..1dad1f8 100644
--- a/src/gui/game/GameView.cpp
+++ b/src/gui/game/GameView.cpp
@@ -1473,6 +1473,13 @@ void GameView::OnKeyPress(int key, Uint16 character, bool shift, bool ctrl, bool
else
c->InvertAirSim();
break;
+ case ';':
+ if (ctrl)
+ {
+ c->SetReplaceModeFlags(c->GetReplaceModeFlags()^SPECIFIC_DELETE);
+ break;
+ }
+ //fancy case switch without break
case SDLK_INSERT:
c->SetReplaceModeFlags(c->GetReplaceModeFlags()^REPLACE_MODE);
break;
@@ -2062,16 +2069,25 @@ void GameView::OnDraw()
ctype = sample.particle.tmp&0xFF;
if(showDebug)
{
- if (sample.particle.type == PT_LAVA && ctype > 0 && ctype < PT_NUM)
+ if (sample.particle.type == PT_LAVA && c->IsValidElement(ctype))
sampleInfo << "Molten " << c->ElementResolve(ctype, -1);
- else if ((sample.particle.type == PT_PIPE || sample.particle.type == PT_PPIP) && ctype > 0 && ctype < PT_NUM)
+ else if ((sample.particle.type == PT_PIPE || sample.particle.type == PT_PPIP) && c->IsValidElement(ctype))
sampleInfo << c->ElementResolve(sample.particle.type, -1) << " with " << c->ElementResolve(ctype, (int)sample.particle.pavg[1]);
else if (sample.particle.type == PT_LIFE)
sampleInfo << c->ElementResolve(sample.particle.type, sample.particle.ctype);
+ else if (sample.particle.type == PT_FILT)
+ {
+ sampleInfo << c->ElementResolve(sample.particle.type, sample.particle.ctype);
+ const char* filtModes[] = {"set colour", "AND", "OR", "subtract colour", "red shift", "blue shift", "no effect", "XOR", "NOT"};
+ if (sample.particle.tmp>=0 && sample.particle.tmp<=8)
+ sampleInfo << " (" << filtModes[sample.particle.tmp] << ")";
+ else
+ sampleInfo << " (unknown mode)";
+ }
else
{
sampleInfo << c->ElementResolve(sample.particle.type, sample.particle.ctype);
- if(ctype > 0 && ctype < PT_NUM)
+ if (c->IsValidElement(ctype))
sampleInfo << " (" << c->ElementResolve(ctype, -1) << ")";
else
sampleInfo << " ()";
@@ -2094,7 +2110,9 @@ void GameView::OnDraw()
sampleInfo << ", Temp: " << std::fixed << sample.particle.temp -273.15f;
sampleInfo << ", Pressure: " << std::fixed << sample.AirPressure;
}
- if(sample.particle.type == PT_PHOT)
+ if (sample.particle.type == PT_PHOT || sample.particle.type == PT_BIZR || sample.particle.type == PT_BIZRG || sample.particle.type == PT_BIZRS)
+ wavelengthGfx = sample.particle.ctype;
+ if (sample.particle.type == PT_FILT && sample.particle.ctype)
wavelengthGfx = sample.particle.ctype;
}
else if (sample.WallType)
diff --git a/src/simulation/Simulation.cpp b/src/simulation/Simulation.cpp
index c1cf22e..b090841 100644
--- a/src/simulation/Simulation.cpp
+++ b/src/simulation/Simulation.cpp
@@ -388,23 +388,23 @@ int Simulation::flood_prop_2(int x, int y, size_t propoffset, void * propvalue,
}
for (x=x1; x<=x2; x++)
{
- i = pmap[y][x]>>8;
+ i = pmap[y][x];
if (!i)
- i = photons[y][x]>>8;
+ i = photons[y][x];
if (!i)
continue;
switch (proptype) {
case StructProperty::Float:
- *((float*)(((char*)&parts[i])+propoffset)) = *((float*)propvalue);
+ *((float*)(((char*)&parts[i>>8])+propoffset)) = *((float*)propvalue);
break;
case StructProperty::ParticleType:
case StructProperty::Integer:
- *((int*)(((char*)&parts[i])+propoffset)) = *((int*)propvalue);
+ *((int*)(((char*)&parts[i>>8])+propoffset)) = *((int*)propvalue);
break;
case StructProperty::UInteger:
- *((unsigned int*)(((char*)&parts[i])+propoffset)) = *((unsigned int*)propvalue);
+ *((unsigned int*)(((char*)&parts[i>>8])+propoffset)) = *((unsigned int*)propvalue);
break;
default:
@@ -2019,13 +2019,16 @@ void Simulation::init_can_move()
}
//a list of lots of things PHOT can move through
// TODO: replace with property
- for (movingType = 0; movingType < PT_NUM; movingType++)
+ for (destinationType = 0; destinationType < PT_NUM; destinationType++)
{
- if (movingType == PT_GLAS || movingType == PT_PHOT || movingType == PT_FILT || movingType == PT_INVIS
- || movingType == PT_CLNE || movingType == PT_PCLN || movingType == PT_BCLN || movingType == PT_PBCN
- || movingType == PT_WATR || movingType == PT_DSTW || movingType == PT_SLTW || movingType == PT_GLOW
- || movingType == PT_ISOZ || movingType == PT_ISZS || movingType == PT_QRTZ || movingType == PT_PQRT)
- can_move[PT_PHOT][movingType] = 2;
+ if (destinationType == PT_GLAS || destinationType == PT_PHOT || destinationType == PT_FILT || destinationType == PT_INVIS
+ || destinationType == PT_CLNE || destinationType == PT_PCLN || destinationType == PT_BCLN || destinationType == PT_PBCN
+ || destinationType == PT_WATR || destinationType == PT_DSTW || destinationType == PT_SLTW || destinationType == PT_GLOW
+ || destinationType == PT_ISOZ || destinationType == PT_ISZS || destinationType == PT_QRTZ || destinationType == PT_PQRT
+ || destinationType == PT_H2)
+ can_move[PT_PHOT][destinationType] = 2;
+ if (destinationType != PT_DMND && destinationType != PT_INSL && destinationType != PT_VOID && destinationType != PT_PVOD)
+ can_move[PT_PROT][destinationType] = 2;
}
//other special cases that weren't covered above
@@ -2163,7 +2166,7 @@ int Simulation::try_move(int i, int x, int y, int nx, int ny)
if ((r & 0xFF) < PT_NUM && elements[r&0xFF].HeatConduct && ((r&0xFF)!=PT_HSWC||parts[r>>8].life==10) && (r&0xFF)!=PT_FILT)
parts[i].temp = parts[r>>8].temp = restrict_flt((parts[r>>8].temp+parts[i].temp)/2, MIN_TEMP, MAX_TEMP);
}
- if ((parts[i].type==PT_NEUT || parts[i].type==PT_ELEC) && ((r&0xFF)==PT_CLNE || (r&0xFF)==PT_PCLN || (r&0xFF)==PT_BCLN || (r&0xFF)==PT_PBCN)) {
+ else if ((parts[i].type==PT_NEUT || parts[i].type==PT_ELEC) && ((r&0xFF)==PT_CLNE || (r&0xFF)==PT_PCLN || (r&0xFF)==PT_BCLN || (r&0xFF)==PT_PBCN)) {
if (!parts[r>>8].ctype)
parts[r>>8].ctype = parts[i].type;
}
@@ -2192,63 +2195,64 @@ int Simulation::try_move(int i, int x, int y, int nx, int ny)
if (e == 2) //if occupy same space
{
- if (parts[i].type == PT_PHOT && (r&0xFF)==PT_GLOW && !parts[r>>8].life)
- if (rand() < RAND_MAX/30)
+ if (parts[i].type == PT_PHOT)
+ {
+ if ((r&0xFF) == PT_GLOW)
{
- parts[r>>8].life = 120;
- create_gain_photon(i);
+ if (!parts[r>>8].life && rand() < RAND_MAX/30)
+ {
+ parts[r>>8].life = 120;
+ create_gain_photon(i);
+ }
}
- if (parts[i].type == PT_PHOT && (r&0xFF)==PT_FILT)
- {
- int temp_bin = (int)((parts[r>>8].temp-273.0f)*0.025f);
- if (temp_bin < 0) temp_bin = 0;
- if (temp_bin > 25) temp_bin = 25;
- if(!parts[r>>8].tmp){
- parts[i].ctype = 0x1F << temp_bin; //Assign Colour
- } else if(parts[r>>8].tmp==1){
- parts[i].ctype &= 0x1F << temp_bin; //Filter Colour
- } else if(parts[r>>8].tmp==2){
- parts[i].ctype |= 0x1F << temp_bin; //Add Colour
- } else if(parts[r>>8].tmp==3){
- parts[i].ctype &= ~(0x1F << temp_bin); //Subtract Colour
+ else if ((r&0xFF) == PT_FILT)
+ parts[i].ctype = Element_FILT::interactWavelengths(&parts[r>>8], parts[i].ctype);
+ else if ((r&0xFF) == PT_INVIS)
+ {
+ if (pv[ny/CELL][nx/CELL]<=4.0f && pv[ny/CELL][nx/CELL]>=-4.0f)
+ {
+ part_change_type(i,x,y,PT_NEUT);
+ parts[i].ctype = 0;
+ }
+ }
+ else if ((r&0xFF)==PT_BIZR || (r&0xFF)==PT_BIZRG || (r&0xFF)==PT_BIZRS)
+ {
+ part_change_type(i, x, y, PT_ELEC);
+ parts[i].ctype = 0;
+ }
+ else if ((r&0xFF) == PT_H2)
+ {
+ part_change_type(i, x, y, PT_PROT);
+ parts[i].ctype = 0;
}
}
- if (parts[i].type == PT_NEUT && (r&0xFF)==PT_GLAS) {
- if (rand() < RAND_MAX/10)
- create_cherenkov_photon(i);
- }
- if (parts[i].type == PT_PHOT && (r&0xFF)==PT_INVIS && pv[ny/CELL][nx/CELL]<=4.0f && pv[ny/CELL][nx/CELL]>=-4.0f) {
- part_change_type(i,x,y,PT_NEUT);
- parts[i].ctype = 0;
+ else if (parts[i].type == PT_NEUT)
+ {
+ if ((r&0xFF) == PT_GLAS)
+ if (rand() < RAND_MAX/10)
+ create_cherenkov_photon(i);
}
- if ((parts[i].type==PT_BIZR||parts[i].type==PT_BIZRG) && (r&0xFF)==PT_FILT)
+ else if (parts[i].type == PT_PROT)
{
- int temp_bin = (int)((parts[r>>8].temp-273.0f)*0.025f);
- if (temp_bin < 0) temp_bin = 0;
- if (temp_bin > 25) temp_bin = 25;
- parts[i].ctype = 0x1F << temp_bin;
+ if ((r&0xFF) == PT_INVIS)
+ part_change_type(i, x, y, PT_NEUT);
}
- if (((r&0xFF)==PT_BIZR || (r&0xFF)==PT_BIZRG || (r&0xFF)==PT_BIZRS) && parts[i].type==PT_PHOT)
+ else if ((parts[i].type==PT_BIZR || parts[i].type==PT_BIZRG))
{
- part_change_type(i, x, y, PT_ELEC);
- parts[i].ctype = 0;
+ if ((r&0xFF) == PT_FILT)
+ parts[i].ctype = Element_FILT::interactWavelengths(&parts[r>>8], parts[i].ctype);
}
return 1;
}
//else e=1 , we are trying to swap the particles, return 0 no swap/move, 1 is still overlap/move, because the swap takes place later
- if (parts[i].type == PT_NEUT && (elements[r & 0xFF].Properties & PROP_NEUTABSORB))
- {
- kill_part(i);
- return 0;
- }
if ((r&0xFF)==PT_VOID || (r&0xFF)==PT_PVOD) //this is where void eats particles
{
//void ctype already checked in eval_move
kill_part(i);
return 0;
}
- if ((r&0xFF)==PT_BHOL || (r&0xFF)==PT_NBHL) //this is where blackhole eats particles
+ else if ((r&0xFF)==PT_BHOL || (r&0xFF)==PT_NBHL) //this is where blackhole eats particles
{
if (!legacy_enable)
{
@@ -2257,39 +2261,61 @@ int Simulation::try_move(int i, int x, int y, int nx, int ny)
kill_part(i);
return 0;
}
- if (((r&0xFF)==PT_WHOL||(r&0xFF)==PT_NWHL) && parts[i].type==PT_ANAR) //whitehole eats anar
+ else if (((r&0xFF)==PT_WHOL || (r&0xFF)==PT_NWHL)) //whitehole eats anar
{
- if (!legacy_enable)
+ if (parts[i].type == PT_ANAR)
{
- parts[r>>8].temp = restrict_flt(parts[r>>8].temp- (MAX_TEMP-parts[i].temp)/2, MIN_TEMP, MAX_TEMP);
+ if (!legacy_enable)
+ {
+ parts[r>>8].temp = restrict_flt(parts[r>>8].temp- (MAX_TEMP-parts[i].temp)/2, MIN_TEMP, MAX_TEMP);
+ }
+ kill_part(i);
+ return 0;
}
- kill_part(i);
- return 0;
}
- if ((r&0xFF)==PT_DEUT && parts[i].type==PT_ELEC)
+ else if ((r&0xFF)==PT_DEUT)
{
- if(parts[r>>8].life < 6000)
- parts[r>>8].life += 1;
- parts[r>>8].temp = 0;
- kill_part(i);
- return 0;
+ if (parts[i].type == PT_ELEC)
+ {
+ if(parts[r>>8].life < 6000)
+ parts[r>>8].life += 1;
+ parts[r>>8].temp = 0;
+ kill_part(i);
+ return 0;
+ }
}
- if (((r&0xFF)==PT_VIBR || (r&0xFF)==PT_BVBR) && (elements[parts[i].type].Properties & TYPE_ENERGY))
+ else if (((r&0xFF)==PT_VIBR || (r&0xFF)==PT_BVBR))
{
- parts[r>>8].tmp += 20;
- kill_part(i);
- return 0;
+ if ((elements[parts[i].type].Properties & TYPE_ENERGY))
+ {
+ parts[r>>8].tmp += 20;
+ kill_part(i);
+ return 0;
+ }
}
- if (parts[i].type==PT_CNCT && y<ny && (pmap[y+1][x]&0xFF)==PT_CNCT)//check below CNCT for another CNCT
- return 0;
+ if (parts[i].type == PT_NEUT)
+ {
+ if (elements[r & 0xFF].Properties & PROP_NEUTABSORB)
+ {
+ kill_part(i);
+ return 0;
+ }
+ }
+ else if (parts[i].type == PT_CNCT)
+ {
+ if (y<ny && (pmap[y+1][x]&0xFF) == PT_CNCT) //check below CNCT for another CNCT
+ return 0;
+ }
+ else if(parts[i].type == PT_GBMB)
+ {
+ if (parts[i].life>0)
+ return 0;
+ }
if ((bmap[y/CELL][x/CELL]==WL_EHOLE && !emap[y/CELL][x/CELL]) && !(bmap[ny/CELL][nx/CELL]==WL_EHOLE && !emap[ny/CELL][nx/CELL]))
return 0;
- if(parts[i].type==PT_GBMB&&parts[i].life>0)
- return 0;
-
e = r >> 8; //e is now the particle number at r (pmap[ny][nx])
if (r)//the swap part, if we make it this far, swap
{
@@ -2663,6 +2689,11 @@ int Simulation::create_part(int p, int x, int y, int tv)
parts[index].ctype = PT_DUST;
return index;
}
+ if (p==-2 && ((elements[type].Properties & PROP_DRAWONCTYPE) || type==PT_CRAY))
+ {
+ parts[index].ctype = PT_SPRK;
+ return index;
+ }
if (!(type == PT_INST || (elements[type].Properties&PROP_CONDUCTS)) || parts[index].life!=0)
return -1;
if (p == -2 && type == PT_INST)
@@ -2849,7 +2880,7 @@ int Simulation::create_part(int p, int x, int y, int tv)
break;
case PT_QRTZ:
case PT_PQRT:
- parts[i].tmp = (rand()%11);
+ parts[i].tmp2 = (rand()%11);
break;
case PT_CLST:
parts[i].tmp = (rand()%7);
@@ -2941,12 +2972,16 @@ int Simulation::create_part(int p, int x, int y, int tv)
parts[i].ctype = 0x47FFFF;
break;
case PT_DTEC:
- parts[i].tmp2 = 2;
- break;
case PT_TSNS:
parts[i].tmp2 = 2;
break;
- case PT_FIGH:{
+ case PT_VIRS:
+ case PT_VRSS:
+ case PT_VRSG:
+ parts[i].pavg[1] = 250;
+ break;
+ case PT_FIGH:
+ {
unsigned char fcount = 0;
while (fcount < 100 && fcount < (fighcount+1) && fighters[fcount].spwn==1) fcount++;
if (fcount < 100 && fighters[fcount].spwn==0)
@@ -2961,35 +2996,53 @@ int Simulation::create_part(int p, int x, int y, int tv)
return i;
}
parts[i].type=0;
- return -1;}
- case PT_PHOT:{
+ return -1;
+ }
+ case PT_PHOT:
+ {
float a = (rand()%8) * 0.78540f;
parts[i].life = 680;
parts[i].ctype = 0x3FFFFFFF;
parts[i].vx = 3.0f*cosf(a);
parts[i].vy = 3.0f*sinf(a);
- break;}
- case PT_ELEC:{
+ break;
+ }
+ case PT_ELEC:
+ {
float a = (rand()%360)*3.14159f/180.0f;
parts[i].life = 680;
parts[i].vx = 2.0f*cosf(a);
parts[i].vy = 2.0f*sinf(a);
- break;}
- case PT_NEUT:{
+ break;
+ }
+ case PT_NEUT:
+ {
float r = (rand()%128+128)/127.0f;
float a = (rand()%360)*3.14159f/180.0f;
parts[i].life = rand()%480+480;
parts[i].vx = r*cosf(a);
parts[i].vy = r*sinf(a);
- break;}
- case PT_TRON:{
+ break;
+ }
+ case PT_PROT:
+ {
+ float a = (rand()%36)* 0.17453f;
+ parts[i].life = 680;
+ parts[i].vx = 2.0f*cosf(a);
+ parts[i].vy = 2.0f*sinf(a);
+ break;
+ }
+ case PT_TRON:
+ {
int randhue = rand()%360;
int randomdir = rand()%4;
parts[i].tmp = 1|(randomdir<<5)|(randhue<<7);//set as a head and a direction
parts[i].tmp2 = 4;//tail
parts[i].life = 5;
- break;}
- case PT_LIGH:{
+ break;
+ }
+ case PT_LIGH:
+ {
float gx, gy, gsize;
if (p!=-2)
{
@@ -3008,7 +3061,8 @@ int Simulation::create_part(int p, int x, int y, int tv)
}
parts[i].tmp = (((int)(atan2f(-gy, gx)*(180.0f/M_PI)))+rand()%40-20+360)%360;
parts[i].tmp2 = 4;
- break;}
+ break;
+ }
default:
break;
}
@@ -3762,7 +3816,7 @@ void Simulation::update_particles_i(int start, int inc)
s = 1;
//A fix for ice with ctype = 0
- if ((t==PT_ICEI || t==PT_SNOW) && (parts[i].ctype==0 || parts[i].ctype>=PT_NUM || parts[i].ctype==PT_ICEI || parts[i].ctype==PT_SNOW))
+ if ((t==PT_ICEI || t==PT_SNOW) && (parts[i].ctype<=0 || parts[i].ctype>=PT_NUM || parts[i].ctype==PT_ICEI || parts[i].ctype==PT_SNOW || !elements[parts[i].ctype].Enabled))
parts[i].ctype = PT_WATR;
if (ctemph>elements[t].HighTemperature && elements[t].HighTemperatureTransition>-1)
@@ -3789,7 +3843,7 @@ void Simulation::update_particles_i(int start, int inc)
#endif
else if (t == PT_ICEI || t == PT_SNOW)
{
- if (parts[i].ctype < PT_NUM && parts[i].ctype != t)
+ if (parts[i].ctype > 0 && parts[i].ctype < PT_NUM && parts[i].ctype != t)
{
if (elements[parts[i].ctype].LowTemperatureTransition==t && pt<=elements[parts[i].ctype].LowTemperature)
s = 0;
@@ -3892,7 +3946,7 @@ void Simulation::update_particles_i(int start, int inc)
}
else if (t == PT_LAVA)
{
- if (parts[i].ctype>0 && parts[i].ctype<PT_NUM && parts[i].ctype!=PT_LAVA)
+ if (parts[i].ctype>0 && parts[i].ctype<PT_NUM && parts[i].ctype!=PT_LAVA && parts[i].ctype!=PT_LAVA && elements[parts[i].ctype].Enabled)
{
if (parts[i].ctype==PT_THRM&&pt>=elements[PT_BMTL].HighTemperature)
s = 0;
diff --git a/src/simulation/Simulation.h b/src/simulation/Simulation.h
index 9c900ab..4c4ee95 100644
--- a/src/simulation/Simulation.h
+++ b/src/simulation/Simulation.h
@@ -70,7 +70,6 @@ public:
bool gravWallChanged;
//Portals and Wifi
Particle portalp[CHANNELS][8][80];
- Particle emptyparticle;
int portal_rx[8];
int portal_ry[8];
int wireless[CHANNELS][2];
diff --git a/src/simulation/elements/ACID.cpp b/src/simulation/elements/ACID.cpp
index e078551..4ea94ff 100644
--- a/src/simulation/elements/ACID.cpp
+++ b/src/simulation/elements/ACID.cpp
@@ -48,7 +48,7 @@ Element_ACID::Element_ACID()
//#TPT-Directive ElementHeader Element_ACID static int update(UPDATE_FUNC_ARGS)
int Element_ACID::update(UPDATE_FUNC_ARGS)
- {
+{
int r, rx, ry, trade, np;
for (rx=-2; rx<3; rx++)
for (ry=-2; ry<3; ry++)
@@ -95,7 +95,7 @@ int Element_ACID::update(UPDATE_FUNC_ARGS)
}
}
}
- for ( trade = 0; trade<2; trade ++)
+ for (trade = 0; trade<2; trade++)
{
rx = rand()%5-2;
ry = rand()%5-2;
@@ -109,8 +109,8 @@ int Element_ACID::update(UPDATE_FUNC_ARGS)
int temp = parts[i].life - parts[r>>8].life;
if (temp==1)
{
- parts[r>>8].life ++;
- parts[i].life --;
+ parts[r>>8].life++;
+ parts[i].life--;
}
else if (temp>0)
{
@@ -126,7 +126,6 @@ int Element_ACID::update(UPDATE_FUNC_ARGS)
//#TPT-Directive ElementHeader Element_ACID static int graphics(GRAPHICS_FUNC_ARGS)
int Element_ACID::graphics(GRAPHICS_FUNC_ARGS)
-
{
int s = cpart->life;
if (s>75) s = 75; //These two should not be here.
@@ -140,5 +139,4 @@ int Element_ACID::graphics(GRAPHICS_FUNC_ARGS)
return 0;
}
-
Element_ACID::~Element_ACID() {}
diff --git a/src/simulation/elements/ARAY.cpp b/src/simulation/elements/ARAY.cpp
index ac28834..16bff2d 100644
--- a/src/simulation/elements/ARAY.cpp
+++ b/src/simulation/elements/ARAY.cpp
@@ -98,7 +98,7 @@ int Element_ARAY::update(UPDATE_FUNC_ARGS)
break;
}
} else if ((r&0xFF)==PT_FILT) {//get color if passed through FILT
- colored = parts[r>>8].ctype;
+ colored = Element_FILT::interactWavelengths(&parts[r>>8], colored);
//this if prevents BRAY from stopping on certain materials
} else if ((r&0xFF)!=PT_STOR && (r&0xFF)!=PT_INWR && ((r&0xFF)!=PT_SPRK || parts[r>>8].ctype!=PT_INWR) && (r&0xFF)!=PT_ARAY && (r&0xFF)!=PT_WIFI && !((r&0xFF)==PT_SWCH && parts[r>>8].life>=10)) {
if (nyy!=0 || nxx!=0) {
diff --git a/src/simulation/elements/BCOL.cpp b/src/simulation/elements/BCOL.cpp
index 3fb85af..cb53f6c 100644
--- a/src/simulation/elements/BCOL.cpp
+++ b/src/simulation/elements/BCOL.cpp
@@ -21,7 +21,7 @@ Element_BCOL::Element_BCOL()
Flammable = 0;
Explosive = 0;
- Meltable = 5;
+ Meltable = 0;
Hardness = 2;
Weight = 90;
diff --git a/src/simulation/elements/CRAY.cpp b/src/simulation/elements/CRAY.cpp
index 2933dcf..002ed28 100644
--- a/src/simulation/elements/CRAY.cpp
+++ b/src/simulation/elements/CRAY.cpp
@@ -96,13 +96,14 @@ int Element_CRAY::update(UPDATE_FUNC_ARGS)
else
nr = sim->create_part(-1, x+nxi+nxx, y+nyi+nyy, parts[i].ctype);
if (nr!=-1) {
- parts[nr].dcolour = colored;
+ if (colored)
+ parts[nr].dcolour = colored;
parts[nr].temp = parts[i].temp;
if(!--partsRemaining)
docontinue = 0;
}
} else if ((r&0xFF)==PT_FILT) { // get color if passed through FILT
- colored = wavelengthToDecoColour(parts[r>>8].ctype);
+ colored = wavelengthToDecoColour(Element_FILT::getWavelengths(&parts[r>>8]));
} else if ((r&0xFF) == PT_CRAY || nostop) {
docontinue = 1;
} else if(destroy && r && ((r&0xFF) != PT_DMND)) {
diff --git a/src/simulation/elements/DTEC.cpp b/src/simulation/elements/DTEC.cpp
index 8ecaf2e..ed894a2 100644
--- a/src/simulation/elements/DTEC.cpp
+++ b/src/simulation/elements/DTEC.cpp
@@ -73,6 +73,7 @@ int Element_DTEC::update(UPDATE_FUNC_ARGS)
}
}
}
+ int photonWl = 0;
for (rx=-rd; rx<rd+1; rx++)
for (ry=-rd; ry<rd+1; ry++)
if (x+rx>=0 && y+ry>=0 && x+rx<XRES && y+ry<YRES && (rx || ry))
@@ -84,7 +85,32 @@ int Element_DTEC::update(UPDATE_FUNC_ARGS)
continue;
if (parts[r>>8].type == parts[i].ctype && (parts[i].ctype != PT_LIFE || parts[i].tmp == parts[r>>8].ctype || !parts[i].tmp))
parts[i].life = 1;
+ if (parts[r>>8].type == PT_PHOT)
+ photonWl = parts[r>>8].ctype;
}
+ if (photonWl)
+ {
+ int nx, ny;
+ for (rx=-1; rx<2; rx++)
+ for (ry=-1; ry<2; ry++)
+ if (BOUNDS_CHECK && (rx || ry))
+ {
+ r = pmap[y+ry][x+rx];
+ if (!r)
+ continue;
+ nx = x+rx;
+ ny = y+ry;
+ while ((r&0xFF)==PT_FILT)
+ {
+ parts[r>>8].ctype = photonWl;
+ nx += rx;
+ ny += ry;
+ if (nx<0 || ny<0 || nx>=XRES || ny>=YRES)
+ break;
+ r = pmap[ny][nx];
+ }
+ }
+ }
return 0;
}
diff --git a/src/simulation/elements/ELEC.cpp b/src/simulation/elements/ELEC.cpp
index 8ab4af1..56e90b3 100644
--- a/src/simulation/elements/ELEC.cpp
+++ b/src/simulation/elements/ELEC.cpp
@@ -91,6 +91,7 @@ int Element_ELEC::update(UPDATE_FUNC_ARGS)
sim->create_part(r>>8, x+rx, y+ry, PT_H2);
return 1;
case PT_NEUT:
+ case PT_PROT: // this is the correct reaction, not NEUT, but leaving NEUT in anyway
sim->part_change_type(r>>8, x+rx, y+ry, PT_H2);
parts[r>>8].life = 0;
parts[r>>8].ctype = 0;
@@ -124,8 +125,6 @@ int Element_ELEC::update(UPDATE_FUNC_ARGS)
return 0;
}
-
-
//#TPT-Directive ElementHeader Element_ELEC static int graphics(GRAPHICS_FUNC_ARGS)
int Element_ELEC::graphics(GRAPHICS_FUNC_ARGS)
diff --git a/src/simulation/elements/EXOT.cpp b/src/simulation/elements/EXOT.cpp
index df075e0..e2f6e41 100644
--- a/src/simulation/elements/EXOT.cpp
+++ b/src/simulation/elements/EXOT.cpp
@@ -47,11 +47,13 @@ Element_EXOT::Element_EXOT()
}
//#TPT-Directive ElementHeader Element_EXOT static int update(UPDATE_FUNC_ARGS)
-int Element_EXOT::update(UPDATE_FUNC_ARGS) {
+int Element_EXOT::update(UPDATE_FUNC_ARGS)
+{
int r, rt, rx, ry, nb, rrx, rry, trade, tym;
for (rx=-2; rx<=2; rx++)
for (ry=-2; ry<=2; ry++)
- if (BOUNDS_CHECK && (rx || ry)) {
+ if (BOUNDS_CHECK && (rx || ry))
+ {
r = pmap[y+ry][x+rx];
if (!r)
continue;
@@ -65,11 +67,14 @@ int Element_EXOT::update(UPDATE_FUNC_ARGS) {
}
else if (rt == PT_EXOT)
{
+ if (parts[r>>8].ctype == PT_PROT)
+ parts[i].ctype = PT_PROT;
if (parts[r>>8].life == 1500 && !(rand()%1000))
parts[i].life = 1500;
}
else if (rt == PT_LAVA)
{
+ //turn molten TTAN or molten GOLD to molten VIBR
if (parts[r>>8].ctype == PT_TTAN || parts[r>>8].ctype == PT_GOLD)
{
if (!(rand()%10))
@@ -79,66 +84,71 @@ int Element_EXOT::update(UPDATE_FUNC_ARGS) {
return 1;
}
}
+ //molten VIBR will kill the leftover EXOT though, so the VIBR isn't killed later
else if (parts[r>>8].ctype == PT_VIBR)
{
- if (1>rand()%1000)
+ if (!(rand()%1000))
{
sim->kill_part(i);
return 1;
}
}
}
- if ((parts[i].tmp>245) && (parts[i].life>1000))
+ if (parts[i].tmp > 245 && parts[i].life > 1000)
if (rt!=PT_EXOT && rt!=PT_BREC && rt!=PT_DMND && rt!=PT_CLNE && rt!=PT_PRTI && rt!=PT_PRTO && rt!=PT_PCLN && rt!=PT_VOID && rt!=PT_NBHL && rt!=PT_WARP)
{
sim->create_part(i, x, y, rt);
- return 0;
+ return 1;
}
}
+
parts[i].tmp--;
parts[i].tmp2--;
- if (parts[i].tmp<1 || parts[i].tmp>250)
+ //reset tmp every 250 frames, gives EXOT it's slow flashing effect
+ if (parts[i].tmp < 1 || parts[i].tmp > 250)
parts[i].tmp = 250;
- if (parts[i].tmp2<1)
+
+ if (parts[i].tmp2 < 1)
parts[i].tmp2 = 1;
- else if (parts[i].tmp2>6000)
+ else if (parts[i].tmp2 > 6000)
{
parts[i].tmp2 = 10000;
- if (parts[i].life<1001)
+ if (parts[i].life < 1001)
{
sim->part_change_type(i, x, y, PT_WARP);
return 0;
}
}
- else if(parts[i].life<1001)
+ else if(parts[i].life < 1001)
sim->pv[y/CELL][x/CELL] += (parts[i].tmp2*CFDS)/160000;
+
if (sim->pv[y/CELL][x/CELL]>200 && parts[i].temp>9000 && parts[i].tmp2>200)
{
parts[i].tmp2 = 6000;
sim->part_change_type(i, x, y, PT_WARP);
return 0;
}
- if (parts[i].tmp2>100)
+ if (parts[i].tmp2 > 100)
{
- for ( trade = 0; trade<9; trade ++)
+ for (trade = 0; trade < 9; trade++)
{
rx = rand()%5-2;
ry = rand()%5-2;
- if (x+rx>=0 && y+ry>0 && x+rx<XRES && y+ry<YRES && (rx || ry))
+ if (BOUNDS_CHECK && (rx || ry))
{
r = pmap[y+ry][x+rx];
if (!r)
continue;
- if ((r&0xFF)==PT_EXOT && (parts[i].tmp2>parts[r>>8].tmp2) && parts[r>>8].tmp2>=0 )//diffusion
+ if ((r&0xFF)==PT_EXOT && (parts[i].tmp2 > parts[r>>8].tmp2) && parts[r>>8].tmp2 >= 0) //diffusion
{
tym = parts[i].tmp2 - parts[r>>8].tmp2;
- if (tym ==1)
+ if (tym == 1)
{
- parts[r>>8].tmp2 ++;
- parts[i].tmp2 --;
+ parts[r>>8].tmp2++;
+ parts[i].tmp2--;
break;
}
- if (tym>0)
+ if (tym > 0)
{
parts[r>>8].tmp2 += tym/2;
parts[i].tmp2 -= tym/2;
@@ -148,7 +158,17 @@ int Element_EXOT::update(UPDATE_FUNC_ARGS) {
}
}
}
- if (parts[i].temp<273.15f)
+ if (parts[i].ctype == PT_PROT)
+ {
+ if (parts[i].temp < 50.0f)
+ {
+ sim->create_part(i, x, y, PT_CFLM);
+ return 1;
+ }
+ else
+ parts[i].temp -= 1.0f;
+ }
+ else if (parts[i].temp < 273.15f)
{
parts[i].vx = 0;
parts[i].vy = 0;
diff --git a/src/simulation/elements/FILT.cpp b/src/simulation/elements/FILT.cpp
index d6b82f2..8ece142 100644
--- a/src/simulation/elements/FILT.cpp
+++ b/src/simulation/elements/FILT.cpp
@@ -48,21 +48,17 @@ Element_FILT::Element_FILT()
//#TPT-Directive ElementHeader Element_FILT static int graphics(GRAPHICS_FUNC_ARGS)
int Element_FILT::graphics(GRAPHICS_FUNC_ARGS)
-
{
- int x, temp_bin = (int)((cpart->temp-273.0f)*0.025f);
- if (temp_bin < 0) temp_bin = 0;
- if (temp_bin > 25) temp_bin = 25;
- cpart->ctype = 0x1F << temp_bin;
+ int x, wl = Element_FILT::getWavelengths(cpart);
*colg = 0;
*colb = 0;
*colr = 0;
for (x=0; x<12; x++) {
- *colr += (cpart->ctype >> (x+18)) & 1;
- *colb += (cpart->ctype >> x) & 1;
+ *colr += (wl >> (x+18)) & 1;
+ *colb += (wl >> x) & 1;
}
for (x=0; x<12; x++)
- *colg += (cpart->ctype >> (x+9)) & 1;
+ *colg += (wl >> (x+9)) & 1;
x = 624/(*colr+*colg+*colb+1);
*cola = 127;
*colr *= x;
@@ -73,5 +69,68 @@ int Element_FILT::graphics(GRAPHICS_FUNC_ARGS)
return 0;
}
+//#TPT-Directive ElementHeader Element_FILT static int interactWavelengths(Particle* cpart, int origWl)
+// Returns the wavelengths in a particle after FILT interacts with it (e.g. a photon)
+// cpart is the FILT particle, origWl the original wavelengths in the interacting particle
+int Element_FILT::interactWavelengths(Particle* cpart, int origWl)
+{
+ const int mask = 0x3FFFFFFF;
+ int filtWl = getWavelengths(cpart);
+ switch (cpart->tmp)
+ {
+ case 0:
+ return filtWl; //Assign Colour
+ case 1:
+ return origWl & filtWl; //Filter Colour
+ case 2:
+ return origWl | filtWl; //Add Colour
+ case 3:
+ return origWl & (~filtWl); //Subtract colour of filt from colour of photon
+ case 4:
+ {
+ int shift = int((cpart->temp-273.0f)*0.025f);
+ if (shift<=0) shift = 1;
+ return (origWl << shift) & mask; // red shift
+ }
+ case 5:
+ {
+ int shift = int((cpart->temp-273.0f)*0.025f);
+ if (shift<=0) shift = 1;
+ return (origWl >> shift) & mask; // blue shift
+ }
+ case 6:
+ return origWl; // No change
+ case 7:
+ return origWl ^ filtWl; // XOR colours
+ case 8:
+ return (~origWl) & mask; // Invert colours
+ case 9:
+ {
+ int t1, t2, t3, r;
+ t1 = (origWl & 0x0000FF)+(rand()%5)-2;
+ t1 = ((origWl & 0x00FF00)>>8)+(rand()%5)-2;
+ t3 = ((origWl & 0xFF0000)>>16)+(rand()%5)-2;
+ return (origWl & 0xFF000000) | (t3<<16) | (t2<<8) | t1;
+ }
+ default:
+ return filtWl;
+ }
+}
+
+//#TPT-Directive ElementHeader Element_FILT static int getWavelengths(Particle* cpart)
+int Element_FILT::getWavelengths(Particle* cpart)
+{
+ if (cpart->ctype)
+ {
+ return cpart->ctype;
+ }
+ else
+ {
+ int temp_bin = (int)((cpart->temp-273.0f)*0.025f);
+ if (temp_bin < 0) temp_bin = 0;
+ if (temp_bin > 25) temp_bin = 25;
+ return (0x1F << temp_bin);
+ }
+}
Element_FILT::~Element_FILT() {}
diff --git a/src/simulation/elements/PHOT.cpp b/src/simulation/elements/PHOT.cpp
index e132d3d..4fe5bbe 100644
--- a/src/simulation/elements/PHOT.cpp
+++ b/src/simulation/elements/PHOT.cpp
@@ -88,6 +88,11 @@ int Element_PHOT::update(UPDATE_FUNC_ARGS)
parts[i].ctype = 0x1F<<(rand()%26);
parts[i].life++; //Delay death
}
+ else if ((r&0xFF) == PT_FILT && parts[r>>8].tmp==9)
+ {
+ parts[i].vx += ((float)(rand()%1000-500))/1000.0f;
+ parts[i].vy += ((float)(rand()%1000-500))/1000.0f;
+ }
}
return 0;
}
diff --git a/src/simulation/elements/PIPE.cpp b/src/simulation/elements/PIPE.cpp
index 14dbee0..ee1a21a 100644
--- a/src/simulation/elements/PIPE.cpp
+++ b/src/simulation/elements/PIPE.cpp
@@ -71,6 +71,8 @@ int Element_PIPE::update(UPDATE_FUNC_ARGS)
{
int r, rx, ry, np;
int rnd, rndstore;
+ if ((parts[i].tmp&0xFF)>=PT_NUM || !sim->elements[parts[i].tmp&0xFF].Enabled)
+ parts[i].tmp &= ~0xFF;
if (parts[i].tmp & PPIP_TMPFLAG_TRIGGERS)
{
int pause_changed = 0;
@@ -285,7 +287,7 @@ int Element_PIPE::update(UPDATE_FUNC_ARGS)
//#TPT-Directive ElementHeader Element_PIPE static int graphics(GRAPHICS_FUNC_ARGS)
int Element_PIPE::graphics(GRAPHICS_FUNC_ARGS)
{
- if ((cpart->tmp&0xFF)>0 && (cpart->tmp&0xFF)<PT_NUM)
+ if ((cpart->tmp&0xFF)>0 && (cpart->tmp&0xFF)<PT_NUM && ren->sim->elements[(cpart->tmp&0xFF)].Enabled)
{
//Create a temp. particle and do a subcall.
Particle tpart;
diff --git a/src/simulation/elements/PROT.cpp b/src/simulation/elements/PROT.cpp
new file mode 100644
index 0000000..4302244
--- /dev/null
+++ b/src/simulation/elements/PROT.cpp
@@ -0,0 +1,153 @@
+#include "simulation/Elements.h"
+//#TPT-Directive ElementClass Element_PROT PT_PROT 173
+Element_PROT::Element_PROT()
+{
+ Identifier = "DEFAULT_PT_PROT";
+ Name = "PROT";
+ Colour = PIXPACK(0x990000);
+ MenuVisible = 1;
+ MenuSection = SC_NUCLEAR;
+ Enabled = 1;
+
+ Advection = 0.0f;
+ AirDrag = 0.00f * CFDS;
+ AirLoss = 1.00f;
+ Loss = 1.00f;
+ Collision = -.99f;
+ Gravity = 0.0f;
+ Diffusion = 0.00f;
+ HotAir = 0.000f * CFDS;
+ Falldown = 0;
+
+ Flammable = 0;
+ Explosive = 0;
+ Meltable = 0;
+ Hardness = 0;
+
+ Weight = -1;
+
+ Temperature = R_TEMP+273.15f;
+ HeatConduct = 61;
+ Description = "Protons. Transfer heat to materials, and removes sparks.";
+
+ State = ST_GAS;
+ Properties = TYPE_ENERGY|PROP_LIFE_KILL;
+
+ LowPressure = IPL;
+ LowPressureTransition = NT;
+ HighPressure = IPH;
+ HighPressureTransition = NT;
+ LowTemperature = ITL;
+ LowTemperatureTransition = NT;
+ HighTemperature = ITH;
+ HighTemperatureTransition = NT;
+
+ Update = &Element_PROT::update;
+ Graphics = &Element_PROT::graphics;
+}
+
+//#TPT-Directive ElementHeader Element_PROT static int update(UPDATE_FUNC_ARGS)
+int Element_PROT::update(UPDATE_FUNC_ARGS)
+{
+ sim->pv[y/CELL][x/CELL] -= .003f;
+ int under = pmap[y][x];
+ //set off explosives (only when hot because it wasn't as fun when it made an entire save explode)
+ if (parts[i].temp > 273.15f+500.0f && (sim->elements[under&0xFF].Flammable || sim->elements[under&0xFF].Explosive || (under&0xFF) == PT_BANG))
+ {
+ sim->create_part(under>>8, x, y, PT_FIRE);
+ parts[under>>8].temp += restrict_flt(sim->elements[under&0xFF].Flammable*5, MIN_TEMP, MAX_TEMP);
+ sim->pv[y/CELL][x/CELL] += 1.00f;
+ }
+ //remove active sparks
+ else if ((under&0xFF) == PT_SPRK)
+ {
+ sim->part_change_type(under>>8, x, y, parts[under>>8].ctype);
+ parts[under>>8].life = 44+parts[under>>8].life;
+ parts[under>>8].ctype = 0;
+ }
+ //prevent inactive sparkable elements from being sparked
+ else if ((sim->elements[under&0xFF].Properties&PROP_CONDUCTS) && parts[under>>8].life <= 4)
+ {
+ parts[under>>8].life = 40+parts[under>>8].life;
+ }
+ else if ((under&0xFF) == PT_EXOT)
+ parts[under>>8].ctype = PT_PROT;
+
+ //make temp of other things closer to it's own temperature. This will change temp of things that don't conduct, and won't change the PROT's temperature
+ if (under)
+ {
+ if ((under&0xFF) == PT_WIFI || (under&0xFF) == PT_PRTI || (under&0xFF) == PT_PRTO)
+ {
+ float change;
+ if (parts[i].temp<173.15f) change = -1000.0f;
+ else if (parts[i].temp<273.15f) change = -100.0f;
+ else if (parts[i].temp>473.15f) change = 1000.0f;
+ else if (parts[i].temp>373.15f) change = 100.0f;
+ else change = 0.0f;
+ parts[under>>8].temp = restrict_flt(parts[under>>8].temp+change, MIN_TEMP, MAX_TEMP);
+ }
+ else
+ {
+ parts[under>>8].temp = restrict_flt(parts[under>>8].temp-(parts[under>>8].temp-parts[i].temp)/4.0f, MIN_TEMP, MAX_TEMP);
+ }
+ }
+ //else, slowly kill it if it's not inside an element
+ else
+ parts[i].life--;
+
+ //if this proton has collided with another last frame, change it into a heavier element
+ if (parts[i].tmp)
+ {
+ int newID, element;
+ if (parts[i].tmp > 4250)
+ element = PT_SING; //particle accelerators are known to create earth-destroying black holes
+ else if (parts[i].tmp > 275)
+ element = PT_PLUT;
+ else if (parts[i].tmp > 170)
+ element = PT_URAN;
+ else if (parts[i].tmp > 100)
+ element = PT_PLSM;
+ else if (parts[i].tmp > 40)
+ element = PT_O2;
+ else if (parts[i].tmp > 20)
+ element = PT_CO2;
+ else
+ element = PT_NBLE;
+ newID = sim->create_part(-1, x+rand()%3-1, y+rand()%3-1, element);
+ parts[newID].temp = restrict_flt(100.0f*parts[i].tmp, MIN_TEMP, MAX_TEMP);
+ sim->kill_part(i);
+ return 1;
+ }
+ //collide with other protons to make heavier materials
+ int ahead = sim->photons[y][x];
+ if ((ahead>>8) != i && (ahead&0xFF) == PT_PROT)
+ {
+ float velocity1 = powf(parts[i].vx, 2.0f)+powf(parts[i].vy, 2.0f);
+ float velocity2 = powf(parts[ahead>>8].vx, 2.0f)+powf(parts[ahead>>8].vy, 2.0f);
+ float direction1 = atan2f(-parts[i].vy, parts[i].vx);
+ float direction2 = atan2f(-parts[ahead>>8].vy, parts[ahead>>8].vx);
+ float difference = direction1 - direction2; if (difference < 0) difference += 6.28319f;
+
+ if (difference > 3.12659f && difference < 3.15659f && velocity1 + velocity2 > 10.0f)
+ {
+ parts[ahead>>8].tmp += (int)(velocity1 + velocity2);
+ sim->kill_part(i);
+ return 1;
+ }
+ }
+ return 0;
+}
+
+//#TPT-Directive ElementHeader Element_PROT static int graphics(GRAPHICS_FUNC_ARGS)
+int Element_PROT::graphics(GRAPHICS_FUNC_ARGS)
+{
+ *firea = 20;
+ *firer = 250;
+ *fireg = 128;
+ *fireb = 128;
+
+ *pixel_mode |= FIRE_ADD;
+ return 1;
+}
+
+Element_PROT::~Element_PROT() {}
diff --git a/src/simulation/elements/PRTO.cpp b/src/simulation/elements/PRTO.cpp
index 6ec11b4..1eae7ce 100644
--- a/src/simulation/elements/PRTO.cpp
+++ b/src/simulation/elements/PRTO.cpp
@@ -85,7 +85,7 @@ int Element_PRTO::update(UPDATE_FUNC_ARGS)
sim->create_part(-1,x-1,y+1,PT_SPRK);
sim->create_part(-1,x-1,y,PT_SPRK);
sim->create_part(-1,x-1,y-1,PT_SPRK);
- sim->portalp[parts[i].tmp][randomness][nnx] = sim->emptyparticle;
+ memset(&sim->portalp[parts[i].tmp][randomness][nnx], 0, sizeof(Particle));
break;
}
else if (sim->portalp[parts[i].tmp][randomness][nnx].type)
@@ -132,7 +132,7 @@ int Element_PRTO::update(UPDATE_FUNC_ARGS)
parts[np] = sim->portalp[parts[i].tmp][randomness][nnx];
parts[np].x = x+rx;
parts[np].y = y+ry;
- sim->portalp[parts[i].tmp][randomness][nnx] = sim->emptyparticle;
+ memset(&sim->portalp[parts[i].tmp][randomness][nnx], 0, sizeof(Particle));
break;
}
}
diff --git a/src/simulation/elements/PSTN.cpp b/src/simulation/elements/PSTN.cpp
index 6dda77f..998f7a2 100644
--- a/src/simulation/elements/PSTN.cpp
+++ b/src/simulation/elements/PSTN.cpp
@@ -167,7 +167,7 @@ int Element_PSTN::update(UPDATE_FUNC_ARGS)
//#TPT-Directive ElementHeader Element_PSTN static int CanMoveStack(Simulation * sim, int stackX, int stackY, int directionX, int directionY, int maxSize, int amount, bool retract, int block)
int Element_PSTN::CanMoveStack(Simulation * sim, int stackX, int stackY, int directionX, int directionY, int maxSize, int amount, bool retract, int block)
{
- int posX, posY, r, spaces = 0, currentPos = 0;
+ int posX, posY, r, spaces = 0, currentPos = 0, num = 0;
if (amount <= 0)
return 0;
for(posX = stackX, posY = stackY; currentPos < maxSize + amount && currentPos < XRES-1; posX += directionX, posY += directionY) {
@@ -176,7 +176,7 @@ int Element_PSTN::CanMoveStack(Simulation * sim, int stackX, int stackY, int dir
}
r = sim->pmap[posY][posX];
if (sim->IsWallBlocking(posX, posY, 0) || (block && (r&0xFF) == block))
- return spaces;
+ return num;
if(!r) {
spaces++;
tempParts[currentPos++] = -1;
@@ -186,8 +186,9 @@ int Element_PSTN::CanMoveStack(Simulation * sim, int stackX, int stackY, int dir
if(spaces < maxSize && currentPos < maxSize && (!retract || ((r&0xFF) == PT_FRME) && posX == stackX && posY == stackY))
tempParts[currentPos++] = r>>8;
else
- return spaces;
+ return num;
}
+ num++;
}
if (spaces)
return currentPos;
diff --git a/src/simulation/elements/QRTZ.cpp b/src/simulation/elements/QRTZ.cpp
index 5eec6d6..b399662 100644
--- a/src/simulation/elements/QRTZ.cpp
+++ b/src/simulation/elements/QRTZ.cpp
@@ -60,7 +60,7 @@ int Element_QRTZ::update(UPDATE_FUNC_ARGS)
}
}
// absorb SLTW
- if (parts[i].ctype!=-1)
+ if (parts[i].tmp != -1)
for (rx=-1; rx<2; rx++)
for (ry=-1; ry<2; ry++)
if (BOUNDS_CHECK && (rx || ry))
@@ -71,15 +71,15 @@ int Element_QRTZ::update(UPDATE_FUNC_ARGS)
else if ((r&0xFF)==PT_SLTW && !(rand()%500))
{
sim->kill_part(r>>8);
- parts[i].ctype ++;
+ parts[i].tmp++;
}
}
// grow and diffuse
- if (parts[i].ctype>0)
+ if (parts[i].tmp > 0)
{
- bool stopgrow=false;
+ bool stopgrow = false;
int rnd, sry, srx;
- for ( trade = 0; trade<9; trade ++)
+ for (trade = 0; trade < 9; trade++)
{
rnd = rand()%0x3FF;
rx = (rnd%5)-2;
@@ -91,20 +91,20 @@ int Element_QRTZ::update(UPDATE_FUNC_ARGS)
{
if (!stopgrow)//try to grow
{
- if (!pmap[y+sry][x+srx] && parts[i].ctype!=0)
+ if (!pmap[y+sry][x+srx] && parts[i].tmp!=0)
{
np = sim->create_part(-1,x+srx,y+sry,PT_QRTZ);
if (np>-1)
{
- parts[np].tmp = parts[i].tmp;
- parts[i].ctype--;
+ parts[np].tmp2 = parts[i].tmp2;
+ parts[i].tmp--;
if (rand()%2)
{
- parts[np].ctype=-1;//dead qrtz
+ parts[np].tmp=-1;//dead qrtz
}
- else if (!parts[i].ctype && !(rand()%15))
+ else if (!parts[i].tmp && !(rand()%15))
{
- parts[i].ctype=-1;
+ parts[i].tmp=-1;
}
stopgrow=true;
}
@@ -114,19 +114,19 @@ int Element_QRTZ::update(UPDATE_FUNC_ARGS)
r = pmap[y+ry][x+rx];
if (!r)
continue;
- else if ((r&0xFF)==PT_QRTZ && (parts[i].ctype>parts[r>>8].ctype) && parts[r>>8].ctype>=0)
+ else if ((r&0xFF)==PT_QRTZ && (parts[i].tmp>parts[r>>8].tmp) && parts[r>>8].tmp>=0)
{
- tmp = parts[i].ctype - parts[r>>8].ctype;
+ tmp = parts[i].tmp - parts[r>>8].tmp;
if (tmp ==1)
{
- parts[r>>8].ctype ++;
- parts[i].ctype --;
+ parts[r>>8].tmp++;
+ parts[i].tmp--;
break;
}
if (tmp>0)
{
- parts[r>>8].ctype += tmp/2;
- parts[i].ctype -= tmp/2;
+ parts[r>>8].tmp += tmp/2;
+ parts[i].tmp -= tmp/2;
break;
}
}
@@ -141,7 +141,7 @@ int Element_QRTZ::update(UPDATE_FUNC_ARGS)
int Element_QRTZ::graphics(GRAPHICS_FUNC_ARGS)
//QRTZ and PQRT
{
- int t = cpart->type, z = cpart->tmp - 5;//speckles!
+ int t = cpart->type, z = cpart->tmp2 - 5;//speckles!
/*if (cpart->temp>(ptransitions[t].thv-800.0f))//hotglow for quartz
{
float frequency = 3.1415/(2*ptransitions[t].thv-(ptransitions[t].thv-800.0f));
diff --git a/src/simulation/elements/SOAP.cpp b/src/simulation/elements/SOAP.cpp
index de7055d..fb88287 100644
--- a/src/simulation/elements/SOAP.cpp
+++ b/src/simulation/elements/SOAP.cpp
@@ -28,7 +28,7 @@ Element_SOAP::Element_SOAP()
Temperature = R_TEMP-2.0f +273.15f;
HeatConduct = 29;
- Description = "Soap. Creates bubbles. Washes off deco color.";
+ Description = "Soap. Creates bubbles, washes off deco color, and cures virus.";
State = ST_LIQUID;
Properties = TYPE_LIQUID|PROP_NEUTPENETRATE|PROP_LIFE_DEC;
diff --git a/src/simulation/elements/VIRS.cpp b/src/simulation/elements/VIRS.cpp
new file mode 100644
index 0000000..a4a8800
--- /dev/null
+++ b/src/simulation/elements/VIRS.cpp
@@ -0,0 +1,145 @@
+#include "simulation/Elements.h"
+//#TPT-Directive ElementClass Element_VIRS PT_VIRS 174
+Element_VIRS::Element_VIRS()
+{
+ Identifier = "DEFAULT_PT_VIRS";
+ Name = "VIRS";
+ Colour = PIXPACK(0xFE11F6);
+ MenuVisible = 1;
+ MenuSection = SC_LIQUID;
+ Enabled = 1;
+
+ Advection = 0.6f;
+ AirDrag = 0.01f * CFDS;
+ AirLoss = 0.98f;
+ Loss = 0.95f;
+ Collision = 0.0f;
+ Gravity = 0.1f;
+ Diffusion = 0.00f;
+ HotAir = 0.000f * CFDS;
+ Falldown = 2;
+
+ Flammable = 100;
+ Explosive = 0;
+ Meltable = 0;
+ Hardness = 20;
+
+ Weight = 31;
+
+ Temperature = 72.0f + 273.15f;
+ HeatConduct = 251;
+ Description = "Virus. Turns everything it touches into virus.";
+
+ State = ST_LIQUID;
+ Properties = TYPE_LIQUID|PROP_DEADLY;
+
+ LowPressure = IPL;
+ LowPressureTransition = NT;
+ HighPressure = IPH;
+ HighPressureTransition = NT;
+ LowTemperature = 305.0f;
+ LowTemperatureTransition = PT_VRSS;
+ HighTemperature = 673.0f;
+ HighTemperatureTransition = PT_VRSG;
+
+ Update = &Element_VIRS::update;
+
+}
+
+//#TPT-Directive ElementHeader Element_VIRS static int update(UPDATE_FUNC_ARGS)
+int Element_VIRS::update(UPDATE_FUNC_ARGS)
+{
+ //pavg[0] measures how many frames until it is cured (0 if still actively spreading and not being cured)
+ //pavg[1] measures how many frames until it dies
+ int r, rx, ry, rndstore = rand();
+ if (parts[i].pavg[0])
+ {
+ parts[i].pavg[0] -= (rndstore&0x1) ? 0:1;
+ //has been cured, so change back into the original element
+ if (!parts[i].pavg[0])
+ {
+ sim->part_change_type(i,x,y,parts[i].tmp2);
+ parts[i].tmp2 = 0;
+ parts[i].pavg[0] = 0;
+ parts[i].pavg[1] = 0;
+ return 0;
+ }
+ }
+ //decrease pavg[1] so it slowly dies
+ if (parts[i].pavg[1] > 0)
+ {
+ if (((rndstore>>1)&0xD) < 1)
+ {
+ parts[i].pavg[1]--;
+ //if pavg[1] is now 0 and it's not in the process of being cured, kill it
+ if (!parts[i].pavg[1] && !parts[i].pavg[0])
+ {
+ sim->kill_part(i);
+ return 1;
+ }
+ }
+ }
+
+ //none of the things in the below loop happen while virus is being cured
+ if (parts[i].pavg[0])
+ return 0;
+
+ for (rx=-1; rx<2; rx++)
+ {
+ //reset rndstore, one random can last through 3 locations and reduce rand() calling by up to 6x as much
+ rndstore = rand();
+ for (ry=-1; ry<2; ry++)
+ {
+ if (BOUNDS_CHECK && (rx || ry))
+ {
+ r = pmap[y+ry][x+rx];
+ if (!r)
+ continue;
+
+ //spread "being cured" state
+ if (((r&0xFF) == PT_VIRS || (r&0xFF) == PT_VRSS || (r&0xFF) == PT_VRSG) && parts[r>>8].pavg[0])
+ {
+ parts[i].pavg[0] = parts[r>>8].pavg[0] + (((rndstore&0x7)>>1) ? 2:1);
+ rndstore = rndstore >> 3;
+ return 0;
+ }
+ //soap cures virus
+ else if ((r&0xFF) == PT_SOAP)
+ {
+ parts[i].pavg[0] += 10;
+ if (!((rndstore&0x7)>>1))
+ sim->kill_part(r>>8);
+ return 0;
+ }
+ //transforms things into virus here
+ else if ((r&0xFF) != PT_VIRS && (r&0xFF) != PT_VRSS && (r&0xFF) != PT_VRSG && (r&0xFF) != PT_DMND)
+ {
+ if (!((rndstore&0xF)>>1))
+ {
+ parts[r>>8].tmp2 = (r&0xFF);
+ parts[r>>8].pavg[0] = 0;
+ if (parts[i].pavg[1])
+ parts[r>>8].pavg[1] = parts[i].pavg[1] + ((rndstore>>4) ? 1:0);
+ else
+ parts[r>>8].pavg[1] = 0;
+ if (parts[r>>8].temp < 305.0f)
+ sim->part_change_type(r>>8,x,y,PT_VRSS);
+ else if (parts[r>>8].temp > 673.0f)
+ sim->part_change_type(r>>8,x,y,PT_VRSG);
+ else
+ sim->part_change_type(r>>8,x,y,PT_VIRS);
+ }
+ rndstore = rndstore >> 5;
+ }
+ //protons make VIRS last forever
+ else if ((sim->photons[y+ry][x+rx]&0xFF) == PT_PROT)
+ {
+ parts[i].pavg[1] = 0;
+ }
+ }
+ }
+ }
+ return 0;
+}
+
+Element_VIRS::~Element_VIRS() {}
diff --git a/src/simulation/elements/VRSG.cpp b/src/simulation/elements/VRSG.cpp
new file mode 100644
index 0000000..8c699d7
--- /dev/null
+++ b/src/simulation/elements/VRSG.cpp
@@ -0,0 +1,49 @@
+#include "simulation/Elements.h"
+//#TPT-Directive ElementClass Element_VRSG PT_VRSG 176
+Element_VRSG::Element_VRSG()
+{
+ Identifier = "DEFAULT_PT_VRSG";
+ Name = "VRSG";
+ Colour = PIXPACK(0xFE68FE);
+ MenuVisible = 0;
+ MenuSection = SC_GAS;
+ Enabled = 1;
+
+ Advection = 1.0f;
+ AirDrag = 0.01f * CFDS;
+ AirLoss = 0.99f;
+ Loss = 0.30f;
+ Collision = -0.1f;
+ Gravity = 0.0f;
+ Diffusion = 0.75f;
+ HotAir = 0.000f * CFDS;
+ Falldown = 0;
+
+ Flammable = 500;
+ Explosive = 0;
+ Meltable = 0;
+ Hardness = 0;
+
+ Weight = 1;
+
+ Temperature = 522.0f + 273.15f;
+ HeatConduct = 251;
+ Description = "Gas Virus. Turns everything it touches into virus.";
+
+ State = ST_GAS;
+ Properties = TYPE_GAS|PROP_DEADLY;
+
+ LowPressure = IPL;
+ LowPressureTransition = NT;
+ HighPressure = IPH;
+ HighPressureTransition = NT;
+ LowTemperature = 673.0f;
+ LowTemperatureTransition = PT_VIRS;
+ HighTemperature = ITH;
+ HighTemperatureTransition = NT;
+
+ Update = &Element_VIRS::update;
+
+}
+
+Element_VRSG::~Element_VRSG() {}
diff --git a/src/simulation/elements/VRSS.cpp b/src/simulation/elements/VRSS.cpp
new file mode 100644
index 0000000..903a5f7
--- /dev/null
+++ b/src/simulation/elements/VRSS.cpp
@@ -0,0 +1,49 @@
+#include "simulation/Elements.h"
+//#TPT-Directive ElementClass Element_VRSS PT_VRSS 175
+Element_VRSS::Element_VRSS()
+{
+ Identifier = "DEFAULT_PT_VRSS";
+ Name = "VRSS";
+ Colour = PIXPACK(0xD408CD);
+ MenuVisible = 0;
+ MenuSection = SC_SOLIDS;
+ Enabled = 1;
+
+ Advection = 0.0f;
+ AirDrag = 0.00f * CFDS;
+ AirLoss = 0.90f;
+ Loss = 0.00f;
+ Collision = 0.0f;
+ Gravity = 0.0f;
+ Diffusion = 0.00f;
+ HotAir = 0.000f * CFDS;
+ Falldown = 0;
+
+ Flammable = 5;
+ Explosive = 0;
+ Meltable = 0;
+ Hardness = 1;
+
+ Weight = 100;
+
+ Temperature = R_TEMP+ 273.15f;
+ HeatConduct = 251;
+ Description = "Solid Virus. Turns everything it touches into virus.";
+
+ State = ST_SOLID;
+ Properties = TYPE_SOLID|PROP_DEADLY;
+
+ LowPressure = IPL;
+ LowPressureTransition = NT;
+ HighPressure = IPH;
+ HighPressureTransition = NT;
+ LowTemperature = ITL;
+ LowTemperatureTransition = NT;
+ HighTemperature = 305.0f;
+ HighTemperatureTransition = PT_VIRS;
+
+ Update = &Element_VIRS::update;
+
+}
+
+Element_VRSS::~Element_VRSS() {}