Esempio n. 1
0
void CNihilanth :: HuntThink( void )
{
	pev->nextthink = gpGlobals->time + 0.1;
	DispatchAnimEvents( );
	StudioFrameAdvance( );

	ShootBalls( );

	// if dead, force cancelation of current animation
	if (pev->health <= 0)
	{
		SetThink( DyingThink );
		m_fSequenceFinished = TRUE;
		return;
	}

	// ALERT( at_console, "health %.0f\n", pev->health );

	// if damaged, try to abosorb some spheres
	if (pev->health < gSkillData.nihilanthHealth && AbsorbSphere( ))
	{
		pev->health += gSkillData.nihilanthHealth / N_SPHERES;
	}

	// get new sequence
	if (m_fSequenceFinished)
	{
		// if (!m_fSequenceLoops)
		pev->frame = 0;
		NextActivity( );
		ResetSequenceInfo( );
		pev->framerate = 2.0 - 1.0 * (pev->health / gSkillData.nihilanthHealth);
	}

	// look for current enemy	
	if (m_hEnemy != NULL && m_hRecharger == NULL)
	{
		if (FVisible( m_hEnemy ))
		{
			if (m_flLastSeen < gpGlobals->time - 5)
				m_flPrevSeen = gpGlobals->time;
			m_flLastSeen = gpGlobals->time;
			m_posTarget = m_hEnemy->pev->origin;
			m_vecTarget = (m_posTarget - pev->origin).Normalize();
			m_vecDesired = m_vecTarget;
			m_posDesired = Vector( pev->origin.x, pev->origin.y, m_posTarget.z + m_flAdj );
		}
		else
		{
			m_flAdj = min( m_flAdj + 10, 1000 );
		}
	}

	// don't go too high
	if (m_posDesired.z > m_flMaxZ)
		m_posDesired.z = m_flMaxZ;

	// don't go too low
	if (m_posDesired.z < m_flMinZ)
		m_posDesired.z = m_flMinZ;

	Flight( );
}
Esempio n. 2
0
void AvHBaseBuildable::PlayAnimationAtIndex(int inIndex, bool inForce, float inFrameRate)
{
	// Only play animations on buildings that we have artwork for
	bool thePlayAnim = false;

	if(inIndex >= 0)
	{
		switch(this->mMessageID)
		{
		case BUILD_RESOURCES:
		case BUILD_ARMSLAB:
		case BUILD_COMMANDSTATION:
		case BUILD_INFANTRYPORTAL:
		case BUILD_TURRET_FACTORY:
		case TURRET_FACTORY_UPGRADE:
		case BUILD_ARMORY:
		case ARMORY_UPGRADE:
		case BUILD_OBSERVATORY:
		case BUILD_TURRET:
		case BUILD_SIEGE:
		case BUILD_PROTOTYPE_LAB:
		case ALIEN_BUILD_HIVE:
		case ALIEN_BUILD_RESOURCES:
		case ALIEN_BUILD_OFFENSE_CHAMBER:
		case ALIEN_BUILD_DEFENSE_CHAMBER:
		case ALIEN_BUILD_SENSORY_CHAMBER:
		case ALIEN_BUILD_MOVEMENT_CHAMBER:
			thePlayAnim = true;
		}
	}

	// Make sure we're not interrupting another animation
	if(thePlayAnim)
	{
		// Allow forcing of new animation, but it's better to complete current animation then interrupt it and play it again
		float theCurrentTime = gpGlobals->time;
		if((theCurrentTime >= this->mTimeAnimationDone) || (inForce && (inIndex != this->mLastAnimationPlayed)))
		{
			this->pev->sequence	= inIndex;
			this->pev->frame = 0;
			ResetSequenceInfo();

            this->pev->framerate = inFrameRate;

            // Set to last frame to play backwards
            if(this->pev->framerate < 0)
            {
                this->pev->frame = 255;
            }

			this->mLastAnimationPlayed = inIndex;
			float theTimeForAnim = this->GetTimeForAnimation(inIndex);
			this->mTimeAnimationDone = theCurrentTime + theTimeForAnim;
			
			// Recalculate size
			//Vector theMinSize, theMaxSize;
			//this->ExtractBbox(this->pev->sequence, (float*)&theMinSize, (float*)&theMaxSize);
			//UTIL_SetSize(this->pev, theMinSize, theMaxSize); 
		}
	}
}
Esempio n. 3
0
void CSqueakGrenade :: Spawn( void )
{
	Precache( );
	// motor
	pev->movetype = MOVETYPE_BOUNCE;
	pev->solid = SOLID_BBOX;

	inceptionDepth = 0;
	isStill = false;
	float health = gSkillData.snarkHealth;

	SET_MODEL(ENT(pev), "models/w_squeak.mdl");
	UTIL_SetSize(pev, Vector( -4, -4, 0), Vector(4, 4, 8));

	if ( auto depth = gameplayMods::snarkInception.isActive<int>() ) {
		inceptionDepth = *depth;
	}
	isPenguin = gameplayMods::snarkPenguins.isActive();
	if ( isPenguin ) {
		SET_MODEL(ENT(pev), "models/w_pingu.mdl");
		UTIL_SetSize(pev, Vector( -6, -6, 0), Vector(6, 6, 20));
		health = gSkillData.headcrabHealth;
		if ( !gameplayMods::snarkNuclear.isActive() ) {
			pev->skin = 1;
			SetBodygroup( 1, 1 );
		}
	}
	
	UTIL_SetOrigin( pev, pev->origin );

	SetTouch( &CSqueakGrenade::SuperBounceTouch );
	SetThink( &CSqueakGrenade::HuntThink );
	pev->nextthink = gpGlobals->time + 0.1;
	m_flNextHunt = gpGlobals->time + 1E6;

	pev->flags |= FL_MONSTER;
	pev->takedamage		= DAMAGE_AIM;
	pev->health			= health;
	pev->gravity		= 0.5;
	pev->friction		= 0.5;

	pev->dmg = gSkillData.snarkDmgPop;

	m_flDie = gpGlobals->time + SQUEEK_DETONATE_DELAY;

	m_flFieldOfView = 0; // 180 degrees

	if ( pev->owner )
		m_hOwner = Instance( pev->owner );

	m_flNextBounceSoundTime = gpGlobals->time;// reset each time a snark is spawned.

	pev->sequence = WSQUEAK_RUN;
	ResetSequenceInfo( );

	canBeInvisible = TRUE;
	isInvisible = FALSE;
	formerRenderAmount = pev->renderamt;
	formerRenderMode = pev->rendermode;
	ToggleInvisibility();
}
//=========================================================
//=========================================================
void CHornet::Spawn(void)
{
	Precache();

	pev->movetype = MOVETYPE_FLY;
	pev->solid = SOLID_BBOX;
	pev->takedamage = DAMAGE_YES;
	pev->flags |= FL_MONSTER;
	pev->health = 1;// weak!

	if (g_pGameRules->IsMultiplayer())
	{
		// hornets don't live as long in multiplayer
		m_flStopAttack = gpGlobals->time + 3.5;
	}
	else
	{
		m_flStopAttack = gpGlobals->time + 5.0;
	}

	m_flFieldOfView = 0.9; // +- 25 degrees

	if (RANDOM_LONG(1, 5) <= 2)
	{
		m_iHornetType = HORNET_TYPE_RED;
		m_flFlySpeed = HORNET_RED_SPEED;
	}
	else
	{
		m_iHornetType = HORNET_TYPE_ORANGE;
		m_flFlySpeed = HORNET_ORANGE_SPEED;
	}

	SET_MODEL(ENT(pev), "models/hornet.mdl");
	UTIL_SetSize(pev, Vector(-4, -4, -4), Vector(4, 4, 4));

	SetTouch(&CHornet::DieTouch);
	SetThink(&CHornet::StartTrack);

	edict_t *pSoundEnt = pev->owner;
	if (!pSoundEnt)
		pSoundEnt = edict();

	switch (RANDOM_LONG(0, 2))
	{
	case 0:	EMIT_SOUND(pSoundEnt, CHAN_WEAPON, "agrunt/ag_fire1.wav", 1, ATTN_NORM);	break;
	case 1:	EMIT_SOUND(pSoundEnt, CHAN_WEAPON, "agrunt/ag_fire2.wav", 1, ATTN_NORM);	break;
	case 2:	EMIT_SOUND(pSoundEnt, CHAN_WEAPON, "agrunt/ag_fire3.wav", 1, ATTN_NORM);	break;
	}

	if (!FNullEnt(pev->owner) && (pev->owner->v.flags & FL_CLIENT))
	{
		pev->dmg = gSkillData.plrDmgHornet;
	}
	else
	{
		// no real owner, or owner isn't a client. 
		pev->dmg = gSkillData.monDmgHornet;
	}

	SetNextThink(0.1);
	ResetSequenceInfo();
}
Esempio n. 5
0
//=========================================================
// SetActivity 
//=========================================================
void CFriend :: SetActivity ( Activity NewActivity )
{
	int	iSequence = ACTIVITY_NOT_AVAILABLE;
	void *pmodel = GET_MODEL_PTR( ENT(pev) );

	switch ( NewActivity)
	{
	case ACT_RANGE_ATTACK1:
					
//		if (RANDOM_LONG(0,1))
//		{
//			iSequence = LookupSequence( "throwgrenade" );
//		}
//		else
//		{
			if (pev->frags)
			{
				iSequence = LookupSequence( "standing_shotgun" );
			}
			else
			{
				iSequence = LookupSequence( "standing_mp5" );
			}
//		}
		break;

	case ACT_RANGE_ATTACK2:
		// grunt is going to a secondary long range attack. This may be a thrown 
		// grenade or fired grenade, we must determine which and pick proper sequence
		// get toss anim
		iSequence = LookupSequence( "throwgrenade" );
		break;

	case ACT_RUN:
		if ( pev->health <= LIMP_HEALTH )
		{
			// limp!
			iSequence = LookupActivity ( ACT_RUN_HURT );
		}
		else
		{
			iSequence = LookupActivity ( NewActivity );
		}
		break;
	case ACT_WALK:
		if ( pev->health <= LIMP_HEALTH )
		{
			// limp!
			iSequence = LookupActivity ( ACT_WALK_HURT );
		}
		else
		{
			iSequence = LookupActivity ( NewActivity );
		}
		break;
	case ACT_IDLE:
		if ( m_MonsterState == MONSTERSTATE_COMBAT )
		{
			NewActivity = ACT_IDLE_ANGRY;
		}
		iSequence = LookupActivity ( NewActivity );
		break;
	default:
		iSequence = LookupActivity ( NewActivity );
		break;
	}
	
	m_Activity = NewActivity; // Go ahead and set this so it doesn't keep trying when the anim is not present

	// Set to the desired anim, or default anim if the desired is not present
	if ( iSequence > ACTIVITY_NOT_AVAILABLE )
	{
		if ( pev->sequence != iSequence || !m_fSequenceLoops )
		{
			pev->frame = 0;
		}

		pev->sequence		= iSequence;	// Set to the reset anim (if it's there)
		ResetSequenceInfo( );
		SetYawSpeed();
	}
	else
	{
		// Not available try to get default anim
		ALERT ( at_console, "%s has no sequence for act:%d\n", STRING(pev->classname), NewActivity );
		pev->sequence		= 0;	// Set to the reset anim (if it's there)
	}
}
Esempio n. 6
0
void CFuncMachinegun::PostFrame( CBasePlayer *pActivator )
{
	Vector plAngles = pActivator->pev->angles;
	while (plAngles.y < 0) plAngles.y += 360;

	float yawAngle = plAngles.y - pev->angles.y;
	float pitchAngle = pActivator->pev->angles.x * -3;
	SetBoneController( 0, yawAngle );
	SetBoneController( 1, pitchAngle );
	StudioFrameAdvance();

	// return to idle after fire anim
	if (m_fSequenceFinished)
	{
		pev->sequence	= TURRET_IDLE;
		pev->frame	= 0;
		ResetSequenceInfo();
		m_fSequenceLoops = TRUE;
	}

	if ( gpGlobals->time < m_flNextAttack )
		return;

	if ( pActivator->pev->button & IN_ATTACK && (m_iAmmo > 0 || m_iAmmo == -1))
	{
	// fire
		Vector vecForward, vecSrc, vecAngles;
		vecAngles = pActivator->pev->angles;
		vecAngles.x = vecAngles.x * -3; // invert anf scale pitch
		UTIL_MakeVectorsPrivate( vecAngles, vecForward, NULL, NULL );
		GetAttachment(0, vecSrc, vecAngles);

		pev->sequence = TURRET_SHOOT_SOLID; // sounds, muzzleflashes, and shells will go by anim event
		pev->frame = 0;
		ResetSequenceInfo();
		m_fSequenceLoops = FALSE;
	
		switch( m_projectileType )
		{
			default:
			case TANK_BULLET_9MM:
				FireMagnumBullets(vecSrc, vecForward, VECTOR_CONE_6DEGREES, 16384, BULLET_9MM, pActivator->pev);
			break;

			case TANK_BULLET_12MM:
				FireMagnumBullets(vecSrc, vecForward, VECTOR_CONE_6DEGREES, 16384, BULLET_12MM, pActivator->pev);
			break;

			case TANK_BULLET_14MM:
				FireMagnumBullets(vecSrc, vecForward, VECTOR_CONE_7DEGREES, 16384, BULLET_14MM, pActivator->pev);
			break;

			case TANK_BULLET_BUCKSHOT:
				for ( i = 0; i < 8; i++ )
				FireMagnumBullets(vecSrc, vecForward, VECTOR_CONE_10DEGREES, 16384, BULLET_BUCKSHOT, pActivator->pev);
			break;

			case TANK_BULLET_12G:
				for ( i = 0; i < 4; i++ )
				FireMagnumBullets(vecSrc, vecForward, VECTOR_CONE_15DEGREES, 16384, BULLET_12G, pActivator->pev);
			break;

			case TANK_BULLET_57MM:
				FireMagnumBullets(vecSrc, vecForward, VECTOR_CONE_2DEGREES, 16384, BULLET_57mm, pActivator->pev);
			break;

			case TANK_BULLET_762NATO:
				FireMagnumBullets(vecSrc, vecForward, VECTOR_CONE_3DEGREES, 16384, BULLET_762Nato, pActivator->pev);
			break;

			case TANK_BULLET_338MAGNUM:
				FireMagnumBullets(vecSrc, vecForward, VECTOR_CONE_0DEGREES, 16384, BULLET_338Magnum, pActivator->pev);
			break;

			case TANK_BULLET_762X54:
				FireMagnumBullets(vecSrc, vecForward, VECTOR_CONE_4DEGREES, 16384, BULLET_762x54, pActivator->pev);
			break;

			case TANK_BULLET_86MM:
				FireMagnumBullets(vecSrc, vecForward, VECTOR_CONE_8DEGREES, 16384, BULLET_86mm, pActivator->pev);
			break;

			case TANK_BULLET_32MM:
				FireMagnumBullets(vecSrc, vecForward, VECTOR_CONE_5DEGREES, 16384, BULLET_32mm, pActivator->pev);
			break;

			case TANK_BULLET_127MM:
				FireMagnumBullets(vecSrc, vecForward, VECTOR_CONE_1DEGREES, 16384, BULLET_127MM, pActivator->pev);
			break;

			case TANK_BULLET_BFG:
				for ( i = 0; i < 8; i++ )
				FireMagnumBullets(vecSrc, vecForward, VECTOR_CONE_40DEGREES, 16384, BULLET_BFG, pActivator->pev);
			break;

			case TANK_BULLET_NAIL:
				FireMagnumBullets(vecSrc, vecForward, VECTOR_CONE_0DEGREES, 16384, BULLET_NAILGUN, pActivator->pev);
			break;

			case TANK_BULLET_BOLT:
				CBolt::ShootBolt(pActivator->pev, vecSrc + vecForward*16, vecForward * 5000, 0 );
			break;

			case TANK_ENERGY_HOMINGSHOCK:
				CShock::ShootShock(pActivator->pev, vecSrc + vecForward*16, vecForward * 400, FALSE );
			break;

			case TANK_ENERGY_SHOCK:
				CShock::ShootShock(pActivator->pev, vecSrc + vecForward*16, vecForward * 700, TRUE );
			break;

			case TANK_ENERGY_PLASMA:
				CPlasma::ShootPlasma(pActivator->pev, vecSrc + vecForward*16, vecForward * 20000 );
			break;

			case TANK_ENERGY_PLASMALARGE:
				CPlasma2::ShootPlasma2(pActivator->pev, vecSrc + vecForward*16, vecForward * 20000 );
			break;

			case TANK_ENERGY_FLAME:
				CFlame::ShootFlame(pActivator->pev, vecSrc + vecForward*16, vecForward * 900 );
			break;

			case TANK_ENERGY_ECHARGE:
				CEnergycharge::ShootEnergycharge(pActivator->pev, vecSrc + vecForward*16, vecForward * 8000);
			break;

			case TANK_ENERGY_FROSTBALL:
				CFrostball::ShootFrostball(pActivator->pev, vecSrc + vecForward*16, vecForward * 5000);
			break;

			case TANK_ENERGY_GLUON:
				CGluon::ShootGluon(pActivator->pev, vecSrc + vecForward*16, vecForward * 2500 );
			break;

			case TANK_ENERGY_GLUONLARGE:
				CGluon2::ShootGluon2(pActivator->pev, vecSrc + vecForward*16, vecForward * 6800, 10);
			break;
	
			case TANK_ENERGY_DISPBALL_HALF:
				CDispball::ShootDispball(pActivator->pev, vecSrc + vecForward*16, vecForward * 3000, 1);
			break;

			case TANK_ENERGY_DISPBALL_FULL:
				CDispball::ShootDispball(pActivator->pev, vecSrc + vecForward*16, vecForward * 1500, 2);
			break;

			case TANK_ENERGY_PBOLT:
				CPBolt::ShootPBolt(pActivator->pev, vecSrc + vecForward*16, vecForward * 15000 );
			break;

			case TANK_ROCKET_XBOLT:
				CBolt::ShootBolt(pActivator->pev, vecSrc + vecForward*16, vecForward * 7500, 2);
			break;

			case TANK_ROCKET_CLUSTER:
				CClMomma::ShootClusterMomma(pActivator->pev, vecSrc + vecForward*16, vecForward * 1250, 3 );
			break;

			case TANK_ROCKET_M203GREN:
				CM203grenade::ShootM203grenade(pActivator->pev, vecSrc + vecForward*16, vecForward * 1800);
			break;

			case TANK_ROCKET_AK74GREN:
				CAK74grenade::ShootAK74grenade(pActivator->pev, vecSrc + vecForward*16, vecForward * 4000);
			break;

			case TANK_ROCKET_HANDGREN:
				CGrenade::ShootGrenade(pActivator->pev, vecSrc + vecForward*16, vecForward * 1500, 3.5);
			break;

			case TANK_ROCKET_NGGREN:
				CNGgrenade::ShootNGgrenade(pActivator->pev, vecSrc + vecForward*16, vecForward * 2000, 3 );
			break;

			case TANK_ROCKET_U2:
				CU2Momma::ShootU2Momma(pActivator->pev, vecSrc + vecForward*16, vecForward * 900, 1 );
			break;

			case TANK_ROCKET_TESLAGREN:
				CTeslagren::ShootTeslagren(pActivator->pev, vecSrc + vecForward*16, vecForward * 3000);
			break;

			case TANK_ROCKET_MMISSILE:
				CMmissile::ShootMmissile(pActivator->pev, vecSrc + vecForward*16, vecForward * 5250 );
			break;

			case TANK_ROCKET_DEMOLITION:
				CWhlProjectile::ShootWhlProjectile(pActivator->pev, vecSrc + vecForward*16, vecForward * 2250, FALSE );
			break;

			case TANK_ROCKET_RPG:
				CRpgRocket::ShootRpgRocket(pActivator->pev, vecSrc + vecForward*16, vecForward * 2500, FALSE, NULL);
			break;
        
			case TANK_ROCKET_DUMBFIRE:
				CDumbfire::ShootDumbfire(pActivator->pev, vecSrc + vecForward*16, vecForward * 250);
			break;

			case TANK_ROCKET_HELLFIRE:
				Chellfire::ShootHellfire(pActivator->pev, vecSrc + vecForward*16, vecForward * 300, TRUE);
			break;

			case TANK_MORTAR:
				CTankProj::ShootTankProj(pActivator->pev, vecSrc + vecForward*16, vecForward * 100000);
			break;

			case TANK_ROCKET_NUKE:
				CNuke::ShootNuke(pActivator->pev, vecSrc + vecForward*16, vecForward * 1500, FALSE);
			break;

			case TANK_ROCKET_NUKE_CONTROLLED:
				CNuke::ShootNuke(pActivator->pev, vecSrc + vecForward*16, vecForward * 800, TRUE);
			break;

			case TANK_ROCKET_FLAKBOMB:
				CFlakBomb::ShootFlakBomb(pActivator->pev, vecSrc + vecForward*16, vecForward * 1800);
			break;

			case TANK_ROCKET_30MMGREN:
				C30mmgren::Shoot30mmgren(pActivator->pev, vecSrc + vecForward*16, vecForward * 4500);
			break;

			case TANK_ROCKET_BIOMASS:
				CBiomass::ShootBiomass(pActivator->pev, vecSrc + vecForward*16, vecForward * 3000, 200);
			break;

			case TANK_BEAM_BLASTER:
				FireBeam(vecSrc, vecForward, BEAM_BLASTER, 0, pActivator->pev);
			break;

			case TANK_BEAM_GAUSS:
				FireBeam(vecSrc, vecForward, BEAM_GAUSS, 0, pActivator->pev);
			break;

			case TANK_BEAM_GAUSSCHARGED:
				FireBeam(vecSrc, vecForward, BEAM_GAUSSCHARGED, 420, pActivator->pev);
			break;

			case TANK_BEAM_PHOTONGUN:
				FireBeam(vecSrc, vecForward, BEAM_PHOTONGUN, 0, pActivator->pev);
			break;

			case TANK_BEAM_PHOTONGUN_EXP:
				FireBeam(vecSrc, vecForward, BEAM_PHOTONGUN_EXP, 0, pActivator->pev);
			break;

			case TANK_BEAM_TAUCANNON:
				FireBeam(vecSrc, vecForward, BEAM_TAUCANNON, 0, pActivator->pev);
			break;

			case TANK_BEAM_PULSERIFLE:
				FireBeam(vecSrc, vecForward, BEAM_PULSERIFLE, 0, pActivator->pev);
			break;

			case TANK_BEAM_M72:
				FireMagnumBullets(vecSrc, vecForward, VECTOR_CONE_0DEGREES, 16384, BULLET_2MM, pActivator->pev);
			break;

			case TANK_BEAM_M72QUAD:
				FireMagnumBullets(vecSrc, vecForward, VECTOR_CONE_0DEGREES, 16384, BULLET_2MM_QUAD, pActivator->pev);
			break;

			case TANK_BEAM_IONTURRET:
				FireBeam(vecSrc, vecForward, BEAM_IONTURRET, 0, pActivator->pev);
			break;

			case TANK_BEAM_TESLAGUN:
				FireBeam(vecSrc, vecForward, BEAM_TESLAGUN, 0, pActivator->pev);
			break;
		}
		if (m_iAmmo > 0)
			m_iAmmo--;

		// update ammo counter
		MESSAGE_BEGIN( MSG_ONE, gmsgSpecTank, NULL, pActivator->pev );
			WRITE_BYTE( 2 ); // ammo update
			WRITE_LONG(m_iAmmo);
			WRITE_BYTE( m_spread ); // crosshair update
		MESSAGE_END();
		
		m_flNextAttack = gpGlobals->time + (1/m_fireRate);		
	}
	else if ( pActivator->pev->button & IN_ATTACK2 && m_AllowZoom)
	{
		if (m_fInZoom == 0) 
		{
			pActivator->m_iFOV = 25;
			m_fInZoom = 1;
		}
			else if (m_fInZoom == 1) 
		{
			pActivator->m_iFOV = 90;
			m_fInZoom = 0;
		}
		m_flNextAttack = gpGlobals->time + 0.3;
	}
}
Esempio n. 7
0
void CTentacle :: DieThink( void )
{
	pev->nextthink = gpGlobals-> time + 0.1;

	DispatchAnimEvents( );
	StudioFrameAdvance( );

	ChangeYaw( 24 );

	if (m_fSequenceFinished)
	{
		if (pev->sequence == m_iGoalAnim)
		{
			switch( m_iGoalAnim )
			{
			case TENTACLE_ANIM_Engine_Idle:
			case TENTACLE_ANIM_Engine_Sway:
			case TENTACLE_ANIM_Engine_Swat:
			case TENTACLE_ANIM_Engine_Bob:
				m_iGoalAnim = TENTACLE_ANIM_Engine_Sway + RANDOM_LONG( 0, 2 );
				break;
			case TENTACLE_ANIM_Engine_Death1:
			case TENTACLE_ANIM_Engine_Death2:
			case TENTACLE_ANIM_Engine_Death3:
				UTIL_Remove( this );
				return;
			}
		}

		// ALERT( at_console, "%d : %d => ", pev->sequence, m_iGoalAnim );
		pev->sequence = FindTransition( pev->sequence, m_iGoalAnim, &m_iDir );
		// ALERT( at_console, "%d\n", pev->sequence );

		if (m_iDir > 0)
		{
			pev->frame = 0;
		}
		else
		{
			pev->frame = 255;
		}
		ResetSequenceInfo( );

		float dy;
		switch( pev->sequence )
		{
		case TENTACLE_ANIM_Floor_Rear:
		case TENTACLE_ANIM_Floor_Rear_Idle:
		case TENTACLE_ANIM_Lev1_Rear:
		case TENTACLE_ANIM_Lev1_Rear_Idle:
		case TENTACLE_ANIM_Lev2_Rear:
		case TENTACLE_ANIM_Lev2_Rear_Idle:
		case TENTACLE_ANIM_Lev3_Rear:
		case TENTACLE_ANIM_Lev3_Rear_Idle:
		case TENTACLE_ANIM_Engine_Idle:
		case TENTACLE_ANIM_Engine_Sway:
		case TENTACLE_ANIM_Engine_Swat:
		case TENTACLE_ANIM_Engine_Bob:
		case TENTACLE_ANIM_Engine_Death1:
		case TENTACLE_ANIM_Engine_Death2:
		case TENTACLE_ANIM_Engine_Death3:
			pev->framerate = RANDOM_FLOAT( m_iDir - 0.2, m_iDir + 0.2 );
			dy = 180;
			break;
		default:
			pev->framerate = 1.5;
			dy = 0;
			break;
		}
		pev->ideal_yaw = m_flInitialYaw + dy;
	}
}
Esempio n. 8
0
//
// TentacleThink
//
void CTentacle :: Cycle( void )
{
	// ALERT( at_console, "%s %.2f %d %d\n", STRING( pev->targetname ), pev->origin.z, m_MonsterState, m_IdealMonsterState );
	pev->nextthink = gpGlobals-> time + 0.1;

	// ALERT( at_console, "%s %d %d %d %f %f\n", STRING( pev->targetname ), pev->sequence, m_iGoalAnim, m_iDir, pev->framerate, pev->health );

	if (m_MonsterState == MONSTERSTATE_SCRIPT || m_IdealMonsterState == MONSTERSTATE_SCRIPT)
	{
		pev->angles.y = m_flInitialYaw;
		pev->ideal_yaw = m_flInitialYaw;	
		ClearConditions( IgnoreConditions() );
		MonsterThink( );
		m_iGoalAnim = TENTACLE_ANIM_Pit_Idle;
		return;
	}

	DispatchAnimEvents( );
	StudioFrameAdvance( );

	ChangeYaw( pev->yaw_speed );

	CSound *pSound;

	Listen( );

	// Listen will set this if there's something in my sound list
	if ( HasConditions( bits_COND_HEAR_SOUND ) )
		pSound = PBestSound();
	else
		pSound = NULL;

	if ( pSound )
	{
		Vector vecDir;
		if (gpGlobals->time - m_flPrevSoundTime < 0.5)
		{
			float dt = gpGlobals->time - m_flPrevSoundTime;
			vecDir = pSound->m_vecOrigin + (pSound->m_vecOrigin - m_vecPrevSound) / dt - pev->origin;
		}
		else
		{
			vecDir = pSound->m_vecOrigin - pev->origin;
		}
		m_flPrevSoundTime = gpGlobals->time;
		m_vecPrevSound = pSound->m_vecOrigin;

		m_flSoundYaw = UTIL_VecToYaw ( vecDir ) - m_flInitialYaw;
		m_iSoundLevel = Level( vecDir.z );

		if (m_flSoundYaw < -180)
			m_flSoundYaw += 360;
		if (m_flSoundYaw > 180)
			m_flSoundYaw -= 360;

		// ALERT( at_console, "sound %d %.0f\n", m_iSoundLevel, m_flSoundYaw );
		if (m_flSoundTime < gpGlobals->time)
		{
			// play "I hear new something" sound
			char *sound;	

			switch( RANDOM_LONG(0,1) )
			{
			case 0: sound = "tentacle/te_alert1.wav"; break;
			case 1: sound = "tentacle/te_alert2.wav"; break;
			}

			// UTIL_EmitAmbientSound(ENT(pev), pev->origin + Vector( 0, 0, MyHeight()), sound, 1.0, ATTN_NORM, 0, 100);
		}
		m_flSoundTime = gpGlobals->time + RANDOM_FLOAT( 5.0, 10.0 );
	}

	// clip ideal_yaw
	float dy = m_flSoundYaw;
	switch( pev->sequence )
	{
	case TENTACLE_ANIM_Floor_Rear:
	case TENTACLE_ANIM_Floor_Rear_Idle:
	case TENTACLE_ANIM_Lev1_Rear:
	case TENTACLE_ANIM_Lev1_Rear_Idle:
	case TENTACLE_ANIM_Lev2_Rear:
	case TENTACLE_ANIM_Lev2_Rear_Idle:
	case TENTACLE_ANIM_Lev3_Rear:
	case TENTACLE_ANIM_Lev3_Rear_Idle:
		if (dy < 0 && dy > -m_flMaxYaw)
			dy = -m_flMaxYaw;
		if (dy > 0 && dy < m_flMaxYaw)
			dy = m_flMaxYaw;
		break;
	default:
		if (dy < -m_flMaxYaw)
			dy = -m_flMaxYaw;
		if (dy > m_flMaxYaw)
			dy = m_flMaxYaw;
	}
	pev->ideal_yaw = m_flInitialYaw + dy;

	if (m_fSequenceFinished)
	{
		// ALERT( at_console, "%s done %d %d\n", STRING( pev->targetname ), pev->sequence, m_iGoalAnim );
		if (pev->health <= 1)
		{
			m_iGoalAnim = TENTACLE_ANIM_Pit_Idle;
			if (pev->sequence == TENTACLE_ANIM_Pit_Idle)
			{
				pev->health = 75;
			}
		}
		else if ( m_flSoundTime > gpGlobals->time )
		{
			if (m_flSoundYaw >= -(m_flMaxYaw + 30) && m_flSoundYaw <= (m_flMaxYaw + 30))
			{
				// strike
				m_iGoalAnim = LookupActivity( ACT_T_STRIKE + m_iSoundLevel );
			}
			else if (m_flSoundYaw >= -m_flMaxYaw * 2 && m_flSoundYaw <= m_flMaxYaw * 2) 
			{
				// tap
				m_iGoalAnim = LookupActivity( ACT_T_TAP + m_iSoundLevel );
			}
			else
			{
				// go into rear idle
				m_iGoalAnim = LookupActivity( ACT_T_REARIDLE + m_iSoundLevel );
			}
		}
		else if (pev->sequence == TENTACLE_ANIM_Pit_Idle)
		{
			// stay in pit until hear noise
			m_iGoalAnim = TENTACLE_ANIM_Pit_Idle;
		}
		else if (pev->sequence == m_iGoalAnim)
		{
			if (MyLevel() >= 0 && gpGlobals->time < m_flSoundTime)
			{
				if (RANDOM_LONG(0,9) < m_flSoundTime - gpGlobals->time)
				{
					// continue stike
					m_iGoalAnim = LookupActivity( ACT_T_STRIKE + m_iSoundLevel );
				}
				else
				{
					// tap
					m_iGoalAnim = LookupActivity( ACT_T_TAP + m_iSoundLevel );
				}
			}
			else if (MyLevel( ) < 0)
			{
				m_iGoalAnim = LookupActivity( ACT_T_IDLE + 0 );
			}
			else
			{
				if (m_flNextSong < gpGlobals->time)
				{
					// play "I hear new something" sound
					char *sound;	

					switch( RANDOM_LONG(0,1) )
					{
					case 0: sound = "tentacle/te_sing1.wav"; break;
					case 1: sound = "tentacle/te_sing2.wav"; break;
					}

					EMIT_SOUND(ENT(pev), CHAN_VOICE, sound, 1.0, ATTN_NORM);

					m_flNextSong = gpGlobals->time + RANDOM_FLOAT( 10, 20 );
				}

				if (RANDOM_LONG(0,15) == 0)
				{
					// idle on new level
					m_iGoalAnim = LookupActivity( ACT_T_IDLE + RANDOM_LONG(0,3) );
				}
				else if (RANDOM_LONG(0,3)  == 0)
				{
					// tap
					m_iGoalAnim = LookupActivity( ACT_T_TAP + MyLevel( ) );
				}
				else
				{
					// idle
					m_iGoalAnim = LookupActivity( ACT_T_IDLE + MyLevel( ) );
				}
			}
			if (m_flSoundYaw < 0)
				m_flSoundYaw += RANDOM_FLOAT( 2, 8 );
			else
				m_flSoundYaw -= RANDOM_FLOAT( 2, 8 );
		}

		pev->sequence = FindTransition( pev->sequence, m_iGoalAnim, &m_iDir );

		if (m_iDir > 0)
		{
			pev->frame = 0;
		}
		else
		{
			m_iDir = -1; // just to safe
			pev->frame = 255;
		}
		ResetSequenceInfo( );

		m_flFramerateAdj = RANDOM_FLOAT( -0.2, 0.2 );
		pev->framerate = m_iDir * 1.0 + m_flFramerateAdj;

		switch( pev->sequence)
		{
		case TENTACLE_ANIM_Floor_Tap:
		case TENTACLE_ANIM_Lev1_Tap:
		case TENTACLE_ANIM_Lev2_Tap:
		case TENTACLE_ANIM_Lev3_Tap:
			{
				Vector vecSrc;
				UTIL_MakeVectors( pev->angles );

				TraceResult tr1, tr2;

				vecSrc = pev->origin + Vector( 0, 0, MyHeight() - 4);
				UTIL_TraceLine( vecSrc, vecSrc + gpGlobals->v_forward * 512, ignore_monsters, ENT( pev ), &tr1 );

				vecSrc = pev->origin + Vector( 0, 0, MyHeight() + 8);
				UTIL_TraceLine( vecSrc, vecSrc + gpGlobals->v_forward * 512, ignore_monsters, ENT( pev ), &tr2 );

				// ALERT( at_console, "%f %f\n", tr1.flFraction * 512, tr2.flFraction * 512 );

				m_flTapRadius = SetBlending( 0, RANDOM_FLOAT( tr1.flFraction * 512, tr2.flFraction * 512 ) );
			}
			break;
		default:
			m_flTapRadius = 336; // 400 - 64
			break;
		}
		pev->view_ofs.z = MyHeight( );
		// ALERT( at_console, "seq %d\n", pev->sequence );
	}

	if (m_flPrevSoundTime + 2.0 > gpGlobals->time)
	{
		// 1.5 normal speed if hears sounds
		pev->framerate = m_iDir * 1.5 + m_flFramerateAdj;
	}
	else if (m_flPrevSoundTime + 5.0 > gpGlobals->time)
	{
		// slowdown to normal
		pev->framerate = m_iDir + m_iDir * (5 - (gpGlobals->time - m_flPrevSoundTime)) / 2 + m_flFramerateAdj;
	}
}