void Cmd_Bandage_f(edict_t * ent) { if ((ent->client->bleeding != 0 || ent->client->leg_damage != 0) && ent->client->bandaging != 1) ent->client->reload_attempts = 0; // prevent any further reloading if ((ent->client->weaponstate == WEAPON_READY || ent->client->weaponstate == WEAPON_END_MAG) && (ent->client->bleeding != 0 || ent->client->leg_damage != 0) && ent->client->bandaging != 1) { // zucc - check if they have a primed grenade if (ent->client->curr_weap == GRENADE_NUM && ((ent->client->ps.gunframe >= GRENADE_IDLE_FIRST && ent->client->ps.gunframe <= GRENADE_IDLE_LAST) || (ent->client->ps.gunframe >= GRENADE_THROW_FIRST && ent->client->ps.gunframe <= GRENADE_THROW_LAST))) { int damage; ent->client->ps.gunframe = 0; if (use_classic->value) damage = 170; else damage = GRENADE_DAMRAD; if(ent->client->quad_framenum > level.framenum) damage *= 1.5f; fire_grenade2(ent, ent->s.origin, vec3_origin, damage, 0, 2, damage * 2, false); INV_AMMO(ent, GRENADE_NUM)--; if (INV_AMMO(ent, GRENADE_NUM) <= 0) { ent->client->newweapon = GET_ITEM(MK23_NUM); } } ent->client->bandaging = 1; ent->client->resp.sniper_mode = SNIPER_1X; ent->client->ps.fov = 90; ent->client->desired_fov = 90; if (ent->client->pers.weapon) ent->client->ps.gunindex = gi.modelindex(ent->client->pers.weapon->view_model); gi.cprintf(ent, PRINT_HIGH, "You've started bandaging\n"); } else if (ent->client->bandaging == 1) gi.cprintf(ent, PRINT_HIGH, "Already bandaging\n"); //FIREBLADE 12/26/98 - fix inappropriate message else if (ent->client->bleeding == 0 && ent->client->leg_damage == 0) gi.cprintf(ent, PRINT_HIGH, "No need to bandage\n"); else gi.cprintf(ent, PRINT_HIGH, "Can't bandage now\n"); //FIREBLADE }
void Cmd_IR_f(edict_t * ent) { int band = 0; if (!ir->value) { gi.cprintf(ent, PRINT_HIGH, "IR vision not enabled on this server.\n"); return; } if (INV_AMMO(ent, BAND_NUM)) band = 1; if (ent->client->resp.ir == 0) { ent->client->resp.ir = 1; if (band) gi.cprintf(ent, PRINT_HIGH, "IR vision disabled.\n"); else gi.cprintf(ent, PRINT_HIGH, "IR vision will be disabled when you get a bandolier.\n"); } else { ent->client->resp.ir = 0; if (band) gi.cprintf(ent, PRINT_HIGH, "IR vision enabled.\n"); else gi.cprintf(ent, PRINT_HIGH, "IR vision will be enabled when you get a bandolier.\n"); } }
/* =============== G_SetClientEvent =============== */ void G_SetClientEvent (edict_t * ent) { if (ent->s.event) return; if (ent->groundentity && xyspeed > 225) { //zucc added item check to see if they have slippers if ((int)(current_client->bobtime + bobmove) != bobcycle && !INV_AMMO(ent, SLIP_NUM)) ent->s.event = EV_FOOTSTEP; } }
void SP_LaserSight(edict_t * self, gitem_t * item) { vec3_t start, forward, right, end; if (!INV_AMMO(self, LASER_NUM)) { if (self->lasersight) { // laser is on G_FreeEdict(self->lasersight); self->lasersight = NULL; } return; } //zucc code to make it be used with the right weapons switch (self->client->curr_weap) { case MK23_NUM: case MP5_NUM: case M4_NUM: break; default: // laser is on but we want it off if (self->lasersight) { G_FreeEdict(self->lasersight); self->lasersight = NULL; } return; } AngleVectors(self->client->v_angle, forward, right, NULL); VectorSet(end, 100, 0, 0); G_ProjectSource(self->s.origin, end, forward, right, start); self->lasersight = G_Spawn(); self->lasersight->owner = self; self->lasersight->movetype = MOVETYPE_NOCLIP; self->lasersight->solid = SOLID_NOT; self->lasersight->classname = "lasersight"; self->lasersight->s.modelindex = gi.modelindex("sprites/lsight.sp2"); self->lasersight->s.renderfx = RF_TRANSLUCENT; self->lasersight->think = LaserSightThink; self->lasersight->nextthink = level.time + 0.01; }
void DeadDropSpec(edict_t * ent) { gitem_t *spec; edict_t *dropped; int i; for(i = 0; i<ITEM_COUNT; i++) { if (INV_AMMO(ent, tnums[i]) > 0) { spec = GET_ITEM(tnums[i]); dropped = Drop_Item(ent, spec); // hack the velocity to make it bounce random dropped->velocity[0] = (rand() % 600) - 300; dropped->velocity[1] = (rand() % 600) - 300; dropped->nextthink = level.time + 1; dropped->think = MakeTouchSpecThink; dropped->owner = NULL; dropped->spawnflags = DROPPED_PLAYER_ITEM; ent->client->pers.inventory[ITEM_INDEX(spec)] = 0; } } }
void DeadDropSpec(edict_t * ent) { gitem_t *spec; edict_t *dropped; int i, itemNum; for(i = 0; i<ITEM_COUNT; i++) { itemNum = ITEM_FIRST + i; if (INV_AMMO(ent, itemNum) > 0) { spec = GET_ITEM(itemNum); dropped = Drop_Item(ent, spec); // hack the velocity to make it bounce random dropped->velocity[0] = (rand() % 600) - 300; dropped->velocity[1] = (rand() % 600) - 300; dropped->nextthink = level.framenum + 1 * HZ; dropped->think = MakeTouchSpecThink; dropped->owner = NULL; dropped->spawnflags = DROPPED_PLAYER_ITEM; ent->client->inventory[ITEM_INDEX(spec)] = 0; } } }
/* ================= P_FallingDamage ================= */ void P_FallingDamage (edict_t * ent) { float delta; int damage; vec3_t dir; if (lights_camera_action || ent->client->ctf_uvtime > 0) return; if (ent->s.modelindex != 255) return; // not in the player model if (ent->movetype == MOVETYPE_NOCLIP) return; if ((ent->client->oldvelocity[2] < 0) && (ent->velocity[2] > ent->client->oldvelocity[2]) && (!ent->groundentity)) { delta = ent->client->oldvelocity[2]; } else { if (!ent->groundentity) return; delta = ent->velocity[2] - ent->client->oldvelocity[2]; ent->client->jumping = 0; } delta = delta * delta * 0.0001; // never take damage if just release grapple or on grapple if (level.time - ent->client->ctf_grapplereleasetime <= FRAMETIME * 2 || (ent->client->ctf_grapple && ent->client->ctf_grapplestate > CTF_GRAPPLE_STATE_FLY)) return; // never take falling damage if completely underwater if (ent->waterlevel == 3) return; else if (ent->waterlevel == 2) delta *= 0.25; else if (ent->waterlevel == 1) delta *= 0.5; if (delta < 1) return; if (delta < 15) { // zucc look for slippers to avoid noise if(!INV_AMMO(ent, SLIP_NUM)) ent->s.event = EV_FOOTSTEP; return; } ent->client->fall_value = delta * 0.5; if (ent->client->fall_value > 40) ent->client->fall_value = 40; ent->client->fall_time = level.time + FALL_TIME; if (delta <= 30) { //zucc added check for slippers, this is just another noise if(!INV_AMMO(ent, SLIP_NUM)) ent->s.event = EV_FALLSHORT; return; } /* when fall damage is disabled, play the normal fall sound */ if((int) dmflags->value & DF_NO_FALLING) { ent->s.event = EV_FALLSHORT; return; } if (ent->health > 0) { if (delta >= 55) ent->s.event = EV_FALLFAR; else // all falls are far ent->s.event = EV_FALLFAR; } ent->pain_debounce_time = level.time; // no normal pain sound if (!deathmatch->value || !((int) dmflags->value & DF_NO_FALLING)) { damage = (int) (((delta - 30) / 2)); if (damage < 1) damage = 1; // zucc scale this up damage *= 10; VectorSet (dir, 0, 0, 1); T_Damage (ent, world, world, dir, ent->s.origin, vec3_origin, damage, 0, 0, MOD_FALLING); } }
/* ============= SV_CalcBlend ============= */ void SV_CalcBlend (edict_t * ent) { int contents; vec3_t vieworg; int remaining; // enable ir vision if appropriate if (ir->value) { if ((INV_AMMO(ent, BAND_NUM) && ent->client->resp.ir == 0) || (ent->client->chase_target != NULL && ent->client->chase_target->client != NULL && ent->client->chase_mode == 2 && ent->client->chase_target->client->resp.ir == 0 && INV_AMMO(ent->client->chase_target, BAND_NUM))) { ent->client->ps.rdflags |= RDF_IRGOGGLES; } else { ent->client->ps.rdflags &= ~RDF_IRGOGGLES; } } ent->client->ps.blend[0] = ent->client->ps.blend[1] = ent->client->ps.blend[2] = ent->client->ps.blend[3] = 0; // add for contents VectorAdd (ent->s.origin, ent->client->ps.viewoffset, vieworg); contents = gi.pointcontents (vieworg); if (contents & (CONTENTS_LAVA | CONTENTS_SLIME | CONTENTS_WATER)) ent->client->ps.rdflags |= RDF_UNDERWATER; else ent->client->ps.rdflags &= ~RDF_UNDERWATER; if (contents & (CONTENTS_SOLID | CONTENTS_LAVA)) SV_AddBlend (1.0f, 0.3f, 0.0f, 0.6f, ent->client->ps.blend); else if (contents & CONTENTS_SLIME) SV_AddBlend (0.0f, 0.1f, 0.05f, 0.6f, ent->client->ps.blend); else if (contents & CONTENTS_WATER) SV_AddBlend (0.5f, 0.3f, 0.2f, 0.4f, ent->client->ps.blend); // AQ2:TNG - Igor[Rock] adding new irvision mode if (new_irvision->value && (ent->client->resp.ir == 0) && INV_AMMO(ent, BAND_NUM)) { SV_AddBlend (0.1f, 0.0f, 0.0f, 0.4f, ent->client->ps.blend); } // AQ2:TNG end of new irvision mode // add for powerups if (ent->client->quad_framenum > level.framenum) { remaining = ent->client->quad_framenum - level.framenum; if (remaining == 30) // beginning to fade gi.sound (ent, CHAN_ITEM, gi.soundindex("items/damage2.wav"), 1, ATTN_NORM, 0); if (remaining > 30 || (remaining & 4)) SV_AddBlend (0, 0, 1, 0.08f, ent->client->ps.blend); } else if (ent->client->invincible_framenum > level.framenum) { remaining = ent->client->invincible_framenum - level.framenum; if (remaining == 30) // beginning to fade gi.sound (ent, CHAN_ITEM, gi.soundindex("items/protect2.wav"), 1, ATTN_NORM, 0); if (remaining > 30 || (remaining & 4)) SV_AddBlend (1, 1, 0, 0.08f, ent->client->ps.blend); } else if (ent->client->enviro_framenum > level.framenum) { remaining = ent->client->enviro_framenum - level.framenum; if (remaining == 30) // beginning to fade gi.sound (ent, CHAN_ITEM, gi.soundindex("items/airout.wav"), 1, ATTN_NORM, 0); if (remaining > 30 || (remaining & 4)) SV_AddBlend (0, 1, 0, 0.08f, ent->client->ps.blend); } else if (ent->client->breather_framenum > level.framenum) { remaining = ent->client->breather_framenum - level.framenum; if (remaining == 30) // beginning to fade gi.sound (ent, CHAN_ITEM, gi.soundindex ("items/airout.wav"), 1, ATTN_NORM, 0); if (remaining > 30 || (remaining & 4)) SV_AddBlend (0.4f, 1, 0.4f, 0.04f, ent->client->ps.blend); } // add for damage if (ent->client->damage_alpha > 0) SV_AddBlend (ent->client->damage_blend[0], ent->client->damage_blend[1], ent->client->damage_blend[2], ent->client->damage_alpha, ent->client->ps.blend); if (ent->client->bonus_alpha > 0) SV_AddBlend (0.85f, 0.7f, 0.3f, ent->client->bonus_alpha, ent->client->ps.blend); // drop the damage value ent->client->damage_alpha -= 0.06f; if (ent->client->damage_alpha < 0) ent->client->damage_alpha = 0; // drop the bonus value ent->client->bonus_alpha -= 0.1f; if (ent->client->bonus_alpha < 0) ent->client->bonus_alpha = 0; }
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) { gclient_t *client; char buf[256]; int take, save; int asave, psave; int te_sparks, do_sparks = 0; int damage_type = 0; // used for MOD later int bleeding = 0; // damage causes bleeding int head_success = 0; int instant_dam = 1; float z_rel; int height; float from_top; vec_t dist; float targ_maxs2; //FB 6/1/99 // do this before teamplay check if (!targ->takedamage) return; //FIREBLADE if (teamplay->value && mod != MOD_TELEFRAG) { if (lights_camera_action) return; // AQ2:TNG - JBravo adding UVtime if (ctf->value && targ->client) { if(targ->client->ctf_uvtime > 0) return; if (attacker->client && attacker->client->ctf_uvtime > 0) return; } // AQ2:TNG - JBravo adding FF after rounds if (targ != attacker && targ->client && attacker->client && targ->client->resp.team == attacker->client->resp.team && ((int)(dmflags->value) & (DF_NO_FRIENDLY_FIRE))) { if (team_round_going) return; else if (!ff_afterround->value) return; } // AQ:TNG } //FIREBLADE if (dm_shield->value && targ->client) { if (targ->client->ctf_uvtime > 0) return; if (attacker->client && attacker->client->ctf_uvtime > 0) return; } // damage reduction for shotgun // if far away, reduce it to original action levels if (mod == MOD_M3) { dist = Distance(targ->s.origin, inflictor->s.origin); if (dist > 450.0) damage = damage - 2; } targ_maxs2 = targ->maxs[2]; if (targ_maxs2 == 4) targ_maxs2 = CROUCHING_MAXS2; //FB 6/1/99 height = abs (targ->mins[2]) + targ_maxs2; // locational damage code // base damage is head shot damage, so all the scaling is downwards if (targ->client) { if (!((targ != attacker) && ((deathmatch->value && ((int)dmflags->value & (DF_MODELTEAMS | DF_SKINTEAMS))) || coop->value) && (attacker && attacker->client && OnSameTeam (targ, attacker) && ((int)dmflags->value & DF_NO_FRIENDLY_FIRE) && (team_round_going && ff_afterround->value)))) { // TNG Stats - Add +1 to hit, make sure that hc and m3 are handles differently if ((attacker->client) && (mod != MOD_M3) && (mod != MOD_HC)) { strcpy(attacker->client->resp.last_damaged_players, targ->client->pers.netname); if (!teamplay->value || team_round_going || stats_afterround->value) { attacker->client->resp.stats_hits[mod]++; attacker->client->resp.stats_shots_h++; } } // TNG Stats END if (mod == MOD_MK23 || mod == MOD_MP5 || mod == MOD_M4 || mod == MOD_SNIPER || mod == MOD_DUAL || mod == MOD_KNIFE || mod == MOD_KNIFE_THROWN) { z_rel = point[2] - targ->s.origin[2]; from_top = targ_maxs2 - z_rel; if (from_top < 0.0) //FB 6/1/99 from_top = 0.0; //Slightly negative values were being handled wrong bleeding = 1; instant_dam = 0; // damage reduction for longer range pistol shots if (mod == MOD_MK23 || mod == MOD_DUAL) { dist = Distance(targ->s.origin, inflictor->s.origin); if (dist > 600.0 && dist < 1400.0) damage = (int) (damage * 2 / 3); else if (dist > 1400.0) damage = (int) (damage * 1 / 2); } //gi.cprintf(targ, PRINT_HIGH, "z_rel is %f\n leg: %f stomach: %f chest: %f\n", z_rel, LEG_DAMAGE, STOMACH_DAMAGE, CHEST_DAMAGE ); //gi.cprintf(targ, PRINT_HIGH, "point[2]: %f targ->s.origin[2]: %f height: %d\n", point[2], targ->s.origin[2], height ); //gi.cprintf(targ, PRINT_HIGH, "abs(trag->min[2]): %d targ_max[2] %d\n", (int)abs(targ->mins[2]), (int)targ_maxs2); //gi.cprintf(attacker, PRINT_HIGH, "abs(trag->min[2]): %d targ_max[2] %d\n", (int)abs(targ->mins[2]), (int)targ_maxs2); //gi.cprintf(attacker, PRINT_HIGH, "abs(trag->min[0]): %d targ_max[0] %d\n", (int)abs(targ->mins[0]), (int)targ->maxs[0]); //gi.cprintf(attacker, PRINT_HIGH, "abs(trag->min[1]): %d targ_max[1] %d\n", (int)abs(targ->mins[1]), (int)targ->maxs[1]); if (from_top < 2 * HEAD_HEIGHT) { vec3_t new_point; VerifyHeadShot (point, dir, HEAD_HEIGHT, new_point); VectorSubtract (new_point, targ->s.origin, new_point); //gi.cprintf(attacker, PRINT_HIGH, "z: %d y: %d x: %d\n", (int)(targ_maxs2 - new_point[2]),(int)(new_point[1]) , (int)(new_point[0]) ); if ((targ_maxs2 - new_point[2]) < HEAD_HEIGHT && (abs (new_point[1])) < HEAD_HEIGHT * .8 && (abs (new_point[0])) < HEAD_HEIGHT * .8) { head_success = 1; } } if (head_success) { if (attacker->client) { if (!teamplay->value || team_round_going || stats_afterround->value) { attacker->client->resp.stats_headshot[mod]++; } //AQ2:TNG Slicer Last Damage Location if (INV_AMMO(targ, HELM_NUM)) { attacker->client->resp.last_damaged_part = LOC_KVLR_HELMET; if ((!teamplay->value || team_round_going || stats_afterround->value)) attacker->client->resp.stats_locations[LOC_KVLR_HELMET]++; } else { attacker->client->resp.last_damaged_part = LOC_HDAM; if ((!teamplay->value || team_round_going || stats_afterround->value)) attacker->client->resp.stats_locations[LOC_HDAM]++; } //AQ2:TNG END if (!OnSameTeam (targ, attacker)) attacker->client->resp.hs_streak++; // AQ:TNG Igor[Rock] changing sound dir if (attacker->client->resp.hs_streak == 3) { if (use_rewards->value) { sprintf (buf, "ACCURACY %s!", attacker->client->pers.netname); CenterPrintAll (buf); gi.sound (&g_edicts[0], CHAN_VOICE | CHAN_NO_PHS_ADD, gi.soundindex ("tng/accuracy.wav"), 1.0, ATTN_NONE, 0.0); } attacker->client->resp.hs_streak = 0; } // end of changing sound dir } if (INV_AMMO(targ, HELM_NUM) && mod != MOD_KNIFE && mod != MOD_KNIFE_THROWN && mod != MOD_SNIPER) { if (attacker->client) { gi.cprintf (attacker, PRINT_HIGH, "%s has a Kevlar Helmet - AIM FOR THE BODY!\n", targ->client->pers.netname); gi.cprintf (targ, PRINT_HIGH, "Kevlar Helmet absorbed a part of %s's shot\n", attacker->client->pers.netname); } gi.sound (targ, CHAN_ITEM, gi.soundindex("misc/vest.wav"), 1, ATTN_NORM, 0); damage = (int) (damage / 2); damage_type = LOC_HDAM; bleeding = 0; instant_dam = 1; stopAP = 1; do_sparks = 1; } else if (INV_AMMO(targ, HELM_NUM) && mod == MOD_SNIPER) { if (attacker->client) { gi.cprintf (attacker, PRINT_HIGH, "%s has a Kevlar Helmet, too bad you have AP rounds...\n", targ->client->pers.netname); gi.cprintf (targ, PRINT_HIGH, "Kevlar Helmet absorbed some of %s's AP sniper round\n", attacker->client->pers.netname); } damage = (int) (damage * 0.325); gi.sound (targ, CHAN_VOICE, gi.soundindex("misc/headshot.wav"), 1, ATTN_NORM, 0); damage_type = LOC_HDAM; } else { damage = damage * 1.8 + 1; gi.cprintf (targ, PRINT_HIGH, "Head damage\n"); if (attacker->client) gi.cprintf (attacker, PRINT_HIGH, "You hit %s in the head\n", targ->client->pers.netname); damage_type = LOC_HDAM; if (mod != MOD_KNIFE && mod != MOD_KNIFE_THROWN) gi.sound (targ, CHAN_VOICE, gi.soundindex ("misc/headshot.wav"), 1, ATTN_NORM, 0); //else // gi.sound(targ, CHAN_VOICE, gi.soundindex("misc/glurp.wav"), 1, ATTN_NORM, 0); } } else if (z_rel < LEG_DAMAGE) { damage = damage * .25; gi.cprintf (targ, PRINT_HIGH, "Leg damage\n"); if (attacker->client) { attacker->client->resp.hs_streak = 0; gi.cprintf (attacker, PRINT_HIGH, "You hit %s in the legs\n", targ->client->pers.netname); } damage_type = LOC_LDAM; if (!heroes->value || targ->client->resp.team == 2) { // ESJ Heroes don't run out targ->client->leg_damage = 1; targ->client->leghits++; } //AQ2:TNG Slicer Last Damage Location attacker->client->resp.last_damaged_part = LOC_LDAM; //AQ2:TNG END if (!teamplay->value || team_round_going || stats_afterround->value) attacker->client->resp.stats_locations[LOC_LDAM]++; // TNG Stats } else if (z_rel < STOMACH_DAMAGE) { damage = damage * .4; gi.cprintf (targ, PRINT_HIGH, "Stomach damage\n"); if (attacker->client) { attacker->client->resp.hs_streak = 0; gi.cprintf (attacker, PRINT_HIGH, "You hit %s in the stomach\n", targ->client->pers.netname); } damage_type = LOC_SDAM; //TempFile bloody gibbing if (mod == MOD_SNIPER && sv_gib->value) ThrowGib (targ, "models/objects/gibs/sm_meat/tris.md2", damage, GIB_ORGANIC); //AQ2:TNG Slicer Last Damage Location attacker->client->resp.last_damaged_part = LOC_SDAM; //AQ2:TNG END if (!teamplay->value || team_round_going || stats_afterround->value) attacker->client->resp.stats_locations[LOC_SDAM]++; // TNG Stats } else //(z_rel < CHEST_DAMAGE) { if (attacker->client) { attacker->client->resp.hs_streak = 0; } if (INV_AMMO(targ, KEV_NUM) && mod != MOD_KNIFE && mod != MOD_KNIFE_THROWN && mod != MOD_SNIPER) { if (attacker->client) { gi.cprintf (attacker, PRINT_HIGH, "%s has a Kevlar Vest - AIM FOR THE HEAD!\n", targ->client->pers.netname); gi.cprintf (targ, PRINT_HIGH, "Kevlar Vest absorbed most of %s's shot\n", attacker->client->pers.netname); /* if (IsFemale(targ)) gi.cprintf(attacker, PRINT_HIGH, "You bruised %s through her Kevlar Vest\n", targ->client->pers.netname); else gi.cprintf(attacker, PRINT_HIGH, "You bruised %s through his Kevlar Vest\n", targ->client->pers.netname); */ } gi.sound (targ, CHAN_ITEM, gi.soundindex ("misc/vest.wav"), 1, ATTN_NORM, 0); damage = (int) (damage / 10); damage_type = LOC_CDAM; bleeding = 0; instant_dam = 1; stopAP = 1; do_sparks = 1; } else if (INV_AMMO(targ, KEV_NUM) && mod == MOD_SNIPER) { if (attacker->client) { gi.cprintf (attacker, PRINT_HIGH, "%s has a Kevlar Vest, too bad you have AP rounds...\n", targ->client->pers.netname); gi.cprintf (targ, PRINT_HIGH, "Kevlar Vest absorbed some of %s's AP sniper round\n", attacker->client->pers.netname); } damage = damage * .325; damage_type = LOC_CDAM; } else { damage = damage * .65; gi.cprintf (targ, PRINT_HIGH, "Chest damage\n"); if (attacker->client) gi.cprintf (attacker, PRINT_HIGH, "You hit %s in the chest\n", targ->client->pers.netname); damage_type = LOC_CDAM; //TempFile bloody gibbing if (mod == MOD_SNIPER && sv_gib->value) ThrowGib (targ, "models/objects/gibs/sm_meat/tris.md2", damage, GIB_ORGANIC); } //AQ2:TNG Slicer Last Damage Location if (INV_AMMO(targ, KEV_NUM) && mod != MOD_KNIFE && mod != MOD_KNIFE_THROWN) { attacker->client->resp.last_damaged_part = LOC_KVLR_VEST; if (!teamplay->value || team_round_going || stats_afterround->value) attacker->client->resp.stats_locations[LOC_KVLR_VEST]++; // TNG Stats } else { attacker->client->resp.last_damaged_part = LOC_CDAM; if (!teamplay->value || team_round_going || stats_afterround->value) attacker->client->resp.stats_locations[LOC_CDAM]++; // TNG Stats } //AQ2:TNG END } /*else { // no mod to damage gi.cprintf(targ, PRINT_HIGH, "Head damage\n"); if (attacker->client) gi.cprintf(attacker, PRINT_HIGH, "You hit %s in the head\n", targ->client->pers.netname); damage_type = LOC_HDAM; gi.sound(targ, CHAN_VOICE, gi.soundindex("misc/headshot.wav"), 1, ATTN_NORM, 0); } */ } if (team_round_going && attacker->client && targ != attacker && OnSameTeam (targ, attacker)) { Add_TeamWound (attacker, targ, mod); } } } if (damage_type && !instant_dam) // bullets but not vest hits { vec3_t temp; vec3_t temporig; //vec3_t forward; VectorMA (targ->s.origin, 50, dir, temp); //AngleVectors (attacker->client->v_angle, forward, NULL, NULL); VectorScale (dir, 20, temp); VectorAdd (point, temp, temporig); if (mod != MOD_SNIPER) spray_blood (targ, temporig, dir, damage, mod); else spray_sniper_blood (targ, temporig, dir); } if (mod == MOD_FALLING && !(targ->flags & FL_GODMODE) ) { if (!heroes->value || targ->client->resp.team == 2) { // ESJ no limp for heroes if (targ->client && targ->health > 0) { gi.cprintf (targ, PRINT_HIGH, "Leg damage\n"); targ->client->leg_damage = 1; targ->client->leghits++; // bleeding = 1; for testing } } } if (heroes->value && targ->client && targ->client->resp.team == 1) //ESJ take damage or give points, depending { if (attacker->client) //not fall damage or the like { attacker->client->points += damage; while (attacker->client->points >= 100) { attacker->client->resp.score++; attacker->client->points -= 100; } } damage = 0; } // friendly fire avoidance // if enabled you can't hurt teammates (but you can hurt yourself) // knockback still occurs if (targ != attacker && ((deathmatch->value && ((int)dmflags->value & (DF_MODELTEAMS | DF_SKINTEAMS))) || coop->value)) { if (OnSameTeam (targ, attacker)) { if ((int)dmflags->value & DF_NO_FRIENDLY_FIRE && (team_round_going || !ff_afterround->value)) damage = 0; else mod |= MOD_FRIENDLY_FIRE; } } meansOfDeath = mod; locOfDeath = damage_type; // location client = targ->client; if (dflags & DAMAGE_BULLET) te_sparks = TE_BULLET_SPARKS; else te_sparks = TE_SPARKS; VectorNormalize (dir); // bonus damage for suprising a monster // if (!(dflags & DAMAGE_RADIUS) && (targ->svflags & SVF_MONSTER) && (attacker->client) && (!targ->enemy) && (targ->health > 0)) // damage *= 2; if (targ->flags & FL_NO_KNOCKBACK) knockback = 0; // figure momentum add if (!(dflags & DAMAGE_NO_KNOCKBACK)) { if ((knockback) && (targ->movetype != MOVETYPE_NONE) && (targ->movetype != MOVETYPE_BOUNCE) && (targ->movetype != MOVETYPE_PUSH) && (targ->movetype != MOVETYPE_STOP)) { vec3_t kvel, flydir; float mass; if (mod != MOD_FALLING) { VectorCopy (dir, flydir); flydir[2] += 0.4f; } if (targ->mass < 50) mass = 50; else mass = targ->mass; if (targ->client && attacker == targ) VectorScale (flydir, 1600.0 * (float) knockback / mass, kvel); // the rocket jump hack... else VectorScale (flydir, 500.0 * (float) knockback / mass, kvel); // FB //if (mod == MOD_KICK ) //{ // kvel[2] = 0; //} VectorAdd (targ->velocity, kvel, targ->velocity); } } take = damage; save = 0; // check for godmode if ((targ->flags & FL_GODMODE) && !(dflags & DAMAGE_NO_PROTECTION)) { take = 0; save = damage; SpawnDamage (te_sparks, point, normal, save); } // zucc don't need this stuff, but to remove it need to change how damagefeedback works with colors // check for invincibility if ((client && client->invincible_framenum > level.framenum) && !(dflags & DAMAGE_NO_PROTECTION)) { if (targ->pain_debounce_time < level.time) { gi.sound (targ, CHAN_ITEM, gi.soundindex ("items/protect4.wav"), 1, ATTN_NORM, 0); targ->pain_debounce_time = level.time + 2; } take = 0; save = damage; } psave = CheckPowerArmor (targ, point, normal, take, dflags); take -= psave; asave = CheckArmor (targ, point, normal, take, te_sparks, dflags); take -= asave; //treat cheat/powerup savings the same as armor asave += save; // team damage avoidance if (!(dflags & DAMAGE_NO_PROTECTION) && CheckTeamDamage (targ, attacker)) return; if ((mod == MOD_M3) || (mod == MOD_HC) || (mod == MOD_HELD_GRENADE) || (mod == MOD_HG_SPLASH) || (mod == MOD_G_SPLASH) || (mod == MOD_BREAKINGGLASS)) { //FB 6/3/99 - shotgun damage report stuff int playernum = targ - g_edicts; playernum--; if (playernum >= 0 && playernum <= game.maxclients - 1) *(took_damage + playernum) = 1; //FB 6/3/99 bleeding = 1; instant_dam = 0; } /* if ( (mod == MOD_M3) || (mod == MOD_HC) ) { instant_dam = 1; remain = take % 2; take = (int)(take/2); // balances out difference in how action and axshun handle damage/bleeding } */ if (ctf->value) CTFCheckHurtCarrier (targ, attacker); // do the damage if (take) { // zucc added check for stopAP, if it hit a vest we want sparks if (((targ->svflags & SVF_MONSTER) || (client)) && !do_sparks) SpawnDamage (TE_BLOOD, point, normal, take); else SpawnDamage (te_sparks, point, normal, take); // all things that have at least some instantaneous damage, i.e. bruising/falling if (instant_dam) targ->health = targ->health - take; if (targ->health <= 0) { if (client && attacker->client) { //Added these here also, if this is the last shot and before shots is from //different attacker, msg's would go to wrong client -M if (!OnSameTeam (attacker, targ)) attacker->client->resp.damage_dealt += damage; client->attacker = attacker; client->attacker_mod = mod; client->attacker_loc = damage_type; } if ((targ->svflags & SVF_MONSTER) || (client)) targ->flags |= FL_NO_KNOCKBACK; Killed (targ, inflictor, attacker, take, point); return; } } if (targ->svflags & SVF_MONSTER) { M_ReactToDamage (targ, attacker); if (!(targ->monsterinfo.aiflags & AI_DUCKED) && (take)) { targ->pain (targ, attacker, knockback, take); // nightmare mode monsters don't go into pain frames often if (skill->value == 3) targ->pain_debounce_time = level.time + 5; } } else if (client) { if (!(targ->flags & FL_GODMODE) && (take)) targ->pain (targ, attacker, knockback, take); } else if (take) { if (targ->pain) targ->pain (targ, attacker, knockback, take); } // add to the damage inflicted on a player this frame // the total will be turned into screen blends and view angle kicks // at the end of the frame if (client) { client->damage_parmor += psave; client->damage_armor += asave; client->damage_blood += take; client->damage_knockback += knockback; //zucc handle adding bleeding here if (damage_type && bleeding) // one of the hit location weapons { /* zucc add in partial bleeding, changed if ( client->bleeding < 4*damage*BLEED_TIME ) { client->bleeding = 4*damage*BLEED_TIME + client->bleeding/2; } else { client->bleeding += damage*BLEED_TIME*2; } */ client->bleeding += damage * BLEED_TIME; VectorSubtract (point, targ->absmax, targ->client->bleedloc_offset); //VectorSubtract(point, targ->s.origin, client->bleedloc_offset); } else if (bleeding) { /* if ( client->bleeding < damage*BLEED_TIME ) { client->bleeding = damage*BLEED_TIME; //client->bleedcount = 0; } */ client->bleeding += damage * BLEED_TIME; VectorSubtract (point, targ->absmax, targ->client->bleedloc_offset); //VectorSubtract(point, targ->s.origin, client->bleedloc_offset); } if (attacker->client) { if (!OnSameTeam (attacker, targ)) attacker->client->resp.damage_dealt += damage; client->attacker = attacker; client->attacker_mod = mod; client->attacker_loc = damage_type; client->push_timeout = 50; //VectorCopy(dir, client->bleeddir ); //VectorCopy(point, client->bleedpoint ); //VectorCopy(normal, client->bleednormal); } VectorCopy (point, client->damage_from); } }