1 #include "simulation/ElementCommon.h"
2 #include "common/tpt-minmax.h"
3 
4 static int update(UPDATE_FUNC_ARGS);
5 static int graphics(GRAPHICS_FUNC_ARGS);
6 
Element_DEUT()7 void Element::Element_DEUT()
8 {
9 	Identifier = "DEFAULT_PT_DEUT";
10 	Name = "DEUT";
11 	Colour = PIXPACK(0x00153F);
12 	MenuVisible = 1;
13 	MenuSection = SC_NUCLEAR;
14 	Enabled = 1;
15 
16 	Advection = 0.6f;
17 	AirDrag = 0.01f * CFDS;
18 	AirLoss = 0.98f;
19 	Loss = 0.95f;
20 	Collision = 0.0f;
21 	Gravity = 0.1f;
22 	Diffusion = 0.00f;
23 	HotAir = 0.000f	* CFDS;
24 	Falldown = 2;
25 
26 	Flammable = 0;
27 	Explosive = 0;
28 	Meltable = 0;
29 	Hardness = 20;
30 
31 	Weight = 31;
32 
33 	DefaultProperties.temp = R_TEMP - 2.0f + 273.15f;
34 	HeatConduct = 251;
35 	Description = "Deuterium oxide. Volume changes with temp, radioactive with neutrons.";
36 
37 	Properties = TYPE_LIQUID|PROP_NEUTPASS;
38 
39 	LowPressure = IPL;
40 	LowPressureTransition = NT;
41 	HighPressure = IPH;
42 	HighPressureTransition = NT;
43 	LowTemperature = ITL;
44 	LowTemperatureTransition = NT;
45 	HighTemperature = ITH;
46 	HighTemperatureTransition = NT;
47 
48 	DefaultProperties.life = 10;
49 
50 	Update = &update;
51 	Graphics = &graphics;
52 }
53 
update(UPDATE_FUNC_ARGS)54 static int update(UPDATE_FUNC_ARGS)
55 {
56 	int r, rx, ry, trade, np;
57 	float gravtot = fabs(sim->gravy[(y/CELL)*(XRES/CELL)+(x/CELL)])+fabs(sim->gravx[(y/CELL)*(XRES/CELL)+(x/CELL)]);
58 	// Prevent division by 0
59 	float temp = std::max(1.0f, (parts[i].temp + 1));
60 	int maxlife = ((10000/(temp + 1))-1);
61 	if (RNG::Ref().chance(10000 % static_cast<int>(temp + 1), static_cast<int>(temp + 1)))
62 		maxlife++;
63 	// Compress when Newtonian gravity is applied
64 	// multiplier=1 when gravtot=0, multiplier -> 5 as gravtot -> inf
65 	maxlife = maxlife*(5.0f - 8.0f/(gravtot+2.0f));
66 	if (parts[i].life < maxlife)
67 	{
68 		for (rx=-1; rx<2; rx++)
69 			for (ry=-1; ry<2; ry++)
70 				if (BOUNDS_CHECK && (rx || ry))
71 				{
72 					r = pmap[y+ry][x+rx];
73 					if (!r || (parts[i].life >=maxlife))
74 						continue;
75 					if (TYP(r)==PT_DEUT&& RNG::Ref().chance(1, 3))
76 					{
77 						// If neighbour life+1 fits in the free capacity for this particle, absorb neighbour
78 						// Condition is written in this way so that large neighbour life values don't cause integer overflow
79 						if (parts[ID(r)].life <= maxlife - parts[i].life - 1)
80 						{
81 							parts[i].life += parts[ID(r)].life + 1;
82 							sim->kill_part(ID(r));
83 						}
84 					}
85 				}
86 	}
87 	else
88 		for (rx=-1; rx<2; rx++)
89 			for (ry=-1; ry<2; ry++)
90 				if (BOUNDS_CHECK && (rx || ry))
91 				{
92 					//Leave if there is nothing to do
93 					if (parts[i].life <= maxlife)
94 						goto trade;
95 					r = pmap[y+ry][x+rx];
96 					if ((!r)&&parts[i].life>=1)//if nothing then create deut
97 					{
98 						np = sim->create_part(-1,x+rx,y+ry,PT_DEUT);
99 						if (np<0) continue;
100 						parts[i].life--;
101 						parts[np].temp = parts[i].temp;
102 						parts[np].life = 0;
103 					}
104 				}
105 trade:
106 	for ( trade = 0; trade<4; trade ++)
107 	{
108 		rx = RNG::Ref().between(-2, 2);
109 		ry = RNG::Ref().between(-2, 2);
110 		if (BOUNDS_CHECK && (rx || ry))
111 		{
112 			r = pmap[y+ry][x+rx];
113 			if (!r)
114 				continue;
115 			if (TYP(r)==PT_DEUT&&(parts[i].life>parts[ID(r)].life)&&parts[i].life>0)//diffusion
116 			{
117 				int temp = parts[i].life - parts[ID(r)].life;
118 				if (temp ==1)
119 				{
120 					parts[ID(r)].life ++;
121 					parts[i].life --;
122 				}
123 				else if (temp>0)
124 				{
125 					parts[ID(r)].life += temp/2;
126 					parts[i].life -= temp/2;
127 				}
128 			}
129 		}
130 	}
131 	return 0;
132 }
133 
graphics(GRAPHICS_FUNC_ARGS)134 static int graphics(GRAPHICS_FUNC_ARGS)
135 {
136 	if(cpart->life>=240)
137 	{
138 		*firea = 60;
139 		*firer = *colr += 255;
140 		*fireg = *colg += 255;
141 		*fireb = *colb += 255;
142 		*pixel_mode |= PMODE_GLOW | FIRE_ADD;
143 	}
144 	else if(cpart->life>0)
145 	{
146 		*colr += cpart->life*1;
147 		*colg += cpart->life*2;
148 		*colb += cpart->life*3;
149 		*pixel_mode |= PMODE_BLUR;
150 	}
151 	else
152 	{
153 		*pixel_mode |= PMODE_BLUR;
154 	}
155 	return 0;
156 }
157