mirror of
https://github.com/mapbase-source/source-sdk-2013.git
synced 2025-01-27 14:17:59 +03:00
Added support for NPC door opening activities and adjustable open distance
This commit is contained in:
parent
97a6934061
commit
0ce4251ba3
@ -103,6 +103,12 @@ protected:
|
||||
|
||||
inline CBaseEntity *GetActivator();
|
||||
|
||||
#ifdef MAPBASE
|
||||
inline float GetNPCOpenDistance() { return m_flNPCOpenDistance; }
|
||||
inline Activity GetNPCOpenFrontActivity() { return m_eNPCOpenFrontActivity; }
|
||||
inline Activity GetNPCOpenBackActivity() { return m_eNPCOpenBackActivity; }
|
||||
#endif
|
||||
|
||||
private:
|
||||
|
||||
// Implement these in your leaf class.
|
||||
@ -196,6 +202,12 @@ private:
|
||||
string_t m_SoundOpen;
|
||||
string_t m_SoundClose;
|
||||
|
||||
#ifdef MAPBASE
|
||||
float m_flNPCOpenDistance;
|
||||
Activity m_eNPCOpenFrontActivity;
|
||||
Activity m_eNPCOpenBackActivity;
|
||||
#endif
|
||||
|
||||
// dvs: FIXME: can we remove m_flSpeed from CBaseEntity?
|
||||
//float m_flSpeed; // Rotation speed when opening or closing in degrees per second.
|
||||
|
||||
|
@ -9763,7 +9763,11 @@ void CAI_BaseNPC::HandleAnimEvent( animevent_t *pEvent )
|
||||
|
||||
case NPC_EVENT_OPEN_DOOR:
|
||||
{
|
||||
#ifdef MAPBASE
|
||||
CBasePropDoor *pDoor = m_hOpeningDoor;
|
||||
#else
|
||||
CBasePropDoor *pDoor = (CBasePropDoor *)(CBaseEntity *)GetNavigator()->GetPath()->GetCurWaypoint()->GetEHandleData();
|
||||
#endif
|
||||
if (pDoor != NULL)
|
||||
{
|
||||
OpenPropDoorNow( pDoor );
|
||||
@ -13951,6 +13955,10 @@ bool CAI_BaseNPC::OnUpcomingPropDoor( AILocalMoveGoal_t *pMoveGoal,
|
||||
|
||||
GetNavigator()->GetPath()->PrependWaypoints( pOpenDoorRoute );
|
||||
|
||||
#ifdef MAPBASE
|
||||
GetNavigator()->SetArrivalDirection( opendata.vecFaceDir );
|
||||
#endif
|
||||
|
||||
m_hOpeningDoor = pDoor;
|
||||
pMoveGoal->maxDist = distClear;
|
||||
*pResult = AIMR_CHANGE_TYPE;
|
||||
@ -13971,6 +13979,21 @@ bool CAI_BaseNPC::OnUpcomingPropDoor( AILocalMoveGoal_t *pMoveGoal,
|
||||
//-----------------------------------------------------------------------------
|
||||
void CAI_BaseNPC::OpenPropDoorBegin( CBasePropDoor *pDoor )
|
||||
{
|
||||
#ifdef MAPBASE
|
||||
opendata_t opendata;
|
||||
pDoor->GetNPCOpenData(this, opendata);
|
||||
|
||||
if (HaveSequenceForActivity( opendata.eActivity ))
|
||||
{
|
||||
int iLayer = AddGesture( opendata.eActivity );
|
||||
float flDuration = GetLayerDuration( iLayer );
|
||||
|
||||
// Face the door and wait for the activity to finish before trying to move through the doorway.
|
||||
m_flMoveWaitFinished = gpGlobals->curtime + flDuration + pDoor->GetOpenInterval();
|
||||
AddFacingTarget( opendata.vecFaceDir, 1.0, flDuration );
|
||||
}
|
||||
else
|
||||
#else
|
||||
// dvs: not quite working, disabled for now.
|
||||
//opendata_t opendata;
|
||||
//pDoor->GetNPCOpenData(this, opendata);
|
||||
@ -13980,6 +14003,7 @@ void CAI_BaseNPC::OpenPropDoorBegin( CBasePropDoor *pDoor )
|
||||
// SetIdealActivity(opendata.eActivity);
|
||||
//}
|
||||
//else
|
||||
#endif
|
||||
{
|
||||
// We don't have an appropriate sequence, just open the door magically.
|
||||
OpenPropDoorNow( pDoor );
|
||||
@ -13999,6 +14023,15 @@ void CAI_BaseNPC::OpenPropDoorNow( CBasePropDoor *pDoor )
|
||||
|
||||
// Wait for the door to finish opening before trying to move through the doorway.
|
||||
m_flMoveWaitFinished = gpGlobals->curtime + pDoor->GetOpenInterval();
|
||||
|
||||
#ifdef MAPBASE
|
||||
// Remove the door from our waypoint
|
||||
if (GetNavigator()->GetPath() && GetNavigator()->GetCurWaypointFlags() & bits_WP_TO_DOOR)
|
||||
{
|
||||
GetNavigator()->GetPath()->GetCurWaypoint()->ModifyFlags( bits_WP_TO_DOOR, false );
|
||||
GetNavigator()->GetPath()->GetCurWaypoint()->m_hData = NULL;
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
|
||||
|
@ -2184,11 +2184,26 @@ bool CAI_Navigator::OnMoveBlocked( AIMoveResult_t *pResult )
|
||||
if (pDoor != NULL)
|
||||
{
|
||||
GetOuter()->OpenPropDoorBegin( pDoor );
|
||||
#ifdef MAPBASE
|
||||
// Tell the navigation to stop running until we're done.
|
||||
OnNewGoal();
|
||||
#endif
|
||||
*pResult = AIMR_OK;
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
#ifdef MAPBASE
|
||||
if ( GetOuter()->m_hOpeningDoor )
|
||||
{
|
||||
// In the process of opening a door
|
||||
// Because navigation is now supposed to terminate when a NPC begins opening a door, this code should not be reached.
|
||||
DbgNavMsg( GetOuter(), "CAI_Navigator::OnMoveBlocked had to check for m_hOpeningDoor\n" );
|
||||
*pResult = AIMR_OK;
|
||||
return true;
|
||||
}
|
||||
#endif
|
||||
|
||||
|
||||
// Allow the NPC to override this behavior
|
||||
if ( GetOuter()->OnMoveBlocked( pResult ))
|
||||
@ -2719,6 +2734,11 @@ void CAI_Navigator::AdvancePath()
|
||||
if (pDoor != NULL)
|
||||
{
|
||||
GetOuter()->OpenPropDoorBegin(pDoor);
|
||||
|
||||
#ifdef MAPBASE
|
||||
// Tell the navigation to stop running until we're done.
|
||||
OnNewGoal();
|
||||
#endif
|
||||
}
|
||||
else
|
||||
{
|
||||
|
@ -4099,6 +4099,11 @@ BEGIN_DATADESC(CBasePropDoor)
|
||||
DEFINE_KEYFIELD(m_SoundClose, FIELD_SOUNDNAME, "soundcloseoverride"),
|
||||
DEFINE_KEYFIELD(m_ls.sLockedSound, FIELD_SOUNDNAME, "soundlockedoverride"),
|
||||
DEFINE_KEYFIELD(m_ls.sUnlockedSound, FIELD_SOUNDNAME, "soundunlockedoverride"),
|
||||
#ifdef MAPBASE
|
||||
DEFINE_KEYFIELD(m_flNPCOpenDistance, FIELD_FLOAT, "opendistoverride"),
|
||||
DEFINE_KEYFIELD(m_eNPCOpenFrontActivity, FIELD_INTEGER, "openfrontactivityoverride"),
|
||||
DEFINE_KEYFIELD(m_eNPCOpenBackActivity, FIELD_INTEGER, "openbackactivityoverride"),
|
||||
#endif
|
||||
DEFINE_KEYFIELD(m_SlaveName, FIELD_STRING, "slavename" ),
|
||||
DEFINE_FIELD(m_bLocked, FIELD_BOOLEAN),
|
||||
//DEFINE_KEYFIELD(m_flBlockDamage, FIELD_FLOAT, "dmg"),
|
||||
@ -4143,6 +4148,11 @@ END_SEND_TABLE()
|
||||
CBasePropDoor::CBasePropDoor( void )
|
||||
{
|
||||
m_hMaster = NULL;
|
||||
#ifdef MAPBASE
|
||||
m_flNPCOpenDistance = -1;
|
||||
m_eNPCOpenFrontActivity = ACT_INVALID;
|
||||
m_eNPCOpenBackActivity = ACT_INVALID;
|
||||
#endif
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
@ -4340,6 +4350,32 @@ void CBasePropDoor::CalcDoorSounds()
|
||||
{
|
||||
strSoundLocked = AllocPooledString( pkvHardwareData->GetString( "locked" ) );
|
||||
strSoundUnlocked = AllocPooledString( pkvHardwareData->GetString( "unlocked" ) );
|
||||
|
||||
#ifdef MAPBASE
|
||||
if (m_eNPCOpenFrontActivity == ACT_INVALID)
|
||||
{
|
||||
const char *pszActivity = pkvHardwareData->GetString( "activity_front" );
|
||||
if (pszActivity[0] != '\0')
|
||||
{
|
||||
m_eNPCOpenFrontActivity = (Activity)CAI_BaseNPC::GetActivityID( pszActivity );
|
||||
if (m_eNPCOpenFrontActivity == ACT_INVALID)
|
||||
m_eNPCOpenFrontActivity = ActivityList_RegisterPrivateActivity( pszActivity );
|
||||
}
|
||||
}
|
||||
if (m_eNPCOpenBackActivity == ACT_INVALID)
|
||||
{
|
||||
const char *pszActivity = pkvHardwareData->GetString( "activity_back" );
|
||||
if (pszActivity[0] != '\0')
|
||||
{
|
||||
m_eNPCOpenBackActivity = (Activity)CAI_BaseNPC::GetActivityID( pszActivity );
|
||||
if (m_eNPCOpenBackActivity == ACT_INVALID)
|
||||
m_eNPCOpenBackActivity = ActivityList_RegisterPrivateActivity( pszActivity );
|
||||
}
|
||||
}
|
||||
|
||||
if (m_flNPCOpenDistance == -1)
|
||||
m_flNPCOpenDistance = pkvHardwareData->GetFloat( "npc_distance", 32.0 );
|
||||
#endif
|
||||
}
|
||||
|
||||
// If any sounds were missing, try the "defaults" block.
|
||||
@ -5940,6 +5976,11 @@ void CPropDoorRotating::DoorResume( void )
|
||||
AngularMove( m_angGoal, m_flSpeed );
|
||||
}
|
||||
|
||||
#ifdef MAPBASE
|
||||
ConVar ai_door_enable_acts( "ai_door_enable_acts", "1", FCVAR_NONE, "Enables the new door-opening activities." );
|
||||
ConVar ai_door_open_dist_override( "ai_door_open_dist_override", "-1", FCVAR_NONE, "Overrides the distance from a door a NPC has to navigate to in order to open a door." );
|
||||
#endif
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Purpose:
|
||||
// Input : vecMoveDir -
|
||||
@ -5961,20 +6002,37 @@ void CPropDoorRotating::GetNPCOpenData(CAI_BaseNPC *pNPC, opendata_t &opendata)
|
||||
|
||||
Vector vecNPCOrigin = pNPC->GetAbsOrigin();
|
||||
|
||||
#ifdef MAPBASE
|
||||
float flPosOffset = ai_door_open_dist_override.GetFloat() >= 0.0f ? ai_door_open_dist_override.GetFloat() : GetNPCOpenDistance();
|
||||
#else
|
||||
float flPosOffset = 64;
|
||||
#endif
|
||||
|
||||
if (pNPC->GetAbsOrigin().Dot(vecForward) > GetAbsOrigin().Dot(vecForward))
|
||||
{
|
||||
// In front of the door relative to the door's forward vector.
|
||||
opendata.vecStandPos += vecForward * 64;
|
||||
opendata.vecStandPos += vecForward * flPosOffset;
|
||||
opendata.vecFaceDir = -vecForward;
|
||||
#ifdef MAPBASE
|
||||
opendata.eActivity = !ai_door_enable_acts.GetBool() ? ACT_INVALID : GetNPCOpenFrontActivity();
|
||||
#endif
|
||||
}
|
||||
else
|
||||
{
|
||||
// Behind the door relative to the door's forward vector.
|
||||
opendata.vecStandPos -= vecForward * 64;
|
||||
opendata.vecStandPos -= vecForward * flPosOffset;
|
||||
opendata.vecFaceDir = vecForward;
|
||||
#ifdef MAPBASE
|
||||
opendata.eActivity = !ai_door_enable_acts.GetBool() ? ACT_INVALID : GetNPCOpenBackActivity();
|
||||
#endif
|
||||
}
|
||||
|
||||
#ifdef MAPBASE
|
||||
if (opendata.eActivity == ACT_INVALID)
|
||||
opendata.eActivity = ACT_OPEN_DOOR;
|
||||
#else
|
||||
opendata.eActivity = ACT_OPEN_DOOR;
|
||||
#endif
|
||||
}
|
||||
|
||||
|
||||
|
Loading…
x
Reference in New Issue
Block a user