1 #include "simulation/ElementCommon.h"
2
3 int Element_PIPE_update(UPDATE_FUNC_ARGS);
4 int Element_PIPE_graphics(GRAPHICS_FUNC_ARGS);
5
Element_PPIP()6 void Element::Element_PPIP()
7 {
8 Identifier = "DEFAULT_PT_PPIP";
9 Name = "PPIP";
10 Colour = PIXPACK(0x444466);
11 MenuVisible = 1;
12 MenuSection = SC_POWERED;
13 Enabled = 1;
14
15 Advection = 0.0f;
16 AirDrag = 0.00f * CFDS;
17 AirLoss = 0.95f;
18 Loss = 0.00f;
19 Collision = 0.0f;
20 Gravity = 0.0f;
21 Diffusion = 0.00f;
22 HotAir = 0.000f * CFDS;
23 Falldown = 0;
24
25 Flammable = 0;
26 Explosive = 0;
27 Meltable = 0;
28 Hardness = 0;
29
30 Weight = 100;
31
32 DefaultProperties.temp = 273.15f;
33 HeatConduct = 0;
34 Description = "Powered version of PIPE, use PSCN/NSCN to Activate/Deactivate.";
35
36 Properties = TYPE_SOLID|PROP_LIFE_DEC;
37
38 LowPressure = IPL;
39 LowPressureTransition = NT;
40 HighPressure = IPH;
41 HighPressureTransition = NT;
42 LowTemperature = ITL;
43 LowTemperatureTransition = NT;
44 HighTemperature = ITH;
45 HighTemperatureTransition = NT;
46
47 DefaultProperties.life = 60;
48
49 Update = &Element_PIPE_update;
50 Graphics = &Element_PIPE_graphics;
51 }
52
53 // parts[].tmp flags
54 // trigger flags to be processed this frame (trigger flags for next frame are shifted 3 bits to the left):
55 constexpr int PPIP_TMPFLAG_TRIGGER_ON = 0x10000000;
56 constexpr int PPIP_TMPFLAG_TRIGGER_OFF = 0x08000000;
57 constexpr int PPIP_TMPFLAG_TRIGGER_REVERSE = 0x04000000;
58 // 0x000000FF element
59 // 0x00000100 is single pixel pipe
60 // 0x00000200 will transfer like a single pixel pipe when in forward mode
61 // 0x00001C00 forward single pixel pipe direction
62 // 0x00002000 will transfer like a single pixel pipe when in reverse mode
63 // 0x0001C000 reverse single pixel pipe direction
64
65 int Element_PPIP_ppip_changed = 0;
66
Element_PPIP_flood_trigger(Simulation * sim,int x,int y,int sparkedBy)67 void Element_PPIP_flood_trigger(Simulation * sim, int x, int y, int sparkedBy)
68 {
69 int coord_stack_limit = XRES*YRES;
70 unsigned short (*coord_stack)[2];
71 int coord_stack_size = 0;
72 int x1, x2;
73
74 Particle * parts = sim->parts;
75 int (*pmap)[XRES] = sim->pmap;
76
77 // Separate flags for on and off in case PPIP is sparked by PSCN and NSCN on the same frame
78 // - then PSCN can override NSCN and behaviour is not dependent on particle order
79 int prop = 0;
80 if (sparkedBy==PT_PSCN) prop = PPIP_TMPFLAG_TRIGGER_ON << 3;
81 else if (sparkedBy==PT_NSCN) prop = PPIP_TMPFLAG_TRIGGER_OFF << 3;
82 else if (sparkedBy==PT_INST) prop = PPIP_TMPFLAG_TRIGGER_REVERSE << 3;
83
84 if (prop==0 || TYP(pmap[y][x])!=PT_PPIP || (parts[ID(pmap[y][x])].tmp & prop))
85 return;
86
87 coord_stack = new unsigned short[coord_stack_limit][2];
88 coord_stack[coord_stack_size][0] = x;
89 coord_stack[coord_stack_size][1] = y;
90 coord_stack_size++;
91
92 do
93 {
94 coord_stack_size--;
95 x = coord_stack[coord_stack_size][0];
96 y = coord_stack[coord_stack_size][1];
97 x1 = x2 = x;
98 // go left as far as possible
99 while (x1>=CELL)
100 {
101 if (TYP(pmap[y][x1-1]) != PT_PPIP)
102 {
103 break;
104 }
105 x1--;
106 }
107 // go right as far as possible
108 while (x2<XRES-CELL)
109 {
110 if (TYP(pmap[y][x2+1]) != PT_PPIP)
111 {
112 break;
113 }
114 x2++;
115 }
116 // fill span
117 for (x=x1; x<=x2; x++)
118 {
119 if (!(parts[ID(pmap[y][x])].tmp & prop))
120 Element_PPIP_ppip_changed = 1;
121 parts[ID(pmap[y][x])].tmp |= prop;
122 }
123
124 // add adjacent pixels to stack
125 // +-1 to x limits to include diagonally adjacent pixels
126 // Don't need to check x bounds here, because already limited to [CELL, XRES-CELL]
127 if (y>=CELL+1)
128 for (x=x1-1; x<=x2+1; x++)
129 if (TYP(pmap[y-1][x]) == PT_PPIP && !(parts[ID(pmap[y-1][x])].tmp & prop))
130 {
131 coord_stack[coord_stack_size][0] = x;
132 coord_stack[coord_stack_size][1] = y-1;
133 coord_stack_size++;
134 if (coord_stack_size>=coord_stack_limit)
135 {
136 delete[] coord_stack;
137 return;
138 }
139 }
140 if (y<YRES-CELL-1)
141 for (x=x1-1; x<=x2+1; x++)
142 if (TYP(pmap[y+1][x]) == PT_PPIP && !(parts[ID(pmap[y+1][x])].tmp & prop))
143 {
144 coord_stack[coord_stack_size][0] = x;
145 coord_stack[coord_stack_size][1] = y+1;
146 coord_stack_size++;
147 if (coord_stack_size>=coord_stack_limit)
148 {
149 delete[] coord_stack;
150 return;
151 }
152 }
153 } while (coord_stack_size>0);
154 delete[] coord_stack;
155 }
156