// --------------------------------------------------------------- // BubbleMod // // AUTHOR // Tyler Lund // // 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( &CFlyingCrowbar::BubbleThink ); pev->nextthink = gpGlobals->time + 0.25; // Set the touch function. SetTouch( &CFlyingCrowbar::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( &CBaseEntity::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 ); }