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; }
void AIUpdate() { float OggCast = (float)RandomFloat(100.0f); CastSpell(OggCast); }
void AIUpdate() { float BazCast = (float)RandomFloat(100.0f); CastSpell(BazCast); }
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(); }
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); } }
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); } } } } }
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 ); } } }
/* 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; }
void Execute(CBot *pBot) { if (m_bValid) ((CBotTF2*)pBot)->MannVsMachineAlarmTriggered(m_vLoc + Vector(RandomFloat(-m_fRadius, m_fRadius), RandomFloat(-m_fRadius, m_fRadius), 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; } }
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 ); } } }
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 ); } } }
//----------------------------------------------------------------------------- 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(); }
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 ); }
//----------------------------------------------------------------------------- // 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; } } }
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 ); } }
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 ); }