]> icculus.org git repositories - divverent/nexuiz.git/blob - data/qcsrc/client/particles.qc
got it to work with brush ents
[divverent/nexuiz.git] / data / qcsrc / client / particles.qc
1 vector PointInBrush_vec;
2 entity PointInBrush_brush;
3 entity PointInBrush_allmask;
4 .float dphitcontentsmask;
5 float PointInBrush_Recurse()
6 {
7         float s;
8         entity se;
9         float f;
10
11         traceline(PointInBrush_vec, PointInBrush_vec, 0, world);
12         if not(trace_ent)
13                 return 0;
14         if(trace_ent == PointInBrush_brush)
15                 return 1;
16
17         se = trace_ent;
18         s = se.solid;
19         se.solid = SOLID_NOT;
20         f = PointInBrush_Recurse();
21         se.solid = s;
22
23         return f;
24 }
25 float PointInBrush(entity brush, vector point)
26 {
27         float f, s;
28
29         if not(brush.modelindex)
30                 return 1;
31
32         s = brush.solid;
33         brush.solid = SOLID_BSP;
34         PointInBrush_vec = point;
35         PointInBrush_brush = brush;
36         f = PointInBrush_Recurse();
37         brush.solid = s;
38
39         return f;
40 }
41
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
49 .float absolute;
50 .vector movedir; // trace direction
51
52 void Draw_PointParticles()
53 {
54         float n, i, fail;
55         vector p;
56         vector sz;
57         vector o;
58         o = self.origin;
59         sz = self.maxs - self.mins;
60         n = self.impulse * drawframetime;
61         fail = 0;
62         for(i = random(); i <= n && fail <= 64*n; ++i)
63         {
64                 p = o + self.mins;
65                 p_x += random() * sz_x;
66                 p_y += random() * sz_y;
67                 p_z += random() * sz_z;
68                 if(PointInBrush(self, p))
69                 {
70                         if(self.movedir != '0 0 0')
71                         {
72                                 traceline(p, p + normalize(self.movedir) * 4096, 0, world);
73                                 p = trace_endpos;
74                                 pointparticles(self.cnt, p, trace_plane_normal * vlen(self.movedir) + self.velocity + randomvec() * self.waterlevel, self.count, self.glow_color);
75                         }
76                         else
77                                 pointparticles(self.cnt, p, self.velocity + randomvec() * self.waterlevel, self.count, self.glow_color);
78                         if(self.noise != "")
79                         {
80                                 self.origin = p;
81                                 sound(self, CHAN_AUTO, self.noise, 1, ATTN_NORM);
82                         }
83                 }
84                 else if(self.absolute)
85                 {
86                         ++fail;
87                         --i;
88                 }
89         }
90         self.origin = o;
91 }
92
93 void Ent_PointParticles()
94 {
95         float f;
96         f = ReadByte();
97         if(f & 2)
98         {
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);
103                 if(!self.absolute)
104                         self.impulse *= -self.maxs_x * self.maxs_y * self.maxs_z / 262144; // relative: particles per 64^3 cube
105         }
106         if(f & 1)
107         {
108                 self.modelindex = ReadShort();
109                 self.origin_x = ReadCoord();
110                 self.origin_y = ReadCoord();
111                 self.origin_z = ReadCoord();
112                 if(self.modelindex)
113                 {
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();
120                 }
121                 else
122                 {
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;
129                 }
130
131                 self.cnt = ReadShort(); // effect number
132
133                 self.velocity = decompressShortVector(ReadShort());
134                 self.movedir = decompressShortVector(ReadShort());
135                 self.waterlevel = ReadCoord();
136                 self.count = ReadCoord();
137                 self.glow_color = ReadByte();
138                 if(self.noise)
139                         strunzone(self.noise);
140                 self.noise = strzone(ReadString());
141         }
142
143         setorigin(self, self.origin);
144         setsize(self, self.mins, self.maxs);
145         self.solid = SOLID_NOT;
146         self.draw = Draw_PointParticles;
147 }
148
149 void Ent_PointParticles_Remove()
150 {
151         if(self.noise)
152                 strunzone(self.noise);
153         self.noise = string_null;
154 }
155
156 void Draw_Rain()
157 {
158     te_particlerain(self.origin + self.mins, self.origin + self.maxs, self.velocity, self.count * drawframetime, self.glow_color);
159 }
160
161 void Draw_Snow()
162 {
163     te_particlesnow(self.origin + self.mins, self.origin + self.maxs, self.velocity, self.count * drawframetime, self.glow_color);
164 }
165
166 void Ent_RainOrSnow()
167 {
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
178
179         self.mins    = -0.5 * self.maxs;
180         self.maxs    =  0.5 * self.maxs;
181         self.origin  = self.origin - self.mins;
182
183         setorigin(self, self.origin);
184         setsize(self, self.mins, self.maxs);
185         self.solid = SOLID_NOT;
186         if(self.impulse)
187                 self.draw = Draw_Rain;
188         else
189                 self.draw = Draw_Snow;
190 }