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