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