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

📄 doors.cpp

📁 this keik game source
💻 CPP
📖 第 1 页 / 共 3 页
字号:
		{
		if ( max_health )
			{
			takedamage	= DAMAGE_YES;
			health		= max_health;
			}

		// trigger all paired doors
		door = ( Door * )G_GetEntity( nextdoor );
		assert( door->isSubclassOf( Door ) );
		while( door && ( door != this ) )
			{
			door->ProcessEvent( EV_Door_Close );
			door = ( Door * )G_GetEntity( door->nextdoor );
			assert( door->isSubclassOf( Door ) );
			}
		}
	}

void Door::Open
	(
	Event *ev
	)

	{
	Door *door;
	Event *e;
	Entity *other;

	if ( ev->NumArgs() < 1 )
		{
		ev->Error( "No entity specified to open door.  Door may open the wrong way." );
		other = world;
		}
	else
		{
		other = ev->GetEntity( 1 );
		}

	if ( state == STATE_OPENING )
		{
		// already going up
		return;	
		}

	if ( state == STATE_OPEN )
		{
		// reset top wait time
		if ( wait > 0 )
			{
         CancelEventsOfType( EV_Door_Close );
         PostEvent( EV_Door_Close, wait );
			}
		return;
		}

   previous_state = state;
	state = STATE_OPENING;

	e = new Event( EV_Door_DoOpen );
	e->AddEntity( other );
	ProcessEvent( e );

	if ( sound_move.length() > 1 )
		{
		ProcessEvent( EV_DoorSound );
		sound( sound_move, 1, CHAN_VOICE + CHAN_NO_PHS_ADD, ATTN_NORM );
		}
	if ( master == this )
		{
		// trigger all paired doors
		door = ( Door * )G_GetEntity( nextdoor );
		assert( door->isSubclassOf( Door ) );
		while( door && ( door != this ) )
			{
			e = new Event( EV_Door_Open );
			e->AddEntity( other );
			door->ProcessEvent( e );
			door = ( Door * )G_GetEntity( door->nextdoor );
			assert( door->isSubclassOf( Door ) );
			}

		SetAreaPortals( Target(), true );
		}
	}

void Door::DoorUse
	(
	Event *ev
	)
	
	{
	Entity *other;
   qboolean respond;
	Event *e;

	other = ev->GetEntity( 1 );

	respond = ( ( ( respondto & TRIGGER_PLAYERS ) && other->isClient() ) ||
		( ( respondto & TRIGGER_MONSTERS ) && other->isSubclassOf( Actor ) ) );

   if ( !respond )
      return;

	// only allow use when not triggerd by other events
	if ( health || ( spawnflags & ( DOOR_AUTO_OPEN | DOOR_TARGETED ) ) )
		{
      if ( other->isSubclassOf( Sentient ) && ( state == STATE_CLOSED ) )
         {
         if ( health )
            {
            gi.centerprintf ( other->edict, "jcx yv 20 string \"This door is jammed.\"" );
            }
         else if ( spawnflags & DOOR_TARGETED )
            {
            RandomGlobalSound( "door_triggered", 1, CHAN_VOICE + CHAN_NO_PHS_ADD, ATTN_NORM );
            //gi.centerprintf ( other->edict, "jcx yv 20 string \"This door opens elsewhere.\"" );
            }
         }
		return;
		}

   assert( master );
   if ( !master )
      {
      // bulletproofing
      master = this;
      }

	if ( master->state == STATE_CLOSED )
		{
		e = new Event( EV_Door_TryOpen );
		e->AddEntity( other );
		master->ProcessEvent( e );
		}
	else if ( master->state == STATE_OPEN )
		{
		e = new Event( EV_Door_Close );
		e->AddEntity( other );
		master->ProcessEvent( e );
		}
	}

void Door::DoorFire
	(
	Event *ev
	)
	
	{
	Event *e;
	Entity *other;

	other = ev->GetEntity( 1 );

	assert( master == this );
	if ( master != this )
		{
		gi.error( "DoorFire: master != self" );
		}

	// no more messages
	SetMessage( NULL );

	// reset health in case we were damage triggered
	health = max_health;

	// will be reset upon return
	takedamage = DAMAGE_NO;

	if ( ( spawnflags & ( DOOR_TOGGLE | DOOR_START_OPEN ) ) && ( state == STATE_OPENING || state == STATE_OPEN ) )
		{
		spawnflags &= ~DOOR_START_OPEN;
		ProcessEvent( EV_Door_Close );
		}
	else
		{
		e = new Event( EV_Door_Open );
		e->AddEntity( other );
		ProcessEvent( e );
		}
	}

void Door::DoorBlocked
	(
	Event *ev
	)

	{
	Event *e;
	Entity *other;

   assert( master );
	if ( ( master ) && ( master != this ) )
		{
		master->ProcessEvent( ev );
		return;
		}

   if ( lastblocktime > level.time )
      {
      return;
      }

   lastblocktime = level.time + 0.3;

	other = ev->GetEntity( 1 );

	if ( dmg )
		{
		other->Damage( this, this, (int)dmg, worldorigin, vec_zero, vec_zero, 0, 0, MOD_CRUSH, -1, -1, 1.0f );
		}

   // 
   // if we killed him, lets keep on going
   //
   if ( other->health <= 0 )
		{
      return;
		}
	
	if ( state == STATE_OPENING || state == STATE_OPEN )
		{
		spawnflags &= ~DOOR_START_OPEN;
		ProcessEvent( EV_Door_Close );
		}
	else
		{
		e = new Event( EV_Door_Open );
		e->AddEntity( other );
		ProcessEvent( e );
		}
	}

void Door::FieldTouched
	(
	Event *ev
	)

	{
	Entity *other;

	other = ev->GetEntity( 1 );

#ifdef SIN_DEMO
	if ( ( state != STATE_OPEN ) && !( spawnflags & DOOR_AUTO_OPEN ) && 
		( !other || !other->isSubclassOf( Actor ) ) )
#else
	if ( ( state != STATE_OPEN ) && !( spawnflags & DOOR_AUTO_OPEN ) )
#endif
		{
		return;
		}

	TryOpen( ev );
	}

qboolean	Door::CanBeOpenedBy
	(
	Entity *ent
	)

	{
   assert( master );
	if ( ( master ) && ( master != this ) )
		{
		return master->CanBeOpenedBy( ent );
		}

	if ( !locked && !key.length() )
		{
		return true;
		}
		
	if ( ent && ent->isSubclassOf( Sentient ) && ( ( Sentient * )ent )->HasItem( key.c_str() ) )
		{
		return true;
		}

	return false;
	}

void Door::TryOpen
	(
	Event *ev
	)

	{
	Entity *other;
	Event *event;

	//FIXME
	// hack so that doors aren't triggered by guys when game starts.
	// have to fix delay that guys go through before setting up their threads
	if ( level.time < 0.4 )
		{
		return;
		}

	other = ev->GetEntity( 1 );

   assert( master );
	if ( master && ( this != master ) )
		{
		event = new Event( EV_Door_TryOpen );
		event->AddEntity( other );
		master->ProcessEvent( event );
		return;
		}

	if ( !other || ( other->health <= 0 ) )
		{
		return;
		}

   if ( locked )
      {
      if ( sound_locked.length() > 1 )
         {
         other->sound( sound_locked.c_str(), 1, CHAN_VOICE );
         }
      else if ( other->isSubclassOf( Player) )
         {
         other->RandomSound( "snd_locked", 1, CHAN_VOICE );
         //gi.centerprintf ( other->edict, "jcx yv 20 string \"This door is locked.\"" );
         }

		// locked doors don't open for anyone
      return;
      }

   if ( !CanBeOpenedBy( other ) )
		{
      Item        *item;
      ClassDef		*cls;  

		if ( other->isClient() )
			{
			cls = getClass( key.c_str() );
			if ( !cls )
				{
				gi.dprintf( "No item named '%s'\n", key.c_str() );
				return;
				}
			item = ( Item * )cls->newInstance();
			item->CancelEventsOfType( EV_Item_DropToFloor );
			item->CancelEventsOfType( EV_Remove );
			item->ProcessPendingEvents();
			gi.centerprintf ( other->edict, "jcx yv 20 string \"You need this item:\" jcx yv -20 icon %d", item->GetIconIndex() );
			delete item;
			}
      return;
      }

	// once we're opened by an item, we no longer need that item to open the door
	key = "";

	if ( Message().length() )
		{
      gi.centerprintf( other->edict, "jcx jcy string \"%s\"", Message().c_str() );
		sound( sound_message, 1, CHAN_VOICE + CHAN_NO_PHS_ADD, ATTN_NORM );
		}

	event = new Event( EV_Door_Fire );
	event->AddEntity( other );
	ProcessEvent( event );
	}

void Door::SpawnTriggerField
	(
	Vector fmins, 
	Vector fmaxs
	)

	{
	TouchField *trig;
	Vector min;
	Vector max;
	
	min = fmins - "60 60 8";
	max = fmaxs + "60 60 8";

	trig = new TouchField;
	trig->Setup( this, EV_Door_TriggerFieldTouched, min, max, respondto );
	
	trigger = trig->entnum;
	}

EXPORT_FROM_DLL qboolean Door::DoorTouches
	(
	Door *e1
	)

	{
	if ( e1->doormin.x > doormax.x )
		{
		return false;
		}
	if ( e1->doormin.y > doormax.y )
		{
		return false;
		}
	if ( e1->doormin.z > doormax.z )
		{
		return false;
		}
	if ( e1->doormax.x < doormin.x )
		{
		return false;
		}
	if ( e1->doormax.y < doormin.y )
		{
		return false;
		}
	if ( e1->doormax.z < doormin.z )
		{
		return false;
		}

	return true;
	}

void Door::LinkDoors
	(
	Event *ev
	)

	{
	Door	*ent;
	Door	*next;
	Vector			cmins;
	Vector			cmaxs;
	int				t;
	int				i;

	if ( nextdoor )
		{
		// already linked by another door
		return;
		}

	// master doors own themselves
	master = this;

	if ( spawnflags & DOOR_DONT_LINK )
		{
		// don't want to link this door
		nextdoor = entnum;
		return;	
		}

	cmins = absmin;
	cmaxs = absmax;
	
	ent = this;
	for( t = entnum; t != 0; t = G_FindClass( t, getClassID() ) )
		{
		next = ( Door * )G_GetEntity( t );
		if ( !ent->DoorTouches( next ) )
			{
			continue;
			}

		if ( next->nextdoor )
			{
			error( "cross connected doors.  Targetname = %s entity %d", TargetName(), entnum );
			}
		
		ent->nextdoor = next->entnum;
		ent = next;

		for( i = 0; i < 3; i++ )
			{
			if ( ent->absmin[ i ] < cmins[ i ] )
				{
				cmins[ i ] = ent->absmin[ i ];
				}
			if ( ent->absmax[ i ] > cmaxs[ i ] )
				{

⌨️ 快捷键说明

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