CWeaponSDKBase* CSDKPlayer::FindWeapon (SDKWeaponID id) { int i; for (i = 0; i < WeaponCount(); i++) { CWeaponSDKBase *wpn = (CWeaponSDKBase *)GetWeapon (i); if (wpn) { if (wpn->GetWeaponID () == id) return wpn; } } return NULL; }
bool PlayerOutOfAmmoAndMultipleWeaponsConditions( C_SDKPlayer *pPlayer, class CLesson *pLesson ) { if (!PlayerHasMultipleWeaponsConditions(pPlayer, pLesson)) return false; CWeaponSDKBase* pWeapon = pPlayer->GetActiveSDKWeapon(); if (!pWeapon) return false; if (pWeapon->GetWeaponID() == SDK_WEAPON_BRAWL) return false; return !pWeapon->HasPrimaryAmmo(); }
CBaseCombatWeapon* CSDKPlayer::GetLastWeapon() { // This is pretty silly, but I'd rather mess around with stock Valve code as little as possible. #ifdef CLIENT_DLL CBaseCombatWeapon* pLastWeapon = BaseClass::GetLastWeapon(); #else CBaseCombatWeapon* pLastWeapon = BaseClass::Weapon_GetLast(); #endif if (pLastWeapon && pLastWeapon != GetActiveWeapon()) return pLastWeapon; CWeaponSDKBase* pHeaviest = NULL; CWeaponSDKBase* pBrawl = NULL; for (int i = 0; i < WeaponCount(); i++) { if (!GetWeapon(i)) continue; if (GetWeapon(i) == GetActiveWeapon()) continue; CWeaponSDKBase* pSDKWeapon = dynamic_cast<CWeaponSDKBase*>(GetWeapon(i)); if (!pSDKWeapon) continue; if (pSDKWeapon->GetWeaponID() == SDK_WEAPON_BRAWL) { pBrawl = pSDKWeapon; continue; } if (!pHeaviest) { pHeaviest = pSDKWeapon; continue; } if (pHeaviest->GetWeight() < pSDKWeapon->GetWeight()) pHeaviest = pSDKWeapon; } if (!pHeaviest) pHeaviest = pBrawl; return pHeaviest; }
bool PlayerHasMultipleWeaponsConditions( C_SDKPlayer *pPlayer, class CLesson *pLesson ) { if (!PlayerAliveConditions(pPlayer, pLesson)) return false; int iWeapons = 0; for (int i = 0; i < pPlayer->WeaponCount(); i++) { if (!pPlayer->GetWeapon(i)) continue; CWeaponSDKBase* pWeapon = dynamic_cast<CWeaponSDKBase*>(pPlayer->GetWeapon(i)); if (!pWeapon) continue; if (pWeapon->GetWeaponID() == SDK_WEAPON_BRAWL) continue; iWeapons++; } return iWeapons > 1; }
//----------------------------------------------------------------------------- // Purpose: determine the class name of the weapon that got a kill //----------------------------------------------------------------------------- const char *CSDKGameRules::GetKillingWeaponName( const CTakeDamageInfo &info, CSDKPlayer *pVictim, int *iWeaponID ) { CBaseEntity *pInflictor = info.GetInflictor(); CBaseEntity *pKiller = info.GetAttacker(); CBasePlayer *pScorer = SDKGameRules()->GetDeathScorer( pKiller, pInflictor, pVictim ); const char *killer_weapon_name = "world"; *iWeaponID = SDK_WEAPON_NONE; if ( pScorer && pInflictor && ( pInflictor == pScorer ) ) { // If the inflictor is the killer, then it must be their current weapon doing the damage if ( pScorer->GetActiveWeapon() ) { killer_weapon_name = pScorer->GetActiveWeapon()->GetClassname(); if ( pScorer->IsPlayer() ) { *iWeaponID = ToSDKPlayer(pScorer)->GetActiveSDKWeapon()->GetWeaponID(); } } } else if ( pInflictor ) { killer_weapon_name = STRING( pInflictor->m_iClassname ); CWeaponSDKBase *pWeapon = dynamic_cast< CWeaponSDKBase * >( pInflictor ); if ( pWeapon ) { *iWeaponID = pWeapon->GetWeaponID(); } else { CBaseGrenadeProjectile *pBaseGrenade = dynamic_cast<CBaseGrenadeProjectile*>( pInflictor ); if ( pBaseGrenade ) { *iWeaponID = pBaseGrenade->GetWeaponID(); } } } // strip certain prefixes from inflictor's classname const char *prefix[] = { "weapon_", "NPC_", "func_" }; for ( int i = 0; i< ARRAYSIZE( prefix ); i++ ) { // if prefix matches, advance the string pointer past the prefix int len = Q_strlen( prefix[i] ); if ( strncmp( killer_weapon_name, prefix[i], len ) == 0 ) { killer_weapon_name += len; break; } } // grenade projectiles need to be translated to 'grenade' if ( 0 == Q_strcmp( killer_weapon_name, "grenade_projectile" ) ) { killer_weapon_name = "grenade"; } return killer_weapon_name; }
bool CSDKPlayer::PlayerUse() { #ifdef GAME_DLL // Was use pressed or released? if ( ((m_nButtons | m_afButtonPressed | m_afButtonReleased) & IN_USE) && !IsObserver() ) { Vector forward, up; EyeVectors( &forward, NULL, &up ); Vector vecSearchCenter = EyePosition(); CBaseEntity *pObject = nullptr; CBaseEntity *pNearest = nullptr; float flNearest = FLT_MAX; // Look for grenades so we can prioritize picking them up first. for ( CEntitySphereQuery sphere( vecSearchCenter, PLAYER_USE_RADIUS ); ( pObject = sphere.GetCurrentEntity() ) != NULL; sphere.NextEntity() ) { if ( !pObject ) continue; if ( !IsUseableEntity( pObject, FCAP_USE_IN_RADIUS ) ) continue; CWeaponSDKBase* pWeapon = dynamic_cast<CWeaponSDKBase*>(pObject); if (!pWeapon) continue; if (pWeapon->GetWeaponID() != SDK_WEAPON_GRENADE) continue; // If we're full up on grenades, pass over to whatever other weapons are lying around. if (!g_pGameRules->CanHavePlayerItem(this, pWeapon)) continue; // see if it's more roughly in front of the player than previous guess Vector point; pObject->CollisionProp()->CalcNearestPoint( vecSearchCenter, &point ); Vector dir = point - vecSearchCenter; VectorNormalize(dir); float dot = DotProduct( dir, forward ); // Need to be looking at the object more or less if ( dot < 0.8 ) continue; float dist = CalcDistanceToLine( point, vecSearchCenter, forward ); ConVarRef sv_debug_player_use("sv_debug_player_use"); if ( sv_debug_player_use.GetBool() ) { Msg("Radius found %s, dist %.2f\n", pObject->GetClassname(), dist ); } // Not worried about shit being behind a wall at this point. // Just greedily gobble up all nearby grenades since there's // no penalty to the player for doing so. if ( dist < flNearest ) { pNearest = pObject; flNearest = dist; } } if (pNearest) { // This is a grenade. Use it to pick it up. variant_t emptyVariant; pNearest->AcceptInput( "Use", this, this, emptyVariant, USE_TOGGLE ); return true; } } #endif bool bUsed = BaseClass::PlayerUse(); if (bUsed) return bUsed; if (!(m_afButtonPressed & IN_USE)) return false; if (!IsAlive()) return false; return false; }
//----------------------------------------------------------------------------- // Purpose: //----------------------------------------------------------------------------- void CBaseSDKGrenade::ItemPostFrame() { CSDKPlayer *pPlayer = GetPlayerOwner(); if ( !pPlayer ) return; CBaseViewModel *vm = pPlayer->GetViewModel( m_nViewModelIndex ); if ( !vm ) return; // If they let go of the fire button, they want to throw the grenade. if ( m_bPinPulled && !(pPlayer->m_nButtons & IN_ATTACK) ) { pPlayer->DoAnimationEvent( PLAYERANIMEVENT_ATTACK_PRIMARY ); // if (m_bSecondary) // DropGrenade(); // else ThrowGrenade(); if (!pPlayer->IsStyleSkillActive(SKILL_TROLL)) DecrementAmmo( pPlayer ); m_bPinPulled = false; SendWeaponAnim( ACT_VM_THROW ); SetWeaponIdleTime( GetCurrentTime() + SequenceDuration() ); m_bPinPulled = false; // m_bSecondary = false; } else if( m_bRedraw ) { // Has the throw animation finished playing if( m_flTimeWeaponIdle < GetCurrentTime() ) { // if we're officially out of grenades, ditch this weapon if( pPlayer->GetAmmoCount(m_iPrimaryAmmoType) <= 0 ) { #ifdef GAME_DLL pPlayer->Weapon_Drop( this, NULL, NULL ); UTIL_Remove(this); #endif pPlayer->SwitchToNextBestWeapon( NULL ); //Tony; now switch! cuz we rans outs! } else if (pPlayer->IsStyleSkillActive(SKILL_TROLL)) { m_bRedraw = false; m_flNextPrimaryAttack = GetCurrentTime() + 1.2; m_flNextSecondaryAttack = GetCurrentTime() + 1.2; SendWeaponAnim( GetDeployActivity() ); } else { m_bRedraw = false; // Only switch to the next best weapon if the next best weapon is not brawl. CBaseCombatWeapon *pNewWeapon = g_pGameRules->GetNextBestWeapon(pPlayer, this); CWeaponSDKBase* pSDKNewWeapon = dynamic_cast<CWeaponSDKBase*>(pNewWeapon); bool bSwitch = true; if (!pSDKNewWeapon) bSwitch = false; // If I'm going to switch to brawl but I have more grenades, don't switch. else if (pSDKNewWeapon && pSDKNewWeapon->GetWeaponID() == SDK_WEAPON_BRAWL && pPlayer->GetAmmoCount(m_iPrimaryAmmoType) > 0) bSwitch = false; if (bSwitch) pPlayer->SwitchToNextBestWeapon( this ); } return; //don't animate this grenade any more! } } else if( !m_bRedraw ) { BaseClass::ItemPostFrame(); } }