Beispiel #1
0
/*
void widow_attack (edict_t *self)
{
	float	range, luck;

//	gi.dprintf ("widow attack\n");

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

	if (self->bad_area)
	{
		if ((random() < 0.1) || (level.time < self->timestamp))
			self->monsterinfo.currentmove = &widow_move_attack_pre_blaster;
		else
		{
			gi.sound (self, CHAN_WEAPON, sound_rail, 1, ATTN_NORM, 0);
			self->monsterinfo.currentmove = &widow_move_attack_pre_rail;
		}
		return;
	}

	// if we can't see the target, spawn stuff
	if ((self->monsterinfo.attack_state == AS_BLIND) && (blaster_frames))
	{
		self->monsterinfo.currentmove = &widow_move_spawn;
		return;
	}

	range = realrange (self, self->enemy);

	if (range < 600)
	{
		luck = random();
		if (SLOTS_LEFT >= 2)
		{
			if (luck <= 0.40)
				self->monsterinfo.currentmove = &widow_move_attack_pre_blaster;
			else if ((luck <= 0.7) && !(level.time < self->timestamp))
			{
				gi.sound (self, CHAN_WEAPON, sound_rail, 1, ATTN_NORM, 0);
				self->monsterinfo.currentmove = &widow_move_attack_pre_rail;
			}
			else
				self->monsterinfo.currentmove = &widow_move_spawn;
		}
		else
		{
			if ((luck <= 0.50) || (level.time < self->timestamp))
				self->monsterinfo.currentmove = &widow_move_attack_pre_blaster;
			else
			{
				gi.sound (self, CHAN_WEAPON, sound_rail, 1, ATTN_NORM, 0);
				self->monsterinfo.currentmove = &widow_move_attack_pre_rail;
			}
		}
	}
	else
	{
		luck = random();
		if (SLOTS_LEFT >= 2)
		{
			if (luck < 0.3)
				self->monsterinfo.currentmove = &widow_move_attack_pre_blaster;
			else if ((luck < 0.65) || (level.time < self->timestamp))
				self->monsterinfo.currentmove = &widow_move_spawn;
			else
			{
				gi.sound (self, CHAN_WEAPON, sound_rail, 1, ATTN_NORM, 0);
				self->monsterinfo.currentmove = &widow_move_attack_pre_rail;
			}
		}
		else
		{
			if ((luck < 0.45) || (level.time < self->timestamp))
				self->monsterinfo.currentmove = &widow_move_attack_pre_blaster;
			else
			{
				gi.sound (self, CHAN_WEAPON, sound_rail, 1, ATTN_NORM, 0);
				self->monsterinfo.currentmove = &widow_move_attack_pre_rail;
			}
		}
	}
}
*/
void widow_attack_blaster (edict_t *self)
{
	self->monsterinfo.pausetime = level.time + 1.0 + (2.0*random());
//	self->monsterinfo.pausetime = level.time + 100;
//	self->plat2flags = 0;
	self->monsterinfo.currentmove = &widow_move_attack_blaster;
	self->monsterinfo.nextframe = WidowTorso (self);
}
Beispiel #2
0
void
widow_attack_blaster(edict_t *self)
{
	if (!self)
	{
		return;
	}

	self->monsterinfo.pausetime = level.time + 1.0 + (2.0 * random());
	self->monsterinfo.currentmove = &widow_move_attack_blaster;
	self->monsterinfo.nextframe = WidowTorso(self);
}
Beispiel #3
0
void WidowBlaster (edict_t *self)
{
	vec3_t	forward, right, target, vec, targ_angles;
	vec3_t	start;
	int		flashnum;
	int		effect;

	if (!self->enemy)
		return;

	shotsfired++;
	if (!(shotsfired % 4))
		effect = EF_BLASTER;
	else
		effect = 0;

	AngleVectors (self->s.angles, forward, right, NULL);
	if ((self->s.frame >= FRAME_spawn05) && (self->s.frame <= FRAME_spawn13))
	{
		// sweep
		flashnum = MZ2_WIDOW_BLASTER_SWEEP1 + self->s.frame - FRAME_spawn05;
		G_ProjectSource (self->s.origin, monster_flash_offset[flashnum], forward, right, start);
		VectorSubtract (self->enemy->s.origin, start, target);
		vectoangles2 (target, targ_angles);
		
		VectorCopy (self->s.angles, vec);

		vec[PITCH] += targ_angles[PITCH];
		vec[YAW] -= sweep_angles[flashnum-MZ2_WIDOW_BLASTER_SWEEP1];

		AngleVectors (vec, forward, NULL, NULL);
		monster_fire_blaster2 (self, start, forward, BLASTER2_DAMAGE*widow_damage_multiplier, 1000, flashnum, effect);
	}
	else if ((self->s.frame >= FRAME_fired02a) && (self->s.frame <= FRAME_fired20))
	{
		vec3_t angles;
		float aim_angle, target_angle;
		float error;

		self->monsterinfo.aiflags |= AI_MANUAL_STEERING;

		self->monsterinfo.nextframe = WidowTorso (self);

		if (!self->monsterinfo.nextframe)
			self->monsterinfo.nextframe = self->s.frame;

		if (self->s.frame == FRAME_fired02a)
			flashnum = MZ2_WIDOW_BLASTER_0;
		else
			flashnum = MZ2_WIDOW_BLASTER_100 + self->s.frame - FRAME_fired03;

		G_ProjectSource (self->s.origin, monster_flash_offset[flashnum], forward, right, start);

		PredictAim (self->enemy, start, 1000, true, ((random()*0.1)-0.05), forward, NULL);

		// clamp it to within 10 degrees of the aiming angle (where she's facing)
		vectoangles2 (forward, angles);
		// give me 100 -> -70
		aim_angle = 100 - (10*(flashnum-MZ2_WIDOW_BLASTER_100));
		if (aim_angle <= 0)
			aim_angle += 360;
		target_angle = self->s.angles[YAW] - angles[YAW];
		if (target_angle <= 0)
			target_angle += 360;

		error = aim_angle - target_angle;

		// positive error is to entity's left, aka positive direction in engine
		// unfortunately, I decided that for the aim_angle, positive was right.  *sigh*
		if (error > VARIANCE)
		{
			angles[YAW] = (self->s.angles[YAW] - aim_angle) + VARIANCE;
			AngleVectors (angles, forward, NULL, NULL);
		}
		else if (error < -VARIANCE)
		{
			angles[YAW] = (self->s.angles[YAW] - aim_angle) - VARIANCE;
			AngleVectors (angles, forward, NULL, NULL);
		}

		monster_fire_blaster2 (self, start, forward, BLASTER2_DAMAGE*widow_damage_multiplier, 1000, flashnum, effect);
	}
	else if ((self->s.frame >= FRAME_run01) && (self->s.frame <= FRAME_run08))
	{
		flashnum = MZ2_WIDOW_RUN_1 + self->s.frame - FRAME_run01;
		G_ProjectSource (self->s.origin, monster_flash_offset[flashnum], forward, right, start);
		
		VectorSubtract (self->enemy->s.origin, start, target);
		target[2] += self->enemy->viewheight;

		monster_fire_blaster2 (self, start, target, BLASTER2_DAMAGE*widow_damage_multiplier, 1000, flashnum, effect);
	}
}	
Beispiel #4
0
void WidowBlaster (edict_t *self)
{
	vec3_t	forward, right, target, vec, targ_angles;
	vec3_t	start, end;
	int		flashnum;
	int		effect;

	if (!self->enemy)
		return;

	shotsfired++;
	if (!(shotsfired % 4))
		effect = EF_BLASTER;
	else
		effect = 0;

	AngleVectors (self->s.angles, forward, right, NULL);
	if ((self->s.frame >= FRAME_spawn05) && (self->s.frame <= FRAME_spawn13))
	{
		// sweep
		flashnum = MZ2_WIDOW_BLASTER_SWEEP1 + self->s.frame - FRAME_spawn05;
		G_ProjectSource (self->s.origin, monster_flash_offset[flashnum], forward, right, start);
		VectorCopy(self->enemy->s.origin, end);

		// Lazarus fog reduction of accuracy
		if(self->monsterinfo.visibility < FOG_CANSEEGOOD)
		{
			end[0] += crandom() * 640 * (FOG_CANSEEGOOD - self->monsterinfo.visibility);
			end[1] += crandom() * 640 * (FOG_CANSEEGOOD - self->monsterinfo.visibility);
			end[2] += crandom() * 320 * (FOG_CANSEEGOOD - self->monsterinfo.visibility);
		}

		VectorSubtract (end, start, target);
		vectoangles2 (target, targ_angles);

		VectorCopy (self->s.angles, vec);

		vec[PITCH] += targ_angles[PITCH];
		vec[YAW] -= sweep_angles[flashnum-MZ2_WIDOW_BLASTER_SWEEP1];

		AngleVectors (vec, forward, NULL, NULL);
	//	monster_fire_blaster (self, start, forward, BLASTER2_DAMAGE*widow_damage_multiplier, 1000, flashnum, (effect!=0)?(effect|EF_TRACKER):0, BLASTER_GREEN);
		monster_fire_blaster2 (self, start, forward, BLASTER2_DAMAGE*widow_damage_multiplier, 1000, flashnum, effect);

/*		if (self->s.frame == FRAME_spawn13)
		{
			VectorMA (start, 1024, forward, debugend);

			gi.WriteByte (svc_temp_entity);
			gi.WriteByte (TE_DEBUGTRAIL);
			gi.WritePosition (start);
			gi.WritePosition (debugend);
			gi.multicast (start, MULTICAST_ALL);

			drawbbox (self);
			self->monsterinfo.aiflags |= AI_HOLD_FRAME|AI_MANUAL_STEERING;
		}
*/
	}
	else if ((self->s.frame >= FRAME_fired02a) && (self->s.frame <= FRAME_fired20))
	{
		vec3_t angles;
		float aim_angle, target_angle;
		float error;

		self->monsterinfo.aiflags |= AI_MANUAL_STEERING;

		self->monsterinfo.nextframe = WidowTorso (self);

		if (!self->monsterinfo.nextframe)
			self->monsterinfo.nextframe = self->s.frame;

//		if ((g_showlogic) && (g_showlogic->value))
//			gi.dprintf ("%d\n", self->monsterinfo.nextframe);

		if (self->s.frame == FRAME_fired02a)
			flashnum = MZ2_WIDOW_BLASTER_0;
		else
			flashnum = MZ2_WIDOW_BLASTER_100 + self->s.frame - FRAME_fired03;

		G_ProjectSource (self->s.origin, monster_flash_offset[flashnum], forward, right, start);

		PredictAim (self->enemy, start, 1000, true, ((random()*0.1)-0.05), forward, NULL);

		// clamp it to within 10 degrees of the aiming angle (where she's facing)
		vectoangles2 (forward, angles);
		// give me 100 -> -70
		aim_angle = 100 - (10*(flashnum-MZ2_WIDOW_BLASTER_100));
		if (aim_angle <= 0)
			aim_angle += 360;
		target_angle = self->s.angles[YAW] - angles[YAW];
		if (target_angle <= 0)
			target_angle += 360;

		error = aim_angle - target_angle;

		// positive error is to entity's left, aka positive direction in engine
		// unfortunately, I decided that for the aim_angle, positive was right.  *sigh*
		if (error > VARIANCE)
		{
//			if ((g_showlogic) && (g_showlogic->value))
//				gi.dprintf ("angle %2.2f (really %2.2f) (%2.2f off of %2.2f) corrected to", target_angle, angles[YAW], error, aim_angle);
			angles[YAW] = (self->s.angles[YAW] - aim_angle) + VARIANCE;
//			if ((g_showlogic) && (g_showlogic->value))
//			{
//				if (angles[YAW] <= 0)
//					angles[YAW] += 360;
//				gi.dprintf (" %2.2f\n", angles[YAW]);
//			}
			AngleVectors (angles, forward, NULL, NULL);
		}
		else if (error < -VARIANCE)
		{
//			if ((g_showlogic) && (g_showlogic->value))
//				gi.dprintf ("angle %2.2f (really %2.2f) (%2.2f off of %2.2f) corrected to", target_angle, angles[YAW], error, aim_angle);
			angles[YAW] = (self->s.angles[YAW] - aim_angle) - VARIANCE;
//			if ((g_showlogic) && (g_showlogic->value))
//			{
//				if (angles[YAW] <= 0)
//					angles[YAW] += 360;
//				gi.dprintf (" %2.2f\n", angles[YAW]);
//			}
			AngleVectors (angles, forward, NULL, NULL);
		}
//		gi.dprintf ("%2.2f - %2.2f - %2.2f - %2.2f\n", aim_angle, self->s.angles[YAW] - angles[YAW], target_angle, error);
//		gi.dprintf ("%2.2f - %2.2f - %2.2f\n", angles[YAW], aim_angle, self->s.angles[YAW]);

/*
		if (self->s.frame == FRAME_fired20)
		{
			VectorMA (start, 512, forward, debugend);
			gi.WriteByte (svc_temp_entity);
			gi.WriteByte (TE_DEBUGTRAIL);
			gi.WritePosition (start);
			gi.WritePosition (forward);
			gi.multicast (start, MULTICAST_ALL);

			drawbbox (self);
			self->monsterinfo.aiflags |= AI_HOLD_FRAME;
			self->monsterinfo.nextframe = FRAME_fired20;
			self->monsterinfo.aiflags |= AI_MANUAL_STEERING;
		}
*/
/*
		if (!(self->plat2flags % 3))
			effect = EF_HYPERBLASTER;
		else
			effect = 0;
		self->plat2flags ++;
*/
	//	monster_fire_blaster (self, start, forward, BLASTER2_DAMAGE*widow_damage_multiplier, 1000, flashnum, (effect!=0)?(effect|EF_TRACKER):0, BLASTER_GREEN);
		monster_fire_blaster2 (self, start, forward, BLASTER2_DAMAGE*widow_damage_multiplier, 1000, flashnum, effect);
	}
	else if ((self->s.frame >= FRAME_run01) && (self->s.frame <= FRAME_run08))
	{
		flashnum = MZ2_WIDOW_RUN_1 + self->s.frame - FRAME_run01;
		G_ProjectSource (self->s.origin, monster_flash_offset[flashnum], forward, right, start);
		VectorCopy(self->enemy->s.origin, end);

		// Lazarus fog reduction of accuracy
		if(self->monsterinfo.visibility < FOG_CANSEEGOOD)
		{
			end[0] += crandom() * 640 * (FOG_CANSEEGOOD - self->monsterinfo.visibility);
			end[1] += crandom() * 640 * (FOG_CANSEEGOOD - self->monsterinfo.visibility);
			end[2] += crandom() * 320 * (FOG_CANSEEGOOD - self->monsterinfo.visibility);
		}

		VectorSubtract (end, start, target);
		target[2] += self->enemy->viewheight;

	//	monster_fire_blaster (self, start, target, BLASTER2_DAMAGE*widow_damage_multiplier, 1000, flashnum, (effect!=0)?(effect|EF_TRACKER):0, BLASTER_GREEN);
		monster_fire_blaster2 (self, start, target, BLASTER2_DAMAGE*widow_damage_multiplier, 1000, flashnum, effect);
	}
//	else
//	{
//		if ((g_showlogic) && (g_showlogic->value))
//			gi.dprintf ("widow: firing on non-fire frame!\n");
//	}
}