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

📄 sentient.cpp

📁 this keik game source
💻 CPP
📖 第 1 页 / 共 5 页
字号:
               this->client->pers.netname, armor_damage, damage, location ); 
            }
         else
            {
            gi.cprintf ( attacker->edict, PRINT_HIGH, "TARG:%s ARMOR_DAM:%0.2f TOT_DAM:%0.2f LOC:%s\n", 
               getClassname(), armor_damage, damage, location );
            }
         }

      // Send message to victim
      if ( this->isClient() && attacker != this ) 
         {
         gi.cprintf ( this->edict, PRINT_HIGH, "TARG:%s ARMOR_DAM:%0.2f TOT_DAM:%0.2f LOC:%s\n", 
            this->client->pers.netname, armor_damage, damage, location );
         }
      }

   
   // Blood and sparks effects
   if ( 
        ( damage > 0 ) && 
        ( meansofdeath != MOD_DROWN ) && 
        ( meansofdeath != MOD_MUTANT_DRAIN )
      )
      {
      // Blood particles
      if ( flags & FL_BLOOD )
         {
         Particles( position, normal, __min( 150,damage ), 127, PARTICLE_RANDOM );
      
         // Blood splat
         if ( dflags & DAMAGE_BULLET )
            SprayBlood( position, direction, damage );
         }
      // Sparks from metal
      else if ( flags & FL_SPARKS )
         { 
         SpawnSparks (position, normal, __min(damage, 75) );
         }
      }
   else if (  armor_damage > 0 )
      {
      // Sparks off armor
      Particles( position, normal, __min(armor_damage, 75), 122, 0 );
      }

   // Gib if we are dead and get hit by a rocket or shotgun
   if ( deadflag == DEAD_DEAD )
      {
      health -= damage;
      if ( DoGib( meansofdeath, inflictor ) )
         {
         Event *gibEv;

         gibEv = new Event( EV_Gib );
         gibEv->AddInteger( 0 );
         ProcessEvent( gibEv );
         }
      return;
      }
   else if ( deadflag )
      {
      health -= damage; 
      return;
      }

   // Do the kick
	if (!(dflags & DAMAGE_NO_KNOCKBACK))
      {
		if ((knockback) && 
         (movetype != MOVETYPE_NONE) && 
         (movetype != MOVETYPE_BOUNCE) && 
         (movetype != MOVETYPE_PUSH) && 
         (movetype != MOVETYPE_STOP))
         {
	         float	m;

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

            direction.normalize();
   		   if ( isClient() && ( attacker == this ) && deathmatch->value )
		         momentum = direction * ( 1700.0f * ( float )knockback / m ); // the rocket jump hack...
	         else
		         momentum = direction * ( 500.0f * ( float )knockback / m );

            if ( dflags & DAMAGE_BULLET )
               {
               // Clip the z velocity for bullet weapons
               if ( momentum.z > 75)
                  momentum.z = 75;
               }
            velocity += momentum;
         }
      }

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

   // do the damage
	health -= damage;

   // He's dead jim, send out a bunch of events
   if ( health <= 0 )
		{
      if ( ( meansofdeath == MOD_ION ) && !( flags & FL_NOION ) )
         {
         flags |= FL_DIE_TESSELATE;
         RandomGlobalSound( "snd_tesselate" );
         }

		event = new Event( EV_Killed );
		event->AddEntity( attacker );
		event->AddInteger( damage );
		event->AddEntity( inflictor );
      event->AddString( location );
      event->AddInteger( meansofdeath );
		ProcessEvent( event );
		return;
		}

   if ( ( damage > 0 ) && ( meansofdeath == MOD_ION ) && !( flags & FL_NOION ) )
      {
      // Do the ion particlizer effect
      TesselateModel
         (
         this,
         1,
         1000,
         direction,
         damage,
         1.0f,
         0,
         vec3_origin,
         TESSELATE_EXPANDANDSHRINK,
         126
         );
      }
   
   // Tesselate from damage
   if (flags & FL_TESSELATE)
      {
      TesselateModel
         (
         this,
         tess_min_size,
         tess_max_size,
         direction,
         damage,
         1.0f,
         tess_thickness,
         vec3_origin
         );
      }

   // Darken if we are hurt
   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;
      }

   // Drop your weapon if you get hit in the hands
   if ( location == gun_bone_group_name && ( ( damage > 50 ) || ( G_Random( 1 ) > 0.97f ) ) )
      {
      // don't drop weapons when in deathmatch and DF_NO_DROP_WEAPONS is set
      if ( currentWeapon && currentWeapon->IsDroppable() && ( !deathmatch->value || !DM_FLAG( DF_NO_DROP_WEAPONS ) ) )
         {
         DropCurrentWeapon();
         WeaponKnockedFromHands();
         }
      }

   if ( meansofdeath == MOD_MUTANT_DRAIN )
      return;

	// Send pain event
   event = new Event( EV_Pain );
	event->AddFloat( damage );
	event->AddEntity( attacker );
   event->AddString( location );
   event->AddInteger( meansofdeath );
	ProcessEvent( event );
   }

void Sentient::UpdateSilencedWeapons
   (
   void
   )
   
   {  
   // If the current weapon is silencable, then change it.
   if ( currentWeapon && currentWeapon->IsSilenced() )
      {
      currentWeapon->ProcessEvent(EV_Weapon_PutAwayAndRaise);
      }
   }

int Sentient::NumInventoryItems
   (
   void
   )

   {
   
   return inventory.NumObjects();

   }

Item *Sentient::NextItem
	(
	Item *item
	)

	{
	Item		*next_item;
	int		i;
	int		n;
   qboolean item_found = false;

   if ( !item )
      {
      item_found = true;
      }
   else if ( !inventory.ObjectInList( item->entnum ) )
		{
		error( "NextItem", "Item not in list" );
		}

	n = inventory.NumObjects();

	for( i = 1; i <= n; i++ )
		{
		next_item = ( Item * )G_GetEntity( inventory.ObjectAt( i ) );
      assert( next_item );
      
 		if ( next_item->isSubclassOf( InventoryItem ) && item_found )
         return next_item;

      if ( next_item == item )
         item_found = true;
      }

   return NULL;
   }


Item *Sentient::PrevItem
	(
	Item *item
	)

	{
	Item		*prev_item;
	int		i;
	int		n;
   qboolean item_found = false;

   if ( !item )
      {
      item_found = true;
      }
   else if ( !inventory.ObjectInList( item->entnum ) )
		{
		error( "NextItem", "Item not in list" );
		}

	n = inventory.NumObjects();

	for( i = n; i >= 1; i-- )
		{
		prev_item = ( Item * )G_GetEntity( inventory.ObjectAt( i ) );
      assert( prev_item );
      
 		if ( prev_item->isSubclassOf( InventoryItem ) && item_found)
         return prev_item;

      if ( prev_item == item )
         item_found = true;
      }

   return NULL;
   }


// This will search a dead body and create a floating inventory for that player
// which will be displayed on the client as a list of icons.  If the user presses
// use, then he will pick up the items in that floating inventory, and the body
// will be faded out.
void Sentient::SearchBody
   (
   Event *ev
   )

   {
   int i,n;
   Item *item;
   Entity *other;
   Player *player;
   Event *event;
   qboolean inventory_created = false;

	other = ev->GetEntity( 1 );
   assert( other );
   
   // Only players can touch this
   if ( !other->isSubclassOf( Player ) ) 
      return;

   // Can't touch yourself
   if ( other == this )
      return;

   // Make sure the body is dead
   if ( !deadflag )
      return;

   n = inventory.NumObjects();

   // No items, get out of here
   if ( n == 0 )
      {
      return;
      }

	player = ( Player * )other;

   // Check to see if this inventory is already being displayed for
   // this body.
   if ( player->GetFloatingOwner() == this )
      {
      // Still touching the body, so extend the clear time
      player->CancelEventsOfType( EV_Player_ClearFloatingInventory );
      event = new Event( EV_Player_ClearFloatingInventory );
      player->PostEvent( event, 0.4f );
      return;
      }
   else if ( player->GetFloatingOwner() )
      {
      // Currently looking at an inventory, so don't bother with this one.
      return;
      }
   else
      {
      // Make sure the inventory is cleared out before making a new one.
      // Could have some left over items in there from other bodies
      player->ProcessEvent( EV_Player_ClearFloatingInventory );
      }
      
   // Create the inventory
	for( i = 1; i <= n; i++ )
		{
		item = ( Item * )G_GetEntity( inventory.ObjectAt( i ) );
      assert( item );
      if ( item->Amount() )
         {
         player->AddItemToFloatingInventory( item );
         inventory_created = true;   
         }
      }
   
   if (!inventory_created)
      return;

   // Set the current owner of the inventory
   player->SetFloatingOwner( this );
   
   // Send the inventory to the client
   player->SendFloatingInventory();

   // Clear the inventory in the future
   event = new Event( EV_Player_ClearFloatingInventory );
   player->PostEvent( event, 0.3f );
   }
   
void Sentient::UselessCheck( Event *ev )
   {
   Item     *item;
   int      n;
   int      i;
   Event    *event;

   // Check to see if we have any inventory and
   // remove if we don't

   n = inventory.NumObjects();
   for ( i = 1; i <= n; i++ ) 
      {
      item = ( Item * )G_GetEntity( inventory.ObjectAt( i ) );
      assert( item );
      if ( item->Amount() )
         {
         PostEvent ( EV_Sentient_UselessCheck, 1.0f + G_Random() );
         return;
         }
      }

   event = new Event( "remove_useless" );
   ProcessEvent( event );
   }

qboolean Sentient::HasInventoryOfType
	(
	const char *type
	)

	{
	int	num;
	int	i;
	Item	*item;

	num = inventory.NumObjects();
	for( i = num; i > 0; i-- )
		{
		item = ( Item * )G_GetEntity( inventory.ObjectAt( i ) );
		if ( checkInheritance( type, item->getClassname() ) )
         {
         return true;
         }    
		}
   return false;
	}

void Sentient::DropInventoryItems
   (
   void
   )

   {
   int   num;
   int   i;
   Item  *item;

   // Drop any inventory items
 	num = inventory.NumObjects();
	for( i = num; i >= 1; i-- )
		{
		item = ( Item * )G_GetEntity( inventory.ObjectAt( i ) );
      if ( item->isSubclassOf( InventoryItem ) )
         {
         item->Drop();
         }
      }
   }

qboolean Sentient::PowerupActive
   (
   void
   )

   {
   if ( poweruptype && this->client )
      {
      gi.cprintf( edict, PRINT_HIGH, "You are already using a powerup\n" );
      }

   return poweruptype;
   }

void Sentient::SprayBlood
   (
   Vector src,
   Vector dir,
   float damage
   )

   {
	trace_t	trace;
   Vector	norm;
	Vector	end;
   Vector   ang;
   float		dist;
   float		scale;
   BloodSplat *splat;

	dir.normalize();
	end = src + dir * 2048;

	trace = G_Trace( src, vec_zero, vec_zero, end, this, MASK_SOLIDNONFENCE, "Sentient::SprayBlood" );

	if ( HitSky( &trace ) || ( trace.ent->solid != SOLID_BSP ) || ( trace.ent->s.number != 0 ) ) 
		{
		return;
		}
   
   dist = ( Vector( trace.endpos ) - src ).length();
   scale = damage / ( dist * 0.3 );
   if ( scale > 0.6 )
		{
      scale = 0.6;
		}

   if ( scale < 0.02 )
		{
      return;
		}

   norm = trace.plane.normal;
   norm.x = -norm.x;
   norm.y = -norm.y;
   ang = norm.toAngles();
	ang.z = G_Random( 360 );
   end = trace.endpos + Vector( trace.plane.normal ) * 0.2;

   splat = new BloodSplat( end, ang, scale );
   }

EXPORT_FROM_DLL void Sentient::setModel
	(
	const char *mdl
	)

	{
   if ( currentWeapon )
      {
      // rebind the current gun
      currentWeapon->DetachFromOwner();
      Entity::setModel( mdl );
      currentWeapon->AttachToOwner();
      }
   else
      {
      Entity::setModel( mdl );
      }
	}

void Sentient::TurnOffShadow
   (
   Event *ev
   )

   {
   // HACK FIXME
   //
   // temporary shadow flag
   //
   edict->s.renderfx &= ~RF_XFLIP;
   }

EXPORT_FROM_DLL void Sentient::Archive
	(
	Archiver &arc
	)
   {
   int i;
   int num;

   Entity::Archive( arc );

   num = inventory.NumObjects();
	arc.WriteInteger( num  );
	for( i = 1; i <= num; i++ )
		{
		arc.WriteInteger( inventory.ObjectAt( i ) );
		}
   arc.WriteObjectPointer( currentWeapon );
   arc.WriteObjectPointer( currentItem );
   arc.WriteObjectPointer( newWeapon );
   arc.WriteString( currentAnim );
   arc.WriteBoolean( animOverride );
   arc.WriteEvent( *tempAnimEvent );
   arc.WriteString( gun_bone_group_name );
   arc.WriteBoolean( stopanimating_till

⌨️ 快捷键说明

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