void CRotButton::Spawn( void ) { Precache(); // set the axis of rotation AxisDir( pev ); // check for clockwise rotation if( FBitSet( pev->spawnflags, SF_ROTBUTTON_ROTATE_BACKWARDS )) pev->movedir = pev->movedir * -1; pev->movetype = MOVETYPE_PUSH; if( FBitSet( pev->spawnflags, SF_ROTBUTTON_PASSABLE )) pev->solid = SOLID_NOT; else pev->solid = SOLID_BSP; // shared code use this flag as BUTTON_DONTMOVE so we need to clear it here ClearBits( pev->spawnflags, SF_ROTBUTTON_PASSABLE ); ClearBits( pev->spawnflags, SF_BUTTON_SPARK_IF_OFF ); ClearBits( pev->spawnflags, SF_BUTTON_DAMAGED_AT_LASER ); SET_MODEL( edict(), GetModel() ); if( pev->speed == 0 ) pev->speed = 40; if( m_flWait == 0 ) m_flWait = 1; if( pev->health > 0 ) { pev->takedamage = DAMAGE_YES; } m_iState = STATE_OFF; m_vecAngle1 = GetLocalAngles(); m_vecAngle2 = GetLocalAngles() + pev->movedir * m_flMoveDistance; ASSERTSZ( m_vecAngle1 != m_vecAngle2, "rotating button start/end positions are equal" ); m_fStayPushed = (m_flWait == -1) ? TRUE : FALSE; m_fRotating = TRUE; // if the button is flagged for USE button activation only, take away it's touch function and add a use function if( !FBitSet( pev->spawnflags, SF_BUTTON_TOUCH_ONLY )) { SetTouch( NULL ); SetUse( &CBaseButton::ButtonUse ); } else { // touchable button SetTouch( &CBaseButton::ButtonTouch ); } UTIL_SetOrigin( this, GetLocalOrigin( )); m_pUserData = WorldPhysic->CreateKinematicBodyFromEntity( this ); }
void CMomentaryRotButton :: Spawn( void ) { // g-cont. just to have two seperate entities if( FClassnameIs( pev, "momentary_rot_door" )) SetBits( pev->spawnflags, SF_MOMENTARY_ROT_DOOR ); Precache(); AxisDir( pev ); m_bUpdateTarget = true; if( pev->speed == 0 ) pev->speed = 100; m_startPosition = bound( 0.0f, m_startPosition, 1.0f ); if( m_flMoveDistance < 0 ) { pev->movedir = pev->movedir * -1; m_flMoveDistance = -m_flMoveDistance; } m_direction = -1; m_start = GetLocalAngles() - pev->movedir * m_flMoveDistance * m_startPosition; m_end = GetLocalAngles() + pev->movedir * m_flMoveDistance * (1.0f - m_startPosition); pev->ideal_yaw = m_startPosition; m_iState = STATE_OFF; if( FBitSet( pev->spawnflags, SF_MOMENTARY_ROT_DOOR )) pev->solid = SOLID_BSP; else pev->solid = SOLID_NOT; pev->movetype = MOVETYPE_PUSH; SET_MODEL( edict(), GetModel() ); UTIL_SetOrigin( this, GetLocalOrigin( )); m_lastUsed = 0; m_pUserData = WorldPhysic->CreateKinematicBodyFromEntity( this ); SetUse( &CMomentaryRotButton::ButtonUse ); }
void CRotDoor :: Spawn( void ) { // set the axis of rotation AxisDir( pev ); if( FBitSet( pev->spawnflags, SF_DOOR_PASSABLE )) pev->solid = SOLID_NOT; else pev->solid = SOLID_BSP; Precache(); // check for clockwise rotation if( FBitSet( pev->spawnflags, SF_DOOR_ROTATE_BACKWARDS )) pev->movedir = pev->movedir * -1; m_vecAngle1 = GetLocalAngles(); m_vecAngle2 = GetLocalAngles() + pev->movedir * m_flMoveDistance; ASSERTSZ( m_vecAngle1 != m_vecAngle2, "rotating door start/end positions are equal" ); pev->movetype = MOVETYPE_PUSH; SET_MODEL( edict(), GetModel() ); // NOTE: original Half-Life was contain a bug in AngularMove function // while m_flWait was equal 0 then object has stopped forever. See code from quake: /* void AngularMove( Vector vecDest, float flSpeed ) { ... ... ... if( flTravelTime < 0.1f ) { pev->avelocity = g_vecZero; pev->nextthink = pev->ltime + 0.1f; return; } } */ // this block was removed from Half-Life and there no difference // between wait = 0 and wait = -1. But in Xash this bug was fixed // and level-designer errors is now actual. I'm set m_flWait to -1 for compatibility if( m_flWait == 0.0f ) m_flWait = -1; if( pev->speed == 0 ) pev->speed = 100; // DOOR_START_OPEN is to allow an entity to be lighted in the closed position // but spawn in the open position if( FBitSet( pev->spawnflags, SF_DOOR_START_OPEN )) { // swap pos1 and pos2, put door at pos2, invert movement direction Vector vecNewAngles = m_vecAngle2; m_vecAngle2 = m_vecAngle1; m_vecAngle1 = vecNewAngles; pev->movedir = pev->movedir * -1; // We've already had our physics setup in BaseClass::Spawn, so teleport to our // current position. If we don't do this, our vphysics shadow will not update. Teleport( NULL, &m_vecAngle1, NULL ); } else { SetLocalAngles( m_vecAngle1 ); } m_iState = STATE_OFF; RelinkEntity(); m_pUserData = WorldPhysic->CreateKinematicBodyFromEntity( this ); if( FBitSet( pev->spawnflags, SF_DOOR_USE_ONLY )) { SetTouch( NULL ); } else { // touchable button SetTouch( DoorTouch ); } }