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

📄 misc.cpp

📁 this keik game source
💻 CPP
📖 第 1 页 / 共 4 页
字号:
"land_radius"  The distance of the ground the piece\
               should be when on the ground ( default 0 )
"anglespeed"   Speed at which pieces rotate ( default 100 ) \
               if RANDOMANGLES ( default is 600 )
"key"          The item needed to activate this. (default nothing)

IF RANDOMANGLES is set, object randomly spins while in the air.
IF LANDSHATTER is set, object shatters when it hits the ground.
IF TWOSTAGE is set, object can be shattered once it lands on the ground.
IF ACCUMALATIVE is set, damage is accumlative not threshold
IF INVISIBLE is set, these are invisible and not solid until triggered
If NOT_PLAYERS is set, the trigger does not respond to players
If MONSTERS is set, the trigger will respond to monsters
If PROJECTILES is set, the trigger will respond to projectiles (rockets, grenades, etc.)

/*****************************************************************************/
#define RANDOMANGLES ( 1 << 0 )
#define LANDSHATTER  ( 1 << 1 )
#define INVISIBLE    ( 1 << 5 )
#define ACCUMULATIVE ( 1 << 6 )
#define TWOSTAGE     ( 1 << 7 )

CLASS_DECLARATION( Trigger, ExplodingWall, "func_explodingwall" );

Event EV_ExplodingWall_StopRotating( "stoprotating" );
Event EV_ExplodingWall_OnGround( "checkonground" );

ResponseDef ExplodingWall::Responses[] =
	{
		{ &EV_Trigger_Effect,	( Response )Explode },
		{ &EV_Damage,				( Response )DamageEvent },
		{ &EV_Touch,				( Response )TouchFunc },
		{ &EV_ExplodingWall_StopRotating, ( Response )StopRotating },
		{ &EV_ExplodingWall_OnGround, ( Response )CheckOnGround },
		{ NULL, NULL }
	};

void ExplodingWall::Explode
	(
	Event *ev
	)

	{
	Entity		*other;
	Vector		pos;
   Vector      mins, maxs;
	int			i;

   if ( spawnflags & INVISIBLE )
      {
	   showModel();
	   setSolidType( SOLID_BSP );
   	takedamage = DAMAGE_YES;
      }

	if ( takedamage == DAMAGE_NO )
		{
		return;
		}

	other = ev->GetEntity( 1 );

	health = 0;
	takedamage = DAMAGE_NO;

	// Create explosions
	for( i = 0; i < explosions; i++ )
		{
		pos[ 0 ] = absmin[ 0 ] + G_Random( size[ 0 ] );
		pos[ 1 ] = absmin[ 1 ] + G_Random( size[ 1 ] );
		pos[ 2 ] = absmin[ 2 ] + G_Random( size[ 2 ] );

		CreateExplosion( pos, dmg, 1.0f, true, this, other, this );
		}
	
	// throw itself
   state = 1;
   on_ground = false;
   PostEvent( EV_ExplodingWall_OnGround, 0.1f );
	velocity[ 0 ] = G_CRandom( 70 );
	velocity[ 1 ] = G_CRandom( 70 );
	velocity[ 2 ] = 140 + G_Random( 70 );
	setMoveType( MOVETYPE_BOUNCE );
	setSolidType( SOLID_BBOX );
   if ( spawnflags & RANDOMANGLES )
      {
	   avelocity[ 0 ] = G_Random( angle_speed );
	   avelocity[ 1 ] = G_Random( angle_speed );
	   avelocity[ 2 ] = G_Random( angle_speed );
      }
   else
      {
      Vector delta;
      float most;
      float time;
      int   t;

      delta = land_angles - worldangles;
      if ( delta[ 0 ] > 180 )
         delta[ 0 ] -= 360;
      if ( delta[ 0 ] < -180 )
         delta[ 0 ] += 360;
      if ( delta[ 1 ] > 180 )
         delta[ 1 ] -= 360;
      if ( delta[ 1 ] < -180 )
         delta[ 1 ] += 360;
      if ( delta[ 2 ] > 180 )
         delta[ 2 ] -= 360;
      if ( delta[ 2 ] < -180 )
         delta[ 2 ] += 360;
      most = MaxValue( delta );
      if ( !angle_speed )
         angle_speed = 1;
      t = 10 * most / angle_speed;
      time = (float)t / 10;
      delta = delta * (1.0/time);
      avelocity = delta;
      PostEvent( EV_ExplodingWall_StopRotating, time );
      state = 2;
      }

	ActivateTargets( ev );

   if ( land_radius > 0 )
      {
      mins[0] = mins[1] = mins[2] = -land_radius;
      maxs[0] = maxs[1] = maxs[2] = land_radius;
	   setSize( mins, maxs );
      }

	attack_finished = 0;
	}

void ExplodingWall::DamageEvent
	(
	Event *ev
	)

	{
	Event			*event;
	Entity		*inflictor;
	Entity		*attacker;
	int			damage;

	if ( takedamage == DAMAGE_NO )
		{
		return;
		}

   if ( on_ground )
      {
      GroundDamage( ev );
      return;
      }

	damage		= ev->GetInteger( 1 );
	inflictor	= ev->GetEntity( 2 );
	attacker		= ev->GetEntity( 3 );

   if ( spawnflags & ACCUMULATIVE )
      {
      health -= damage;
      if ( health > 0 )
         return;
      }
   else
      {
	   if ( damage < health )
		   {
		   return;
		   }
      }

	event = new Event( EV_Activate );
	event->AddEntity( attacker );
	ProcessEvent( event );
	}

void ExplodingWall::GroundDamage
	(
	Event *ev
	)

	{
   Vector      dir;
	Entity		*inflictor;
	Entity		*attacker;
	Vector		pos;
	int			damage;

	if ( takedamage == DAMAGE_NO )
		{
		return;
		}

	damage		= ev->GetInteger( 1 );
	inflictor	= ev->GetEntity( 2 );
	attacker		= ev->GetEntity( 3 );

   if ( spawnflags & ACCUMULATIVE )
      {
      health -= damage;
      if ( health > 0 )
         return;
      }
   else
      {
	   if ( damage < health )
		   {
		   return;
		   }
      }

   if ( explosions )
      {
		pos[ 0 ] = absmin[ 0 ] + G_Random( size[ 0 ] );
		pos[ 1 ] = absmin[ 1 ] + G_Random( size[ 1 ] );
		pos[ 2 ] = absmin[ 2 ] + G_Random( size[ 2 ] );

		CreateExplosion( pos, damage, 1.0f, true, this, attacker, this );
      }
   takedamage = DAMAGE_NO;
   hideModel();
   dir = worldorigin - attacker->worldorigin;
   TesselateModel
      (
      this,
      tess_min_size,
      tess_max_size,
      dir,
      damage,
      tess_percentage,
      tess_thickness,
      vec3_origin
      );
	ProcessEvent( EV_BreakingSound );
   PostEvent( EV_Remove, 0 );
	}

void ExplodingWall::SetupSecondStage
	(
   void
	)

	{
   health = max_health;
	takedamage = DAMAGE_YES;
	}

void ExplodingWall::StopRotating
	(
	Event *ev
	)

	{
   avelocity = vec_zero;
   setAngles( land_angles );
   if ( spawnflags & TWOSTAGE )
      SetupSecondStage();
	}

void ExplodingWall::CheckOnGround
	(
	Event *ev
	)

	{
   if ( ( velocity == vec_zero ) && groundentity )
      {
      Vector delta;
      float most;
      float time;
      int   t;

      delta = land_angles - worldangles;
      if ( delta.length() > 1 )
         {
         if ( delta[ 0 ] > 180 )
            delta[ 0 ] -= 360;
         if ( delta[ 0 ] < -180 )
            delta[ 0 ] += 360;
         if ( delta[ 1 ] > 180 )
            delta[ 1 ] -= 360;
         if ( delta[ 1 ] < -180 )
            delta[ 1 ] += 360;
         if ( delta[ 2 ] > 180 )
            delta[ 2 ] -= 360;
         if ( delta[ 2 ] < -180 )
            delta[ 2 ] += 360;
         most = MaxValue( delta );
         if ( angle_speed > 3 )
            t = 10.0f * most / ( angle_speed / 3 );
         else
            t = 10.0f * most;
         time = (float)t / 10;
         delta = delta * (1.0/time);
         avelocity = delta;
         PostEvent( EV_ExplodingWall_StopRotating, time );
         }
      state = 2;
	   setSize( orig_mins, orig_maxs );
      on_ground = true;
      }
   else
      PostEvent( ev, 0.1f );
	}

void ExplodingWall::TouchFunc
	(
	Event *ev
	)

	{
	Entity *other;

	if ( ( velocity == vec_zero ) || ( level.time < attack_finished ) )
		{
		return;
		}

   other = ev->GetEntity( 1 );

   if ( ( spawnflags & LANDSHATTER ) && ( other == world ) )
      {
      Vector pos;

   	takedamage = DAMAGE_NO;

      if ( explosions )
         {
		   pos[ 0 ] = absmin[ 0 ] + G_Random( size[ 0 ] );
		   pos[ 1 ] = absmin[ 1 ] + G_Random( size[ 1 ] );
		   pos[ 2 ] = absmin[ 2 ] + G_Random( size[ 2 ] );

		   CreateExplosion( pos, dmg, 1.0f, true, this, other, this );
         }
      hideModel();
      TesselateModel
         (
         this,
         tess_min_size,
         tess_max_size,
         vec_zero,
         100,
         tess_percentage,
         tess_thickness,
         vec3_origin
         );
		ProcessEvent( EV_BreakingSound );
      PostEvent( EV_Remove, 0 );
      return;
      }

	if ( other->takedamage )
		{
		other->Damage( this, activator, dmg, worldorigin, vec_zero, vec_zero, 20, 0, MOD_EXPLODEWALL, -1, -1, 1.0f );
		RandomGlobalSound( "debris_generic", 1, CHAN_WEAPON, ATTN_NORM );
		attack_finished = level.time + 0.1;
		}
	}

ExplodingWall::ExplodingWall()
	{
   if ( spawnflags & INVISIBLE )
      {
	   if ( Targeted() )
   	  	takedamage = DAMAGE_YES;
      else
         takedamage = DAMAGE_NO;
      hideModel();
	   setSolidType( SOLID_NOT );
      }
   else
      {
	   showModel();
	   setSolidType( SOLID_BSP );
     	takedamage = DAMAGE_YES;
      }
	setMoveType( MOVETYPE_PUSH );
	setOrigin( origin );

	health = G_GetFloatArg( "health", 60 );
	max_health = health;
   on_ground = false;

   state = 0;
   if ( spawnflags & RANDOMANGLES )
   	angle_speed = G_GetFloatArg( "anglespeed", 600 );
   else
   	angle_speed = G_GetFloatArg( "anglespeed", 100 );

	land_radius = G_GetFloatArg( "land_radius", 0 );
	land_angles = G_GetVectorArg( "land_angles" );
	dmg = G_GetIntArg( "dmg", 10 );
	explosions = G_GetIntArg( "explosions", 1 );

   orig_mins = mins;
   orig_maxs = maxs;

	respondto = spawnflags ^ TRIGGER_PLAYERS;
	}

/*****************************************************************************/
/*SINED detail (0.5 0 1.0) ?

Used to fake details before the Quake 2 merge.

/*****************************************************************************/

CLASS_DECLARATION( Entity, Detail, "detail" );

ResponseDef Detail::Responses[] =
	{
		{ NULL, NULL }
	};

Detail::Detail()
	{
	// Be an asshole to the level designers so that they make the change asap.
	gi.dprintf( "Detail brushes are no longer needed.  Use Surface attributes.\n" );

	if ( !G_GetSpawnArg( "model" ) )
		{
		gi.dprintf( "Detail brush with NULL model removed!!!\n" );
		ProcessEvent( EV_Remove );
		}
	else
		{
		ProcessEvent( EV_Remove );
		}
	}

/*****************************************************************************/
/*SINED misc_oxygen (1 0 0) ? VISIBLE

Touching this entity will reset the drowning time - only
responds to players.

"key" The item needed to activate this. (default nothing)
/*****************************************************************************/

CLASS_DECLARATION( Trigger, Oxygenator, "misc_oxygen" );

ResponseDef Oxygenator::Responses[] =
	{
	   { &EV_Trigger_Effect,	( Response )Oxygenator::Oxygenate },
		{ NULL, NULL }
	};

Oxygenator::Oxygenator()
	{
	if ( spawnflags & 1 )
		{
		showModel();
		}

   time = 20;
	respondto = TRIGGER_PLAYERS;
	}

EXPORT_FROM_DLL void Oxygenator::Oxygenate
	(
	Event *ev
	)

   {
   Entity *other;
   Player *player;

   other = ev->GetEntity( 1 );

   if ( !other )
      return;

   player = ( Player * )( Sentient * )other;
   player->GiveOxygen( time );
   }

/*****************************************************************************/
/*SINED misc_teleporter (1 0 0) ? VISIBLE x NOT_PLAYERS NOT_MONSTERS NOT_PROJECTILES

Touching this entity will teleport players to the targeted object.

"key" The item needed to activate this. (default nothing)

If NOT_PLAYERS is set, the teleporter does not teleport players
If NOT_MONSTERS is set, the teleporter does not teleport monsters
If NOT_PROJECTILES is set, the teleporter does not teleport projectiles (rockets, grenades, etc.)

/*****************************************************************************/

CLASS_DECLARATION( Trigger, Teleporter, "misc_teleporter" );

ResponseDef Teleporter::Responses[] =
	{
	   { &EV_Trigger_Effect,	( Response )Teleporter::Teleport },
		{ NULL, NULL }
	};

EXPORT_FROM_DLL void Teleporter::Teleport
	(
	Event *ev
	)

	{
	gclient_t	*client;
	Entity		*dest;
	int			num;
	int			i;
	Entity		*other;
	Vector		mid;

⌨️ 快捷键说明

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