diff --git a/src/client/GameSave.cpp b/src/client/GameSave.cpp index 52ad64bf2..941228eaa 100644 --- a/src/client/GameSave.cpp +++ b/src/client/GameSave.cpp @@ -965,6 +965,13 @@ void GameSave::readOPS(char * data, int dataLength) case PT_FIGH: if (savedVersion < 88 && particles[newIndex].ctype == OLD_SPC_AIR) particles[newIndex].ctype = SPC_AIR; + case PT_FILT: + if (savedVersion < 89) + { + if (particles[newIndex].tmp<0 || particles[newIndex].tmp>3) + particles[newIndex].tmp = 6; + particles[newIndex].ctype = 0; + } } newIndex++; } @@ -1587,6 +1594,15 @@ 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; + } + } } } diff --git a/src/gui/game/GameView.cpp b/src/gui/game/GameView.cpp index f7fa6f578..01ba39c04 100644 --- a/src/gui/game/GameView.cpp +++ b/src/gui/game/GameView.cpp @@ -2068,6 +2068,15 @@ void GameView::OnDraw() 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"}; + if (sample.particle.tmp>=0 && sample.particle.tmp<=6) + sampleInfo << " (" << filtModes[sample.particle.tmp] << ")"; + else + sampleInfo << " (unknown mode)"; + } else { sampleInfo << c->ElementResolve(sample.particle.type, sample.particle.ctype); @@ -2094,7 +2103,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 c1cf22e44..64371acbd 100644 --- a/src/simulation/Simulation.cpp +++ b/src/simulation/Simulation.cpp @@ -2200,18 +2200,7 @@ int Simulation::try_move(int i, int x, int y, int nx, int ny) } 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 - } + parts[i].ctype = Element_FILT::interactWavelengths(&parts[r>>8], parts[i].ctype); } if (parts[i].type == PT_NEUT && (r&0xFF)==PT_GLAS) { if (rand() < RAND_MAX/10) @@ -2223,10 +2212,7 @@ int Simulation::try_move(int i, int x, int y, int nx, int ny) } if ((parts[i].type==PT_BIZR||parts[i].type==PT_BIZRG) && (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; - parts[i].ctype = 0x1F << temp_bin; + parts[i].ctype = Element_FILT::interactWavelengths(&parts[r>>8], parts[i].ctype); } if (((r&0xFF)==PT_BIZR || (r&0xFF)==PT_BIZRG || (r&0xFF)==PT_BIZRS) && parts[i].type==PT_PHOT) { diff --git a/src/simulation/elements/ARAY.cpp b/src/simulation/elements/ARAY.cpp index ac288347d..16bff2d4e 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/CRAY.cpp b/src/simulation/elements/CRAY.cpp index 2933dcf1e..b906c3368 100644 --- a/src/simulation/elements/CRAY.cpp +++ b/src/simulation/elements/CRAY.cpp @@ -102,7 +102,7 @@ int Element_CRAY::update(UPDATE_FUNC_ARGS) 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 8ecaf2e56..ed894a2ca 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=0 && y+ry>=0 && x+rx>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/FILT.cpp b/src/simulation/elements/FILT.cpp index d6b82f26c..62c3afcfc 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,56 @@ 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 + 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() {}