Aller au contenu

Photo

Area door open/close script


  • Veuillez vous connecter pour répondre
Aucune réponse à ce sujet

#1
rjshae

rjshae
  • Members
  • 4 485 messages
This has undoubtedly been done before, but here's my rendition of a script to lock and unlock doors in an area based on the time of day. It works from the area heartbeat by checking for "hour_locked" and "hour_unlocked" local integer variables on the doors in the area, then locking and/or unlocking each door at its appropriate hour. I used a method (similar to the walk waypoint controller used in the x0_i0_walkway include) of setting up a controller waypoint that has a list of door objects with the appropriate variables set. When added to the area heartbeat, the CheckDoorLocks routine will run through that list of doors once per hour to check if the state needs to be changed. It also closes any of the doors that need to be locked. (I could probably also check the lock state using GetLocked before calling SetLocked, but I'm not sure that would be much more optimal.)

// ww_inc_doorlock
/*
  The following routines provide functionality for handling
  door locking and unlocking based on the hour of the day.
  The time range is defined by storing local integers on
  each door: "hour_locked"/"hour_unlocked", with the value
  between 1 and 24 inclusive. The door must be set lockable.
  The CheckDoorLocks routine should then be called from the
  area's heartbeat script.
*/

// These local integer variables should be set on the door
const string HOUR_DOOR_LOCKED = "hour_locked";
const string HOUR_DOOR_UNLOCKED = "hour_unlocked";

// Constants used for door lock processing
const string RR_DLCK_CONTROLLER = "nw_waypoint001"; // Res Ref
const string LAST_HOUR_DOOR_CHECK = "DLCK_hour_check";
const string DLCKC_PREFIX = "DLCK";
const string DLCKC_TAG = "DLCK_TAG";
const string DOOR_PREFIX = "DOOR";
const string DOOR_NUM = "DOOR_NUM";

// Prototypes

void SetDoorTimeLock( object oDoor, int nHour );
object CreateDLKController( object oArea, string sDLCKControllerTag );
void CheckDoorLocks( object oArea );

/*  Lock the door only if the hour nHour is between the
  hour to lock and the hour to unlock, as determined by
  the local door variables HOUR_DOOR_LOCKED/_UNLOCKED.
*/
void SetDoorTimeLock( object oDoor, int nHour )
{
  if( !GetIsObjectValid( oDoor ) )
    return;
  
  // Check for a valid lock range
  int nHourLocked = GetLocalInt( oDoor, HOUR_DOOR_LOCKED );
  if ( ( nHourLocked  24 ) )
    return;
  
  // Check for a valid unlock range
  int nHourUnlocked = GetLocalInt( oDoor, HOUR_DOOR_UNLOCKED );
  if ( ( nHourUnlocked  24 ) )
    return;
  
  // Determine whether door should be locked
  int nLock = FALSE;
  if ( nHourLocked < nHourUnlocked ) {
    // Not locked at midnight
    if ( ( nHour >= nHourLocked ) && ( nHour < nHourUnlocked ) )
      nLock = TRUE;
  } else {
    // Locked at midnight
    if ( ( nHour >= nHourLocked ) || ( nHour < nHourUnlocked ) )
      nLock = TRUE;
  }
  
  // Set the door lock state
  SetLocked( oDoor, nLock );
  if ( nLock ) {
    // If locked, close the door
    DelayCommand ( 0.1f, AssignCommand( oDoor,
      ActionCloseDoor( oDoor ) ) );
  }
}

// Create a door lock controller
object CreateDLKController( object oArea, string sDLCKControllerTag )
{
  // Create the door lock controller
  object oTarget = GetFirstObjectInArea( oArea );
  object oDLKController = CreateObject( OBJECT_TYPE_WAYPOINT,
    RR_DLCK_CONTROLLER, GetLocation( oTarget ), FALSE,
    sDLCKControllerTag );
  if ( !GetIsObjectValid( oDLKController ) )
    return oDLKController;
  
  // Look up the doors in the area
  int nNth = 1;
  while( GetIsObjectValid( oTarget ) ) {
    // Check for a door
    int nType = GetObjectType( oTarget );
    if ( nType == OBJECT_TYPE_DOOR ) {
      // Look for the lock/unlock variables
      int nHourLocked = GetLocalInt( oTarget, HOUR_DOOR_LOCKED );
      int nHourUnlocked = GetLocalInt( oTarget, HOUR_DOOR_UNLOCKED );
      
      // Check if a time range has been assigned
      if ( ( nHourLocked > 0 ) && ( nHourUnlocked > 0 ) ) {
              SetLocalObject( oDLKController,
          DOOR_PREFIX + IntToString( nNth ),
          oTarget );
        nNth++;
      }
    }
    oTarget = GetNextObjectInArea( OBJECT_SELF );
  }
  nNth--;
  SetLocalInt( oDLKController, DOOR_NUM, nNth );
  
  return oDLKController;
}

//  Set the lock state of the doors in the area.
void CheckDoorLocks( object oArea )
{
  // Get the hour (range = [1, 24])
  int nHour = GetTimeHour() + 1;
  
  // Exit if the hour is unchanged
  int nLastHour = GetLocalInt( oArea, LAST_HOUR_DOOR_CHECK );
  if ( nLastHour == nHour )
    return;
  SetLocalInt( oArea, LAST_HOUR_DOOR_CHECK, nHour );
  
  // Look for a door lock controller
  string sAreaTag = GetTag( oArea );
  string sDLKControllerTag = DLCKC_PREFIX + "_" + sAreaTag;
  object oDLKController = GetWaypointByTag( sDLKControllerTag );
  
  // if controlled doesn't exist then create it
  if ( !GetIsObjectValid( oDLKController ) )
    oDLKController = CreateDLKController( oArea, sDLKControllerTag );
  
  // Cycle through the doors and set lock state appropriately
  int i;
  int nDoors = GetLocalInt( oDLKController, DOOR_NUM );
  for ( i = 1; i <= nDoors; i++ ) {
    // Set the door lock state
    object oDoor = GetLocalObject( oDLKController,
        DOOR_PREFIX + IntToString( i ) );
    SetDoorTimeLock( oDoor, nHour );
  }
}

Modifié par rjshae, 17 août 2010 - 03:04 .