30 qboolean
CanDamage(edict_t *targ, edict_t *inflictor)
37 VectorAdd(targ->absmin, targ->absmax, dest);
38 VectorScale(dest, 0.5, dest);
40 if (trace.fraction == 1.0)
42 if (trace.ent == targ)
48 if (trace.fraction == 1.0)
51 VectorCopy(targ->s.origin, dest);
55 if (trace.fraction == 1.0)
58 VectorCopy(targ->s.origin, dest);
62 if (trace.fraction == 1.0)
65 VectorCopy(targ->s.origin, dest);
69 if (trace.fraction == 1.0)
72 VectorCopy(targ->s.origin, dest);
76 if (trace.fraction == 1.0)
89 void Killed(edict_t *targ, edict_t *inflictor, edict_t *attacker,
int damage, vec3_t point)
91 if (targ->health < -999)
94 targ->enemy = attacker;
96 if ((targ->svflags & SVF_MONSTER) && (targ->deadflag !=
DEAD_DEAD)) {
100 if (
coop->value && attacker->client)
101 attacker->client->resp.score++;
103 if (strcmp(attacker->classname,
"monster_medic") == 0)
104 targ->owner = attacker;
110 targ->die(targ, inflictor, attacker, damage, point);
114 if ((targ->svflags & SVF_MONSTER) && (targ->deadflag !=
DEAD_DEAD)) {
119 targ->die(targ, inflictor, attacker, damage, point);
137 gi.multicast(
origin, MULTICAST_PVS);
165 static int CheckPowerArmor(edict_t *ent, vec3_t point, vec3_t normal,
int damage,
int dflags)
169 int power_armor_type;
179 client = ent->client;
190 power = client->pers.inventory[index];
192 }
else if (ent->svflags & SVF_MONSTER) {
193 power_armor_type = ent->monsterinfo.power_armor_type;
194 power = ent->monsterinfo.power_armor_power;
210 VectorSubtract(point, ent->s.origin, vec);
212 dot = DotProduct(vec,
forward);
217 pa_te_type = TE_SCREEN_SPARKS;
221 pa_te_type = TE_SHIELD_SPARKS;
222 damage = (2 * damage) / 3;
225 save = power * damagePerCell;
234 power_used = save / damagePerCell;
237 client->pers.inventory[index] -= power_used;
239 ent->monsterinfo.power_armor_power -= power_used;
243 static int CheckArmor(edict_t *ent, vec3_t point, vec3_t normal,
int damage,
int te_sparks,
int dflags)
253 client = ent->client;
271 if (save >= client->pers.inventory[index])
272 save = client->pers.inventory[index];
277 client->pers.inventory[index] -= save;
285 if (!(attacker->client) && !(attacker->svflags & SVF_MONSTER))
288 if (attacker == targ || attacker == targ->enemy)
294 if (attacker->client || (attacker->monsterinfo.aiflags &
AI_GOOD_GUY))
301 if (attacker->client) {
306 if (targ->enemy && targ->enemy->client) {
307 if (
visible(targ, targ->enemy)) {
308 targ->oldenemy = attacker;
311 targ->oldenemy = targ->enemy;
313 targ->enemy = attacker;
314 if (!(targ->monsterinfo.aiflags &
AI_DUCKED))
322 (strcmp(targ->classname, attacker->classname) != 0) &&
323 (strcmp(attacker->classname,
"monster_tank") != 0) &&
324 (strcmp(attacker->classname,
"monster_supertank") != 0) &&
325 (strcmp(attacker->classname,
"monster_makron") != 0) &&
326 (strcmp(attacker->classname,
"monster_jorg") != 0)) {
327 if (targ->enemy && targ->enemy->client)
328 targ->oldenemy = targ->enemy;
329 targ->enemy = attacker;
330 if (!(targ->monsterinfo.aiflags &
AI_DUCKED))
334 else if (attacker->enemy == targ) {
335 if (targ->enemy && targ->enemy->client)
336 targ->oldenemy = targ->enemy;
337 targ->enemy = attacker;
338 if (!(targ->monsterinfo.aiflags &
AI_DUCKED))
342 else if (attacker->enemy && attacker->enemy != targ) {
343 if (targ->enemy && targ->enemy->client)
344 targ->oldenemy = targ->enemy;
345 targ->enemy = attacker->enemy;
346 if (!(targ->monsterinfo.aiflags &
AI_DUCKED))
358 void T_Damage(edict_t *targ, edict_t *inflictor, edict_t *attacker, vec3_t dir, vec3_t point, vec3_t normal,
int damage,
int knockback,
int dflags,
int mod)
367 if (!targ->takedamage)
373 if ((targ != attacker) && ((
deathmatch->value && ((
int)(
dmflags->value) & (DF_MODELTEAMS | DF_SKINTEAMS))) ||
coop->value)) {
375 if ((
int)(
dmflags->value) & DF_NO_FRIENDLY_FIRE)
390 client = targ->client;
393 te_sparks = TE_BULLET_SPARKS;
395 te_sparks = TE_SPARKS;
400 if (!(dflags &
DAMAGE_RADIUS) && (targ->svflags & SVF_MONSTER) && (attacker->client) && (!targ->enemy) && (targ->health > 0))
417 if (targ->client && attacker == targ)
418 VectorScale(dir, 1600.0 * (
float)knockback / mass, kvel);
420 VectorScale(dir, 500.0 * (
float)knockback / mass, kvel);
422 VectorAdd(targ->velocity, kvel, targ->velocity);
438 if (targ->pain_debounce_time <
level.
time) {
439 gi.sound(targ, CHAN_ITEM,
gi.soundindex(
"items/protect4.wav"), 1, ATTN_NORM, 0);
440 targ->pain_debounce_time =
level.
time + 2;
449 asave =
CheckArmor(targ, point, normal, take, te_sparks, dflags);
461 if ((targ->svflags & SVF_MONSTER) || (client))
470 targ->health = targ->health - take;
472 if (targ->health <= 0) {
473 if ((targ->svflags & SVF_MONSTER) || (client))
475 Killed(targ, inflictor, attacker, take, point);
480 if (targ->svflags & SVF_MONSTER) {
482 if (!(targ->monsterinfo.aiflags &
AI_DUCKED) && (take)) {
483 targ->pain(targ, attacker, knockback, take);
485 if (
skill->value == 3)
486 targ->pain_debounce_time =
level.
time + 5;
490 targ->pain(targ, attacker, knockback, take);
493 targ->pain(targ, attacker, knockback, take);
500 client->damage_parmor += psave;
501 client->damage_armor += asave;
502 client->damage_blood += take;
503 client->damage_knockback += knockback;
504 VectorCopy(point, client->damage_from);
514 void T_RadiusDamage(edict_t *inflictor, edict_t *attacker,
float damage, edict_t *ignore,
float radius,
int mod)
521 while ((ent =
findradius(ent, inflictor->s.origin, radius)) != NULL) {
524 if (!ent->takedamage)
527 VectorAdd(ent->mins, ent->maxs, v);
528 VectorMA(ent->s.origin, 0.5, v, v);
529 VectorSubtract(inflictor->s.origin, v, v);
530 points = damage - 0.5 * VectorLength(v);
532 points = points * 0.5;
535 VectorSubtract(ent->s.origin, inflictor->s.origin, dir);