예제 #1
0
void WidowExplosionLeg (edict_t *self)
{
//	int		n;
	vec3_t	f,r,u, startpoint;
	vec3_t	offset1 = {-31.89, -47.86, 67.02};
	vec3_t	offset2 = {-44.9, -82.14, 54.72};

	//gi.dprintf ("Leg\n");

	AngleVectors (self->s.angles, f, r, u);
	G_ProjectSource2 (self->s.origin, offset1, f, r, u, startpoint);

	gi.WriteByte (svc_temp_entity);
	gi.WriteByte (TE_EXPLOSION1_BIG);
	gi.WritePosition (startpoint);
	gi.multicast (self->s.origin, MULTICAST_ALL);

	ThrowWidowGibSized (self, "models/monsters/blackwidow2/gib2/tris.md2", 200, GIB_METALLIC, startpoint, 
		gi.soundindex ("misc/fhit3.wav"), false);
	ThrowWidowGibLoc (self, "models/objects/gibs/sm_meat/tris.md2", 300, GIB_ORGANIC, startpoint, false);
	ThrowWidowGibLoc (self, "models/objects/gibs/sm_metal/tris.md2", 100, GIB_METALLIC, startpoint, false);

	G_ProjectSource2 (self->s.origin, offset2, f, r, u, startpoint);

	gi.WriteByte (svc_temp_entity);
	gi.WriteByte (TE_EXPLOSION1);
	gi.WritePosition (startpoint);
	gi.multicast (self->s.origin, MULTICAST_ALL);

	ThrowWidowGibSized (self, "models/monsters/blackwidow2/gib1/tris.md2", 300, GIB_METALLIC, startpoint,
		gi.soundindex ("misc/fhit3.wav"), false);
	ThrowWidowGibLoc (self, "models/objects/gibs/sm_meat/tris.md2", 300, GIB_ORGANIC, startpoint, false);
	ThrowWidowGibLoc (self, "models/objects/gibs/sm_metal/tris.md2", 100, GIB_METALLIC, startpoint, false);
}
예제 #2
0
파일: widow.c 프로젝트: DrItanium/rogue
void spawn_out_do (edict_t *self)
{
	vec3_t startpoint,f,r,u;

	AngleVectors (self->s.angles, f, r, u);
	G_ProjectSource2 (self->s.origin, beameffects[0], f, r, u, startpoint);
	gi.WriteByte (svc_temp_entity);
	gi.WriteByte (TE_WIDOWSPLASH);
	gi.WritePosition (startpoint);
	gi.multicast (startpoint, MULTICAST_ALL);

	G_ProjectSource2 (self->s.origin, beameffects[1], f, r, u, startpoint);
	gi.WriteByte (svc_temp_entity);
	gi.WriteByte (TE_WIDOWSPLASH);
	gi.WritePosition (startpoint);
	gi.multicast (startpoint, MULTICAST_ALL);

	VectorCopy (self->s.origin, startpoint);
	startpoint[2] += 36;
	gi.WriteByte (svc_temp_entity);
	gi.WriteByte (TE_BOSSTPORT);
	gi.WritePosition (startpoint);
	gi.multicast (startpoint, MULTICAST_PVS);

	Widowlegs_Spawn (self->s.origin, self->s.angles);
	
	G_FreeEdict (self);
}
예제 #3
0
파일: m_actor_weap.c 프로젝트: qbism/qbq2
// Rocket Launcher
void actorRocket (edict_t *self)
{
	vec3_t	start, target;
	vec3_t	forward, right, up;
	int		damage = 80;

	if(!self->enemy || !self->enemy->inuse)
		return;

	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_rocket (self, start, forward, damage, 550, damage+20, damage, 
		( (self->spawnflags & SF_MONSTER_SPECIAL) ? self->enemy : NULL) );

	gi.positioned_sound(start,self,CHAN_WEAPON,gi.soundindex("weapons/rocklf1a.wav"),1,ATTN_NORM,0);

	if(developer->value)
	{
		if (!(self->monsterinfo.aiflags & AI_TWO_GUNS) || (self->framenumbers % 2))
			TraceAimPoint(start,target);
	}
}
예제 #4
0
파일: m_actor_weap.c 프로젝트: qbism/qbq2
// Railgun
void actorRailGun (edict_t *self)
{
	vec3_t	start, target;
	vec3_t	forward, right, up;

	if(!self->enemy || !self->enemy->inuse)
		return;

	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_rail (self, start, forward, 80, 100);  // Do slightly less damage

	gi.positioned_sound(start,self,CHAN_WEAPON,gi.soundindex("weapons/railgf1a.wav"),1,ATTN_NORM,0);

	if(developer->value)
	{
		if (!(self->monsterinfo.aiflags & AI_TWO_GUNS) || (self->framenumbers % 2))
			TraceAimPoint(start,target);
	}
}
예제 #5
0
void
spawn_out_start(edict_t *self)
{
	vec3_t startpoint, f, r, u;

	if (!self)
	{
		return;
	}

	self->wait = level.time + 2.0;

	AngleVectors(self->s.angles, f, r, u);

	G_ProjectSource2(self->s.origin, beameffects[0], f, r, u, startpoint);
	gi.WriteByte(svc_temp_entity);
	gi.WriteByte(TE_WIDOWBEAMOUT);
	gi.WriteShort(20001);
	gi.WritePosition(startpoint);
	gi.multicast(startpoint, MULTICAST_ALL);

	G_ProjectSource2(self->s.origin, beameffects[1], f, r, u, startpoint);
	gi.WriteByte(svc_temp_entity);
	gi.WriteByte(TE_WIDOWBEAMOUT);
	gi.WriteShort(20002);
	gi.WritePosition(startpoint);
	gi.multicast(startpoint, MULTICAST_ALL);

	gi.sound(self, CHAN_VOICE, gi.soundindex("misc/bwidowbeamout.wav"), 1, ATTN_NORM, 0);
}
예제 #6
0
파일: m_actor_weap.c 프로젝트: qbism/qbq2
//Blaster
void actorBlaster (edict_t *self)
{
	vec3_t	start, target;
	vec3_t	forward, right, up;
	int		damage;
	int		effect, color;

	if(!self->enemy || !self->enemy->inuse)
		return;

	// Knightmare- select color and effect
	if (blaster_color->value == 2) { //green
		color = BLASTER_GREEN;
		effect = (EF_BLASTER|EF_TRACKER);
	}
	else if (blaster_color->value == 3) { //blue
		color = BLASTER_BLUE;
#ifdef KMQUAKE2_ENGINE_MOD
		effect = EF_BLASTER|EF_BLUEHYPERBLASTER;
#else
		effect = EF_BLUEHYPERBLASTER;
#endif
	}
#ifdef KMQUAKE2_ENGINE_MOD
	else if (blaster_color->value == 4) {//red
		color = BLASTER_RED;
		effect = EF_BLASTER|EF_IONRIPPER;
	}
#endif
	else { //standard yellow
		color = BLASTER_ORANGE;
		effect = EF_BLASTER;
	}

	AngleVectors (self->s.angles, forward, right, up);
	G_ProjectSource2 (self->s.origin, self->muzzle, forward, right, up, start);
	ActorTarget(self,target);
	VectorSubtract (target, start, forward);
	VectorNormalize (forward);

	if(self->monsterinfo.aiflags & AI_TWO_GUNS)
		damage = 5;
	else
		damage = 10;

	monster_fire_blaster (self, start, forward, damage, 600, MZ2_SOLDIER_BLASTER_2, effect, color);

	if(developer->value)
		TraceAimPoint(start,target);

	if(self->monsterinfo.aiflags & AI_TWO_GUNS)
	{
		G_ProjectSource2(self->s.origin,self->muzzle2,forward,right,up,start);
		VectorSubtract (target, start, forward);
		VectorNormalize (forward);
		monster_fire_blaster (self, start, forward, damage, 600, MZ2_SOLDIER_BLASTER_2, effect, color);
	}

}
예제 #7
0
파일: m_actor_weap.c 프로젝트: qbism/qbq2
// Machinegun
void actorMachineGun (edict_t *self)
{
	vec3_t	start, target;
	vec3_t	forward, right, up;
	int		damage;

	if(!self->enemy || !self->enemy->inuse) {
		self->monsterinfo.pausetime = 0;
		return;
	}

	AngleVectors (self->s.angles, forward, right, up);
	G_ProjectSource2 (self->s.origin, self->muzzle, forward, right, up, start);
	ActorTarget(self,target);
	VectorSubtract (target, start, forward);
	VectorNormalize (forward);

	if(self->monsterinfo.aiflags & AI_TWO_GUNS)
		damage = 2;
	else
		damage = 4;

	fire_bullet (self, start, forward, damage, 2, DEFAULT_BULLET_HSPREAD, DEFAULT_BULLET_VSPREAD, MOD_MACHINEGUN);

	gi.WriteByte(svc_temp_entity);
	gi.WriteByte(TE_CHAINFIST_SMOKE);
	gi.WritePosition(start);
	gi.multicast(start, MULTICAST_PVS);
	gi.positioned_sound(start,self,CHAN_WEAPON,gi.soundindex(va("weapons/machgf%db.wav",self->actor_gunframe % 5 + 1)),1,ATTN_NORM,0);

	if(self->flash)
	{
		VectorCopy(start,self->flash->s.origin);
		self->flash->think = muzzleflash_think;
		self->flash->wait  = level.time + FRAMETIME;
		self->flash->think(self->flash);
	}

	if(developer->value)
		TraceAimPoint(start,target);

	if(self->monsterinfo.aiflags & AI_TWO_GUNS)
	{
		G_ProjectSource2 (self->s.origin, self->muzzle2, forward, right, up, start);
		ActorTarget(self,target);
		VectorSubtract (target, start, forward);
		VectorNormalize (forward);
		fire_bullet (self, start, forward, damage, 2, DEFAULT_BULLET_HSPREAD, DEFAULT_BULLET_VSPREAD, MOD_MACHINEGUN);
		gi.WriteByte(svc_temp_entity);
		gi.WriteByte(TE_CHAINFIST_SMOKE);
		gi.WritePosition(start);
		gi.multicast(start, MULTICAST_PVS);
	}
}
예제 #8
0
파일: m_actor_weap.c 프로젝트: qbism/qbq2
//Super Shotgun
void actorSuperShotgun (edict_t *self)
{
	vec3_t	start, target;
	vec3_t	forward, right, up;
	vec3_t	angles;

	if(!self->enemy || !self->enemy->inuse)
		return;

	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);
	vectoangles(forward,angles);
	angles[YAW] -= 5;
	AngleVectors(angles,forward,NULL,NULL);
	fire_shotgun (self, start, forward, 6, 12, DEFAULT_SHOTGUN_HSPREAD, DEFAULT_SHOTGUN_VSPREAD, DEFAULT_SSHOTGUN_COUNT/2, MOD_SSHOTGUN);
	angles[YAW] += 10;
	AngleVectors(angles,forward,NULL,NULL);
	fire_shotgun (self, start, forward, 6, 12, DEFAULT_SHOTGUN_HSPREAD, DEFAULT_SHOTGUN_VSPREAD, DEFAULT_SSHOTGUN_COUNT/2, MOD_SSHOTGUN);

	gi.WriteByte(svc_temp_entity);
	gi.WriteByte(TE_CHAINFIST_SMOKE);
	gi.WritePosition(start);
	gi.multicast(start, MULTICAST_PVS);
	gi.positioned_sound(start,self,CHAN_WEAPON,gi.soundindex("weapons/sshotf1b.wav"),1,ATTN_NORM,0);

	if(self->flash)
	{
		VectorCopy(start,self->flash->s.origin);
		self->flash->s.frame = 0;
		self->flash->think   = muzzleflash_think;
		self->flash->wait    = level.time + FRAMETIME;
		self->flash->think(self->flash);
	}

	if(developer->value)
	{
		if (!(self->monsterinfo.aiflags & AI_TWO_GUNS) || (self->framenumbers % 2))
			TraceAimPoint(start,target);
	}
}
예제 #9
0
void
widow_ready_spawn(edict_t *self)
{
	vec3_t f, r, u, offset, startpoint, spawnpoint;
	int i;

	if (!self)
	{
		return;
	}

	WidowBlaster(self);
	AngleVectors(self->s.angles, f, r, u);

	for (i = 0; i < 2; i++)
	{
		VectorCopy(spawnpoints[i], offset);
		G_ProjectSource2(self->s.origin, offset, f, r, u, startpoint);

		if (FindSpawnPoint(startpoint, stalker_mins, stalker_maxs, spawnpoint,
					64))
		{
			SpawnGrow_Spawn(spawnpoint, 1);
		}
	}
}
예제 #10
0
파일: widow2.c 프로젝트: yquake2/rogue
void
ThrowArm1(edict_t *self)
{
	int n;
	vec3_t f, r, u, startpoint;
	vec3_t offset1 = {65.76, 17.52, 7.56};

	if (!self)
	{
		return;
	}

	AngleVectors(self->s.angles, f, r, u);
	G_ProjectSource2(self->s.origin, offset1, f, r, u, startpoint);

	gi.WriteByte(svc_temp_entity);
	gi.WriteByte(TE_EXPLOSION1_BIG);
	gi.WritePosition(startpoint);
	gi.multicast(self->s.origin, MULTICAST_ALL);

	for (n = 0; n < 2; n++)
	{
		ThrowWidowGibLoc(self, "models/objects/gibs/sm_metal/tris.md2",
				100, GIB_METALLIC, startpoint, false);
	}
}
예제 #11
0
파일: widow2.c 프로젝트: yquake2/rogue
void
Widow2Tongue(edict_t *self)
{
	vec3_t f, r, u;
	vec3_t start, end, dir;
	trace_t tr;

	if (!self)
	{
		return;
	}

	AngleVectors(self->s.angles, f, r, u);
	G_ProjectSource2(self->s.origin, offsets[self->s.frame - FRAME_tongs01], f, r, u, start);
	VectorCopy(self->enemy->s.origin, end);

	if (!widow2_tongue_attack_ok(start, end, 256))
	{
		end[2] = self->enemy->s.origin[2] + self->enemy->maxs[2] - 8;

		if (!widow2_tongue_attack_ok(start, end, 256))
		{
			end[2] = self->enemy->s.origin[2] + self->enemy->mins[2] + 8;

			if (!widow2_tongue_attack_ok(start, end, 256))
			{
				return;
			}
		}
	}

	VectorCopy(self->enemy->s.origin, end);

	tr = gi.trace(start, NULL, NULL, end, self, MASK_SHOT);

	if (tr.ent != self->enemy)
	{
		return;
	}

	gi.sound(self, CHAN_WEAPON, sound_tentacles_retract, 1, ATTN_NORM, 0);

	gi.WriteByte(svc_temp_entity);
	gi.WriteByte(TE_PARASITE_ATTACK);
	gi.WriteShort(self - g_edicts);
	gi.WritePosition(start);
	gi.WritePosition(end);
	gi.multicast(self->s.origin, MULTICAST_PVS);

	VectorSubtract(start, end, dir);
	T_Damage(self->enemy, self, self, dir, self->enemy->s.origin,
			vec3_origin, 2, 0, DAMAGE_NO_KNOCKBACK, MOD_UNKNOWN);
}
예제 #12
0
파일: m_actor_weap.c 프로젝트: qbism/qbq2
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++;
}
예제 #13
0
void ThrowArm2 (edict_t *self)
{
//	int		n;
	vec3_t	f,r,u, startpoint;
	vec3_t	offset1 = {65.76, 17.52, 7.56};

	AngleVectors (self->s.angles, f, r, u);
	G_ProjectSource2 (self->s.origin, offset1, f, r, u, startpoint);

	ThrowWidowGibSized (self, "models/monsters/blackwidow2/gib4/tris.md2", 200, GIB_METALLIC, startpoint, 
		gi.soundindex ("misc/fhit3.wav"), false);
	ThrowWidowGibLoc (self, "models/objects/gibs/sm_meat/tris.md2", 300, GIB_ORGANIC, startpoint, false);
}
예제 #14
0
void
WidowSpawn(edict_t *self)
{
	vec3_t f, r, u, offset, startpoint, spawnpoint;
	edict_t *ent, *designated_enemy;
	int i;

	if (!self)
	{
		return;
	}

	AngleVectors(self->s.angles, f, r, u);

	for (i = 0; i < 2; i++)
	{
		VectorCopy(spawnpoints[i], offset);

		G_ProjectSource2(self->s.origin, offset, f, r, u, startpoint);

		if (FindSpawnPoint(startpoint, stalker_mins, stalker_maxs, spawnpoint,
					64))
		{
			ent = CreateGroundMonster(spawnpoint, self->s.angles, stalker_mins, stalker_maxs,
					"monster_stalker", 256);

			if (!ent)
			{
				continue;
			}

			self->monsterinfo.monster_used++;
			ent->monsterinfo.commander = self;
			ent->nextthink = level.time;
			ent->think(ent);

			ent->monsterinfo.aiflags |= /* AI_SPAWNED_WIDOW | */ AI_DO_NOT_COUNT | AI_IGNORE_SHOTS;

			designated_enemy = self->enemy;

			if ((designated_enemy->inuse) && (designated_enemy->health > 0))
			{
				ent->enemy = designated_enemy;
				FoundTarget(ent);
				ent->monsterinfo.attack(ent);
			}
		}
	}
}
예제 #15
0
파일: widow2.c 프로젝트: yquake2/rogue
void
Widow2TonguePull(edict_t *self)
{
	vec3_t vec;
	vec3_t f, r, u;
	vec3_t start, end;

	if (!self)
	{
		return;
	}

	if ((!self->enemy) || (!self->enemy->inuse))
	{
		self->monsterinfo.run(self);
		return;
	}

	AngleVectors(self->s.angles, f, r, u);
	G_ProjectSource2(self->s.origin, offsets[self->s.frame - FRAME_tongs01],
			f, r, u, start);
	VectorCopy(self->enemy->s.origin, end);

	if (!widow2_tongue_attack_ok(start, end, 256))
	{
		return;
	}

	if (self->enemy->groundentity)
	{
		self->enemy->s.origin[2] += 1;
		self->enemy->groundentity = NULL;
	}

	VectorSubtract(self->s.origin, self->enemy->s.origin, vec);

	if (self->enemy->client)
	{
		VectorNormalize(vec);
		VectorMA(self->enemy->velocity, 1000, vec, self->enemy->velocity);
	}
	else
	{
		self->enemy->ideal_yaw = vectoyaw(vec);
		M_ChangeYaw(self->enemy);
		VectorScale(f, 1000, self->enemy->velocity);
	}
}
예제 #16
0
void WidowExplosion1 (edict_t *self)
{
	int		n;
	vec3_t	f,r,u, startpoint;
	vec3_t	offset = {23.74, -37.67, 76.96};

//	gi.dprintf ("1\n");
	AngleVectors (self->s.angles, f, r, u);
	G_ProjectSource2 (self->s.origin, offset, f, r, u, startpoint);

	gi.WriteByte (svc_temp_entity);
	gi.WriteByte (TE_EXPLOSION1);
	gi.WritePosition (startpoint);
	gi.multicast (self->s.origin, MULTICAST_ALL);
	
	for (n= 0; n < 1; n++)
		ThrowWidowGibLoc (self, "models/objects/gibs/sm_meat/tris.md2", 300, GIB_ORGANIC, startpoint, false);
	for (n= 0; n < 1; n++)
		ThrowWidowGibLoc (self, "models/objects/gibs/sm_metal/tris.md2", 100, GIB_METALLIC, startpoint, false);
	for (n= 0; n < 2; n++)
		ThrowWidowGibLoc (self, "models/objects/gibs/sm_metal/tris.md2", 300, GIB_METALLIC, startpoint, false);
}
예제 #17
0
파일: widow2.c 프로젝트: yquake2/rogue
void
WidowExplosion7(edict_t *self)
{
	int n;
	vec3_t f, r, u, startpoint;
	vec3_t offset = {-20.11, -1.11, 40.76};

	if (!self)
	{
		return;
	}

	AngleVectors(self->s.angles, f, r, u);
	G_ProjectSource2(self->s.origin, offset, f, r, u, startpoint);

	gi.WriteByte(svc_temp_entity);
	gi.WriteByte(TE_EXPLOSION1);
	gi.WritePosition(startpoint);
	gi.multicast(self->s.origin, MULTICAST_ALL);

	for (n = 0; n < 1; n++)
	{
		ThrowWidowGibLoc(self, "models/objects/gibs/sm_meat/tris.md2",
				300, GIB_ORGANIC, startpoint, false);
	}

	for (n = 0; n < 1; n++)
	{
		ThrowWidowGibLoc(self, "models/objects/gibs/sm_metal/tris.md2",
				100, GIB_METALLIC, startpoint, false);
	}

	for (n = 0; n < 2; n++)
	{
		ThrowWidowGibLoc(self, "models/objects/gibs/sm_metal/tris.md2",
				300, GIB_METALLIC, startpoint, false);
	}
}
예제 #18
0
//==========================================================================================
//
// AimGrenade finds the correct aim vector to get a grenade from start to target at initial
// velocity = speed. Returns false if grenade can't make it to target.
//
//==========================================================================================
qboolean AimGrenade (edict_t *self, vec3_t start, vec3_t target, vec_t speed, vec3_t aim)
{
	vec3_t		angles, forward, right, up;
	vec3_t		from_origin, from_muzzle;
	vec3_t		aim_point;
	vec_t		xo, yo;
	vec_t		x;
	float		cosa, t, vx, y;
	float		drop;
	float		last_error, v_error;
	int			i;
	vec3_t		last_aim;

	VectorCopy(target,aim_point);
	VectorSubtract(aim_point,self->s.origin,from_origin);
	VectorSubtract(aim_point, start, from_muzzle);

	if(self->svflags & SVF_MONSTER)
	{
		VectorCopy(from_muzzle,aim);
		VectorNormalize(aim);
		yo = from_muzzle[2];
		xo = sqrt(from_muzzle[0]*from_muzzle[0] + from_muzzle[1]*from_muzzle[1]);
	}
	else
	{
		VectorCopy(from_origin,aim);
		VectorNormalize(aim);
		yo = from_origin[2];
		xo = sqrt(from_origin[0]*from_origin[0] + from_origin[1]*from_origin[1]);
	}

	// If resulting aim vector is looking straight up or straight down, we're 
	// done. Actually now that I write this down and think about it... should
	// probably check straight up to make sure grenade will actually reach the
	// target.
	if( (aim[2] == 1.0) || (aim[2] == -1.0))
		return true;

	// horizontal distance to target from muzzle
	x = sqrt( from_muzzle[0]*from_muzzle[0] + from_muzzle[1]*from_muzzle[1]);
	cosa = sqrt(aim[0]*aim[0] + aim[1]*aim[1]);
	// constant horizontal velocity (since grenades don't have drag)
	vx = speed * cosa;
	// time to reach target x
	t = x/vx;
	// if flight time is less than one frame, no way grenade will drop much,
	// shoot the sucker now.
	if(t < FRAMETIME)
		return true;
	// in that time, grenade will drop this much:
	drop = 0.5*sv_gravity->value*t*t;
	y = speed*aim[2]*t - drop;
	v_error = target[2] - start[2] - y;

	// if we're fairly close and we'll hit target at current angle,
	// no need for all this, just shoot it
	if( (x < 128) && (fabs(v_error) < 16) )
		return true;

	last_error = 100000.;
	VectorCopy(aim,last_aim);

	// Unfortunately there is no closed-form solution for this problem,
	// so we creep up on an answer and balk if it takes more than 
	// 10 iterations to converge to the tolerance we'll accept.
	for(i=0; i<10 && fabs(v_error) > 4 && fabs(v_error) < fabs(last_error); i++)
	{
		last_error = v_error;
		aim[2] = cosa * (yo + drop)/xo;
		VectorNormalize(aim);
		if(!(self->svflags & SVF_MONSTER))
		{
			vectoangles(aim,angles);
			AngleVectors(angles, forward, right, up);
			G_ProjectSource2(self->s.origin,self->move_origin,forward,right,up,start);
			VectorSubtract(aim_point,start,from_muzzle);
			x = sqrt(from_muzzle[0]*from_muzzle[0] + from_muzzle[1]*from_muzzle[1]);
		}
		cosa = sqrt(aim[0]*aim[0] + aim[1]*aim[1]);
		vx = speed * cosa;
		t = x/vx;
		drop = 0.5*sv_gravity->value*t*t;
		y = speed*aim[2]*t - drop;
		v_error = target[2] - start[2] - y;
		if(fabs(v_error) < fabs(last_error))
			VectorCopy(aim,last_aim);
	}
	
	if(i >= 10 || v_error > 64)
		return false;
	if(fabs(v_error) > fabs(last_error))
	{
		VectorCopy(last_aim,aim);
		if(!(self->svflags & SVF_MONSTER))
		{
			vectoangles(aim,angles);
			AngleVectors(angles, forward, right, up);
			G_ProjectSource2(self->s.origin,self->move_origin,forward,right,up,start);
			VectorSubtract(aim_point,start,from_muzzle);
		}
	}
	
	// Sanity check... if launcher is at the same elevation or a bit above the 
	// target entity, check to make sure he won't bounce grenades off the 
	// top of a doorway or other obstruction. If he WOULD do that, then figure out 
	// the max elevation angle that will get the grenade through the door, and 
	// hope we get a good bounce.
	if( (start[2] - target[2] < 160) &&
		(start[2] - target[2] > -16)   )
	{
		trace_t	tr;
		vec3_t	dist;
		
		tr = gi.trace(start,vec3_origin,vec3_origin,aim_point,self,MASK_SOLID);
		if( (tr.fraction < 1.0) && (!self->enemy || (tr.ent != self->enemy) )) {
			// OK... the aim vector hit a solid, but would the grenade actually hit?
			int		contents;
			cosa = sqrt(aim[0]*aim[0] + aim[1]*aim[1]);
			vx = speed * cosa;
			VectorSubtract(tr.endpos,start,dist);
			dist[2] = 0;
			x = VectorLength(dist);
			t = x/vx;
			drop = 0.5*sv_gravity->value*t*(t+FRAMETIME);
			tr.endpos[2] -= drop;
			// move just a bit in the aim direction
			tr.endpos[0] += aim[0];
			tr.endpos[1] += aim[1];
			contents = gi.pointcontents(tr.endpos);
			while((contents & MASK_SOLID) && (aim_point[2] > target[2])) {
				aim_point[2] -= 8.0;
				VectorSubtract(aim_point,self->s.origin,from_origin);
				VectorCopy(from_origin,aim);
				VectorNormalize(aim);
				if(!(self->svflags & SVF_MONSTER))
				{
					vectoangles(aim,angles);
					AngleVectors(angles, forward, right, up);
					G_ProjectSource2(self->s.origin,self->move_origin,forward,right,up,start);
					VectorSubtract(aim_point,start,from_muzzle);
				}
				tr = gi.trace(start,vec3_origin,vec3_origin,aim_point,self,MASK_SOLID);
				if(tr.fraction < 1.0) {
					cosa = sqrt(aim[0]*aim[0] + aim[1]*aim[1]);
					vx = speed * cosa;
					VectorSubtract(tr.endpos,start,dist);
					dist[2] = 0;
					x = VectorLength(dist);
					t = x/vx;
					drop = 0.5*sv_gravity->value*t*(t+FRAMETIME);
					tr.endpos[2] -= drop;
					tr.endpos[0] += aim[0];
					tr.endpos[1] += aim[1];
					contents = gi.pointcontents(tr.endpos);
				}
			}
		}
	}
	return true;
}
예제 #19
0
파일: m_actor_weap.c 프로젝트: qbism/qbq2
void actorGrenadeLauncher (edict_t *self)
{
	vec3_t	start,target;
	vec3_t	forward, right, up;
	vec3_t	aim;
	vec3_t	dist;
	vec_t	monster_speed;

	if(!self->enemy || !self->enemy->inuse)
		return;

	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);
	if(self->enemy->absmin[2] <= self->absmax[2])
		target[2] += self->enemy->mins[2] - self->enemy->viewheight;
	VectorSubtract(target, start, aim);

	// lead target... 20, 35, 50, 65 chance of leading
	if( random() < (0.2 + skill->value * 0.15) )
	{
		float	dist;
		float	time;

		dist = VectorLength (aim);
		time = dist/GRENADE_VELOCITY;  // Not correct, but better than nothin'
		VectorMA(target, time, self->enemy->velocity, target);
		VectorSubtract(target, start, aim);
	}
	
	VectorCopy(aim,forward);
	VectorNormalize (aim);
	if(aim[2] < 1.0) {
		float	cosa, t, x, vx, y;
		float	drop;
		float	last_error, last_up, v_error;
		int		i;
		VectorCopy(forward,target);	// save target point
		// horizontal distance to target
		x = sqrt( forward[0]*forward[0] + forward[1]*forward[1]);
		cosa = sqrt(aim[0]*aim[0] + aim[1]*aim[1]);
		// constant horizontal velocity (since grenades don't have drag)
		vx = GRENADE_VELOCITY * cosa;
		// time to reach target x
		t = x/vx;
		// in that time, grenade will drop this much:
		drop = 0.5*sv_gravity->value*t*(t+FRAMETIME);
		forward[2] = target[2] + drop;
		// this is a good first cut, but incorrect since angle now changes, so
		// horizontal speed changes
		VectorCopy(forward,aim);
		VectorNormalize(aim);
		cosa = sqrt(aim[0]*aim[0] + aim[1]*aim[1]);
		vx = GRENADE_VELOCITY * cosa;
		t = x/vx;
		y = GRENADE_VELOCITY*aim[2]*t - 0.5*sv_gravity->value*t*(t+FRAMETIME);
		v_error = target[2]-y;
		last_error = 2*v_error;
		for(i=0; i<10 && fabs(v_error) > 4 && fabs(v_error) < fabs(last_error); i++) {
			drop = 0.5*sv_gravity->value*t*(t+FRAMETIME);
			forward[2] = target[2] + drop;
			VectorCopy(forward,aim);
			VectorNormalize(aim);
			cosa = sqrt(aim[0]*aim[0] + aim[1]*aim[1]);
			vx = GRENADE_VELOCITY * cosa;
			t = x/vx;
			y = GRENADE_VELOCITY*aim[2]*t - 0.5*sv_gravity->value*t*(t+FRAMETIME);
			v_error = target[2]-y;
			// If error is increasing... we can't get there from here and
			// probably shouldn't be here in the first place. Too late now...
			// use last aim vector and shoot.
			if(fabs(v_error) < fabs(last_error))
				last_up = forward[2];
		}
		if(fabs(v_error) > fabs(last_error)) {
			forward[2] = last_up;
			VectorCopy(forward,aim);
			VectorNormalize(aim);
		}
		// Sanity check... if gunner is at the same elevation or a bit above the 
		// target entity, check to make sure he won't bounce grenades off the 
		// top of a doorway. If he WOULD do that, then figure out the max elevation
		// angle that will get the grenade through the door, and hope we get a 
		// good bounce.
		if( (self->s.origin[2] - self->enemy->s.origin[2] < 160) &&
			(self->s.origin[2] - self->enemy->s.origin[2] > -16)   ) {
			trace_t	tr;

			VectorAdd(start,forward,target);
			tr = gi.trace(start,vec3_origin,vec3_origin,target,self,MASK_SOLID);
			if(tr.fraction < 1.0) {
				// OK... the aim vector hit a solid, but would the grenade actually hit?
				int		contents;

				cosa = sqrt(aim[0]*aim[0] + aim[1]*aim[1]);
				vx = GRENADE_VELOCITY * cosa;
				VectorSubtract(tr.endpos,start,dist);
				dist[2] = 0;
				x = VectorLength(dist);
				t = x/vx;
				drop = 0.5*sv_gravity->value*t*(t+FRAMETIME);
				tr.endpos[2] -= drop;
				// move just a bit in the aim direction
				tr.endpos[0] += aim[0];
				tr.endpos[1] += aim[1];
				contents = gi.pointcontents(tr.endpos);
				while((contents & MASK_SOLID) && (target[2] > self->enemy->s.origin[2])) {
					target[2] -= 8.0;
					VectorSubtract(target,start,forward);
					VectorCopy(forward,aim);
					VectorNormalize(aim);
					tr = gi.trace(start,vec3_origin,vec3_origin,target,self,MASK_SOLID);
					if(tr.fraction < 1.0) {
						cosa = sqrt(aim[0]*aim[0] + aim[1]*aim[1]);
						vx = GRENADE_VELOCITY * cosa;
						VectorSubtract(tr.endpos,start,dist);
						dist[2] = 0;
						x = VectorLength(dist);
						t = x/vx;
						drop = 0.5*sv_gravity->value*t*(t+FRAMETIME);
						tr.endpos[2] -= drop;
						tr.endpos[0] += aim[0];
						tr.endpos[1] += aim[1];
						contents = gi.pointcontents(tr.endpos);
					}
					// drop aim point another bit for insurance
					target[2] -= 8;
					VectorSubtract(target,start,forward);
					VectorCopy(forward,aim);
					VectorNormalize(aim);
				}
			}
		}
	}
	// DWH - take into account (sort of) Lazarus feature of adding shooter's velocity to
	// grenade velocity
	monster_speed = VectorLength(self->velocity);
	if(monster_speed > 0) {
		vec3_t	v1;
		vec_t	delta;

		VectorCopy(self->velocity,v1);
		VectorNormalize(v1);
		delta = -monster_speed/GRENADE_VELOCITY;
		VectorMA(aim,delta,v1,aim);
		VectorNormalize(aim);
	}
	fire_grenade (self, start, aim, 50, GRENADE_VELOCITY, 2.5, 90, false);

	gi.positioned_sound(start,self,CHAN_WEAPON,gi.soundindex("weapons/grenlf1a.wav"),1,ATTN_NORM,0);

	if(developer->value)
	{
		if (!(self->monsterinfo.aiflags & AI_TWO_GUNS) || (self->framenumbers % 2))
			TraceAimPoint(start,target);
	}
}
예제 #20
0
파일: widow2.c 프로젝트: yquake2/rogue
qboolean
Widow2_CheckAttack(edict_t *self)
{
	vec3_t spot1, spot2;
	vec3_t temp;
	float chance = 0;
	trace_t tr;
	int enemy_range;
	float enemy_yaw;
	float real_enemy_range;
	vec3_t f, r, u;

	if (!self)
	{
		return false;
	}

	if (!self->enemy)
	{
		return false;
	}

	WidowPowerups(self);

	if ((random() < 0.8) && (SELF_SLOTS_LEFT >= 2) &&
		(realrange(self, self->enemy) > 150))
	{
		self->monsterinfo.aiflags |= AI_BLOCKED;
		self->monsterinfo.attack_state = AS_MISSILE;
		return true;
	}

	if (self->enemy->health > 0)
	{
		/* see if any entities are in the way of the shot */
		VectorCopy(self->s.origin, spot1);
		spot1[2] += self->viewheight;
		VectorCopy(self->enemy->s.origin, spot2);
		spot2[2] += self->enemy->viewheight;

		tr = gi.trace(spot1, NULL, NULL, spot2, self,
				CONTENTS_SOLID | CONTENTS_MONSTER | CONTENTS_SLIME |
				CONTENTS_LAVA);

		/* do we have a clear shot? */
		if (tr.ent != self->enemy)
		{
			/* go ahead and spawn stuff if we're mad a a client */
			if (self->enemy->client && (SELF_SLOTS_LEFT >= 2))
			{
				self->monsterinfo.attack_state = AS_BLIND;
				return true;
			}

			if ((self->enemy->solid != SOLID_NOT) || (tr.fraction < 1.0))
			{
				return false;
			}
		}
	}

	enemy_range = range(self, self->enemy);
	VectorSubtract(self->enemy->s.origin, self->s.origin, temp);
	enemy_yaw = vectoyaw2(temp);

	self->ideal_yaw = enemy_yaw;

	/* melee attack */
	if (self->timestamp < level.time)
	{
		real_enemy_range = realrange(self, self->enemy);

		if (real_enemy_range < 300)
		{
			AngleVectors(self->s.angles, f, r, u);
			G_ProjectSource2(self->s.origin, offsets[0], f, r, u, spot1);
			VectorCopy(self->enemy->s.origin, spot2);

			if (widow2_tongue_attack_ok(spot1, spot2, 256))
			{
				/* be nice in easy mode */
				if ((skill->value == 0) && (rand() & 3))
				{
					return false;
				}

				if (self->monsterinfo.melee)
				{
					self->monsterinfo.attack_state = AS_MELEE;
				}
				else
				{
					self->monsterinfo.attack_state = AS_MISSILE;
				}

				return true;
			}
		}
	}

	if (level.time < self->monsterinfo.attack_finished)
	{
		return false;
	}

	if (self->monsterinfo.aiflags & AI_STAND_GROUND)
	{
		chance = 0.4;
	}
	else if (enemy_range == RANGE_NEAR)
	{
		chance = 0.8;
	}
	else if (enemy_range == RANGE_MID)
	{
		chance = 0.8;
	}
	else if (enemy_range == RANGE_FAR)
	{
		chance = 0.5;
	}

	if ((random() < chance) || (self->enemy->solid == SOLID_NOT))
	{
		self->monsterinfo.attack_state = AS_MISSILE;
		return true;
	}

	return false;
}
예제 #21
0
파일: m_actor_weap.c 프로젝트: qbism/qbq2
// Chaingun
void actorChaingun (edict_t *self)
{
	vec3_t	start, target;
	vec3_t	forward, right, up;
	int		i;
	int		shots;
	int		damage;

	if(!self->enemy || !self->enemy->inuse)
		self->monsterinfo.pausetime = 0;

	if(level.time >= self->monsterinfo.pausetime) {
		self->s.sound = 0;
		gi.sound(self,CHAN_AUTO,gi.soundindex("weapons/chngnd1a.wav"),1,ATTN_IDLE,0);
		return;
	}

	if(self->actor_gunframe == 0)
		gi.sound(self, CHAN_AUTO, gi.soundindex("weapons/chngnu1a.wav"), 1, ATTN_IDLE, 0);

	if(self->actor_gunframe == 21 && level.time < self->monsterinfo.pausetime)
		self->actor_gunframe = 15;
	else
		self->actor_gunframe++;

	self->s.sound = gi.soundindex("weapons/chngnl1a.wav");
#ifdef LOOP_SOUND_ATTENUATION
	self->s.attenuation = ATTN_IDLE;
#endif

	if(self->actor_gunframe <= 9)
		shots = 1;
	else if(self->actor_gunframe <= 14)
		shots = 2;
	else
		shots = 3;

	AngleVectors (self->s.angles, forward, right, up);
	G_ProjectSource2 (self->s.origin, self->muzzle, forward, right, up, start);
	ActorTarget(self,target);
	VectorSubtract (target, start, forward);
	VectorNormalize (forward);
	if(self->monsterinfo.aiflags & AI_TWO_GUNS)
		damage = 2;
	else
		damage = 4;

	for(i=0; i<shots; i++)
		fire_bullet (self, start, forward, damage, 2, DEFAULT_BULLET_HSPREAD, DEFAULT_BULLET_VSPREAD, MOD_CHAINGUN);

	gi.WriteByte(svc_temp_entity);
	gi.WriteByte(TE_CHAINFIST_SMOKE);
	gi.WritePosition(start);
	gi.multicast(start, MULTICAST_PVS);
	gi.positioned_sound(start,self,CHAN_WEAPON,gi.soundindex(va("weapons/machgf%db.wav",self->actor_gunframe % 5 + 1)),1,ATTN_NORM,0);

	if(self->flash)
	{
		VectorCopy(start,self->flash->s.origin);
		self->flash->think = muzzleflash_think;
		self->flash->wait  = level.time + FRAMETIME;
		self->flash->think(self->flash);
	}

	if(developer->value)
		TraceAimPoint(start,target);

	if(self->monsterinfo.aiflags & AI_TWO_GUNS)
	{
		G_ProjectSource2 (self->s.origin, self->muzzle2, forward, right, up, start);
		ActorTarget(self,target);
		VectorSubtract (target, start, forward);
		VectorNormalize (forward);
		for(i=0; i<shots; i++)
			fire_bullet (self, start, forward, damage, 2, DEFAULT_BULLET_HSPREAD, DEFAULT_BULLET_VSPREAD, MOD_CHAINGUN);
		gi.WriteByte(svc_temp_entity);
		gi.WriteByte(TE_CHAINFIST_SMOKE);
		gi.WritePosition(start);
		gi.multicast(start, MULTICAST_PVS);
	}
}
예제 #22
0
void Widow2Spawn (edict_t *self)
{
	vec3_t	f, r, u, offset, startpoint, spawnpoint;
	edict_t	*ent, *designated_enemy;
	int		i;

	AngleVectors (self->s.angles, f, r, u);

	for (i=0; i < 2; i++)
	{
		VectorCopy (spawnpoints[i], offset);

		G_ProjectSource2 (self->s.origin, offset, f, r, u, startpoint);

		if (FindSpawnPoint (startpoint, stalker_mins, stalker_maxs, spawnpoint, 64))
		{
			ent = CreateGroundMonster (spawnpoint, self->s.angles, stalker_mins, stalker_maxs, "monster_stalker", 256);

			if (!ent)
				continue;

			self->monsterinfo.monster_used++;
			ent->monsterinfo.commander = self;
//			if ((g_showlogic) && (g_showlogic->value))
//				gi.dprintf ("widow: post-spawn : %d slots left\n", SELF_SLOTS_LEFT);

			ent->nextthink = level.time;
			ent->think (ent);
			
			ent->monsterinfo.aiflags |= AI_SPAWNED_WIDOW|AI_DO_NOT_COUNT|AI_IGNORE_SHOTS;

			if (!(coop && coop->value))
			{
				designated_enemy = self->enemy;
			}
			else
			{
				designated_enemy = PickCoopTarget(ent);
				if (designated_enemy)
				{
					// try to avoid using my enemy
					if (designated_enemy == self->enemy)
					{
						designated_enemy = PickCoopTarget(ent);
						if (designated_enemy)
						{
//							if ((g_showlogic) && (g_showlogic->value))
//							{
//								gi.dprintf ("PickCoopTarget returned a %s - ", designated_enemy->classname);
//								if (designated_enemy->client)
//									gi.dprintf ("with name %s\n", designated_enemy->client->pers.netname);
//								else
//									gi.dprintf ("NOT A CLIENT\n");
//							}
						}
						else
						{
//							if ((g_showlogic) && (g_showlogic->value))
//								gi.dprintf ("pick coop failed, using my current enemy\n");
							designated_enemy = self->enemy;
						}
					}
				}
				else
				{
//					if ((g_showlogic) && (g_showlogic->value))
//						gi.dprintf ("pick coop failed, using my current enemy\n");
					designated_enemy = self->enemy;
				}
			}

			if ((designated_enemy->inuse) && (designated_enemy->health > 0))
			{
				ent->enemy = designated_enemy;
				FoundTarget (ent);
				ent->monsterinfo.attack(ent);
			}
		}
	}
}
예제 #23
0
파일: m_actor_weap.c 프로젝트: qbism/qbq2
void actorHyperblaster (edict_t *self)
{
	vec3_t	start, target;
	vec3_t	forward, right, up;
	int		damage;
	int		effect;
	int		color;

	if(!self->enemy || !self->enemy->inuse) {
		self->monsterinfo.pausetime = 0;
		self->s.sound = 0;
		return;
	}

	self->s.sound = gi.soundindex("weapons/hyprbl1a.wav");
#ifdef LOOP_SOUND_ATTENUATION
	self->s.attenuation = ATTN_IDLE;
#endif

	if (level.time >= self->monsterinfo.pausetime)
	{
		self->actor_gunframe++;
	}
	else
	{
		// Knightmare- select color
		if (hyperblaster_color->value == 2) //green
			color = BLASTER_GREEN;
		else if (hyperblaster_color->value == 3) //blue
			color = BLASTER_BLUE;
	#ifdef KMQUAKE2_ENGINE_MOD
		else if (hyperblaster_color->value == 4) //red
			color = BLASTER_RED;
	#endif
		else //standard yellow
			color = BLASTER_ORANGE;

		AngleVectors (self->s.angles, forward, right, up);
		G_ProjectSource2 (self->s.origin, self->muzzle, forward, right, up, start);
		ActorTarget(self,target);
		VectorSubtract (target, start, forward);
		VectorNormalize (forward);
		if ((random() * 3) < 1)
		{
			if (hyperblaster_color->value == 2) //green
				effect = (EF_HYPERBLASTER|EF_TRACKER);
			else if (hyperblaster_color->value == 3) //blue
				effect = EF_BLUEHYPERBLASTER;
	#ifdef KMQUAKE2_ENGINE_MOD
			else if (hyperblaster_color->value == 4) //red
				effect = EF_HYPERBLASTER|EF_IONRIPPER;
	#endif
			else //standard yellow
				effect = EF_HYPERBLASTER;
		}
		else
			effect = 0;

		gi.positioned_sound(start,self,CHAN_WEAPON,gi.soundindex("weapons/hyprbf1a.wav"),1,ATTN_NORM,0);

		if(self->monsterinfo.aiflags & AI_TWO_GUNS)
			damage = 8;
		else
			damage = 15;

		fire_blaster (self, start, forward, damage, 1000, effect, true, color);

		if(developer->value)
			TraceAimPoint(start,target);

		if(self->monsterinfo.aiflags & AI_TWO_GUNS)
		{
			G_ProjectSource2 (self->s.origin, self->muzzle2, forward, right, up, start);
			ActorTarget(self,target);
			VectorSubtract (target, start, forward);
			VectorNormalize (forward);
			if ((random() * 3) < 1)
			{
				if (hyperblaster_color->value == 2) //green
					effect = (EF_HYPERBLASTER|EF_TRACKER);
				else if (hyperblaster_color->value == 3) //blue
					effect = EF_BLUEHYPERBLASTER;
	#ifdef KMQUAKE2_ENGINE_MOD
				else if (hyperblaster_color->value == 4) //red
					effect = EF_HYPERBLASTER|EF_IONRIPPER;
	#endif
				else //standard yellow
					effect = EF_HYPERBLASTER;
			}
			else
				effect = 0;
			fire_blaster (self, start, forward, damage, 1000, effect, true, color);
		}

		self->actor_gunframe++;
		if (self->actor_gunframe == 12)
			self->actor_gunframe = 6;
	}

	if (self->actor_gunframe == 12)
	{
		gi.sound(self, CHAN_AUTO, gi.soundindex("weapons/hyprbd1a.wav"), 1, ATTN_NORM, 0);
		self->s.sound = 0;
	}

}