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