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

📄 thrall.cpp

📁 this keik game source
💻 CPP
📖 第 1 页 / 共 2 页
字号:
//-----------------------------------------------------------------------------
//
//  $Logfile:: /Quake 2 Engine/Sin/code/game/thrall.cpp                       $
// $Revision:: 12                                                             $
//   $Author:: Aldie                                                          $
//     $Date:: 11/09/98 12:58a                                                $
//
// Copyright (C) 1998 by Ritual Entertainment, Inc.
// All rights reserved.
//
// This source is may not be distributed and/or modified without
// expressly written permission by Ritual Entertainment, Inc.
//
// $Log:: /Quake 2 Engine/Sin/code/game/thrall.cpp                            $
// 
// 12    11/09/98 12:58a Aldie
// Parentmode for death sequence
// 
// 11    11/08/98 8:30p Aldie
// Added gibfest for thrall
// 
// 10    10/27/98 10:17p Jimdose
// better aiming by walls
// more damage from pulse
// precached models
// 
// 9     10/27/98 5:22p Jimdose
// tweaked him
// 
// 8     10/27/98 5:55a Jimdose
// added Chatter
// 
// 7     10/27/98 4:55a Jimdose
// NULLed out EV_FadeOut response so that Thrall sticks around
// 
// 6     10/27/98 3:52a Jimdose
// got pulse weapon working
// 
// 5     10/26/98 2:50p Aldie
// Fixed a bug with checking of NULL owners
// 
// 4     10/24/98 3:33a Jimdose
// changed refrences to origin to worldorigin
// 
// 3     10/24/98 12:51a Aldie
// Fixed init bug
// 
// 2     10/23/98 5:37a Jimdose
// Created file
// 
// 1     10/22/98 10:19p Jimdose
// 
// DESCRIPTION:
// ThrallMaster
// 

#include "g_local.h"
#include "actor.h"
#include "thrall.h"
#include "explosion.h"
#include "vehicle.h"
#include "object.h"
#include "gibs.h"

#define DRUNKMISSILE_SPEED 1000.0f

Event EV_ThrallMaster_FirePulse( "firepulse" );
Event EV_ThrallMaster_FireRockets( "firerockets" );
Event EV_ThrallMaster_GibFest( "gibfest" );

CLASS_DECLARATION( Actor, ThrallMaster, "boss_thrallmaster" );

ResponseDef ThrallMaster::Responses[] =
	{
      { &EV_ThrallMaster_FirePulse,     ( Response )ThrallMaster::FirePulse },
      { &EV_ThrallMaster_FireRockets,   ( Response )ThrallMaster::FireRockets },
      { &EV_Sentient_WeaponUse,         ( Response )ThrallMaster::WeaponUse },
      { &EV_ThrallMaster_GibFest,       ( Response )ThrallMaster::GibFest },
      { &EV_FadeOut,                    NULL },
		{ NULL, NULL }
	};

ThrallMaster::ThrallMaster()
	{
   modelIndex( "sprites/thrallpulse.spr" );
   modelIndex( "view_genbullet.def" );
   modelIndex( "trocket.def" );
   modelIndex( "thrallfire.def" );

   setModel( "thrall.def" );
   weaponmode = PRIMARY;
   gunbone = "gun";
   flags |= FL_NOION;
	}

Vector ThrallMaster::GunPosition
	(
	void
	)

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

	// get the gun position of the actor
	if ( !gi.GetBoneInfo( edict->s.modelindex, gunbone.c_str(), &groupindex, &tri_num, orient ) )
		{
		// Gun doesn't have a barrel, just return the default
		return worldorigin + gunoffset;
		}

	gi.GetBoneTransform( edict->s.modelindex, groupindex, tri_num, orient, edict->s.anim,
		edict->s.frame, edict->s.scale, trans, offset.vec3() );

	MatrixTransformVector( offset.vec3(), orientation, result.vec3() );
	result += worldorigin;

	return result;
	}

qboolean ThrallMaster::CanShootFrom
	(
	Vector pos,
	Entity *ent,
	qboolean usecurrentangles
	)

	{
   int      mask;
	Vector	delta;
	Vector	start;
	Vector	end;
	float		len;
	trace_t	trace;
	Vehicle	*v;
	Entity	*t;
   Vector   ang;

	if ( !currentWeapon || !WithinDistance( ent, vision_distance ) )
		{
      if (!currentWeapon && !has_melee )
		   return false;
		}

	if ( usecurrentangles )
		{
   	Vector	dir;

      start = pos + GunPosition() - worldorigin;
		end = ent->centroid;
		end.z += ( ent->absmax.z - ent->centroid.z ) * 0.75f;
		delta = end - start;
      ang = delta.toAngles();
      ang.x = -ang.x;
      ang.y = angles.y;
		len = delta.length();
   	ang.AngleVectors( &dir, NULL, NULL );
      dir *= len;
      end = start + dir;
		}
	else
		{
      vec3_t	trans[ 3 ];
      vec3_t	transtemp[ 3 ];
      vec3_t   orient;
      int		groupindex;
      int		tri_num;
	   Vector	offset = vec_zero;
	   Vector	result;

      // endpos
		end = ent->centroid;
		end.z += ( ent->absmax.z - ent->centroid.z ) * 0.75f;

      // get the gun position of the actor
   	if ( !gi.GetBoneInfo( edict->s.modelindex, gunbone.c_str(), &groupindex, &tri_num, orient ) )
		   {
		   // Gun doesn't have a barrel, just return the default
		   result = gunoffset;
		   }
      else
         {
         Vector forward, right, up;

         // get new forward vec
         forward = end - worldorigin;
         forward.z = 0;
         forward.normalize();
         forward.copyTo( trans[ 0 ] );

         // new right vec
         right.x = -forward.y;
         right.y = forward.x;
         right.z = 0;
         right.copyTo( trans[ 1 ] );

         // new up vec
         up.x = 0;
         up.y = 0;
         up.z = 1;
         up.copyTo( trans[ 2 ] );

         gi.GetBoneTransform( edict->s.modelindex, groupindex, tri_num, orient, edict->s.anim,
		      edict->s.frame, edict->s.scale, transtemp, offset.vec3() );

	      MatrixTransformVector( offset.vec3(), trans, result.vec3() );
         }

      start = pos + result;
      delta = end - start;
      len = delta.length();
		}

	// check if we're too far away, or too close
   if ( currentWeapon )
      {
	   if ( ( len > attack_range ) || ( len > currentWeapon->GetMaxRange() ) || ( len < currentWeapon->GetMinRange() ) )
		   {
		   return false;
		   }
      mask = MASK_SHOT;
      }
   else
      {
	   if ( ( len > attack_range ) || ( len > melee_range ) )
		   {
		   return false;
		   }
      mask = MASK_PROJECTILE;
      }

	// shoot past the guy we're shooting at
	end += delta * 4;

	// Check if he's visible
	trace = G_Trace( start, vec_zero, vec_zero, end, this, mask, "Actor::CanShootFrom" );
	if ( trace.startsolid )
		{
		return false;
		}

	// If we hit the guy we wanted, then shoot
	if ( trace.ent == ent->edict )
		{
		return true;
		}

	// if we hit a vehicle, check if the driver is someone we want to hit
	t = trace.ent->entity;
	if ( t && t->isSubclassOf( Vehicle ) )
		{
		v = ( Vehicle * )t;
		if ( ( v->Driver() == ent ) || IsEnemy( v->Driver() ) )
			{
			return true;
			}
		return false;
		}

	// If we hit someone else we don't like, then shoot
	if ( IsEnemy( t ) )
		{
		return true;
		}

	// if we hit something breakable, check if shooting it will
   // let us shoot someone.
	if ( t->isSubclassOf( Shatter ) || 
		t->isSubclassOf( Object ) ||
		t->isSubclassOf( DamageThreshold ) ||
		t->isSubclassOf( ScriptModel ) )
		{
      trace = G_Trace( Vector( trace.endpos ), vec_zero, vec_zero, end, t, mask, "Actor::CanShootFrom 2" );
	   if ( trace.startsolid )
		   {
		   return false;
		   }

	   // If we hit the guy we wanted, then shoot
	   if ( trace.ent == ent->edict )
		   {
		   return true;
		   }

	   // If we hit someone else we don't like, then shoot
	   if ( IsEnemy( trace.ent->entity ) )
		   {
		   return true;
		   }

      // Forget it then
      return false;
		}

	return false;
	}

void ThrallMaster::Chatter
	(
	const char *snd,
	float chance,
	float volume,
	int channel
	)

	{
	if ( chattime > level.time )
		{
		return;
		}

   RandomSound( snd, volume, channel, ATTN_NONE );

	chattime = level.time + 7 + G_Random( 5 );
	}

void ThrallMaster::WeaponUse
   (
   Event *ev
   )

   {
   Sentient::WeaponUse( ev );
   if ( weaponmode == PRIMARY )
      {
      weaponmode = SECONDARY;
      gunbone = "chest";
      }
   else
      {
      weaponmode = PRIMARY;
      gunbone = "gun";
      }
   }

void ThrallMaster::GibFest
   (
   Event *ev
   )

   {
   Vector   pos;
   Gib      *gib1, *gib2;

   if ( sv_gibs->value && !parentmode->value )
      {
      GetBone( "chest", &pos, NULL, NULL, NULL );

      pos += worldorigin;

      gib1 = new Gib( "gib1.def" );
      gib1->setOrigin(pos);
      gib1->worldorigin.copyTo(gib1->edict->s.old_origin);
      gib1->SetVelocity( 1000 );
      gib1->velocity *= 3;
      gib1->edict->s.scale = 3.0;
      gib1->fadesplat = false;

      gib2 = new Gib( "gib2.def" );
      gib2->setOrigin(pos);
      gib2->worldorigin.copyTo(gib2->edict->s.old_origin);
      gib2->SetVelocity( 1000 );
      gib2->velocity *= 3;
      gib2->edict->s.scale = 3.0;
      gib2->fadesplat = false;
      }
   }

void ThrallMaster::FirePulse
	(
	Event *ev
	)

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

void ThrallMaster::FireRockets
	(
	Event *ev
	)

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

CLASS_DECLARATION( Weapon, ThrallGun, NULL );

ResponseDef ThrallGun::Responses[] =
	{
	   { &EV_Weapon_Shoot,        ( Response )ThrallGun::Shoot },
      { &EV_Weapon_SecondaryUse, ( Response )ThrallGun::SecondaryUse },
		{ NULL, NULL }
	};

ThrallGun::ThrallGun()
   {
   SetModels( NULL, "view_genbullet.def" );
	SetAmmo( "Rockets", 1, 10 );
   }

void ThrallGun::Shoot
	(
	Event *ev
	)

	{
	DrunkMissile *missile;
   ThrallPulse *pulse;
	Vector	pos;
	Vector	dir;

	assert( owner );
	if ( !owner )
		{
		return;
		}

   GetMuzzlePosition( &pos, &dir );

   if ( weaponmode == PRIMARY )
      {
	   missile = new DrunkMissile;
	   missile->Setup( owner, pos, dir );
      NextAttack( 0 );
      }
   else
      {
	   pulse = new ThrallPulse;
	   pulse->Setup( owner, pos, dir );
	   NextAttack( 0 );
      }
	}

void ThrallGun::SecondaryUse
   (
   Event *ev
   )

   {
   if ( weaponmode == PRIMARY )
      {
      weaponmode = SECONDARY;
      }
   else
      {
      weaponmode = PRIMARY;
      }
   }


Event EV_DrunkMissile_HeatSeek( "heatseek" );

CLASS_DECLARATION( Projectile, DrunkMissile, NULL );

ResponseDef DrunkMissile::Responses[] =
	{
      { &EV_Touch,                   ( Response )DrunkMissile::Explode },
      { &EV_DrunkMissile_HeatSeek,   ( Response )DrunkMissile::HeatSeek },
		{ NULL, NULL }
	};

EXPORT_FROM_DLL void DrunkMissile::Explode
	(
   Event *ev
	)

	{
	int damg;
	Vector v;
	Entity *other;
   Entity *owner;

   other = ev->GetEntity( 1 );

⌨️ 快捷键说明

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