summaryrefslogtreecommitdiff
path: root/src/simulation/elements/PPIP.cpp
diff options
context:
space:
mode:
authorSimon Robertshaw <simon@hardwired.org.uk>2012-08-20 15:48:03 (GMT)
committer Simon Robertshaw <simon@hardwired.org.uk>2012-08-20 15:48:03 (GMT)
commitb318c3721a43de9789efc6c286b41566649f5252 (patch)
tree861c1f51b18e7ba7525b2a4903d9c7998af4a00a /src/simulation/elements/PPIP.cpp
parent13888623a5a7f6fa9f532570c1b733f0fcdf2a64 (diff)
downloadpowder-b318c3721a43de9789efc6c286b41566649f5252.zip
powder-b318c3721a43de9789efc6c286b41566649f5252.tar.gz
TPT: Powered pipe, based on jacob1's commits
Diffstat (limited to 'src/simulation/elements/PPIP.cpp')
-rw-r--r--src/simulation/elements/PPIP.cpp160
1 files changed, 160 insertions, 0 deletions
diff --git a/src/simulation/elements/PPIP.cpp b/src/simulation/elements/PPIP.cpp
new file mode 100644
index 0000000..03d0b82
--- /dev/null
+++ b/src/simulation/elements/PPIP.cpp
@@ -0,0 +1,160 @@
+#include "simulation/Elements.h"
+//#TPT-Directive ElementClass Element_PPIP PT_PPIP 161
+Element_PPIP::Element_PPIP()
+{
+ Identifier = "DEFAULT_PT_PPIP";
+ Name = "PPIP";
+ Colour = PIXPACK(0x444466);
+ MenuVisible = 1;
+ MenuSection = SC_SOLIDS;
+ 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;
+
+ Temperature = 273.15f;
+ HeatConduct = 0;
+ Description = "Powered version of PIPE, use PSCN/NSCN to Activate/Deactivate.";
+
+ State = ST_SOLID;
+ Properties = TYPE_SOLID|PROP_LIFE_DEC;
+
+ LowPressure = IPL;
+ LowPressureTransition = NT;
+ HighPressure = 10.0f;
+ HighPressureTransition = PT_BRMT;
+ LowTemperature = ITL;
+ LowTemperatureTransition = NT;
+ HighTemperature = ITH;
+ HighTemperatureTransition = NT;
+
+ Update = &Element_PIPE::update;
+ Graphics = &Element_PIPE::graphics;
+}
+
+#define PFLAG_NORMALSPEED 0x00010000
+// parts[].tmp flags
+// trigger flags to be processed this frame (trigger flags for next frame are shifted 3 bits to the left):
+#define PPIP_TMPFLAG_TRIGGER_ON 0x10000000
+#define PPIP_TMPFLAG_TRIGGER_OFF 0x08000000
+#define PPIP_TMPFLAG_TRIGGER_REVERSE 0x04000000
+#define PPIP_TMPFLAG_TRIGGERS 0x1C000000
+// current status of the pipe
+#define PPIP_TMPFLAG_PAUSED 0x02000000
+#define PPIP_TMPFLAG_REVERSED 0x01000000
+// 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
+
+//#TPT-Directive ElementHeader Element_PPIP static int ppip_changed
+int Element_PPIP::ppip_changed = 0;
+
+//#TPT-Directive ElementHeader Element_PPIP static void flood_trigger(Simulation * sim, int x, int y, int sparkedBy)
+void Element_PPIP::flood_trigger(Simulation * sim, int x, int y, int sparkedBy)
+{
+ int coord_stack_limit = XRES*YRES;
+ unsigned short (*coord_stack)[2];
+ int coord_stack_size = 0;
+ int x1, x2;
+
+ Particle * parts = sim->parts;
+ int (*pmap)[XRES] = sim->pmap;
+
+ // Separate flags for on and off in case PPIP is sparked by PSCN and NSCN on the same frame
+ // - then PSCN can override NSCN and behaviour is not dependent on particle order
+ int prop = 0;
+ if (sparkedBy==PT_PSCN) prop = PPIP_TMPFLAG_TRIGGER_ON << 3;
+ else if (sparkedBy==PT_NSCN) prop = PPIP_TMPFLAG_TRIGGER_OFF << 3;
+ else if (sparkedBy==PT_INST) prop = PPIP_TMPFLAG_TRIGGER_REVERSE << 3;
+
+ if (prop==0 || (pmap[y][x]&0xFF)!=PT_PPIP || (parts[pmap[y][x]>>8].tmp & prop))
+ return;
+
+ coord_stack = new unsigned short[coord_stack_limit][2];
+ coord_stack[coord_stack_size][0] = x;
+ coord_stack[coord_stack_size][1] = y;
+ coord_stack_size++;
+
+ do
+ {
+ coord_stack_size--;
+ x = coord_stack[coord_stack_size][0];
+ y = coord_stack[coord_stack_size][1];
+ x1 = x2 = x;
+ // go left as far as possible
+ while (x1>=CELL)
+ {
+ if ((pmap[y][x1-1]&0xFF)!=PT_PPIP)
+ {
+ break;
+ }
+ x1--;
+ }
+ // go right as far as possible
+ while (x2<XRES-CELL)
+ {
+ if ((pmap[y][x2+1]&0xFF)!=PT_PPIP)
+ {
+ break;
+ }
+ x2++;
+ }
+ // fill span
+ for (x=x1; x<=x2; x++)
+ {
+ if (!(parts[pmap[y][x]>>8].tmp & prop))
+ ppip_changed = 1;
+ parts[pmap[y][x]>>8].tmp |= prop;
+ }
+
+ // add adjacent pixels to stack
+ // +-1 to x limits to include diagonally adjacent pixels
+ // Don't need to check x bounds here, because already limited to [CELL, XRES-CELL]
+ if (y>=CELL+1)
+ for (x=x1-1; x<=x2+1; x++)
+ if ((pmap[y-1][x]&0xFF)==PT_PPIP && !(parts[pmap[y-1][x]>>8].tmp & prop))
+ {
+ coord_stack[coord_stack_size][0] = x;
+ coord_stack[coord_stack_size][1] = y-1;
+ coord_stack_size++;
+ if (coord_stack_size>=coord_stack_limit)
+ {
+ delete[] coord_stack;
+ return;
+ }
+ }
+ if (y<YRES-CELL-1)
+ for (x=x1-1; x<=x2+1; x++)
+ if ((pmap[y+1][x]&0xFF)==PT_PPIP && !(parts[pmap[y+1][x]>>8].tmp & prop))
+ {
+ coord_stack[coord_stack_size][0] = x;
+ coord_stack[coord_stack_size][1] = y+1;
+ coord_stack_size++;
+ if (coord_stack_size>=coord_stack_limit)
+ {
+ delete[] coord_stack;
+ return;
+ }
+ }
+ } while (coord_stack_size>0);
+ delete[] coord_stack;
+}
+
+Element_PPIP::~Element_PPIP() {}