]> icculus.org git repositories - divverent/nexuiz.git/blob - data/qcsrc/client/particles.qc
get rid of .info files; make interpolation generic
[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         if(n == 0)
62                 return;
63         fail = 0;
64         for(i = random(); i <= n && fail <= 64*n; ++i)
65         {
66                 p = o + self.mins;
67                 p_x += random() * sz_x;
68                 p_y += random() * sz_y;
69                 p_z += random() * sz_z;
70                 if(PointInBrush(self, p))
71                 {
72                         if(self.movedir != '0 0 0')
73                         {
74                                 traceline(p, p + normalize(self.movedir) * 4096, 0, world);
75                                 p = trace_endpos;
76                                 pointparticles(self.cnt, p, trace_plane_normal * vlen(self.movedir) + self.velocity + randomvec() * self.waterlevel, self.count, self.glow_color);
77                         }
78                         else
79                                 pointparticles(self.cnt, p, self.velocity + randomvec() * self.waterlevel, self.count, self.glow_color);
80                         if(self.noise != "")
81                         {
82                                 self.origin = p;
83                                 sound(self, CHAN_AUTO, self.noise, 1, ATTN_NORM);
84                         }
85                 }
86                 else if(self.absolute)
87                 {
88                         ++fail;
89                         --i;
90                 }
91         }
92         self.origin = o;
93 }
94
95 void Ent_PointParticles()
96 {
97         float f;
98         f = ReadByte();
99         if(f & 2)
100         {
101                 self.impulse = ReadCoord(); // density (<0: point, >0: volume)
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 & 4)
107         {
108                 self.origin_x = ReadCoord();
109                 self.origin_y = ReadCoord();
110                 self.origin_z = ReadCoord();
111         }
112         if(f & 1)
113         {
114                 self.modelindex = ReadShort();
115                 if(self.modelindex)
116                 {
117                         self.mins_x = ReadCoord();
118                         self.mins_y = ReadCoord();
119                         self.mins_z = ReadCoord();
120                         self.maxs_x = ReadCoord();
121                         self.maxs_y = ReadCoord();
122                         self.maxs_z = ReadCoord();
123                 }
124                 else
125                 {
126                         self.mins    = '0 0 0';
127                         self.maxs_x = ReadCoord();
128                         self.maxs_y = ReadCoord();
129                         self.maxs_z = ReadCoord();
130                 }
131
132                 self.cnt = ReadShort(); // effect number
133
134                 self.velocity = decompressShortVector(ReadShort());
135                 self.movedir = decompressShortVector(ReadShort());
136                 self.waterlevel = ReadCoord();
137                 self.count = ReadCoord();
138                 self.glow_color = ReadByte();
139                 if(self.noise)
140                         strunzone(self.noise);
141                 self.noise = strzone(ReadString());
142         }
143
144         setorigin(self, self.origin);
145         setsize(self, self.mins, self.maxs);
146         self.solid = SOLID_NOT;
147         self.draw = Draw_PointParticles;
148 }
149
150 void Ent_PointParticles_Remove()
151 {
152         if(self.noise)
153                 strunzone(self.noise);
154         self.noise = string_null;
155 }
156
157 void Draw_Rain()
158 {
159     te_particlerain(self.origin + self.mins, self.origin + self.maxs, self.velocity, self.count * drawframetime, self.glow_color);
160 }
161
162 void Draw_Snow()
163 {
164     te_particlesnow(self.origin + self.mins, self.origin + self.maxs, self.velocity, self.count * drawframetime, self.glow_color);
165 }
166
167 void Ent_RainOrSnow()
168 {
169         self.impulse = ReadByte(); // Rain, Snow, or Whatever
170         self.origin_x = ReadCoord();
171         self.origin_y = ReadCoord();
172         self.origin_z = ReadCoord();
173         self.maxs_x = ReadCoord();
174         self.maxs_y = ReadCoord();
175         self.maxs_z = ReadCoord();
176         self.velocity = decompressShortVector(ReadShort());
177         self.count = ReadShort() * 10;
178         self.glow_color = ReadByte(); // color
179
180         self.mins    = -0.5 * self.maxs;
181         self.maxs    =  0.5 * self.maxs;
182         self.origin  = self.origin - self.mins;
183
184         setorigin(self, self.origin);
185         setsize(self, self.mins, self.maxs);
186         self.solid = SOLID_NOT;
187         if(self.impulse)
188                 self.draw = Draw_Rain;
189         else
190                 self.draw = Draw_Snow;
191 }