void monster_fire_bfg (edict_t *self, vec3_t start, vec3_t aimdir, int damage, int speed, int kick, float damage_radius, int flashtype) { float chance; // holy freeze reduces firing rate by 50% if (que_typeexists(self->curses, AURA_HOLYFREEZE)) { if (random() <= 0.5) return; } // chill effect reduces attack rate/refire if (self->chill_time > level.time) { chance = 1 / (1 + CHILL_DEFAULT_BASE + CHILL_DEFAULT_ADDON * self->chill_level); if (random() > chance) return; } damage = monster_increaseDamageByTalent(self->activator, damage); fire_bfg (self, start, aimdir, damage, speed, damage_radius); gi.WriteByte (svc_muzzleflash2); gi.WriteShort (self - g_edicts); gi.WriteByte (flashtype); gi.multicast (start, MULTICAST_PVS); }
void weapon_bfg_fire (edict_t *ent) { vec3_t offset, start; vec3_t forward, right; int damage, ammo, speed; float damage_radius; iteminfo_t *info = getWornItemInfo(ent, 0); damage = (info->arg1 + info->arg3 * (ent->client->ps.gunframe - 8)) * (1.0 + ent->client->pers.skill[1] * info->arg2); ammo = (int) ceil((ent->client->ps.gunframe - 8) * info->arg7); speed = (info->arg4 + info->arg5 * (float) ent->client->pers.skill[7]) - (ent->client->ps.gunframe - 8) * info->arg6; damage_radius = 120 + damage / 10.0; if (damage_radius > 140) damage_radius = 140; if (ent->client->ps.gunframe == 9) { // send muzzle flash if ((ent->client->silencer_shots > 0) && (ent->client->pers.skill[58] > 7)) { ent->client->silencer_shots -= 1; } else { gi.WriteByte (svc_muzzleflash); gi.WriteShort (ent-g_edicts); gi.WriteByte (MZ_BFG | is_silenced); gi.multicast (ent->s.origin, MULTICAST_PVS); } PlayerNoise(ent, ent->s.origin, PNOISE_WEAPON); } if (ent->client->pers.inventory[ent->client->ammo_index] < ammo) { ent->client->ps.gunframe = 32 - (ent->client->ps.gunframe - 8); return; } if ( (ent->client->ps.gunframe < (17 + info->arg9)) && ((ent->client->buttons & BUTTON_ATTACK) || (ent->client->ps.gunframe < (9 + info->arg8)))) { ent->client->ps.gunframe++; return; } damage = applyWeaponBonuses(ent, damage, 1); AngleVectors (ent->client->v_angle, forward, right, NULL); VectorScale (forward, -2, ent->client->kick_origin); // make a big pitch kick with an inverse fall ent->client->v_dmg_pitch = -(ent->client->ps.gunframe - 8) * 2; ent->client->v_dmg_roll = crandom()*8; ent->client->v_dmg_time = level.time + DAMAGE_TIME; VectorSet(offset, 8, 8, ent->viewheight-8); P_ProjectSource (ent->client, ent->s.origin, offset, forward, right, start); fire_bfg (ent, start, forward, damage, speed, damage_radius); ent->client->silencer_shots-=9; ent->client->ps.gunframe = 32 - (ent->client->ps.gunframe - 8); PlayerNoise(ent, start, PNOISE_WEAPON); // if (! ( (int)dmflags->value & DF_INFINITE_AMMO ) ) ent->client->pers.inventory[ent->client->ammo_index] -= ammo; }
void monster_fire_bfg(edict_t *self, vec3_t start, vec3_t aimdir, int damage, int speed, int kick, float damage_radius, int flashtype){ fire_bfg(self, start, aimdir, damage, speed, damage_radius); gi.WriteByte(svc_muzzleflash2); gi.WriteShort(self - g_edicts); gi.WriteByte(flashtype); gi.multicast(start, MULTICAST_PVS); }
static void Grenade_Explode_Rocket (edict_t *ent) { vec3_t origin; int mod; if (ent->owner->client) PlayerNoise(ent->owner, ent->s.origin, PNOISE_IMPACT); fire_bfg (ent, ent->s.origin, ent->s.origin, 200, 50, 1000); //FIXME: if we are onground then raise our Z just a bit since we are a point? if (ent->enemy) { float points; vec3_t v; vec3_t dir; VectorAdd (ent->enemy->mins, ent->enemy->maxs, v); VectorMA (ent->enemy->s.origin, 0.5, v, v); VectorSubtract (ent->s.origin, v, v); points = ent->dmg - 0.5 * VectorLength (v); VectorSubtract (ent->enemy->s.origin, ent->s.origin, dir); if (ent->spawnflags & 1) mod = MOD_HANDGRENADE; else mod = MOD_GRENADE; T_Damage (ent->enemy, ent, ent->owner, dir, ent->s.origin, vec3_origin, (int)points, (int)points, DAMAGE_RADIUS, mod); } if (ent->spawnflags & 2) mod = MOD_HELD_GRENADE; else if (ent->spawnflags & 1) mod = MOD_HG_SPLASH; else mod = MOD_G_SPLASH; T_RadiusDamage(ent, ent->owner, ent->dmg, ent->enemy, ent->dmg_radius, mod); VectorMA (ent->s.origin, -0.02, ent->velocity, origin); gi.WriteByte (svc_temp_entity); if (ent->waterlevel) { if (ent->groundentity) gi.WriteByte (TE_GRENADE_EXPLOSION_WATER); else gi.WriteByte (TE_ROCKET_EXPLOSION_WATER); } else { if (ent->groundentity) gi.WriteByte (TE_GRENADE_EXPLOSION); else gi.WriteByte (TE_ROCKET_EXPLOSION); } gi.WritePosition (origin); gi.multicast (ent->s.origin, MULTICAST_PHS); G_FreeEdict (ent); }
void weapon_bfg_fire (edict_t *ent) { vec3_t offset, start; vec3_t forward, right; int damage; float damage_radius = 1000; if (deathmatch->value) damage = 200; else damage = 500; if (ent->client->ps.gunframe == 9) { // send muzzle flash gi.WriteByte (svc_muzzleflash); gi.WriteShort (ent-g_edicts); gi.WriteByte (MZ_BFG | is_silenced); gi.multicast (ent->s.origin, MULTICAST_PVS); ent->client->ps.gunframe++; PlayerNoise(ent, start, PNOISE_WEAPON); return; } // cells can go down during windup (from power armor hits), so // check again and abort firing if we don't have enough now if (ent->client->pers.inventory[ent->client->ammo_index] < 50) { ent->client->ps.gunframe++; return; } if (is_quad) damage *= 4; AngleVectors (ent->client->v_angle, forward, right, NULL); VectorScale (forward, -2, ent->client->kick_origin); // make a big pitch kick with an inverse fall ent->client->v_dmg_pitch = -40; ent->client->v_dmg_roll = crandom()*8; ent->client->v_dmg_time = level.time + DAMAGE_TIME; VectorSet(offset, 8, 8, ent->viewheight-8); P_ProjectSource (ent->client, ent->s.origin, offset, forward, right, start); fire_bfg (ent, start, forward, damage, 400, damage_radius); ent->client->ps.gunframe++; PlayerNoise(ent, start, PNOISE_WEAPON); if (! ( (int)dmflags->value & DF_INFINITE_AMMO ) ) ent->client->pers.inventory[ent->client->ammo_index] -= 50; }
void BFG_Fire ( gentity_t *ent ) { gentity_t *m; m = fire_bfg (ent, muzzle, forward); m->damage *= s_quadFactor; m->splashDamage *= s_quadFactor; // VectorAdd( m->s.pos.trDelta, ent->client->ps.velocity, m->s.pos.trDelta ); // "real" physics }
void monster_fire_bfg (edict_t *self, vec3_t start, vec3_t aimdir, int damage, int speed, int kick, float damage_radius, int flashtype) { if(EMPNukeCheck(self, start)) { gi.sound (self, CHAN_AUTO, gi.soundindex("items/empnuke/emp_missfire.wav"), 1, ATTN_NORM, 0); return; } ANIM_AIM(self, aimdir); fire_bfg (self, start, aimdir, damage, speed, damage_radius); gi.WriteByte (svc_muzzleflash2); gi.WriteShort (self - g_edicts); gi.WriteByte (flashtype); gi.multicast (start, MULTICAST_PVS); }
void actorBFG (edict_t *self) { vec3_t start, target; vec3_t forward, right, up; if(!self->enemy || !self->enemy->inuse) { self->monsterinfo.pausetime = 0; return; } if(self->actor_gunframe == 0) gi.positioned_sound(self->s.origin,self,CHAN_WEAPON,gi.soundindex("weapons/bfg__f1y.wav"),1,ATTN_NORM,0); if(self->actor_gunframe == 10) { AngleVectors (self->s.angles, forward, right, up); if(self->monsterinfo.aiflags & AI_TWO_GUNS) { if(self->framenumbers % 2) G_ProjectSource2 (self->s.origin, self->muzzle2, forward, right, up, start); else G_ProjectSource2 (self->s.origin, self->muzzle, forward, right, up, start); self->framenumbers++; } else G_ProjectSource2 (self->s.origin, self->muzzle, forward, right, up, start); ActorTarget(self,target); VectorSubtract (target, start, forward); VectorNormalize (forward); fire_bfg (self, start, forward, 500, 300, 1000); self->endtime = level.time + 1; if(developer->value) { if (!(self->monsterinfo.aiflags & AI_TWO_GUNS) || (self->framenumbers % 2)) TraceAimPoint(start,target); } } self->actor_gunframe++; }
void weapon_railgun_fire (gentity_t *ent) { vec3_t end; trace_t trace; gentity_t *tent; gentity_t *traceEnt; int damage; int i; int hits; int unlinked; int passent; gentity_t *unlinkedEntities[MAX_RAIL_HITS]; if (0) { tent = fire_bfg (ent, muzzle, forward); tent->damage *= s_quadFactor; tent->splashDamage *= s_quadFactor; return; } damage = 80 * s_quadFactor; VectorMA (muzzle, 8192, forward, end); // trace only against the solids, so the railgun will go through people unlinked = 0; hits = 0; passent = ent->s.number; do { trap_Trace (&trace, muzzle, NULL, NULL, end, passent, MASK_SHOT ); if ( trace.entityNum >= ENTITYNUM_MAX_NORMAL ) { break; } traceEnt = &g_entities[ trace.entityNum ]; if ( traceEnt->takedamage ) { if( LogAccuracyHit( traceEnt, ent ) ) { hits++; } G_Damage (traceEnt, ent, ent, forward, trace.endpos, damage, 0, MOD_RAILGUN); } if ( trace.contents & CONTENTS_SOLID ) { break; // we hit something solid enough to stop the beam } // unlink this entity, so the next trace will go past it trap_UnlinkEntity( traceEnt ); unlinkedEntities[unlinked] = traceEnt; unlinked++; } while ( unlinked < MAX_RAIL_HITS ); // link back in any entities we unlinked for ( i = 0 ; i < unlinked ; i++ ) { trap_LinkEntity( unlinkedEntities[i] ); } // the final trace endpos will be the terminal point of the rail trail // snap the endpos to integers to save net bandwidth, but nudged towards the line SnapVectorTowards( trace.endpos, muzzle ); // send railgun beam effect tent = G_TempEntity( trace.endpos, EV_RAILTRAIL ); // set player number for custom colors on the railtrail tent->s.clientNum = ent->s.clientNum; VectorCopy( muzzle, tent->s.origin2 ); // move origin a bit to come closer to the drawn gun muzzle VectorMA( tent->s.origin2, 4, right, tent->s.origin2 ); VectorMA( tent->s.origin2, -1, up, tent->s.origin2 ); // no explosion at end if SURF_NOIMPACT, but still make the trail if ( trace.surfaceFlags & SURF_NOIMPACT ) { tent->s.eventParm = 255; // don't make the explosion at the end } else { tent->s.eventParm = DirToByte( trace.plane.normal ); } tent->s.clientNum = ent->s.clientNum; // give the shooter a reward sound if they have made two railgun hits in a row if ( hits == 0 ) { // complete miss ent->client->accurateCount = 0; } else { // check for "impressive" reward sound ent->client->accurateCount += hits; if ( ent->client->accurateCount >= 2 ) { ent->client->accurateCount -= 2; ent->client->ps.persistant[PERS_IMPRESSIVE_COUNT]++; // add the sprite over the player's head ent->client->ps.eFlags &= ~(EF_AWARD_IMPRESSIVE | EF_AWARD_EXCELLENT | EF_AWARD_GAUNTLET | EF_AWARD_ASSIST | EF_AWARD_DEFEND | EF_AWARD_CAP ); ent->client->ps.eFlags |= EF_AWARD_IMPRESSIVE; ent->client->rewardTime = level.time + REWARD_SPRITE_TIME; } ent->client->accuracy_hits++; } }