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

📄 hl1_npc_hgrunt.cpp

📁 hl2 source code. Do not use it illegal.
💻 CPP
📖 第 1 页 / 共 5 页
字号:
				SetAbsVelocity( vecVel );
			}

			return SCHED_GRUNT_REPEL;
		}
	case SCHED_GRUNT_REPEL_ATTACK:
		{
			Vector vecVel = GetAbsVelocity();
			if ( vecVel.z > -128 )
			{
				vecVel.z -= 32;
				SetAbsVelocity( vecVel );
			}

			return SCHED_GRUNT_REPEL_ATTACK;
		}
	default:
		{
			return BaseClass::TranslateSchedule( scheduleType );
		}
	}
}

//=========================================================
// CHGruntRepel - when triggered, spawns a monster_human_grunt
// repelling down a line.
//=========================================================

class CNPC_HGruntRepel:public CAI_BaseNPC
{
	DECLARE_CLASS( CNPC_HGruntRepel, CAI_BaseNPC );
public:
	void Spawn( void );
	void Precache( void );
	void RepelUse ( CBaseEntity *pActivator, CBaseEntity *pCaller, USE_TYPE useType, float value );
	int m_iSpriteTexture;	// Don't save, precache

	DECLARE_DATADESC();
};

LINK_ENTITY_TO_CLASS( monster_grunt_repel, CNPC_HGruntRepel );



//---------------------------------------------------------
// Save/Restore
//---------------------------------------------------------
BEGIN_DATADESC( CNPC_HGruntRepel )
	DEFINE_USEFUNC( CNPC_HGruntRepel, RepelUse ),
END_DATADESC()

void CNPC_HGruntRepel::Spawn( void )
{
	Precache( );
	SetSolid( SOLID_NONE );

	SetUse( RepelUse );
}

void CNPC_HGruntRepel::Precache( void )
{
	UTIL_PrecacheOther( "monster_human_grunt" );
	m_iSpriteTexture = engine->PrecacheModel( "sprites/rope.vmt" );
}

void CNPC_HGruntRepel::RepelUse ( CBaseEntity *pActivator, CBaseEntity *pCaller, USE_TYPE useType, float value )
{
	trace_t tr;
	UTIL_TraceLine( GetAbsOrigin(), GetAbsOrigin() + Vector( 0, 0, -4096.0), MASK_NPCSOLID, this,COLLISION_GROUP_NONE, &tr);
	
	CBaseEntity *pEntity = Create( "monster_human_grunt", GetAbsOrigin(), GetAbsAngles() );
	CAI_BaseNPC *pGrunt = pEntity->MyNPCPointer( );
	pGrunt->SetMoveType( MOVETYPE_FLY );
	pGrunt->SetAbsVelocity( Vector( 0, 0, random->RandomFloat( -196, -128 ) ) );
	pGrunt->SetActivity( ACT_GLIDE );
	// UNDONE: position?
	pGrunt->m_vecLastPosition = tr.endpos;

	CBeam *pBeam = CBeam::BeamCreate( "sprites/rope.vmt", 10 );
	pBeam->PointEntInit( GetAbsOrigin() + Vector(0,0,112), pGrunt );
	pBeam->SetBeamFlags( FBEAM_SOLID );
	pBeam->SetColor( 255, 255, 255 );
	pBeam->SetThink( SUB_Remove );
	SetNextThink( gpGlobals->curtime + -4096.0 * tr.fraction / pGrunt->GetAbsVelocity().z + 0.5 );

	UTIL_Remove( this );
}


//------------------------------------------------------------------------------
//
// Schedules
//
//------------------------------------------------------------------------------
AI_BEGIN_CUSTOM_NPC( monster_human_grunt, CNPC_HGrunt )

	DECLARE_ACTIVITY( ACT_GRUNT_LAUNCH_GRENADE )
	DECLARE_ACTIVITY( ACT_GRUNT_TOSS_GRENADE )
	DECLARE_ACTIVITY( ACT_GRUNT_MP5_STANDING );
	DECLARE_ACTIVITY( ACT_GRUNT_MP5_CROUCHING );
	DECLARE_ACTIVITY( ACT_GRUNT_SHOTGUN_STANDING );
	DECLARE_ACTIVITY( ACT_GRUNT_SHOTGUN_CROUCHING );

	DECLARE_CONDITION( COND_GRUNT_NOFIRE )
	
	DECLARE_TASK( TASK_GRUNT_FACE_TOSS_DIR )
	DECLARE_TASK( TASK_GRUNT_SPEAK_SENTENCE )
	DECLARE_TASK( TASK_GRUNT_CHECK_FIRE )
		
	DECLARE_SQUADSLOT( SQUAD_SLOT_GRENADE1 )
	DECLARE_SQUADSLOT( SQUAD_SLOT_GRENADE2 )
	DECLARE_SQUADSLOT( SQUAD_SLOT_ENGAGE1 )
	DECLARE_SQUADSLOT( SQUAD_SLOT_ENGAGE2 )

	//=========================================================
	// > SCHED_GRUNT_FAIL
	//=========================================================
	DEFINE_SCHEDULE
	(
		SCHED_GRUNT_FAIL,
	
		"	Tasks"
		"		TASK_STOP_MOVING		0"
		"		TASK_SET_ACTIVITY		ACTIVITY:ACT_IDLE"
		"		TASK_WAIT				0"
		"		TASK_WAIT_PVS			0"
		"	"
		"	Interrupts"
		"		COND_CAN_RANGE_ATTACK1"
		"		COND_CAN_MELEE_ATTACK1"
	)
	
	//=========================================================
	// > SCHED_GRUNT_COMBAT_FAIL
	//=========================================================
	DEFINE_SCHEDULE
	(
		SCHED_GRUNT_COMBAT_FAIL,
	
		"	Tasks"
		"		TASK_STOP_MOVING		0"
		"		TASK_SET_ACTIVITY		ACTIVITY:ACT_IDLE"
		"		TASK_WAIT_FACE_ENEMY	2"
		"		TASK_WAIT_PVS			0"
		"	"
		"	Interrupts"
		"		COND_CAN_RANGE_ATTACK1"
		)
	
	//=========================================================
	// > SCHED_GRUNT_VICTORY_DANCE
	// Victory dance!
	//=========================================================
	DEFINE_SCHEDULE
	(
		SCHED_GRUNT_VICTORY_DANCE,
	
		"	Tasks"
		"		TASK_STOP_MOVING				0"
		"		TASK_FACE_ENEMY					0"
		"		TASK_WAIT						1.5"
		"		TASK_GET_PATH_TO_ENEMY_CORPSE	0"
		"		TASK_WALK_PATH					0"
		"		TASK_WAIT_FOR_MOVEMENT			0"
		"		TASK_FACE_ENEMY					0"
		"		TASK_PLAY_SEQUENCE				ACTIVITY:ACT_VICTORY_DANCE"
		"	"
		"	Interrupts"
		"		COND_NEW_ENEMY"
		"		COND_LIGHT_DAMAGE"
		"		COND_HEAVY_DAMAGE"
	)
	
	//=========================================================
	// > SCHED_GRUNT_ESTABLISH_LINE_OF_FIRE
	// Establish line of fire - move to a position that allows
	// the grunt to attack.
	//=========================================================
	DEFINE_SCHEDULE
	(
		SCHED_GRUNT_ESTABLISH_LINE_OF_FIRE,
	
		"	Tasks"
		"		TASK_SET_FAIL_SCHEDULE		SCHEDULE:SCHED_GRUNT_TAKE_COVER_FROM_ENEMY"
		"		TASK_GET_PATH_TO_ENEMY		0"
		"		TASK_GRUNT_SPEAK_SENTENCE	0"
		"		TASK_RUN_PATH				0"
		"		TASK_WAIT_FOR_MOVEMENT		0"
		"	"
		"	Interrupts"
		"		COND_NEW_ENEMY"
		"		COND_ENEMY_DEAD"
		"		COND_LIGHT_DAMAGE"
		"		COND_HEAVY_DAMAGE"
		"		COND_CAN_RANGE_ATTACK1"
		"		COND_CAN_MELEE_ATTACK1"
		"		COND_CAN_RANGE_ATTACK2"
		"		COND_CAN_MELEE_ATTACK2"
		"		COND_HEAR_DANGER"
	)
	
	//=========================================================
	// > SCHED_GRUNT_FOUND_ENEMY
	// Grunt established sight with an enemy
	// that was hiding from the squad.
	//=========================================================
	DEFINE_SCHEDULE
	(
		SCHED_GRUNT_FOUND_ENEMY,
	
		"	Tasks"
		"		TASK_STOP_MOVING				0"
		"		TASK_FACE_ENEMY					0"
		"		TASK_PLAY_SEQUENCE_FACE_ENEMY	ACTIVITY:ACT_SIGNAL1"
		"	"
		"	Interrupts"
		"		COND_HEAR_DANGER"
	)
	
	
	//=========================================================
	// > SCHED_GRUNT_COMBAT_FACE
	//=========================================================
	DEFINE_SCHEDULE
	(
		SCHED_GRUNT_COMBAT_FACE,
	
		"	Tasks"
		"		TASK_STOP_MOVING		0"
		"		TASK_SET_ACTIVITY		ACTIVITY:ACT_IDLE"
		"		TASK_FACE_ENEMY			0"
		"		TASK_WAIT				1.5"
		"		TASK_SET_SCHEDULE		SCHEDULE:SCHED_GRUNT_SWEEP"
		"	"
		"	Interrupts"
		"		COND_NEW_ENEMY"
		"		COND_ENEMY_DEAD"
		"		COND_CAN_RANGE_ATTACK1"
		"		COND_CAN_RANGE_ATTACK2"
	)
	
	
	//=========================================================
	// > SCHED_GRUNT_SIGNAL_SUPPRESS
	// Suppressing fire - don't stop shooting until the clip is
	// empty or grunt gets hurt.
	//=========================================================
	DEFINE_SCHEDULE
	(
		SCHED_GRUNT_SIGNAL_SUPPRESS,
	
		"	Tasks"
		"		TASK_STOP_MOVING				0"
		"		TASK_FACE_IDEAL					0"
		"		TASK_PLAY_SEQUENCE_FACE_ENEMY	ACTIVITY:ACT_SIGNAL2"
		"		TASK_FACE_ENEMY					0"
		"		TASK_GRUNT_CHECK_FIRE			0"
		"		TASK_RANGE_ATTACK1				0"
		"		TASK_FACE_ENEMY					0"
		"		TASK_GRUNT_CHECK_FIRE			0"
		"		TASK_RANGE_ATTACK1				0"
		"		TASK_FACE_ENEMY					0"
		"		TASK_GRUNT_CHECK_FIRE			0"
		"		TASK_RANGE_ATTACK1				0"
		"		TASK_FACE_ENEMY					0"
		"		TASK_GRUNT_CHECK_FIRE			0"
		"		TASK_RANGE_ATTACK1				0"
		"		TASK_FACE_ENEMY					0"
		"		TASK_GRUNT_CHECK_FIRE			0"
		"		TASK_RANGE_ATTACK1				0"
		"	"
		"	Interrupts"
		"		COND_ENEMY_DEAD"
		"		COND_LIGHT_DAMAGE"
		"		COND_HEAVY_DAMAGE"
		"		COND_GRUNT_NOFIRE"
		"		COND_NO_PRIMARY_AMMO"
		"		COND_HEAR_DANGER"
	)
	
	//=========================================================
	// > SCHED_GRUNT_SUPPRESS
	//=========================================================
	DEFINE_SCHEDULE
	(
		SCHED_GRUNT_SUPPRESS,
	
		"	Tasks"
		"		TASK_STOP_MOVING			0"
		"		TASK_FACE_ENEMY				0"
		"		TASK_GRUNT_CHECK_FIRE		0"
		"		TASK_RANGE_ATTACK1			0"
		"		TASK_FACE_ENEMY				0"
		"		TASK_GRUNT_CHECK_FIRE		0"
		"		TASK_RANGE_ATTACK1			0"
		"		TASK_FACE_ENEMY				0"
		"		TASK_GRUNT_CHECK_FIRE		0"
		"		TASK_RANGE_ATTACK1			0"
		"		TASK_FACE_ENEMY				0"
		"		TASK_GRUNT_CHECK_FIRE		0"
		"		TASK_RANGE_ATTACK1			0"
		"		TASK_FACE_ENEMY				0"
		"		TASK_GRUNT_CHECK_FIRE		0"
		"		TASK_RANGE_ATTACK1			0"
		"	"
		"	Interrupts"
		"		COND_ENEMY_DEAD"
		"		COND_LIGHT_DAMAGE"
		"		COND_HEAVY_DAMAGE"
		"		COND_GRUNT_NOFIRE"
		"		COND_NO_PRIMARY_AMMO"
		"		COND_HEAR_DANGER"
	)
	
	//=========================================================
	// > SCHED_GRUNT_WAIT_IN_COVER
	// grunt wait in cover - we don't allow danger or the ability
	// to attack to break a grunt's run to cover schedule, but
	// when a grunt is in cover, we do want them to attack if they can.
	//=========================================================
	DEFINE_SCHEDULE
	(
		SCHED_GRUNT_WAIT_IN_COVER,
	
		"	Tasks"
		"		TASK_STOP_MOVING		0"
		"		TASK_SET_ACTIVITY		ACTIVITY:ACT_IDLE"
		"		TASK_WAIT_FACE_ENEMY	1"
		"	"
		"	Interrupts"
		"		COND_NEW_ENEMY"
		"		COND_HEAR_DANGER"
		"		COND_CAN_RANGE_ATTACK1"
		"		COND_CAN_RANGE_ATTACK2"
		"		COND_CAN_MELEE_ATTACK1"
		"		COND_CAN_MELEE_ATTACK2"
	)
	
	
	//=========================================================
	// > SCHED_GRUNT_TAKE_COVER
	// !!!BUGBUG - set a decent fail schedule here.
	//=========================================================
	DEFINE_SCHEDULE
	(
		SCHED_GRUNT_TAKE_COVER,
	
		"	Tasks"
		"		TASK_STOP_MOVING			0"
		"		TASK_SET_FAIL_SCHEDULE		SCHEDULE:SCHED_GRUNT_TAKE_COVER_FAILED"
		"		TASK_WAIT					0.2"
		"		TASK_FIND_COVER_FROM_ENEMY	0"
		"		TASK_GRUNT_SPEAK_SENTENCE	0"
		"		TASK_RUN_PATH				0"
		"		TASK_WAIT_FOR_MOVEMENT		0"
		"		TASK_REMEMBER				MEMORY:INCOVER"
		"		TASK_SET_SCHEDULE			SCHEDULE:SCHED_GRUNT_WAIT_IN_COVER"
		"	"
		"	Interrupts"
	)
	
	
	//=========================================================
	// > SCHED_GRUNT_GRENADE_COVER
	// drop grenade then run to cover.
	//=========================================================
	DEFINE_SCHEDULE
	(
		SCHED_GRUNT_GRENADE_COVER,
	
		"	Tasks"
		"		TASK_STOP_MOVING						0"
		"		TASK_FIND_COVER_FROM_ENEMY				99"
		"		TASK_FIND_FAR_NODE_COVER_FROM_ENEMY		384"
		"		TASK_PLAY_SEQUENCE						ACTIVITY:ACT_SPECIAL_ATTACK1"
		"		TASK_CLEAR_MOVE_WAIT					0"
		"		TASK_RUN_PATH							0"
		"		TASK_WAIT_FOR_MOVEMENT					0"
		"		TASK_SET_SCHEDULE						SCHEDULE:SCHED_GRUNT_WAIT_IN_COVER"
		"	"
		"	Interrupts"
	)
		
	//=========================================================
	// > SCHED_GRUNT_TOSS_GRENADE_COVER
	// drop grenade then run to cover.
	//=========================================================
	DEFINE_SCHEDULE
	(
		SCHED_GRUNT_TOSS_GRENADE_COVER,
	
		"	Tasks"
		"		TASK_FACE_ENEMY				0"
		"		TASK_RANGE_ATTACK2			0"
		"		TASK_SET_SCHEDULE			SCHEDULE:SCHED_GRUNT_TAKE_COVER_FROM_ENEMY"
		"	"
		"	Interrupts"
	)
	
	//=========================================================
	// > SCHED_GRUNT_HIDE_RELOAD
	// Grunt reload schedule
	//=========================================================
	DEFINE_SCHEDULE
	(
		SCHED_GRUNT_HIDE_RELOAD,
	
		"	Tasks"
		"		TASK_STOP_MOVING				0"
		"		TASK_SET_FAIL_SCHEDULE			SCHEDULE:SCHED_GRUNT_RELOAD"
		"		TASK_FIND_COVER_FROM_ENEMY		0"
		"		TASK_RUN_PATH					0"
		"		TASK_WAIT_FOR_MOVEMENT			0"
		"		TASK_REMEMBER					MEMORY:INCOVER"
		"		TASK_FACE_ENEMY					0"
		"		TASK_PLAY_SEQUENCE				ACTIVITY:ACT_RELOAD"
		"	"
		"	Interrupts"
		"		COND_HEAVY_DAMAGE"
		"		COND_HEAR_DANGER"
	)
	
	//=========================================================
	// > SCHED_GRUNT_SWEEP
	// Do a turning sweep of the area
	//=========================================================
	DEFINE_SCHEDULE
	(
		SCHED_GRUNT_SWEEP,
	
		"	Tasks"
		"		TASK_TURN_LEFT			179"
		"		TASK_WAIT				1"
		"		TASK_TURN_LEFT			179"
		"		TASK_WAIT				1"
		"	"
		"	Interrupts"
		"		COND_NEW_ENEMY"
		"		COND_LIGHT_DAMAGE"
		"		COND_HEAVY_DAMAGE"
		"		COND_CAN_RANGE_ATTACK1"
		"		COND_CAN_RANGE_ATTACK2"
		"		COND_HEAR_WORLD"
		"		COND_HEAR_DANGER"
		"		COND_HEAR_PLAYER"
	)
	
	//=========================================================
	// > SCHED_GRUNT_RANGE_ATTACK1A
	// primary range attack. Overriden because base class stops attacking when the enemy is occluded.
	// grunt's grenade toss requires the enemy be occluded.
	//=========================================================
	DEFINE_SCHEDULE
	(
		SCHED_GRUNT_RANGE_ATTACK1A,
	
		"	Tasks"
		"		TASK_STOP_MOVING					0"
		"		TASK_PLAY_SEQUENCE_FACE_ENEMY		ACTIVITY:ACT_CROUCH"
		"		TASK_GRUNT_CHECK_FIRE				0"
		"		TASK_RANGE_ATTACK1					0"
		"		TASK_FACE_ENEMY						0"
		"		TASK_GRUNT_CHECK_FIRE				0"
		"		TASK_RANGE_ATTACK1					0"
		"		TASK_FACE_ENEMY						0"
		"		TASK_GRUNT_CHECK_FIRE				0"
		"		TASK_RANGE_ATTA

⌨️ 快捷键说明

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