⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 doors.cpp

📁 this keik game source
💻 CPP
📖 第 1 页 / 共 3 页
字号:
				cmaxs[ i ] = ent->absmax[ i ];
				}
			}

		// set master door
		ent->master = this;

		if ( ent->health )
			{
			health = ent->health;
			}

		if ( ent->Targeted() )
			{
			if ( !Targeted() )
				{
				SetTargetName( ent->TargetName() );
				}
			else if ( strcmp( TargetName(), ent->TargetName() ) )
				{
				// not a critical error, but let them know about it.
				gi.dprintf( "cross connected doors" );

				ent->SetTargetName( TargetName() );
				}
			}

		if ( ent->Message().length() )
			{
			if ( Message().length() && !strcmp( Message().c_str(), ent->Message().c_str() ) )
				{
				// not a critical error, but let them know about it.
				gi.dprintf( "Different messages on linked doors.  Targetname = %s", TargetName() );
				}

			// only master should have a message
			SetMessage( ent->Message().c_str() );
			ent->SetMessage( NULL );
			}
		}

	// make the chain a loop
	ent->nextdoor = entnum;

	// open up any portals we control
	SetAreaPortals( Target(), ( spawnflags & DOOR_START_OPEN ) ? true : false );

	// shootable or targeted doors don't need a trigger
	if ( health || ( spawnflags & DOOR_TARGETED ) )
		{
		// Don't let the player trigger the door
		return;
		}

   // Don't spawn trigger field when set to toggle
   if ( !( spawnflags & DOOR_TOGGLE ) )
      {
	   SpawnTriggerField( cmins, cmaxs );
      }
	}

void Door::SetTime
	(
	Event *ev
	)

	{
	traveltime = ev->GetFloat( 1 );
	if ( traveltime < FRAMETIME )
		{
		traveltime = FRAMETIME;
		}

	speed = 1.0f / traveltime;
	}

void Door::LockDoor
	(
	Event *ev
	)

	{
   locked = true;
	}

void Door::UnlockDoor
	(
	Event *ev
	)

	{
   locked = false;
	}

/*****************************************************************************/
/*SINED func_rotatingdoor (0 .5 .8) ? START_OPEN OPEN_DIRECTION DOOR_DONT_LINK NOT_PLAYERS NOT_MONSTERS TOGGLE AUTO_OPEN TARGETED
if two doors touch, they are assumed to be connected and operate as a unit.

TOGGLE causes the door to wait in both the start and end states for a trigger event.
DOOR_DONT_LINK is for when you have two doors that are touching but you want to operate independently.

START_OPEN causes the door to move to its destination when spawned, and operate in reverse.  It is used to temporarily or permanently close off an area when triggered (not usefull for touch or takedamage doors).
OPEN_DIRECTION indicates which direction to open when START_OPEN is set.
AUTO_OPEN causes the door to open when a player is near instead of waiting for the player to use the door.
TARGETED door is only operational from triggers or script

"message"		is printed when the door is touched if it is a trigger door and it hasn't been fired yet
"openangle"    how wide to open the door
"angle"			determines the opening direction.  point toward the middle of the door (away from the hinge)
"targetname"	if set, no touch field will be spawned and a remote button or trigger field activates the door.
"health"			if set, door must be shot open
"time"			move time (0.3 default)
"wait"			wait before returning (3 default, -1 = never return)
"dmg"				damage to inflict when blocked (0 default)
"key"          The item needed to open this door (default nothing)

"sound_stop"		Specify the sound that plays when the door stops moving (default global door_stop)
"sound_move"		Specify the sound that plays when the door opens or closes (default global door_moving)
"sound_message"	Specify the sound that plays when the door displays a message
"sound_locked"	   Specify the sound that plays when the door is locked
  
/*****************************************************************************/
CLASS_DECLARATION( Door, RotatingDoor, "func_rotatingdoor" );

ResponseDef RotatingDoor::Responses[] =
	{
	   { &EV_Door_DoClose,		            ( Response )RotatingDoor::DoClose },
	   { &EV_Door_DoOpen,		            ( Response )RotatingDoor::DoOpen },
		{ NULL, NULL }
	};

void RotatingDoor::DoOpen
   (
 	Event *ev
   )

	{
	Vector ang;

	if ( previous_state == STATE_CLOSED )
      {
      if ( ev->NumArgs() > 0 )
         {
   	   Entity *other;
	      Vector p;

	      other = ev->GetEntity( 1 );
         p = other->worldorigin - worldorigin;
         p.z = 0;
         diropened = dir * p;
         }
      else
         {
         diropened = 0 - init_door_direction;
         }
      }

	if ( diropened < 0 )
		{
		ang = startangle + Vector( 0, angle, 0 );
		}
	else
		{
		ang = startangle - Vector( 0, angle, 0 );
		}

	MoveTo( worldorigin, ang, fabs( speed*angle ), EV_Door_OpenEnd );
   }

void RotatingDoor::DoClose
   (
 	Event *ev
   )

	{
	MoveTo( worldorigin, startangle, fabs( speed*angle ), EV_Door_CloseEnd );
   }

RotatingDoor::RotatingDoor()
	{
	startangle = angles;

	angle = G_GetFloatArg( "openangle", 90 );

   init_door_direction = (spawnflags & DOOR_OPEN_DIRECTION);
	}

/*
/*****************************************************************************/
/*SINED func_door (0 .5 .8) ? START_OPEN x DOOR_DONT_LINK NOT_PLAYERS NOT_MONSTERS TOGGLE AUTO_OPEN TARGETED
if two doors touch, they are assumed to be connected and operate as a unit.

TOGGLE causes the door to wait in both the start and end states for a trigger event.
DOOR_DONT_LINK is for when you have two doors that are touching but you want to operate independently.

START_OPEN causes the door to move to its destination when spawned, and operate in reverse.  It is used to temporarily or permanently close off an area when triggered (not usefull for touch or takedamage doors).
OPEN_DIRECTION indicates which direction to open when START_OPEN is set.
AUTO_OPEN causes the door to open when a player is near instead of waiting for the player to use the door.
TARGETED door is only operational from triggers or script

"message"		is printed when the door is touched if it is a trigger door and it hasn't been fired yet
"angle"			determines the opening direction.  point toward the middle of the door (away from the hinge)
"targetname"	if set, no touch field will be spawned and a remote button or trigger field activates the door.
"health"			if set, door must be shot open
"speed"			move speed (100 default)
"time"			move time (1/speed default, overides speed)
"wait"			wait before returning (3 default, -1 = never return)
"lip"				lip remaining at end of move (8 default)
"dmg"				damage to inflict when blocked (0 default)
"key"          The item needed to open this door (default nothing)

"sound_stop"		Specify the sound that plays when the door stops moving (default global door_stop)
"sound_move"		Specify the sound that plays when the door opens or closes (default global door_moving)
"sound_message"	Specify the sound that plays when the door displays a message
"sound_locked"	   Specify the sound that plays when the door is locked
  
/*****************************************************************************/
CLASS_DECLARATION( Door, SlidingDoor, "func_door" );

ResponseDef SlidingDoor::Responses[] =
	{
	   { &EV_Door_DoClose,		            ( Response )SlidingDoor::DoClose },
	   { &EV_Door_DoOpen,		            ( Response )SlidingDoor::DoOpen },
		{ NULL, NULL }
	};

void SlidingDoor::DoOpen
   (
 	Event *ev
   )

	{
	MoveTo( pos2, angles, speed*totalmove, EV_Door_OpenEnd );
   }

void SlidingDoor::DoClose
   (
 	Event *ev
   )

	{
	MoveTo( pos1, angles, speed*totalmove, EV_Door_CloseEnd );
   }

SlidingDoor::SlidingDoor()
	{
   Vector movedir;
   float sp;

	lip = G_GetFloatArg( "lip", 8 );

	movedir = G_GetMovedir();
	totalmove = fabs( movedir * size ) - lip;
	pos1 = worldorigin;
	pos2 = pos1 + movedir * totalmove;
   setOrigin( pos1 );

	sp = G_GetFloatArg( "speed", 0 );
   if (sp)
      {
      speed = sp / totalmove;
      }
	}

/*
/*****************************************************************************/
/*SINED func_scriptdoor (0 .5 .8) ? START_OPEN x DOOR_DONT_LINK NOT_PLAYERS NOT_MONSTERS TOGGLE AUTO_OPEN TARGETED
if two doors touch, they are assumed to be connected and operate as a unit.

TOGGLE causes the door to wait in both the start and end states for a trigger event.
DOOR_DONT_LINK is for when you have two doors that are touching but you want to operate independently.

START_OPEN causes the door to move to its destination when spawned, and operate in reverse.  It is used to temporarily or permanently close off an area when triggered (not usefull for touch or takedamage doors).
OPEN_DIRECTION indicates which direction to open when START_OPEN is set.
AUTO_OPEN causes the door to open when a player is near instead of waiting for the player to use the door.
TARGETED door is only operational from triggers or script

"message"		is printed when the door is touched if it is a trigger door and it hasn't been fired yet
"angle"			determines the opening direction.  point toward the middle of the door (away from the hinge)
"targetname"	if set, no touch field will be spawned and a remote button or trigger field activates the door.
"health"			if set, door must be shot open
"speed"			move speed (100 default)
"time"			move time (1/speed default, overides speed)
"wait"			wait before returning (3 default, -1 = never return)
"dmg"				damage to inflict when blocked (0 default)
"key"          The item needed to open this door (default nothing)
"initthread"   code to execute to setup the door (optional)
"openthread"   code to execute when opening the door (required)
"closethread"  code to execute when closing the door (required)

"sound_stop"		Specify the sound that plays when the door stops moving (default global door_stop)
"sound_move"		Specify the sound that plays when the door opens or closes (default global door_moving)
"sound_message"	Specify the sound that plays when the door displays a message
"sound_locked"	   Specify the sound that plays when the door is locked
  
/*****************************************************************************/
CLASS_DECLARATION( Door, ScriptDoor, "func_scriptdoor" );

Event EV_ScriptDoor_DoInit( "doinit" );
Event EV_ScriptDoor_SetOpenThread( "openthread" );
Event EV_ScriptDoor_SetCloseThread( "closethread" );

ResponseDef ScriptDoor::Responses[] =
	{
	   { &EV_ScriptDoor_DoInit,		      ( Response )ScriptDoor::DoInit },
	   { &EV_Door_DoClose,		            ( Response )ScriptDoor::DoClose },
	   { &EV_Door_DoOpen,		            ( Response )ScriptDoor::DoOpen },
	   { &EV_ScriptDoor_SetOpenThread,           ( Response )ScriptDoor::SetOpenThread },
	   { &EV_ScriptDoor_SetCloseThread,          ( Response )ScriptDoor::SetCloseThread },
		{ NULL, NULL }
	};

void ScriptDoor::SetOpenThread
   (
 	Event *ev
   )
	{
   openthreadname = ev->GetString( 1 );
   }

void ScriptDoor::SetCloseThread
   (
 	Event *ev
   )
	{
   closethreadname = ev->GetString( 1 );
   }

void ScriptDoor::DoInit
   (
 	Event *ev
   )
	{
   const char * label = NULL;
   GameScript * s;
   const char * tname;

   s = ScriptLib.GetScript( ScriptLib.GetGameScript() );

   if ( !s )
      {
      warning( "DoInit", "Null game script" );
      return;
      }

   if ( initthreadname.length() )
      label = initthreadname.c_str();

	doorthread = Director.CreateThread( s, label, MODEL_SCRIPT );
   if ( !doorthread )
      {
      warning( "DoInit", "Could not allocate thread." );
      return;
      }
	doorthread->Vars()->SetVariable( "self", this );
   tname = TargetName();
   if ( tname && tname[ 0 ] )
      {
      str name;
      name = "$" + str( tname );
	   doorthread->Vars()->SetVariable( "targetname", name.c_str() );
      }
	doorthread->Vars()->SetVariable( "startorigin", startorigin );
	doorthread->Vars()->SetVariable( "startangles", startangle );
	doorthread->Vars()->SetVariable( "movedir", movedir );
	doorthread->Vars()->SetVariable( "doorsize", doorsize );
   if ( initthreadname.length() )
      {
      // start right away
      doorthread->Start( -1 );
      }
   }

void ScriptDoor::DoOpen
   (
 	Event *ev
   )
	{
   if ( !doorthread )
      {
      warning( "DoOpen", "No Thread allocated." );
      return;
      }
   else
      {
      if ( !doorthread->Goto( openthreadname.c_str() ) )
         {
         warning( "DoOpen", "Could not goto %s", openthreadname.c_str() );
         return;
         }
      }

   if ( previous_state == STATE_CLOSED )
      {
      diropened = 0;
      if ( ev->NumArgs() > 0 )
         {
   	   Entity *other;
	      Vector p;

	      other = ev->GetEntity( 1 );
	      p = other->worldorigin - worldorigin;
         p.z = 0;
         diropened = dir * p;
         }
      }
	doorthread->Vars()->SetVariable( "origin", worldorigin );
	doorthread->Vars()->SetVariable( "opendot", diropened );
   doorthread->Start( 0 );
   }

void ScriptDoor::DoClose
   (
 	Event *ev
   )
	{
   if ( !doorthread )
      {
      warning( "DoClose", "No Thread allocated." );
      return;
      }
   else
      {
      if ( !doorthread->Goto( closethreadname.c_str() ) )
         {
         warning( "DoOpen", "Could not goto %s", closethreadname.c_str() );
         }
      }
	doorthread->Vars()->SetVariable( "origin", worldorigin );
   doorthread->Start( 0 );
   }

ScriptDoor::ScriptDoor()
	{
   const char * text;

	startangle = angles;
   //
   // see if we have an initthread
   //
	text = G_GetSpawnArg( "initthread" );
   if ( text )
      initthreadname = text;

   //
   // see if we have an openthread
   //
	text = G_GetSpawnArg( "openthread" );
   if ( text )
      openthreadname = text;
   else
      warning("ScriptDoor","No openthread defined for door at %.2f %.2f %.2f", origin[0], origin[1], origin[2] );

   //
   // see if we have an closethread
   //
	text = G_GetSpawnArg( "closethread" );
   if ( text )
      closethreadname = text;
   else
      warning("ScriptDoor","No closethread defined for door at %.2f %.2f %.2f", origin[0], origin[1], origin[2] );
   //
   // clear out the sounds if necessary
   // scripted doors typically have their own sounds
   //
   text = G_GetSpawnArg( "sound_stop" );
   if ( !text )
      sound_stop = "";
   text = G_GetSpawnArg( "sound_move" );
   if ( !text )
      sound_move = "";

	movedir = G_GetMovedir();
   startorigin = worldorigin;
	doorsize = fabs( movedir * size );
	PostEvent( EV_ScriptDoor_DoInit, 0 );
	}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -