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

📄 sentient.cpp

📁 this keik game source
💻 CPP
📖 第 1 页 / 共 5 页
字号:
   giveItem( type, amount );

	if ( currentWeapon && !currentWeapon->HasAmmo() )
		{
   	Weapon		*best;
		best = BestWeapon();
		if ( best )
			{
			ChangeWeapon( best );
			}
		}
   }

void Sentient::EventTakeArmor
	(
	Event *ev
	)

	{
   int			amount;
	const char	*type;
	Armor			*armor;

	type = ev->GetString( 1 );
   amount = ev->GetInteger( 2 );

	armor = ( Armor * )FindItem( type );
	if ( armor )
		{
		armor->Remove( amount );
		}
   }

void Sentient::EventGiveArmor
	(
	Event *ev
	)

	{
   int			amount;
	const char	*type;
	Armor			*armor;

	type     = ev->GetString( 1 );
   amount   = ev->GetInteger( 2 );

	if ( !checkInheritance( &Armor::ClassInfo, type ) )
		{
		gi.dprintf( "%s is not usable as armor\n", type );
		return;
		}

	armor    = ( Armor * )FindItem( type );

	if ( armor )
		{
		armor->Set( amount );
		}
	else
		{
      giveItem( type, amount );
      }
   }

void Sentient::EventGiveItem
   (
   Event *ev
   )

   {
	const char	*type;
   float       amount;

	type     = ev->GetString( 1 );
   amount   = ev->GetInteger( 2 );

   giveItem( type, amount );
   }

void Sentient::EventGiveInventoryItem
   (
   Event *ev
   )

   {
	const char	         *type;
   int                  amount;

	type     = ev->GetString( 1 );
   amount   = ev->GetInteger( 2 );

	if ( !checkInheritance( &InventoryItem::ClassInfo, type ) )
      {
      gi.dprintf( "item '%s' is not a InventoryItem\n", type );
      return;
      }

   giveItem( type, amount );
   }

void Sentient::WeaponPutAway
	(
	Event *ev
	)

	{
	SetCurrentWeapon( newWeapon );
	}

void Sentient::WeaponReady
	(
	Event *ev
	)

	{
   if ( newWeapon )
      {
      ChangeWeapon( newWeapon );
      }
	}

void Sentient::WeaponDoneFiring
	(
	Event *ev
	)

	{
	Weapon *best;

   if ( newWeapon )
      {
      ChangeWeapon( newWeapon );
      }
   else if ( !currentWeapon || !currentWeapon->HasAmmo() || !currentWeapon->ReadyToUse() )
		{
		best = BestWeapon();
		if ( best )
			{
			ChangeWeapon( best );
			}
		}
	}

EXPORT_FROM_DLL void Sentient::AnimLoop
	(
	Event *ev
	)

	{
	Event *t;

	animOverride = false;

	if ( deadflag )
		{
		StopAnimating();
		}
	else if ( animating )
		{
		RandomAnimate( currentAnim.c_str(), NULL );
		}
   else
      {
      stopanimating_tillchange = true;
      }

	if ( tempAnimEvent )
		{
		t = tempAnimEvent;
		tempAnimEvent = NULL;
      ProcessEvent( t );
		}
	}

EXPORT_FROM_DLL void Sentient::SetAnim
	(
	const char *anim
	)

	{
	assert( anim );

   assert ( !deadflag );

	if ( str( anim ) == currentAnim )
		{
      if (!animating && !stopanimating_tillchange)
         StartAnimating();
		return;
		}

   stopanimating_tillchange = false;
   currentAnim = str( anim );

	if ( animOverride )
		{
		return;
		}

	RandomAnimate( currentAnim.c_str(), EV_Sentient_AnimLoop );

   if (!animating)
      StartAnimating();
	}

EXPORT_FROM_DLL void Sentient::TempAnim
	(
	const char *anim,
	Event *event
	)

	{
   assert ( !deadflag );

	assert( anim );

	animOverride = true;

	tempAnimEvent = event;

	RandomAnimate( anim, EV_Sentient_AnimLoop );
	}

void Sentient::TempAnim
	(
	const char *anim,
	Event &event
   )

   {
	Event *ev;

	ev = new Event( event );
	TempAnim( anim, ev );
   }

void Sentient::PrintDamageLocationToAttacker
   (
   edict_s     *attacker,
   const char  *victim_name,
   const char  *location
   )

   {
   const char *expanded_location;

   expanded_location = ExpandLocation( location );

   if ( expanded_location )
      gi.cprintf ( attacker, PRINT_MEDIUM, "You hit %s in the %s.\n", victim_name, expanded_location );
   }

void Sentient::PrintDamageLocationToVictim
   (
   edict_s     *victim,
   const char  *location
   )

   {
   const char *expanded_location;

   expanded_location = ExpandLocation( location );

   if ( expanded_location )
      gi.cprintf ( victim, PRINT_MEDIUM, "%s damage\n", expanded_location );
   }

qboolean Sentient::DoGib
   (
   int meansofdeath,
   Entity *inflictor
   )

   {
   if ( !( flags & FL_DIE_GIBS ) || parentmode->value )
      {
      return false;
      }

   if ( 
       ( meansofdeath == MOD_TELEFRAG ) || 
       ( meansofdeath == MOD_MUTANTHANDS ) || 
       ( meansofdeath == MOD_HELIGUN ) || 
       ( meansofdeath == MOD_LAVA ) ||
       ( ( meansofdeath == MOD_FISTS ) && ( inflictor->flags & FL_ADRENALINE ) ) ||
       ( ( meansofdeath == MOD_SHOTGUN ) && ( G_Random() < 0.3 ) )
      )
      {
      return true;
      }

   if ( health > -75 )
      {
      return false;
      }

   // Impact and Crush < -75 health
   if ( ( meansofdeath == MOD_IMPACT ) || 
        ( meansofdeath == MOD_CRUSH ) ||
        ( meansofdeath == MOD_VEHICLE )
      )
      {
      return true;
      }

   // Any projectiles except spear
   if ( inflictor->isSubclassOf( Projectile ) )
      {
      if ( meansofdeath != MOD_SPEARGUN )
         {
         return true;
         }
      }
   
   // Shotgun only 10% of the time
   if ( meansofdeath == MOD_SHOTGUN )
      {
      if ( G_Random() > 0.5 )
         {
         return true;
         }
      }

   return false;
   }
   
void Sentient::ArmorDamage
	(
   Event *ev
   )

	{
   Armor    *armor=0;
 	Entity	*inflictor;
	Entity	*attacker;
	float		damage;
   float    armor_damage=0;
	Vector	momentum;
   Vector   position;
   Vector   normal;
   Vector   direction;
   Event		*event;
   int      dflags;
   int      meansofdeath;
   int      knockback;
   float    damage_mult;
   int      groupnum;
   int      trinum;
   const char *location="";
   float    unmodified_damage=0;

   if ( ( takedamage == DAMAGE_NO ) || ( movetype == MOVETYPE_NOCLIP ) )
	   {      
      if ( isClient () )
         {
         Player *player;
         
         player = ( Player * )this;
         if ( !player->GetVehicle() )
            return;
         }
      else
         {
         return;
         }
      }

   damage		   = ev->GetFloat  ( 1 );
	inflictor	   = ev->GetEntity ( 2 );
	attacker		   = ev->GetEntity ( 3 );
   position       = ev->GetVector ( 4 );
   direction      = ev->GetVector ( 5 );
   normal         = ev->GetVector ( 6 );
   knockback      = ev->GetInteger( 7 );
   dflags         = ev->GetInteger( 8 );
   meansofdeath   = ev->GetInteger( 9 );
   groupnum       = ev->GetInteger( 10 );
   trinum         = ev->GetInteger( 11 );
   damage_mult    = ev->GetFloat  ( 12 );

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

      delta = centroid - worldorigin;
      radius = delta.length();

      //
      // transform the centroid around by the current orientation
      //
		MatrixTransformVector( delta.vec3(), orientation, org.vec3() );
      org += worldorigin;

      forcefield->setModel( "sphere2.def" );
      forcefield->setOrigin( org );
      forcefield->worldorigin.copyTo(forcefield->edict->s.old_origin);
      forcefield->setMoveType( MOVETYPE_NONE );
      forcefield->setSolidType( SOLID_NOT );
      forcefield->edict->s.scale = radius / 16;
      alpha = ( damage * damage_mult ) / 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;
      }

	// if enabled you can't hurt teammates (but you can hurt yourself)
	// knockback still occurs
	if ( ( attacker != this ) && ( DM_FLAG( DF_MODELTEAMS | DF_SKINTEAMS ) ) )
	   {
		if ( OnSameTeam ( this, attacker ) )
		   {
	      // check for friendly fire
         if ( DM_FLAG( DF_FRIENDLY_FIRE ) )
				meansofdeath = MOD_FRIENDLY_FIRE;
			else
				damage = 0;
		   }
	   }

   if (groupnum == -1)
      location = "all";
   else
      location = gi.Group_NumToName( edict->s.modelindex, groupnum );
   
   // Adjust damage for skill level
   if ( isClient() && !deathmatch->value && !(dflags & DAMAGE_NO_SKILL))
      {
      // Clamp the damage multiplier
      if ( damage_mult > 2 )
         damage_mult = 2;
      
      switch( ( int )skill->value )
         {
         case 0:
            damage *= 0.2f;
            break;
         case 1:
            damage *= 0.4f;
            break;
         case 2:
            damage *= 0.6f;
            break;
         default:
            damage *= 0.8f; 
            break;
         }
      }

   // Shields reduce damage by 75%
   if ( flags & FL_SHIELDS )
      {
      damage *= 0.25f;
      }
   else if ( flags & FL_MUTANT )
      {
      damage *= 0.33f;
      }

   // If in deathmatch, client takes a minimum of 33% damage from source
   if ( deathmatch->value )
      {
      damage *= 0.66f;
      unmodified_damage = damage * 0.33f;
      }

   // check to see if we have armor in this location to reduce the damage
   if (location[0]  && !(dflags & DAMAGE_NO_ARMOR) )
      {
      if ( !strncmp( location,"all",3 ) )
         {
         char *armortypes[] = {"RiotHelmet", "FlakJacket", "FlakPants", NULL};
         int i = 0;
         float reduced_damage = 0;
   
         // Go through all the armor types
         while (armortypes[i])
            {
            float partial_damage = damage / 3;
            float odam = partial_damage;

            armor = ( Armor * )FindItem( armortypes[i] );
            
            // Check for armor in this spot
            if ( armor && ( armor->Amount() > 0 ) )
               {
               // Reduce the parital damage by the amount of armor
               partial_damage -= armor->Amount();
         
               if ( partial_damage < 0 )
                  partial_damage = 0;

               // Remove the amount absorbed by the armor from the armor.
               armor->Remove( odam - partial_damage );

               // Keep track of the damage done to the armor for testing purposes
               armor_damage += (odam - partial_damage );
               }   
            // Keep track of damage done after armor has been applied
            reduced_damage += partial_damage;
            i++;
            }
         // This is the damage after all armor is done
         damage = reduced_damage;
         }
      // else check for specific location based
      else if ( !strncmp( location,"head",4 ) )
         armor = ( Armor * )FindItem( "RiotHelmet" );
      else if ( !strncmp(location,"torso",4 ) )
         armor = ( Armor * )FindItem( "FlakJacket" );
//      else if ( !strncmp( location,"arm",3 ) )
//         armor = ( Armor * )FindItem( "FlakJacket" );
      else if ( !strncmp(location,"leg",3 ) )
         armor = ( Armor * )FindItem( "FlakPants" );
      
      // If armor is there, remove the appropriate amount
      if ( armor && ( armor->Amount() > 0 ) && !(dflags & DAMAGE_NO_ARMOR) )
         {
         float odam = damage;
         damage -= armor->Amount();
         
         if ( damage < 0 )
            damage = 0;

         armor->Remove( odam-damage );
         armor_damage += (odam - damage );
         }
      }

   damage += unmodified_damage;

   // Damage multiplier
   damage *= damage_mult;

   // Damage skins if armor didn't absorb all damage
   if ( ( damage > 0 ) && ( groupnum != -1 ) && ( flags & FL_BLOOD ) )
      if ( !edict->s.groups[ groupnum ] )
         edict->s.groups[ groupnum ]++;

   // Show location based damage.
   if ( sv_showdamagelocation->value && deathmatch->value )
      {
      // Send message to attacker
      if ( attacker->isClient() )
         {
         if ( this->client )
            {
            PrintDamageLocationToAttacker( attacker->edict, this->client->pers.netname, location );
            }
         }

      // Send message to victim
      if ( this->isClient() && attacker != this ) 
         {
         PrintDamageLocationToVictim(this->edict, location);
         }
      }

   // Shows detailed damage messages 
   if ( sv_showdamage->value )
      {
      // Send message to attacker
      if ( attacker->isClient() )
         {
         if ( this->client )
            {
            gi.cprintf ( attacker->edict, PRINT_HIGH, "TARG:%s ARMOR_DAM:%0.2f TOT_DAM:%0.2f LOC:%s\n", 

⌨️ 快捷键说明

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