]> icculus.org git repositories - divverent/nexuiz.git/blob - qcsrc/gamec/g_damage.c
Some changes to the grenade launcher and shotgun that weren't my changes
[divverent/nexuiz.git] / qcsrc / gamec / g_damage.c
1
2 void Obituary (entity attacker, entity targ, float deathtype)
3 {
4         string  s;
5
6         if (targ.classname == "player" || targ.classname == "corpse")
7         {
8                 if (targ.classname == "corpse")
9                         s = "A corpse";
10                 else
11                         s = targ.netname;
12
13                 // Suicides
14                 if (targ == attacker)
15                 {
16                         if (deathtype == IT_LASER)
17                                 bprint (s, " was unable to resist the urge to self-immolate\n");
18                         else if (deathtype == IT_GRENADE_LAUNCHER)
19                                 bprint (s, " detonated\n");
20                         else if (deathtype == IT_ELECTRO)
21                                 bprint (s, " played with plasma\n");
22                         else if (deathtype == IT_HAGAR)
23                                 bprint (s, " should have used a different weapon\n");
24                         else if (deathtype == IT_ROCKET_LAUNCHER)
25                                 bprint (s, " exploded\n");
26                         else
27                                 bprint (s, " competes for the Darwin awards\n");
28
29                         self.frags = self.frags - 1;
30                 }
31                 // Kills
32                 else if (attacker.classname == "player")
33                 {
34                         if (deathtype == IT_LASER)
35                                 bprint (s, " was a victim of laser surgeon ", attacker.netname, "\n");
36                         else if (deathtype == IT_UZI)
37                                 bprint (s, " was riddled full of holes by ", attacker.netname, "\n");
38                         else if (deathtype == IT_SHOTGUN)
39                                 bprint (s, " was gunned by ", attacker.netname, "\n");
40                         else if (deathtype == IT_GRENADE_LAUNCHER)
41                                 bprint (s, " was blasted by ", attacker.netname, "\n");
42                         else if (deathtype == IT_ELECTRO)
43                                 bprint (s, " bathed in ", attacker.netname, "'s plasma\n");
44                         else if (deathtype == IT_CRYLINK)
45                                 bprint (s, " was zapped by ", attacker.netname, "\n");
46                         else if (deathtype == IT_NEX)
47                                 bprint (s, " sports a new hole from ", attacker.netname, "\n");
48                         else if (deathtype == IT_HAGAR)
49                                 bprint (s, " was pummeled by ", attacker.netname, "\n");
50                         else if (deathtype == IT_ROCKET_LAUNCHER)
51                                 bprint (s, " was given a lesson in rocketry by ", attacker.netname, "\n");
52                         else
53                                 bprint (s, " was killed by ", attacker.netname, "\n");
54
55                         attacker.frags = attacker.frags + 1;
56                 }
57                 else if (deathtype == DEATH_HURTTRIGGER)
58                         bprint (s, " ", attacker.message, "\n");
59                 else if (deathtype == DEATH_FALL)
60                         bprint (s, " hit the ground with a crunch\n");
61                 else if (deathtype == DEATH_BIGFALL)
62                         bprint (s, " fell into oblivion\n");
63                 else if (deathtype == DEATH_DROWN)
64                         bprint (s, " wished he had gills\n");
65                 else
66                         bprint (s, " died\n");
67         }
68 }
69
70 void Damage (entity targ, entity inflictor, entity attacker, float damage, float deathtype, vector hitloc, vector force)
71 {
72         local entity oldself;
73         oldself = self;
74         self = targ;
75         if (attacker.items & IT_STRENGTH)
76         {
77                 damage = damage * POWERUP_STRENGTH_DAMAGE;
78                 force = force * POWERUP_STRENGTH_FORCE;
79         }
80         if (targ.items & IT_INVINCIBLE)
81                 damage = damage * POWERUP_INVINCIBLE_TAKEDAMAGE;
82         // apply push
83         if (self.damageforcescale)
84         {
85                 self.velocity = self.velocity + self.damageforcescale * force;
86                 self.flags = self.flags - (self.flags & FL_ONGROUND);
87         }
88         // apply damage
89         if (self.event_damage)
90                 self.event_damage (inflictor, attacker, damage, deathtype, hitloc, force);
91         self = oldself;
92 }
93
94 void RadiusDamage (entity inflictor, entity attacker, float coredamage, float edgedamage, float rad, entity ignore, float forceintensity, float deathtype)
95 {
96         entity  targ;
97         float   finaldmg;
98         float   power;
99         vector  blastorigin;
100         vector  force;
101         vector  m1;
102         vector  m2;
103         vector  nearest;
104         vector  diff;
105
106         blastorigin = (inflictor.origin + (inflictor.mins + inflictor.maxs) * 0.5);
107
108         targ = findradius (blastorigin, rad);
109         while (targ)
110         {
111                 if (targ != inflictor)
112                         if (ignore != targ)
113                         {
114                                 // LordHavoc: measure distance to nearest point on target (not origin)
115                                 // (this guarentees 100% damage on a touch impact)
116                                 nearest = blastorigin;
117                                 m1 = targ.origin + targ.mins;
118                                 m2 = targ.origin + targ.maxs;
119                                 if (nearest_x < m1_x) nearest_x = m1_x;
120                                 if (nearest_y < m1_y) nearest_y = m1_y;
121                                 if (nearest_z < m1_z) nearest_z = m1_z;
122                                 if (nearest_x > m2_x) nearest_x = m2_x;
123                                 if (nearest_y > m2_y) nearest_y = m2_y;
124                                 if (nearest_z > m2_z) nearest_z = m2_z;
125                                 diff = nearest - blastorigin;
126                                 // round up a little on the damage to ensure full damage on impacts
127                                 // and turn the distance into a fraction of the radius
128                                 power = 1 - ((vlen (diff) - 2) / rad);
129                                 //bprint(" ");
130                                 //bprint(ftos(power));
131                                 if (power > 0)
132                                 {
133                                         if (power > 1)
134                                                 power = 1;
135                                         finaldmg = coredamage * power + edgedamage * (1 - power);
136                                         force = normalize(diff) * (finaldmg / coredamage) * forceintensity;
137                                         if (targ == attacker)
138                                                 finaldmg = finaldmg * 0.6;      // Partial damage if the attacker hits himself
139                                         if (finaldmg > 0)
140                                                 Damage (targ, inflictor, attacker, finaldmg, deathtype, inflictor.origin, force);
141                                 }
142                         }
143                 targ = targ.chain;
144         }
145 }
146
147 /*
148 entity  multi_ent;
149 float   multi_damage;
150 vector  multi_force;
151
152 void ClearMultiDamage (void)
153 {
154         multi_ent = world;
155         multi_damage = 0;
156         multi_force = '0 0 0';
157 }
158
159 void ApplyMultiDamage (void)
160 {
161         if (!multi_ent)
162                 return;
163
164         Damage (self, multi_ent.origin, multi_ent, 0, multi_damage, multi_force);
165 }
166
167 void AddMultiDamage (entity hit, float damage, vector force)
168 {
169         if (!hit)
170                 return;
171
172         if (hit != multi_ent)
173         {
174                 ApplyMultiDamage ();
175                 ClearMultiDamage ();
176                 multi_ent = hit;
177         }
178         multi_damage = multi_damage + damage;
179         multi_force = multi_force + force;
180 }
181
182 void FireBullets (float shotcount, vector dir, vector spread, float deathtype)
183 {
184         vector  direction;
185         vector  source;
186         vector  vel;
187         vector  org;
188
189         makevectors (self.v_angle);
190
191         source = self.origin + v_forward * 10;  // FIXME
192         source_x = self.absmin_z + self.size_z * 0.7;   // ??? whaddabout view_ofs
193
194         // LordHavoc: better to use normal damage
195         //ClearMultiDamage ();
196         while (shotcount > 0)
197         {
198                 direction = dir + crandom () * spread_x * v_right + crandom () * spread_y * v_up;
199
200                 traceline (source, source + direction * 2048, FALSE, self);
201                 if (trace_fraction != 1.0)
202                 {
203                         vel = normalize (direction + v_up * crandom () + v_right * crandom ());
204                         vel = vel + 2 * trace_plane_normal;
205                         vel = vel * 200;
206
207                         org = trace_endpos - direction * 4;
208
209                         if (!trace_ent.takedamage)
210                                 te_gunshot (org);
211                         // LordHavoc: better to use normal damage
212                         //AddMultiDamage (trace_ent, 4, direction * 4);
213                         Damage (trace_ent, self, self, 4, deathtype, trace_endpos, direction * 4);
214                 }
215
216                 shotcount = shotcount + 1;
217         }
218
219         // LordHavoc: better to use normal damage
220         //ApplyMultiDamage ();
221 }
222 */