📄 hl1_npc_hgrunt.cpp
字号:
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 + -