Пример #1
0
void widow_attack (edict_t *self)
{
	float	luck;
	qboolean rail_frames = false, blaster_frames = false, blocked = false, anger = false;

	self->movetarget = NULL;

	if (self->monsterinfo.aiflags & AI_BLOCKED)
	{
		blocked = true;
		self->monsterinfo.aiflags &= ~AI_BLOCKED;
	}
	
	if (self->monsterinfo.aiflags & AI_TARGET_ANGER)
	{
		anger = true;
		self->monsterinfo.aiflags &= ~AI_TARGET_ANGER;
	}

	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 ((self->s.frame == FRAME_walk13) || ((self->s.frame >= FRAME_walk01) && (self->s.frame <= FRAME_walk03)))
		rail_frames = true;

	if ((self->s.frame >= FRAME_walk09) && (self->s.frame <= FRAME_walk12))
		blaster_frames = true;

	WidowCalcSlots(self);

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

	// accept bias towards spawning regardless of frame
	if (blocked && (SELF_SLOTS_LEFT >= 2))
	{
		self->monsterinfo.currentmove = &widow_move_spawn;
		return;
	}

	if ((realrange(self, self->enemy) > 300) && (!anger) && (random() < 0.5)  && (!blocked))
	{
		self->monsterinfo.currentmove = &widow_move_run_attack;
		return;
	}

	if (blaster_frames)
	{
		if (SELF_SLOTS_LEFT >= 2)
		{
			self->monsterinfo.currentmove = &widow_move_spawn;
			return;
		}
		else if (self->monsterinfo.pausetime + BLASTER_TIME <= level.time)
		{
			self->monsterinfo.currentmove = &widow_move_attack_pre_blaster;
			return;
		}
	}

	if (rail_frames)
	{
		if (!(level.time < self->timestamp))
		{
			gi.sound (self, CHAN_WEAPON, sound_rail, 1, ATTN_NORM, 0);
			self->monsterinfo.currentmove = &widow_move_attack_pre_rail;
		}
	}

	if ((rail_frames) || (blaster_frames))
		return;

	luck = random();
	if (SELF_SLOTS_LEFT >= 2)
	{
		if ((luck <= 0.40) && (self->monsterinfo.pausetime + BLASTER_TIME <= level.time))
			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 (level.time < self->timestamp)
			self->monsterinfo.currentmove = &widow_move_attack_pre_blaster;
		else if ((luck <= 0.50) || (level.time + BLASTER_TIME >= self->monsterinfo.pausetime))
		{
			gi.sound (self, CHAN_WEAPON, sound_rail, 1, ATTN_NORM, 0);
			self->monsterinfo.currentmove = &widow_move_attack_pre_rail;
		}
		else // holdout to blaster
			self->monsterinfo.currentmove = &widow_move_attack_pre_blaster;
	}
}
Пример #2
0
/*QUAKED monster_widow (1 .5 0) (-40 -40 0) (40 40 144) Ambush Trigger_Spawn Sight
*/
void SP_monster_widow (edict_t *self)
{
	if (deathmatch->value)
	{
		G_FreeEdict (self);
		return;
	}

	sound_pain1 = gi.soundindex ("widow/bw1pain1.wav");
	sound_pain2 = gi.soundindex ("widow/bw1pain2.wav");
	sound_pain3 = gi.soundindex ("widow/bw1pain3.wav");
	sound_search1 = gi.soundindex ("bosshovr/bhvunqv1.wav");
	sound_rail = gi.soundindex ("gladiator/railgun.wav");

	self->movetype = MOVETYPE_STEP;
	self->solid = SOLID_BBOX;
	self->s.modelindex = gi.modelindex ("models/monsters/blackwidow/tris.md2");
	VectorSet (self->mins, -40, -40, 0);
	VectorSet (self->maxs, 40, 40, 144);

	self->health = 2000 + 1000*(skill->value);
	if (coop->value)
		self->health += 500*(skill->value);
	self->gib_health = -5000;
	self->mass = 1500;
	if (skill->value == 3)
	{
		self->monsterinfo.power_armor_type = POWER_ARMOR_SHIELD;
		self->monsterinfo.power_armor_power = 500;
	}

	self->yaw_speed = 30;
	
	self->flags |= FL_IMMUNE_LASER;
	self->monsterinfo.aiflags |= AI_IGNORE_SHOTS;

	self->pain = widow_pain;
	self->die = widow_die;

	self->monsterinfo.melee = widow_melee;
	self->monsterinfo.stand = widow_stand;
	self->monsterinfo.walk = widow_walk;
	self->monsterinfo.run = widow_run;
	self->monsterinfo.attack = widow_attack;
	self->monsterinfo.search = widow_search;
	self->monsterinfo.checkattack = Widow_CheckAttack;
	self->monsterinfo.sight = widow_sight;
	
	self->monsterinfo.blocked = widow_blocked;

	gi.linkentity (self);

	self->monsterinfo.currentmove = &widow_move_stand;	
	self->monsterinfo.scale = MODEL_SCALE;

	WidowPrecache();
	WidowCalcSlots(self);
	widow_damage_multiplier = 1;

	walkmonster_start (self);
}
Пример #3
0
/*
 * QUAKED monster_widow (1 .5 0) (-40 -40 0) (40 40 144) Ambush Trigger_Spawn Sight
 */
void
SP_monster_widow(edict_t *self)
{
	if (!self)
	{
		return;
	}

	/* ace - monsters spawned with FL_RMONSTER will get converted	*
	 * to a random spawn spot for the randomizer system.  Class		*
	 * and tier will be tallied, origin, angles, spawnflags, etc..	*
	 * will also be recorded.  This entity will be freed after.		*/
/*	if (self->flags & FL_RMONSTER)
	{
		SP_monster_rspawnspot (self);
		return;
	} */

	if (deathmatch->value)
	{
		G_FreeEdict(self);
		return;
	}

	sound_pain1 = gi.soundindex("widow/bw1pain1.wav");
	sound_pain2 = gi.soundindex("widow/bw1pain2.wav");
	sound_pain3 = gi.soundindex("widow/bw1pain3.wav");
	sound_search1 = gi.soundindex("bosshovr/bhvunqv1.wav");
	sound_rail = gi.soundindex("gladiator/railgun.wav");

	self->movetype = MOVETYPE_STEP;
	self->solid = SOLID_BBOX;
	self->s.modelindex = gi.modelindex("models/monsters/blackwidow/tris.md2");
	VectorSet(self->mins, -40, -40, 0);
	VectorSet(self->maxs, 40, 40, 144);

	self->health = 2000 + 1000 * (skill->value);

	if (coop->value)
	{
		self->health += 500 * (skill->value);
	}

	self->gib_health = -5000;
	self->mass = 1500;

	if (skill->value == 3)
	{
		self->monsterinfo.power_armor_type = POWER_ARMOR_SHIELD;
		self->monsterinfo.power_armor_power = 500;
	}

	self->yaw_speed = 30;

	self->flags |= FL_IMMUNE_LASER;
	self->monsterinfo.aiflags |= AI_IGNORE_SHOTS;

	self->pain = widow_pain;
	self->die = widow_die;

	self->monsterinfo.melee = widow_melee;
	self->monsterinfo.stand = widow_stand;
	self->monsterinfo.walk = widow_walk;
	self->monsterinfo.run = widow_run;
	self->monsterinfo.attack = widow_attack;
	self->monsterinfo.search = widow_search;
	self->monsterinfo.checkattack = Widow_CheckAttack;
	self->monsterinfo.sight = widow_sight;

	self->monsterinfo.blocked = widow_blocked;

	gi.linkentity(self);

	self->monsterinfo.currentmove = &widow_move_stand;
	self->monsterinfo.scale = MODEL_SCALE;

	WidowPrecache();
	WidowCalcSlots(self);
	widow_damage_multiplier = 1;

	walkmonster_start(self);
}
Пример #4
0
void
widow2_attack(edict_t *self)
{
	float range, luck;
	qboolean blocked = false;

	if (!self)
	{
		return;
	}

	if (self->monsterinfo.aiflags & AI_BLOCKED)
	{
		blocked = true;
		self->monsterinfo.aiflags &= ~AI_BLOCKED;
	}

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

	if (self->bad_area)
	{
		if ((random() < 0.75) || (level.time < self->monsterinfo.attack_finished))
		{
			self->monsterinfo.currentmove = &widow2_move_attack_pre_beam;
		}
		else
		{
			self->monsterinfo.currentmove = &widow2_move_attack_disrupt;
		}

		return;
	}

	WidowCalcSlots(self);

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

	/* accept bias towards spawning */
	if (blocked && (SELF_SLOTS_LEFT >= 2))
	{
		self->monsterinfo.currentmove = &widow2_move_spawn;
		return;
	}

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

	if (range < 600)
	{
		luck = random();

		if (SELF_SLOTS_LEFT >= 2)
		{
			if (luck <= 0.40)
			{
				self->monsterinfo.currentmove = &widow2_move_attack_pre_beam;
			}
			else if ((luck <= 0.7) && !(level.time < self->monsterinfo.attack_finished))
			{
				self->monsterinfo.currentmove = &widow2_move_attack_disrupt;
			}
			else
			{
				self->monsterinfo.currentmove = &widow2_move_spawn;
			}
		}
		else
		{
			if ((luck <= 0.50) || (level.time < self->monsterinfo.attack_finished))
			{
				self->monsterinfo.currentmove = &widow2_move_attack_pre_beam;
			}
			else
			{
				self->monsterinfo.currentmove = &widow2_move_attack_disrupt;
			}
		}
	}
	else
	{
		luck = random();

		if (SELF_SLOTS_LEFT >= 2)
		{
			if (luck < 0.3)
			{
				self->monsterinfo.currentmove = &widow2_move_attack_pre_beam;
			}
			else if ((luck < 0.65) || (level.time < self->monsterinfo.attack_finished))
			{
				self->monsterinfo.currentmove = &widow2_move_spawn;
			}
			else
			{
				self->monsterinfo.currentmove = &widow2_move_attack_disrupt;
			}
		}
		else
		{
			if ((luck < 0.45) || (level.time < self->monsterinfo.attack_finished))
			{
				self->monsterinfo.currentmove = &widow2_move_attack_pre_beam;
			}
			else
			{
				self->monsterinfo.currentmove = &widow2_move_attack_disrupt;
			}
		}
	}
}
Пример #5
0
/*
 * QUAKED monster_widow2 (1 .5 0) (-70 -70 0) (70 70 144) Ambush Trigger_Spawn Sight
 */
void
SP_monster_widow2(edict_t *self)
{
	if (!self)
	{
		return;
	}

	if (deathmatch->value)
	{
		G_FreeEdict(self);
		return;
	}

	sound_pain1 = gi.soundindex("widow/bw2pain1.wav");
	sound_pain2 = gi.soundindex("widow/bw2pain2.wav");
	sound_pain3 = gi.soundindex("widow/bw2pain3.wav");
	sound_death = gi.soundindex("widow/death.wav");
	sound_search1 = gi.soundindex("bosshovr/bhvunqv1.wav");
	sound_tentacles_retract = gi.soundindex("brain/brnatck3.wav");

	self->movetype = MOVETYPE_STEP;
	self->solid = SOLID_BBOX;
	self->s.modelindex = gi.modelindex("models/monsters/blackwidow2/tris.md2");
	VectorSet(self->mins, -70, -70, 0);
	VectorSet(self->maxs, 70, 70, 144);

	self->health = 2000 + 800 + 1000 * (skill->value);

	if (coop->value)
	{
		self->health += 500 * (skill->value);
	}

	self->gib_health = -900;
	self->mass = 2500;

	if (skill->value == 3)
	{
		self->monsterinfo.power_armor_type = POWER_ARMOR_SHIELD;
		self->monsterinfo.power_armor_power = 750;
	}

	self->yaw_speed = 30;

	self->flags |= FL_IMMUNE_LASER;
	self->monsterinfo.aiflags |= AI_IGNORE_SHOTS;

	self->pain = widow2_pain;
	self->die = widow2_die;

	self->monsterinfo.melee = widow2_melee;
	self->monsterinfo.stand = widow2_stand;
	self->monsterinfo.walk = widow2_walk;
	self->monsterinfo.run = widow2_run;
	self->monsterinfo.attack = widow2_attack;
	self->monsterinfo.search = widow2_search;
	self->monsterinfo.checkattack = Widow2_CheckAttack;
	gi.linkentity(self);

	self->monsterinfo.currentmove = &widow2_move_stand;
	self->monsterinfo.scale = MODEL_SCALE;

	Widow2Precache();
	WidowCalcSlots(self);
	walkmonster_start(self);
}
Пример #6
0
/*QUAKED monster_widow (1 .5 0) (-40 -40 0) (40 40 144) Ambush Trigger_Spawn Sight GoodGuy
*/
void SP_monster_widow (edict_t *self)
{
	if (deathmatch->value)
	{
		G_FreeEdict (self);
		return;
	}

	sound_pain1 = gi.soundindex ("widow/bw1pain1.wav");
	sound_pain2 = gi.soundindex ("widow/bw1pain2.wav");
	sound_pain3 = gi.soundindex ("widow/bw1pain3.wav");
	sound_search1 = gi.soundindex ("bosshovr/bhvunqv1.wav");
//	sound_sight	= gi.soundindex ("widow/sight.wav");
	sound_rail = gi.soundindex ("gladiator/railgun.wav");

//	self->s.sound = gi.soundindex ("bosshovr/bhvengn1.wav");

	self->movetype = MOVETYPE_STEP;
	self->solid = SOLID_BBOX;

	// Lazarus: special purpose skins
	if ( self->style )
	{
		PatchMonsterModel("models/monsters/blackwidow/tris.md2");
		self->s.skinnum = self->style * 2;
	//	self->style = 0; //clear for custom bloodtype flag
	}

	self->s.modelindex = gi.modelindex ("models/monsters/blackwidow/tris.md2");
	VectorSet (self->mins, -40, -40, 0);
	VectorSet (self->maxs, 40, 40, 144);

	if(!self->health)
		self->health = 2000 + 1000*(skill->value);
	if (coop->value)
		self->health += 500*(skill->value);
//	self->health = 1;
	if(!self->gib_health)
		self->gib_health = -5000;
	if(!self->mass)
		self->mass = 1500;
/*
	if (skill->value == 2)
	{
		self->monsterinfo.power_armor_type = POWER_ARMOR_SHIELD;
		self->monsterinfo.power_armor_power = 250;
	}
	else */if (skill->value == 3)
	{
		self->monsterinfo.power_armor_type = POWER_ARMOR_SHIELD;
		self->monsterinfo.power_armor_power = 500;
	}

	self->yaw_speed = 30;

	self->flags |= FL_IMMUNE_LASER;
	self->monsterinfo.aiflags |= AI_IGNORE_SHOTS;

	self->pain = widow_pain;
	self->die = widow_die;

	self->monsterinfo.melee = widow_melee;
	self->monsterinfo.stand = widow_stand;
	self->monsterinfo.walk = widow_walk;
	self->monsterinfo.run = widow_run;
	self->monsterinfo.attack = widow_attack;
	self->monsterinfo.search = widow_search;
	self->monsterinfo.checkattack = Widow_CheckAttack;
	self->monsterinfo.sight = widow_sight;
	self->monsterinfo.blocked = widow_blocked;

	if (!self->blood_type)
		self->blood_type = 3; //sparks and blood

	// Lazarus
	if(self->powerarmor)
	{
		if (self->powerarmortype == 1)
			self->monsterinfo.power_armor_type = POWER_ARMOR_SCREEN;
		else
			self->monsterinfo.power_armor_type = POWER_ARMOR_SHIELD;
		self->monsterinfo.power_armor_power = self->powerarmor;
	}
	self->common_name = "Black Widow";

	gi.linkentity (self);

	self->monsterinfo.currentmove = &widow_move_stand;
	self->monsterinfo.scale = MODEL_SCALE;

	WidowPrecache();
	WidowCalcSlots(self);
	widow_damage_multiplier = 1;

	walkmonster_start (self);
}