Beispiel #1
0
VOID
PAL_BattleCommitAction(
   VOID
)
/*++
  Purpose:

    Commit the action which the player decided.

  Parameters:

    None.

  Return value:

    None.

--*/
{
   WORD      w;

   g_Battle.rgPlayer[g_Battle.UI.wCurPlayerIndex].action.ActionType =
      g_Battle.UI.wActionType;
   g_Battle.rgPlayer[g_Battle.UI.wCurPlayerIndex].action.sTarget =
      (SHORT)g_Battle.UI.wSelectedIndex;
   g_Battle.rgPlayer[g_Battle.UI.wCurPlayerIndex].action.wActionID =
      g_Battle.UI.wObjectID;

   //
   // Check if the action is valid
   //
   switch (g_Battle.UI.wActionType)
   {
   case kBattleActionMagic:
      w = gpGlobals->g.lprgMagic[gpGlobals->g.rgObject[g_Battle.UI.wObjectID].magic.wMagicNumber].wCostMP;
      if (gpGlobals->g.PlayerRoles.rgwMP[gpGlobals->rgParty[g_Battle.UI.wCurPlayerIndex].wPlayerRole] < w)
      {
         w = gpGlobals->g.lprgMagic[gpGlobals->g.rgObject[g_Battle.UI.wObjectID].magic.wMagicNumber].wType;
         if (w == kMagicTypeApplyToPlayer || w == kMagicTypeApplyToParty ||
            w == kMagicTypeTransform)
         {
            g_Battle.UI.wActionType = kBattleActionDefend;
         }
         else
         {
            g_Battle.UI.wActionType = kBattleActionAttack;
            if (g_Battle.rgPlayer[g_Battle.UI.wCurPlayerIndex].action.sTarget == -1)
            {
               g_Battle.rgPlayer[g_Battle.UI.wCurPlayerIndex].action.sTarget = 0;
            }
         }
      }
      break;

   case kBattleActionThrowItem:
   case kBattleActionUseItem:
      break;
   }

   //
   // Calculate the waiting time for the action
   //
   switch (g_Battle.UI.wActionType)
   {
   case kBattleActionMagic:
      {
         LPMAGIC      p;
         WORD         wCostMP;

         //
         // The base casting time of magic is set to the MP costed
         //
         p = &(gpGlobals->g.lprgMagic[gpGlobals->g.rgObject[g_Battle.UI.wObjectID].magic.wMagicNumber]);
         wCostMP = p->wCostMP;

         if (wCostMP == 1)
         {
            if (p->wType == kMagicTypeSummon)
            {
               //
               // The Wine God is an ultimate move which should take long
               //
               wCostMP = 200;
            }
         }
         else if (p->wType == kMagicTypeApplyToPlayer || p->wType == kMagicTypeApplyToParty ||
            p->wType == kMagicTypeTransform)
         {
            //
            // Healing magics should take shorter
            //
            wCostMP /= 3;
         }

         g_Battle.rgPlayer[g_Battle.UI.wCurPlayerIndex].action.flRemainingTime = wCostMP;
      }
      break;

   case kBattleActionFlee:
      //
      // Fleeing should take a fairly long time
      //
      g_Battle.rgPlayer[g_Battle.UI.wCurPlayerIndex].action.flRemainingTime = RandomFloat(25, 75);
      break;

   case kBattleActionDefend:
      //
      // Defend takes no time
      //
      g_Battle.rgPlayer[g_Battle.UI.wCurPlayerIndex].action.flRemainingTime = 0;
      break;

   default:
      g_Battle.rgPlayer[g_Battle.UI.wCurPlayerIndex].action.flRemainingTime = 5;
      break;
   }

   g_Battle.rgPlayer[g_Battle.UI.wCurPlayerIndex].state = kFighterAct;
   g_Battle.UI.state = kBattleUIWait;
}
Beispiel #2
0
	void AIUpdate()
	{
		float OggCast = (float)RandomFloat(100.0f);
		CastSpell(OggCast);
	}
Beispiel #3
0
	void AIUpdate()
	{
		float BazCast = (float)RandomFloat(100.0f);
		CastSpell(BazCast);
	}
Beispiel #4
0
void MoonScriptCreatureAI::AddRareLoot(Unit* pTarget, uint32 pItemID, float pPercentChance)
{
	float result = RandomFloat(100.0f);
	if (result <= pPercentChance)
		LootMgr::getSingleton().AddLoot(&pTarget->loot, pItemID, 1, 1, 0);
}
//---------------------------------------------------------
// Purpose: Draw the radar panel.
//			We're probably doing too much other work in here
//---------------------------------------------------------
void CHudRadar::Paint()
{
    if (m_iImageID == -1 )
    {
        // Set up the image ID's if they've somehow gone bad.
        m_textureID_IconLambda = vgui::surface()->CreateNewTextureID();
        vgui::surface()->DrawSetTextureFile( m_textureID_IconLambda, RADAR_CONTACT_LAMBDA_MATERIAL, true, false );

        m_textureID_IconBuster = vgui::surface()->CreateNewTextureID();
        vgui::surface()->DrawSetTextureFile( m_textureID_IconBuster, RADAR_CONTACT_BUSTER_MATERIAL, true, false );

        m_textureID_IconStrider = vgui::surface()->CreateNewTextureID();
        vgui::surface()->DrawSetTextureFile( m_textureID_IconStrider, RADAR_CONTACT_STRIDER_MATERIAL, true, false );

        m_textureID_IconDog = vgui::surface()->CreateNewTextureID();
        vgui::surface()->DrawSetTextureFile( m_textureID_IconDog, RADAR_CONTACT_DOG_MATERIAL, true, false );

        m_textureID_IconBase = vgui::surface()->CreateNewTextureID();
        vgui::surface()->DrawSetTextureFile( m_textureID_IconBase, RADAR_CONTACT_BASE_MATERIAL, true, false );

        m_iImageID = vgui::surface()->CreateNewTextureID();
        vgui::surface()->DrawSetTextureFile( m_iImageID, RADAR_PANEL_MATERIAL, true, false );
    }

    // Draw the radar background.
    int wide, tall;
    GetSize(wide, tall);
    int alpha = 255;
    vgui::surface()->DrawSetColor(255, 255, 255, alpha);
    vgui::surface()->DrawSetTexture(m_iImageID);
    vgui::surface()->DrawTexturedRect(0, 0, wide, tall);

    // Manage the CRT 'ghosting' effect
    if( gpGlobals->curtime > m_flTimeStartGhosting )
    {
        if( m_ghostAlpha < RADAR_MAX_GHOST_ALPHA )
        {
            m_ghostAlpha++;
        }
        else
        {
            m_flTimeStartGhosting = FLT_MAX;
            m_flTimeStopGhosting = gpGlobals->curtime + RandomFloat( 1.0f, 2.0f );// How long to ghost for
        }
    }
    else if( gpGlobals->curtime > m_flTimeStopGhosting )
    {
        // We're supposed to stop ghosting now.
        if( m_ghostAlpha > 0 )
        {
            // Still fading the effects.
            m_ghostAlpha--;
        }
        else
        {
            // DONE fading the effects. Now stop ghosting for a short while
            m_flTimeStartGhosting = gpGlobals->curtime + RandomFloat( 2.0f, 3.0f );// how long between ghosts
            m_flTimeStopGhosting = FLT_MAX;
        }
    }

    // Now go through the list of radar targets and represent them on the radar screen
    // by drawing their icons on top of the background.
    C_BasePlayer *pLocalPlayer = C_BasePlayer::GetLocalPlayer();

    for( int i = 0 ; i < m_iNumRadarContacts ; i++ )
    {
        int alpha = 90;
        CRadarContact *pContact = &m_radarContacts[ i ];
        float deltaT = pContact->m_flTimeToRemove - gpGlobals->curtime;
        if ( deltaT < RADAR_BLIP_FADE_TIME )
        {
            float factor = deltaT / RADAR_BLIP_FADE_TIME;

            alpha = (int) ( ((float)alpha) * factor );

            if( alpha < 10 )
                alpha = 10;
        }

        if( RADAR_USE_ICONS )
        {
            int flicker = RandomInt( 0, 30 );
            DrawIconOnRadar( pContact->m_vecOrigin, pLocalPlayer, pContact->m_iType, RADAR_IGNORE_Z, 255, 255, 255, alpha + flicker );
        }
        else
        {
            DrawPositionOnRadar( pContact->m_vecOrigin, pLocalPlayer, pContact->m_iType, RADAR_IGNORE_Z, 255, 255, 255, alpha );
        }
    }

    MaintainRadarContacts();
}
Beispiel #6
0
Spectrum IGIIntegrator::Li(const Scene *scene,
		const RayDifferential &ray, const Sample *sample,
		   float *alpha) const {
	Spectrum L(0.);
	Intersection isect;
	if (scene->Intersect(ray, &isect)) {
		if (alpha) *alpha = 1.;
		Vector wo = -ray.d;
		// Compute emitted light if ray hit an area light source
		L += isect.Le(wo);
		// Evaluate BSDF at hit point
		BSDF *bsdf = isect.GetBSDF(ray);
		const Point &p = bsdf->dgShading.p;
		const Normal &n = bsdf->dgShading.nn;
		L += UniformSampleAllLights(scene, p, n,
					    wo, bsdf, sample,
					    lightSampleOffset, bsdfSampleOffset,
					    bsdfComponentOffset);
		// Compute indirect illumination with virtual lights
		u_int lSet = min(u_int(sample->oneD[vlSetOffset][0] * nLightSets),
		                 nLightSets-1);
		for (u_int i = 0; i < virtualLights[lSet].size(); ++i) {
			const VirtualLight &vl = virtualLights[lSet][i];
			// Add contribution from _VirtualLight_ _vl_
			// Ignore light if it's too close to current point
			float d2 = DistanceSquared(p, vl.p);
			//if (d2 < .8 * minDist2) continue;
			float distScale = SmoothStep(.8 * minDist2, 1.2 * minDist2, d2);
			// Compute virtual light's tentative contribution _Llight_
			Vector wi = Normalize(vl.p - p);
			Spectrum f = distScale * bsdf->f(wo, wi);
			if (f.Black()) continue;
			float G = AbsDot(wi, n) * AbsDot(wi, vl.n) / d2;
			Spectrum Llight = indirectScale * f * G * vl.Le /
				virtualLights[lSet].size();
			Llight *= scene->Transmittance(Ray(p, vl.p - p));
			// Possibly skip shadow ray with Russian roulette
			if (Llight.y() < rrThreshold) {
				float continueProbability = .1f;
				if (RandomFloat() > continueProbability)
					continue;
				Llight /= continueProbability;
			}
			static StatsCounter vlsr("IGI Integrator", "Shadow Rays to Virtual Lights"); //NOBOOK
			++vlsr; //NOBOOK
			if (!scene->IntersectP(Ray(p, vl.p - p, RAY_EPSILON,
					1.f - RAY_EPSILON)))
				L += Llight;
		}
		// Trace rays for specular reflection and refraction
		if (specularDepth++ < maxSpecularDepth) {
			Vector wi;
			// Trace rays for specular reflection and refraction
			Spectrum f = bsdf->Sample_f(wo, &wi,
						BxDFType(BSDF_REFLECTION | BSDF_SPECULAR));
			if (!f.Black()) {
				// Compute ray differential _rd_ for specular reflection
				RayDifferential rd(p, wi);
				rd.hasDifferentials = true;
				rd.rx.o = p + isect.dg.dpdx;
				rd.ry.o = p + isect.dg.dpdy;
				// Compute differential reflected directions
				Normal dndx = bsdf->dgShading.dndu * bsdf->dgShading.dudx +
					bsdf->dgShading.dndv * bsdf->dgShading.dvdx;
				Normal dndy = bsdf->dgShading.dndu * bsdf->dgShading.dudy +
					bsdf->dgShading.dndv * bsdf->dgShading.dvdy;
				Vector dwodx = -ray.rx.d - wo, dwody = -ray.ry.d - wo;
				float dDNdx = Dot(dwodx, n) + Dot(wo, dndx);
				float dDNdy = Dot(dwody, n) + Dot(wo, dndy);
				rd.rx.d = wi -
					dwodx + 2 * Vector(Dot(wo, n) * dndx +
						 dDNdx * n);
				rd.ry.d = wi -
					dwody + 2 * Vector(Dot(wo, n) * dndy +
						 dDNdy * n);
				L += scene->Li(rd, sample) * f * AbsDot(wi, n);
			}
			f = bsdf->Sample_f(wo, &wi,
					   BxDFType(BSDF_TRANSMISSION | BSDF_SPECULAR));
			if (!f.Black()) {
				// Compute ray differential _rd_ for specular transmission
				RayDifferential rd(p, wi);
				rd.hasDifferentials = true;
				rd.rx.o = p + isect.dg.dpdx;
				rd.ry.o = p + isect.dg.dpdy;

				float eta = bsdf->eta;
				Vector w = -wo;
				if (Dot(wo, n) < 0) eta = 1.f / eta;

				Normal dndx = bsdf->dgShading.dndu * bsdf->dgShading.dudx + bsdf->dgShading.dndv * bsdf->dgShading.dvdx;
				Normal dndy = bsdf->dgShading.dndu * bsdf->dgShading.dudy + bsdf->dgShading.dndv * bsdf->dgShading.dvdy;

				Vector dwodx = -ray.rx.d - wo, dwody = -ray.ry.d - wo;
				float dDNdx = Dot(dwodx, n) + Dot(wo, dndx);
				float dDNdy = Dot(dwody, n) + Dot(wo, dndy);

				float mu = eta * Dot(w, n) - Dot(wi, n);
				float dmudx = (eta - (eta*eta*Dot(w,n))/Dot(wi, n)) * dDNdx;
				float dmudy = (eta - (eta*eta*Dot(w,n))/Dot(wi, n)) * dDNdy;

				rd.rx.d = wi + eta * dwodx - Vector(mu * dndx + dmudx * n);
				rd.ry.d = wi + eta * dwody - Vector(mu * dndy + dmudy * n);
				L += scene->Li(rd, sample) * f * AbsDot(wi, n);
			}
		}
		--specularDepth;
	}
	else {
		// Handle ray with no intersection
		if (alpha) *alpha = 0.;
		for (u_int i = 0; i < scene->lights.size(); ++i)
			L += scene->lights[i]->Le(ray);
		if (alpha && !L.Black()) *alpha = 1.;
		return L;
	}
	return L;
}
void CAI_LeadBehavior::RunTask( const Task_t *pTask )		
{ 
	switch ( pTask->iTask )
	{
		case TASK_LEAD_SUCCEED:
		{
			if ( !IsSpeaking() )
			{
				TaskComplete();
				NotifyEvent( LBE_DONE );
			}
			break;
		}
		case TASK_LEAD_ARRIVE:
		{
			if ( !IsSpeaking() )
			{
				TaskComplete();
				NotifyEvent( LBE_ARRIVAL_DONE );
			}
			break;
		}

		case TASK_LEAD_MOVE_TO_RANGE:
		{
			// If we haven't spoken our start speech, move closer
 			if ( !m_hasspokenstart)
			{
				ChainRunTask( TASK_MOVE_TO_GOAL_RANGE, m_leaddistance - 24 );
			}
			else
			{
 				ChainRunTask( TASK_MOVE_TO_GOAL_RANGE, m_retrievedistance );

				if ( !TaskIsComplete() )
				{
					// Transition to a walk when we get near the player
					// Check Z first, and only check 2d if we're within that
					Vector vecGoalPos = GetNavigator()->GetGoalPos();
					float distance = fabs(vecGoalPos.z - GetLocalOrigin().z);
					bool bWithinZ = false;
					if ( distance < m_retrievedistance )
					{
						distance = ( vecGoalPos - GetLocalOrigin() ).Length2D();
						bWithinZ = true;
					}

					if ( distance > m_retrievedistance )
					{
						Activity followActivity = ACT_WALK;
						if ( GetOuter()->GetState() == NPC_STATE_COMBAT || ( (!bWithinZ || distance < (m_retrievedistance*4)) && GetOuter()->GetState() != NPC_STATE_COMBAT ) )
						{
							followActivity = ACT_RUN;
						}

						// Don't confuse move and shoot by resetting the activity every think
						Activity curActivity = GetNavigator()->GetMovementActivity();
						switch( curActivity )
						{
						case ACT_WALK_AIM:	curActivity = ACT_WALK;	break;
						case ACT_RUN_AIM:	curActivity = ACT_RUN;	break;
						}
						
						if ( curActivity != followActivity )
						{
							GetNavigator()->SetMovementActivity(followActivity);
						}
						GetNavigator()->SetArrivalDirection( GetOuter()->GetTarget() );
					}
				}
			}
			break;
		}

		case TASK_LEAD_RETRIEVE_WAIT:
		{
			ChainRunTask( TASK_WAIT_INDEFINITE );
			break;
		}

		case TASK_LEAD_WALK_PATH:
		{
			// If we're leading, and we're supposed to run, run instead of walking
			if ( m_run && 
				( IsCurSchedule( SCHED_LEAD_WAITFORPLAYER, false ) || IsCurSchedule( SCHED_LEAD_PLAYER, false ) || IsCurSchedule( SCHED_LEAD_SPEAK_THEN_LEAD_PLAYER, false )|| IsCurSchedule( SCHED_LEAD_RETRIEVE, false ) ) )
			{
				ChainRunTask( TASK_RUN_PATH );
			}
			else
			{
				ChainRunTask( TASK_WALK_PATH );
			}

			// While we're walking
			if ( TaskIsRunning() && IsCurSchedule( SCHED_LEAD_PLAYER, false ) )
			{
				// If we're not speaking, and we haven't tried for a while, try to speak lead idle
				if ( m_flNextLeadIdle < gpGlobals->curtime && !IsSpeaking() )
				{
					m_flNextLeadIdle = gpGlobals->curtime + RandomFloat( 10,15 );

					if ( !m_args.iRetrievePlayer && HasCondition( COND_LEAD_FOLLOWER_LOST ) && HasCondition(COND_SEE_PLAYER) )
					{
						Speak( TLK_LEAD_COMINGBACK );
					}
					else
					{
						Speak( TLK_LEAD_IDLE );
					}
				}
			}

			break;
		}

		default:
			BaseClass::RunTask( pTask);
	}
}
Beispiel #8
0
void CASW_Director::UpdateSpawningState()
{
	if ( m_bFinale )				// in finale, just keep spawning aliens forever
	{
		m_bSpawningAliens = true;

		if ( asw_director_debug.GetBool() )
		{
			engine->Con_NPrintf( 8, "%s: %f %s", m_bSpawningAliens ? "Spawning aliens" : "Relaxing",
				m_SustainTimer.HasStarted() ? m_SustainTimer.GetRemainingTime() : -1,
				"Finale" );
		}
		return;
	}

	//=====================================================================================
	// Main director rollercoaster logic
	//   Spawns aliens until a peak intensity is reached, then gives the marines a breather
	//=====================================================================================

	if ( !m_bSpawningAliens )			// not spawning aliens, we're in a relaxed state
	{
		if ( !m_SustainTimer.HasStarted() )
		{
			if ( GetMaxIntensity() < 1.0f )	// don't start our relax timer until the marines have left the peak
			{
				if ( m_bInitialWait )		// just do a short delay before starting combat at the beginning of a mission
				{
					m_SustainTimer.Start( RandomFloat( 3.0f, 16.0f ) );
					m_bInitialWait = false;
				}
				else
				{
					m_SustainTimer.Start( RandomFloat( asw_director_relaxed_min_time.GetFloat(), asw_director_relaxed_max_time.GetFloat() ) );
				}
			}
		}
		else if ( m_SustainTimer.IsElapsed() )		// TODO: Should check their intensity meters are below a certain threshold?  Should probably also not wait if they run too far ahead
		{
			m_bSpawningAliens = true;
			m_bReachedIntensityPeak = false;
			m_SustainTimer.Invalidate();
			m_fTimeBetweenAliens = 0;
			m_AlienSpawnTimer.Invalidate();
		}
	}
	else								// we're spawning aliens
	{
		if ( m_bReachedIntensityPeak )
		{
			// hold the peak intensity for a while, then drop back to the relaxed state
			if ( !m_SustainTimer.HasStarted() )
			{
				m_SustainTimer.Start( RandomFloat( asw_director_peak_min_time.GetFloat(), asw_director_peak_max_time.GetFloat() ) );
			}
			else if ( m_SustainTimer.IsElapsed() )
			{
				m_bSpawningAliens = false;
				m_SustainTimer.Invalidate();
			}
		}
		else
		{
			if ( GetMaxIntensity() >= 1.0f )
			{
				m_bReachedIntensityPeak = true;
			}
		}
	}

	if ( asw_director_debug.GetInt() > 0 )
	{
		engine->Con_NPrintf( 8, "%s: %f %s", m_bSpawningAliens ? "Spawning aliens" : "Relaxing",
			m_SustainTimer.HasStarted() ? m_SustainTimer.GetRemainingTime() : -1,
			m_bReachedIntensityPeak ? "Peaked" : "Not peaked" );
	}
}
float CTFPointWeaponMimic::GetSpeed() const
{
	return RandomFloat(this->m_flSpeedMin, this->m_flSpeedMax);
}
        void OnDied(Unit* mKiller)
        {
            if(mKiller->IsPlayer())
            {
                Player * plr = TO_PLAYER(mKiller);
                if(plr->HasQuest(10896))
                {
                    if(Rand(90))
                    {
                        switch(_unit->GetEntry())
                        {
                            case 22307:
                                min = 4; max = 11;
                                break;
                            case 22095:
                                min = 2; max = 5;
                                break;
                        }

                        finall = min + RandomUInt(max - min);

                        float SSX = _unit->GetPositionX();
                        float SSY = _unit->GetPositionY();
                        float SSZ = _unit->GetPositionZ();
                        float SSO = _unit->GetOrientation();

                        for(uint8 i = 0; i < finall; i++)
                        {
                            Creature * NewCreature = _unit->GetMapMgr()->GetInterface()->SpawnCreature(22419, SSX + RandomFloat(3.0f), SSY + RandomFloat(3.0f), SSZ, SSO + RandomFloat(1.0f), true, false, 0, 0);
                            if ( NewCreature != NULL )
                                NewCreature->Despawn(120000, 0);
                        }
                    }
                }
            }
        }
Beispiel #11
0
void CASW_Director::UpdateHorde()
{
	if ( asw_director_debug.GetInt() > 0 )
	{
		if ( m_bHordeInProgress )
		{
			engine->Con_NPrintf( 11, "Horde in progress.  Left to spawn = %d", ASWSpawnManager()->GetHordeToSpawn() );
		}
		engine->Con_NPrintf( 12, "Next Horde due: %f", m_HordeTimer.GetRemainingTime() );

		engine->Con_NPrintf( 15, "Awake aliens: %d\n", ASWSpawnManager()->GetAwakeAliens() );
		engine->Con_NPrintf( 16, "Awake drones: %d\n", ASWSpawnManager()->GetAwakeDrones() );
	}

	bool bHordesEnabled = m_bHordesEnabled || asw_horde_override.GetBool();
	if ( !bHordesEnabled || !ASWSpawnManager() )
		return;

	if ( !m_HordeTimer.HasStarted() )
	{
		float flDuration = RandomFloat( asw_horde_interval_min.GetFloat(), asw_horde_interval_max.GetFloat() );
		if ( m_bFinale )
		{
			flDuration = RandomFloat( 5.0f, 10.0f );
		}
		if ( asw_director_debug.GetBool() )
		{
			Msg( "Will be spawning a horde in %f seconds\n", flDuration );
		}
		m_HordeTimer.Start( flDuration );
	}
	else if ( m_HordeTimer.IsElapsed() )
	{
		if ( ASWSpawnManager()->GetAwakeDrones() < 25 )
		{
			int iNumAliens = RandomInt( asw_horde_size_min.GetInt(), asw_horde_size_max.GetInt() );

			if ( ASWSpawnManager()->AddHorde( iNumAliens ) )
			{
				if ( asw_director_debug.GetBool() )
				{
					Msg("Created horde of size %d\n", iNumAliens);
				}
				m_bHordeInProgress = true;

				if ( ASWGameRules() )
				{
					ASWGameRules()->BroadcastSound( "Spawner.Horde" );
				}
				m_HordeTimer.Invalidate();
			}
			else
			{
				// if we failed to find a horde position, try again shortly.
				m_HordeTimer.Start( RandomFloat( 10.0f, 16.0f ) );
			}
		}
		else
		{
			// if there are currently too many awake aliens, then wait 10 seconds before trying again
			m_HordeTimer.Start( 10.0f );
		}
	}
}
Beispiel #12
0
/* For visibility testing: if bAbsolute is false, random modifiers must return the
 * minimum possible scroll speed. */
float ArrowEffects::GetYOffset( const PlayerState* pPlayerState, int iCol, float fNoteBeat, float &fPeakYOffsetOut, bool &bIsPastPeakOut, bool bAbsolute )
{
	// Default values that are returned if boomerang is off.
	fPeakYOffsetOut = FLT_MAX;
	bIsPastPeakOut = true;


	float fYOffset = 0;

	/* Usually, fTimeSpacing is 0 or 1, in which case we use entirely beat spacing or
	 * entirely time spacing (respectively).  Occasionally, we tween between them. */
	if( pPlayerState->m_CurrentPlayerOptions.m_fTimeSpacing != 1.0f )
	{
		/* offset by VisualDelayEffect seconds */
		float fSongBeat = GAMESTATE->m_fSongBeatVisible;
		float fBeatsUntilStep = fNoteBeat - fSongBeat;
		float fYOffsetBeatSpacing = fBeatsUntilStep * ARROW_SPACING;
		fYOffset += fYOffsetBeatSpacing * (1-pPlayerState->m_CurrentPlayerOptions.m_fTimeSpacing);
	}

	if( pPlayerState->m_CurrentPlayerOptions.m_fTimeSpacing != 0.0f )
	{
		/* offset by VisualDelaySeconds amount */
		float fSongSeconds = GAMESTATE->m_fMusicSecondsVisible;
		float fNoteSeconds = GAMESTATE->m_pCurSong->GetElapsedTimeFromBeat(fNoteBeat);
		float fSecondsUntilStep = fNoteSeconds - fSongSeconds;
		float fBPM = pPlayerState->m_CurrentPlayerOptions.m_fScrollBPM;
		float fBPS = fBPM/60.f;
		float fYOffsetTimeSpacing = fSecondsUntilStep * fBPS * ARROW_SPACING;
		fYOffset += fYOffsetTimeSpacing * pPlayerState->m_CurrentPlayerOptions.m_fTimeSpacing;
	}

	// don't mess with the arrows after they've crossed 0
	if( fYOffset < 0 )
		return fYOffset * pPlayerState->m_CurrentPlayerOptions.m_fScrollSpeed;

	const float* fAccels = pPlayerState->m_CurrentPlayerOptions.m_fAccels;
	//const float* fEffects = pPlayerState->m_CurrentPlayerOptions.m_fEffects;


	float fYAdjust = 0;	// fill this in depending on PlayerOptions

	if( fAccels[PlayerOptions::ACCEL_BOOST] != 0 )
	{
		float fEffectHeight = GetNoteFieldHeight(pPlayerState);
		float fNewYOffset = fYOffset * 1.5f / ((fYOffset+fEffectHeight/1.2f)/fEffectHeight); 
		float fAccelYAdjust =	fAccels[PlayerOptions::ACCEL_BOOST] * (fNewYOffset - fYOffset);
		// TRICKY:	Clamp this value, or else BOOST+BOOMERANG will draw a ton of arrows on the screen.
		CLAMP( fAccelYAdjust, -400.f, 400.f );
		fYAdjust += fAccelYAdjust;
	}
	if( fAccels[PlayerOptions::ACCEL_BRAKE] != 0 )
	{
		float fEffectHeight = GetNoteFieldHeight(pPlayerState);
		float fScale = SCALE( fYOffset, 0.f, fEffectHeight, 0, 1.f );
		float fNewYOffset = fYOffset * fScale; 
		float fBrakeYAdjust = fAccels[PlayerOptions::ACCEL_BRAKE] * (fNewYOffset - fYOffset);
		// TRICKY:	Clamp this value the same way as BOOST so that in BOOST+BRAKE, BRAKE doesn't overpower BOOST
		CLAMP( fBrakeYAdjust, -400.f, 400.f );
		fYAdjust += fBrakeYAdjust;
	}
	if( fAccels[PlayerOptions::ACCEL_WAVE] != 0 )
		fYAdjust +=	fAccels[PlayerOptions::ACCEL_WAVE] * 20.0f*RageFastSin( fYOffset/38.0f );

	fYOffset += fYAdjust;

	//
	// Factor in boomerang
	//
	if( fAccels[PlayerOptions::ACCEL_BOOMERANG] != 0 )
	{
		float fOriginalYOffset = fYOffset;

		fYOffset = (-1*fOriginalYOffset*fOriginalYOffset/SCREEN_HEIGHT) + 1.5f*fOriginalYOffset;
		float fPeakAtYOffset = SCREEN_HEIGHT * 0.75f;	// zero point of function above
		fPeakYOffsetOut = (-1*fPeakAtYOffset*fPeakAtYOffset/SCREEN_HEIGHT) + 1.5f*fPeakAtYOffset;
		bIsPastPeakOut = fOriginalYOffset < fPeakAtYOffset;
	}

	//
	// Factor in scroll speed
	//
	float fScrollSpeed = pPlayerState->m_CurrentPlayerOptions.m_fScrollSpeed;
	if( pPlayerState->m_CurrentPlayerOptions.m_fRandomSpeed > 0 && !bAbsolute )
	{
		int seed = GAMESTATE->m_iStageSeed + ( BeatToNoteRow( fNoteBeat ) << 8 ) + (iCol * 100);

		/* Temporary hack: the first call to RandomFloat isn't "random"; it takes an extra
		 * call to get the RNG rolling. */
		RandomFloat( seed );
		float fRandom = RandomFloat( seed );

		/* Random speed always increases speed: a random speed of 10 indicates [1,11].
		 * This keeps it consistent with other mods: 0 means no effect. */
		fScrollSpeed *=
				SCALE( fRandom,
						0.0f, 1.0f,
						1.0f, pPlayerState->m_CurrentPlayerOptions.m_fRandomSpeed + 1.0f );
	}	


	if( fAccels[PlayerOptions::ACCEL_EXPAND] != 0 )
	{
		/* Timers can't be global, since they'll be initialized before SDL. */
		static RageTimer timerExpand;
		if( !GAMESTATE->m_bFreeze )
			g_fExpandSeconds += timerExpand.GetDeltaTime();
		else
			timerExpand.GetDeltaTime();	// throw away
		float fExpandMultiplier = SCALE( RageFastCos(g_fExpandSeconds*3), -1, 1, 0.75f, 1.75f );
		fScrollSpeed *=	SCALE( fAccels[PlayerOptions::ACCEL_EXPAND], 0.f, 1.f, 1.f, fExpandMultiplier );
	}

	fYOffset *= fScrollSpeed;
	fPeakYOffsetOut *= fScrollSpeed;

	return fYOffset;
}
Beispiel #13
0
	void Execute(CBot *pBot)
	{
		if (m_bValid)
			((CBotTF2*)pBot)->MannVsMachineAlarmTriggered(m_vLoc + Vector(RandomFloat(-m_fRadius, m_fRadius), RandomFloat(-m_fRadius, m_fRadius), 0));
	}
Beispiel #14
0
// Image Pipeline Function Definitions
void ApplyImagingPipeline(float *rgb, int xResolution,
                          int yResolution, float *yWeight,
                          float bloomRadius, float bloomWeight,
                          const char *toneMapName,
                          const ParamSet *toneMapParams,
                          float gamma, float dither, int maxDisplayValue) {
    int nPix = xResolution * yResolution ;
    // Possibly apply bloom effect to image
    if (bloomRadius > 0.f && bloomWeight > 0.f) {
        // Compute image-space extent of bloom effect
        int bloomSupport = Float2Int(bloomRadius *
                                     max(xResolution, yResolution));
        int bloomWidth = bloomSupport / 2;
        // Initialize bloom filter table
        float *bloomFilter = new float[bloomWidth * bloomWidth];
        for (int i = 0; i < bloomWidth * bloomWidth; ++i) {
            float dist = sqrtf(float(i)) / float(bloomWidth);
            bloomFilter[i] = powf(max(0.f, 1.f - dist), 4.f);
        }
        // Apply bloom filter to image pixels
        float *bloomImage = new float[3*nPix];
        ProgressReporter prog(yResolution, "Bloom filter"); //NOBOOK
        for (int y = 0; y < yResolution; ++y) {
            for (int x = 0; x < xResolution; ++x) {
                // Compute bloom for pixel _(x,y)_
                // Compute extent of pixels contributing bloom
                int x0 = max(0, x - bloomWidth);
                int x1 = min(x + bloomWidth, xResolution - 1);
                int y0 = max(0, y - bloomWidth);
                int y1 = min(y + bloomWidth, yResolution - 1);
                int offset = y * xResolution + x;
                float sumWt = 0.;
                for (int by = y0; by <= y1; ++by)
                    for (int bx = x0; bx <= x1; ++bx) {
                        // Accumulate bloom from pixel $(bx,by)$
                        int dx = x - bx, dy = y - by;
                        if (dx == 0 && dy == 0) continue;
                        int dist2 = dx*dx + dy*dy;
                        if (dist2 < bloomWidth * bloomWidth) {
                            int bloomOffset = bx + by * xResolution;
                            float wt = bloomFilter[dist2];
                            sumWt += wt;
                            for (int j = 0; j < 3; ++j)
                                bloomImage[3*offset+j] += wt * rgb[3*bloomOffset+j];
                        }
                    }
                bloomImage[3*offset  ] /= sumWt;
                bloomImage[3*offset+1] /= sumWt;
                bloomImage[3*offset+2] /= sumWt;
            }
            prog.Update(); //NOBOOK
        }
        prog.Done(); //NOBOOK
        // Mix bloom effect into each pixel
        for (int i = 0; i < 3 * nPix; ++i)
            rgb[i] = Lerp(bloomWeight, rgb[i], bloomImage[i]);
        // Free memory allocated for bloom effect
        delete[] bloomFilter;
        delete[] bloomImage;
    }
    // Apply tone reproduction to image
    ToneMap *toneMap = NULL;
    if (toneMapName)
        toneMap = MakeToneMap(toneMapName,
                              toneMapParams ? *toneMapParams : ParamSet());
    if (toneMap) {
        float maxDisplayY = 100.f;
        float *scale = new float[nPix], *lum = new float[nPix];
        // Compute pixel luminance values
        float stdYWeight[3] = { 0.212671f, 0.715160f, 0.072169f };
        if (!yWeight) yWeight = stdYWeight;
        for (int i = 0; i < nPix; ++i)
            lum[i] = 683.f * (yWeight[0] * rgb[3*i] +
                              yWeight[1] * rgb[3*i+1] + yWeight[2] * rgb[3*i+2]);
        toneMap->Map(lum, xResolution, yResolution,
                     maxDisplayY, scale);
        // Apple scale to pixels for tone mapping and map to $[0,1]$
        float displayTo01 = 683.f / maxDisplayY;
        for (int i = 0; i < xResolution * yResolution; ++i) {
            rgb[3*i  ] *= scale[i] * displayTo01;
            rgb[3*i+1] *= scale[i] * displayTo01;
            rgb[3*i+2] *= scale[i] * displayTo01;
        }
        delete[] scale;
        delete[] lum;
    }
    // Handle out-of-gamut RGB values
    for (int i = 0; i < nPix; ++i) {
        float m = max(rgb[3*i], max(rgb[3*i+1], rgb[3*i+2]));
        if (m > 1.f)
            for (int j = 0; j < 3; ++j)
                rgb[3*i+j] /= m;
    }
    // Apply gamma correction to image
    if (gamma != 1.f) {
        float invGamma = 1.f / gamma;
        for (int i = 0; i < 3*nPix; ++i)
            rgb[i] = powf(rgb[i], invGamma);
    }
    // Map image to display range
    for (int i = 0; i < 3*nPix; ++i)
        rgb[i] *= maxDisplayValue;
    // Dither image
    if (dither > 0.f)
        for (int i = 0; i < 3*nPix; ++i)
            rgb[i] += 2.f * dither * (RandomFloat() - .5f);
}
void Test::LaunchBomb(){
	b2Vec2 p(RandomFloat(-15.0f, 15.0f), 30.0f);
	b2Vec2 v = -5.0f * p;
	LaunchBomb(p, v);
}
//-----------------------------------------------------------------------------
// Purpose: 
//-----------------------------------------------------------------------------
void FX_BuildWarp( Vector &vecOrigin, QAngle &vecAngles, float flScale )
{
	if ( EffectOccluded( vecOrigin, 0 ) )
		return;

	CSmartPtr<CSimpleEmitter> pSimple = CSimpleEmitter::Create( "dust" );
	pSimple->SetSortOrigin( vecOrigin );

	SimpleParticle *pParticle;

	Vector color( 1, 1, 1 );
	float  colorRamp;

	// Big flash
	pParticle = (SimpleParticle *) pSimple->AddParticle( sizeof( SimpleParticle ), pSimple->GetPMaterial( "effects/blueflare2" ), vecOrigin );
	if ( pParticle != NULL )
	{
		pParticle->m_flLifetime = 0.0f;
		pParticle->m_flDieTime	= 0.5;
		pParticle->m_vecVelocity = vec3_origin;
		colorRamp = RandomFloat( 0.75f, 1.25f );
		pParticle->m_uchColor[0]	= min( 1.0f, color[0] * colorRamp ) * 255.0f;
		pParticle->m_uchColor[1]	= min( 1.0f, color[1] * colorRamp ) * 255.0f;
		pParticle->m_uchColor[2]	= min( 1.0f, color[2] * colorRamp ) * 255.0f;
		pParticle->m_uchStartSize	= RandomFloat( 10,15 );
		pParticle->m_uchEndSize		= pParticle->m_uchStartSize * 8 * flScale;
		pParticle->m_uchStartAlpha	= 48;
		pParticle->m_uchEndAlpha	= 0;
		pParticle->m_flRoll			= 0;
		pParticle->m_flRollDelta	= 0;
	}

	// Bright light
	// Move it towards the camera
	Vector vecForward;
	AngleVectors( MainViewAngles(), &vecForward );
	vecOrigin -= (vecForward * 8);
	CSmartPtr<CWarpParticleEmitter> pWarpEmitter = CWarpParticleEmitter::Create( "dust" );
	pWarpEmitter->SetSortOrigin( vecOrigin );

	pParticle = (SimpleParticle *) pWarpEmitter->AddParticle( sizeof( SimpleParticle ), pWarpEmitter->GetPMaterial( "effects/human_build_warp" ), vecOrigin );
	if ( pParticle != NULL )
	{
		pParticle->m_flLifetime = 0.0f;
		pParticle->m_flDieTime	= 0.4;
		pParticle->m_vecVelocity = vec3_origin;

		colorRamp = RandomFloat( 0.75f, 1.25f );
		pParticle->m_uchColor[0]	= min( 1.0f, color[0] * colorRamp ) * 255.0f;
		pParticle->m_uchColor[1]	= min( 1.0f, color[1] * colorRamp ) * 255.0f;
		pParticle->m_uchColor[2]	= min( 1.0f, color[2] * colorRamp ) * 255.0f;
		
		pParticle->m_uchStartSize	= RandomInt( 10,13 ) * flScale;
		pParticle->m_uchEndSize		= pParticle->m_uchStartSize * 9;
		
		pParticle->m_uchStartAlpha	= 32;
		pParticle->m_uchEndAlpha	= 192;
		
		pParticle->m_flRoll			= 0;
		pParticle->m_flRollDelta	= 0;
	}
}
Beispiel #17
0
void FX_Tesla( const CTeslaInfo &teslaInfo )
{
	C_BaseEntity *pEntity = ClientEntityList().GetEnt( teslaInfo.m_nEntIndex );

	// Send out beams around us
	int iNumBeamsAround = (teslaInfo.m_nBeams * 2) / 3; // (2/3 of the beams are placed around in a circle)
	int iNumRandomBeams = teslaInfo.m_nBeams - iNumBeamsAround;
	int iTotalBeams = iNumBeamsAround + iNumRandomBeams;
	float flYawOffset = RandomFloat(0,360);
	for ( int i = 0; i < iTotalBeams; i++ )
	{
		// Make a couple of tries at it
		int iTries = -1;
		Vector vecForward;
		trace_t tr;
		do
		{
			iTries++;

			// Some beams are deliberatly aimed around the point, the rest are random.
			if ( i < iNumBeamsAround )
			{
				QAngle vecTemp = teslaInfo.m_vAngles;
				vecTemp[YAW] += anglemod( flYawOffset + ((360 / iTotalBeams) * i) );
				AngleVectors( vecTemp, &vecForward );

				// Randomly angle it up or down
				vecForward.z = RandomFloat( -1, 1 );
			}
			else
			{
				vecForward = RandomVector( -1, 1 );
			}
			VectorNormalize( vecForward );

			UTIL_TraceLine( teslaInfo.m_vPos, teslaInfo.m_vPos + (vecForward * teslaInfo.m_flRadius), MASK_SHOT, pEntity, COLLISION_GROUP_NONE, &tr );
		} while ( tr.fraction >= 1.0 && iTries < 3 );

		Vector vecEnd = tr.endpos - (vecForward * 8);

		// Only spark & glow if we hit something
		if ( tr.fraction < 1.0 )
		{
			if ( !EffectOccluded( tr.endpos, 0 ) )
			{
				// Move it towards the camera
				Vector vecFlash = tr.endpos;
				Vector vecForward;
				AngleVectors( MainViewAngles(), &vecForward );
				vecFlash -= (vecForward * 8);

				g_pEffects->EnergySplash( vecFlash, -vecForward, false );

				// End glow
				CSmartPtr<CSimpleEmitter> pSimple = CSimpleEmitter::Create( "dust" );
				pSimple->SetSortOrigin( vecFlash );
				SimpleParticle *pParticle;
				pParticle = (SimpleParticle *) pSimple->AddParticle( sizeof( SimpleParticle ), pSimple->GetPMaterial( "effects/tesla_glow_noz" ), vecFlash );
				if ( pParticle != NULL )
				{
					pParticle->m_flLifetime = 0.0f;
					pParticle->m_flDieTime	= RandomFloat( 0.5, 1 );
					pParticle->m_vecVelocity = vec3_origin;
					Vector color( 1,1,1 );
					float  colorRamp = RandomFloat( 0.75f, 1.25f );
					pParticle->m_uchColor[0]	= min( 1.0f, color[0] * colorRamp ) * 255.0f;
					pParticle->m_uchColor[1]	= min( 1.0f, color[1] * colorRamp ) * 255.0f;
					pParticle->m_uchColor[2]	= min( 1.0f, color[2] * colorRamp ) * 255.0f;
					pParticle->m_uchStartSize	= RandomFloat( 6,13 );
					pParticle->m_uchEndSize		= pParticle->m_uchStartSize - 2;
					pParticle->m_uchStartAlpha	= 255;
					pParticle->m_uchEndAlpha	= 10;
					pParticle->m_flRoll			= RandomFloat( 0,360 );
					pParticle->m_flRollDelta	= 0;
				}
			}
		}

		// Build the tesla
		FX_BuildTesla( pEntity, teslaInfo.m_vPos, tr.endpos, teslaInfo.m_pszSpriteName, teslaInfo.m_flBeamWidth, teslaInfo.m_vColor, FBEAM_ONLYNOISEONCE, teslaInfo.m_flTimeVisible );
	}
}
//-----------------------------------------------------------------------------
// Purpose: Build impact
//-----------------------------------------------------------------------------
void FX_BuildImpact( const Vector &origin, const QAngle &vecAngles, const Vector &vecNormal, float flScale, bool bGround = false, CBaseEntity *pIgnore = NULL )
{
	Vector	offset;
	float	spread = 0.1f;
	
	CSmartPtr<CDustParticle> pSimple = CDustParticle::Create( "dust" );
	pSimple->SetSortOrigin( origin );

	SimpleParticle	*pParticle;

	Vector color( 0.35, 0.35, 0.35 );
	float  colorRamp;

	// If we're hitting the ground, try and get the ground color
	if ( bGround )
	{
		trace_t	tr;
		UTIL_TraceLine( origin, origin + Vector(0,0,-32), MASK_SHOT, pIgnore, COLLISION_GROUP_NONE, &tr );
		GetColorForSurface( &tr, &color );
	}

	int iNumPuffs = 8;
	for ( int i = 0; i < iNumPuffs; i++ )
	{
		QAngle vecTemp = vecAngles;
		vecTemp[YAW] += (360 / iNumPuffs) * i;
		Vector vecForward;
		AngleVectors( vecTemp, &vecForward );

		pParticle = (SimpleParticle *) pSimple->AddParticle( sizeof( SimpleParticle ), pSimple->GetPMaterial( "particle/particle_smokegrenade" ), origin );

		if ( pParticle != NULL )
		{
			pParticle->m_flLifetime = 0.0f;
			pParticle->m_flDieTime	= RandomFloat( 0.5f, 1.0f );

			pParticle->m_vecVelocity.Random( -spread, spread );
			pParticle->m_vecVelocity += ( vecForward * RandomFloat( 1.0f, 6.0f ) );
			
			VectorNormalize( pParticle->m_vecVelocity );

			float	fForce = RandomFloat( 500, 750 );

			// scaled
			pParticle->m_vecVelocity *= fForce * flScale;
			
			colorRamp = RandomFloat( 0.75f, 1.25f );
			pParticle->m_uchColor[0]	= min( 1.0f, color[0] * colorRamp ) * 255.0f;
			pParticle->m_uchColor[1]	= min( 1.0f, color[1] * colorRamp ) * 255.0f;
			pParticle->m_uchColor[2]	= min( 1.0f, color[2] * colorRamp ) * 255.0f;
			
			// scaled
			pParticle->m_uchStartSize	= flScale * RandomInt( 15, 20 );

			// scaled
			pParticle->m_uchEndSize		= flScale * pParticle->m_uchStartSize * 4;
			
			pParticle->m_uchStartAlpha	= RandomInt( 32, 255 );
			pParticle->m_uchEndAlpha	= 0;
			
			pParticle->m_flRoll			= RandomInt( 0, 360 );
			pParticle->m_flRollDelta	= RandomFloat( -8.0f, 8.0f );
		}
	}			
}
Beispiel #19
0
void IGIIntegrator::Preprocess(const Scene *scene) {
	if (scene->lights.size() == 0) return;
	// Compute samples for emitted rays from lights
	float *lightNum = new float[nLightPaths * nLightSets];
	float *lightSamp0 = new float[2 * nLightPaths *	nLightSets];
	float *lightSamp1 = new float[2 * nLightPaths * nLightSets];
	LDShuffleScrambled1D(nLightPaths, nLightSets, lightNum);
	LDShuffleScrambled2D(nLightPaths, nLightSets, lightSamp0);
	LDShuffleScrambled2D(nLightPaths, nLightSets, lightSamp1);
	// Precompute information for light sampling densities
	int nLights = int(scene->lights.size());
	float *lightPower = (float *)alloca(nLights * sizeof(float));
	float *lightCDF = (float *)alloca((nLights+1) * sizeof(float));
	for (int i = 0; i < nLights; ++i)
		lightPower[i] = scene->lights[i]->Power(scene).y();
	float totalPower;
	ComputeStep1dCDF(lightPower, nLights, &totalPower, lightCDF);
	for (u_int s = 0; s < nLightSets; ++s) {
		for (u_int i = 0; i < nLightPaths; ++i) {
			// Follow path _i_ from light to create virtual lights
			int sampOffset = s*nLightPaths + i;
			// Choose light source to trace path from
			float lightPdf;
			int lNum = Floor2Int(SampleStep1d(lightPower, lightCDF,
				totalPower, nLights, lightNum[sampOffset], &lightPdf) * nLights);
//			fprintf(stderr, "samp %f -> num %d\n", lightNum[sampOffset], lNum);
			Light *light = scene->lights[lNum];
			// Sample ray leaving light source
			RayDifferential ray;
			float pdf;
			Spectrum alpha =
				light->Sample_L(scene, lightSamp0[2*sampOffset],
						lightSamp0[2*sampOffset+1],
						lightSamp1[2*sampOffset],
						lightSamp1[2*sampOffset+1],
						&ray, &pdf);
			if (pdf == 0.f || alpha.Black()) continue;
			alpha /= pdf * lightPdf;
//			fprintf(stderr, "initial alpha %f, light # %d\n", alpha.y(), lNum);
			Intersection isect;
			int nIntersections = 0;
			while (scene->Intersect(ray, &isect) && !alpha.Black()) {
				++nIntersections;
				alpha *= scene->Transmittance(ray);
				Vector wo = -ray.d;
				BSDF *bsdf = isect.GetBSDF(ray);
				// Create virtual light at ray intersection point
				static StatsCounter vls("IGI Integrator", "Virtual Lights Created"); //NOBOOK
				++vls; //NOBOOK
				Spectrum Le = alpha * bsdf->rho(wo) / M_PI;
//				fprintf(stderr, "\tmade light with le y %f\n", Le.y());
				virtualLights[s].push_back(VirtualLight(isect.dg.p, isect.dg.nn, Le));
				// Sample new ray direction and update weight
				Vector wi;
				float pdf;
				BxDFType flags;
				Spectrum fr = bsdf->Sample_f(wo, &wi, RandomFloat(),
								 RandomFloat(), RandomFloat(),
								 &pdf, BSDF_ALL, &flags);
				if (fr.Black() || pdf == 0.f)
					break;
				Spectrum anew = alpha * fr * AbsDot(wi, bsdf->dgShading.nn) / pdf;
				float r = anew.y() / alpha.y();
//				fprintf(stderr, "\tr = %f\n", r);
				if (RandomFloat() > r)
					break;
				alpha = anew / r;
//				fprintf(stderr, "\tnew alpha %f\n", alpha.y());
				ray = RayDifferential(isect.dg.p, wi);
			}
			BSDF::FreeAll();
		}
	}
	delete[] lightNum; // NOBOOK
	delete[] lightSamp0; // NOBOOK
	delete[] lightSamp1; // NOBOOK
}
void CGasolineEmitter::UpdateFire( float frametime )
{
	float flLifetime = gpGlobals->curtime - m_pBlob->m_flCreateTime;

	float litPercent = 1;
	if ( m_pBlob->IsLit() )
	{
		litPercent = 1 - (flLifetime / m_pBlob->m_flMaxLifetime);
		if ( litPercent <= 0 )
			return;
	}
	else
	{
		return;
	}

	// Don't show a burn effect for a blob that hasn't hit anything yet.
	// If you do, it tends to make the flamethrower effect look weird.
	if ( !m_pBlob->IsStopped() )
		return;

	// Make a coordinate system in which to spawn the particles. It 
	Vector vUp, vRight;
	vUp.Init();
	vRight.Init();
	if ( m_pBlob->IsStopped() )
	{
		QAngle angles;
		VectorAngles( m_pBlob->GetSurfaceNormal(), angles );
		AngleVectors( angles, NULL, &vRight, &vUp );
	}
	
	PMaterialHandle hMaterial = m_hFireMaterial;
	float flParticleLifetime = 1;
	float flRadius = 7;
	unsigned char uchColor[4] = { 255, 128, 0, 128 };
	float flMaxZVel = 29;


	float curDelta = frametime;
	while ( m_Timer.NextEvent( curDelta ) )
	{
		// Based on how close we are to expiring, show less particles.
		if ( RandomFloat( 0, 1 ) > litPercent )
			continue;

		Vector vPos = m_pBlob->GetAbsOrigin();
		if ( m_pBlob->IsStopped() )
		{
			float flAngle = RandomFloat( 0, M_PI * 2 );
			float flDist = RandomFloat( 0, GASOLINE_BLOB_RADIUS );
			vPos += vRight * (cos( flAngle ) * flDist);
			vPos += vUp * ( sin( flAngle ) * flDist );
		}
		else
		{
			vPos += RandomVector( -GASOLINE_BLOB_RADIUS, GASOLINE_BLOB_RADIUS );
		}
		
		SimpleParticle *pParticle = AddSimpleParticle( hMaterial, vPos, flParticleLifetime, flRadius );
		if ( pParticle )
		{
			pParticle->m_uchColor[0] = uchColor[0];
			pParticle->m_uchColor[1] = uchColor[1];
			pParticle->m_uchColor[2] = uchColor[2];

			pParticle->m_uchEndAlpha = 0;
			pParticle->m_uchStartAlpha = uchColor[3];

			pParticle->m_vecVelocity.x = RandomFloat( -2, 2 );
			pParticle->m_vecVelocity.y = RandomFloat( -2, 2 );
			pParticle->m_vecVelocity.z = RandomFloat( 3, flMaxZVel );
		}
	}
}
Beispiel #21
0
//-----------------------------------------------------------------------------
void C_Fish::ClientThink()
{
	if (FishDebug.GetBool())
	{
		debugoverlay->AddLineOverlay( m_pos, m_actualPos, 255, 0, 0, true, 0.1f );
		switch( m_localLifeState )
		{
			case LIFE_DYING:
				debugoverlay->AddTextOverlay( m_pos, 0.1f, "DYING" );
				break;

			case LIFE_DEAD:
				debugoverlay->AddTextOverlay( m_pos, 0.1f, "DEAD" );
				break;
		}
	}

	float deltaT = gpGlobals->frametime;


	// check if we just died
	if (m_localLifeState == LIFE_ALIVE && m_lifeState != LIFE_ALIVE)
	{
		// we have died
		m_localLifeState = LIFE_DYING;

		m_deathDepth = m_pos.z;

		// determine surface float angle
		m_deathAngle = RandomFloat( 87.0f, 93.0f ) * ((RandomInt( 0, 100 ) < 50) ? 1.0f : -1.0f);
	}


	switch( m_localLifeState )
	{
		case LIFE_DYING:
		{
			// depth parameter
			float t = (m_pos.z - m_deathDepth) / (m_waterLevel - m_deathDepth);
			t *= t;

			// roll onto side
			m_angles.z = m_deathAngle * t;

			// float to surface
			const float fudge = 2.0f;
			if (m_pos.z < m_waterLevel - fudge)
			{
				m_vel.z += (1.0f - t) * m_buoyancy * deltaT;
			}
			else
			{
				m_localLifeState = LIFE_DEAD;
			}

			break;
		}

		case LIFE_DEAD:
		{
			// depth parameter
			float t = (m_pos.z - m_deathDepth) / (m_waterLevel - m_deathDepth);
			t *= t;

			// roll onto side
			m_angles.z = m_deathAngle * t;

			// keep near water surface
			const float sub = 0.5f;
			m_vel.z += 10.0f * (m_waterLevel - m_pos.z - sub) * deltaT;

			// bob on surface
			const float rollAmp = 5.0f;
			const float rollFreq = 2.33f;
			m_angles.z += rollAmp * sin( rollFreq * (gpGlobals->curtime + 10.0f * entindex()) ) * deltaT;

			const float rollAmp2 = 7.0f;
			const float rollFreq2 = 4.0f;
			m_angles.x += rollAmp2 * sin( rollFreq2 * (gpGlobals->curtime + 10.0f * entindex()) ) * deltaT;

			const float bobAmp = 0.75f;
			const float bobFreq = 4.0f;
			m_vel.z += bobAmp * sin( bobFreq * (gpGlobals->curtime + 10.0f * entindex()) ) * deltaT;

			const float bobAmp2 = 0.75f;
			const float bobFreq2 = 3.333f;
			m_vel.z += bobAmp2 * sin( bobFreq2 * (gpGlobals->curtime + 10.0f * entindex()) ) * deltaT;

			// decay movement speed to zero
			const float drag = 1.0f;
			m_vel.z -= drag * m_vel.z * deltaT;

			break;
		}

		case LIFE_ALIVE:
		{
			// use server-side Z coordinate directly
			m_pos.z = m_actualPos.z;

			// use server-side angles
			m_angles = m_actualAngles;

			// fishy wiggle based on movement
			if (!m_wiggleTimer.IsElapsed())
			{
				float swimPower = 1.0f - (m_wiggleTimer.GetElapsedTime() / m_wiggleTimer.GetCountdownDuration());
				const float amp = 6.0f * swimPower;
				float wiggle = amp * sin( m_wigglePhase );

				m_wigglePhase += m_wiggleRate * deltaT;

				// wiggle decay
				const float wiggleDecay = 5.0f;
				m_wiggleRate -= wiggleDecay * deltaT;

				m_angles.y += wiggle;
			}

			break;
		}
	}

	// compute error between our local position and actual server position
	Vector error = m_actualPos - m_pos;
	error.z = 0.0f;
	float errorLen = error.Length();

	if (m_localLifeState == LIFE_ALIVE)
	{
		// if error is far above average, start swimming
		const float wiggleThreshold = 2.0f;
		if (errorLen - m_averageError > wiggleThreshold)
		{
			// if error is large, we must have started swimming
			const float swimTime = 5.0f;
			m_wiggleTimer.Start( swimTime );

			m_wiggleRate = 2.0f * errorLen;

			const float maxWiggleRate = 30.0f;
			if (m_wiggleRate > maxWiggleRate)
			{
				m_wiggleRate = maxWiggleRate;
			}
		}

		// update average error
		m_errorHistory[ m_errorHistoryIndex++ ] = errorLen;
		if (m_errorHistoryIndex >= MAX_ERROR_HISTORY)
		{
			m_errorHistoryIndex = 0;
			m_errorHistoryCount = MAX_ERROR_HISTORY;
		}
		else if (m_errorHistoryCount < MAX_ERROR_HISTORY)
		{
			++m_errorHistoryCount;
		}

		m_averageError = 0.0f;
		if (m_errorHistoryCount)
		{
			for( int r=0; r<m_errorHistoryCount; ++r )
			{
				m_averageError += m_errorHistory[r];
			}
			m_averageError /= (float)m_errorHistoryCount;
		}
	}

	// keep fish motion smooth by correcting towards actual server position
	// NOTE: This only tracks XY motion
	const float maxError = 20.0f;
	float errorT = errorLen / maxError;
	if (errorT > 1.0f)
	{
		errorT = 1.0f;
	}

	// we want a nonlinear spring force for tracking
	errorT *= errorT;

	// as fish move faster, their error increases - use a stiffer spring when fast, and a weak one when slow
	const float trackRate = 0.0f + errorT * 115.0f;
	m_vel.x += trackRate * error.x * deltaT;
	m_vel.y += trackRate * error.y * deltaT;

	const float trackDrag = 2.0f + errorT * 6.0f;
	m_vel.x -= trackDrag * m_vel.x * deltaT;
	m_vel.y -= trackDrag * m_vel.y * deltaT;


	// euler integration
	m_pos += m_vel * deltaT;

	SetNetworkOrigin( m_pos );
	SetAbsOrigin( m_pos );

	SetNetworkAngles( m_angles );
	SetAbsAngles( m_angles );
}
Vect RandomVect(BOOL bPositiveOnly)
{
    return Vect(RandomFloat(bPositiveOnly), RandomFloat(bPositiveOnly), RandomFloat(bPositiveOnly)).Norm();
}
Beispiel #23
0
void MoonScriptCreatureAI::AIUpdate()
{
	SpellDesc*	Spell;
	uint32		CurrentTime = (uint32)time(NULL);

	//Elapse timers
	for( TimerArray::iterator TimerIter = mTimers.begin(); TimerIter != mTimers.end(); ++TimerIter )
	{
		TimerIter->second -= mAIUpdateFrequency;
	}

	//Check if we have a spell scheduled to be cast
	for( SpellDescList::iterator SpellIter = mScheduledSpells.begin(); SpellIter != mScheduledSpells.end(); ++SpellIter )
	{
		Spell = (*SpellIter);
		if( CastSpellInternal(Spell, CurrentTime) )	//Can fail if we are already casting a spell, or if the spell is on cooldown
		{
			mScheduledSpells.erase(SpellIter);
			break;
		}
	}

	//Do not schedule spell if we are *currently* casting a non-instant cast spell
	if( !IsCasting() && !mRunToTargetCache )
	{
		//Check if have queued spells that needs to be scheduled before we go back to random casting
		if( !mQueuedSpells.empty() )
		{
			Spell = mQueuedSpells.front();
			mScheduledSpells.push_back(Spell);
			mQueuedSpells.pop_front();

			//Stop melee attack for a short while for scheduled spell cast
			if( Spell->mCastTime >= 0 )
			{
				DelayNextAttack(mAIUpdateFrequency + CalcSpellAttackTime(Spell));
				if( Spell->mCastTime > 0 )
				{
					SetCanMove(false);
					SetBehavior(Behavior_Spell);
				}
			}
			return;	//Scheduling one spell at a time, exit now
		}

		//Try our chance at casting a spell (Will actually be cast on next ai update, so we just
		//schedule it. This is needed to avoid next dealt melee damage while we cast the spell.)
		float ChanceRoll = RandomFloat(100), ChanceTotal = 0;
		for( SpellDescArray::iterator SpellIter = mSpells.begin(); SpellIter != mSpells.end(); ++SpellIter )
		{
			Spell = (*SpellIter);
			if( Spell->mEnabled == false ) continue;
			if( Spell->mChance == 0 ) continue;

			//Check if spell won the roll
			if( (Spell->mChance == 100 || (ChanceRoll >= ChanceTotal && ChanceRoll < ChanceTotal + Spell->mChance)) &&
				(Spell->mLastCastTime + Spell->mCooldown <= CurrentTime) &&
				!IsSpellScheduled(Spell) )
			{
				mScheduledSpells.push_back(Spell);

				//Stop melee attack for a short while for scheduled spell cast
				if( Spell->mCastTime >= 0 )
				{
					DelayNextAttack(mAIUpdateFrequency + CalcSpellAttackTime(Spell));
					if( Spell->mCastTime > 0 )
					{
						SetCanMove(false);
						SetBehavior(Behavior_Spell);
					}
				}
				return;	//Scheduling one spell at a time, exit now
			}
			else if( Spell->mChance != 100 ) ChanceTotal += Spell->mChance;	//Only add spells that aren't 100% chance of casting
		}

		//Go back to default behavior since we didn't decide anything
		SetCanMove(true);
		SetBehavior(Behavior_Melee);

		//Random taunts
		if( ChanceRoll >= 95 ) RandomEmote(mOnTauntEmotes);
	}
}
//-----------------------------------------------------------------------------
// Purpose: Tesla effect
//-----------------------------------------------------------------------------
void C_EntityDissolve::BuildTeslaEffect( mstudiobbox_t *pHitBox, const matrix3x4_t &hitboxToWorld, bool bRandom, float flYawOffset )
{
	Vector vecOrigin;
	QAngle vecAngles;
	MatrixGetColumn( hitboxToWorld, 3, vecOrigin );
	MatrixAngles( hitboxToWorld, vecAngles.Base() );
	C_BaseEntity *pEntity = GetMoveParent();

	// Make a couple of tries at it
	int iTries = -1;
	Vector vecForward;
	trace_t tr;
	do
	{
		iTries++;

		// Some beams are deliberatly aimed around the point, the rest are random.
		if ( !bRandom )
		{
			QAngle vecTemp = vecAngles;
			vecTemp[YAW] += flYawOffset;
			AngleVectors( vecTemp, &vecForward );

			// Randomly angle it up or down
			vecForward.z = RandomFloat( -1, 1 );
		}
		else
		{
			vecForward = RandomVector( -1, 1 );
		}

		UTIL_TraceLine( vecOrigin, vecOrigin + (vecForward * 192), MASK_SHOT, pEntity, COLLISION_GROUP_NONE, &tr );
	} while ( tr.fraction >= 1.0 && iTries < 3 );

	Vector vecEnd = tr.endpos - (vecForward * 8);

	// Only spark & glow if we hit something
	if ( tr.fraction < 1.0 )
	{
		if ( !EffectOccluded( tr.endpos ) )
		{
			// Move it towards the camera
			Vector vecFlash = tr.endpos;
			Vector vecForward;
			AngleVectors( MainViewAngles(), &vecForward );
			vecFlash -= (vecForward * 8);

			g_pEffects->EnergySplash( vecFlash, -vecForward, false );

			// End glow
			CSmartPtr<CSimpleEmitter> pSimple = CSimpleEmitter::Create( "dust" );
			pSimple->SetSortOrigin( vecFlash );
			SimpleParticle *pParticle;
			pParticle = (SimpleParticle *) pSimple->AddParticle( sizeof( SimpleParticle ), pSimple->GetPMaterial( "effects/tesla_glow_noz" ), vecFlash );
			if ( pParticle != NULL )
			{
				pParticle->m_flLifetime = 0.0f;
				pParticle->m_flDieTime	= RandomFloat( 0.5, 1 );
				pParticle->m_vecVelocity = vec3_origin;
				Vector color( 1,1,1 );
				float  colorRamp = RandomFloat( 0.75f, 1.25f );
				pParticle->m_uchColor[0]	= MIN( 1.0f, color[0] * colorRamp ) * 255.0f;
				pParticle->m_uchColor[1]	= MIN( 1.0f, color[1] * colorRamp ) * 255.0f;
				pParticle->m_uchColor[2]	= MIN( 1.0f, color[2] * colorRamp ) * 255.0f;
				pParticle->m_uchStartSize	= RandomFloat( 6,13 );
				pParticle->m_uchEndSize		= pParticle->m_uchStartSize - 2;
				pParticle->m_uchStartAlpha	= 255;
				pParticle->m_uchEndAlpha	= 10;
				pParticle->m_flRoll			= RandomFloat( 0,360 );
				pParticle->m_flRollDelta	= 0;
			}
		}
	}

	// Build the tesla
	FX_BuildTesla( pEntity, vecOrigin, tr.endpos );
}
Beispiel #25
0
//-----------------------------------------------------------------------------
// Purpose:
// Input  : *pPlayer -
//			*pMoveData -
//-----------------------------------------------------------------------------
void CPropCrane::RunCraneMovement( float flTime )
{
    if ( m_flExtensionRate )
    {
        // Extend / Retract the crane
        m_flExtension = clamp( m_flExtension + (m_flExtensionRate * 10 * flTime), 0, 2 );
        SetPoseParameter( "armextensionpose", m_flExtension );
        StudioFrameAdvance();
    }

    // Drop the magnet until it hits the ground
    if ( m_bDropping )
    {
        // Drop until the magnet hits something
        if ( m_hCraneMagnet->HasHitSomething() )
        {
            // We hit the ground, stop dropping
            m_hCraneTip->m_pSpring->SetSpringConstant( CRANE_SPRING_CONSTANT_INITIAL_RAISING );
            m_bDropping = false;
            m_flNextDropAllowedTime = gpGlobals->curtime + 3.0;
            m_flSlowRaiseTime = gpGlobals->curtime;

            m_ServerVehicle.PlaySound( VS_MISC2 );
        }
    }
    else if ( (m_flSlowRaiseTime + CRANE_SLOWRAISE_TIME) > gpGlobals->curtime )
    {
        float flDelta = (gpGlobals->curtime - m_flSlowRaiseTime);

        flDelta = clamp( flDelta, 0, CRANE_SLOWRAISE_TIME );
        float flCurrentSpringConstant = RemapVal( flDelta, 0, CRANE_SLOWRAISE_TIME, CRANE_SPRING_CONSTANT_INITIAL_RAISING, CRANE_SPRING_CONSTANT_HANGING );
        m_hCraneTip->m_pSpring->SetSpringConstant( flCurrentSpringConstant );
    }

    // If we've moved in any way, update the tip
    if ( m_bDropping || m_flExtensionRate || GetLocalAngularVelocity() != vec3_angle )
    {
        RecalculateCraneTip();
    }

    // Make danger sounds underneath the magnet if we have something attached to it
    /*
    if ( (m_flNextDangerSoundTime < gpGlobals->curtime) && (m_hCraneMagnet->GetTotalMassAttachedObjects() > 0) )
    {
    	// Trace down from the magnet and make a danger sound on the ground
    	trace_t tr;
    	Vector vecSource = m_hCraneMagnet->GetAbsOrigin();
    	UTIL_TraceLine( vecSource, vecSource - Vector(0,0,2048), MASK_SOLID_BRUSHONLY, m_hCraneMagnet, 0, &tr );

    	if ( tr.fraction < 1.0 )
    	{
    		// Make the volume proportional to the amount of mass on the magnet
    		float flVolume = clamp( (m_hCraneMagnet->GetTotalMassAttachedObjects() * 0.5), 100.f, 600.f );
    		CSoundEnt::InsertSound( SOUND_DANGER, tr.endpos, flVolume, 0.2, this );

    		//Msg("Total: %.2f Volume: %.2f\n", m_hCraneMagnet->GetTotalMassAttachedObjects(), flVolume );
    		//Vector vecVolume = Vector(flVolume,flVolume,flVolume) * 0.5;
    		//NDebugOverlay::Box( tr.endpos, -vecVolume, vecVolume, 255,0,0, false, 0.3 );
    		//NDebugOverlay::Cross3D( tr.endpos, -Vector(10,10,10), Vector(10,10,10), 255,0,0, false, 0.3 );
    	}

    	m_flNextDangerSoundTime = gpGlobals->curtime + 0.3;
    }
    */

    // Play creak sounds on the magnet if there's heavy weight on it
    if ( (m_flNextCreakSound < gpGlobals->curtime) && (m_hCraneMagnet->GetTotalMassAttachedObjects() > 100) )
    {
        // Randomly play creaks from the magnet, and increase the chance based on the turning speed
        float flSpeedPercentage = clamp( fabs(m_flTurn) / m_flMaxTurnSpeed, 0, 1 );
        if ( RandomFloat(0,1) > (0.95 - (0.1 * flSpeedPercentage)) )
        {
            if ( m_ServerVehicle.m_vehicleSounds.iszSound[VS_MISC4] != NULL_STRING )
            {
                CPASAttenuationFilter filter( m_hCraneMagnet );

                EmitSound_t ep;
                ep.m_nChannel = CHAN_VOICE;
                ep.m_pSoundName = STRING(m_ServerVehicle.m_vehicleSounds.iszSound[VS_MISC4]);
                ep.m_flVolume = 1.0f;
                ep.m_SoundLevel = SNDLVL_NORM;

                CBaseEntity::EmitSound( filter, m_hCraneMagnet->entindex(), ep );
            }
            m_flNextCreakSound = gpGlobals->curtime + 5.0;
        }
    }
}
Beispiel #26
0
void CASW_Rocket::SeekThink( void )
{
	// If we have a grace period, go solid when it ends
	if ( m_flGracePeriodEndsAt )
	{
		if ( m_flGracePeriodEndsAt < gpGlobals->curtime )
		{
			RemoveSolidFlags( FSOLID_NOT_SOLID );
			m_flGracePeriodEndsAt = 0;
		}
	}

	Vector vNewVelocity = GetAbsVelocity();
	
	if ( m_bFlyingWild )
	{
		// wobble crazily. Poll for a new target every quarter second, and if none is found, go
		// careering off.
		if ( gpGlobals->curtime >= m_flNextWobbleTime )
		{
			Assert( !m_hHomingTarget.Get() );
			CBaseEntity *pHomingTarget = FindPotentialTarget(); 
			if ( pHomingTarget )
			{
				SetTarget( pHomingTarget );
				m_bFlyingWild = false;
			}
			else
			{
				// pick a new wobble direction
				/*
				m_vWobbleAngles = GetAbsAngles();
				m_vWobbleAngles.y =  m_vWobbleAngles.y + RandomFloat( -asw_rocket_wobble_amp.GetFloat(), asw_rocket_wobble_amp.GetFloat() ) ;
				if ( m_vWobbleAngles.y < 0 )
				{
					m_vWobbleAngles.y = 360 + m_vWobbleAngles.y;
				}
				else if ( m_vWobbleAngles.y > 360 )
				{
					m_vWobbleAngles.y = fmod( m_vWobbleAngles.y, 360 );
				}

				*/

				m_vWobbleAngles = GetAbsAngles();
				m_vWobbleAngles.y = fmodf( m_vWobbleAngles.y + RandomFloat( -asw_rocket_wobble_amp.GetFloat(), asw_rocket_wobble_amp.GetFloat() ), 360 );

				m_flNextWobbleTime = gpGlobals->curtime + asw_rocket_wobble_freq.GetFloat();
			}
		}
	}


	if ( !m_bFlyingWild )
	{
		Vector	targetPos;
		FindHomingPosition( &targetPos );

		// find target direction
		Vector	vTargetDir;
		VectorSubtract( targetPos, GetAbsOrigin(), vTargetDir );
		float flDist = VectorNormalize( vTargetDir );

		// find current direction
		Vector	vDir	= GetAbsVelocity();
		//float	flSpeed	= VectorNormalize( vDir );

		vNewVelocity = IntegrateRocketThrust( vTargetDir, flDist );

		// face direction of movement
		QAngle	finalAngles;
		VectorAngles( vNewVelocity, finalAngles );
		SetAbsAngles( finalAngles );

		// set to the new calculated velocity
		SetAbsVelocity( vNewVelocity );
	}
	else // wobble crazily
	{
#pragma message("TODO: straighten out this math")
		if ( gpGlobals->curtime >= m_flNextWobbleTime )
		{
			// pick a new wobble direction
			m_vWobbleAngles = GetAbsAngles();
			m_vWobbleAngles.y = fmodf( m_vWobbleAngles.y + RandomFloat( -asw_rocket_wobble_amp.GetFloat(), asw_rocket_wobble_amp.GetFloat() ), 360 );

			m_flNextWobbleTime = gpGlobals->curtime + asw_rocket_wobble_freq.GetFloat();
		}
		QAngle finalAngles = GetAbsAngles();
		finalAngles.y = ApproachAngle( m_vWobbleAngles.y, finalAngles.y, 360.f * (gpGlobals->curtime - GetLastThink()) );

		Vector forward;
		AngleVectors( finalAngles, &forward );
		vNewVelocity = forward * FastSqrtEst( vNewVelocity.LengthSqr() );
		if ( IsWallDodging() )
		{
			ComputeWallDodge( vNewVelocity );
			finalAngles.y = ApproachAngle( m_vWobbleAngles.y, finalAngles.y, 360.f * (gpGlobals->curtime - GetLastThink()) );
		}

		vNewVelocity = IntegrateRocketThrust( forward, 0 );

		// face direction of movement
		SetAbsAngles( finalAngles );

		// set to the new calculated velocity
		SetAbsVelocity( vNewVelocity );
	}

	// blow us up after our lifetime
	if (GetLifeFraction() >= 1.0f)
	{
		Explode();
	}
	else
	{
		// Think as soon as possible
		SetNextThink( gpGlobals->curtime );
	}
}
Beispiel #27
0
	void AIUpdate()
	{
		float TarCast = (float)RandomFloat(100.0f);
		CastSpell(TarCast);
	}
//-----------------------------------------------------------------------------
// Purpose: 
//-----------------------------------------------------------------------------
void CWeaponSMG1::Operator_HandleAnimEvent( animevent_t *pEvent, CBaseCombatCharacter *pOperator )
{
	switch( pEvent->event )
	{
	case EVENT_WEAPON_SMG1:
		{
			Vector vecShootOrigin, vecShootDir;
			QAngle angDiscard;

			// Support old style attachment point firing
			if ((pEvent->options == NULL) || (pEvent->options[0] == '\0') || (!pOperator->GetAttachment(pEvent->options, vecShootOrigin, angDiscard)))
			{
				vecShootOrigin = pOperator->Weapon_ShootPosition();
			}

			CAI_BaseNPC *npc = pOperator->MyNPCPointer();
			ASSERT( npc != NULL );
			vecShootDir = npc->GetActualShootTrajectory( vecShootOrigin );

			FireNPCPrimaryAttack( pOperator, vecShootOrigin, vecShootDir );
		}
		break;

	case EVENT_WEAPON_AR2_ALTFIRE:
		{
			CAI_BaseNPC *npc = pOperator->MyNPCPointer();

			Vector vecShootOrigin, vecShootDir;
			vecShootOrigin = pOperator->Weapon_ShootPosition();
			//vecShootDir = npc->GetShootEnemyDir( vecShootOrigin );

			//Checks if it can fire the grenade
			WeaponRangeAttack2Condition();

			Vector vecThrow = m_vecTossVelocity;

			//If on the rare case the vector is 0 0 0, cancel for avoid launching the grenade without speed
			//This should be on WeaponRangeAttack2Condition(), but for some unknown reason return CASE_NONE
			//doesn't stop the launch
			if (vecThrow == Vector(0, 0, 0))
			{
				break;
			}

			CGrenadeAR2 *pGrenade = (CGrenadeAR2*)Create("grenade_ar2", vecShootOrigin, vec3_angle, npc);
			pGrenade->SetAbsVelocity(vecThrow);
			pGrenade->SetLocalAngularVelocity(RandomAngle(-400, 400)); //tumble in air
			pGrenade->SetMoveType(MOVETYPE_FLYGRAVITY, MOVECOLLIDE_FLY_BOUNCE);

			pGrenade->SetThrower(GetOwner());

			pGrenade->SetGravity(0.5); // lower gravity since grenade is aerodynamic and engine doesn't know it.

			pGrenade->SetDamage(sk_plr_dmg_smg1_grenade.GetFloat());

			if (g_pGameRules->IsSkillLevel(SKILL_HARD))
			{
				m_flNextGrenadeCheck = gpGlobals->curtime + RandomFloat(2,3);
			}
			else if (g_pGameRules->IsSkillLevel(SKILL_VERYHARD))
			{
				m_flNextGrenadeCheck = gpGlobals->curtime + RandomFloat(1.5,2);
			}
			else if (g_pGameRules->IsSkillLevel(SKILL_NIGHTMARE))
			{
				m_flNextGrenadeCheck = gpGlobals->curtime + RandomFloat(1,1.5);
			}
			else
			{
				m_flNextGrenadeCheck = gpGlobals->curtime + 6;// wait six seconds before even looking again to see if a grenade can be thrown.
			}

			m_iClip2--;
		}
		break;

	default:
		BaseClass::Operator_HandleAnimEvent( pEvent, pOperator );
		break;
	}
}
		void AIUpdate()
		{
			float val = RandomFloat(100.0f);
			SpellCast(val);
		}
vParticleOperator_RainSimulation::vParticleOperator_RainSimulation()
{
	veloSaved.Init();
	flIdleTime = 0;
	flMoveTime = CFrameTimeHelper::GetCurrentTime() + RandomFloat( 0.2f, 0.4f );
}