From bebe9bd8fd0e4b73fdeb9ea0218bda704e0a6fad Mon Sep 17 00:00:00 2001 From: jacksonmj Date: Thu, 29 Aug 2013 17:19:07 +0100 Subject: [PATCH] Add a way for photons to set the colour of FILT (major version bump required) Also add some new FILT modes, and make FILT modes affect BIZR and BRAY colour in the same way as they affect photon colour. Photons passing next to DTEC will set the colour of all FILT in a straight line starting from any FILT adjacent to the DTEC (a bit like an ARAY beam), and the exact colour of the photon will be used for FILT interactions instead of the colour based on temperature. FILT tmp=4: red shift, tmp=5: blue shift. Size of shift determined by FILT temperature. tmp=6: FILT has no effect on photon colour (possible before by using invalid tmp modes, but here's a supported method of doing it. Invalid tmp modes should be automatically replaced in existing saves). Also, FILT mode is now described in the HUD. --- src/client/GameSave.cpp | 16 ++++++++ src/gui/game/GameView.cpp | 13 ++++++- src/simulation/Simulation.cpp | 18 +-------- src/simulation/elements/ARAY.cpp | 2 +- src/simulation/elements/CRAY.cpp | 2 +- src/simulation/elements/DTEC.cpp | 26 +++++++++++++ src/simulation/elements/FILT.cpp | 63 ++++++++++++++++++++++++++++---- 7 files changed, 113 insertions(+), 27 deletions(-) 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() {}