do bouncing client side (sound is still server side)
[divverent/nexuiz.git] / data / qcsrc / client / projectile.qc
1 .float count; // set if clientside projectile
2 .float cnt; // sound index
3 .float gravity;
4
5 void Projectile_Draw()
6 {
7         vector oldorg;
8
9         oldorg = self.origin;
10
11         if(self.count & 0x80)
12         {
13                 //self.move_flags &~= FL_ONGROUND;
14                 Movetype_Physics(TRUE);
15                 self.angles = vectoangles(self.velocity);
16         }
17         else
18         {
19                 InterpolateOrigin_Do();
20         }
21
22         switch(self.cnt)
23         {
24                 case PROJECTILE_ELECTRO:
25                         break; // electro uses no trail
26                 case PROJECTILE_ROCKET:
27                         trailparticles(self, particleeffectnum("TR_ROCKET"), oldorg, self.origin); // rocket
28                         break;
29                 case PROJECTILE_TAG:
30                         trailparticles(self, particleeffectnum("TR_VORESPIKE"), oldorg, self.origin); // seeker
31                         break;
32                 default:
33                         break;
34         }
35
36         self.renderflags = 0;
37
38         if(self.count & 0x80 || self.iflags & IFLAG_VALID)
39                 R_AddEntity(self);
40 }
41
42 void loopsound(entity e, float ch, string samp, float vol, float attn)
43 {
44         if(csqc_flags & CSQC_FLAG_COLORCODES)
45                 sound(e, ch, samp, vol, attn);
46 }
47
48 void Ent_RemoveProjectile()
49 {
50         if(self.cnt)
51                 loopsound(self, CHAN_PAIN, "misc/null.wav", VOL_BASE, ATTN_NORM);
52 }
53
54 void Ent_Projectile()
55 {
56         float f;
57         float sz;
58
59         InterpolateOrigin_Undo();
60
61         // projectile properties:
62         //   kind (interpolated, or clientside)
63         //
64         //   modelindex
65         //   origin
66         //   scale
67         //   if clientside:
68         //     velocity
69         //     gravity
70         //   soundindex (hardcoded list)
71         //   effects
72         //
73         // projectiles don't send angles, because they always follow the velocity
74         
75         f = ReadByte();
76         self.count = (f & 0xC0);
77         self.iflags = IFLAG_AUTOANGLES | IFLAG_ANGLES;
78         self.move_flags &~= FL_ONGROUND;
79
80         // sv_gameplayfix_delayprojectiles
81         if(!self.move_time)
82                 self.move_time = time + ticrate;
83         else
84                 self.move_time = max(self.move_time, time);
85
86         if(self.count & 0x80)
87                 InterpolateOrigin_Undo();
88
89         if(f & 1)
90         {
91                 self.origin_x = ReadCoord();
92                 self.origin_y = ReadCoord();
93                 self.origin_z = ReadCoord();
94                 if(self.count & 0x80)
95                 {
96                         self.velocity_x = ReadCoord();
97                         self.velocity_y = ReadCoord();
98                         self.velocity_z = ReadCoord();
99                         self.gravity = ReadCoord();
100
101                         self.move_origin = self.origin;
102                         self.move_velocity = self.velocity;
103                 }
104         }
105
106         if(f & 2)
107         {
108                 self.modelindex = ReadShort();
109                 if(f & 0x40)
110                 {
111                         self.scale = ReadByte() / 16.0;
112                         self.effects = ReadShort();
113                         self.effects |= 65536 * ReadByte();
114                 }
115                 else
116                 {
117                         self.scale = 1;
118                         self.effects = 0;
119                 }
120
121                 self.cnt = ReadShort();
122
123                 switch(self.cnt)
124                 {
125                         case PROJECTILE_ELECTRO:
126                                 // only new engines support sound moving with object
127                                 loopsound(self, CHAN_PAIN, "weapons/electro_fly.wav", VOL_BASE, ATTN_NORM);
128                                 self.mins = '0 0 -3';
129                                 self.maxs = '0 0 -3';
130                                 self.move_movetype = MOVETYPE_BOUNCE;
131                                 break;
132                         case PROJECTILE_ROCKET:
133                                 loopsound(self, CHAN_PAIN, "weapons/rocket_fly.wav", VOL_BASE, ATTN_NORM);
134                                 self.mins = '-3 -3 -3';
135                                 self.maxs = '3 3 3';
136                                 self.move_movetype = MOVETYPE_TOSS;
137                                 break;
138                         case PROJECTILE_TAG:
139                                 loopsound(self, CHAN_PAIN, "weapons/tag_rocket_fly.wav", VOL_BASE, ATTN_NORM);
140                                 self.mins = '-2 -2 -2';
141                                 self.maxs = '2 2 2';
142                                 self.move_movetype = MOVETYPE_TOSS;
143                                 break;
144                         default:
145                                 self.mins = '0 0 0';
146                                 self.maxs = '0 0 0';
147                                 self.move_movetype = MOVETYPE_TOSS;
148                                 break;
149                 }
150         }
151
152         if(self.count)
153                 InterpolateOrigin_Note();
154         
155         self.draw = Projectile_Draw;
156 }