]> icculus.org git repositories - divverent/nexuiz.git/blob - data/qcsrc/client/damage.qc
client projectiles: use a better way to find the trace normal
[divverent/nexuiz.git] / data / qcsrc / client / damage.qc
1 void Ent_DamageInfo()
2 {
3         float hittype, dmg, rad, edge, thisdmg;
4         vector force, org, thisforce;
5         entity oldself;
6
7         oldself = self;
8
9         hittype = ReadShort();
10         org_x = ReadCoord();
11         org_y = ReadCoord();
12         org_z = ReadCoord();
13
14         dmg = ReadByte();
15         rad = ReadByte();
16         edge = ReadByte();
17         force = decompressShortVector(ReadShort());
18
19         for(self = findradius(org, rad); self; self = self.chain)
20         {
21                 if(rad)
22                 {
23                         thisdmg = vlen(self.origin - org) / rad;
24                         if(thisdmg >= 1)
25                                 continue;
26                         thisdmg = dmg + (edge - dmg) * thisdmg;
27                         thisforce = vlen(force) * normalize(self.origin - org);
28                 }
29                 else
30                 {
31                         thisdmg = dmg;
32                         thisforce = force;
33                 }
34
35                 if(self.damageforcescale)
36                         if(vlen(thisforce))
37                         {
38                                 self.move_velocity = self.move_velocity + self.damageforcescale * thisforce;
39                                 self.move_flags &~= FL_ONGROUND;
40                         }
41
42                 if(self.event_damage)
43                         self.event_damage(thisdmg, hittype, org, thisforce);
44         }
45
46         self = oldself;
47
48         setorigin(self, org); // for sound() calls
49
50         // TODO spawn particle effects and sounds based on hittype
51         
52         if(!DEATH_ISSPECIAL(hittype))
53         {
54                 float hitwep, secondary, bounce, headshot;
55                 vector org2, backoff;
56                 float r;
57
58                 hitwep = DEATH_WEAPONOFWEAPONDEATH(hittype);
59                 secondary = hittype & HITTYPE_SECONDARY;
60                 bounce = hittype & HITTYPE_BOUNCE;
61                 headshot = hittype & HITTYPE_HEADSHOT;
62                 r = random();
63
64                 traceline(org - normalize(force) * 16, org + normalize(force) * 16, MOVE_NOMONSTERS, world);
65                 if(trace_fraction < 1)
66                         backoff = trace_plane_normal;
67                 else
68                         backoff = -1 * normalize(force);
69
70                 switch(hitwep)
71                 {
72                         case WEP_LASER:
73                                 org2 = org + backoff * 8;
74                                 pointparticles(particleeffectnum("laser_impact"), org2, backoff * 1000, 1);
75                                 sound (self, CHAN_PROJECTILE, "weapons/laserimpact.wav", VOL_BASE, ATTN_NORM);
76                                 break;
77                         case WEP_SHOTGUN:
78                                 pointparticles(particleeffectnum("shotgun_impact"), org, backoff * 1000, 1);
79                                 break;
80                         case WEP_UZI:
81                                 pointparticles(particleeffectnum("machinegun_impact"), org, backoff * 1000, 1);
82                                 break;
83                         case WEP_GRENADE_LAUNCHER:
84                                 org2 = org + backoff * 12;
85                                 pointparticles(particleeffectnum("grenade_explode"), org2, '0 0 0', 1);
86                                 sound (self, CHAN_PROJECTILE, "weapons/grenade_impact.wav", VOL_BASE, ATTN_NORM);
87                                 break;
88                         case WEP_ELECTRO:
89                                 org2 = org + backoff * 8;
90                                 if(secondary)
91                                 {
92                                         sound (self, CHAN_PROJECTILE, "weapons/electro_impact.wav", VOL_BASE, ATTN_NORM);
93                                         pointparticles(particleeffectnum("electro_ballexplode"), org2, '0 0 0', 1);
94                                 }
95                                 else
96                                 {
97                                         if(bounce)
98                                         {
99                                                 // this is sent as "primary bounce" to distinguish it from secondary bounced balls
100                                                 sound (self, CHAN_PROJECTILE, "weapons/electro_impact_combo.wav", VOL_BASE, ATTN_NORM);
101                                                 pointparticles(particleeffectnum("electro_combo"), org2, '0 0 0', 1);
102                                         }
103                                         else
104                                         {
105                                                 sound (self, CHAN_PROJECTILE, "weapons/electro_impact.wav", VOL_BASE, ATTN_NORM);
106                                                 pointparticles(particleeffectnum("electro_impact"), org2, '0 0 0', 1);
107                                         }
108                                 }
109                         case WEP_CRYLINK:
110                                 if(secondary)
111                                 {
112                                         sound (self, CHAN_PROJECTILE, "weapons/crylink_impact2.wav", VOL_BASE, ATTN_NORM);
113                                         pointparticles(particleeffectnum("crylink_impact"), org, '0 0 0', 1);
114                                 }
115                                 else
116                                 {
117                                         sound (self, CHAN_PROJECTILE, "weapons/crylink_impact.wav", VOL_BASE, ATTN_NORM);
118                                         pointparticles(particleeffectnum("crylink_impactbig"), org, '0 0 0', 1);
119                                 }
120                                 break;
121                         case WEP_NEX:
122                                 sound(self, CHAN_PROJECTILE, "weapons/neximpact.wav", VOL_BASE, ATTN_NORM);
123                                 pointparticles(particleeffectnum("nex_impact"), org - normalize(force) * 6, '0 0 0', 1);
124                                 break;
125                         case WEP_HAGAR:
126                                 org2 = org + backoff * 12;
127                                 if (r<0.15)
128                                         sound (self, CHAN_PROJECTILE, "weapons/hagexp1.wav", VOL_BASE, ATTN_NORM);
129                                 else if (r<0.7)
130                                         sound (self, CHAN_PROJECTILE, "weapons/hagexp2.wav", VOL_BASE, ATTN_NORM);
131                                 else
132                                         sound (self, CHAN_PROJECTILE, "weapons/hagexp3.wav", VOL_BASE, ATTN_NORM);
133                                 pointparticles(particleeffectnum("hagar_explode"), org2, '0 0 0', 1);
134                                 break;
135                         case WEP_ROCKET_LAUNCHER:
136                                 org2 = org + backoff * 16;
137                                 sound (self, CHAN_PROJECTILE, "weapons/rocket_impact.wav", VOL_BASE, ATTN_NORM);
138                                 pointparticles(particleeffectnum("rocket_explode"), org2, '0 0 0', 1);
139                                 break;
140                         case WEP_PORTO:
141                                 print("Since when does Porto send DamageInfo?\n");
142                                 break;
143                         case WEP_MINSTANEX:
144                                 sound(self, CHAN_PROJECTILE, "weapons/neximpact.wav", VOL_BASE, ATTN_NORM);
145                                 pointparticles(particleeffectnum("nex_impact"), org - normalize(force) * 6, '0 0 0', 1);
146                                 break;
147                         case WEP_HOOK:
148                                 org2 = org + backoff * 12;
149                                 sound (self, CHAN_PROJECTILE, "weapons/hookbomb_impact.wav", VOL_BASE, ATTN_NORM);
150                                 pointparticles(particleeffectnum("hookbomb_explode"), org2, '0 0 0', 1);
151                                 break;
152                         case WEP_SEEKER:
153                                 org2 = org + backoff * 12;
154                                 if(secondary)
155                                 {
156                                         if (r<0.15)
157                                                 sound (self, CHAN_PROJECTILE, "weapons/flacexp1.wav", 1, ATTN_NORM);
158                                         else if (r<0.7)
159                                                 sound (self, CHAN_PROJECTILE, "weapons/flacexp2.wav", 1, ATTN_NORM);
160                                         else
161                                                 sound (self, CHAN_PROJECTILE, "weapons/flacexp3.wav", 1, ATTN_NORM);
162                                         pointparticles(particleeffectnum("flac_explode"), org2, '0 0 0', 1);
163                                 }
164                                 else
165                                 {
166                                         if(bounce)
167                                         {
168                                                 if (r<0.15)
169                                                         sound (self, CHAN_PROJECTILE, "weapons/tagexp1.wav", 1, ATTN_NORM);
170                                                 else if (r<0.7)
171                                                         sound (self, CHAN_PROJECTILE, "weapons/tagexp2.wav", 1, ATTN_NORM);
172                                                 else
173                                                         sound (self, CHAN_PROJECTILE, "weapons/tagexp3.wav", 1, ATTN_NORM);
174                                                 pointparticles(particleeffectnum("hagar_explode"), org2, '0 0 0', 1);
175                                         }
176                                         else if(headshot)
177                                         {
178                                                 sound (self, CHAN_PROJECTILE, "weapons/tag_impact.wav", 1, ATTN_NORM);
179                                         }
180                                         else
181                                         {
182                                                 if (r<0.15)
183                                                         sound (self, CHAN_PROJECTILE, "weapons/seekerexp1.wav", 1, ATTN_NORM);
184                                                 else if (r<0.7)
185                                                         sound (self, CHAN_PROJECTILE, "weapons/seekerexp2.wav", 1, ATTN_NORM);
186                                                 else
187                                                         sound (self, CHAN_PROJECTILE, "weapons/seekerexp3.wav", 1, ATTN_NORM);
188                                                 pointparticles(particleeffectnum("hagar_explode"), org2, '0 0 0', 1);
189                                         }
190                                 }
191                                 break;
192                         case WEP_HLAC:
193                                 org2 = org + backoff * 12;
194                                 sound (self, CHAN_PROJECTILE, "weapons/laserimpact.wav", VOL_BASE, ATTN_NORM);
195                                 pointparticles(particleeffectnum("laser_impact"), org2, backoff * 1000, 1);
196                                 break;
197                         case WEP_CAMPINGRIFLE:
198                                 pointparticles(particleeffectnum("machinegun_impact"), org, backoff * 1000, 1);
199                                 break;
200                         default:
201                                 dprint("Unhandled damage of weapon ", ftos(hitwep), "\n");
202                                 break;
203                 }
204         }
205 }