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

📄 sentient.cpp

📁 this keik game source
💻 CPP
📖 第 1 页 / 共 5 页
字号:
// 9     11/20/97 9:02p Jimdose
// Changed Container class to use entity # instead of void *
// 
// 8     11/18/97 5:27p Markd
// Changed "ammo" command and also fixed some weapon checking
// 
// 7     11/15/97 6:54p Markd
// Added InterpretCommand, Added "fire", "ammo" and "weapon" command
// 
// 6     10/28/97 6:05p Jimdose
// Sentients now pick up nails from nail weapons.
// 
// 5     10/27/97 3:29p Jimdose
// Removed dependency on quakedef.h
// 
// 4     10/24/97 2:58p Jimdose
// Fixed bug where sentient was bound to weapon instead of weapon bound to
// sentient.
// 
// 3     10/01/97 2:04p Jimdose
// Weapons are now bound to their owners when they are picked up.
// 
// 2     9/26/97 6:47p Jimdose
// Added standard Ritual headers
//
// DESCRIPTION:
// Base class of entity that can carry other entities, and use weapons.
//

#include "g_local.h"
#include "entity.h"
#include "sentient.h"
#include "weapon.h"
#include "scriptmaster.h"
#include "ammo.h"
#include "armor.h"
#include "misc.h"
#include "inventoryitem.h"
#include "player.h"
#include "actor.h"

CLASS_DECLARATION( Entity, Sentient, NULL );

Event EV_Sentient_Attack( "fire" );
Event EV_Sentient_ReleaseAttack( "releasefire" );
Event EV_Sentient_GiveWeapon( "weapon" );
Event EV_Sentient_GiveAmmo( "ammo" );
Event EV_Sentient_GiveArmor( "armor" );
Event EV_Sentient_GiveItem( "item" );
Event EV_Sentient_GiveTargetname( "give" );
Event EV_Sentient_GiveInventoryItem( "invitem" );
Event EV_Sentient_GiveHealth( "health", EV_CHEAT );
Event EV_Sentient_TakeWeapon( "take_weapon" );
Event EV_Sentient_TakeAmmo( "take_ammo" );
Event EV_Sentient_TakeArmor( "take_armor" );
Event EV_Sentient_TakeItem( "take_item" );
Event EV_Sentient_WeaponPutAway( "weapon_putaway" );
Event EV_Sentient_WeaponReady( "weapon_ready" );
Event EV_Sentient_WeaponDoneFiring( "weapon_donefiring" );
Event EV_Sentient_AnimLoop( "animloop" );
Event EV_Sentient_UselessCheck( "useless_check" );
Event EV_Sentient_TurnOffShadow( "noshadow" );
Event EV_Sentient_Freeze( "freeze" );
Event EV_Sentient_UnFreeze( "unfreeze" );
Event EV_Sentient_ImpactDamage( "impact_damage" );
Event EV_Sentient_WeaponUse( "weaponuse", EV_CONSOLE );
Event EV_Sentient_SetDropWeapon( "dropweapon" );
Event EV_Sentient_DropWeaponNow( "dropweaponnow" );

ResponseDef Sentient::Responses[] =
   {
	   { &EV_Sentient_Attack,				( Response )Sentient::FireWeapon },
      { &EV_Sentient_ReleaseAttack,		( Response )Sentient::ReleaseFireWeapon },
	   { &EV_Sentient_GiveWeapon,			( Response )Sentient::EventGiveWeapon },
      { &EV_Sentient_TakeWeapon,			( Response )Sentient::EventTakeWeapon },
	   { &EV_Sentient_GiveAmmo,			( Response )Sentient::EventGiveAmmo },
      { &EV_Sentient_TakeAmmo,			( Response )Sentient::EventTakeAmmo },
      { &EV_Sentient_GiveArmor,			( Response )Sentient::EventGiveArmor },
      { &EV_Sentient_TakeArmor,			( Response )Sentient::EventTakeArmor },
      { &EV_Sentient_GiveItem,         ( Response )Sentient::EventGiveItem },
      { &EV_Sentient_GiveInventoryItem,( Response )Sentient::EventGiveInventoryItem },
      { &EV_Sentient_GiveHealth,       ( Response )Sentient::EventGiveHealth },
      { &EV_Sentient_GiveTargetname,   ( Response )Sentient::EventGiveTargetname },
      { &EV_Sentient_WeaponPutAway,		( Response )Sentient::WeaponPutAway },
	   { &EV_Sentient_WeaponReady,		( Response )Sentient::WeaponReady },
		{ &EV_Sentient_WeaponDoneFiring,	( Response )Sentient::WeaponDoneFiring },
		{ &EV_Sentient_AnimLoop,			( Response )Sentient::AnimLoop },
      { &EV_Damage,                    ( Response )Sentient::ArmorDamage },
      { &EV_Touch,                     ( Response )Sentient::SearchBody },
  		{ &EV_Sentient_UselessCheck,		( Response )Sentient::UselessCheck },
  		{ &EV_Sentient_TurnOffShadow,		( Response )Sentient::TurnOffShadow },
      { &EV_Sentient_Freeze,		      ( Response )Sentient::Freeze },
      { &EV_Sentient_UnFreeze,	      ( Response )Sentient::UnFreeze },
      { &EV_Sentient_ImpactDamage,     ( Response )Sentient::ImpactDamage },
      { &EV_Sentient_WeaponUse,		   ( Response )Sentient::WeaponUse },
      { &EV_Sentient_SetDropWeapon,	   ( Response )Sentient::SetDropWeapon },
      { &EV_Sentient_DropWeaponNow,	   ( Response )Sentient::DropWeaponNowEvent },
      { &EV_Sentient_TakeItem,	      ( Response )Sentient::EventTakeItem },
		{ NULL, NULL }
	};

Container<Sentient *> SentientList;

Sentient::Sentient()
	{
   Vector defangles;

	SentientList.AddObject( ( Sentient * )this );

	inventory.ClearObjectList();
	currentWeapon = NULL;
   currentItem = NULL;
	newWeapon = NULL;
	animOverride = false;
	dropweapon = true;
   tempAnimEvent = NULL;
   
	eyeposition = "0 0 64";
	gunoffset = "0 0 56";
   
   firedown = false;
   firedowntime = 0;

   // angles
   defangles = Vector( 0, G_GetFloatArg( "angle", 0 ), 0 );
   if (defangles.y == -1)
      {
      defangles = Vector( -90, 0, 0 );
      }
   else if (defangles.y == -2)
      {
      defangles = Vector( 90, 0, 0 );
      }
   angles = G_GetVectorArg( "angles", defangles );
	setAngles( angles );
   stopanimating_tillchange = false;

   poweruptype    = 0;
   poweruptimer   = 0;
   sentientFrozen = false;

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

Sentient::~Sentient()
	{
	SentientList.RemoveObject( ( Sentient * )this );
	FreeInventory();
	}

Vector Sentient::EyePosition
	(
	void
	)

	{
	Vector pos;

	pos = worldorigin;
	pos[ gravity_axis[ gravaxis ].x ] += eyeposition[ 0 ];
	pos[ gravity_axis[ gravaxis ].y ] += eyeposition[ 1 ] * gravity_axis[ gravaxis ].sign;
	pos[ gravity_axis[ gravaxis ].z ] += eyeposition[ 2 ] * gravity_axis[ gravaxis ].sign;

	return pos;
	}

Vector Sentient::GunPosition
	(
	void
	)

	{
	Vector pos;

	pos = worldorigin;
	pos[ gravity_axis[ gravaxis ].x ] += gunoffset[ 0 ];
	pos[ gravity_axis[ gravaxis ].y ] += gunoffset[ 1 ] * gravity_axis[ gravaxis ].sign;
	pos[ gravity_axis[ gravaxis ].z ] += gunoffset[ 2 ] * gravity_axis[ gravaxis ].sign;

	return pos;
	}

inline void Sentient::GetGunOrientation
	(
   Vector pos, 
	Vector *forward,
	Vector *right,
	Vector *up
	)
	
	{
	const gravityaxis_t &grav = gravity_axis[ gravaxis ];

	if ( forward )
		{
		( *forward )[ grav.x ] = orientation[ 0 ][ 0 ];
		( *forward )[ grav.y ] = orientation[ 0 ][ 1 ] * grav.sign;
		( *forward )[ grav.z ] = orientation[ 0 ][ 2 ] * grav.sign;
		}

	if ( right )
		{
		( *right )[ grav.x ] = -orientation[ 1 ][ 0 ];
		( *right )[ grav.y ] = - orientation[ 1 ][ 1 ] * grav.sign;
		( *right )[ grav.z ] = - orientation[ 1 ][ 2 ] * grav.sign;
		}

	if ( up )
		{
		( *up )[ grav.x ] = orientation[ 2 ][ 0 ];
		( *up )[ grav.y ] = orientation[ 2 ][ 1 ] * grav.sign;
		( *up )[ grav.z ] = orientation[ 2 ][ 2 ] * grav.sign;
		}
	}

void Sentient::GetMuzzlePositionAndDirection
   (
   Vector *pos,
   Vector *dir
   )

   {
   *pos = Vector( "0 0 0" );
   *dir = Vector( "0 0 0" );

   if ( currentWeapon )
      currentWeapon->GetMuzzlePosition( pos, dir );
   }

void Sentient::EventGiveHealth
   (
   Event *ev
   )

   {
   int group_num;

   health = ev->GetFloat( 1 );

   if ( isClient() )
      {
      for( group_num = 0; group_num < edict->s.numgroups ; group_num++ )
         {
         edict->s.groups[ group_num ] &= ~MDL_GROUP_SKINOFFSET_BIT0;
         }
      }
   }

void Sentient::FireWeapon
	(
	Event *ev
	)

	{
	if ( ( currentWeapon ) && currentWeapon->ReadyToFire() && currentWeapon->HasAmmo() )
		{
		currentWeapon->Fire();
		}
	}

void Sentient::ReleaseFireWeapon
	(
	Event *ev
	)

	{
   // Only need to check if currentWeapon because FireWeapon checks for
   // the weapon ready and if it has ammo.
	if ( currentWeapon )
		{
      float fireholdtime = ev->GetFloat( 1 );
      currentWeapon->ReleaseFire( fireholdtime );
		}
	}

void Sentient::AddItem
	(
	Item *object
	)

	{
	inventory.AddObject( object->entnum );

   if ( object->isSubclassOf( InventoryItem ) ) 
      {
      currentItem = (InventoryItem *)object;
      }
   //
   // set our global game variables if client
   //
   if ( isClient() )
      {
      str fullname;
      ScriptVariable * var;

      fullname = str( "playeritem_" ) + object->getClassname();
      var = gameVars.GetVariable( fullname.c_str() );
      if ( !var )
         {
         gameVars.SetVariable( fullname.c_str(), 1 );
         }
      else
         {
         int amount;

         amount = var->intValue() + 1;
         var->setIntValue( amount );
         }

      var = levelVars.GetVariable( fullname.c_str() );
      if ( !var )
         {
         levelVars.SetVariable( fullname.c_str(), 1 );
         }
      else
         {
         int amount;

         amount = var->intValue() + 1;
         var->setIntValue( amount );
         }
      }
	}

void Sentient::RemoveItem
	(
	Item *object
	)

	{
	Weapon *weapon;

	inventory.RemoveObject( object->entnum );
	if ( currentWeapon == object )
		{
		currentWeapon = NULL;
		if ( newWeapon == object )
			{
			newWeapon = NULL;
			weapon = BestWeapon();
			}
		else
			{
			weapon = newWeapon;
			}

		SetCurrentWeapon( weapon );
		}

   //
   // set our global game variables if client
   //
   if ( isClient() )
      {
      str fullname;
      ScriptVariable * var;

      fullname = str( "playeritem_" ) + object->getClassname();

      var = levelVars.GetVariable( fullname.c_str() );
      if ( var )
         {
         int amount;

         amount = var->intValue() - 1;
         if ( amount < 0 )
            amount = 0;
         var->setIntValue( amount );
         }
      }

   if ( currentItem == (InventoryItem *) object )
      {
      currentItem = NULL;
      // Try to set the the current item

      currentItem = (InventoryItem *)NextItem( NULL );
      if (!currentItem)
         {
         currentItem = (InventoryItem *)PrevItem( NULL );
         }
      }
	}

Item *Sentient::FindItem
	(
	const char *itemname
	)

	{
	int	num;
	int	i;
	Item	*item;

	num = inventory.NumObjects();
	for( i = 1; i <= num; i++ )
		{
		item = ( Item * )G_GetEntity( inventory.ObjectAt( i ) );
		if ( !Q_stricmp( item->getClassname(), itemname ) )
			{
			return item;
			}
		}

	return NULL;
	}

void Sentient::FreeInventory
	(
	void
	)

	{
	int	num;
	int	i;
	Item	*item;

	if ( currentWeapon )
      currentWeapon->DetachFromOwner();

   SetCurrentWeapon( NULL );
	newWeapon = NULL;

	num = inventory.NumObjects();
	for( i = num; i > 0; i-- )
		{
		item = ( Item * )G_GetEntity( inventory.ObjectAt( i ) );
		delete item;
		}

	inventory.ClearObjectList();
   currentItem = NULL;
	}

void Sentient::FreeInventoryOfType
	(
	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() ) )
         {
         inventory.RemoveObject( item->entnum );

         // If the current item is about to be deleted, then look for
         // another item to be current
         if ( currentItem == item )
            {
            currentItem = NULL;
            // Try to set the the current item

           currentItem = (InventoryItem *)NextItem( NULL );
            if (!currentItem)
               {
               currentItem = (InventoryItem *)PrevItem( NULL );
               }
            }
         delete item;
         }    
		}
	}

qboolean Sentient::HasItem
	(
	const char *itemname
	)

	{
	return ( FindItem( itemname ) != NULL );
	}

int Sentient::NumWeapons
	(
   void
	)

	{
	int	num;
	int	i;
	Item	*item;
   int   numweaps;

   numweaps = 0;

	num = inventory.NumObjects();
	for( i = 1; i <= num; i++ )
		{
		item = ( Item * )G_GetEntity( inventory.ObjectAt( i ) );
      if ( checkInheritance( &Weapon::ClassInfo, item->getClassname() ) )
			{
         numweaps++;
			}
		}

   return numweaps;
	}

Weapon * Sentient::WeaponNumber
	(
   int weaponnum
	)

	{
	int	num;
	int	i;
	Item	*item;

	// make it so that 0 is our first weapon rather than 1
   weaponnum++;
	num = inventory.NumObjects();
	for( i = 1; i <= num; i++ )
		{
		item = ( Item * )G_GetEntity( inventory.ObjectAt( i ) );
      if ( item->isSubclassOf( Weapon ) )
         {
         weaponnum--;
         if ( !weaponnum )
				{
            return ( Weapon * )item;
				}
         }
		}

   return NULL;
	}

void Sentient::ChangeWeapon
	(
	Weapon *weapon
	)

	{
	if ( weapon == currentWeapon )
		{
		return;
		}

	if ( currentWeapon )
		{
		if ( !weapon->ReadyToUse() )
			{
			return;
			}
		newWeapon = weapon;
		if ( !currentWeapon->ReadyToChange() )
			{
			return;
			}
		currentWeapon->PutAway();
		}
	else
		{
		SetCurrentWeapon( weapon );
		}
	}

void Sentient::ForceChangeWeapon
	(
	Weapon *weapon
	)

	{
   if ( newWeapon == weapon )
      {
      return;
      }

	if ( weapon == currentWeapon )

⌨️ 快捷键说明

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