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

📄 weapon.cpp

📁 this keik game source
💻 CPP
📖 第 1 页 / 共 4 页
字号:
	// handles most cases
	weapontype			= WEAPON_2HANDED_HI;

   // start off unattached
   attached          = false;

	// maximum effective firing distance (for AI)
	maxrange = 8192 * 2; // FIXME grr... magic number...
	
	// minimum safe firing distance (for AI)
	minrange = 0;

	// speed of the projectile (0 == infinite speed)
	projectilespeed = 0;

   // default action_level_increment
   action_level_increment = 2;
	}

Weapon::~Weapon()
	{
   DetachGun();
	}

void Weapon::CreateSpawnArgs
   (
   void
   )

   {
   Item::CreateSpawnArgs();
   G_SetIntArg( "ammo_in_clip", ammo_in_clip );
   G_SetIntArg( "silenced", silenced );
   G_SetIntArg( "weaponmode", weaponmode );
   }

int Weapon::Rank
	(
	void
	)

	{
	return rank;
	}

int Weapon::Order
	(
	void
	)

	{
	return order;
	}

void Weapon::SetRank
	(
	int order,
	int rank
	)

	{
	this->order = order;
	this->rank = rank;
	}

void Weapon::SetType
	(
	weapontype_t type
	)

	{
	weapontype = type;
	}

weapontype_t Weapon::GetType
	(
	void
	)

	{
	return weapontype;
	}

void Weapon::SetAmmo
	(
	const char *type,
	int amount,
	int startamount
	)

	{
   if ( type )
		{
	   ammotype = type;
      primary_ammo_type = type;
		}
	else
		{
		ammotype = "";
      primary_ammo_type = "";
      }

	ammorequired = amount;
	startammo = startamount;
	}

void Weapon::SetSecondaryAmmo
   (
   const char *type,
	int amount,
	int startamount
	)

	{
   if ( type )
		{
	   secondary_ammo_type = type;
		}
	else
		{
      secondary_ammo_type = "";
      }

	secondary_ammorequired = amount;
	}

void Weapon::SetAmmoAmount
	(
	int amount
	)

	{
   if ( ammo_clip_size )
      ammo_in_clip = amount;
	}

void Weapon::UseAmmo
	(
	int amount
	)

	{
   if ( ammo_clip_size )
      {
      ammo_in_clip -= amount;
      if (ammo_in_clip < 0)
         {
         warning("UseAmmo","Used more ammo than in clip.\n");
         ammo_in_clip = 0;
         }
      }
   else
      {
      Ammo * ammo;
	   assert( owner );
	   if ( owner && owner->isClient() && !UnlimitedAmmo() )
		   {
         if ( ammotype.length() )
            {
		      ammo = ( Ammo * )owner->FindItem( ammotype.c_str() );
		      
            if ( weaponmode == PRIMARY )
               {
               if ( !ammo || !ammo->Use( ammorequired ) )
	   		      {
		   	      SetAmmoAmount( 0 );
			         return;
                  }
               }
            else
               {
               if ( !ammo || !ammo->Use( secondary_ammorequired ) )
	   		      {
		   	      SetAmmoAmount( 0 );
			         return;
                  }
               }
		      SetAmmoAmount( ammo->Amount() );
            }
		   }
      }
	}

Vector Weapon::MuzzleOffset
	(
   void
	)

   {
   vec3_t	trans[ 3 ];
   vec3_t   orient;
   int		groupindex;
   int		tri_num;
	Vector	offset = vec_zero;
   int      useanim;
   int      useframe;

   // get the bone information
   if ( ( !edict->s.gunmodelindex ) || ( owner && owner->isClient() ) )
      {
      if ( gi.GetBoneInfo( edict->s.modelindex, "barrel", &groupindex, &tri_num, orient ) )
		   {
         if ( aimanim == -1 )
            {
            useanim = edict->s.anim;
            useframe = edict->s.frame;
            }
         else
            {
            useanim = aimanim;
            useframe = aimframe;
            }
         if ( gi.GetBoneTransform( edict->s.modelindex, groupindex, tri_num, orient, useanim, useframe, 
			   edict->s.scale, trans, offset.vec3() ) )
		      {
            //
            // we scale the pos by 0.3 because of RF_DEPTHHACK 
            //
            offset *= 0.3f;
            if ( owner && owner->isClient() )
               {
               switch( owner->client->pers.hand )
                  {
                  case LEFT_HANDED:
                     offset[ 1 ] *= -1.0f;
                     break;
                  case CENTER_HANDED:
                     offset[ 1 ] = 0;
                     break;
                  }
               }
            }
         }
      }
   //
   // if it is a non-client, than get the information from the world model of the gun
   //
   else if ( gi.GetBoneInfo( edict->s.gunmodelindex, "barrel", &groupindex, &tri_num, orient ) )
      {
      gi.GetBoneTransform( edict->s.gunmodelindex, groupindex, tri_num, orient, 0, 0, 
			edict->s.scale, trans, offset.vec3() );
      }
   // Gun doesn't have a barrel, so search the owner for a barrel bone
   else if ( owner && gi.GetBoneInfo( owner->edict->s.modelindex,
                             "barrel",
                             &groupindex,
                             &tri_num,
                             orient ) )
		{
      gi.GetBoneTransform( owner->edict->s.modelindex, 
                           groupindex,
                           tri_num,
                           orient,
                           owner->edict->s.anim,
                           owner->edict->s.frame,
                           owner->edict->s.scale,
                           trans,
                           offset.vec3() );
		}

   return offset;
   }

void Weapon::GetMuzzlePosition
	(
   Vector *position,
	Vector *forward,
	Vector *right,
	Vector *up
	)

	{
   Vector	offset;
	Vector	f, r, u;
	Vector	pos;
	Vector	end;
   Vector   dir;
	Vector	gunpos;
	trace_t	trace;

	assert( owner );

	// technically, we should never not have an owner when firing.
	if ( !owner )
		{
		return;
		}

   //
   // get the position of the owners gun bone
   //
   gunpos = owner->GunPosition();
	pos = gunpos;

	owner->GetGunOrientation( pos, &f, &r, &u );

   // get the bone information
	offset = MuzzleOffset();

   pos += f * offset[ 0 ];
   pos -= r * offset[ 1 ];
	pos += u * offset[ 2 ];

	// prevent the creature from firing through walls
	trace = G_Trace( gunpos, vec_zero, vec_zero, pos, owner, MASK_PROJECTILE, "Weapon::GetMuzzlePosition" );
	if ( ( trace.fraction < 1 ) || ( trace.startsolid ) || ( trace.allsolid ) )
		{
      pos = gunpos;
      pos -= r * offset[ 1 ];
	   pos += u * offset[ 2 ];
		}

   //
   // calculate where this projectile is going to hit
   //
   end = gunpos + f*2048;
	trace = G_FullTrace( gunpos, vec_zero, vec_zero, end, 10, owner, MASK_SHOT, "Weapon::GetMuzzlePosition" );
   dir = trace.endpos - pos;
   dir.normalize();
   if ( dir*f < 0.707 )
      dir = f;

	if ( position )
		{
		*position = pos;
		}

	if ( forward )
		{
		*forward = dir;
		}

	if ( right )
		{
		*right = r;
		}

	if ( up )
		{
		*up = u;
		}
   }

void Weapon::SetAmmoClipSize
	(
   Event * ev
	)

	{
	ammo_clip_size = ev->GetInteger( 1 );
	}

void Weapon::SetModels
	(
	const char *world,
	const char *view
	)

	{
   Event *ev;
	assert( view );

	viewmodel = view;
   modelIndex( view );

   if ( world )
		{
	   worldmodel = world;
      modelIndex( world );
		}
   else
		{
      worldmodel = "";
		}

	if ( owner )
		{
   	setModel( viewmodel );
		}
	else if ( worldmodel.length() )
		{
		setModel( worldmodel );
		}
   else
      {
		setModel( viewmodel );
      }

   if ( worldmodel.length() )
      {
      ev = new Event( EV_Weapon_ProcessModelCommands );
      ev->AddInteger( modelIndex( worldmodel.c_str() ) );
      PostEvent( ev, 0 );
      }
   ev = new Event( EV_Weapon_ProcessModelCommands );
   ev->AddInteger( modelIndex( viewmodel.c_str() ) );
   PostEvent( ev, 0 );
	}

void Weapon::SetAimAnim
   (
   Event *ev
   )

   {
   str anim;

   anim = ev->GetString( 1 );
   aimanim = gi.Anim_NumForName( edict->s.modelindex, anim.c_str() );
   aimframe = ev->GetInteger( 2 );
   }

void Weapon::SetOwner
	(
	Sentient *ent
	)

	{
	assert( ent );
	if ( !ent )
		{
		// return to avoid any buggy behaviour
		return;
		}

	Item::SetOwner( ent );

	setOrigin( vec_zero );
   setAngles( vec_zero );

	if ( !viewmodel.length() )
		{
		error( "setOwner", "Weapon without viewmodel set" );
		}

	setModel( viewmodel );

	if ( ent->isClient() && ammotype.length() && startammo && !G_GetSpawnArg( "savegame" ) )
		{
      ent->giveItem( ammotype.c_str(), startammo );
		}
	}

int Weapon::AmmoAvailable
	(
	void
	)

	{
	Ammo *ammo;

	if ( owner )
		{
      if ( ammotype.length() )
         {
		   ammo = ( Ammo * )owner->FindItem( ammotype.c_str() );
		   if ( ammo )
			   {
			   return ammo->Amount();
			   }
         }
		}

	return 0;
	}

qboolean Weapon::UnlimitedAmmo
   (
   void
   )

   {
	if ( !owner )
		{
		return false;
		}
		
   if ( !owner->isClient() || ( owner->flags & FL_GODMODE ) || DM_FLAG( DF_INFINITE_AMMO ) )
		{
		return true;
		}

#ifdef SIN_ARCADE
   if ( !sv_infinitebullets || !sv_infiniterockets || !sv_infiniteplasma || !sv_infinitespears || !sv_infinitesniper )
      {
      sv_infinitebullets = gameVars.CreateVariable( "infinitebullets", 0 );
      sv_infiniterockets = gameVars.CreateVariable( "infiniterockets", 0 );
      sv_infiniteplasma  = gameVars.CreateVariable( "infiniteplasma", 0 );
      sv_infinitespears  = gameVars.CreateVariable( "infinitespears", 0 );
      sv_infinitesniper  = gameVars.CreateVariable( "infinitesniper", 0 );
      }

   if ( sv_infinitebullets->intValue() && ( ( !Q_strncasecmp( ammotype.c_str(), "bullet", 6 ) && ( ammotype != "BulletPulse" ) &&
      ( ammotype != "BulletSniper" ) ) || ( ammotype == "ShotgunClip" ) ) )
      {
      return true;
      }

   if ( sv_infiniterockets->intValue() && ( ammotype == "Rockets" ) )
      {
      return true;
      }

   if ( sv_infiniteplasma->intValue() && ( ammotype == "BulletPulse" ) )
      {
      return true;
      }

   if ( sv_infinitesniper->intValue() && ( ammotype == "BulletSniper" ) )
      {
      return true;
      }

   if ( sv_infinitespears->intValue() && ( ammotype == "Spears" ) )
      {
      return true;
      }
#endif

   return false;
   }

qboolean Weapon::HasAmmo
	(
	void
	)

	{
	if ( !owner )
		{
		return false;
		}
		
   if ( UnlimitedAmmo() )
		{
		return true;
		}

   if ( weaponmode == PRIMARY )
      {
      if ( ( ammo_clip_size && ammo_in_clip >= ammorequired ) || AmmoAvailable() >= ammorequired )
		   {
		   return true;
		   }
      }
   else
      {
      if ( ( ammo_clip_size && ammo_in_clip >= secondary_ammorequired ) || AmmoAvailable() >= secondary_ammorequired )
		   {
		   return true;
		   }
      }

	return false;
	}

qboolean Weapon::HasAmmoInClip
	(
	void
	)

	{
   if ( ammo_clip_size )
      {
      if ( weaponmode == PRIMARY )
         {
         if ( ammo_in_clip >= ammorequired )
	   	   {
		      return true;
		      }
         }
      else
         {
         if ( ammo_in_clip >= secondary_ammorequired )
	   	   {
		      return true;
		      }
         }
      }
   else
      {
      return HasAmmo();
      }

	return false;

⌨️ 快捷键说明

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