1 vector PointInBrush_vec;
2 float PointInBrush_Recurse()
8 traceline(PointInBrush_vec, PointInBrush_vec, 0, world);
17 f = PointInBrush_Recurse();
22 float PointInBrush(entity brush, vector point)
26 if not(self.modelindex)
30 self.solid = SOLID_BSP;
31 PointInBrush_vec = point;
32 f = PointInBrush_Recurse();
38 .float cnt; // effect number
39 .vector velocity; // particle velocity
40 .float waterlevel; // direction jitter
41 .float count; // count multiplier
42 .float glow_color; // palette color
43 .float impulse; // density
44 .string noise; // sound
46 .vector movedir; // trace direction
48 void Draw_PointParticles()
55 sz = self.maxs - self.mins;
56 n = self.impulse * drawframetime;
58 for(i = random(); i <= n && fail <= 64*n; ++i)
61 p_x += random() * sz_x;
62 p_y += random() * sz_y;
63 p_z += random() * sz_z;
64 if(PointInBrush(self, p))
66 if(self.movedir != '0 0 0')
68 traceline(p, p + normalize(self.movedir) * 4096, 0, world);
70 pointparticles(self.cnt, p, trace_plane_normal * vlen(self.movedir) + self.velocity + randomvec() * self.waterlevel, self.count, self.glow_color);
73 pointparticles(self.cnt, p, self.velocity + randomvec() * self.waterlevel, self.count, self.glow_color);
77 sound(self, CHAN_AUTO, self.noise, 1, ATTN_NORM);
80 else if(self.absolute)
89 void Ent_PointParticles()
95 self.impulse = ReadCoord(); // density (<0: point, >0: volume)
97 self.impulse = 1; // one per sec
98 self.absolute = (self.impulse >= 0);
100 self.impulse *= -self.maxs_x * self.maxs_y * self.maxs_z / 262144; // relative: particles per 64^3 cube
104 self.modelindex = ReadShort();
105 self.origin_x = ReadCoord();
106 self.origin_y = ReadCoord();
107 self.origin_z = ReadCoord();
108 self.maxs_x = ReadCoord();
109 self.maxs_y = ReadCoord();
110 self.maxs_z = ReadCoord();
112 self.mins = -0.5 * self.maxs;
113 self.maxs = 0.5 * self.maxs;
114 self.origin = self.origin - self.mins;
116 self.cnt = ReadShort(); // effect number
118 self.velocity = decompressShortVector(ReadShort());
119 self.movedir = decompressShortVector(ReadShort());
120 self.waterlevel = ReadCoord();
121 self.count = ReadCoord();
122 self.glow_color = ReadByte();
124 strunzone(self.noise);
125 self.noise = strzone(ReadString());
128 setorigin(self, self.origin);
129 setsize(self, self.mins, self.maxs);
130 self.solid = SOLID_NOT;
131 self.draw = Draw_PointParticles;
134 void Ent_PointParticles_Remove()
137 strunzone(self.noise);
138 self.noise = string_null;
143 te_particlerain(self.origin + self.mins, self.origin + self.maxs, self.velocity, self.count * drawframetime, self.glow_color);
148 te_particlesnow(self.origin + self.mins, self.origin + self.maxs, self.velocity, self.count * drawframetime, self.glow_color);
151 void Ent_RainOrSnow()
153 self.impulse = ReadByte(); // Rain, Snow, or Whatever
154 self.origin_x = ReadCoord();
155 self.origin_y = ReadCoord();
156 self.origin_z = ReadCoord();
157 self.maxs_x = ReadCoord();
158 self.maxs_y = ReadCoord();
159 self.maxs_z = ReadCoord();
160 self.velocity = decompressShortVector(ReadShort());
161 self.count = ReadShort() * 10;
162 self.glow_color = ReadByte(); // color
164 self.mins = -0.5 * self.maxs;
165 self.maxs = 0.5 * self.maxs;
166 self.origin = self.origin - self.mins;
168 setorigin(self, self.origin);
169 setsize(self, self.mins, self.maxs);
170 self.solid = SOLID_NOT;
172 self.draw = Draw_Rain;
174 self.draw = Draw_Snow;