]> icculus.org git repositories - divverent/nexuiz.git/blob - data/qcsrc/client/particles.qc
bugfix target_spawn, and change docs to match it
[divverent/nexuiz.git] / data / qcsrc / client / particles.qc
1 vector PointInBrush_vec;
2 entity PointInBrush_brush;
3 .float dphitcontentsmask;
4 float PointInBrush_Recurse()
5 {
6         float s;
7         entity se;
8         float f;
9
10         traceline(PointInBrush_vec, PointInBrush_vec, 0, world);
11         if not(trace_ent)
12                 return 0;
13         if(trace_ent == PointInBrush_brush)
14                 return 1;
15
16         se = trace_ent;
17         s = se.solid;
18         se.solid = SOLID_NOT;
19         f = PointInBrush_Recurse();
20         se.solid = s;
21
22         return f;
23 }
24 float PointInBrush(entity brush, vector point)
25 {
26         float f, s;
27
28         if not(brush.modelindex)
29                 return 1;
30
31         s = brush.solid;
32         brush.solid = SOLID_BSP;
33         PointInBrush_vec = point;
34         PointInBrush_brush = brush;
35         f = PointInBrush_Recurse();
36         brush.solid = s;
37
38         return f;
39 }
40
41 .float cnt; // effect number
42 .vector velocity; // particle velocity
43 .float waterlevel; // direction jitter
44 .float count; // count multiplier
45 .float glow_color; // palette color
46 .float impulse; // density
47 .string noise; // sound
48 .float absolute;
49 .vector movedir; // trace direction
50
51 void Draw_PointParticles()
52 {
53         float n, i, fail;
54         vector p;
55         vector sz;
56         vector o;
57         o = self.origin;
58         sz = self.maxs - self.mins;
59         n = self.impulse * drawframetime;
60         if(n == 0)
61                 return;
62         fail = 0;
63         for(i = random(); i <= n && fail <= 64*n; ++i)
64         {
65                 p = o + self.mins;
66                 p_x += random() * sz_x;
67                 p_y += random() * sz_y;
68                 p_z += random() * sz_z;
69                 if(PointInBrush(self, p))
70                 {
71                         if(self.movedir != '0 0 0')
72                         {
73                                 traceline(p, p + normalize(self.movedir) * 4096, 0, world);
74                                 p = trace_endpos;
75                                 pointparticles(self.cnt, p, trace_plane_normal * vlen(self.movedir) + self.velocity + randomvec() * self.waterlevel, self.count, self.glow_color);
76                         }
77                         else
78                                 pointparticles(self.cnt, p, self.velocity + randomvec() * self.waterlevel, self.count, self.glow_color);
79                         if(self.noise != "")
80                         {
81                                 self.origin = p;
82                                 sound(self, CHAN_AUTO, self.noise, 1, ATTN_NORM);
83                         }
84                 }
85                 else if(self.absolute)
86                 {
87                         ++fail;
88                         --i;
89                 }
90         }
91         self.origin = o;
92 }
93
94 void Ent_PointParticles()
95 {
96         float f;
97         f = ReadByte();
98         if(f & 2)
99         {
100                 self.impulse = ReadCoord(); // density (<0: point, >0: volume)
101                 self.absolute = (self.impulse >= 0);
102                 if(!self.absolute)
103                         self.impulse *= -self.maxs_x * self.maxs_y * self.maxs_z / 262144; // relative: particles per 64^3 cube
104         }
105         if(f & 4)
106         {
107                 self.origin_x = ReadCoord();
108                 self.origin_y = ReadCoord();
109                 self.origin_z = ReadCoord();
110         }
111         if(f & 1)
112         {
113                 self.modelindex = ReadShort();
114                 if(self.modelindex)
115                 {
116                         self.mins_x = ReadCoord();
117                         self.mins_y = ReadCoord();
118                         self.mins_z = ReadCoord();
119                         self.maxs_x = ReadCoord();
120                         self.maxs_y = ReadCoord();
121                         self.maxs_z = ReadCoord();
122                 }
123                 else
124                 {
125                         self.mins    = '0 0 0';
126                         self.maxs_x = ReadCoord();
127                         self.maxs_y = ReadCoord();
128                         self.maxs_z = ReadCoord();
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 }