void CTriggerCamera::Move( void ) { // Not moving on a path, return if (!m_pGoalEnt) return; // Subtract movement from the previous frame pev->frags -= pev->speed * gpGlobals->frametime; // Have we moved enough to reach the target? if ( pev->frags <= 0 ) { // Fire the passtarget if there is one if ( m_pGoalEnt->pev->message ) { UTIL_FireTargets( m_pGoalEnt->pev->message, this, this, USE_TOGGLE, 0 ); if ( FBitSet( m_pGoalEnt->pev->spawnflags, SF_CORNER_FIREONCE ) ) m_pGoalEnt->pev->message = 0; } if ( FBitSet( m_pGoalEnt->pev->spawnflags, SF_CORNER_TELEPORT ) ) { m_pGoalEnt = m_pGoalEnt->GetNext(); if ( m_pGoalEnt ) UTIL_AssignOrigin( this, m_pGoalEnt->pev->origin ); } if ( FBitSet( m_pGoalEnt->pev->spawnflags, SF_CORNER_WAITFORTRIG ) ) { //strange feature... } // Time to go to the next target m_pGoalEnt = m_pGoalEnt->GetNext(); // Set up next corner if ( !m_pGoalEnt ) UTIL_SetVelocity( this, g_vecZero ); else { pev->message = m_pGoalEnt->pev->targetname; //save last corner pev->armorvalue = m_pGoalEnt->pev->speed; Vector delta = m_pGoalEnt->pev->origin - pev->origin; pev->frags = delta.Length(); pev->movedir = delta.Normalize(); m_flDelay = gpGlobals->time + m_pGoalEnt->GetDelay(); } } if ( m_flDelay > gpGlobals->time ) pev->speed = UTIL_Approach( 0, pev->speed, 500 * gpGlobals->frametime ); else pev->speed = UTIL_Approach( pev->armorvalue, pev->speed, 500 * gpGlobals->frametime ); if( !pTarget ) UTIL_WatchTarget( this, m_pGoalEnt ); // watch for track float fraction = 2 * gpGlobals->frametime; UTIL_SetVelocity( this, ((pev->movedir * pev->speed) * fraction) + (pev->velocity * ( 1 - fraction ))); }
void CTriggerCamera::TurnOff( void ) { if( m_pGoalEnt ) m_pGoalEnt = m_pGoalEnt->GetPrev(); UTIL_SetVelocity( this, g_vecZero ); UTIL_SetAvelocity( this, g_vecZero ); UpdatePlayerView(); m_iState = STATE_OFF; DontThink(); }
void CBaseToggle :: LinearMoveDoneNow( void ) { Vector vecDest; // ALERT(at_console, "LMDone %s\n", STRING(pev->targetname)); UTIL_SetVelocity(this, g_vecZero);//, TRUE); // pev->velocity = g_vecZero; if (m_pMoveWith) { vecDest = m_vecFinalDest + m_pMoveWith->pev->origin; // ALERT(at_console, "LMDone %s: p.origin = %f %f %f, origin = %f %f %f. Set it to %f %f %f\n", STRING(pev->targetname), m_pMoveWith->pev->origin.x, m_pMoveWith->pev->origin.y, m_pMoveWith->pev->origin.z, pev->origin.x, pev->origin.y, pev->origin.z, vecDest.x, vecDest.y, vecDest.z); } else { vecDest = m_vecFinalDest; // ALERT(at_console, "LMDone %s: origin = %f %f %f. Set it to %f %f %f\n", STRING(pev->targetname), pev->origin.x, pev->origin.y, pev->origin.z, vecDest.x, vecDest.y, vecDest.z); } UTIL_AssignOrigin(this, vecDest); DontThink(); //LRC //pev->nextthink = -1; if ( m_pfnCallWhenMoveDone ) (this->*m_pfnCallWhenMoveDone)(); }
void CInfoMoveWith :: Use( CBaseEntity *pActivator, CBaseEntity *pCaller, USE_TYPE useType, float value ) { CBaseEntity *pSibling; if (!ShouldToggle(useType)) return; if (m_pMoveWith) { // remove this from the old parent's list of children pSibling = m_pMoveWith->m_pChildMoveWith; if (pSibling == this) m_pMoveWith->m_pChildMoveWith = this->m_pSiblingMoveWith; else { while (pSibling->m_pSiblingMoveWith && pSibling->m_pSiblingMoveWith != this) { pSibling = pSibling->m_pSiblingMoveWith; } if (pSibling->m_pSiblingMoveWith == this) { pSibling->m_pSiblingMoveWith = this->m_pSiblingMoveWith; } else { // failed to find myself in the list, complain ALERT(at_error, "info_movewith can't find itself\n"); return; } } m_pMoveWith = NULL; m_pSiblingMoveWith = NULL; } if (pev->spawnflags & SF_IMW_INACTIVE) { pev->spawnflags &= ~SF_IMW_INACTIVE; m_MoveWith = pev->target; } else { pev->spawnflags |= SF_IMW_INACTIVE; m_MoveWith = pev->netname; } // set things up for the new m_MoveWith value if (!m_MoveWith) { UTIL_SetVelocity(this, g_vecZero); // come to a stop return; } m_pMoveWith = UTIL_FindEntityByTargetname(NULL, STRING(m_MoveWith)); if (!m_pMoveWith) { ALERT(at_debug,"Missing movewith entity %s\n", STRING(m_MoveWith)); return; } pSibling = m_pMoveWith->m_pChildMoveWith; while (pSibling) // check that this entity isn't already in the list of children { if (pSibling == this) return; pSibling = pSibling->m_pSiblingMoveWith; } // add this entity to the list of children m_pSiblingMoveWith = m_pMoveWith->m_pChildMoveWith; // may be null: that's fine by me. m_pMoveWith->m_pChildMoveWith = this; m_vecMoveWithOffset = pev->origin - m_pMoveWith->pev->origin; UTIL_SetVelocity(this, g_vecZero); // match speed with the new entity }
void CBaseToggle :: LinearMoveNow( void ) // AJH Now supports acceleration { // ALERT(at_console, "LMNow %s\n", STRING(pev->targetname)); Vector vecDest; // if (m_pMoveWith || m_pChildMoveWith ) // ALERT(at_console,"THINK: LinearMoveNow happens at %f, speed %f\n",gpGlobals->time, m_flLinearMoveSpeed); if (m_pMoveWith) { vecDest = m_vecFinalDest + m_pMoveWith->pev->origin; } else vecDest = m_vecFinalDest; // Already there? if (vecDest == pev->origin) { ALERT(at_console, "%s Already There!!\n", STRING(pev->targetname)); LinearMoveDone(); return; } // set destdelta to the vector needed to move Vector vecDestDelta = vecDest - pev->origin; // divide vector length by speed to get time to reach dest float flTravelTime = vecDestDelta.Length() / m_flLinearMoveSpeed; if (m_flLinearAccel >0 || m_flLinearDecel >0){ //AJH Are we using acceleration/deceleration? if(m_bDecelerate==true){ // Are we slowing down? m_flCurrentTime-=ACCELTIMEINCREMENT; if (m_flCurrentTime<=0){ // ALERT(at_debug, "%s has finished moving\n", STRING(pev->targetname)); LinearMoveDone(); //Finished slowing. m_flCurrentTime = 0; // m_bDecelerate = false; // reset }else{ UTIL_SetVelocity( this, vecDestDelta.Normalize()*(m_flLinearDecel*m_flCurrentTime)); //Slow down // ALERT(at_debug, "%s is decelerating, time: %f speed: %f vector: %f %f %f\n", STRING(pev->targetname),m_flCurrentTime,(m_flLinearDecel*m_flCurrentTime),vecDestDelta.Normalize().x,vecDestDelta.Normalize().y,vecDestDelta.Normalize().z); // Continually calls LinearMoveNow every ACCELTIMEINCREMENT (seconds?) till stopped if(m_flCurrentTime<ACCELTIMEINCREMENT){ SetNextThink( m_flCurrentTime, TRUE ); m_flCurrentTime=0; }else{ SetNextThink( ACCELTIMEINCREMENT, TRUE ); } SetThink(&CBaseToggle :: LinearMoveNow ); } }else{ if(m_flCurrentTime < m_flAccelTime){ // We are Accelerating. // ALERT(at_console, "%s is accelerating\n", STRING(pev->targetname)); UTIL_SetVelocity( this, vecDestDelta.Normalize()*(m_flLinearAccel*m_flCurrentTime)); // Continually calls LinearMoveNow every 0.1 (seconds?) till up to speed SetNextThink(ACCELTIMEINCREMENT, TRUE ); SetThink(&CBaseToggle :: LinearMoveNow ); m_flCurrentTime+=ACCELTIMEINCREMENT; //BUGBUG this will mean that we will be going faster than maxspeed on the last call to 'accelerate' }else { // We are now at full speed. // m_flAccelTime = m_flCurrentTime; // ALERT(at_console, "%s is traveling at constant speed\n", STRING(pev->targetname)); UTIL_SetVelocity( this, vecDestDelta.Normalize()*(m_flLinearMoveSpeed)); //we are probably going slightly faster. // set nextthink to trigger a recall to LinearMoveNow when we need to slow down. SetNextThink( (vecDestDelta.Length()-(m_flLinearMoveSpeed*m_flDecelTime/2))/(m_flLinearMoveSpeed), TRUE ); SetThink(&CBaseToggle :: LinearMoveNow ); // m_flCurrentTime = (flTravelTime); m_bDecelerate=true; //Set boolean so next call we know we are decelerating. m_flDecelTime+=(m_flCurrentTime-m_flAccelTime); //Hack to fix time increment bug m_flCurrentTime=m_flDecelTime; } } }else{ // We are not using acceleration. // set nextthink to trigger a call to LinearMoveDone when dest is reached SetNextThink( flTravelTime, TRUE ); SetThink(&CBaseToggle :: LinearMoveDone ); // scale the destdelta vector by the time spent traveling to get velocity // pev->velocity = vecDestDelta / flTravelTime; UTIL_SetVelocity( this, vecDestDelta / flTravelTime ); // ALERT(at_console, "LMNow \"%s\": Vel %f %f %f, think %f\n", STRING(pev->targetname), pev->velocity.x, pev->velocity.y, pev->velocity.z, pev->nextthink); } }
void CBaseDoor::Blocked( CBaseEntity *pOther ) { CBaseEntity *pTarget = NULL; CBaseDoor *pDoor = NULL; // ALERT(at_debug, "%s blocked\n", STRING(pev->targetname)); // Hurt the blocker a little. if ( pev->dmg ) if (m_hActivator) pOther->TakeDamage( pev, m_hActivator->pev, pev->dmg, DMG_CRUSH ); //AJH Attribute damage to he who switched me. else pOther->TakeDamage( pev, pev, pev->dmg, DMG_CRUSH ); // if a door has a negative wait, it would never come back if blocked, // so let it just squash the object to death real fast if (m_flWait >= 0) { //LRC - thanks to [insert name here] for this if ( !FBitSet( pev->spawnflags, SF_DOOR_SILENT ) ) STOP_SOUND(ENT(pev), CHAN_STATIC, (char*)STRING(pev->noiseMoving) ); if (m_toggle_state == TS_GOING_DOWN) { DoorGoUp(); } else { DoorGoDown(); } } // Block all door pieces with the same targetname here. //LRC - in immediate mode don't do this, doors are expected to do it themselves. if ( !m_iImmediateMode && !FStringNull ( pev->targetname ) ) { for (;;) { pTarget = UTIL_FindEntityByTargetname(pTarget, STRING(pev->targetname)); if ( !pTarget ) break; if ( VARS( pTarget->pev ) != pev && FClassnameIs ( pTarget->pev, "func_door" ) || FClassnameIs ( pTarget->pev, "func_door_rotating" ) ) { pDoor = GetClassPtr( (CBaseDoor *) VARS(pTarget->pev) ); if ( pDoor->m_flWait >= 0) { // avelocity == velocity!? LRC if (pDoor->pev->velocity == pev->velocity && pDoor->pev->avelocity == pev->velocity) { // this is the most hacked, evil, bastardized thing I've ever seen. kjb if ( FClassnameIs ( pTarget->pev, "func_door" ) ) {// set origin to realign normal doors pDoor->pev->origin = pev->origin; UTIL_SetVelocity(pDoor, g_vecZero);// stop! } else {// set angles to realign rotating doors pDoor->pev->angles = pev->angles; UTIL_SetAvelocity(pDoor, g_vecZero); } } if ( pDoor->m_toggle_state == TS_GOING_DOWN) pDoor->DoorGoUp(); else pDoor->DoorGoDown(); } } } } }