579 lines
16 KiB
C++
579 lines
16 KiB
C++
#include "simulation/ElementCommon.h"
|
|
|
|
int Element_PIPE_update(UPDATE_FUNC_ARGS);
|
|
int Element_PIPE_graphics(GRAPHICS_FUNC_ARGS);
|
|
void Element_PIPE_transfer_pipe_to_part(Simulation * sim, Particle *pipe, Particle *part, bool STOR);
|
|
static void transfer_part_to_pipe(Particle *part, Particle *pipe);
|
|
static void transfer_pipe_to_pipe(Particle *src, Particle *dest, bool STOR);
|
|
static void pushParticle(Simulation * sim, int i, int count, int original);
|
|
void Element_SOAP_detach(Simulation * sim, int i);
|
|
|
|
void Element::Element_PIPE()
|
|
{
|
|
Identifier = "DEFAULT_PT_PIPE";
|
|
Name = "PIPE";
|
|
Colour = PIXPACK(0x444444);
|
|
MenuVisible = 1;
|
|
MenuSection = SC_FORCE;
|
|
Enabled = 1;
|
|
|
|
Advection = 0.0f;
|
|
AirDrag = 0.00f * CFDS;
|
|
AirLoss = 0.95f;
|
|
Loss = 0.00f;
|
|
Collision = 0.0f;
|
|
Gravity = 0.0f;
|
|
Diffusion = 0.00f;
|
|
HotAir = 0.000f * CFDS;
|
|
Falldown = 0;
|
|
|
|
Flammable = 0;
|
|
Explosive = 0;
|
|
Meltable = 0;
|
|
Hardness = 0;
|
|
|
|
Weight = 100;
|
|
|
|
DefaultProperties.temp = 273.15f;
|
|
HeatConduct = 0;
|
|
Description = "PIPE, moves particles around. Once the BRCK generates, erase some for the exit. Then the PIPE generates and is usable.";
|
|
|
|
Properties = TYPE_SOLID|PROP_LIFE_DEC;
|
|
|
|
LowPressure = IPL;
|
|
LowPressureTransition = NT;
|
|
HighPressure = 10.0f;
|
|
HighPressureTransition = PT_BRMT;
|
|
LowTemperature = ITL;
|
|
LowTemperatureTransition = NT;
|
|
HighTemperature = ITH;
|
|
HighTemperatureTransition = NT;
|
|
|
|
DefaultProperties.life = 60;
|
|
|
|
Update = &Element_PIPE_update;
|
|
Graphics = &Element_PIPE_graphics;
|
|
}
|
|
|
|
// 0x000000FF element
|
|
// 0x00000100 is single pixel pipe
|
|
// 0x00000200 will transfer like a single pixel pipe when in forward mode
|
|
// 0x00001C00 forward single pixel pipe direction
|
|
// 0x00002000 will transfer like a single pixel pipe when in reverse mode
|
|
// 0x0001C000 reverse single pixel pipe direction
|
|
// 0x000E0000 PIPE color data stored here
|
|
|
|
constexpr int PFLAG_NORMALSPEED = 0x00010000;
|
|
constexpr int PFLAG_INITIALIZING = 0x00020000; // colors haven't been set yet
|
|
constexpr int PFLAG_COLOR_RED = 0x00040000;
|
|
constexpr int PFLAG_COLOR_GREEN = 0x00080000;
|
|
constexpr int PFLAG_COLOR_BLUE = 0x000C0000;
|
|
constexpr int PFLAG_COLORS = 0x000C0000;
|
|
|
|
constexpr int PPIP_TMPFLAG_REVERSED = 0x01000000;
|
|
constexpr int PPIP_TMPFLAG_PAUSED = 0x02000000;
|
|
constexpr int PPIP_TMPFLAG_TRIGGER_REVERSE = 0x04000000;
|
|
constexpr int PPIP_TMPFLAG_TRIGGER_OFF = 0x08000000;
|
|
constexpr int PPIP_TMPFLAG_TRIGGER_ON = 0x10000000;
|
|
constexpr int PPIP_TMPFLAG_TRIGGERS = 0x1C000000;
|
|
|
|
signed char pos_1_rx[] = { -1,-1,-1, 0, 0, 1, 1, 1 };
|
|
signed char pos_1_ry[] = { -1, 0, 1,-1, 1,-1, 0, 1 };
|
|
|
|
static void transformPatch(Particle &part, const int (&patch)[8])
|
|
{
|
|
if (part.tmp & 0x00000200) part.tmp = (part.tmp & 0xFFFFE3FF) | (patch[(part.tmp & 0x00001C00) >> 10] << 10);
|
|
if (part.tmp & 0x00002000) part.tmp = (part.tmp & 0xFFFE3FFF) | (patch[(part.tmp & 0x0001C000) >> 14] << 14);
|
|
}
|
|
|
|
void Element_PIPE_patchR(Particle &part)
|
|
{
|
|
// 035 -> 210
|
|
// 1 6 -> 4 3
|
|
// 247 -> 765
|
|
const int patchR[] = { 2, 4, 7, 1, 6, 0, 3, 5 };
|
|
transformPatch(part, patchR);
|
|
}
|
|
|
|
void Element_PIPE_patchH(Particle &part)
|
|
{
|
|
// 035 -> 530
|
|
// 1 6 -> 6 1
|
|
// 247 -> 742
|
|
const int patchH[] = { 5, 6, 7, 3, 4, 0, 1, 2 };
|
|
transformPatch(part, patchH);
|
|
}
|
|
|
|
void Element_PIPE_patchV(Particle &part)
|
|
{
|
|
// 035 -> 247
|
|
// 1 6 -> 1 6
|
|
// 247 -> 035
|
|
const int patchV[] = { 2, 1, 0, 4, 3, 7, 6, 5 };
|
|
transformPatch(part, patchV);
|
|
}
|
|
|
|
static unsigned int prevColor(unsigned int flags)
|
|
{
|
|
unsigned int color = flags & PFLAG_COLORS;
|
|
if (color == PFLAG_COLOR_RED)
|
|
return PFLAG_COLOR_GREEN;
|
|
else if (color == PFLAG_COLOR_GREEN)
|
|
return PFLAG_COLOR_BLUE;
|
|
else if (color == PFLAG_COLOR_BLUE)
|
|
return PFLAG_COLOR_RED;
|
|
return PFLAG_COLOR_RED;
|
|
}
|
|
|
|
static unsigned int nextColor(unsigned int flags)
|
|
{
|
|
unsigned int color = flags & PFLAG_COLORS;
|
|
if (color == PFLAG_COLOR_RED)
|
|
return PFLAG_COLOR_BLUE;
|
|
else if (color == PFLAG_COLOR_BLUE)
|
|
color = PFLAG_COLOR_GREEN;
|
|
else if (color == PFLAG_COLOR_GREEN)
|
|
return PFLAG_COLOR_RED;
|
|
return PFLAG_COLOR_GREEN;
|
|
}
|
|
|
|
int Element_PIPE_update(UPDATE_FUNC_ARGS)
|
|
{
|
|
int r, rx, ry, np;
|
|
int rnd, rndstore;
|
|
if (parts[i].ctype && !sim->elements[TYP(parts[i].ctype)].Enabled)
|
|
parts[i].ctype = 0;
|
|
if (parts[i].tmp & PPIP_TMPFLAG_TRIGGERS)
|
|
{
|
|
int pause_changed = 0;
|
|
if (parts[i].tmp & PPIP_TMPFLAG_TRIGGER_ON) // TRIGGER_ON overrides TRIGGER_OFF
|
|
{
|
|
if (parts[i].tmp & PPIP_TMPFLAG_PAUSED)
|
|
pause_changed = 1;
|
|
parts[i].tmp &= ~PPIP_TMPFLAG_PAUSED;
|
|
}
|
|
else if (parts[i].tmp & PPIP_TMPFLAG_TRIGGER_OFF)
|
|
{
|
|
if (!(parts[i].tmp & PPIP_TMPFLAG_PAUSED))
|
|
pause_changed = 1;
|
|
parts[i].tmp |= PPIP_TMPFLAG_PAUSED;
|
|
}
|
|
if (pause_changed)
|
|
{
|
|
int rx, ry, r;
|
|
for (rx=-2; rx<3; rx++)
|
|
for (ry=-2; ry<3; ry++)
|
|
{
|
|
if (BOUNDS_CHECK && (rx || ry))
|
|
{
|
|
r = pmap[y+ry][x+rx];
|
|
if (TYP(r) == PT_BRCK)
|
|
{
|
|
if (parts[i].tmp & PPIP_TMPFLAG_PAUSED)
|
|
parts[ID(r)].tmp = 0;
|
|
else
|
|
parts[ID(r)].tmp = 1; //make surrounding BRCK glow
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
if (parts[i].tmp & PPIP_TMPFLAG_TRIGGER_REVERSE)
|
|
{
|
|
parts[i].tmp ^= PPIP_TMPFLAG_REVERSED;
|
|
// Switch colors so it goes in reverse
|
|
if ((parts[i].tmp&PFLAG_COLORS) != PFLAG_COLOR_GREEN)
|
|
parts[i].tmp ^= PFLAG_COLOR_GREEN;
|
|
if (parts[i].tmp & 0x100) //Switch one pixel pipe direction
|
|
{
|
|
int coords = (parts[i].tmp>>13)&0xF;
|
|
int coords2 = (parts[i].tmp>>9)&0xF;
|
|
parts[i].tmp &= ~0x1FE00;
|
|
parts[i].tmp |= coords<<9;
|
|
parts[i].tmp |= coords2<<13;
|
|
}
|
|
}
|
|
|
|
parts[i].tmp &= ~PPIP_TMPFLAG_TRIGGERS;
|
|
}
|
|
if ((parts[i].tmp&PFLAG_COLORS) && !(parts[i].tmp & PPIP_TMPFLAG_PAUSED))
|
|
{
|
|
if (parts[i].life==3)
|
|
{
|
|
int lastneighbor = -1;
|
|
int neighborcount = 0;
|
|
int count = 0;
|
|
// make automatic pipe pattern
|
|
for (rx=-1; rx<2; rx++)
|
|
for (ry=-1; ry<2; ry++)
|
|
if (BOUNDS_CHECK && (rx || ry))
|
|
{
|
|
count++;
|
|
r = pmap[y+ry][x+rx];
|
|
if (!r)
|
|
continue;
|
|
if (TYP(r) != PT_PIPE && TYP(r) != PT_PPIP)
|
|
continue;
|
|
unsigned int next = nextColor(parts[i].tmp);
|
|
unsigned int prev = prevColor(parts[i].tmp);
|
|
if (parts[ID(r)].tmp&PFLAG_INITIALIZING)
|
|
{
|
|
parts[ID(r)].tmp |= next;
|
|
parts[ID(r)].tmp &= ~PFLAG_INITIALIZING;
|
|
parts[ID(r)].life = 6;
|
|
// Is a single pixel pipe
|
|
if (parts[i].tmp&0x100)
|
|
{
|
|
// Will transfer to a single pixel pipe
|
|
parts[ID(r)].tmp |= 0x200;
|
|
// Coords of where it came from
|
|
parts[ID(r)].tmp |= (count - 1) << 10;
|
|
parts[i].tmp |= (8 - count) << 14;
|
|
parts[i].tmp |= 0x2000;
|
|
}
|
|
neighborcount ++;
|
|
lastneighbor = ID(r);
|
|
}
|
|
else if ((parts[ID(r)].tmp&PFLAG_COLORS) != prev)
|
|
{
|
|
neighborcount ++;
|
|
lastneighbor = ID(r);
|
|
}
|
|
}
|
|
if (neighborcount == 1)
|
|
parts[lastneighbor].tmp |= 0x100;
|
|
}
|
|
else
|
|
{
|
|
if (parts[i].flags&PFLAG_NORMALSPEED)//skip particle push to prevent particle number being higher causing speed up
|
|
{
|
|
parts[i].flags &= ~PFLAG_NORMALSPEED;
|
|
}
|
|
else
|
|
{
|
|
pushParticle(sim, i,0,i);
|
|
}
|
|
|
|
if (nt)//there is something besides PIPE around current particle
|
|
{
|
|
rndstore = RNG::Ref().gen();
|
|
rnd = rndstore&7;
|
|
//rndstore = rndstore>>3;
|
|
rx = pos_1_rx[rnd];
|
|
ry = pos_1_ry[rnd];
|
|
if (BOUNDS_CHECK)
|
|
{
|
|
r = pmap[y+ry][x+rx];
|
|
if(!r)
|
|
r = sim->photons[y+ry][x+rx];
|
|
if (surround_space && !r && TYP(parts[i].ctype)) //creating at end
|
|
{
|
|
np = sim->create_part(-1, x+rx, y+ry, TYP(parts[i].ctype));
|
|
if (np!=-1)
|
|
{
|
|
Element_PIPE_transfer_pipe_to_part(sim, parts+i, parts+np, false);
|
|
}
|
|
}
|
|
//try eating particle at entrance
|
|
else if (!TYP(parts[i].ctype) && (sim->elements[TYP(r)].Properties & (TYPE_PART | TYPE_LIQUID | TYPE_GAS | TYPE_ENERGY)))
|
|
{
|
|
if (TYP(r)==PT_SOAP)
|
|
Element_SOAP_detach(sim, ID(r));
|
|
transfer_part_to_pipe(parts+(ID(r)), parts+i);
|
|
sim->kill_part(ID(r));
|
|
}
|
|
else if (!TYP(parts[i].ctype) && TYP(r)==PT_STOR && sim->IsElement(parts[ID(r)].tmp) && (sim->elements[parts[ID(r)].tmp].Properties & (TYPE_PART | TYPE_LIQUID | TYPE_GAS | TYPE_ENERGY)))
|
|
{
|
|
// STOR stores properties in the same places as PIPE does
|
|
transfer_pipe_to_pipe(parts+(ID(r)), parts+i, true);
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
else if (!(parts[i].tmp&(PFLAG_COLORS|PFLAG_INITIALIZING)) && parts[i].life<=10)
|
|
{
|
|
// make a border
|
|
for (rx=-2; rx<3; rx++)
|
|
for (ry=-2; ry<3; ry++)
|
|
{
|
|
if (BOUNDS_CHECK && (rx || ry))
|
|
{
|
|
r = pmap[y+ry][x+rx];
|
|
if (!r)
|
|
{
|
|
// BRCK border
|
|
int index = sim->create_part(-1,x+rx,y+ry,PT_BRCK);
|
|
if (parts[i].type == PT_PPIP && index != -1)
|
|
parts[index].tmp = 1;
|
|
}
|
|
}
|
|
}
|
|
if (parts[i].life <= 1)
|
|
parts[i].tmp |= PFLAG_INITIALIZING;
|
|
}
|
|
// Wait for empty space before starting to generate automatic pipe pattern
|
|
else if (parts[i].tmp & PFLAG_INITIALIZING)
|
|
{
|
|
if (!parts[i].life)
|
|
{
|
|
for (rx=-1; rx<2; rx++)
|
|
for (ry=-1; ry<2; ry++)
|
|
if (BOUNDS_CHECK && (rx || ry))
|
|
{
|
|
if (!pmap[y+ry][x+rx] && sim->bmap[(y+ry)/CELL][(x+rx)/CELL]!=WL_ALLOWAIR && sim->bmap[(y+ry)/CELL][(x+rx)/CELL]!=WL_WALL && sim->bmap[(y+ry)/CELL][(x+rx)/CELL]!=WL_WALLELEC && (sim->bmap[(y+ry)/CELL][(x+rx)/CELL]!=WL_EWALL || sim->emap[(y+ry)/CELL][(x+rx)/CELL]))
|
|
parts[i].life=50;
|
|
}
|
|
}
|
|
else if (parts[i].life==5)//check for beginning of pipe single pixel
|
|
{
|
|
int issingle = 1;
|
|
for (rx=-1; rx<2; rx++)
|
|
for (ry=-1; ry<2; ry++)
|
|
if (BOUNDS_CHECK && (rx || ry))
|
|
{
|
|
r = pmap[y+ry][x+rx];
|
|
if ((TYP(r)==PT_PIPE || TYP(r) == PT_PPIP) && parts[i].life)
|
|
issingle = 0;
|
|
}
|
|
if (issingle)
|
|
parts[i].tmp |= 0x100;
|
|
}
|
|
else if (parts[i].life == 2)
|
|
{
|
|
parts[i].tmp |= PFLAG_COLOR_RED;
|
|
parts[i].tmp &= ~PFLAG_INITIALIZING;
|
|
parts[i].life = 6;
|
|
}
|
|
}
|
|
return 0;
|
|
}
|
|
|
|
int Element_PIPE_graphics(GRAPHICS_FUNC_ARGS)
|
|
{
|
|
int t = TYP(cpart->ctype);
|
|
if (t>0 && t<PT_NUM && ren->sim->elements[t].Enabled)
|
|
{
|
|
if (t == PT_STKM || t == PT_STKM2 || t == PT_FIGH)
|
|
return 0;
|
|
if (ren->graphicscache[t].isready)
|
|
{
|
|
*pixel_mode = ren->graphicscache[t].pixel_mode;
|
|
*cola = ren->graphicscache[t].cola;
|
|
*colr = ren->graphicscache[t].colr;
|
|
*colg = ren->graphicscache[t].colg;
|
|
*colb = ren->graphicscache[t].colb;
|
|
*firea = ren->graphicscache[t].firea;
|
|
*firer = ren->graphicscache[t].firer;
|
|
*fireg = ren->graphicscache[t].fireg;
|
|
*fireb = ren->graphicscache[t].fireb;
|
|
}
|
|
else
|
|
{
|
|
// Temp particle used for graphics.
|
|
Particle tpart = *cpart;
|
|
|
|
// Emulate the graphics of stored particle.
|
|
memset(cpart, 0, sizeof(Particle));
|
|
cpart->type = t;
|
|
cpart->temp = tpart.temp;
|
|
cpart->life = tpart.tmp2;
|
|
cpart->tmp = tpart.tmp3;
|
|
cpart->ctype = tpart.tmp4;
|
|
|
|
*colr = PIXR(ren->sim->elements[t].Colour);
|
|
*colg = PIXG(ren->sim->elements[t].Colour);
|
|
*colb = PIXB(ren->sim->elements[t].Colour);
|
|
if (ren->sim->elements[t].Graphics)
|
|
{
|
|
(*(ren->sim->elements[t].Graphics))(ren, cpart, nx, ny, pixel_mode, cola, colr, colg, colb, firea, firer, fireg, fireb);
|
|
}
|
|
else
|
|
{
|
|
Element::defaultGraphics(ren, cpart, nx, ny, pixel_mode, cola, colr, colg, colb, firea, firer, fireg, fireb);
|
|
}
|
|
|
|
// Restore original particle data.
|
|
*cpart = tpart;
|
|
}
|
|
//*colr = PIXR(elements[t].pcolors);
|
|
//*colg = PIXG(elements[t].pcolors);
|
|
//*colb = PIXB(elements[t].pcolors);
|
|
}
|
|
else
|
|
{
|
|
switch (cpart->tmp & PFLAG_COLORS)
|
|
{
|
|
case PFLAG_COLOR_RED:
|
|
*colr = 50;
|
|
*colg = 1;
|
|
*colb = 1;
|
|
break;
|
|
case PFLAG_COLOR_GREEN:
|
|
*colr = 1;
|
|
*colg = 50;
|
|
*colb = 1;
|
|
break;
|
|
case PFLAG_COLOR_BLUE:
|
|
*colr = 1;
|
|
*colg = 1;
|
|
*colb = 50;
|
|
break;
|
|
default:
|
|
break;
|
|
}
|
|
}
|
|
return 0;
|
|
}
|
|
|
|
void Element_PIPE_transfer_pipe_to_part(Simulation * sim, Particle *pipe, Particle *part, bool STOR)
|
|
{
|
|
// STOR also calls this function to move particles from STOR to PRTI
|
|
// PIPE was changed, so now PIPE and STOR don't use the same particle storage format
|
|
if (STOR)
|
|
{
|
|
part->type = TYP(pipe->tmp);
|
|
pipe->tmp = 0;
|
|
}
|
|
else
|
|
{
|
|
part->type = TYP(pipe->ctype);
|
|
pipe->ctype = 0;
|
|
}
|
|
part->temp = pipe->temp;
|
|
part->life = pipe->tmp2;
|
|
part->tmp = pipe->tmp3;
|
|
part->ctype = pipe->tmp4;
|
|
|
|
if (!(sim->elements[part->type].Properties & TYPE_ENERGY))
|
|
{
|
|
part->vx = 0.0f;
|
|
part->vy = 0.0f;
|
|
}
|
|
part->tmp2 = 0;
|
|
part->flags = 0;
|
|
part->dcolour = 0;
|
|
}
|
|
|
|
static void transfer_part_to_pipe(Particle *part, Particle *pipe)
|
|
{
|
|
pipe->ctype = part->type;
|
|
pipe->temp = part->temp;
|
|
pipe->tmp2 = part->life;
|
|
pipe->tmp3 = part->tmp;
|
|
pipe->tmp4 = part->ctype;
|
|
}
|
|
|
|
static void transfer_pipe_to_pipe(Particle *src, Particle *dest, bool STOR)
|
|
{
|
|
// STOR to PIPE
|
|
if (STOR)
|
|
{
|
|
dest->ctype = src->tmp;
|
|
src->tmp = 0;
|
|
}
|
|
else
|
|
{
|
|
dest->ctype = src->ctype;
|
|
src->ctype = 0;
|
|
}
|
|
dest->temp = src->temp;
|
|
dest->tmp2 = src->tmp2;
|
|
dest->tmp3 = src->tmp3;
|
|
dest->tmp4 = src->tmp4;
|
|
}
|
|
|
|
static void pushParticle(Simulation * sim, int i, int count, int original)
|
|
{
|
|
int rndstore, rnd, rx, ry, r, x, y, np, q;
|
|
unsigned int notctype = nextColor(sim->parts[i].tmp);
|
|
if (!TYP(sim->parts[i].ctype) || count >= 2)//don't push if there is nothing there, max speed of 2 per frame
|
|
return;
|
|
x = (int)(sim->parts[i].x+0.5f);
|
|
y = (int)(sim->parts[i].y+0.5f);
|
|
if( !(sim->parts[i].tmp&0x200) )
|
|
{
|
|
//normal random push
|
|
rndstore = RNG::Ref().gen();
|
|
// RAND_MAX is at least 32767 on all platforms i.e. pow(8,5)-1
|
|
// so can go 5 cycles without regenerating rndstore
|
|
// (although now we use our own randomizer so maybe should reevaluate all the rndstore usages in every element)
|
|
for (q=0; q<3; q++)//try to push 3 times
|
|
{
|
|
rnd = rndstore&7;
|
|
rndstore = rndstore>>3;
|
|
rx = pos_1_rx[rnd];
|
|
ry = pos_1_ry[rnd];
|
|
if (BOUNDS_CHECK)
|
|
{
|
|
r = sim->pmap[y+ry][x+rx];
|
|
if (!r)
|
|
continue;
|
|
else if ((TYP(r)==PT_PIPE || TYP(r) == PT_PPIP) && (sim->parts[ID(r)].tmp&PFLAG_COLORS) != notctype && !TYP(sim->parts[ID(r)].ctype))
|
|
{
|
|
transfer_pipe_to_pipe(sim->parts+i, sim->parts+(ID(r)), false);
|
|
if (ID(r) > original)
|
|
sim->parts[ID(r)].flags |= PFLAG_NORMALSPEED;//skip particle push, normalizes speed
|
|
count++;
|
|
pushParticle(sim, ID(r),count,original);
|
|
}
|
|
else if (TYP(r) == PT_PRTI) //Pass particles into PRTI for a pipe speed increase
|
|
{
|
|
int portaltmp = sim->parts[ID(r)].tmp;
|
|
if (portaltmp >= CHANNELS)
|
|
portaltmp = CHANNELS-1;
|
|
else if (portaltmp < 0)
|
|
portaltmp = 0;
|
|
for (int nnx = 0; nnx < 80; nnx++)
|
|
if (!sim->portalp[portaltmp][count][nnx].type)
|
|
{
|
|
Element_PIPE_transfer_pipe_to_part(sim, sim->parts+i, &(sim->portalp[portaltmp][count][nnx]), false);
|
|
count++;
|
|
break;
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
else //predefined 1 pixel thick pipe movement
|
|
{
|
|
int coords = 7 - ((sim->parts[i].tmp>>10)&7);
|
|
r = sim->pmap[y+ pos_1_ry[coords]][x+ pos_1_rx[coords]];
|
|
if ((TYP(r)==PT_PIPE || TYP(r) == PT_PPIP) && (sim->parts[ID(r)].tmp&PFLAG_COLORS) != notctype && !TYP(sim->parts[ID(r)].ctype))
|
|
{
|
|
transfer_pipe_to_pipe(sim->parts+i, sim->parts+(ID(r)), false);
|
|
if (ID(r) > original)
|
|
sim->parts[ID(r)].flags |= PFLAG_NORMALSPEED;//skip particle push, normalizes speed
|
|
count++;
|
|
pushParticle(sim, ID(r),count,original);
|
|
}
|
|
else if (TYP(r) == PT_PRTI) //Pass particles into PRTI for a pipe speed increase
|
|
{
|
|
int portaltmp = sim->parts[ID(r)].tmp;
|
|
if (portaltmp >= CHANNELS)
|
|
portaltmp = CHANNELS-1;
|
|
else if (portaltmp < 0)
|
|
portaltmp = 0;
|
|
for (int nnx = 0; nnx < 80; nnx++)
|
|
if (!sim->portalp[portaltmp][count][nnx].type)
|
|
{
|
|
Element_PIPE_transfer_pipe_to_part(sim, sim->parts+i, &(sim->portalp[portaltmp][count][nnx]), false);
|
|
count++;
|
|
break;
|
|
}
|
|
}
|
|
else if (!r) //Move particles out of pipe automatically, much faster at ends
|
|
{
|
|
rx = pos_1_rx[coords];
|
|
ry = pos_1_ry[coords];
|
|
np = sim->create_part(-1,x+rx,y+ry,TYP(sim->parts[i].ctype));
|
|
if (np!=-1)
|
|
{
|
|
Element_PIPE_transfer_pipe_to_part(sim, sim->parts+i, sim->parts+np, false);
|
|
}
|
|
}
|
|
|
|
}
|
|
return;
|
|
}
|