1 #include "simulation/ElementCommon.h"
2 
3 static int update(UPDATE_FUNC_ARGS);
4 static void create(ELEMENT_CREATE_FUNC_ARGS);
5 
Element_SING()6 void Element::Element_SING()
7 {
8 	Identifier = "DEFAULT_PT_SING";
9 	Name = "SING";
10 	Colour = PIXPACK(0x242424);
11 	MenuVisible = 1;
12 	MenuSection = SC_NUCLEAR;
13 	Enabled = 1;
14 
15 	Advection = 0.7f;
16 	AirDrag = 0.36f * CFDS;
17 	AirLoss = 0.96f;
18 	Loss = 0.80f;
19 	Collision = 0.1f;
20 	Gravity = 0.12f;
21 	Diffusion = 0.00f;
22 	HotAir = -0.001f	* CFDS;
23 	Falldown = 1;
24 
25 	Flammable = 0;
26 	Explosive = 0;
27 	Meltable = 0;
28 	Hardness = 0;
29 
30 	Weight = 86;
31 
32 	HeatConduct = 70;
33 	Description = "Singularity. Creates huge amounts of negative pressure and destroys everything.";
34 
35 	Properties = TYPE_PART|PROP_LIFE_DEC;
36 
37 	LowPressure = IPL;
38 	LowPressureTransition = NT;
39 	HighPressure = IPH;
40 	HighPressureTransition = NT;
41 	LowTemperature = ITL;
42 	LowTemperatureTransition = NT;
43 	HighTemperature = ITH;
44 	HighTemperatureTransition = NT;
45 
46 	Update = &update;
47 	Create = &create;
48 }
49 
update(UPDATE_FUNC_ARGS)50 static int update(UPDATE_FUNC_ARGS)
51 {
52 	int r, rx, ry, cry, crx, nb, spawncount;
53 	int singularity = -parts[i].life;
54 	float angle, v;
55 
56 	if (sim->pv[y/CELL][x/CELL]<singularity)
57 		sim->pv[y/CELL][x/CELL] += 0.1f*(singularity-sim->pv[y/CELL][x/CELL]);
58 	if (sim->pv[y/CELL+1][x/CELL]<singularity)
59 		sim->pv[y/CELL+1][x/CELL] += 0.1f*(singularity-sim->pv[y/CELL+1][x/CELL]);
60 	if (sim->pv[y/CELL-1][x/CELL]<singularity)
61 		sim->pv[y/CELL-1][x/CELL] += 0.1f*(singularity-sim->pv[y/CELL-1][x/CELL]);
62 
63 	sim->pv[y/CELL][x/CELL+1] += 0.1f*(singularity-sim->pv[y/CELL][x/CELL+1]);
64 	sim->pv[y/CELL+1][x/CELL+1] += 0.1f*(singularity-sim->pv[y/CELL+1][x/CELL+1]);
65 	sim->pv[y/CELL][x/CELL-1] += 0.1f*(singularity-sim->pv[y/CELL][x/CELL-1]);
66 	sim->pv[y/CELL-1][x/CELL-1] += 0.1f*(singularity-sim->pv[y/CELL-1][x/CELL-1]);
67 
68 	if (parts[i].life<1) {
69 		//Pop!
70 		for (rx=-1; rx<2; rx++) {
71 			crx = (x/CELL)+rx;
72 			for (ry=-1; ry<2; ry++) {
73 				cry = (y/CELL)+ry;
74 				if (cry >= 0 && crx >= 0 && crx < (XRES/CELL) && cry < (YRES/CELL)) {
75 					sim->pv[cry][crx] += (float)parts[i].tmp;
76 				}
77 			}
78 		}
79 		spawncount = std::abs(parts[i].tmp);
80 		spawncount = (spawncount>255) ? 3019 : std::pow((double)(spawncount/8), 2)*M_PI;
81 		for (int j = 0;j < spawncount; j++)
82 		{
83 			switch (RNG::Ref().gen() % 3)
84 			{
85 				case 0:
86 					nb = sim->create_part(-3, x, y, PT_PHOT);
87 					break;
88 				case 1:
89 					nb = sim->create_part(-3, x, y, PT_NEUT);
90 					break;
91 				case 2:
92 					nb = sim->create_part(-3, x, y, PT_ELEC);
93 					break;
94 			}
95 			if (nb!=-1) {
96 				parts[nb].life = RNG::Ref().between(0, 299);
97 				parts[nb].temp = MAX_TEMP/2;
98 				angle = RNG::Ref().uniform01()*2.0f*M_PI;
99 				v = RNG::Ref().uniform01()*5.0f;
100 				parts[nb].vx = v*cosf(angle);
101 				parts[nb].vy = v*sinf(angle);
102 			}
103 			else if (sim->pfree==-1)
104 				break;//if we've run out of particles, stop trying to create them - saves a lot of lag on "sing bomb" saves
105 		}
106 		sim->kill_part(i);
107 		return 1;
108 	}
109 	for (rx=-1; rx<2; rx++)
110 		for (ry=-1; ry<2; ry++)
111 			if (BOUNDS_CHECK && (rx || ry))
112 			{
113 				r = pmap[y+ry][x+rx];
114 				if (!r)
115 					continue;
116 				if (TYP(r)!=PT_DMND&& RNG::Ref().chance(1, 3))
117 				{
118 					if (TYP(r)==PT_SING && parts[ID(r)].life >10)
119 					{
120 						if (parts[i].life+parts[ID(r)].life > 255)
121 							continue;
122 						parts[i].life += parts[ID(r)].life;
123 					}
124 					else
125 					{
126 						if (parts[i].life+3 > 255)
127 						{
128 							if (parts[ID(r)].type!=PT_SING && RNG::Ref().chance(1, 1000))
129 							{
130 								int np;
131 								np = sim->create_part(ID(r),x+rx,y+ry,PT_SING);
132 								parts[np].life = RNG::Ref().between(60, 109);
133 							}
134 							continue;
135 						}
136 						parts[i].life += 3;
137 						parts[i].tmp++;
138 					}
139 					parts[i].temp = restrict_flt(parts[ID(r)].temp+parts[i].temp, MIN_TEMP, MAX_TEMP);
140 					sim->kill_part(ID(r));
141 				}
142 			}
143 	return 0;
144 }
145 
create(ELEMENT_CREATE_FUNC_ARGS)146 static void create(ELEMENT_CREATE_FUNC_ARGS)
147 {
148 	sim->parts[i].life = RNG::Ref().between(60, 109);
149 }
150