|
|
|
/***
|
|
|
|
*
|
|
|
|
* Copyright (c) 1996-2001, Valve LLC. All rights reserved.
|
|
|
|
*
|
|
|
|
* This product contains software technology licensed from Id
|
|
|
|
* Software, Inc. ("Id Technology"). Id Technology (c) 1996 Id Software, Inc.
|
|
|
|
* All Rights Reserved.
|
|
|
|
*
|
|
|
|
* Use, distribution, and modification of this source code and/or resulting
|
|
|
|
* object code is restricted to non-commercial enhancements to products from
|
|
|
|
* Valve LLC. All other use, distribution, or modification is prohibited
|
|
|
|
* without written permission from Valve LLC.
|
|
|
|
*
|
|
|
|
****/
|
|
|
|
|
|
|
|
#include "extdll.h"
|
|
|
|
#include "util.h"
|
|
|
|
#include "cbase.h"
|
|
|
|
#include "monsters.h"
|
|
|
|
#include "weapons.h"
|
|
|
|
#include "nodes.h"
|
|
|
|
#include "player.h"
|
|
|
|
#include "gamerules.h"
|
|
|
|
#include "grapple_tonguetip.h"
|
|
|
|
|
|
|
|
LINK_ENTITY_TO_CLASS( grapple_tip, CBarnacleGrappleTip )
|
|
|
|
|
|
|
|
void CBarnacleGrappleTip::Precache()
|
|
|
|
{
|
|
|
|
PRECACHE_MODEL( "models/shock_effect.mdl" );
|
|
|
|
}
|
|
|
|
|
|
|
|
void CBarnacleGrappleTip::Spawn()
|
|
|
|
{
|
|
|
|
Precache();
|
|
|
|
|
|
|
|
pev->movetype = MOVETYPE_FLY;
|
|
|
|
pev->solid = SOLID_BBOX;
|
|
|
|
|
|
|
|
SET_MODEL( ENT(pev), "models/shock_effect.mdl" );
|
|
|
|
|
|
|
|
UTIL_SetSize( pev, Vector(0, 0, 0), Vector(0, 0, 0) );
|
|
|
|
|
|
|
|
UTIL_SetOrigin( pev, pev->origin );
|
|
|
|
|
|
|
|
SetThink( &CBarnacleGrappleTip::FlyThink );
|
|
|
|
SetTouch( &CBarnacleGrappleTip::TongueTouch );
|
|
|
|
|
|
|
|
Vector vecAngles = pev->angles;
|
|
|
|
|
|
|
|
vecAngles.x -= 30.0;
|
|
|
|
|
|
|
|
pev->angles = vecAngles;
|
|
|
|
|
|
|
|
UTIL_MakeVectors( pev->angles );
|
|
|
|
|
|
|
|
vecAngles.x = -( 30.0 + vecAngles.x );
|
|
|
|
|
|
|
|
pev->velocity = g_vecZero;
|
|
|
|
|
|
|
|
pev->gravity = 1.0;
|
|
|
|
|
|
|
|
pev->nextthink = gpGlobals->time + 0.02;
|
|
|
|
|
|
|
|
m_bIsStuck = FALSE;
|
|
|
|
m_bMissed = FALSE;
|
|
|
|
}
|
|
|
|
|
|
|
|
void CBarnacleGrappleTip::FlyThink()
|
|
|
|
{
|
|
|
|
UTIL_MakeAimVectors( pev->angles );
|
|
|
|
|
|
|
|
pev->angles = UTIL_VecToAngles( gpGlobals->v_forward );
|
|
|
|
|
|
|
|
const float flNewVel = ( ( pev->velocity.Length() * 0.8 ) + 400.0 );
|
|
|
|
|
|
|
|
pev->velocity = pev->velocity * 0.2 + ( flNewVel * gpGlobals->v_forward );
|
|
|
|
|
|
|
|
if( !g_pGameRules->IsMultiplayer() )
|
|
|
|
{
|
|
|
|
//Note: the old grapple had a maximum velocity of 1600. - Solokiller
|
|
|
|
if( pev->velocity.Length() > 750.0 )
|
|
|
|
{
|
|
|
|
pev->velocity = pev->velocity.Normalize() * 750.0;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
//TODO: should probably clamp at sv_maxvelocity to prevent the tip from going off course. - Solokiller
|
|
|
|
if( pev->velocity.Length() > 2000.0 )
|
|
|
|
{
|
|
|
|
pev->velocity = pev->velocity.Normalize() * 2000.0;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
pev->nextthink = gpGlobals->time + 0.02;
|
|
|
|
}
|
|
|
|
|
|
|
|
void CBarnacleGrappleTip::OffsetThink()
|
|
|
|
{
|
|
|
|
//Nothing
|
|
|
|
}
|
|
|
|
|
|
|
|
void CBarnacleGrappleTip::TongueTouch( CBaseEntity* pOther )
|
|
|
|
{
|
|
|
|
if( !pOther )
|
|
|
|
{
|
|
|
|
targetClass = GRAPPLE_NOT_A_TARGET;
|
|
|
|
m_bMissed = TRUE;
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
if( pOther->IsPlayer() )
|
|
|
|
{
|
|
|
|
targetClass = GRAPPLE_MEDIUM;
|
|
|
|
|
|
|
|
m_hGrappleTarget = pOther;
|
|
|
|
|
|
|
|
m_bIsStuck = TRUE;
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
targetClass = CheckTarget( pOther );
|
|
|
|
|
|
|
|
if( targetClass != GRAPPLE_NOT_A_TARGET )
|
|
|
|
{
|
|
|
|
m_bIsStuck = TRUE;
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
m_bMissed = TRUE;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
pev->velocity = g_vecZero;
|
|
|
|
|
|
|
|
m_GrappleType = targetClass;
|
|
|
|
|
|
|
|
SetThink( &CBarnacleGrappleTip::OffsetThink );
|
|
|
|
pev->nextthink = gpGlobals->time + 0.02;
|
|
|
|
|
|
|
|
SetTouch( NULL );
|
|
|
|
}
|
|
|
|
|
|
|
|
int CBarnacleGrappleTip::CheckTarget( CBaseEntity* pTarget )
|
|
|
|
{
|
|
|
|
if( !pTarget )
|
|
|
|
return GRAPPLE_NOT_A_TARGET;
|
|
|
|
|
|
|
|
if( pTarget->IsPlayer() )
|
|
|
|
{
|
|
|
|
m_hGrappleTarget = pTarget;
|
|
|
|
|
|
|
|
return pTarget->SizeForGrapple();
|
|
|
|
}
|
|
|
|
|
|
|
|
Vector vecStart = pev->origin;
|
|
|
|
Vector vecEnd = pev->origin + pev->velocity * 1024.0;
|
|
|
|
|
|
|
|
TraceResult tr;
|
|
|
|
|
|
|
|
UTIL_TraceLine( vecStart, vecEnd, ignore_monsters, edict(), &tr );
|
|
|
|
|
|
|
|
CBaseEntity* pHit = Instance( tr.pHit );
|
|
|
|
|
|
|
|
/* if( !pHit )
|
|
|
|
pHit = CWorld::GetInstance();*/
|
|
|
|
|
|
|
|
float rgfl1[3];
|
|
|
|
float rgfl2[3];
|
|
|
|
const char *pTexture;
|
|
|
|
|
|
|
|
vecStart.CopyToArray(rgfl1);
|
|
|
|
vecEnd.CopyToArray(rgfl2);
|
|
|
|
|
|
|
|
if (pHit)
|
|
|
|
pTexture = TRACE_TEXTURE(ENT(pHit->pev), rgfl1, rgfl2);
|
|
|
|
else
|
|
|
|
pTexture = TRACE_TEXTURE(ENT(0), rgfl1, rgfl2);
|
|
|
|
|
|
|
|
bool bIsFixed = false;
|
|
|
|
|
|
|
|
if( pTexture && strnicmp( pTexture, "xeno_grapple", 12 ) == 0 )
|
|
|
|
{
|
|
|
|
bIsFixed = true;
|
|
|
|
}
|
|
|
|
else if (pTarget->SizeForGrapple() != GRAPPLE_NOT_A_TARGET)
|
|
|
|
{
|
|
|
|
if (pTarget->SizeForGrapple() == GRAPPLE_FIXED) {
|
|
|
|
bIsFixed = true;
|
|
|
|
} else {
|
|
|
|
m_hGrappleTarget = pTarget;
|
|
|
|
m_vecOriginOffset = pev->origin - pTarget->pev->origin;
|
|
|
|
return pTarget->SizeForGrapple();
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
if( bIsFixed )
|
|
|
|
{
|
|
|
|
m_hGrappleTarget = pTarget;
|
|
|
|
m_vecOriginOffset = g_vecZero;
|
|
|
|
|
|
|
|
return GRAPPLE_FIXED;
|
|
|
|
}
|
|
|
|
|
|
|
|
return GRAPPLE_NOT_A_TARGET;
|
|
|
|
}
|
|
|
|
|
|
|
|
void CBarnacleGrappleTip::SetPosition( Vector vecOrigin, Vector vecAngles, CBaseEntity* pOwner )
|
|
|
|
{
|
|
|
|
UTIL_SetOrigin( pev, vecOrigin );
|
|
|
|
pev->angles = vecAngles;
|
|
|
|
pev->owner = pOwner->edict();
|
|
|
|
}
|