1 #include "simulation/ElementCommon.h"
2 #include "simulation/Air.h"
3 
4 static int update(UPDATE_FUNC_ARGS);
5 
Element_HEAC()6 void Element::Element_HEAC()
7 {
8 	Identifier = "DEFAULT_PT_HEAC";
9 	Name = "HEAC";
10 	Colour = PIXPACK(0xCB6351);
11 	MenuVisible = 1;
12 	MenuSection = SC_SOLIDS;
13 	Enabled = 1;
14 
15 	Advection = 0.0f;
16 	AirDrag = 0.00f * CFDS;
17 	AirLoss = 0.90f;
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 = 1;
28 	Hardness = 0;
29 
30 	Weight = 100;
31 
32 	HeatConduct = 251;
33 	Description = "Rapid heat conductor.";
34 
35 	Properties = TYPE_SOLID;
36 
37 	LowPressure = IPL;
38 	LowPressureTransition = NT;
39 	HighPressure = IPH;
40 	HighPressureTransition = NT;
41 	LowTemperature = ITL;
42 	LowTemperatureTransition = NT;
43 	// can't melt by normal heat conduction, this is used by other elements for special melting behavior
44 	HighTemperature = 1887.15f;
45 	HighTemperatureTransition = NT;
46 
47 	Update = &update;
48 }
49 
__anon821d51380102(Simulation* a, int b) 50 static const auto isInsulator = [](Simulation* a, int b) -> bool {
51 	return b && (a->elements[TYP(b)].HeatConduct == 0 || (TYP(b) == PT_HSWC && a->parts[ID(b)].life != 10));
52 };
53 
54 // If this is used elsewhere (GOLD), it should be moved into Simulation.h
55 template<class BinaryPredicate>
CheckLine(Simulation * sim,int x1,int y1,int x2,int y2,BinaryPredicate func)56 bool CheckLine(Simulation* sim, int x1, int y1, int x2, int y2, BinaryPredicate func)
57 {
58 	bool reverseXY = abs(y2-y1) > abs(x2-x1);
59 	int x, y, dx, dy, sy;
60 	float e, de;
61 	if (reverseXY)
62 	{
63 		y = x1;
64 		x1 = y1;
65 		y1 = y;
66 		y = x2;
67 		x2 = y2;
68 		y2 = y;
69 	}
70 	if (x1 > x2)
71 	{
72 		y = x1;
73 		x1 = x2;
74 		x2 = y;
75 		y = y1;
76 		y1 = y2;
77 		y2 = y;
78 	}
79 	dx = x2 - x1;
80 	dy = abs(y2 - y1);
81 	e = 0.0f;
82 	if (dx)
83 		de = dy/(float)dx;
84 	else
85 		de = 0.0f;
86 	y = y1;
87 	sy = (y1<y2) ? 1 : -1;
88 	for (x=x1; x<=x2; x++)
89 	{
90 		if (reverseXY)
91 		{
92 			if (func(sim, sim->pmap[x][y])) return true;
93 		}
94 		else
95 		{
96 			if (func(sim, sim->pmap[y][x])) return true;
97 		}
98 		e += de;
99 		if (e >= 0.5f)
100 		{
101 			y += sy;
102 			if ((y1<y2) ? (y<=y2) : (y>=y2))
103 			{
104 				if (reverseXY)
105 				{
106 					if (func(sim, sim->pmap[x][y])) return true;
107 				}
108 				else
109 				{
110 					if (func(sim, sim->pmap[y][x])) return true;
111 				}
112 			}
113 			e -= 1.0f;
114 		}
115 	}
116 	return false;
117 }
118 
update(UPDATE_FUNC_ARGS)119 static int update(UPDATE_FUNC_ARGS)
120 {
121 	const int rad = 4;
122 	int rry, rrx, r, count = 0;
123 	float tempAgg = 0;
124 	for (int rx = -1; rx <= 1; rx++)
125 	{
126 		for (int ry = -1; ry <= 1; ry++)
127 		{
128 			rry = ry * rad;
129 			rrx = rx * rad;
130 			if (x+rrx >= 0 && x+rrx < XRES && y+rry >= 0 && y+rry < YRES && !CheckLine(sim, x, y, x+rrx, y+rry, isInsulator))
131 			{
132 				r = pmap[y+rry][x+rrx];
133 				if (r && sim->elements[TYP(r)].HeatConduct > 0 && (TYP(r) != PT_HSWC || parts[ID(r)].life == 10))
134 				{
135 					count++;
136 					tempAgg += parts[ID(r)].temp;
137 				}
138 				r = sim->photons[y+rry][x+rrx];
139 				if (r && sim->elements[TYP(r)].HeatConduct > 0 && (TYP(r) != PT_HSWC || parts[ID(r)].life == 10))
140 				{
141 					count++;
142 					tempAgg += parts[ID(r)].temp;
143 				}
144 			}
145 		}
146 	}
147 
148 	if (count > 0)
149 	{
150 		parts[i].temp = tempAgg/count;
151 
152 		for (int rx = -1; rx <= 1; rx++)
153 		{
154 			for (int ry = -1; ry <= 1; ry++)
155 			{
156 				rry = ry * rad;
157 				rrx = rx * rad;
158 				if (x+rrx >= 0 && x+rrx < XRES && y+rry >= 0 && y+rry < YRES && !CheckLine(sim, x, y, x+rrx, y+rry, isInsulator))
159 				{
160 					r = pmap[y+rry][x+rrx];
161 					if (r && sim->elements[TYP(r)].HeatConduct > 0 && (TYP(r) != PT_HSWC || parts[ID(r)].life == 10))
162 					{
163 						parts[ID(r)].temp = parts[i].temp;
164 					}
165 					r = sim->photons[y+rry][x+rrx];
166 					if (r && sim->elements[TYP(r)].HeatConduct > 0 && (TYP(r) != PT_HSWC || parts[ID(r)].life == 10))
167 					{
168 						parts[ID(r)].temp = parts[i].temp;
169 					}
170 				}
171 			}
172 		}
173 	}
174 
175 	return 0;
176 }
177