]> icculus.org git repositories - divverent/nexuiz.git/blob - data/qcsrc/client/particles.qc
misc_laser is now client side too (untested too)
[divverent/nexuiz.git] / data / qcsrc / client / particles.qc
1 vector PointInBrush_vec;
2 float PointInBrush_Recurse()
3 {
4         float s;
5         entity se;
6         float f;
7
8         traceline(PointInBrush_vec, PointInBrush_vec, 0, world);
9         if not(trace_ent)
10                 return 0;
11         if(trace_ent == self)
12                 return 1;
13
14         se = trace_ent;
15         s = se.solid;
16         se.solid = SOLID_NOT;
17         f = PointInBrush_Recurse();
18         se.solid = s;
19
20         return f;
21 }
22 float PointInBrush(entity brush, vector point)
23 {
24         float f, s;
25
26         if not(self.modelindex)
27                 return 1;
28
29         s = self.solid;
30         self.solid = SOLID_BSP;
31         PointInBrush_vec = point;
32         f = PointInBrush_Recurse();
33         self.solid = s;
34
35         return f;
36 }
37
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
45 .float absolute;
46 .vector movedir; // trace direction
47
48 void Draw_PointParticles()
49 {
50         float n, i, fail;
51         vector p;
52         vector sz;
53         vector o;
54         o = self.origin;
55         sz = self.maxs - self.mins;
56         n = self.impulse * drawframetime;
57         fail = 0;
58         for(i = random(); i <= n && fail <= 64*n; ++i)
59         {
60                 p = o + self.mins;
61                 p_x += random() * sz_x;
62                 p_y += random() * sz_y;
63                 p_z += random() * sz_z;
64                 if(PointInBrush(self, p))
65                 {
66                         if(self.movedir != '0 0 0')
67                         {
68                                 traceline(p, p + normalize(self.movedir) * 4096, 0, world);
69                                 p = trace_endpos;
70                                 pointparticles(self.cnt, p, trace_plane_normal * vlen(self.movedir) + self.velocity + randomvec() * self.waterlevel, self.count, self.glow_color);
71                         }
72                         else
73                                 pointparticles(self.cnt, p, self.velocity + randomvec() * self.waterlevel, self.count, self.glow_color);
74                         if(self.noise != "")
75                         {
76                                 self.origin = p;
77                                 sound(self, CHAN_AUTO, self.noise, 1, ATTN_NORM);
78                         }
79                 }
80                 else if(self.absolute)
81                 {
82                         ++fail;
83                         --i;
84                 }
85         }
86         self.origin = o;
87 }
88
89 void Ent_PointParticles()
90 {
91         float f;
92         f = ReadByte();
93         if(f & 2)
94         {
95                 self.impulse = ReadCoord(); // density (<0: point, >0: volume)
96                 if(self.impulse == 0)
97                         self.impulse = 1; // one per sec
98                 self.absolute = (self.impulse >= 0);
99                 if(!self.absolute)
100                         self.impulse *= -self.maxs_x * self.maxs_y * self.maxs_z / 262144; // relative: particles per 64^3 cube
101         }
102         if(f & 1)
103         {
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();
111
112                 self.mins    = -0.5 * self.maxs;
113                 self.maxs    =  0.5 * self.maxs;
114                 self.origin  = self.origin - self.mins;
115
116                 self.cnt = ReadShort(); // effect number
117
118                 self.velocity = decompressShortVector(ReadShort());
119                 self.movedir = decompressShortVector(ReadShort());
120                 self.waterlevel = ReadCoord();
121                 self.count = ReadCoord();
122                 self.glow_color = ReadByte();
123                 if(self.noise)
124                         strunzone(self.noise);
125                 self.noise = strzone(ReadString());
126         }
127
128         setorigin(self, self.origin);
129         setsize(self, self.mins, self.maxs);
130         self.solid = SOLID_NOT;
131         self.draw = Draw_PointParticles;
132 }
133
134 void Ent_PointParticles_Remove()
135 {
136         if(self.noise)
137                 strunzone(self.noise);
138         self.noise = string_null;
139 }
140
141 void Draw_Rain()
142 {
143     te_particlerain(self.origin + self.mins, self.origin + self.maxs, self.velocity, self.count * drawframetime, self.glow_color);
144 }
145
146 void Draw_Snow()
147 {
148     te_particlesnow(self.origin + self.mins, self.origin + self.maxs, self.velocity, self.count * drawframetime, self.glow_color);
149 }
150
151 void Ent_RainOrSnow()
152 {
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
163
164         self.mins    = -0.5 * self.maxs;
165         self.maxs    =  0.5 * self.maxs;
166         self.origin  = self.origin - self.mins;
167
168         setorigin(self, self.origin);
169         setsize(self, self.mins, self.maxs);
170         self.solid = SOLID_NOT;
171         if(self.impulse)
172                 self.draw = Draw_Rain;
173         else
174                 self.draw = Draw_Snow;
175 }