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

📄 thrall.cpp

📁 this keik game source
💻 CPP
📖 第 1 页 / 共 2 页
字号:
   owner = G_GetEntity( this->owner );

   if ( !owner )
      {
      owner = world;
      }

   if ( !other || ( ( other == owner ) && ( owner != world ) ) || ( other->isSubclassOf( DrunkMissile ) ) )
		{
		return;
		}

   flags &= ~FL_PRETHINK;
   stopsound( CHAN_VOICE );
	setSolidType( SOLID_NOT );
	hideModel();

	if ( HitSky() )
		{
      PostEvent( EV_Remove, 0 );
      return;
		}

	damg = 40 + ( int )G_Random( 20 );

   other->Damage( this, owner, damg, worldorigin, velocity, level.impact_trace.plane.normal, 200, 0, MOD_ROCKET, -1, -1, 1.0f );

   SpawnBlastDamage( &level.impact_trace, damg, owner );

   v = velocity;
	v.normalize();
	
	// don't do radius damage to the other, because all the damage
	// was done in the impact
	v = worldorigin - v * 36;
	CreateExplosion( v, damg, 0.7f, true, this, owner, other );
	PostEvent( EV_Remove, 0.1 );
	}

EXPORT_FROM_DLL float DrunkMissile::ResolveMinimumDistance
	(
	Entity *potential_target,
	float currmin
	)

   {
   float		currdist;
	float		dot;
	Vector	angle;
	Vector	delta;
	Vector	norm;
	float		sine = 0.4f;

	delta = potential_target->centroid - worldorigin;

	norm = delta;
	norm.normalize();

	// Test if the target is in front of the missile
	dot = norm * orientation[ 0 ];
	if ( dot < 0 )
		{
		return currmin;
		}

	// Test if we're within the rocket's viewcone (45 degree cone)
	dot = norm * orientation[ 1 ];
	if ( fabs( dot ) > sine )
		{
		return currmin;
		}

	dot = norm * orientation[ 2 ];
	if ( fabs( dot ) > sine )
		{
		return currmin;
		}

	currdist = delta.length();
	if ( currdist < currmin )
		{
		currmin = currdist;
		target = potential_target;
		}

	return currmin;
	}

EXPORT_FROM_DLL float DrunkMissile::AdjustAngle
	(
	float maxadjust,
	float currangle,
	float targetangle
	)

   {
   float dangle;
	float magangle;

	dangle = currangle - targetangle;

	if ( dangle )
		{
		magangle = ( float )fabs( dangle );
		if ( magangle < maxadjust )
			{
			currangle = targetangle;
			}
		else 
			{
			if ( magangle > 180.0f  )
				{
				maxadjust = -maxadjust;
				}
			if ( dangle > 0 )
				{
				maxadjust = -maxadjust;
				}
			currangle += maxadjust;
			}
		}

	while( currangle >= 360.0f )
		{
		currangle -= 360.0f;
		}

	while( currangle < 0.0f )
		{
		currangle += 360.0f;
		}

	return currangle;
	}

EXPORT_FROM_DLL void DrunkMissile::HeatSeek
	(
	Event *ev
	)

	{
	float		mindist;
	Entity	*ent;
	trace_t  trace;
	Vector	delta;
	Vector	v;
   int      n;
   int      i;

   if ( ( !target ) || ( target == world ) )
		{
		mindist = 8192.0f;

	   n = SentientList.NumObjects();
	   for( i = 1; i <= n; i++ )
		   {
		   ent = SentientList.ObjectAt( i );
			if ( ent->entnum == owner )
				{
				continue;
				}

			if ( ( ( ent->takedamage != DAMAGE_AIM ) || ( ent->health <= 0 ) ) && !( edict->svflags & SVF_MONSTER ) )
				{
				continue;
				}

			trace = G_Trace( worldorigin, vec_zero, vec_zero, ent->centroid, this, MASK_SHOT, "DrunkMissile::HeatSeek" );
			if ( ( trace.fraction != 1.0 ) && ( trace.ent != ent->edict ) )
				{
				continue;
				}
	
			mindist = ResolveMinimumDistance( ent, mindist );
			}
		}
	else 
		{
      float predict;
      float dist;
      float time;
      float angspeed;

      delta = target->centroid - worldorigin;
      dist = delta.length();
      time = dist * ( 1 / DRUNKMISSILE_SPEED );
      predict = ( time * ( 0.5 + ( skill->value + 1 ) * 0.125 ) );
		delta += target->velocity * predict;
		delta.z = -delta.z;
		v = delta.toAngles();

      angspeed = 5.0f + skill->value;
		angles.x = AdjustAngle( angspeed, angles.x, v.x );
		angles.y = AdjustAngle( angspeed, angles.y, v.y );
		angles.z = AdjustAngle( angspeed, angles.z, v.z );
		}

   if ( !target )
	   {
      PostEvent( EV_DrunkMissile_HeatSeek, 0.2 );
	   }
   else
      {
      PostEvent( EV_DrunkMissile_HeatSeek, 0.1 );
      }
	}

EXPORT_FROM_DLL void DrunkMissile::Prethink
	(
	void
	)

	{
	trace_t trace;
	Vector end;

	angles += Vector( G_CRandom( 3 ), G_CRandom( 5 ), 0 );

	// Check if we're about to hit the ground at a shallow angle
	if ( ( velocity.z < 0 ) && ( angles.x < 15.0f ) )
		{
		end = worldorigin + velocity * 0.1f;
		trace = G_Trace( worldorigin, vec_zero, vec_zero, end, this, MASK_SHOT, "DrunkMissile::Prethink" );
		if ( trace.fraction != 1 )
			{
			if ( trace.plane.normal[ 2 ] > 0.6f )
				{
				angles.x = -3;
				}
			}
		}

   setAngles( angles );
   velocity = Vector( orientation[ 0 ] ) * DRUNKMISSILE_SPEED;
	}

EXPORT_FROM_DLL void DrunkMissile::Setup
	(
	Entity *owner,
	Vector pos,
	Vector dir
	)

	{
   Event *ev;

	this->owner = owner->entnum;
	edict->owner = owner->edict;

   flags |= FL_PRETHINK;

	setMoveType( MOVETYPE_FLYMISSILE );
	setSolidType( SOLID_BBOX );
	edict->clipmask = MASK_PROJECTILE;

	// set missile duration
   ev = new Event( EV_Touch );
   ev->AddEntity( world );
   PostEvent( ev, 10 );

   PostEvent( EV_DrunkMissile_HeatSeek, 0.1 + G_Random( 0.2f ) );

	// set missile direction
	angles = dir.toAngles();
	angles[ PITCH ] = - angles[ PITCH ];
	setAngles( angles );
	velocity = Vector( orientation[ 0 ] ) * 800.0f;

	target = NULL;

	setModel( "trocket.def" );
	setSize( "-1 -1 -1", "1 1 1" );
	takedamage = DAMAGE_YES;
	health = 10;
	setOrigin( pos );
   worldorigin.copyTo(edict->s.old_origin);

   edict->s.renderfx |= RF_DLIGHT;
   edict->s.effects  |= EF_ROCKET;
   edict->s.effects  |= EF_EVERYFRAME;
   edict->s.angles[ROLL] = rand() % 360;
	avelocity = "0 0 90";
	gravity = 0;
   edict->s.color_r      = 0.8;
   edict->s.color_g      = 0.4;
   edict->s.color_b      = 0;
   edict->s.radius       = 200;

	// setup ambient thrust
	ev = new Event( EV_RandomEntitySound );
	//ev->AddString( "thrust" );
   ev->AddString( "fire" );
   ProcessEvent( ev );
	}

CLASS_DECLARATION( Projectile, ThrallPulse, NULL );

ResponseDef ThrallPulse::Responses[] =
	{
      { &EV_Touch,                   ( Response )ThrallPulse::Explode },
		{ NULL, NULL }
	};

EXPORT_FROM_DLL void ThrallPulse::Explode
	(
   Event *ev
	)

	{
	int damg;
	Vector v;
	Entity *other;
   Entity *owner;
   ThrallPulseDebris *debris;
   int i;

   other = ev->GetEntity( 1 );

   owner = G_GetEntity( this->owner );

   if ( !owner )
      owner = world;

   if ( !other || ( other == owner ) || ( other->isSubclassOf( ThrallPulse ) ) )
		{
		return;
		}

   flags &= ~FL_PRETHINK;
   stopsound( CHAN_VOICE );
	setSolidType( SOLID_NOT );
	hideModel();

	if ( HitSky() )
		{
      PostEvent( EV_Remove, 0 );
      return;
		}

	damg = 160 + ( int )G_Random( 50 );

   other->Damage( this, owner, damg, worldorigin, velocity, level.impact_trace.plane.normal, 320, 0, MOD_ROCKET, -1, -1, 1.0f );

   SpawnBlastDamage( &level.impact_trace, damg, owner );
   
   v = velocity;
	v.normalize();
	
	// don't do radius damage to the other, because all the damage
	// was done in the impact
	v = worldorigin - v * 36;
	CreateExplosion( v, damg, 0.7f, true, this, owner, other );
	PostEvent( EV_Remove, 0.1 );
   FlashPlayers( v, 1, 1, 1, 0.5, 768 );

   for( i = 1; i < 4; i++ )
      {
      debris = new ThrallPulseDebris;
      debris->Setup( owner, v, i );
      }
	}

EXPORT_FROM_DLL void ThrallPulse::Setup
	(
	Entity *owner,
	Vector pos,
	Vector dir
	)

	{
   Event *ev;

	this->owner = owner->entnum;
	edict->owner = owner->edict;

	setMoveType( MOVETYPE_FLYMISSILE );
	setSolidType( SOLID_BBOX );
	edict->clipmask = MASK_PROJECTILE;

	// set missile duration
   ev = new Event( EV_Touch );
   ev->AddEntity( world );
   PostEvent( ev, 10 );

	// set missile direction
	angles = dir.toAngles();
	angles[ PITCH ] = - angles[ PITCH ];
	setAngles( angles );
	velocity = Vector( orientation[ 0 ] ) * 1400.0f;

	setModel( "sprites/thrallpulse.spr" );
	setSize( "-8 -8 -8", "8 8 8" );
	takedamage = DAMAGE_NO;
	setOrigin( pos );
   worldorigin.copyTo(edict->s.old_origin);
   showModel();

   edict->s.renderfx |= RF_DLIGHT;
   edict->s.angles[ROLL] = rand() % 360;
	avelocity = "0 0 90";
	gravity = 0;
   edict->s.color_r      = 0.8;
   edict->s.color_g      = 0;
   edict->s.color_b      = 0;
   edict->s.radius       = 200;
	}

CLASS_DECLARATION( Projectile, ThrallPulseDebris, NULL );

ResponseDef ThrallPulseDebris::Responses[] =
	{
      { &EV_Touch,            ( Response )ThrallPulseDebris::Touch },
		{ NULL, NULL }
	};

EXPORT_FROM_DLL void ThrallPulseDebris::Touch
	(
   Event *ev
	)

	{
	Entity *other;
   Entity *owner;

   if ( level.time < nexttouch )
      {
      return;
      }

   nexttouch = level.time + 1;

   other = ev->GetEntity( 1 );
   owner = G_GetEntity( this->owner );
   if ( !owner )
      {
      owner = world;
      }

   if ( !other )
		{
		return;
		}

   other->Damage( this, owner, 10 * edict->s.scale, worldorigin, velocity, 
      level.impact_trace.plane.normal, velocity.length(), 0, MOD_DEBRIS, -1, -1, 1.0f );
	}

EXPORT_FROM_DLL void ThrallPulseDebris::Prethink
	(
   void
	)

	{
   if ( ( level.time - spawntime ) > 4 )
      {
      edict->s.scale *= 0.9;
      setSize( Vector( -4, -4, -4 ) * edict->s.scale, Vector( 4, 4, 4 ) * edict->s.scale );
      }
   }

EXPORT_FROM_DLL void ThrallPulseDebris::Setup
	(
   Entity *owner,
	Vector pos,
	float size
	)

	{
	this->owner = owner->entnum;
	edict->owner = owner->edict;

   nexttouch = 0;
   spawntime = level.time;
   flags |= FL_PRETHINK;
   setModel( "thrallfire.def" );
   setMoveType( MOVETYPE_BOUNCE );
	setSolidType( SOLID_TRIGGER );
   edict->s.effects |= EF_ROCKET;
   showModel();
   setOrigin( pos );
   worldorigin.copyTo( edict->s.old_origin );
   velocity = Vector( G_CRandom( 200 ), G_CRandom( 200 ), G_Random( 100 ) + 100 );
   PostEvent( EV_Remove, 4 + 2 * size );
   edict->s.scale *= size;
   setSize( Vector( -4, -4, -4 ) * edict->s.scale, Vector( 4, 4, 4 ) * edict->s.scale );
	}

⌨️ 快捷键说明

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