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

📄 entity.cpp

📁 this keik game source
💻 CPP
📖 第 1 页 / 共 5 页
字号:
      return false;
		}
   if ( !gi.GetBoneTransform( edict->s.modelindex, groupindex, tri_num, orient, edict->s.anim, edict->s.frame, 
			edict->s.scale, trans, p1 ) )
		{
		return false;
		}

	if ( forward || right || up )
		{
		R_ConcatRotations( trans, orientation, trans );
		}

	if ( pos )
		{
		MatrixTransformVector( p1, orientation, p2 );
		*pos = Vector( p2 );
		}
	if ( forward )
		{
		*forward = Vector( trans[ 0 ] );
		}
	if ( right )
		{
		*right = Vector( trans[ 1 ] );
		}
	if ( up )
		{
		*up = Vector( trans[ 2 ] );
		}

	return true;
   }

EXPORT_FROM_DLL void Entity::setAngles
	(
	Vector ang
	)

	{
   Entity * ent;
	float	mat[3][3];
   int num,i;

	angles[ 0 ] = angmod( ang[ 0 ] );
	angles[ 1 ] = angmod( ang[ 1 ] );
	angles[ 2 ] = angmod( ang[ 2 ] );

	if ( bindmaster )
		{
		AnglesToMat( angles.vec3(), mat );
		R_ConcatRotations( mat, bindmaster->orientation, orientation );
		MatrixToEulerAngles( orientation, worldangles.vec3() );
		worldangles.copyTo( edict->s.viewangles );
		}
   else if (edict->s.parent)
      {
      float trans[3][3];
      float local_trans[3][3];
      vec3_t p1;

      ent = ( Entity * )G_GetEntity( edict->s.parent );
		ang.copyTo( edict->s.viewangles );

      if ( gi.GetBoneTransform( ent->edict->s.modelindex, edict->s.bone.group_num, edict->s.bone.tri_num, edict->s.bone.orientation,
         ent->edict->s.anim, ent->edict->s.frame, ent->edict->s.scale, trans, p1 ) )
         {
		   AnglesToMat( angles.vec3(), mat );
		   R_ConcatRotations( mat, trans, local_trans );
		   R_ConcatRotations( local_trans, ent->orientation, orientation );
		   MatrixToEulerAngles( orientation, worldangles.vec3() );
         }
      }
	else
		{
		worldangles = angles;
		AnglesToMat( worldangles.vec3(), orientation );
		worldangles.copyTo( edict->s.viewangles );
		}

	worldangles.copyTo( edict->s.angles );

	// Fill the edicts matrix
	VectorCopy( orientation[ 0 ], edict->s.mat[ 0 ] );
	VectorCopy( orientation[ 1 ], edict->s.mat[ 1 ] );
	VectorCopy( orientation[ 2 ], edict->s.mat[ 2 ] );

   //
   // go through and set our children
   //
   num = numchildren;
   for (i=0;(i < MAX_MODEL_CHILDREN) && num;i++)
      {
      if (!children[i])
         continue;
      ent = ( Entity * )G_GetEntity( children[i] );
      ent->setAngles( ent->angles );
      num--;
      }
	}

EXPORT_FROM_DLL qboolean Entity::droptofloor
	(
	float maxfall
	)

	{
	trace_t	trace;
	Vector	end;
	
	end = origin;
	end[ 2 ]-= maxfall;
	origin += "0 0 1";

	trace = G_Trace( origin, mins, maxs, end, this, MASK_SOLID, "Entity::droptofloor" );
	if ( trace.fraction == 1 || trace.allsolid )
		{
		groundentity = NULL;
		return false;
		}

	setOrigin( trace.endpos );

	groundentity				= trace.ent;
	groundentity_linkcount	= trace.ent->linkcount;

	return true;
	}

void Entity::Damage
   (
   Entity *inflictor,
   Entity *attacker,
   int damage,
   Vector position,
   Vector direction,
   Vector normal,
   int knockback,
   int dflags,
   int meansofdeath,
   int groupnum,
   int trinum,
   float damage_multiplier
   )

   {
	Event	*ev;

	if ( !attacker )
		{
		attacker = world;
		}
	if ( !inflictor )
		{
		inflictor = world;
		}

	ev = new Event( EV_Damage );
	ev->AddInteger( damage );
	ev->AddEntity ( inflictor );
	ev->AddEntity ( attacker );
   ev->AddVector ( position );
   ev->AddVector ( direction );
   ev->AddVector ( normal );
   ev->AddInteger( knockback );   
   ev->AddInteger( dflags );
   ev->AddInteger( meansofdeath );
   ev->AddInteger( groupnum );
   ev->AddInteger( trinum );
   ev->AddFloat  ( damage_multiplier );
   ProcessEvent  ( ev );
   }

void Entity::DamageEvent
	(
	Event *ev
	)

	{
	Entity	*inflictor;
	Entity	*attacker;
	int		damage;
	Vector	dir;
	Vector	momentum;
	Event		*event;
	float		m;

	if ( ( takedamage == DAMAGE_NO ) || ( movetype == MOVETYPE_NOCLIP ) )
		{
		return;
		}

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

	// figure momentum add
	if ( ( inflictor != world ) &&
		( movetype != MOVETYPE_NONE ) && 
		( movetype != MOVETYPE_BOUNCE ) && 
		( movetype != MOVETYPE_PUSH ) && 
		( movetype != MOVETYPE_STOP ) )
		{
		dir = worldorigin - ( inflictor->worldorigin + ( inflictor->mins + inflictor->maxs ) * 0.5 );
		dir.normalize();

		if ( mass < 50)
			{
			m = 50;
			}
		else
			{
			m = mass;
			}

		momentum = dir * damage * ( 1700.0 / m );
		velocity += momentum;
		}

	// check for godmode or invincibility
	if ( flags & FL_GODMODE )
		{
		return;
		}

   // Forcefields make objects invulnerable
   if ( flags & FL_FORCEFIELD )
      {
      float    alpha;
      float    radius;
      Entity   *forcefield;
      //
      // spawn forcefield
      //
      forcefield = new Entity;

      radius = ( centroid - worldorigin ).length();
      forcefield->setModel( "sphere2.def" );
      forcefield->setOrigin( centroid );
      forcefield->worldorigin.copyTo(forcefield->edict->s.old_origin);
      forcefield->setMoveType( MOVETYPE_NONE );
      forcefield->setSolidType( SOLID_NOT );
      forcefield->edict->s.scale = radius / 16;
      alpha = damage / 100;
      if ( alpha > 1 )
         alpha = 1;
      if ( alpha < 0.15f )
         alpha = 0.15f;
      forcefield->edict->s.alpha = alpha;
		forcefield->edict->s.renderfx |= RF_TRANSLUCENT;
      forcefield->PostEvent( EV_Remove, 0.1f );
      return;
      }

	// team play damage avoidance
	//if ( ( global->teamplay == 1 ) && ( edict->team > 0 ) && ( edict->team == attacker->edict->team ) )
	//	{
	//	return;
	//	}

   if ( !deathmatch->value && isSubclassOf( Player ) )
      {
      damage *= 0.15;
      }

   if ( deadflag )
      {
      // Check for gib.
      if ( inflictor->isSubclassOf( Projectile ) )
         {
         Event *gibEv;

         health -= damage;

         gibEv = new Event( EV_Gib );
         gibEv->AddEntity( this );
         gibEv->AddFloat( health );
         ProcessEvent( gibEv );
         }
      return;
      }

	// do the damage
	health -= damage;
	if ( health <= 0 )
		{
      if ( attacker )
         {
		   event = new Event( EV_GotKill );
		   event->AddEntity( this );
		   event->AddInteger( damage );
		   event->AddEntity( inflictor );
         // location based damage
         event->AddString( ev->GetString( 4 ) );
         event->AddInteger( ev->GetInteger( 9 ) );
         event->AddInteger( 0 );
		   attacker->ProcessEvent( event );
         }

		event = new Event( EV_Killed );
		event->AddEntity( attacker );
		event->AddInteger( damage );
		event->AddEntity( inflictor );
      // location based damage
      event->AddString( ev->GetString( 4 ) );
		ProcessEvent( event );
		return;
		}

   if (flags & FL_TESSELATE)
      {
      TesselateModel
         (
         this,
         tess_min_size,
         tess_max_size,
         dir,
         damage,
         tess_percentage*0.5f,
         tess_thickness,
         ev->GetVector( 5 )
         );
      }

   if (flags & FL_DARKEN)
      {
      edict->s.renderfx |= RF_LIGHTOFFSET;
      if ( max_health )
         {
         edict->s.lightofs = - ( 40.0f * ( (float)(max_health - health) / (float)max_health ) );
         }
      else
         {
         edict->s.lightofs -= damage;
         }
      if ( edict->s.lightofs < -127 )
         edict->s.lightofs = -127;
      if ( edict->s.lightofs > 127 )
         edict->s.lightofs = 127;
      }

	event = new Event( EV_Pain );
	event->AddFloat( damage );
	event->AddEntity( attacker );
   // location based damage
   event->AddString( ev->GetString( 4 ) );
	ProcessEvent( event );
	}

/*
============
CanDamage

Returns true if the inflictor can directly damage the target.  Used for
explosions and melee attacks.
============
*/
qboolean Entity::CanDamage
	(
	Entity *target
	)
	
	{
	trace_t	trace;
	Vector	pos;

	// bmodels need special checking because their origin is 0,0,0
	if ( target->getMoveType() == MOVETYPE_PUSH )
		{
		pos = ( target->absmin + target->absmax ) * 0.5;
      trace = G_Trace( origin, vec_origin, vec_origin, pos, this, MASK_SHOT, "Entity::CanDamage 1" );
		if ( trace.fraction == 1 || trace.ent == target->edict )
			{
			return true;
			}
		return false;
		}

   trace = G_Trace( origin, vec_origin, vec_origin, target->centroid, this, MASK_SHOT, "Entity::CanDamage 2" );
	if ( trace.fraction == 1 || trace.ent == target->edict )
		{
		return true;
		}
	pos = target->centroid + Vector( 15, 15, 0 );
   trace = G_Trace( origin, vec_origin, vec_origin, pos, this, MASK_SHOT, "Entity::CanDamage 3" );
	if ( trace.fraction == 1 || trace.ent == target->edict )
		{
		return true;
		}
	pos = target->centroid + Vector( -15, 15, 0 );
   trace = G_Trace( origin, vec_zero, vec_zero, pos, this, MASK_SHOT, "Entity::CanDamage 4" );
	if ( trace.fraction == 1 || trace.ent == target->edict )
		{
		return true;
		}
	pos = target->centroid + Vector( 15, -15, 0 );
   trace = G_Trace( origin, vec_zero, vec_zero, pos, this, MASK_SHOT, "Entity::CanDamage 5" );
	if ( trace.fraction == 1 || trace.ent == target->edict )
		{
		return true;
		}
  	pos = target->centroid + Vector( -15, -15, 0 );
   trace = G_Trace( origin, vec_zero, vec_zero, pos, this, MASK_SHOT, "Entity::CanDamage 6" );
	if ( trace.fraction == 1 || trace.ent == target->edict )
		{
		return true;
		}

	return false;
	}

EXPORT_FROM_DLL qboolean Entity::IsTouching
	(
	Entity *e1
	)

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

	return true;
	}

void Entity::StopAnimating
	(
	void
	)

   {
	// Cancel all animating events
   last_animation_time = -1;
   animating = false;
   total_delta = vec_zero;
   if ( animDoneEvent )
		{
      CancelEventsOfType( animDoneEvent );
		delete animDoneEvent;
		animDoneEvent = NULL;
		}
   }

void Entity::StartAnimating
	(
	void
	)

   {
	// start animating
	AnimateFrame();
   animating = true;
   }

void Entity::NextAnim
	(
	int animnum
	)

   {
   if ( ( animnum >= 0 ) && ( animnum < gi.NumAnims( edict->s.modelindex ) ) )
		{
      next_anim = animnum;
		}
   else 
		{
		// bad value
      return;
		}
   
	// get the next anim delta
	gi.Anim_Delta( edict->s.modelindex, next_anim, next_anim_delta.vec3() );
   next_anim_delta *= edict->s.scale;

   // get the next anim time
	next_anim_time = gi.Anim_Time( edict->s.modelindex, next_anim );
	NextFrame( 0 );
   }

⌨️ 快捷键说明

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