1 #include "simulation/ElementCommon.h"
2 
3 static int update(UPDATE_FUNC_ARGS);
4 static bool ctypeDraw(CTYPEDRAW_FUNC_ARGS);
5 static unsigned int wavelengthToDecoColour(int wavelength);
6 
Element_CRAY()7 void Element::Element_CRAY()
8 {
9 	Identifier = "DEFAULT_PT_CRAY";
10 	Name = "CRAY";
11 	Colour = PIXPACK(0xBBFF00);
12 	MenuVisible = 1;
13 	MenuSection = SC_ELEC;
14 	Enabled = 1;
15 
16 	Advection = 0.0f;
17 	AirDrag = 0.00f * CFDS;
18 	AirLoss = 0.90f;
19 	Loss = 0.00f;
20 	Collision = 0.0f;
21 	Gravity = 0.0f;
22 	Diffusion = 0.00f;
23 	HotAir = 0.000f	* CFDS;
24 	Falldown = 0;
25 
26 	Flammable = 0;
27 	Explosive = 0;
28 	Meltable = 0;
29 	Hardness = 1;
30 
31 	Weight = 100;
32 
33 	HeatConduct = 0;
34 	Description = "Particle Ray Emitter. Creates a beam of particles set by its ctype, with a range set by tmp.";
35 
36 	Properties = TYPE_SOLID;
37 
38 	LowPressure = IPL;
39 	LowPressureTransition = NT;
40 	HighPressure = IPH;
41 	HighPressureTransition = NT;
42 	LowTemperature = ITL;
43 	LowTemperatureTransition = NT;
44 	HighTemperature = ITH;
45 	HighTemperatureTransition = NT;
46 
47 	Update = &update;
48 	CtypeDraw = &ctypeDraw;
49 }
50 
update(UPDATE_FUNC_ARGS)51 static int update(UPDATE_FUNC_ARGS)
52 {
53 	int nxx, nyy, docontinue, nxi, nyi;
54 	// set ctype to things that touch it if it doesn't have one already
55 	if (parts[i].ctype<=0 || !sim->elements[TYP(parts[i].ctype)].Enabled)
56 	{
57 		for (int rx = -1; rx <= 1; rx++)
58 			for (int ry = -1; ry <= 1; ry++)
59 				if (BOUNDS_CHECK)
60 				{
61 					int r = sim->photons[y+ry][x+rx];
62 					if (!r)
63 						r = pmap[y+ry][x+rx];
64 					if (!r)
65 						continue;
66 					if (TYP(r)!=PT_CRAY && TYP(r)!=PT_PSCN && TYP(r)!=PT_INST && TYP(r)!=PT_METL && TYP(r)!=PT_SPRK && TYP(r)<PT_NUM)
67 					{
68 						parts[i].ctype = TYP(r);
69 						parts[i].temp = parts[ID(r)].temp;
70 					}
71 				}
72 	}
73 	else
74 	{
75 		for (int rx =-1; rx <= 1; rx++)
76 			for (int ry = -1; ry <= 1; ry++)
77 				if (BOUNDS_CHECK && (rx || ry))
78 				{
79 					int r = pmap[y+ry][x+rx];
80 					if (!r)
81 						continue;
82 					if (TYP(r)==PT_SPRK && parts[ID(r)].life==3) { //spark found, start creating
83 						unsigned int colored = 0;
84 						bool destroy = parts[ID(r)].ctype==PT_PSCN;
85 						bool nostop = parts[ID(r)].ctype==PT_INST;
86 						bool createSpark = (parts[ID(r)].ctype==PT_INWR);
87 						int partsRemaining = 255;
88 						if (parts[i].tmp) //how far it shoots
89 							partsRemaining = parts[i].tmp;
90 						int spacesRemaining = parts[i].tmp2;
91 						for (docontinue = 1, nxi = rx*-1, nyi = ry*-1, nxx = spacesRemaining*nxi, nyy = spacesRemaining*nyi; docontinue; nyy+=nyi, nxx+=nxi)
92 						{
93 							if (!(x+nxi+nxx<XRES && y+nyi+nyy<YRES && x+nxi+nxx >= 0 && y+nyi+nyy >= 0)) {
94 								break;
95 							}
96 							r = pmap[y+nyi+nyy][x+nxi+nxx];
97 							if (!sim->IsWallBlocking(x+nxi+nxx, y+nyi+nyy, TYP(parts[i].ctype)) && (!sim->pmap[y+nyi+nyy][x+nxi+nxx] || createSpark)) { // create, also set color if it has passed through FILT
98 								int nr = sim->create_part(-1, x+nxi+nxx, y+nyi+nyy, TYP(parts[i].ctype), ID(parts[i].ctype));
99 								if (nr!=-1) {
100 									if (colored)
101 										parts[nr].dcolour = colored;
102 									parts[nr].temp = parts[i].temp;
103 									if (parts[i].life>0)
104 										parts[nr].life = parts[i].life;
105 									if(!--partsRemaining)
106 										docontinue = 0;
107 								}
108 							} else if (TYP(r)==PT_FILT) { // get color if passed through FILT
109 								if (parts[ID(r)].dcolour == 0xFF000000)
110 									colored = 0xFF000000;
111 								else if (parts[ID(r)].tmp==0)
112 								{
113 									int Element_FILT_getWavelengths(Particle* cpart);
114 									colored = wavelengthToDecoColour(Element_FILT_getWavelengths(&parts[ID(r)]));
115 								}
116 								else if (colored==0xFF000000)
117 									colored = 0;
118 								parts[ID(r)].life = 4;
119 							} else if (TYP(r) == PT_CRAY || nostop) {
120 								docontinue = 1;
121 							} else if(destroy && r && (TYP(r) != PT_DMND)) {
122 								sim->kill_part(ID(r));
123 								if(!--partsRemaining)
124 									docontinue = 0;
125 							}
126 							else
127 								docontinue = 0;
128 							if(!partsRemaining)
129 								docontinue = 0;
130 						}
131 					}
132 				}
133 	}
134 	return 0;
135 }
136 
wavelengthToDecoColour(int wavelength)137 static unsigned int wavelengthToDecoColour(int wavelength)
138 {
139 	int colr = 0, colg = 0, colb = 0, x;
140 	for (x=0; x<12; x++) {
141 		colr += (wavelength >> (x+18)) & 1;
142 		colb += (wavelength >>  x)     & 1;
143 	}
144 	for (x=0; x<12; x++)
145 		colg += (wavelength >> (x+9))  & 1;
146 	x = 624/(colr+colg+colb+1);
147 	colr *= x;
148 	colg *= x;
149 	colb *= x;
150 
151 	if(colr > 255) colr = 255;
152 	else if(colr < 0) colr = 0;
153 	if(colg > 255) colg = 255;
154 	else if(colg < 0) colg = 0;
155 	if(colb > 255) colb = 255;
156 	else if(colb < 0) colb = 0;
157 
158 	return (255<<24) | (colr<<16) | (colg<<8) | colb;
159 }
160 
ctypeDraw(CTYPEDRAW_FUNC_ARGS)161 static bool ctypeDraw(CTYPEDRAW_FUNC_ARGS)
162 {
163 	if (!Element::ctypeDrawVInCtype(CTYPEDRAW_FUNC_SUBCALL_ARGS))
164 	{
165 		return false;
166 	}
167 	if (t == PT_LIGH)
168 	{
169 		sim->parts[i].ctype |= PMAPID(30);
170 	}
171 	sim->parts[i].temp = sim->elements[t].DefaultProperties.temp;
172 	return true;
173 }
174