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()
91 self.modelindex = ReadShort();
92 self.origin_x = ReadCoord();
93 self.origin_y = ReadCoord();
94 self.origin_z = ReadCoord();
95 self.maxs_x = ReadCoord();
96 self.maxs_y = ReadCoord();
97 self.maxs_z = ReadCoord();
98 self.cnt = ReadShort(); // effect number
99 self.impulse = ReadCoord(); // density (<0: point, >0: volume)
100 if(self.impulse == 0)
101 self.impulse = 1; // one per sec
102 self.velocity = decompressShortVector(ReadShort());
103 self.movedir = decompressShortVector(ReadShort());
104 self.waterlevel = ReadCoord();
105 self.count = ReadCoord();
106 self.glow_color = ReadByte();
108 strunzone(self.noise);
109 self.noise = strzone(ReadString());
111 self.absolute = (self.impulse >= 0);
113 self.impulse *= -self.maxs_x * self.maxs_y * self.maxs_z / 262144; // relative: particles per 64^3 cube
115 self.mins = -0.5 * self.maxs;
116 self.maxs = 0.5 * self.maxs;
117 self.origin = self.origin - self.mins;
119 setorigin(self, self.origin);
120 setsize(self, self.mins, self.maxs);
121 self.solid = SOLID_NOT;
122 self.draw = Draw_PointParticles;
127 te_particlerain(self.origin + self.mins, self.origin + self.maxs, self.velocity, self.count * drawframetime, self.glow_color);
132 te_particlesnow(self.origin + self.mins, self.origin + self.maxs, self.velocity, self.count * drawframetime, self.glow_color);
135 void Ent_RainOrSnow()
137 self.impulse = ReadByte(); // Rain, Snow, or Whatever
138 self.origin_x = ReadCoord();
139 self.origin_y = ReadCoord();
140 self.origin_z = ReadCoord();
141 self.maxs_x = ReadCoord();
142 self.maxs_y = ReadCoord();
143 self.maxs_z = ReadCoord();
144 self.velocity = decompressShortVector(ReadShort());
145 self.count = ReadShort() * 10;
146 self.glow_color = ReadByte(); // color
148 self.mins = -0.5 * self.maxs;
149 self.maxs = 0.5 * self.maxs;
150 self.origin = self.origin - self.mins;
152 setorigin(self, self.origin);
153 setsize(self, self.mins, self.maxs);
154 self.solid = SOLID_NOT;
156 self.draw = Draw_Rain;
158 self.draw = Draw_Snow;