1 vector PointInBrush_vec;
2 entity PointInBrush_brush;
3 entity PointInBrush_allmask;
4 .float dphitcontentsmask;
5 float PointInBrush_Recurse()
11 traceline(PointInBrush_vec, PointInBrush_vec, 0, world);
14 if(trace_ent == PointInBrush_brush)
20 f = PointInBrush_Recurse();
25 float PointInBrush(entity brush, vector point)
29 if not(brush.modelindex)
33 brush.solid = SOLID_BSP;
34 PointInBrush_vec = point;
35 PointInBrush_brush = brush;
36 f = PointInBrush_Recurse();
42 .float cnt; // effect number
43 .vector velocity; // particle velocity
44 .float waterlevel; // direction jitter
45 .float count; // count multiplier
46 .float glow_color; // palette color
47 .float impulse; // density
48 .string noise; // sound
50 .vector movedir; // trace direction
52 void Draw_PointParticles()
59 sz = self.maxs - self.mins;
60 n = self.impulse * drawframetime;
62 for(i = random(); i <= n && fail <= 64*n; ++i)
65 p_x += random() * sz_x;
66 p_y += random() * sz_y;
67 p_z += random() * sz_z;
68 if(PointInBrush(self, p))
70 if(self.movedir != '0 0 0')
72 traceline(p, p + normalize(self.movedir) * 4096, 0, world);
74 pointparticles(self.cnt, p, trace_plane_normal * vlen(self.movedir) + self.velocity + randomvec() * self.waterlevel, self.count, self.glow_color);
77 pointparticles(self.cnt, p, self.velocity + randomvec() * self.waterlevel, self.count, self.glow_color);
81 sound(self, CHAN_AUTO, self.noise, 1, ATTN_NORM);
84 else if(self.absolute)
93 void Ent_PointParticles()
99 self.impulse = ReadCoord(); // density (<0: point, >0: volume)
100 if(self.impulse == 0)
101 self.impulse = 1; // one per sec
102 self.absolute = (self.impulse >= 0);
104 self.impulse *= -self.maxs_x * self.maxs_y * self.maxs_z / 262144; // relative: particles per 64^3 cube
108 self.modelindex = ReadShort();
109 self.origin_x = ReadCoord();
110 self.origin_y = ReadCoord();
111 self.origin_z = ReadCoord();
114 self.mins_x = ReadCoord();
115 self.mins_y = ReadCoord();
116 self.mins_z = ReadCoord();
117 self.maxs_x = ReadCoord();
118 self.maxs_y = ReadCoord();
119 self.maxs_z = ReadCoord();
123 self.maxs_x = ReadCoord();
124 self.maxs_y = ReadCoord();
125 self.maxs_z = ReadCoord();
126 self.mins = -0.5 * self.maxs;
127 self.maxs = 0.5 * self.maxs;
128 self.origin = self.origin - self.mins;
131 self.cnt = ReadShort(); // effect number
133 self.velocity = decompressShortVector(ReadShort());
134 self.movedir = decompressShortVector(ReadShort());
135 self.waterlevel = ReadCoord();
136 self.count = ReadCoord();
137 self.glow_color = ReadByte();
139 strunzone(self.noise);
140 self.noise = strzone(ReadString());
143 setorigin(self, self.origin);
144 setsize(self, self.mins, self.maxs);
145 self.solid = SOLID_NOT;
146 self.draw = Draw_PointParticles;
149 void Ent_PointParticles_Remove()
152 strunzone(self.noise);
153 self.noise = string_null;
158 te_particlerain(self.origin + self.mins, self.origin + self.maxs, self.velocity, self.count * drawframetime, self.glow_color);
163 te_particlesnow(self.origin + self.mins, self.origin + self.maxs, self.velocity, self.count * drawframetime, self.glow_color);
166 void Ent_RainOrSnow()
168 self.impulse = ReadByte(); // Rain, Snow, or Whatever
169 self.origin_x = ReadCoord();
170 self.origin_y = ReadCoord();
171 self.origin_z = ReadCoord();
172 self.maxs_x = ReadCoord();
173 self.maxs_y = ReadCoord();
174 self.maxs_z = ReadCoord();
175 self.velocity = decompressShortVector(ReadShort());
176 self.count = ReadShort() * 10;
177 self.glow_color = ReadByte(); // color
179 self.mins = -0.5 * self.maxs;
180 self.maxs = 0.5 * self.maxs;
181 self.origin = self.origin - self.mins;
183 setorigin(self, self.origin);
184 setsize(self, self.mins, self.maxs);
185 self.solid = SOLID_NOT;
187 self.draw = Draw_Rain;
189 self.draw = Draw_Snow;