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

📄 hl1_npc_gargantua.cpp

📁 hl2 source code. Do not use it illegal.
💻 CPP
📖 第 1 页 / 共 3 页
字号:
//=========== (C) Copyright 2000 Valve, L.L.C. All rights reserved. ===========
//
// The copyright to the contents herein is the property of Valve, L.L.C.
// The contents may be used and/or copied only with the written permission of
// Valve, L.L.C., or in accordance with the terms and conditions stipulated in
// the agreement/contract under which the contents have been supplied.
//
// Purpose: Bullseyes act as targets for other NPC's to attack and to trigger
//			events 
//
// $Workfile:     $
// $Date:         $
//
//-----------------------------------------------------------------------------
// $Log: $
//
// $NoKeywords: $
//=============================================================================

#include	"cbase.h"
#include	"beam_shared.h"
#include	"Sprite.h"
#include	"AI_Default.h"
#include	"AI_Task.h"
#include	"AI_Schedule.h"
#include	"AI_Node.h"
#include	"AI_Hull.h"
#include	"AI_Hint.h"
#include	"AI_Route.h"
#include	"hl1_npc_gargantua.h"
#include	"soundent.h"
#include	"game.h"
#include	"NPCEvent.h"
#include	"EntityList.h"
#include	"activitylist.h"
#include	"animation.h"
#include	"basecombatweapon.h"
#include	"IEffects.h"
#include	"vstdlib/random.h"
#include	"engine/IEngineSound.h"
#include	"ammodef.h"
#include	"shake.h"
#include	"decals.h"
#include	"customentity.h"
#include	"particle_smokegrenade.h"
#include	"gib.h"
#include	"func_break.h"


extern short	g_sModelIndexFireball;
int				gGargGibModel;

//=========================================================
// Gargantua Monster
//=========================================================
#define GARG_ATTACKDIST 120.0f

// Garg animation events
#define GARG_AE_SLASH_LEFT			1
//#define GARG_AE_BEAM_ATTACK_RIGHT	2		// No longer used
#define GARG_AE_LEFT_FOOT			3
#define GARG_AE_RIGHT_FOOT			4
#define GARG_AE_STOMP				5
#define GARG_AE_BREATHE				6


// Gargantua is immune to any damage but this
#define GARG_DAMAGE					( DMG_ENERGYBEAM | DMG_CRUSH | DMG_MISSILEDEFENSE | DMG_BLAST )
#define GARG_EYE_SPRITE_NAME		"sprites/gargeye1.vmt"
#define GARG_BEAM_SPRITE_NAME		"sprites/xbeam3.vmt"
#define GARG_BEAM_SPRITE2			"sprites/xbeam3.vmt"
#define GARG_STOMP_SPRITE_NAME		"sprites/gargeye1.vmt"
#define GARG_STOMP_BUZZ_SOUND		"weapons/mine_charge.wav"
#define GARG_FLAME_LENGTH			330
#define GARG_GIB_MODEL				"models/metalplategibs.mdl"

#define ATTN_GARG					( ATTN_NORM )

#define STOMP_SPRITE_COUNT			10


#define ATTACH_EYE					1

ConVar sk_gargantua_health ( "sk_gargantua_health", "800" );
ConVar sk_gargantua_dmg_slash( "sk_gargantua_dmg_slash", "10" );
ConVar sk_gargantua_dmg_fire ( "sk_gargantua_dmg_fire", "3" );
ConVar sk_gargantua_dmg_stomp( "sk_gargantua_dmg_stomp", "50" );

enum
{
	TASK_SOUND_ATTACK = LAST_SHARED_TASK,
	TASK_FLAME_SWEEP,
};

enum
{
	SCHED_GARG_FLAME = LAST_SHARED_SCHEDULE,
	SCHED_GARG_SWIPE,
};

const char *CNPC_Gargantua::pAttackHitSounds[] = 
{
	"zombie/claw_strike1.wav",
	"zombie/claw_strike2.wav",
	"zombie/claw_strike3.wav",
};

const char *CNPC_Gargantua::pBeamAttackSounds[] = 
{
	"garg/gar_flameoff1.wav",
	"garg/gar_flameon1.wav",
	"garg/gar_flamerun1.wav",
};


const char *CNPC_Gargantua::pAttackMissSounds[] = 
{
	"zombie/claw_miss1.wav",
	"zombie/claw_miss2.wav",
};

const char *CNPC_Gargantua::pRicSounds[] = 
{
#if 0
	"weapons/ric1.wav",
	"weapons/ric2.wav",
	"weapons/ric3.wav",
	"weapons/ric4.wav",
	"weapons/ric5.wav",
#else
	"debris/metal4.wav",
	"debris/metal6.wav",
	"weapons/ric4.wav",
	"weapons/ric5.wav",
#endif
};

const char *CNPC_Gargantua::pFootSounds[] = 
{
	"garg/gar_step1.wav",
	"garg/gar_step2.wav",
};


const char *CNPC_Gargantua::pIdleSounds[] = 
{
	"garg/gar_idle1.wav",
	"garg/gar_idle2.wav",
	"garg/gar_idle3.wav",
	"garg/gar_idle4.wav",
	"garg/gar_idle5.wav",
};


const char *CNPC_Gargantua::pAttackSounds[] = 
{
	"garg/gar_attack1.wav",
	"garg/gar_attack2.wav",
	"garg/gar_attack3.wav",
};

const char *CNPC_Gargantua::pAlertSounds[] = 
{
	"garg/gar_alert1.wav",
	"garg/gar_alert2.wav",
	"garg/gar_alert3.wav",
};

const char *CNPC_Gargantua::pPainSounds[] = 
{
	"garg/gar_pain1.wav",
	"garg/gar_pain2.wav",
	"garg/gar_pain3.wav",
};

const char *CNPC_Gargantua::pStompSounds[] = 
{
	"garg/gar_stomp1.wav",
};

const char *CNPC_Gargantua::pBreatheSounds[] = 
{
	"garg/gar_breathe1.wav",
	"garg/gar_breathe2.wav",
	"garg/gar_breathe3.wav",
};

LINK_ENTITY_TO_CLASS( monster_gargantua, CNPC_Gargantua );

BEGIN_DATADESC( CNPC_Gargantua )
	DEFINE_FIELD( CNPC_Gargantua, m_pEyeGlow, FIELD_CLASSPTR  ),
	DEFINE_FIELD( CNPC_Gargantua, m_eyeBrightness, FIELD_INTEGER ),
	DEFINE_FIELD( CNPC_Gargantua, m_seeTime, FIELD_TIME ),
	DEFINE_FIELD( CNPC_Gargantua, m_flameTime, FIELD_TIME ),
	DEFINE_FIELD( CNPC_Gargantua, m_streakTime, FIELD_TIME ),
	DEFINE_ARRAY( CNPC_Gargantua, m_pFlame, FIELD_CLASSPTR, 4 ),
	DEFINE_FIELD( CNPC_Gargantua, m_flameX, FIELD_FLOAT ),
	DEFINE_FIELD( CNPC_Gargantua, m_flameY, FIELD_FLOAT ),
	DEFINE_FIELD( CNPC_Gargantua, m_flDmgTime, FIELD_FLOAT ),
END_DATADESC()

static void MoveToGround( Vector *position, CBaseEntity *ignore, const Vector &mins, const Vector &maxs )
{
	trace_t tr;
	// Find point on floor where enemy would stand at chasePosition
	Vector floor = *position;
	floor.z -= 1024;
	UTIL_TraceHull( *position, floor, mins, maxs, MASK_NPCSOLID, ignore, COLLISION_GROUP_NONE, &tr );
	if ( tr.fraction < 1 )
	{
		position->z = tr.endpos.z;
	}
}

class CStomp : public CBaseEntity
{
	DECLARE_CLASS( CStomp, CBaseEntity );

public:
	void Spawn( void );
	void Think( void );
	static CStomp *StompCreate( Vector &origin, Vector &end, float speed, CBaseEntity* pOwner );

private:
	Vector			m_vecMoveDir;
	float			m_flScale;
	float			m_flSpeed;
	unsigned int	m_uiFramerate;
	float			m_flDmgTime;
	CBaseEntity*	m_pOwner;

// UNDONE: re-use this sprite list instead of creating new ones all the time
//	CSprite		*m_pSprites[ STOMP_SPRITE_COUNT ];
};

LINK_ENTITY_TO_CLASS( garg_stomp, CStomp );
CStomp *CStomp::StompCreate( Vector &origin, Vector &end, float speed, CBaseEntity* pOwner )
{
	CStomp *pStomp = (CStomp*)CreateEntityByName( "garg_stomp" );

	pStomp->SetAbsOrigin( origin );
	Vector dir = (end - origin);
//	pStomp->m_flScale = dir.Length();
	pStomp->m_flScale = 2048;
	pStomp->m_vecMoveDir = dir;
	VectorNormalize( pStomp->m_vecMoveDir );
	pStomp->m_flSpeed = speed;
	pStomp->m_pOwner = pOwner;
	pStomp->Spawn();
	
	return pStomp;

}

void CStomp::Spawn( void )
{
	SetNextThink( gpGlobals->curtime );
	pev->classname = MAKE_STRING("garg_stomp");
	m_flDmgTime = gpGlobals->curtime;

	m_uiFramerate = 30;
//	pev->rendermode = kRenderTransTexture;
//	SetBrightness( 0 );
	CPASAttenuationFilter filter( this );
	enginesound->EmitSound( filter, entindex(), CHAN_VOICE, GARG_STOMP_BUZZ_SOUND, 1.0, ATTN_NORM, 0, PITCH_NORM );

}


#define	STOMP_INTERVAL		0.025

void CStomp::Think( void )
{
	trace_t tr;

	SetNextThink( gpGlobals->curtime + 0.1 );

	// Do damage for this frame
	Vector vecStart = GetAbsOrigin();
	vecStart.z += 30;
	Vector vecEnd = vecStart + (m_vecMoveDir * m_flSpeed * gpGlobals->frametime);

	UTIL_TraceHull( vecStart, vecEnd, Vector(-32, -32, -32), Vector(32, 32, 32), MASK_SOLID, m_pOwner, COLLISION_GROUP_NONE, &tr );
//	NDebugOverlay::Line( vecStart, vecEnd, 0, 255, 0, false, 10.0f );
	
	if ( tr.m_pEnt )
	{
		CBaseEntity *pEntity = tr.m_pEnt;
		CTakeDamageInfo info( this, this, 50, DMG_SONIC );
		CalculateMeleeDamageForce( &info, m_vecMoveDir, tr.endpos );
		pEntity->TakeDamage( info );
	}

	// Accelerate the effect
	m_flSpeed += (gpGlobals->frametime) * m_uiFramerate;
	m_uiFramerate += (gpGlobals->frametime) * 2000;
	
	// Move and spawn trails
	while ( gpGlobals->curtime - m_flDmgTime > STOMP_INTERVAL )
	{
		SetAbsOrigin( GetAbsOrigin() + m_vecMoveDir * m_flSpeed * STOMP_INTERVAL );
		for ( int i = 0; i < 2; i++ )
		{
			CSprite *pSprite = CSprite::SpriteCreate( GARG_STOMP_SPRITE_NAME, GetAbsOrigin(), TRUE );
			if ( pSprite )
			{
				UTIL_TraceLine( GetAbsOrigin(), GetAbsOrigin() - Vector(0,0,500), MASK_SOLID, this, COLLISION_GROUP_NONE, &tr );
				pSprite->SetAbsOrigin( tr.endpos );
//				pSprite->pev->velocity = Vector(RandomFloat(-200,200),RandomFloat(-200,200),175);
				pSprite->SetNextThink( gpGlobals->curtime + 0.3 );
				pSprite->SetThink( &CSprite::SUB_Remove );
				pSprite->SetTransparency( kRenderTransAdd, 255, 255, 255, 255, kRenderFxFadeFast );
			}
			g_pEffects->EnergySplash( tr.endpos, tr.plane.normal );
		}
		m_flDmgTime += STOMP_INTERVAL;
		// Scale has the "life" of this effect
		m_flScale -= STOMP_INTERVAL * m_flSpeed;
		if ( m_flScale <= 0 )
		{
			// Life has run out
			UTIL_Remove(this);
//			STOP_SOUND( edict(), CHAN_BODY, GARG_STOMP_BUZZ_SOUND );
			CPASAttenuationFilter filter( this );
			StopSound( entindex(), CHAN_STATIC, GARG_STOMP_BUZZ_SOUND );

		}

	}
}


//=========================================================================
// Gargantua
//=========================================================================

//=========================================================
// Spawn
//=========================================================
void CNPC_Gargantua::Spawn()
{
	Precache( );

	SetModel( "models/garg.mdl" );

	SetNavType(NAV_GROUND);
	SetSolid( SOLID_BBOX );
	AddSolidFlags( FSOLID_NOT_STANDABLE );
	SetMoveType( MOVETYPE_STEP );

	m_bloodColor		= BLOOD_COLOR_GREEN;
	m_iHealth			= sk_gargantua_health.GetFloat();
	SetViewOffset( Vector ( 0, 0, 96 ) );// taken from mdl file
	m_flFieldOfView		= -0.2;// width of forward view cone ( as a dotproduct result )
	m_NPCState			= NPC_STATE_NONE;

	CapabilitiesAdd( bits_CAP_MOVE_GROUND );
	CapabilitiesAdd( bits_CAP_INNATE_RANGE_ATTACK1 | bits_CAP_INNATE_MELEE_ATTACK1 | bits_CAP_INNATE_MELEE_ATTACK2 );

	SetHullType( HULL_WIDE_HUMAN );
	SetHullSizeNormal();

	m_pEyeGlow = CSprite::SpriteCreate( GARG_EYE_SPRITE_NAME, GetAbsOrigin(), FALSE );
	m_pEyeGlow->SetTransparency( kRenderGlow, 255, 255, 255, 0, kRenderFxNoDissipation );
	m_pEyeGlow->SetAttachment( this, 1 );
	EyeOff();

	m_seeTime = gpGlobals->curtime + 5;
	m_flameTime = gpGlobals->curtime + 2;
		
	NPCInit();

	BaseClass::Spawn();

	Relink();
}

//=========================================================
// Precache - precaches all resources this monster needs
//=========================================================
void CNPC_Gargantua::Precache()
{
	engine->PrecacheModel("models/garg.mdl");
	engine->PrecacheModel( GARG_EYE_SPRITE_NAME );
	engine->PrecacheModel( GARG_BEAM_SPRITE_NAME );
	engine->PrecacheModel( GARG_BEAM_SPRITE2 );
	//gStompSprite = PRECACHE_MODEL( GARG_STOMP_SPRITE_NAME );
	gGargGibModel = engine->PrecacheModel( GARG_GIB_MODEL );
	enginesound->PrecacheSound( GARG_STOMP_BUZZ_SOUND );

	PRECACHE_SOUND_ARRAY(pAttackHitSounds);
	PRECACHE_SOUND_ARRAY(pBeamAttackSounds);
	PRECACHE_SOUND_ARRAY(pAttackMissSounds);
	PRECACHE_SOUND_ARRAY(pRicSounds);

⌨️ 快捷键说明

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