mirror of
https://github.com/nillerusr/source-engine.git
synced 2026-08-13 20:21:06 +00:00
add hl1,portal,dod source code
This commit is contained in:
@@ -0,0 +1,269 @@
|
||||
//========= Copyright Valve Corporation, All rights reserved. ============//
|
||||
//
|
||||
// Purpose: A volume which bumps portal placement. Keeps a global list loaded in from the map
|
||||
// and provides an interface with which prop_portal can get this list and avoid successfully
|
||||
// creating portals partially inside the volume.
|
||||
//
|
||||
// $NoKeywords: $
|
||||
//======================================================================================//
|
||||
|
||||
#include "cbase.h"
|
||||
#include "triggers.h"
|
||||
#include "portal_player.h"
|
||||
#include "weapon_portalgun.h"
|
||||
#include "prop_portal_shared.h"
|
||||
#include "portal_shareddefs.h"
|
||||
#include "physobj.h"
|
||||
#include "portal/weapon_physcannon.h"
|
||||
#include "model_types.h"
|
||||
#include "rumble_shared.h"
|
||||
|
||||
// memdbgon must be the last include file in a .cpp file!!!
|
||||
#include "tier0/memdbgon.h"
|
||||
|
||||
static char *g_pszPortalNonCleansable[] =
|
||||
{
|
||||
"func_door",
|
||||
"func_door_rotating",
|
||||
"prop_door_rotating",
|
||||
"func_tracktrain",
|
||||
"env_ghostanimating",
|
||||
"physicsshadowclone",
|
||||
"prop_energy_ball",
|
||||
NULL,
|
||||
};
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Purpose: Removes anything that touches it. If the trigger has a targetname,
|
||||
// firing it will toggle state.
|
||||
//-----------------------------------------------------------------------------
|
||||
class CTriggerPortalCleanser : public CBaseTrigger
|
||||
{
|
||||
public:
|
||||
DECLARE_CLASS( CTriggerPortalCleanser, CBaseTrigger );
|
||||
|
||||
void Spawn( void );
|
||||
void Touch( CBaseEntity *pOther );
|
||||
|
||||
DECLARE_DATADESC();
|
||||
|
||||
// Outputs
|
||||
COutputEvent m_OnDissolve;
|
||||
COutputEvent m_OnFizzle;
|
||||
COutputEvent m_OnDissolveBox;
|
||||
};
|
||||
|
||||
BEGIN_DATADESC( CTriggerPortalCleanser )
|
||||
|
||||
// Outputs
|
||||
DEFINE_OUTPUT( m_OnDissolve, "OnDissolve" ),
|
||||
DEFINE_OUTPUT( m_OnFizzle, "OnFizzle" ),
|
||||
DEFINE_OUTPUT( m_OnDissolveBox, "OnDissolveBox" ),
|
||||
|
||||
END_DATADESC()
|
||||
|
||||
|
||||
LINK_ENTITY_TO_CLASS( trigger_portal_cleanser, CTriggerPortalCleanser );
|
||||
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Purpose:
|
||||
//-----------------------------------------------------------------------------
|
||||
void CTriggerPortalCleanser::Spawn( void )
|
||||
{
|
||||
BaseClass::Spawn();
|
||||
InitTrigger();
|
||||
}
|
||||
|
||||
// Creates a base entity with model/physics matching the parameter ent.
|
||||
// Used to avoid higher level functions on a disolving entity, which should be inert
|
||||
// and not react the way it used to (touches, etc).
|
||||
// Uses simple physics entities declared in physobj.cpp
|
||||
CBaseEntity* ConvertToSimpleProp ( CBaseEntity* pEnt )
|
||||
{
|
||||
CBaseEntity *pRetVal = NULL;
|
||||
int modelindex = pEnt->GetModelIndex();
|
||||
const model_t *model = modelinfo->GetModel( modelindex );
|
||||
if ( model && modelinfo->GetModelType(model) == mod_brush )
|
||||
{
|
||||
pRetVal = CreateEntityByName( "simple_physics_brush" );
|
||||
}
|
||||
else
|
||||
{
|
||||
pRetVal = CreateEntityByName( "simple_physics_prop" );
|
||||
}
|
||||
|
||||
pRetVal->KeyValue( "model", STRING(pEnt->GetModelName()) );
|
||||
pRetVal->SetAbsOrigin( pEnt->GetAbsOrigin() );
|
||||
pRetVal->SetAbsAngles( pEnt->GetAbsAngles() );
|
||||
pRetVal->Spawn();
|
||||
pRetVal->VPhysicsInitNormal( SOLID_VPHYSICS, 0, false );
|
||||
|
||||
return pRetVal;
|
||||
}
|
||||
|
||||
|
||||
void CTriggerPortalCleanser::Touch( CBaseEntity *pOther )
|
||||
{
|
||||
if ( !PassesTriggerFilters( pOther ) )
|
||||
return;
|
||||
|
||||
if ( pOther->IsPlayer() )
|
||||
{
|
||||
CPortal_Player *pPlayer = ToPortalPlayer( pOther );
|
||||
|
||||
if ( pPlayer )
|
||||
{
|
||||
CWeaponPortalgun *pPortalgun = dynamic_cast<CWeaponPortalgun*>( pPlayer->Weapon_OwnsThisType( "weapon_portalgun" ) );
|
||||
|
||||
if ( pPortalgun )
|
||||
{
|
||||
bool bFizzledPortal = false;
|
||||
|
||||
if ( pPortalgun->CanFirePortal1() )
|
||||
{
|
||||
CProp_Portal *pPortal = CProp_Portal::FindPortal( pPortalgun->m_iPortalLinkageGroupID, false );
|
||||
|
||||
if ( pPortal && pPortal->m_bActivated )
|
||||
{
|
||||
pPortal->DoFizzleEffect( PORTAL_FIZZLE_KILLED, false );
|
||||
pPortal->Fizzle();
|
||||
// HACK HACK! Used to make the gun visually change when going through a cleanser!
|
||||
pPortalgun->m_fEffectsMaxSize1 = 50.0f;
|
||||
|
||||
bFizzledPortal = true;
|
||||
}
|
||||
|
||||
// Cancel portals that are still mid flight
|
||||
if ( pPortal && pPortal->GetNextThink( s_pDelayedPlacementContext ) > gpGlobals->curtime )
|
||||
{
|
||||
pPortal->SetContextThink( NULL, gpGlobals->curtime, s_pDelayedPlacementContext );
|
||||
pPortalgun->m_fEffectsMaxSize2 = 50.0f;
|
||||
bFizzledPortal = true;
|
||||
}
|
||||
}
|
||||
|
||||
if ( pPortalgun->CanFirePortal2() )
|
||||
{
|
||||
CProp_Portal *pPortal = CProp_Portal::FindPortal( pPortalgun->m_iPortalLinkageGroupID, true );
|
||||
|
||||
if ( pPortal && pPortal->m_bActivated )
|
||||
{
|
||||
pPortal->DoFizzleEffect( PORTAL_FIZZLE_KILLED, false );
|
||||
pPortal->Fizzle();
|
||||
// HACK HACK! Used to make the gun visually change when going through a cleanser!
|
||||
pPortalgun->m_fEffectsMaxSize2 = 50.0f;
|
||||
|
||||
bFizzledPortal = true;
|
||||
}
|
||||
|
||||
// Cancel portals that are still mid flight
|
||||
if ( pPortal && pPortal->GetNextThink( s_pDelayedPlacementContext ) > gpGlobals->curtime )
|
||||
{
|
||||
pPortal->SetContextThink( NULL, gpGlobals->curtime, s_pDelayedPlacementContext );
|
||||
pPortalgun->m_fEffectsMaxSize2 = 50.0f;
|
||||
bFizzledPortal = true;
|
||||
}
|
||||
}
|
||||
|
||||
if ( bFizzledPortal )
|
||||
{
|
||||
pPortalgun->SendWeaponAnim( ACT_VM_FIZZLE );
|
||||
pPortalgun->SetLastFiredPortal( 0 );
|
||||
m_OnFizzle.FireOutput( pOther, this );
|
||||
pPlayer->RumbleEffect( RUMBLE_RPG_MISSILE, 0, RUMBLE_FLAG_RESTART );
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
CBaseAnimating *pBaseAnimating = dynamic_cast<CBaseAnimating*>( pOther );
|
||||
|
||||
if ( pBaseAnimating && !pBaseAnimating->IsDissolving() )
|
||||
{
|
||||
int i = 0;
|
||||
|
||||
while ( g_pszPortalNonCleansable[ i ] )
|
||||
{
|
||||
if ( FClassnameIs( pBaseAnimating, g_pszPortalNonCleansable[ i ] ) )
|
||||
{
|
||||
// Don't dissolve non cleansable objects
|
||||
return;
|
||||
}
|
||||
|
||||
++i;
|
||||
}
|
||||
|
||||
// The portal weight box, used for puzzles in the portal mod is differentiated by its name
|
||||
// always being 'box'. We use special logic when the cleanser dissolves a box so this is a special output for it.
|
||||
if ( pBaseAnimating->NameMatches( "box" ) )
|
||||
{
|
||||
m_OnDissolveBox.FireOutput( pOther, this );
|
||||
}
|
||||
|
||||
if ( FClassnameIs( pBaseAnimating, "updateitem2" ) )
|
||||
{
|
||||
pBaseAnimating->EmitSound( "UpdateItem.Fizzle" );
|
||||
}
|
||||
|
||||
Vector vOldVel;
|
||||
AngularImpulse vOldAng;
|
||||
pBaseAnimating->GetVelocity( &vOldVel, &vOldAng );
|
||||
|
||||
IPhysicsObject* pOldPhys = pBaseAnimating->VPhysicsGetObject();
|
||||
|
||||
if ( pOldPhys && ( pOldPhys->GetGameFlags() & FVPHYSICS_PLAYER_HELD ) )
|
||||
{
|
||||
CPortal_Player *pPlayer = (CPortal_Player *)GetPlayerHoldingEntity( pBaseAnimating );
|
||||
if( pPlayer )
|
||||
{
|
||||
// Modify the velocity for held objects so it gets away from the player
|
||||
pPlayer->ForceDropOfCarriedPhysObjects( pBaseAnimating );
|
||||
|
||||
pPlayer->GetAbsVelocity();
|
||||
vOldVel = pPlayer->GetAbsVelocity() + Vector( pPlayer->EyeDirection2D().x * 4.0f, pPlayer->EyeDirection2D().y * 4.0f, -32.0f );
|
||||
}
|
||||
}
|
||||
|
||||
// Swap object with an disolving physics model to avoid touch logic
|
||||
CBaseEntity *pDisolvingObj = ConvertToSimpleProp( pBaseAnimating );
|
||||
if ( pDisolvingObj )
|
||||
{
|
||||
// Remove old prop, transfer name and children to the new simple prop
|
||||
pDisolvingObj->SetName( pBaseAnimating->GetEntityName() );
|
||||
UTIL_TransferPoseParameters( pBaseAnimating, pDisolvingObj );
|
||||
TransferChildren( pBaseAnimating, pDisolvingObj );
|
||||
pDisolvingObj->SetCollisionGroup( COLLISION_GROUP_INTERACTIVE_DEBRIS );
|
||||
pBaseAnimating->AddSolidFlags( FSOLID_NOT_SOLID );
|
||||
pBaseAnimating->AddEffects( EF_NODRAW );
|
||||
|
||||
IPhysicsObject* pPhys = pDisolvingObj->VPhysicsGetObject();
|
||||
if ( pPhys )
|
||||
{
|
||||
pPhys->EnableGravity( false );
|
||||
|
||||
Vector vVel = vOldVel;
|
||||
AngularImpulse vAng = vOldAng;
|
||||
|
||||
// Disolving hurts, damp and blur the motion a little
|
||||
vVel *= 0.5f;
|
||||
vAng.z += 20.0f;
|
||||
|
||||
pPhys->SetVelocity( &vVel, &vAng );
|
||||
}
|
||||
|
||||
pBaseAnimating->AddFlag( FL_DISSOLVING );
|
||||
UTIL_Remove( pBaseAnimating );
|
||||
}
|
||||
|
||||
CBaseAnimating *pDisolvingAnimating = dynamic_cast<CBaseAnimating*>( pDisolvingObj );
|
||||
if ( pDisolvingAnimating )
|
||||
{
|
||||
pDisolvingAnimating->Dissolve( "", gpGlobals->curtime, false, ENTITY_DISSOLVE_NORMAL );
|
||||
}
|
||||
|
||||
m_OnDissolve.FireOutput( pOther, this );
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user