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

📄 weapon.cpp

📁 this keik game source
💻 CPP
📖 第 1 页 / 共 4 页
字号:
	}

void Weapon::ForceState
   (
   weaponstate_t state
   )

   {
   weaponstate = state;
   }

qboolean Weapon::AttackDone
	(
	void
	)

	{
	return ( attack_finished <= level.time );
	}

qboolean Weapon::ReadyToFire
	(
	void
	)

	{
	return ( weaponstate == WEAPON_READY ) && AttackDone();
	}

qboolean Weapon::ReadyToChange
	(
	void
	)

	{
	return ( weaponstate == WEAPON_READY );
	}

qboolean Weapon::ReadyToUse
	(
	void
	)

	{
   return true;
	}

qboolean Weapon::ChangingWeapons
	(
	void
	)

	{
	return ( weaponstate == WEAPON_LOWERING ) || ( weaponstate == WEAPON_RAISING );
	}

qboolean Weapon::WeaponRaising
	(
	void
	)

	{
	return ( weaponstate == WEAPON_RAISING );
	}

qboolean Weapon::WeaponPuttingAway
	(
	void
	)

	{
	return ( weaponstate == WEAPON_LOWERING );
	}

qboolean Weapon::Reloading
	(
	void
	)

	{
	return ( weaponstate == WEAPON_RELOADING );
	}

void Weapon::PutAway
	(
	void
	)
	
	{
	if ( weaponstate != WEAPON_READY )
		{
		return;
		}

	weaponstate = WEAPON_LOWERING;

   if ( !HasAnim( "putaway" ) || ( deathmatch->value && ( ( int )dmflags->value & DF_FAST_WEAPONS ) ) )
		{
		ProcessEvent( EV_Weapon_DoneLowering );
		return;
		}

   if ( dualmode )
      {
      if ( weaponmode == PRIMARY )
         RandomAnimate( "primaryputaway", EV_Weapon_DoneLowering );
      else
         RandomAnimate( "secondaryputaway", EV_Weapon_DoneLowering );
      }
   else
      if ( ( owner ) && ( owner->flags & FL_SILENCER ) && ( silenced ) )
      	RandomAnimate( "silputaway", EV_Weapon_DoneLowering );
      else
        	RandomAnimate( "putaway", EV_Weapon_DoneLowering );

   //weaponmode = PRIMARY;
	}

void Weapon::ReadyWeapon
	(
	void
	)
	
	{
   str   animname;

	if ( weaponstate != WEAPON_HOLSTERED )
		{
		return;
		}

	weaponstate = WEAPON_RAISING;

	AttachGun();

   if ( ( owner ) && ( owner->flags & FL_SILENCER ) && ( silenced ) )
      animname = "silready";
   else
      {
      if ( weaponmode == SECONDARY )
         animname = "secondaryready";      
      else
         animname = "ready";      

      }

   if ( !HasAnim( animname.c_str() ) || ( deathmatch->value && ( ( int )dmflags->value & DF_FAST_WEAPONS ) ) )
	   {
		ProcessEvent( EV_Weapon_DoneRaising );
		return;
		}

	RandomAnimate( animname.c_str(), EV_Weapon_DoneRaising );
	}

void Weapon::DetachFromOwner
	(
	void
	)
	
	{
   StopAnimating();
   DetachGun();
 	weaponstate = WEAPON_HOLSTERED;
	}

void Weapon::AttachToOwner
	(
	void
	)
	
	{
   AttachGun();
   ForceIdle();
	}

qboolean Weapon::Drop
	(
	void
	)

	{
   float radius;
   Vector temp;

	if ( !owner )
		{
		return false;
		}

	if ( !IsDroppable() )
		{
		return false;
		}

   DetachGun();

   const gravityaxis_t &grav = gravity_axis[ gravaxis ];

   temp[ grav.z ] = 40 * grav.sign;
   if ( owner )
      {
	   setOrigin( owner->worldorigin + temp );
      }
   else
      {
	   setOrigin( worldorigin + temp );
      }
	setModel( worldmodel );

   // hack to fix the bounds when the gun is dropped

   //
   // once dropped reset the rotated bounds
   //
   flags |= FL_ROTATEDBOUNDS;

   gi.CalculateBounds( edict->s.modelindex, edict->s.scale, mins.vec3(), maxs.vec3() );
   radius = ( mins - maxs ).length() * 0.25f;
   mins.x = mins.y = -radius;
   maxs.x = maxs.y = radius;
   setSize( mins, maxs );

	StopAnimating();
   edict->s.frame = 0;
   edict->s.anim = 0;

	// drop the weapon
	PlaceItem();
   if ( owner )
      {
      temp[ grav.x ] = G_CRandom( 50 );
      temp[ grav.y ] = G_CRandom( 50 );
      temp[ grav.z ] = 100 * grav.sign;
	   velocity = owner->velocity * 0.5 + temp;
	   setAngles( owner->angles );
      }

	avelocity = Vector( 0, G_CRandom( 360 ), 0 );

	if ( owner && owner->isClient() )
		{
		spawnflags |= DROPPED_PLAYER_ITEM;
      if ( ammo_clip_size )
         startammo = ammo_in_clip;
      else
         startammo = 0;
      
      // If owner is dead, put all his ammo of that type in the gun.
      if ( owner->deadflag )
         {
         startammo = AmmoAvailable();
         }
		}
	else
		{
		spawnflags |= DROPPED_ITEM;
      if ( ammo_clip_size && ammo_in_clip )
         startammo = ammo_in_clip;
      else
         startammo >>= 2;

      if ( startammo == 0 )
         {
         startammo = 1;
         }
		}

   // Wait some time before the last owner can pickup this weapon
   last_owner = owner;
   last_owner_trigger_time = level.time + 2.5f;

   // Cancel reloading events
   CancelEventsOfType( EV_Weapon_DoneReloading );

   // Remove this from the owner's item list
   if ( owner )
      {
      owner->RemoveItem( this );
      }
   
   owner = NULL;
   
   // Fade out dropped weapons, to keep down the clutter
   PostEvent( EV_FadeOut, 30 );
	return true;
	}


void Weapon::Fire
	(
	void
	)

	{
	if ( !ReadyToFire() )
		{
		return;
		}

	if ( !HasAmmoInClip() )
		{
      CheckReload();
		return;
		}

   if ( weaponmode == PRIMARY )
      UseAmmo( ammorequired );
   else
      UseAmmo( secondary_ammorequired );

	weaponstate = WEAPON_FIRING;

	CancelEventsOfType( EV_Weapon_DoneFiring );
   // this is just a precaution that we can re-trigger
	NextAttack( 5 );

  	if ( dualmode )
      {
      if ( weaponmode == PRIMARY )
         {
         RandomAnimate( "primaryfire", EV_Weapon_DoneFiring );
         }
      else
         {
         RandomAnimate( "secondaryfire", EV_Weapon_DoneFiring );
         }
      }
   else
      {
      if ( ( owner ) && ( owner->flags & FL_SILENCER ) && ( silenced ) )
         RandomAnimate( "silfire", EV_Weapon_DoneFiring );
      else
         RandomAnimate( "fire", EV_Weapon_DoneFiring );
      }

   last_attack_time = level.time;
	}

//**********************************************************************************/
//
// Non-public Weapon functions
//
//**********************************************************************************/

void Weapon::DetachGun
	(
	void
	)

	{
	if ( attached )
		{
      RandomGlobalSound("null_sound", 1, CHAN_WEAPONIDLE );
      attached = false;
      detach();
		hideModel();
		edict->s.gunmodelindex	= 0;
      edict->s.gunanim        = 0;
		edict->s.gunframe		   = 0;
   	edict->s.effects &= ~EF_SMOOTHANGLES;
		}
	}

//
// attach and detach the gun from the owner
//

void Weapon::AttachGun
	(
	void
	)

	{
	int groupindex;
	int tri_num;
	Vector orient;

	if ( !owner )
		{
		return;
		}

   if (attached)
      DetachGun();

	if	( gi.GetBoneInfo( owner->edict->s.modelindex, "gun", &groupindex, &tri_num, orient.vec3() ) )
	   {
      attached = true;
		attach( owner->entnum, groupindex, tri_num, orient );
		showModel();
		setOrigin( vec_zero );
		edict->s.gunmodelindex	= modelIndex( worldmodel.c_str() );
      if ( edict->s.gunmodelindex )
         {
         edict->s.gunanim        = gi.Anim_Random( edict->s.gunmodelindex, "idle" );
         if ( edict->s.gunanim < 0 )
            edict->s.gunanim = 0;
		   edict->s.gunframe		   = 0;
         }
      else
         {
         edict->s.gunanim        = 0;
		   edict->s.gunframe		   = 0;
         }
   	edict->s.effects |= EF_SMOOTHANGLES;
		}
	else
		{
		gi.dprintf( "attach failed\n" );
		}
	}

void Weapon::PickupWeapon
	(
	Event *ev
	)
	
	{
	Sentient *sen;
	Entity   *other;
   Weapon   *weapon;
	Weapon   *current;
   qboolean hasweapon;
   qboolean giveammo;
   Ammo     *ammo;

	other = ev->GetEntity( 1 );
   
   assert( other );

	if ( !other->isSubclassOf( Sentient ) )
      {
		return;
      }

	sen = ( Sentient * )other;

   // If this is the last owner, check to see if he can pick it up
   if ( ( sen == last_owner ) && ( level.time < last_owner_trigger_time ) )
      {
      return;
      }

   hasweapon = sen->HasItem( getClassname() );
   giveammo = ( sen->isClient() && ammotype.length() && startammo );

   // if he already has the weapon, don't pick it up if he doesn't need the ammo
   if ( hasweapon )
      {
      if ( !giveammo )
         {
         return;
         }

      // check if he needs the ammo
      ammo = ( Ammo * )sen->FindItem( ammotype.c_str() );
      if ( ammo && ( ammo->Amount() >= ammo->MaxAmount() ) )
         {
         // doesn't need the ammo or the weapon, so return.
         return;
         }
      }

  	weapon = ( Weapon * )ItemPickup( other );
	if ( !weapon )
      {
      // Item Pickup failed, so don't give ammo either.
      return;
      }

   //
   // once picked up we don't want rotated bounds
   //
   flags &= ~FL_ROTATEDBOUNDS;

   //FIXME
   // Sentient should probably handle this when itempickup is called
   // Check if we should switch his weapon
   current = sen->CurrentWeapon();
	if ( !hasweapon && current && ( current != weapon ) && ( current->AutoChange() ) && 
		( ( current->Rank() < weapon->Rank() ) || ( !current->HasAmmo() && weapon->HasAmmo() ) ) )
		{
		sen->ChangeWeapon( weapon );
		}

   // check if we should give him ammo
	if ( giveammo )
		{
      sen->giveItem( ammotype.c_str(), startammo );
		}
	}

void Weapon::ForceIdle
   (
   void
   )

   {
	weaponstate = WEAPON_READY;
	   
   if ( dualmode )
      {
      if ( weaponmode == PRIMARY )
   	   RandomAnimate( "primaryidle", EV_Weapon_Idle );
      else
         RandomAnimate( "secondaryidle", EV_Weapon_Idle );
      }
   else
      {
      if ( owner && ( owner->flags & FL_SILENCER ) && ( silenced ) )
      	RandomAnimate( "silidle", EV_Weapon_Idle );
      else
         RandomAnimate( "idle", EV_Weapon_Idle );
      }
   }

void Weapon::DoneLowering
	(
	Event *ev
	)

	{
	weaponstate = WEAPON_HOLSTERED;

   DetachGun();

	if ( owner )
		{
		owner->ProcessEvent( EV_Sentient_WeaponPutAway );
		}
	StopAnimating();
	}

void Weapon::DoneRaising
	(
	Event *ev
	)

	{
	weaponstate = WEAPON_READY;

   if ( !ForceReload() )
      {
      ForceIdle();
      }

	if ( !owner )
		{
		PostEvent( EV_Remove, 0 );
		return;
		}

   // Set the ammo type
   if (weaponmode == PRIMARY)
      {
      ammotype = primary_ammo_type;
      }
   else if ( weaponmode == SECONDARY )
      {
      ammotype = secondary_ammo_type;
      }

   if ( owner )
	   owner->ProcessEvent( EV_Sentient_WeaponReady );
	}

void Weapon::DoneFiring
	(
	Event *ev
	)

	{
   if ( !CheckReload() )
      {
      ForceIdle();
      }

	if ( owner )
		{
		owner->ProcessEvent( EV_Sentient_WeaponDoneFiring );
		}
	}

void Weapon::DoneReloading

⌨️ 快捷键说明

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