Portable Half-Life SDK. GoldSource and Xash3D. Crossplatform.
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 
 
 
 
 

215 lines
4.3 KiB

/***
*
* 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();
}