1 #include "simulation/ElementCommon.h"
2 
3 static int update(UPDATE_FUNC_ARGS);
4 
Element_MERC()5 void Element::Element_MERC()
6 {
7 	Identifier = "DEFAULT_PT_MERC";
8 	Name = "MERC";
9 	Colour = PIXPACK(0x736B6D);
10 	MenuVisible = 1;
11 	MenuSection = SC_LIQUID;
12 	Enabled = 1;
13 
14 	Advection = 0.4f;
15 	AirDrag = 0.04f * CFDS;
16 	AirLoss = 0.94f;
17 	Loss = 0.80f;
18 	Collision = 0.0f;
19 	Gravity = 0.3f;
20 	Diffusion = 0.00f;
21 	HotAir = 0.000f	* CFDS;
22 	Falldown = 2;
23 
24 	Flammable = 0;
25 	Explosive = 0;
26 	Meltable = 0;
27 	Hardness = 20;
28 
29 	Weight = 91;
30 
31 	HeatConduct = 251;
32 	Description = "Mercury. Volume changes with temperature, Conductive.";
33 
34 	Properties = TYPE_LIQUID|PROP_CONDUCTS|PROP_NEUTABSORB|PROP_LIFE_DEC;
35 
36 	LowPressure = IPL;
37 	LowPressureTransition = NT;
38 	HighPressure = IPH;
39 	HighPressureTransition = NT;
40 	LowTemperature = ITL;
41 	LowTemperatureTransition = NT;
42 	HighTemperature = ITH;
43 	HighTemperatureTransition = NT;
44 
45 	DefaultProperties.tmp = 10;
46 
47 	Update = &update;
48 }
49 
update(UPDATE_FUNC_ARGS)50 static int update(UPDATE_FUNC_ARGS)
51 {
52 	int r, rx, ry, trade, np;
53 	// Max number of particles that can be condensed into one
54 	const int absorbScale = 10000;
55 	// Obscure division by 0 fix
56 	if (parts[i].temp + 1 == 0)
57 		parts[i].temp = 0;
58 	int maxtmp = (absorbScale/(parts[i].temp + 1))-1;
59 	if (RNG::Ref().chance(absorbScale%((int)parts[i].temp+1), parts[i].temp+1))
60 		maxtmp ++;
61 
62 	if (parts[i].tmp < 0)
63 	{
64 		parts[i].tmp = 0;
65 	}
66 	if (parts[i].tmp > absorbScale)
67 	{
68 		parts[i].tmp = absorbScale;
69 	}
70 
71 	if (parts[i].tmp < maxtmp)
72 	{
73 		for (rx=-1; rx<2; rx++)
74 			for (ry=-1; ry<2; ry++)
75 				if (BOUNDS_CHECK && (rx || ry))
76 				{
77 					r = pmap[y+ry][x+rx];
78 					if (!r || (parts[i].tmp >=maxtmp))
79 						continue;
80 					if (TYP(r)==PT_MERC&& RNG::Ref().chance(1, 3))
81 					{
82 						if ((parts[i].tmp + parts[ID(r)].tmp + 1) <= maxtmp)
83 						{
84 							parts[i].tmp += parts[ID(r)].tmp + 1;
85 							sim->kill_part(ID(r));
86 						}
87 					}
88 				}
89 	}
90 	else
91 		for (rx=-1; rx<2; rx++)
92 			for (ry=-1; ry<2; ry++)
93 				if (BOUNDS_CHECK && (rx || ry))
94 				{
95 					r = pmap[y+ry][x+rx];
96 					if (parts[i].tmp<=maxtmp)
97 						continue;
98 					if ((!r)&&parts[i].tmp>=1)//if nothing then create MERC
99 					{
100 						np = sim->create_part(-1,x+rx,y+ry,PT_MERC);
101 						if (np<0) continue;
102 						parts[i].tmp--;
103 						parts[np].temp = parts[i].temp;
104 						parts[np].tmp = 0;
105 						parts[np].dcolour = parts[i].dcolour;
106 					}
107 				}
108 	for ( trade = 0; trade<4; trade ++)
109 	{
110 		rx = RNG::Ref().between(-2, 2);
111 		ry = RNG::Ref().between(-2, 2);
112 		if (BOUNDS_CHECK && (rx || ry))
113 		{
114 			r = pmap[y+ry][x+rx];
115 			if (!r)
116 				continue;
117 			if (TYP(r)==PT_MERC&&(parts[i].tmp>parts[ID(r)].tmp)&&parts[i].tmp>0)//diffusion
118 			{
119 				int temp = parts[i].tmp - parts[ID(r)].tmp;
120 				if (temp ==1)
121 				{
122 					parts[ID(r)].tmp ++;
123 					parts[i].tmp --;
124 				}
125 				else if (temp>0)
126 				{
127 					parts[ID(r)].tmp += temp/2;
128 					parts[i].tmp -= temp/2;
129 				}
130 			}
131 		}
132 	}
133 	return 0;
134 }
135