move projectile explosions including precaching into w_*.qc; client/damage.qc now...
[xonotic/xonotic-data.pk3dir.git] / qcsrc / client / damage.qc
1 .float silent;
2
3 float w_deathtype, w_issilent, w_random;
4 vector w_org, w_backoff;
5
6 void Ent_DamageInfo(float isNew)
7 {
8         float dmg, rad, edge, thisdmg, forcemul;
9         vector force, thisforce;
10         entity oldself;
11
12         oldself = self;
13
14         w_deathtype = ReadShort();
15         w_issilent = (w_deathtype & 0x8000);
16         w_deathtype = (w_deathtype & 0x7FFF);
17
18         w_org_x = ReadCoord();
19         w_org_y = ReadCoord();
20         w_org_z = ReadCoord();
21
22         dmg = ReadByte();
23         rad = ReadByte();
24         edge = ReadByte();
25         force = decompressShortVector(ReadShort());
26
27         if not(isNew)
28                 return;
29
30         if(rad < 0)
31         {
32                 rad = -rad;
33                 forcemul = -1;
34         }
35         else
36                 forcemul = 1;
37         
38         for(self = findradius(w_org, rad); self; self = self.chain)
39         {
40                 if(rad)
41                 {
42                         thisdmg = vlen(self.origin - w_org) / rad;
43                         if(thisdmg >= 1)
44                                 continue;
45                         if(dmg)
46                         {
47                                 thisdmg = dmg + (edge - dmg) * thisdmg;
48                                 thisforce = forcemul * vlen(force) * (thisdmg / dmg) * normalize(self.origin - w_org);
49                         }
50                         else
51                         {
52                                 thisdmg = 0;
53                                 thisforce = forcemul * vlen(force) * normalize(self.origin - w_org);
54                         }
55                 }
56                 else
57                 {
58                         thisdmg = dmg;
59                         thisforce = forcemul * force;
60                 }
61
62                 //print("check ", ftos(num_for_edict(self)), " ", self.classname, "\n");
63                 //print(ftos(self.damageforcescale), "\n");
64                 //print(vtos(thisforce), "\n");
65                 if(self.damageforcescale)
66                         if(vlen(thisforce))
67                         {
68                                 self.move_velocity = self.move_velocity + self.damageforcescale * thisforce;
69                                 self.move_flags &~= FL_ONGROUND;
70                                 //print("pushed ", ftos(num_for_edict(self)), " loose\n");
71                         }
72
73                 if(w_issilent)
74                         self.silent = 1;
75
76                 if(self.event_damage)
77                         self.event_damage(thisdmg, w_deathtype, w_org, thisforce);
78         }
79
80         self = oldself;
81
82         // TODO spawn particle effects and sounds based on w_deathtype
83         
84         if(!DEATH_ISSPECIAL(w_deathtype))
85         {
86                 float hitwep;
87
88                 hitwep = DEATH_WEAPONOFWEAPONDEATH(w_deathtype);
89                 w_random = prandom();
90
91                 traceline(w_org - normalize(force) * 16, w_org + normalize(force) * 16, MOVE_NOMONSTERS, world);
92                 if(trace_fraction < 1 && hitwep != WEP_NEX && hitwep != WEP_MINSTANEX)
93                         w_backoff = trace_plane_normal;
94                 else
95                         w_backoff = -1 * normalize(force);
96                 setorigin(self, w_org + w_backoff * 2); // for sound() calls
97
98                 (get_weaponinfo(hitwep)).weapon_func(WR_IMPACTEFFECT);
99         }
100 }
101
102 void DamageInfo_Precache()
103 {
104         float i;
105         for(i = WEP_FIRST; i <= WEP_LAST; ++i)
106                 (get_weaponinfo(i)).weapon_func(WR_PRECACHE);
107 }