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.

188 lines
6.6 KiB

// ---------------------------------------------------------------
// BubbleMod
//
// AUTHOR
// Tyler Lund <halflife@bubblemod.org>
//
// LICENSE
//
// Permission is granted to anyone to use this software for
// any purpose on any computer system, and to redistribute it
// in any way, subject to the following restrictions:
//
// 1. The author is not responsible for the consequences of
// use of this software, no matter how awful, even if they
// arise from defects in it.
// 2. The origin of this software must not be misrepresented,
// either by explicit claim or by omission.
// 3. Altered versions must be plainly marked as such, and
// must not be misrepresented (by explicit claim or
// omission) as being the original software.
// 3a. It would be nice if I got a copy of your improved
// version sent to halflife@bubblemod.org.
// 4. This notice must not be removed or altered.
//
// ---------------------------------------------------------------
#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 "BMOD_flyingcrowbar.h"
LINK_ENTITY_TO_CLASS( flying_crowbar, CFlyingCrowbar );
void CFlyingCrowbar::Spawn( )
{
Precache( );
// The flying crowbar is MOVETYPE_TOSS, and SOLID_BBOX.
// We want it to be affected by gravity, and hit objects
// within the game.
pev->movetype = MOVETYPE_TOSS;
pev->solid = SOLID_BBOX;
// Use the world crowbar model.
SET_MODEL(ENT(pev), "models/w_crowbar.mdl");
// Set the origin and size for the HL engine collision
// tables.
UTIL_SetOrigin( pev, pev->origin );
UTIL_SetSize(pev, Vector(-4, -4, -4), Vector(4, 4, 4));
// Store the owner for later use. We want the owner to be able
// to hit themselves with the crowbar. The pev->owner gets cleared
// later to avoid hitting the player as they throw the crowbar.
if ( pev->owner )
m_hOwner = Instance( pev->owner );
// Set the think funtion.
SetThink( BubbleThink );
pev->nextthink = gpGlobals->time + 0.25;
// Set the touch function.
SetTouch( SpinTouch );
}
void CFlyingCrowbar::Precache( )
{
PRECACHE_MODEL ("models/w_crowbar.mdl");
PRECACHE_SOUND ("weapons/cbar_hitbod1.wav");
PRECACHE_SOUND ("weapons/cbar_hit1.wav");
PRECACHE_SOUND ("weapons/cbar_miss1.wav");
}
void CFlyingCrowbar::SpinTouch( CBaseEntity *pOther )
{
// We touched something in the game. Look to see if the object
// is allowed to take damage.
if (pOther->pev->takedamage)
{
// Get the traceline info to the target.
TraceResult tr = UTIL_GetGlobalTrace( );
// Apply damage to the target. If we have an owner stored, use that one,
// otherwise count it as self-inflicted.
ClearMultiDamage( );
pOther->TraceAttack(pev, 90, pev->velocity.Normalize(), &tr,
DMG_NEVERGIB );
if (m_hOwner != NULL)
ApplyMultiDamage( pev, m_hOwner->pev );
else
ApplyMultiDamage( pev, pev );
}
// If we hit a player, make a nice squishy thunk sound. Otherwise
// make a clang noise and throw a bunch of sparks.
if (pOther->IsPlayer())
EMIT_SOUND_DYN(ENT(pev), CHAN_WEAPON, "weapons/cbar_hitbod1.wav",
1.0, ATTN_NORM, 0, 100);
else
{
EMIT_SOUND_DYN(ENT(pev), CHAN_WEAPON, "weapons/cbar_hit1.wav",
1.0, ATTN_NORM, 0, 100);
if (UTIL_PointContents(pev->origin) != CONTENTS_WATER)
{
UTIL_Sparks( pev->origin );
UTIL_Sparks( pev->origin );
UTIL_Sparks( pev->origin );
}
}
// Don't draw the flying crowbar anymore.
pev->effects |= EF_NODRAW;
pev->solid = SOLID_NOT;
// Spawn a crowbar weapon
CBasePlayerWeapon *pItem = (CBasePlayerWeapon *)Create( "weapon_crowbar",
pev->origin , pev->angles, edict() );
// Spawn a weapon box
CWeaponBox *pWeaponBox = (CWeaponBox *)CBaseEntity::Create(
"weaponbox", pev->origin, pev->angles, edict() );
// don't let weapon box tilt.
pWeaponBox->pev->angles.x = 0;
pWeaponBox->pev->angles.z = 0;
// remove the weapon box after 4 mins.
pWeaponBox->pev->nextthink = gpGlobals->time + 240;
pWeaponBox->SetThink( CWeaponBox::Kill );
// Pack the crowbar in the weapon box
pWeaponBox->PackWeapon( pItem );
// *** Start BubbleMod Rune code ***
// Check to see if the crowbar rune is active on the owner,
// if it is, then remove this crowbar after 3 seconds
// instead if 2 mins. This prevents too many crowbars from
// piling up on the server.
//
// REMOVE THIS IF YOU ARE NOT USING THE RUNE CODE
if (m_pPlayer->m_RuneFlags == RUNE_CROWBAR)
pWeaponBox->pev->nextthink = gpGlobals->time + 3;
// *** End BubbleMod Rune Code ***
// Get the unit vector in the direction of motion.
Vector vecDir = pev->velocity.Normalize( );
// Trace a line along the velocity vector to get the normal at impact.
TraceResult tr;
UTIL_TraceLine(pev->origin, pev->origin + vecDir * 100,
dont_ignore_monsters, ENT(pev), &tr);
// Throw the weapon box along the normal so it looks kinda
// like a ricochet. This would be better if I actually
// calcualted the reflection angle, but I'm lazy. :)
pWeaponBox->pev->velocity = tr.vecPlaneNormal * 300;
// Remove this flying_crowbar from the world.
SetThink ( SUB_Remove );
pev->nextthink = gpGlobals->time + .1;
}
void CFlyingCrowbar::BubbleThink( void )
{
// We have no owner. We do this .25 seconds AFTER the crowbar
// is thrown so that we don't hit the owner immediately when throwing
// it. If is comes back later, we want to be able to hit the owner.
pev->owner = NULL;
// Only think every .25 seconds.
pev->nextthink = gpGlobals->time + 0.25;
// Make a whooshy sound.
EMIT_SOUND_DYN(ENT(pev), CHAN_VOICE, "weapons/cbar_miss1.wav",
1, ATTN_NORM, 0, 120);
// If the crowbar enters water, make some bubbles.
if (pev->waterlevel)
UTIL_BubbleTrail( pev->origin - pev->velocity * 0.1, pev->origin, 1 );
}