aboutsummaryrefslogtreecommitdiff
path: root/mp/src/game/server/hl2/weapon_molotov.cpp
diff options
context:
space:
mode:
authorJørgen P. Tjernø <[email protected]>2013-12-02 19:31:46 -0800
committerJørgen P. Tjernø <[email protected]>2013-12-02 19:46:31 -0800
commitf56bb35301836e56582a575a75864392a0177875 (patch)
treede61ddd39de3e7df52759711950b4c288592f0dc /mp/src/game/server/hl2/weapon_molotov.cpp
parentMark some more files as text. (diff)
downloadsource-sdk-2013-f56bb35301836e56582a575a75864392a0177875.tar.xz
source-sdk-2013-f56bb35301836e56582a575a75864392a0177875.zip
Fix line endings. WHAMMY.
Diffstat (limited to 'mp/src/game/server/hl2/weapon_molotov.cpp')
-rw-r--r--mp/src/game/server/hl2/weapon_molotov.cpp904
1 files changed, 452 insertions, 452 deletions
diff --git a/mp/src/game/server/hl2/weapon_molotov.cpp b/mp/src/game/server/hl2/weapon_molotov.cpp
index 3ecae6a6..a1b6e2e1 100644
--- a/mp/src/game/server/hl2/weapon_molotov.cpp
+++ b/mp/src/game/server/hl2/weapon_molotov.cpp
@@ -1,453 +1,453 @@
-//========= Copyright Valve Corporation, All rights reserved. ============//
-//
-// Purpose: This is the molotov weapon
-//
-// $Workfile: $
-// $Date: $
-// $NoKeywords: $
-//=============================================================================//
-
-#include "cbase.h"
-#include "npcevent.h"
-#include "basehlcombatweapon.h"
-#include "basecombatcharacter.h"
-#include "ai_basenpc.h"
-#include "AI_Memory.h"
-#include "player.h"
-#include "gamerules.h" // For g_pGameRules
-#include "weapon_molotov.h"
-#include "grenade_molotov.h"
-#include "in_buttons.h"
-#include "game.h"
-#include "vstdlib/random.h"
-#include "movevars_shared.h"
-
-// memdbgon must be the last include file in a .cpp file!!!
-#include "tier0/memdbgon.h"
-
-BEGIN_DATADESC( CWeaponMolotov )
-
- DEFINE_FIELD( m_nNumAmmoTypes, FIELD_INTEGER ),
- DEFINE_FIELD( m_bNeedDraw, FIELD_BOOLEAN ),
- DEFINE_FIELD( m_iThrowBits, FIELD_INTEGER ),
- DEFINE_FIELD( m_fNextThrowCheck, FIELD_TIME ),
- DEFINE_FIELD( m_vecTossVelocity, FIELD_VECTOR ),
-
- // Function Pointers
- DEFINE_FUNCTION( MolotovTouch ),
-
-END_DATADESC()
-
-
-IMPLEMENT_SERVERCLASS_ST(CWeaponMolotov, DT_WeaponMolotov)
-END_SEND_TABLE()
-
-LINK_ENTITY_TO_CLASS( weapon_molotov, CWeaponMolotov );
-PRECACHE_WEAPON_REGISTER(weapon_molotov);
-
-acttable_t CWeaponMolotov::m_acttable[] =
-{
- { ACT_RANGE_ATTACK1, ACT_RANGE_ATTACK_THROW, true },
-};
-IMPLEMENT_ACTTABLE(CWeaponMolotov);
-
-
-void CWeaponMolotov::Precache( void )
-{
- PrecacheModel("models/props_junk/w_garb_beerbottle.mdl"); //<<TEMP>> need real model
- BaseClass::Precache();
-}
-
-void CWeaponMolotov::Spawn( void )
-{
- // Call base class first
- BaseClass::Spawn();
-
- m_bNeedDraw = true;
-
- SetModel( GetWorldModel() );
- UTIL_SetSize(this, Vector( -6, -6, -2), Vector(6, 6, 2));
-}
-
-//------------------------------------------------------------------------------
-// Purpose : Override to use molotovs pickup touch function
-// Input :
-// Output :
-//------------------------------------------------------------------------------
-void CWeaponMolotov::SetPickupTouch( void )
-{
- SetTouch(MolotovTouch);
-}
-
-//-----------------------------------------------------------------------------
-// Purpose: Override so give correct ammo
-// Input : pOther - the entity that touched me
-// Output :
-//-----------------------------------------------------------------------------
-void CWeaponMolotov::MolotovTouch( CBaseEntity *pOther )
-{
- // ---------------------------------------------------
- // First give weapon to touching entity if allowed
- // ---------------------------------------------------
- BaseClass::DefaultTouch(pOther);
-
- // ----------------------------------------------------
- // Give molotov ammo if touching client
- // ----------------------------------------------------
- if (pOther->GetFlags() & FL_CLIENT)
- {
- // ------------------------------------------------
- // If already owned weapon of this type remove me
- // ------------------------------------------------
- CBaseCombatCharacter* pBCC = ToBaseCombatCharacter( pOther );
- CWeaponMolotov* oldWeapon = (CWeaponMolotov*)pBCC->Weapon_OwnsThisType( GetClassname() );
- if (oldWeapon != this)
- {
- UTIL_Remove( this );
- }
- else
- {
- pBCC->GiveAmmo( 1, m_iSecondaryAmmoType );
- SetThink (NULL);
- }
- }
-}
-
-//-----------------------------------------------------------------------------
-// Purpose: Gets event from anim stream and throws the object
-// Input :
-// Output :
-//-----------------------------------------------------------------------------
-void CWeaponMolotov::Operator_HandleAnimEvent( animevent_t *pEvent, CBaseCombatCharacter *pOperator )
-{
- switch( pEvent->event )
- {
- case EVENT_WEAPON_THROW:
- {
- CAI_BaseNPC *pNPC = GetOwner()->MyNPCPointer();
- if (!pNPC)
- {
- return;
- }
-
- CBaseEntity *pEnemy = pNPC->GetEnemy();
- if (!pEnemy)
- {
- return;
- }
-
- Vector vec_target = pNPC->GetEnemyLKP();
-
- // -----------------------------------------------------
- // Get position of throw
- // -----------------------------------------------------
- // If owner has a hand, set position to the hand bone position
- Vector launchPos;
- int iBIndex = pNPC->LookupBone("Bip01 R Hand");
- if (iBIndex != -1)
- {
- Vector origin;
- QAngle angles;
- pNPC->GetBonePosition( iBIndex, launchPos, angles);
- }
- // Otherwise just set to in front of the owner
- else
- {
- Vector vFacingDir = pNPC->BodyDirection2D( );
- vFacingDir = vFacingDir * 60.0;
- launchPos = pNPC->GetAbsOrigin()+vFacingDir;
- }
-
-
- //Vector vecVelocity = VecCheckToss( pNPC, launchPos, vec_target, 1.0 );
-
- ThrowMolotov( launchPos, m_vecTossVelocity);
-
- // Drop the weapon and remove as no more ammo
- pNPC->Weapon_Drop( this );
- UTIL_Remove( this );
- }
- break;
- default:
- BaseClass::Operator_HandleAnimEvent( pEvent, pOperator );
- break;
- }
-}
-
-
-//-----------------------------------------------------------------------------
-// Purpose:
-// Input :
-// Output :
-//-----------------------------------------------------------------------------
-bool CWeaponMolotov::ObjectInWay( void )
-{
- CBaseCombatCharacter *pOwner = GetOwner();
- if (!pOwner)
- {
- return false;
- }
-
- Vector vecSrc = pOwner->Weapon_ShootPosition( );
- Vector vecAiming = pOwner->BodyDirection2D( );
-
- trace_t tr;
-
- Vector vecEnd = vecSrc + (vecAiming * 32);
- UTIL_TraceLine( vecSrc, vecEnd, MASK_SOLID, pOwner, COLLISION_GROUP_NONE, &tr );
-
- if (tr.fraction < 1.0)
- {
- // Don't block on a living creature
- if (tr.m_pEnt)
- {
- CBaseEntity *pEntity = tr.m_pEnt;
- CBaseCombatCharacter *pBCC = ToBaseCombatCharacter( pEntity );
- if (pBCC)
- {
- return false;
- }
- }
- return true;
- }
- else
- {
- return false;
- }
-}
-
-//-----------------------------------------------------------------------------
-// Purpose: Override to allow throw w/o LOS
-// Input :
-// Output :
-//-----------------------------------------------------------------------------
-bool CWeaponMolotov::WeaponLOSCondition(const Vector &ownerPos, const Vector &targetPos,bool bSetConditions)
-{
- // <<TODO>> should test if can throw from present location here...
- return true;
-}
-
-//-----------------------------------------------------------------------------
-// Purpose: Override to check throw
-// Input :
-// Output :
-//-----------------------------------------------------------------------------
-int CWeaponMolotov::WeaponRangeAttack1Condition( float flDot, float flDist )
-{
- // If things haven't changed too much since last time
- // just return that previously calculated value
- if (gpGlobals->curtime < m_fNextThrowCheck )
- {
- return m_iThrowBits;
- }
-
- if ( flDist < m_fMinRange1) {
- m_iThrowBits = COND_TOO_CLOSE_TO_ATTACK;
- }
- else if (flDist > m_fMaxRange1) {
- m_iThrowBits = COND_TOO_FAR_TO_ATTACK;
- }
- else if (flDot < 0.5) {
- m_iThrowBits = COND_NOT_FACING_ATTACK;
- }
-
- // If moving, can't throw.
- else if ( m_flGroundSpeed != 0 )
- {
- m_iThrowBits = COND_NONE;
- }
- else {
- // Ok we should check again as some time has passed
- // This function is only used by NPC's so we can cast to a Base Monster
- CAI_BaseNPC *pNPC = GetOwner()->MyNPCPointer();
- CBaseEntity *pEnemy = pNPC->GetEnemy();
-
- if (!pEnemy)
- {
- m_iThrowBits = COND_NONE;
- }
- // Get Enemy Position
- Vector vecTarget;
- pEnemy->CollisionProp()->NormalizedToWorldSpace( Vector( 0.5f, 0.5f, 0.0f ), &vecTarget );
-
- // Get Toss Vector
- Vector throwStart = pNPC->Weapon_ShootPosition();
- Vector vecToss;
- CBaseEntity* pBlocker = NULL;
- float throwDist = (throwStart - vecTarget).Length();
- float fGravity = GetCurrentGravity();
- float throwLimit = pNPC->ThrowLimit(throwStart, vecTarget, fGravity, 35, WorldAlignMins(), WorldAlignMaxs(), pEnemy, &vecToss, &pBlocker);
-
- // If I can make the throw (or most of the throw)
- if (!throwLimit || (throwLimit != throwDist && throwLimit > 0.8*throwDist))
- {
- m_vecTossVelocity = vecToss;
- m_iThrowBits = COND_CAN_RANGE_ATTACK1;
-
- }
- else
- {
- m_iThrowBits = COND_NONE;
- }
-
- }
- // don't check again for a while.
- m_fNextThrowCheck = gpGlobals->curtime + 0.33; // 1/3 second.
-
- return m_iThrowBits;
-}
-
-//-----------------------------------------------------------------------------
-// Purpose:
-//
-//
-//-----------------------------------------------------------------------------
-void CWeaponMolotov::ThrowMolotov( const Vector &vecSrc, const Vector &vecVelocity)
-{
- CGrenade_Molotov *pMolotov = (CGrenade_Molotov*)Create( "grenade_molotov", vecSrc, vec3_angle, GetOwner() );
-
- if (!pMolotov)
- {
- Msg("Couldn't make molotov!\n");
- return;
- }
- pMolotov->SetAbsVelocity( vecVelocity );
-
- // Tumble through the air
- QAngle angVel( random->RandomFloat ( -100, -500 ), random->RandomFloat ( -100, -500 ), random->RandomFloat ( -100, -500 ) );
- pMolotov->SetLocalAngularVelocity( angVel );
-
- pMolotov->SetThrower( GetOwner() );
- pMolotov->SetOwnerEntity( ((CBaseEntity*)GetOwner()) );
-}
-
-//-----------------------------------------------------------------------------
-// Purpose:
-//
-//
-//-----------------------------------------------------------------------------
-void CWeaponMolotov::PrimaryAttack( void )
-{
-
- CBasePlayer *pPlayer = ToBasePlayer( GetOwner() );
-
- if (!pPlayer)
- {
- return;
- }
-
- Vector vecSrc = pPlayer->WorldSpaceCenter();
- Vector vecFacing = pPlayer->BodyDirection3D( );
- vecSrc = vecSrc + vecFacing * 18.0;
- // BUGBUG: is this some hack because it's not at the eye position????
- vecSrc.z += 24.0f;
-
- // Player may have turned to face a wall during the throw anim in which case
- // we don't want to throw the SLAM into the wall
- if (ObjectInWay())
- {
- vecSrc = pPlayer->WorldSpaceCenter() + vecFacing * 5.0;
- }
-
- Vector vecAiming = pPlayer->GetAutoaimVector( AUTOAIM_5DEGREES );
- vecAiming.z += 0.20; // Raise up so passes through reticle
-
- ThrowMolotov(vecSrc, vecAiming*800);
- pPlayer->RemoveAmmo( 1, m_iSecondaryAmmoType );
-
-
- // Don't fire again until fire animation has completed
- //m_flNextPrimaryAttack = gpGlobals->curtime + CurSequenceDuration();
- //<<TEMP>> - till real animation is avaible
- m_flNextPrimaryAttack = gpGlobals->curtime + 1.0;
- m_flNextSecondaryAttack = gpGlobals->curtime + 1.0;
-
- m_bNeedDraw = true;
-}
-
-//-----------------------------------------------------------------------------
-// Purpose:
-//
-//
-//-----------------------------------------------------------------------------
-void CWeaponMolotov::SecondaryAttack( void )
-{
- //<<TEMP>>
- // Hmmm... what should I do here?
-}
-
-//-----------------------------------------------------------------------------
-// Purpose:
-//
-//
-//-----------------------------------------------------------------------------
-void CWeaponMolotov::DrawAmmo( void )
-{
- // -------------------------------------------
- // Make sure I have ammo of the current type
- // -------------------------------------------
- CBaseCombatCharacter *pOwner = GetOwner();
- if (pOwner->GetAmmoCount(m_iSecondaryAmmoType) <=0)
- {
- pOwner->Weapon_Drop( this );
- UTIL_Remove(this);
- return;
- }
- Msg("Drawing Molotov...\n");
- m_bNeedDraw = false;
-
- //<<TEMP>> - till real animation is avaible
- m_flNextPrimaryAttack = gpGlobals->curtime + 2.0;
- m_flNextSecondaryAttack = gpGlobals->curtime + 2.0;
-
-}
-
-//-----------------------------------------------------------------------------
-// Purpose: Override so shotgun can do mulitple reloads in a row
-// Input :
-// Output :
-//-----------------------------------------------------------------------------
-void CWeaponMolotov::ItemPostFrame( void )
-{
- CBasePlayer *pOwner = ToBasePlayer( GetOwner() );
- if (!pOwner)
- {
- return;
- }
-
-
- if ((pOwner->m_nButtons & IN_ATTACK2) && (m_flNextSecondaryAttack <= gpGlobals->curtime))
- {
- SecondaryAttack();
- }
- else if ((pOwner->m_nButtons & IN_ATTACK) && (m_flNextPrimaryAttack <= gpGlobals->curtime))
- {
- // Uses secondary ammo only
- if (pOwner->GetAmmoCount(m_iSecondaryAmmoType))
- {
- PrimaryAttack();
- }
- }
- else if (m_bNeedDraw)
- {
- DrawAmmo();
- }
- else
- {
- WeaponIdle( );
- }
-}
-
-
-//-----------------------------------------------------------------------------
-// Purpose: Constructor
-//-----------------------------------------------------------------------------
-CWeaponMolotov::CWeaponMolotov( void )
-{
-#ifdef _DEBUG
- m_vecTossVelocity.Init();
-#endif
-
- m_fMinRange1 = 200;
- m_fMaxRange1 = 1000;
+//========= Copyright Valve Corporation, All rights reserved. ============//
+//
+// Purpose: This is the molotov weapon
+//
+// $Workfile: $
+// $Date: $
+// $NoKeywords: $
+//=============================================================================//
+
+#include "cbase.h"
+#include "npcevent.h"
+#include "basehlcombatweapon.h"
+#include "basecombatcharacter.h"
+#include "ai_basenpc.h"
+#include "AI_Memory.h"
+#include "player.h"
+#include "gamerules.h" // For g_pGameRules
+#include "weapon_molotov.h"
+#include "grenade_molotov.h"
+#include "in_buttons.h"
+#include "game.h"
+#include "vstdlib/random.h"
+#include "movevars_shared.h"
+
+// memdbgon must be the last include file in a .cpp file!!!
+#include "tier0/memdbgon.h"
+
+BEGIN_DATADESC( CWeaponMolotov )
+
+ DEFINE_FIELD( m_nNumAmmoTypes, FIELD_INTEGER ),
+ DEFINE_FIELD( m_bNeedDraw, FIELD_BOOLEAN ),
+ DEFINE_FIELD( m_iThrowBits, FIELD_INTEGER ),
+ DEFINE_FIELD( m_fNextThrowCheck, FIELD_TIME ),
+ DEFINE_FIELD( m_vecTossVelocity, FIELD_VECTOR ),
+
+ // Function Pointers
+ DEFINE_FUNCTION( MolotovTouch ),
+
+END_DATADESC()
+
+
+IMPLEMENT_SERVERCLASS_ST(CWeaponMolotov, DT_WeaponMolotov)
+END_SEND_TABLE()
+
+LINK_ENTITY_TO_CLASS( weapon_molotov, CWeaponMolotov );
+PRECACHE_WEAPON_REGISTER(weapon_molotov);
+
+acttable_t CWeaponMolotov::m_acttable[] =
+{
+ { ACT_RANGE_ATTACK1, ACT_RANGE_ATTACK_THROW, true },
+};
+IMPLEMENT_ACTTABLE(CWeaponMolotov);
+
+
+void CWeaponMolotov::Precache( void )
+{
+ PrecacheModel("models/props_junk/w_garb_beerbottle.mdl"); //<<TEMP>> need real model
+ BaseClass::Precache();
+}
+
+void CWeaponMolotov::Spawn( void )
+{
+ // Call base class first
+ BaseClass::Spawn();
+
+ m_bNeedDraw = true;
+
+ SetModel( GetWorldModel() );
+ UTIL_SetSize(this, Vector( -6, -6, -2), Vector(6, 6, 2));
+}
+
+//------------------------------------------------------------------------------
+// Purpose : Override to use molotovs pickup touch function
+// Input :
+// Output :
+//------------------------------------------------------------------------------
+void CWeaponMolotov::SetPickupTouch( void )
+{
+ SetTouch(MolotovTouch);
+}
+
+//-----------------------------------------------------------------------------
+// Purpose: Override so give correct ammo
+// Input : pOther - the entity that touched me
+// Output :
+//-----------------------------------------------------------------------------
+void CWeaponMolotov::MolotovTouch( CBaseEntity *pOther )
+{
+ // ---------------------------------------------------
+ // First give weapon to touching entity if allowed
+ // ---------------------------------------------------
+ BaseClass::DefaultTouch(pOther);
+
+ // ----------------------------------------------------
+ // Give molotov ammo if touching client
+ // ----------------------------------------------------
+ if (pOther->GetFlags() & FL_CLIENT)
+ {
+ // ------------------------------------------------
+ // If already owned weapon of this type remove me
+ // ------------------------------------------------
+ CBaseCombatCharacter* pBCC = ToBaseCombatCharacter( pOther );
+ CWeaponMolotov* oldWeapon = (CWeaponMolotov*)pBCC->Weapon_OwnsThisType( GetClassname() );
+ if (oldWeapon != this)
+ {
+ UTIL_Remove( this );
+ }
+ else
+ {
+ pBCC->GiveAmmo( 1, m_iSecondaryAmmoType );
+ SetThink (NULL);
+ }
+ }
+}
+
+//-----------------------------------------------------------------------------
+// Purpose: Gets event from anim stream and throws the object
+// Input :
+// Output :
+//-----------------------------------------------------------------------------
+void CWeaponMolotov::Operator_HandleAnimEvent( animevent_t *pEvent, CBaseCombatCharacter *pOperator )
+{
+ switch( pEvent->event )
+ {
+ case EVENT_WEAPON_THROW:
+ {
+ CAI_BaseNPC *pNPC = GetOwner()->MyNPCPointer();
+ if (!pNPC)
+ {
+ return;
+ }
+
+ CBaseEntity *pEnemy = pNPC->GetEnemy();
+ if (!pEnemy)
+ {
+ return;
+ }
+
+ Vector vec_target = pNPC->GetEnemyLKP();
+
+ // -----------------------------------------------------
+ // Get position of throw
+ // -----------------------------------------------------
+ // If owner has a hand, set position to the hand bone position
+ Vector launchPos;
+ int iBIndex = pNPC->LookupBone("Bip01 R Hand");
+ if (iBIndex != -1)
+ {
+ Vector origin;
+ QAngle angles;
+ pNPC->GetBonePosition( iBIndex, launchPos, angles);
+ }
+ // Otherwise just set to in front of the owner
+ else
+ {
+ Vector vFacingDir = pNPC->BodyDirection2D( );
+ vFacingDir = vFacingDir * 60.0;
+ launchPos = pNPC->GetAbsOrigin()+vFacingDir;
+ }
+
+
+ //Vector vecVelocity = VecCheckToss( pNPC, launchPos, vec_target, 1.0 );
+
+ ThrowMolotov( launchPos, m_vecTossVelocity);
+
+ // Drop the weapon and remove as no more ammo
+ pNPC->Weapon_Drop( this );
+ UTIL_Remove( this );
+ }
+ break;
+ default:
+ BaseClass::Operator_HandleAnimEvent( pEvent, pOperator );
+ break;
+ }
+}
+
+
+//-----------------------------------------------------------------------------
+// Purpose:
+// Input :
+// Output :
+//-----------------------------------------------------------------------------
+bool CWeaponMolotov::ObjectInWay( void )
+{
+ CBaseCombatCharacter *pOwner = GetOwner();
+ if (!pOwner)
+ {
+ return false;
+ }
+
+ Vector vecSrc = pOwner->Weapon_ShootPosition( );
+ Vector vecAiming = pOwner->BodyDirection2D( );
+
+ trace_t tr;
+
+ Vector vecEnd = vecSrc + (vecAiming * 32);
+ UTIL_TraceLine( vecSrc, vecEnd, MASK_SOLID, pOwner, COLLISION_GROUP_NONE, &tr );
+
+ if (tr.fraction < 1.0)
+ {
+ // Don't block on a living creature
+ if (tr.m_pEnt)
+ {
+ CBaseEntity *pEntity = tr.m_pEnt;
+ CBaseCombatCharacter *pBCC = ToBaseCombatCharacter( pEntity );
+ if (pBCC)
+ {
+ return false;
+ }
+ }
+ return true;
+ }
+ else
+ {
+ return false;
+ }
+}
+
+//-----------------------------------------------------------------------------
+// Purpose: Override to allow throw w/o LOS
+// Input :
+// Output :
+//-----------------------------------------------------------------------------
+bool CWeaponMolotov::WeaponLOSCondition(const Vector &ownerPos, const Vector &targetPos,bool bSetConditions)
+{
+ // <<TODO>> should test if can throw from present location here...
+ return true;
+}
+
+//-----------------------------------------------------------------------------
+// Purpose: Override to check throw
+// Input :
+// Output :
+//-----------------------------------------------------------------------------
+int CWeaponMolotov::WeaponRangeAttack1Condition( float flDot, float flDist )
+{
+ // If things haven't changed too much since last time
+ // just return that previously calculated value
+ if (gpGlobals->curtime < m_fNextThrowCheck )
+ {
+ return m_iThrowBits;
+ }
+
+ if ( flDist < m_fMinRange1) {
+ m_iThrowBits = COND_TOO_CLOSE_TO_ATTACK;
+ }
+ else if (flDist > m_fMaxRange1) {
+ m_iThrowBits = COND_TOO_FAR_TO_ATTACK;
+ }
+ else if (flDot < 0.5) {
+ m_iThrowBits = COND_NOT_FACING_ATTACK;
+ }
+
+ // If moving, can't throw.
+ else if ( m_flGroundSpeed != 0 )
+ {
+ m_iThrowBits = COND_NONE;
+ }
+ else {
+ // Ok we should check again as some time has passed
+ // This function is only used by NPC's so we can cast to a Base Monster
+ CAI_BaseNPC *pNPC = GetOwner()->MyNPCPointer();
+ CBaseEntity *pEnemy = pNPC->GetEnemy();
+
+ if (!pEnemy)
+ {
+ m_iThrowBits = COND_NONE;
+ }
+ // Get Enemy Position
+ Vector vecTarget;
+ pEnemy->CollisionProp()->NormalizedToWorldSpace( Vector( 0.5f, 0.5f, 0.0f ), &vecTarget );
+
+ // Get Toss Vector
+ Vector throwStart = pNPC->Weapon_ShootPosition();
+ Vector vecToss;
+ CBaseEntity* pBlocker = NULL;
+ float throwDist = (throwStart - vecTarget).Length();
+ float fGravity = GetCurrentGravity();
+ float throwLimit = pNPC->ThrowLimit(throwStart, vecTarget, fGravity, 35, WorldAlignMins(), WorldAlignMaxs(), pEnemy, &vecToss, &pBlocker);
+
+ // If I can make the throw (or most of the throw)
+ if (!throwLimit || (throwLimit != throwDist && throwLimit > 0.8*throwDist))
+ {
+ m_vecTossVelocity = vecToss;
+ m_iThrowBits = COND_CAN_RANGE_ATTACK1;
+
+ }
+ else
+ {
+ m_iThrowBits = COND_NONE;
+ }
+
+ }
+ // don't check again for a while.
+ m_fNextThrowCheck = gpGlobals->curtime + 0.33; // 1/3 second.
+
+ return m_iThrowBits;
+}
+
+//-----------------------------------------------------------------------------
+// Purpose:
+//
+//
+//-----------------------------------------------------------------------------
+void CWeaponMolotov::ThrowMolotov( const Vector &vecSrc, const Vector &vecVelocity)
+{
+ CGrenade_Molotov *pMolotov = (CGrenade_Molotov*)Create( "grenade_molotov", vecSrc, vec3_angle, GetOwner() );
+
+ if (!pMolotov)
+ {
+ Msg("Couldn't make molotov!\n");
+ return;
+ }
+ pMolotov->SetAbsVelocity( vecVelocity );
+
+ // Tumble through the air
+ QAngle angVel( random->RandomFloat ( -100, -500 ), random->RandomFloat ( -100, -500 ), random->RandomFloat ( -100, -500 ) );
+ pMolotov->SetLocalAngularVelocity( angVel );
+
+ pMolotov->SetThrower( GetOwner() );
+ pMolotov->SetOwnerEntity( ((CBaseEntity*)GetOwner()) );
+}
+
+//-----------------------------------------------------------------------------
+// Purpose:
+//
+//
+//-----------------------------------------------------------------------------
+void CWeaponMolotov::PrimaryAttack( void )
+{
+
+ CBasePlayer *pPlayer = ToBasePlayer( GetOwner() );
+
+ if (!pPlayer)
+ {
+ return;
+ }
+
+ Vector vecSrc = pPlayer->WorldSpaceCenter();
+ Vector vecFacing = pPlayer->BodyDirection3D( );
+ vecSrc = vecSrc + vecFacing * 18.0;
+ // BUGBUG: is this some hack because it's not at the eye position????
+ vecSrc.z += 24.0f;
+
+ // Player may have turned to face a wall during the throw anim in which case
+ // we don't want to throw the SLAM into the wall
+ if (ObjectInWay())
+ {
+ vecSrc = pPlayer->WorldSpaceCenter() + vecFacing * 5.0;
+ }
+
+ Vector vecAiming = pPlayer->GetAutoaimVector( AUTOAIM_5DEGREES );
+ vecAiming.z += 0.20; // Raise up so passes through reticle
+
+ ThrowMolotov(vecSrc, vecAiming*800);
+ pPlayer->RemoveAmmo( 1, m_iSecondaryAmmoType );
+
+
+ // Don't fire again until fire animation has completed
+ //m_flNextPrimaryAttack = gpGlobals->curtime + CurSequenceDuration();
+ //<<TEMP>> - till real animation is avaible
+ m_flNextPrimaryAttack = gpGlobals->curtime + 1.0;
+ m_flNextSecondaryAttack = gpGlobals->curtime + 1.0;
+
+ m_bNeedDraw = true;
+}
+
+//-----------------------------------------------------------------------------
+// Purpose:
+//
+//
+//-----------------------------------------------------------------------------
+void CWeaponMolotov::SecondaryAttack( void )
+{
+ //<<TEMP>>
+ // Hmmm... what should I do here?
+}
+
+//-----------------------------------------------------------------------------
+// Purpose:
+//
+//
+//-----------------------------------------------------------------------------
+void CWeaponMolotov::DrawAmmo( void )
+{
+ // -------------------------------------------
+ // Make sure I have ammo of the current type
+ // -------------------------------------------
+ CBaseCombatCharacter *pOwner = GetOwner();
+ if (pOwner->GetAmmoCount(m_iSecondaryAmmoType) <=0)
+ {
+ pOwner->Weapon_Drop( this );
+ UTIL_Remove(this);
+ return;
+ }
+ Msg("Drawing Molotov...\n");
+ m_bNeedDraw = false;
+
+ //<<TEMP>> - till real animation is avaible
+ m_flNextPrimaryAttack = gpGlobals->curtime + 2.0;
+ m_flNextSecondaryAttack = gpGlobals->curtime + 2.0;
+
+}
+
+//-----------------------------------------------------------------------------
+// Purpose: Override so shotgun can do mulitple reloads in a row
+// Input :
+// Output :
+//-----------------------------------------------------------------------------
+void CWeaponMolotov::ItemPostFrame( void )
+{
+ CBasePlayer *pOwner = ToBasePlayer( GetOwner() );
+ if (!pOwner)
+ {
+ return;
+ }
+
+
+ if ((pOwner->m_nButtons & IN_ATTACK2) && (m_flNextSecondaryAttack <= gpGlobals->curtime))
+ {
+ SecondaryAttack();
+ }
+ else if ((pOwner->m_nButtons & IN_ATTACK) && (m_flNextPrimaryAttack <= gpGlobals->curtime))
+ {
+ // Uses secondary ammo only
+ if (pOwner->GetAmmoCount(m_iSecondaryAmmoType))
+ {
+ PrimaryAttack();
+ }
+ }
+ else if (m_bNeedDraw)
+ {
+ DrawAmmo();
+ }
+ else
+ {
+ WeaponIdle( );
+ }
+}
+
+
+//-----------------------------------------------------------------------------
+// Purpose: Constructor
+//-----------------------------------------------------------------------------
+CWeaponMolotov::CWeaponMolotov( void )
+{
+#ifdef _DEBUG
+ m_vecTossVelocity.Init();
+#endif
+
+ m_fMinRange1 = 200;
+ m_fMaxRange1 = 1000;
} \ No newline at end of file