From a2b223cfdee5223f8505b08c8ca2273f48b2f52b Mon Sep 17 00:00:00 2001 From: Andreas Schaafsma Date: Thu, 13 Jan 2022 23:14:43 +0100 Subject: [PATCH] Various changes --- mp/src/game/client/sarena/c_item_rotating.cpp | 83 ++++++ mp/src/game/client/sarena/hud_armor.cpp | 170 +++++++++++ mp/src/game/server/basecombatcharacter.cpp | 14 +- mp/src/game/server/hl2/hl2_player.cpp | 4 +- mp/src/game/server/hl2mp/hl2mp_player.cpp | 28 +- mp/src/game/server/player.cpp | 24 +- mp/src/game/server/sarena/item_rotating.cpp | 265 ++++++++++++++++++ .../game/server/sarena/projectile_rocket.cpp | 259 +++++++++++++++++ mp/src/game/server/sarena/projectile_rocket.h | 46 +++ mp/src/game/server/sarena/sarena_client.cpp | 201 +++++++++++++ mp/src/game/shared/gamemovement.cpp | 19 +- mp/src/game/shared/gamerules.cpp | 2 +- mp/src/game/shared/hl2mp/hl2mp_gamerules.cpp | 4 + .../game/shared/hl2mp/hl2mp_weapon_parse.cpp | 1 + mp/src/game/shared/igamemovement.h | 2 +- mp/src/game/shared/movevars_shared.cpp | 2 +- mp/src/game/shared/sarena/weapon_hatchet.cpp | 228 +++++++++++++++ mp/src/game/shared/sarena/weapon_hatchet.h | 70 +++++ mp/src/game/shared/sarena/weapon_lasergun.cpp | 179 ++++++++++++ mp/src/game/shared/sarena/weapon_railgun.cpp | 177 ++++++++++++ .../shared/sarena/weapon_rocketlauncher.cpp | 172 ++++++++++++ mp/src/game/shared/sarena/weapon_shottie.cpp | 192 +++++++++++++ mp/src/game/shared/takedamageinfo.cpp | 1 + mp/src/game/shared/takedamageinfo.h | 14 + mp/src/game/shared/weapon_parse.cpp | 2 + mp/src/game/shared/weapon_parse.h | 2 + 26 files changed, 2127 insertions(+), 34 deletions(-) create mode 100644 mp/src/game/client/sarena/c_item_rotating.cpp create mode 100644 mp/src/game/client/sarena/hud_armor.cpp create mode 100644 mp/src/game/server/sarena/item_rotating.cpp create mode 100644 mp/src/game/server/sarena/projectile_rocket.cpp create mode 100644 mp/src/game/server/sarena/projectile_rocket.h create mode 100644 mp/src/game/server/sarena/sarena_client.cpp create mode 100644 mp/src/game/shared/sarena/weapon_hatchet.cpp create mode 100644 mp/src/game/shared/sarena/weapon_hatchet.h create mode 100644 mp/src/game/shared/sarena/weapon_lasergun.cpp create mode 100644 mp/src/game/shared/sarena/weapon_railgun.cpp create mode 100644 mp/src/game/shared/sarena/weapon_rocketlauncher.cpp create mode 100644 mp/src/game/shared/sarena/weapon_shottie.cpp diff --git a/mp/src/game/client/sarena/c_item_rotating.cpp b/mp/src/game/client/sarena/c_item_rotating.cpp new file mode 100644 index 00000000..a255a0f8 --- /dev/null +++ b/mp/src/game/client/sarena/c_item_rotating.cpp @@ -0,0 +1,83 @@ +#include "cbase.h" +// memdbgon must be the last include file in a .cpp file!!! +#include "tier0/memdbgon.h" + +#define ITEM_ROTATION_RATE ( 360.0f / 4.0f ) +#define PICKUP_MIN_HEIGHT 50 + +//----------------------------------------------------------------------------- +// Rotating health kit. Heals the player when picked up. +//----------------------------------------------------------------------------- +class C_RotatingPickup : public C_BaseAnimating +{ + DECLARE_CLASS(C_RotatingPickup, C_BaseAnimating); + DECLARE_CLIENTCLASS(); +public: + C_RotatingPickup() { + ClientRotAng = QAngle(0, 0, 0); + ClientPosVector = Vector(0, 0, 0); + m_bRespawning = m_bRespawning_Cache = false; + } + void Spawn() { ClientThink(); } + + bool IsRespawning(); + void ClientThink(); + void PostDataUpdate(DataUpdateType_t updateType); + bool ShouldDraw(); + + bool m_bRespawning; + bool m_bRespawning_Cache; + +private: + QAngle ClientRotAng; // m_angRotation is stomped sometimes (CItem returning the ent to spawn position?) + Vector ClientPosVector; +}; + +LINK_ENTITY_TO_CLASS(item_rotating, C_RotatingPickup); + +IMPLEMENT_CLIENTCLASS_DT(C_RotatingPickup, DT_RotatingPickup, CRotatingPickup) +RecvPropBool(RECVINFO(m_bRespawning)), +END_RECV_TABLE() + +inline bool C_RotatingPickup::IsRespawning() +{ + return m_bRespawning; +} + +void C_RotatingPickup::ClientThink() +{ + if (IsAbsQueriesValid()) + { + if (ClientPosVector.x == 0 && ClientPosVector.y == 0 && ClientPosVector.z == 0) { + ClientPosVector = GetAbsOrigin(); + } + // Rotate + ClientRotAng.x = 0; + ClientRotAng.y += ITEM_ROTATION_RATE * gpGlobals->frametime; + if (ClientRotAng.y >= 360) + ClientRotAng.y -= 360; + Vector vUp = Vector(0, 0, 1); + SetAbsOrigin(ClientPosVector + 5*sin(2*gpGlobals->curtime)*vUp); + SetAbsAngles(ClientRotAng); + } + + SetNextClientThink(CLIENT_THINK_ALWAYS); +} + +void C_RotatingPickup::PostDataUpdate(DataUpdateType_t updateType) +{ + if (m_bRespawning_Cache != m_bRespawning) + { + // Appear/disappear + UpdateVisibility(); + ClientRotAng.y = 0; + m_bRespawning_Cache = m_bRespawning; + } + + return BaseClass::PostDataUpdate(updateType); +} + +bool C_RotatingPickup::ShouldDraw() +{ + return !IsRespawning() && BaseClass::ShouldDraw(); +} \ No newline at end of file diff --git a/mp/src/game/client/sarena/hud_armor.cpp b/mp/src/game/client/sarena/hud_armor.cpp new file mode 100644 index 00000000..c6667669 --- /dev/null +++ b/mp/src/game/client/sarena/hud_armor.cpp @@ -0,0 +1,170 @@ +//========= Copyright Valve Corporation, All rights reserved. ============// +// +// Purpose: +// +// $NoKeywords: $ +// +//=============================================================================// +// +// Health.cpp +// +// implementation of CHudArmor class +// +#include "cbase.h" +#include "hud.h" +#include "hud_macros.h" +#include "view.h" + +#include "iclientmode.h" + +#include +#include +#include +#include + +#include + +using namespace vgui; + +#include "hudelement.h" +#include "hud_numericdisplay.h" + +#include "convar.h" + +// memdbgon must be the last include file in a .cpp file!!! +#include "tier0/memdbgon.h" + +#define INIT_HEALTH -1 + +//----------------------------------------------------------------------------- +// Purpose: Health panel +//----------------------------------------------------------------------------- +class CHudArmor : public CHudElement, public CHudNumericDisplay +{ + DECLARE_CLASS_SIMPLE(CHudArmor, CHudNumericDisplay); + +public: + CHudArmor(const char* pElementName); + virtual void Init(void); + virtual void VidInit(void); + virtual void Reset(void); + virtual void OnThink(); + void MsgFunc_Damage(bf_read& msg); + +private: + // old variables + int m_iHealth; + + int m_bitsDamage; +}; + +DECLARE_HUDELEMENT(CHudArmor); +DECLARE_HUD_MESSAGE(CHudArmor, Damage); + +//----------------------------------------------------------------------------- +// Purpose: Constructor +//----------------------------------------------------------------------------- +CHudArmor::CHudArmor(const char* pElementName) : CHudElement(pElementName), CHudNumericDisplay(NULL, "HudHealth") +{ + SetHiddenBits(HIDEHUD_HEALTH | HIDEHUD_PLAYERDEAD | HIDEHUD_NEEDSUIT); +} + +//----------------------------------------------------------------------------- +// Purpose: +//----------------------------------------------------------------------------- +void CHudArmor::Init() +{ + HOOK_HUD_MESSAGE(CHudArmor, Damage); + Reset(); +} + +//----------------------------------------------------------------------------- +// Purpose: +//----------------------------------------------------------------------------- +void CHudArmor::Reset() +{ + m_iHealth = INIT_HEALTH; + m_bitsDamage = 0; + + wchar_t* tempString = g_pVGuiLocalize->Find("#Valve_Hud_ARMOR"); + + if (tempString) + { + SetLabelText(tempString); + } + else + { + SetLabelText(L"ARMOR"); + } + SetDisplayValue(m_iHealth); +} + +//----------------------------------------------------------------------------- +// Purpose: +//----------------------------------------------------------------------------- +void CHudArmor::VidInit() +{ + Reset(); +} + +//----------------------------------------------------------------------------- +// Purpose: +//----------------------------------------------------------------------------- +void CHudArmor::OnThink() +{ + int newHealth = 0; + C_BasePlayer* local = C_BasePlayer::GetLocalPlayer(); + if (local) + { + // Never below zero + newHealth = MAX(local->GetHealth(), 0); + } + + // Only update the fade if we've changed health + if (newHealth == m_iHealth) + { + return; + } + + m_iHealth = newHealth; + + if (m_iHealth >= 20) + { + g_pClientMode->GetViewportAnimationController()->StartAnimationSequence("HealthIncreasedAbove20"); + } + else if (m_iHealth > 0) + { + g_pClientMode->GetViewportAnimationController()->StartAnimationSequence("HealthIncreasedBelow20"); + g_pClientMode->GetViewportAnimationController()->StartAnimationSequence("HealthLow"); + } + + SetDisplayValue(m_iHealth); +} + +//----------------------------------------------------------------------------- +// Purpose: +//----------------------------------------------------------------------------- +void CHudArmor::MsgFunc_Damage(bf_read& msg) +{ + + int armor = msg.ReadByte(); // armor + int damageTaken = msg.ReadByte(); // health + long bitsDamage = msg.ReadLong(); // damage bits + bitsDamage; // variable still sent but not used + + Vector vecFrom; + + vecFrom.x = msg.ReadBitCoord(); + vecFrom.y = msg.ReadBitCoord(); + vecFrom.z = msg.ReadBitCoord(); + + // Actually took damage? + if (damageTaken > 0 || armor > 0) + { + if (damageTaken > 0) + { + // start the animation + g_pClientMode->GetViewportAnimationController()->StartAnimationSequence("HealthDamageTaken"); + } + } +} \ No newline at end of file diff --git a/mp/src/game/server/basecombatcharacter.cpp b/mp/src/game/server/basecombatcharacter.cpp index 71d6c844..b92f3985 100644 --- a/mp/src/game/server/basecombatcharacter.cpp +++ b/mp/src/game/server/basecombatcharacter.cpp @@ -1406,6 +1406,7 @@ Vector CBaseCombatCharacter::CalcDamageForceVector( const CTakeDamageInfo &info // taking damage from self? Take a little random force, but still try to collapse on the spot. if ( this == pForce ) { + DevMsg("SelfDamage taken"); forceVector.x = random->RandomFloat( -1.0f, 1.0f ); forceVector.y = random->RandomFloat( -1.0f, 1.0f ); forceVector.z = 0.0; @@ -2178,8 +2179,10 @@ bool CBaseCombatCharacter::Weapon_EquipAmmoOnly( CBaseCombatWeapon *pWeapon ) if ( m_hMyWeapons[i].Get() && FClassnameIs(m_hMyWeapons[i], pWeapon->GetClassname()) ) { // Just give the ammo from the clip - int primaryGiven = (pWeapon->UsesClipsForAmmo1()) ? pWeapon->m_iClip1 : pWeapon->GetPrimaryAmmoCount(); - int secondaryGiven = (pWeapon->UsesClipsForAmmo2()) ? pWeapon->m_iClip2 : pWeapon->GetSecondaryAmmoCount(); + //int primaryGiven = (pWeapon->UsesClipsForAmmo1()) ? pWeapon->m_iClip1 : pWeapon->GetPrimaryAmmoCount(); + //int secondaryGiven = (pWeapon->UsesClipsForAmmo2()) ? pWeapon->m_iClip2 : pWeapon->GetSecondaryAmmoCount(); + int primaryGiven = pWeapon->GetDefaultClip1(); + int secondaryGiven = pWeapon->GetDefaultClip2(); int takenPrimary = GiveAmmo( primaryGiven, pWeapon->m_iPrimaryAmmoType); int takenSecondary = GiveAmmo( secondaryGiven, pWeapon->m_iSecondaryAmmoType); @@ -2243,7 +2246,7 @@ CBaseCombatWeapon *CBaseCombatCharacter::Weapon_GetSlot( int slot ) const { if ( m_hMyWeapons[i].Get() != NULL ) { - // If the slots match, it's already occupied + // If the slots match, i t's already occupied if ( m_hMyWeapons[i]->GetSlot() == targetSlot ) return m_hMyWeapons[i]; } @@ -2490,6 +2493,11 @@ int CBaseCombatCharacter::OnTakeDamage_Alive( const CTakeDamageInfo &info ) m_flDamageAccumulator -= 1.0; } + // Reduce damage in case of selfdamage + if (info.GetAttacker() == this) { + flIntegerDamage *= 0.33; + } + if ( flIntegerDamage <= 0 ) return 0; diff --git a/mp/src/game/server/hl2/hl2_player.cpp b/mp/src/game/server/hl2/hl2_player.cpp index e7583f5a..420e7ba8 100644 --- a/mp/src/game/server/hl2/hl2_player.cpp +++ b/mp/src/game/server/hl2/hl2_player.cpp @@ -87,8 +87,8 @@ ConVar hl2_darkness_flashlight_factor ( "hl2_darkness_flashlight_factor", "1" ); #ifdef HL2MP #define HL2_WALK_SPEED 150 - #define HL2_NORM_SPEED 190 - #define HL2_SPRINT_SPEED 320 + #define HL2_NORM_SPEED 400 + #define HL2_SPRINT_SPEED 400 #else #define HL2_WALK_SPEED hl2_walkspeed.GetFloat() #define HL2_NORM_SPEED hl2_normspeed.GetFloat() diff --git a/mp/src/game/server/hl2mp/hl2mp_player.cpp b/mp/src/game/server/hl2mp/hl2mp_player.cpp index 1469d842..c32c5b3e 100644 --- a/mp/src/game/server/hl2mp/hl2mp_player.cpp +++ b/mp/src/game/server/hl2mp/hl2mp_player.cpp @@ -198,12 +198,13 @@ void CHL2MP_Player::GiveDefaultItems( void ) { EquipSuit(); - CBasePlayer::GiveAmmo( 255, "Pistol"); - CBasePlayer::GiveAmmo( 45, "SMG1"); - CBasePlayer::GiveAmmo( 1, "grenade" ); - CBasePlayer::GiveAmmo( 6, "Buckshot"); - CBasePlayer::GiveAmmo( 6, "357" ); - + //CBasePlayer::GiveAmmo( 255, "Pistol"); + //CBasePlayer::GiveAmmo( 45, "SMG1"); + //CBasePlayer::GiveAmmo( 45, "Rail"); + //CBasePlayer::GiveAmmo( 1, "grenade" ); + //CBasePlayer::GiveAmmo( 6, "Buckshot"); + //CBasePlayer::GiveAmmo( 6, "357" ); + /* if ( GetPlayerModelType() == PLAYER_SOUNDS_METROPOLICE || GetPlayerModelType() == PLAYER_SOUNDS_COMBINESOLDIER ) { GiveNamedItem( "weapon_stunstick" ); @@ -212,11 +213,16 @@ void CHL2MP_Player::GiveDefaultItems( void ) { GiveNamedItem( "weapon_crowbar" ); } - - GiveNamedItem( "weapon_pistol" ); - GiveNamedItem( "weapon_smg1" ); - GiveNamedItem( "weapon_frag" ); - GiveNamedItem( "weapon_physcannon" ); + */ + GiveNamedItem("weapon_hatchet"); + //GiveNamedItem("weapon_rocketlauncher"); + //GiveNamedItem("weapon_railgun"); + //GiveNamedItem("weapon_lasergun"); + GiveNamedItem("weapon_shottie"); + //GiveNamedItem( "weapon_pistol" ); + //GiveNamedItem( "weapon_smg1" ); + //GiveNamedItem( "weapon_frag" ); + //GiveNamedItem( "weapon_physcannon" ); const char *szDefaultWeaponName = engine->GetClientConVarValue( engine->IndexOfEdict( edict() ), "cl_defaultweapon" ); diff --git a/mp/src/game/server/player.cpp b/mp/src/game/server/player.cpp index e0e7ccd2..bf02dba0 100644 --- a/mp/src/game/server/player.cpp +++ b/mp/src/game/server/player.cpp @@ -1575,7 +1575,8 @@ static float DamageForce( const Vector &size, float damage ) if ( force > 1000.0) { - force = 1000.0; + // Disabled arbitrary force limit + force = force; // force = 1000.0; } return force; @@ -1592,7 +1593,7 @@ int CBasePlayer::OnTakeDamage_Alive( const CTakeDamageInfo &info ) { // set damage type sustained m_bitsDamageType |= info.GetDamageType(); - + if ( !BaseClass::OnTakeDamage_Alive( info ) ) return 0; @@ -1611,14 +1612,17 @@ int CBasePlayer::OnTakeDamage_Alive( const CTakeDamageInfo &info ) if ( info.GetInflictor() && (GetMoveType() == MOVETYPE_WALK) && ( !attacker->IsSolidFlagSet(FSOLID_TRIGGER)) ) { - Vector force = vecDir * -DamageForce( WorldAlignSize(), info.GetBaseDamage() ); + //Vector force = vecDir * -DamageForce( WorldAlignSize(), info.GetBaseDamage() ); + Vector force = vecDir * -DamageForce(WorldAlignSize(), info.GetBlastForce()); + DevMsg("applying damage force: %.2f", info.GetBlastForce()); if ( force.z > 250.0f ) { - force.z = 250.0f; + //force.z = 250.0f; + force.z = force.z; //disabled arbitrary force limit } ApplyAbsVelocityImpulse( force ); } - + // fire global game event IGameEvent * event = gameeventmanager->CreateEvent( "player_hurt" ); @@ -5677,9 +5681,15 @@ void CBloodSplat::Think( void ) CBaseEntity *CBasePlayer::GiveNamedItem( const char *pszName, int iSubType ) { // If I already own this type don't create one - if ( Weapon_OwnsThisType(pszName, iSubType) ) + //if (Weapon_OwnsThisType(pszName, iSubType)) + //return NULL; + // If I already own this type don't create one + //CBaseCombatWeapon *pWeap = Weapon_OwnsThisType(pszName, iSubType); + if (Weapon_OwnsThisType(pszName, iSubType)) { + //Weapon_EquipAmmoOnly(pWeap); + //DevMsg("kankerrrrrrrrr"); return NULL; - + } // Msg( "giving %s\n", pszName ); EHANDLE pent; diff --git a/mp/src/game/server/sarena/item_rotating.cpp b/mp/src/game/server/sarena/item_rotating.cpp new file mode 100644 index 00000000..759be1fe --- /dev/null +++ b/mp/src/game/server/sarena/item_rotating.cpp @@ -0,0 +1,265 @@ +#include "cbase.h" +#include "items.h" +#include "ammodef.h" +#include "weapon_hl2mpbasehlmpcombatweapon.h" +// memdbgon must be the last include file in a .cpp file!!! +#include "tier0/memdbgon.h" + +#define PICKUP_DECAL "decals/item_base" +#define PICKUP_MODEL "models/items/item_health.mdl" +#define PICKUP_PEDESTALMODEL "models/items/pickup_pedestal.mdl" +#define PICKUP_MIN_HEIGHT 50 +int PickupDecalIndex; // set by CRotatingPickup::Precache() + +enum EItemType { + PICKUP_HEALTH = 0, + PICKUP_ARMOR = 1, + PICKUP_POWERUP = 2, + PICKUP_WEAPON = 3 +}; + +enum EWeapons { + WEAPON_LASERGUN = 0, + WEAPON_RAILGUN = 1, + WEAPON_ROCKETLAUNCHER = 2, +}; + +#define SF_SUPPRESS_PICKUP_DECAL 0x00000002 + +//----------------------------------------------------------------------------- +// Rotating health kit. Heals the player when picked up. +//----------------------------------------------------------------------------- +class CRotatingPickup : public CItem +{ + DECLARE_CLASS(CRotatingPickup, CItem); + DECLARE_DATADESC(); + DECLARE_SERVERCLASS(); +public: + + CRotatingPickup(); + + void Spawn(); + void Activate(); + void Precache(); + bool MyTouch(CBasePlayer* pPlayer); + bool handleWeaponPickup(const char* strWeaponName, CBasePlayer* pPlayer); + + CBaseEntity* Respawn(); + void Materialize(); + + int m_iHealthToGive; + float m_fRespawnTime; + int m_iItemType; + int m_iWeaponType; + CBaseAnimating* pedestalModel; + + CNetworkVar(bool, m_bRespawning); + +private: + Vector MdlTop; +}; + +LINK_ENTITY_TO_CLASS(item_rotating, CRotatingPickup); + +PRECACHE_REGISTER(item_rotating); + +BEGIN_DATADESC(CRotatingPickup) +DEFINE_KEYFIELD(m_iHealthToGive, FIELD_INTEGER, "givehealth"), +DEFINE_KEYFIELD(m_fRespawnTime, FIELD_FLOAT, "respawntime"), +DEFINE_KEYFIELD(m_iItemType, FIELD_INTEGER, "itemtype"), +DEFINE_KEYFIELD(m_iWeaponType, FIELD_INTEGER, "weapontype"), +END_DATADESC() + +IMPLEMENT_SERVERCLASS_ST(CRotatingPickup, DT_RotatingPickup) +SendPropBool(SENDINFO(m_bRespawning)), +SendPropExclude("DT_BaseEntity", "m_angRotation"), +END_SEND_TABLE() + +CRotatingPickup::CRotatingPickup() +{ + pedestalModel = (CBaseAnimating*)CreateEntityByName("prop_dynamic_override"); + + if (m_iHealthToGive <= 0) + m_iHealthToGive = 25; + + if (m_fRespawnTime <= 0) + m_fRespawnTime = 20; +} + + +void CRotatingPickup::Spawn() +{ + // CItem is designed for Vphys objects, so we need to undo a couple of things its spawn() does + Vector OriginalLocation = GetAbsOrigin(); + BaseClass::Spawn(); + + VPhysicsDestroyObject(); + SetAbsOrigin(OriginalLocation); + //pedestalModel->KeyValue("model", PICKUP_PEDESTALMODEL); + pedestalModel->SetModel(PICKUP_PEDESTALMODEL); + //pedestalModel->Create(); + DispatchSpawn(pedestalModel); + pedestalModel->SetAbsOrigin(OriginalLocation); + + UseClientSideAnimation(); + switch (m_iItemType) { + case PICKUP_HEALTH: + SetModel(PICKUP_MODEL); + break; + case PICKUP_ARMOR: + SetModel(PICKUP_MODEL); + break; + case PICKUP_POWERUP: + SetModel(PICKUP_MODEL); + break; + case PICKUP_WEAPON: + switch (m_iWeaponType) { + case WEAPON_LASERGUN: + SetModel("models/weapons/w_lasergun.mdl"); + break; + case WEAPON_RAILGUN: + SetModel("models/weapons/w_railgun.mdl"); + break; + case WEAPON_ROCKETLAUNCHER: + SetModel("models/weapons/w_rocketlauncher.mdl"); + break; + } + break; + } + + + + SetMoveType(MOVETYPE_NONE); + + // Grab the highest point on the model before we change the bounding box + MdlTop = GetAbsOrigin(); + MdlTop.z += GetModelPtr()->hull_max().z; + + SetSolid(SOLID_NONE); + CollisionProp()->UseTriggerBounds(true, 6); // Reign in the volume added to the trigger collision box + Vector OBBSize = Vector(CollisionProp()->OBBSize().Length() / 2); // need to use length as the model will be rotated at 45 degrees on clients + SetSize(-OBBSize, OBBSize); // Resize the bounding box + + AddEffects(EF_NOSHADOW); +} + +void CRotatingPickup::Activate() +{ + BaseClass::Activate(); + + // Ensure minimum distance above a standable surfare + trace_t tr; + UTIL_TraceLine(MdlTop, MdlTop + Vector(0, 0, -PICKUP_MIN_HEIGHT), MASK_PLAYERSOLID, this, COLLISION_GROUP_NONE, &tr); // measuring from MdlTop + if (tr.DidHit()) + { + if (!HasSpawnFlags(SF_SUPPRESS_PICKUP_DECAL)) + engine->StaticDecal(tr.endpos, PickupDecalIndex, 0, 0, false); // mark the location of the pickup + SetAbsOrigin(GetAbsOrigin() + (Vector(0, 0, PICKUP_MIN_HEIGHT * (1 - tr.fraction)))); + } +} + +void CRotatingPickup::Precache() +{ + PrecacheModel(PICKUP_MODEL); + PrecacheModel(PICKUP_PEDESTALMODEL); + PrecacheScriptSound("HealthKit.Touch"); + PrecacheScriptSound("AlyxEmp.Charge"); + PickupDecalIndex = UTIL_PrecacheDecal(PICKUP_DECAL, true); +} + +bool CRotatingPickup::handleWeaponPickup(const char* strWeaponName, CBasePlayer* pPlayer) { + CBaseCombatWeapon* pWeapon = pPlayer->Weapon_OwnsThisType(strWeaponName); + if (!pWeapon) { + pPlayer->GiveNamedItem(strWeaponName); + } + else { + Ammo_t* pAmmoType = GetAmmoDef()->GetAmmoOfIndex(pWeapon->GetPrimaryAmmoType()); + int iMaxAmmo = pAmmoType->pMaxCarry; + //pPlayer->Weapon_EquipAmmoOnly(pPlayer->Weapon_OwnsThisType(strWeaponName)); + const FileWeaponInfo_t& weaponInfo = pWeapon->GetWpnData(); + int iAmmoToGive = weaponInfo.m_iOwnedPickupAmmo; + + if (pPlayer->GetAmmoCount(pAmmoType->pName) + iAmmoToGive < pWeapon->GetDefaultClip1()) { + iAmmoToGive = pWeapon->GetDefaultClip1() - pPlayer->GetAmmoCount(pAmmoType->pName); + pPlayer->GiveAmmo(iAmmoToGive, pAmmoType->pName); + } + else if (pPlayer->GetAmmoCount(pAmmoType->pName) < iMaxAmmo) { + pPlayer->GiveAmmo(iAmmoToGive, pAmmoType->pName); + } + else { + return false; + } + } + return true; +} + +// Called from CItem::ItemTouch() +bool CRotatingPickup::MyTouch(CBasePlayer* pPlayer) +{ + if (pPlayer) + { + switch (m_iItemType) { + case PICKUP_HEALTH: + if (pPlayer->GetHealth() < pPlayer->GetMaxHealth()) + pPlayer->TakeHealth(m_iHealthToGive, DMG_GENERIC); + else + return false; + break; + case PICKUP_ARMOR: + + break; + case PICKUP_POWERUP: + + break; + case PICKUP_WEAPON: + switch (m_iWeaponType) { + case WEAPON_LASERGUN: + if (!handleWeaponPickup("weapon_lasergun", pPlayer)) + return false; + break; + case WEAPON_RAILGUN: + if (!handleWeaponPickup("weapon_railgun", pPlayer)) + return false; + break; + case WEAPON_ROCKETLAUNCHER: + if (!handleWeaponPickup("weapon_rocketlauncher", pPlayer)) + return false; + break; + } + break; + } + + CSingleUserRecipientFilter PlayerFilter(pPlayer); + PlayerFilter.MakeReliable(); + + UserMessageBegin(PlayerFilter, "ItemPickup"); + WRITE_STRING(GetClassname()); + MessageEnd(); + EmitSound(PlayerFilter, pPlayer->entindex(), "HealthKit.Touch"); // this should be done by the HUD really + + Respawn(); + return true; + } + + return false; +} + +// Disappear +CBaseEntity* CRotatingPickup::Respawn() +{ + SetTouch(NULL); + m_bRespawning = true; + + SetThink(&CRotatingPickup::Materialize); + SetNextThink(gpGlobals->curtime + m_fRespawnTime); + + return this; +} + +// Reappear +void CRotatingPickup::Materialize() +{ + EmitSound("AlyxEmp.Charge"); + m_bRespawning = false; + SetTouch(&CItem::ItemTouch); +} \ No newline at end of file diff --git a/mp/src/game/server/sarena/projectile_rocket.cpp b/mp/src/game/server/sarena/projectile_rocket.cpp new file mode 100644 index 00000000..d8b551e8 --- /dev/null +++ b/mp/src/game/server/sarena/projectile_rocket.cpp @@ -0,0 +1,259 @@ +//========= Copyright Valve Corporation, All rights reserved. ============// +// +// Purpose: +// +// $NoKeywords: $ +//=============================================================================// + +#include "cbase.h" +#include "projectile_rocket.h" +#include "soundent.h" +#include "decals.h" +#include "shake.h" +#include "smoke_trail.h" +#include "ar2_explosion.h" +#include "vstdlib/random.h" +#include "engine/IEngineSound.h" +#include "world.h" + +#ifdef PORTAL + #include "portal_util_shared.h" +#endif + +// memdbgon must be the last include file in a .cpp file!!! +#include "tier0/memdbgon.h" + +#define PROJECTILE_ROCKET_MAX_DANGER_RADIUS 300 + +extern short g_sModelIndexFireball; // (in combatweapon.cpp) holds the index for the smoke cloud + +// Moved to HL2_SharedGameRules because these are referenced by shared AmmoDef functions +ConVar sk_plr_dmg_projectile_rocket ("sk_plr_dmg_projectile_rocket", "0"); +ConVar sk_npc_dmg_projectile_rocket ("sk_npc_dmg_projectile_rocket", "0"); +ConVar sk_max_projectile_rocket ("sk_max_projectile_rocket", "0"); + +ConVar sk_projectile_rocket_radius ( "sk_smg1_grenade_radius","0"); + + +// Custom Source Arena cvars +ConVar sk_rocket_blast_force("sk_rocket_blast_force", "100"); // Rocket blast force + + + +ConVar g_CV_rocketSmokeTrail("smoke_trail", "1", 0); // temporary dust explosion switch + +BEGIN_DATADESC( CProjectileRocket ) + + DEFINE_FIELD( m_hSmokeTrail, FIELD_EHANDLE ), + DEFINE_FIELD( m_fSpawnTime, FIELD_TIME ), + DEFINE_FIELD( m_fDangerRadius, FIELD_FLOAT ), + + // Function pointers + DEFINE_ENTITYFUNC( ProjectileRocketTouch ), + DEFINE_THINKFUNC( ProjectileRocketThink ), + +END_DATADESC() + +LINK_ENTITY_TO_CLASS( projectile_rocket, CProjectileRocket ); + +void CProjectileRocket::Spawn( void ) +{ + Precache( ); + SetSolid( SOLID_BBOX ); + SetMoveType( MOVETYPE_FLY, MOVECOLLIDE_FLY_BOUNCE ); + + // Hits everything but debris + SetCollisionGroup( COLLISION_GROUP_PROJECTILE ); + + SetModel( "models/Weapons/ar2_grenade.mdl"); + UTIL_SetSize(this, Vector(-3, -3, -3), Vector(3, 3, 3)); +// UTIL_SetSize(this, Vector(0, 0, 0), Vector(0, 0, 0)); + + SetUse( &CProjectileRocket::DetonateUse ); + SetTouch( &CProjectileRocket::ProjectileRocketTouch ); + SetThink( &CProjectileRocket::ProjectileRocketThink ); + SetNextThink( gpGlobals->curtime + 0.1f ); + + if( GetOwnerEntity() && GetOwnerEntity()->IsPlayer() ) + { + m_flDamage = sk_plr_dmg_projectile_rocket.GetFloat(); + } + else + { + m_flDamage = sk_npc_dmg_projectile_rocket.GetFloat(); + } + + m_DmgRadius = sk_projectile_rocket_radius.GetFloat(); + m_takedamage = DAMAGE_YES; + m_bIsLive = true; + m_iHealth = 1; + + SetGravity( UTIL_ScaleForGravity( 400 ) ); // use a lower gravity for grenades to make them easier to see + SetFriction( 0.8 ); + SetSequence( 0 ); + + m_fDangerRadius = 100; + + m_fSpawnTime = gpGlobals->curtime; + + // ------------- + // Smoke trail. + // ------------- + if( g_CV_rocketSmokeTrail.GetInt() && !IsXbox() ) + { + m_hSmokeTrail = SmokeTrail::CreateSmokeTrail(); + + if( m_hSmokeTrail ) + { + m_hSmokeTrail->m_SpawnRate = 48; + m_hSmokeTrail->m_ParticleLifetime = 1; + m_hSmokeTrail->m_StartColor.Init(0.1f, 0.1f, 0.1f); + m_hSmokeTrail->m_EndColor.Init(0,0,0); + m_hSmokeTrail->m_StartSize = 12; + m_hSmokeTrail->m_EndSize = m_hSmokeTrail->m_StartSize * 4; + m_hSmokeTrail->m_SpawnRadius = 4; + m_hSmokeTrail->m_MinSpeed = 4; + m_hSmokeTrail->m_MaxSpeed = 24; + m_hSmokeTrail->m_Opacity = 0.2f; + + m_hSmokeTrail->SetLifetime(10.0f); + m_hSmokeTrail->FollowEntity(this); + } + } +} + +//----------------------------------------------------------------------------- +// Purpose: The grenade has a slight delay before it goes live. That way the +// person firing it can bounce it off a nearby wall. However if it +// hits another character it blows up immediately +// Input : +// Output : +//----------------------------------------------------------------------------- +void CProjectileRocket::ProjectileRocketThink( void ) +{ + SetNextThink( gpGlobals->curtime + 0.05f ); + + if (!m_bIsLive) + { + // Go live after a short delay + if (m_fSpawnTime + MAX_ROCKET_NO_COLLIDE_TIME < gpGlobals->curtime) + { + m_bIsLive = true; + } + } + + // If I just went solid and my velocity is zero, it means I'm resting on + // the floor already when I went solid so blow up + if (m_bIsLive) + { + if (GetAbsVelocity().Length() == 0.0 || + GetGroundEntity() != NULL ) + { + Detonate(); + } + } + + // The old way of making danger sounds would scare the crap out of EVERYONE between you and where the grenade + // was going to hit. The radius of the danger sound now 'blossoms' over the grenade's lifetime, making it seem + // dangerous to a larger area downrange than it does from where it was fired. + if( m_fDangerRadius <= PROJECTILE_ROCKET_MAX_DANGER_RADIUS ) + { + m_fDangerRadius += ( PROJECTILE_ROCKET_MAX_DANGER_RADIUS * 0.05 ); + } + + CSoundEnt::InsertSound( SOUND_DANGER, GetAbsOrigin() + GetAbsVelocity() * 0.5, m_fDangerRadius, 0.2, this, SOUNDENT_CHANNEL_REPEATED_DANGER ); +} + +void CProjectileRocket::Event_Killed( const CTakeDamageInfo &info ) +{ + Detonate( ); +} + +void CProjectileRocket::ProjectileRocketTouch( CBaseEntity *pOther ) +{ + Assert( pOther ); + if ( !pOther->IsSolid() ) + return; + + // If I'm live go ahead and blow up + if (m_bIsLive) + { + Detonate(); + } + else + { + // If I'm not live, only blow up if I'm hitting an chacter that + // is not the owner of the weapon + CBaseCombatCharacter *pBCC = ToBaseCombatCharacter( pOther ); + if (pBCC && GetThrower() != pBCC) + { + m_bIsLive = true; + Detonate(); + } + } +} + +void CProjectileRocket::Detonate(void) +{ + if (!m_bIsLive) + { + return; + } + m_bIsLive = false; + m_takedamage = DAMAGE_NO; + + if(m_hSmokeTrail) + { + UTIL_Remove(m_hSmokeTrail); + m_hSmokeTrail = NULL; + } + + CPASFilter filter( GetAbsOrigin() ); + + te->Explosion( filter, 0.0, + &GetAbsOrigin(), + g_sModelIndexFireball, + 2.0, + 15, + TE_EXPLFLAG_NONE, + m_DmgRadius, + m_flDamage ); + + Vector vecForward = GetAbsVelocity(); + VectorNormalize(vecForward); + trace_t tr; + UTIL_TraceLine ( GetAbsOrigin(), GetAbsOrigin() + 60*vecForward, MASK_SHOT, + this, COLLISION_GROUP_NONE, &tr); + + + if ((tr.m_pEnt != GetWorldEntity()) || (tr.hitbox != 0)) + { + // non-world needs smaller decals + if( tr.m_pEnt && !tr.m_pEnt->IsNPC() ) + { + UTIL_DecalTrace( &tr, "SmallScorch" ); + } + } + else + { + UTIL_DecalTrace( &tr, "Scorch" ); + } + + UTIL_ScreenShake( GetAbsOrigin(), 25.0, 150.0, 1.0, 750, SHAKE_START ); + CTakeDamageInfo damageInfo = CTakeDamageInfo(this, GetThrower(), m_flDamage, DMG_BLAST); + damageInfo.SetBlastForce(sk_rocket_blast_force.GetFloat()); + RadiusDamage ( damageInfo, GetAbsOrigin(), m_DmgRadius, CLASS_NONE, NULL ); + + UTIL_Remove( this ); +} + +void CProjectileRocket::Precache( void ) +{ + PrecacheModel("models/Weapons/ar2_grenade.mdl"); +} + + +CProjectileRocket::CProjectileRocket(void) +{ + m_hSmokeTrail = NULL; +} diff --git a/mp/src/game/server/sarena/projectile_rocket.h b/mp/src/game/server/sarena/projectile_rocket.h new file mode 100644 index 00000000..682060b6 --- /dev/null +++ b/mp/src/game/server/sarena/projectile_rocket.h @@ -0,0 +1,46 @@ +//========= Copyright Valve Corporation, All rights reserved. ============// +// +// Purpose: Projectile shot from the AR2 +// +// $Workfile: $ +// $Date: $ +// +//----------------------------------------------------------------------------- +// $Log: $ +// +// $NoKeywords: $ +//=============================================================================// + +#ifndef PROJECTILEROCKET_H +#define PROJECTILEROCKET_H + +#include "basegrenade_shared.h" + +#define MAX_ROCKET_NO_COLLIDE_TIME 0.2 + +class SmokeTrail; + +class CProjectileRocket : public CBaseGrenade +{ +public: + DECLARE_CLASS( CProjectileRocket, CBaseGrenade ); + + CHandle< SmokeTrail > m_hSmokeTrail; + float m_fSpawnTime; + float m_fDangerRadius; + + + void Spawn( void ); + void Precache( void ); + void ProjectileRocketTouch( CBaseEntity *pOther ); + void ProjectileRocketThink( void ); + void Event_Killed( const CTakeDamageInfo &info ); + +public: + void EXPORT Detonate(void); + CProjectileRocket(void); + + DECLARE_DATADESC(); +}; + +#endif //GRENADEAR2_H diff --git a/mp/src/game/server/sarena/sarena_client.cpp b/mp/src/game/server/sarena/sarena_client.cpp new file mode 100644 index 00000000..571fbb85 --- /dev/null +++ b/mp/src/game/server/sarena/sarena_client.cpp @@ -0,0 +1,201 @@ +//========= Copyright Valve Corporation, All rights reserved. ============// +// +// Purpose: +// +// $NoKeywords: $ +// +//=============================================================================// +/* + +===== tf_client.cpp ======================================================== + + HL2 client/server game specific stuff + +*/ + +#include "cbase.h" +#include "hl2mp_player.h" +#include "hl2mp_gamerules.h" +#include "gamerules.h" +#include "teamplay_gamerules.h" +#include "entitylist.h" +#include "physics.h" +#include "game.h" +#include "player_resource.h" +#include "engine/IEngineSound.h" +#include "team.h" +#include "viewport_panel_names.h" + +#include "tier0/vprof.h" + +// memdbgon must be the last include file in a .cpp file!!! +#include "tier0/memdbgon.h" + +void Host_Say( edict_t *pEdict, bool teamonly ); + +ConVar sv_motd_unload_on_dismissal( "sv_motd_unload_on_dismissal", "0", 0, "If enabled, the MOTD contents will be unloaded when the player closes the MOTD." ); + +extern CBaseEntity* FindPickerEntityClass( CBasePlayer *pPlayer, char *classname ); +extern bool g_fGameOver; + +void FinishClientPutInServer( CHL2MP_Player *pPlayer ) +{ + pPlayer->InitialSpawn(); + pPlayer->Spawn(); + + + char sName[128]; + Q_strncpy( sName, pPlayer->GetPlayerName(), sizeof( sName ) ); + + // First parse the name and remove any %'s + for ( char *pApersand = sName; pApersand != NULL && *pApersand != 0; pApersand++ ) + { + // Replace it with a space + if ( *pApersand == '%' ) + *pApersand = ' '; + } + + // notify other clients of player joining the game + UTIL_ClientPrintAll( HUD_PRINTNOTIFY, "#Game_connected", sName[0] != 0 ? sName : "" ); + + if ( HL2MPRules()->IsTeamplay() == true ) + { + ClientPrint( pPlayer, HUD_PRINTTALK, "You are on team %s1\n", pPlayer->GetTeam()->GetName() ); + } + + const ConVar *hostname = cvar->FindVar( "hostname" ); + const char *title = (hostname) ? hostname->GetString() : "MESSAGE OF THE DAY"; + + KeyValues *data = new KeyValues("data"); + data->SetString( "title", title ); // info panel title + data->SetString( "type", "1" ); // show userdata from stringtable entry + data->SetString( "msg", "motd" ); // use this stringtable entry + data->SetBool( "unload", sv_motd_unload_on_dismissal.GetBool() ); + + pPlayer->ShowViewPortPanel( PANEL_INFO, true, data ); + + data->deleteThis(); +} + +/* +=========== +ClientPutInServer + +called each time a player is spawned into the game +============ +*/ +void ClientPutInServer( edict_t *pEdict, const char *playername ) +{ + // Allocate a CBaseTFPlayer for pev, and call spawn + CHL2MP_Player *pPlayer = CHL2MP_Player::CreatePlayer( "player", pEdict ); + pPlayer->SetPlayerName( playername ); +} + + +void ClientActive( edict_t *pEdict, bool bLoadGame ) +{ + // Can't load games in CS! + Assert( !bLoadGame ); + + CHL2MP_Player *pPlayer = ToHL2MPPlayer( CBaseEntity::Instance( pEdict ) ); + FinishClientPutInServer( pPlayer ); +} + + +/* +=============== +const char *GetGameDescription() + +Returns the descriptive name of this .dll. E.g., Half-Life, or Team Fortress 2 +=============== +*/ +const char *GetGameDescription() +{ + if ( g_pGameRules ) // this function may be called before the world has spawned, and the game rules initialized + return g_pGameRules->GetGameDescription(); + else + return "Half-Life 2 Deathmatch"; +} + +//----------------------------------------------------------------------------- +// Purpose: Given a player and optional name returns the entity of that +// classname that the player is nearest facing +// +// Input : +// Output : +//----------------------------------------------------------------------------- +CBaseEntity* FindEntity( edict_t *pEdict, char *classname) +{ + // If no name was given set bits based on the picked + if (FStrEq(classname,"")) + { + return (FindPickerEntityClass( static_cast(GetContainingEntity(pEdict)), classname )); + } + return NULL; +} + +//----------------------------------------------------------------------------- +// Purpose: Precache game-specific models & sounds +//----------------------------------------------------------------------------- +void ClientGamePrecache( void ) +{ + CBaseEntity::PrecacheModel("models/player.mdl"); + CBaseEntity::PrecacheModel( "models/gibs/agibs.mdl" ); + CBaseEntity::PrecacheModel ("models/weapons/v_hands.mdl"); + + CBaseEntity::PrecacheScriptSound( "HUDQuickInfo.LowAmmo" ); + CBaseEntity::PrecacheScriptSound( "HUDQuickInfo.LowHealth" ); + + CBaseEntity::PrecacheScriptSound( "FX_AntlionImpact.ShellImpact" ); + CBaseEntity::PrecacheScriptSound( "Missile.ShotDown" ); + CBaseEntity::PrecacheScriptSound( "Bullets.DefaultNearmiss" ); + CBaseEntity::PrecacheScriptSound( "Bullets.GunshipNearmiss" ); + CBaseEntity::PrecacheScriptSound( "Bullets.StriderNearmiss" ); + + CBaseEntity::PrecacheScriptSound( "Geiger.BeepHigh" ); + CBaseEntity::PrecacheScriptSound( "Geiger.BeepLow" ); +} + + +// called by ClientKill and DeadThink +void respawn( CBaseEntity *pEdict, bool fCopyCorpse ) +{ + CHL2MP_Player *pPlayer = ToHL2MPPlayer( pEdict ); + + if ( pPlayer ) + { + if ( gpGlobals->curtime > pPlayer->GetDeathTime() + DEATH_ANIMATION_TIME ) + { + // respawn player + pPlayer->Spawn(); + } + else + { + pPlayer->SetNextThink( gpGlobals->curtime + 0.1f ); + } + } +} + +void GameStartFrame( void ) +{ + VPROF("GameStartFrame()"); + if ( g_fGameOver ) + return; + + gpGlobals->teamplay = (teamplay.GetInt() != 0); + +#ifdef DEBUG + extern void Bot_RunAll(); + Bot_RunAll(); +#endif +} + +//========================================================= +// instantiate the proper game rules object +//========================================================= +void InstallGameRules() +{ + // vanilla deathmatch + CreateGameRulesObject( "CHL2MPRules" ); +} + diff --git a/mp/src/game/shared/gamemovement.cpp b/mp/src/game/shared/gamemovement.cpp index 6f5bc014..584c64c9 100644 --- a/mp/src/game/shared/gamemovement.cpp +++ b/mp/src/game/shared/gamemovement.cpp @@ -1735,8 +1735,10 @@ void CGameMovement::AirAccelerate( Vector& wishdir, float wishspeed, float accel return; // Cap speed - if ( wishspd > GetAirSpeedCap() ) - wishspd = GetAirSpeedCap(); + //if ( wishspd > GetAirSpeedCap() ) + //wishspd = GetAirSpeedCap(); + if (wishspd > 30.0f) + wishspd = 30.0f; // Determine veer amount currentspeed = mv->m_vecVelocity.Dot(wishdir); @@ -2519,8 +2521,8 @@ bool CGameMovement::CheckJumpButton( void ) // Add a little forward velocity based on your current forward velocity - if you are not sprinting. #if defined( HL2_DLL ) || defined( HL2_CLIENT_DLL ) - //if ( gpGlobals->maxClients == 1 ) - //{ + if ( gpGlobals->maxClients == 1 ) + { CHLMoveData *pMoveData = ( CHLMoveData* )mv; Vector vecForward; AngleVectors( mv->m_vecViewAngles, &vecForward ); @@ -2537,7 +2539,7 @@ bool CGameMovement::CheckJumpButton( void ) // If we're over the maximum, we want to only boost as much as will get us to the goal speed if ( flNewSpeed > flMaxSpeed ) { - //flSpeedAddition -= flNewSpeed - flMaxSpeed; + flSpeedAddition -= flNewSpeed - flMaxSpeed; } if ( mv->m_flForwardMove < 0.0f ) @@ -2545,7 +2547,7 @@ bool CGameMovement::CheckJumpButton( void ) // Add it on VectorAdd( (vecForward*flSpeedAddition), mv->m_vecVelocity, mv->m_vecVelocity ); - //} + } #endif FinishGravity(); @@ -2578,7 +2580,7 @@ bool CGameMovement::CheckJumpButton( void ) #endif //Commented out because idk why - else if (pPogoStick->GetInt() == 0 && pQueueJump->GetInt() == 1 && player->GetGroundEntity() != NULL) { + if (pPogoStick->GetInt() == 0 && pQueueJump->GetInt() == 1 && player->GetGroundEntity() != NULL) { // Flag that we jumped. mv->m_nOldButtons |= IN_JUMP; // don't jump again until released } @@ -3864,7 +3866,8 @@ void CGameMovement::CategorizePosition( void ) // Shooting up really fast. Definitely not on ground. // On ladder moving up, so not on ground either // NOTE: 145 is a jump. -#define NON_JUMP_VELOCITY 140.0f +//#define NON_JUMP_VELOCITY 140.0f +#define NON_JUMP_VELOCITY 190.0f float zvel = mv->m_vecVelocity[2]; bool bMovingUp = zvel > 0.0f; diff --git a/mp/src/game/shared/gamerules.cpp b/mp/src/game/shared/gamerules.cpp index 81fa7bfa..ed0c9d7d 100644 --- a/mp/src/game/shared/gamerules.cpp +++ b/mp/src/game/shared/gamerules.cpp @@ -513,7 +513,7 @@ void CGameRules::RadiusDamage( const CTakeDamageInfo &info, const Vector &vecSrc else { // Assume the force passed in is the maximum force. Decay it based on falloff. - float flForce = adjustedInfo.GetDamageForce().Length() * falloff; + float flForce = adjustedInfo.GetDamageForce().Length() * 200 * falloff; adjustedInfo.SetDamageForce( dir * flForce ); adjustedInfo.SetDamagePosition( vecSrc ); } diff --git a/mp/src/game/shared/hl2mp/hl2mp_gamerules.cpp b/mp/src/game/shared/hl2mp/hl2mp_gamerules.cpp index 604e409c..6bbd00e6 100644 --- a/mp/src/game/shared/hl2mp/hl2mp_gamerules.cpp +++ b/mp/src/game/shared/hl2mp/hl2mp_gamerules.cpp @@ -929,6 +929,10 @@ CAmmoDef *GetAmmoDef() def.AddAmmoType("Pistol", DMG_BULLET, TRACER_LINE_AND_WHIZ, 0, 0, 150, BULLET_IMPULSE(200, 1225), 0 ); def.AddAmmoType("SMG1", DMG_BULLET, TRACER_LINE_AND_WHIZ, 0, 0, 225, BULLET_IMPULSE(200, 1225), 0 ); def.AddAmmoType("357", DMG_BULLET, TRACER_LINE_AND_WHIZ, 0, 0, 12, BULLET_IMPULSE(800, 5000), 0 ); + def.AddAmmoType("Rail", DMG_BULLET, TRACER_LINE_AND_WHIZ, 0, 0, 15, BULLET_IMPULSE(800, 5000), 0); + def.AddAmmoType("Laser", DMG_BULLET, TRACER_LINE_AND_WHIZ, 0, 0, 200, BULLET_IMPULSE(200, 1225), 0); + def.AddAmmoType("Rocket", DMG_BURN, TRACER_LINE_AND_WHIZ, 0, 0, 30, 0, 0); + def.AddAmmoType("Shottie", DMG_BULLET | DMG_BUCKSHOT, TRACER_LINE, 0, 0, 30, BULLET_IMPULSE(400, 1200), 0); def.AddAmmoType("XBowBolt", DMG_BULLET, TRACER_LINE, 0, 0, 10, BULLET_IMPULSE(800, 8000), 0 ); def.AddAmmoType("Buckshot", DMG_BULLET | DMG_BUCKSHOT, TRACER_LINE, 0, 0, 30, BULLET_IMPULSE(400, 1200), 0 ); def.AddAmmoType("RPG_Round", DMG_BURN, TRACER_NONE, 0, 0, 3, 0, 0 ); diff --git a/mp/src/game/shared/hl2mp/hl2mp_weapon_parse.cpp b/mp/src/game/shared/hl2mp/hl2mp_weapon_parse.cpp index 9b83dce7..d3a766f3 100644 --- a/mp/src/game/shared/hl2mp/hl2mp_weapon_parse.cpp +++ b/mp/src/game/shared/hl2mp/hl2mp_weapon_parse.cpp @@ -19,6 +19,7 @@ FileWeaponInfo_t* CreateWeaponInfo() CHL2MPSWeaponInfo::CHL2MPSWeaponInfo() { m_iPlayerDamage = 0; + m_iOwnedPickupAmmo = 0; } diff --git a/mp/src/game/shared/igamemovement.h b/mp/src/game/shared/igamemovement.h index a414727c..fbf0ea25 100644 --- a/mp/src/game/shared/igamemovement.h +++ b/mp/src/game/shared/igamemovement.h @@ -40,7 +40,7 @@ class CMoveData public: bool m_bFirstRunOfFunctions : 1; bool m_bGameCodeMovedPlayer : 1; - bool m_bRejumpAllowed = 1; //keeping track of allowed jump status SA + bool m_bRejumpAllowed : 1; //keeping track of allowed jump status SA EntityHandle_t m_nPlayerHandle; // edict index on server, client entity handle on client diff --git a/mp/src/game/shared/movevars_shared.cpp b/mp/src/game/shared/movevars_shared.cpp index af659838..9b704d81 100644 --- a/mp/src/game/shared/movevars_shared.cpp +++ b/mp/src/game/shared/movevars_shared.cpp @@ -49,7 +49,7 @@ ConVar sv_specspeed ( "sv_specspeed", "3", FCVAR_ARCHIVE | FCVAR_NOTIFY | FCVAR_ ConVar sv_specnoclip ( "sv_specnoclip", "1", FCVAR_ARCHIVE | FCVAR_NOTIFY | FCVAR_REPLICATED); #if defined( CSTRIKE_DLL ) || defined( HL1MP_DLL ) || defined( SArena_DLL ) -ConVar sv_maxspeed ( "sv_maxspeed", "320", FCVAR_NOTIFY | FCVAR_REPLICATED); +ConVar sv_maxspeed ( "sv_maxspeed", "400", FCVAR_NOTIFY | FCVAR_REPLICATED); #else ConVar sv_maxspeed ( "sv_maxspeed", "320", FCVAR_NOTIFY | FCVAR_REPLICATED | FCVAR_DEVELOPMENTONLY); #endif // CSTRIKE_DLL diff --git a/mp/src/game/shared/sarena/weapon_hatchet.cpp b/mp/src/game/shared/sarena/weapon_hatchet.cpp new file mode 100644 index 00000000..91519b68 --- /dev/null +++ b/mp/src/game/shared/sarena/weapon_hatchet.cpp @@ -0,0 +1,228 @@ +//========= Copyright Valve Corporation, All rights reserved. ============// +// +// Purpose: Hatchet - an old favorite +// +// $NoKeywords: $ +//=============================================================================// + +#include "cbase.h" +#include "sarena/weapon_hatchet.h" +#include "weapon_hl2mpbasehlmpcombatweapon.h" +#include "gamerules.h" +#include "ammodef.h" +#include "mathlib/mathlib.h" +#include "in_buttons.h" +#include "vstdlib/random.h" +#include "npcevent.h" + +#if defined( CLIENT_DLL ) + #include "c_hl2mp_player.h" +#else + #include "hl2mp_player.h" + #include "ai_basenpc.h" +#endif + + +// memdbgon must be the last include file in a .cpp file!!! +#include "tier0/memdbgon.h" + +#define hatchet_RANGE 75.0f +#define hatchet_REFIRE 0.4f + + +//----------------------------------------------------------------------------- +// CWeaponHatchet +//----------------------------------------------------------------------------- + +IMPLEMENT_NETWORKCLASS_ALIASED( WeaponHatchet, DT_WeaponHatchet ) + +BEGIN_NETWORK_TABLE( CWeaponHatchet, DT_WeaponHatchet ) +END_NETWORK_TABLE() + +BEGIN_PREDICTION_DATA( CWeaponHatchet ) +END_PREDICTION_DATA() + +LINK_ENTITY_TO_CLASS( weapon_hatchet, CWeaponHatchet ); +PRECACHE_WEAPON_REGISTER( weapon_hatchet ); + +#ifndef CLIENT_DLL + +acttable_t CWeaponHatchet::m_acttable[] = +{ + { ACT_RANGE_ATTACK1, ACT_RANGE_ATTACK_SLAM, true }, + { ACT_HL2MP_IDLE, ACT_HL2MP_IDLE_MELEE, false }, + { ACT_HL2MP_RUN, ACT_HL2MP_RUN_MELEE, false }, + { ACT_HL2MP_IDLE_CROUCH, ACT_HL2MP_IDLE_CROUCH_MELEE, false }, + { ACT_HL2MP_WALK_CROUCH, ACT_HL2MP_WALK_CROUCH_MELEE, false }, + { ACT_HL2MP_GESTURE_RANGE_ATTACK, ACT_HL2MP_GESTURE_RANGE_ATTACK_MELEE, false }, + { ACT_HL2MP_GESTURE_RELOAD, ACT_HL2MP_GESTURE_RELOAD_MELEE, false }, + { ACT_HL2MP_JUMP, ACT_HL2MP_JUMP_MELEE, false }, +}; + +IMPLEMENT_ACTTABLE(CWeaponHatchet); + +#endif + +//----------------------------------------------------------------------------- +// Constructor +//----------------------------------------------------------------------------- +CWeaponHatchet::CWeaponHatchet( void ) +{ +} + +//----------------------------------------------------------------------------- +// Purpose: Get the damage amount for the animation we're doing +// Input : hitActivity - currently played activity +// Output : Damage amount +//----------------------------------------------------------------------------- +float CWeaponHatchet::GetDamageForActivity( Activity hitActivity ) +{ + return 25.0f; +} + +//----------------------------------------------------------------------------- +// Purpose: Add in a view kick for this weapon +//----------------------------------------------------------------------------- +void CWeaponHatchet::AddViewKick( void ) +{ + CBasePlayer *pPlayer = ToBasePlayer( GetOwner() ); + + if ( pPlayer == NULL ) + return; + + QAngle punchAng; + + punchAng.x = SharedRandomFloat( "hatchetpax", 1.0f, 2.0f ); + punchAng.y = SharedRandomFloat( "hatchetpay", -2.0f, -1.0f ); + punchAng.z = 0.0f; + + pPlayer->ViewPunch( punchAng ); +} + + +#ifndef CLIENT_DLL +//----------------------------------------------------------------------------- +// Animation event handlers +//----------------------------------------------------------------------------- +void CWeaponHatchet::HandleAnimEventMeleeHit( animevent_t *pEvent, CBaseCombatCharacter *pOperator ) +{ + // Trace up or down based on where the enemy is... + // But only if we're basically facing that direction + Vector vecDirection; + AngleVectors( GetAbsAngles(), &vecDirection ); + + Vector vecEnd; + VectorMA( pOperator->Weapon_ShootPosition(), 50, vecDirection, vecEnd ); + CBaseEntity *pHurt = pOperator->CheckTraceHullAttack( pOperator->Weapon_ShootPosition(), vecEnd, + Vector(-16,-16,-16), Vector(36,36,36), GetDamageForActivity( GetActivity() ), DMG_CLUB, 0.75 ); + + // did I hit someone? + if ( pHurt ) + { + // play sound + WeaponSound( MELEE_HIT ); + + // Fake a trace impact, so the effects work out like a player's crowbaw + trace_t traceHit; + UTIL_TraceLine( pOperator->Weapon_ShootPosition(), pHurt->GetAbsOrigin(), MASK_SHOT_HULL, pOperator, COLLISION_GROUP_NONE, &traceHit ); + ImpactEffect( traceHit ); + } + else + { + WeaponSound( MELEE_MISS ); + } +} + + +//----------------------------------------------------------------------------- +// Animation event +//----------------------------------------------------------------------------- +void CWeaponHatchet::Operator_HandleAnimEvent( animevent_t *pEvent, CBaseCombatCharacter *pOperator ) +{ + switch( pEvent->event ) + { + case EVENT_WEAPON_MELEE_HIT: + HandleAnimEventMeleeHit( pEvent, pOperator ); + break; + + default: + BaseClass::Operator_HandleAnimEvent( pEvent, pOperator ); + break; + } +} + +//----------------------------------------------------------------------------- +// Attempt to lead the target (needed because citizens can't hit manhacks with the hatchet!) +//----------------------------------------------------------------------------- +ConVar sk_hatchet_lead_time( "sk_hatchet_lead_time", "0.9" ); + +int CWeaponHatchet::WeaponMeleeAttack1Condition( float flDot, float flDist ) +{ + // Attempt to lead the target (needed because citizens can't hit manhacks with the hatchet!) + CAI_BaseNPC *pNPC = GetOwner()->MyNPCPointer(); + CBaseEntity *pEnemy = pNPC->GetEnemy(); + if (!pEnemy) + return COND_NONE; + + Vector vecVelocity; + vecVelocity = pEnemy->GetSmoothedVelocity( ); + + // Project where the enemy will be in a little while + float dt = sk_hatchet_lead_time.GetFloat(); + dt += SharedRandomFloat( "hatchetmelee1", -0.3f, 0.2f ); + if ( dt < 0.0f ) + dt = 0.0f; + + Vector vecExtrapolatedPos; + VectorMA( pEnemy->WorldSpaceCenter(), dt, vecVelocity, vecExtrapolatedPos ); + + Vector vecDelta; + VectorSubtract( vecExtrapolatedPos, pNPC->WorldSpaceCenter(), vecDelta ); + + if ( fabs( vecDelta.z ) > 70 ) + { + return COND_TOO_FAR_TO_ATTACK; + } + + Vector vecForward = pNPC->BodyDirection2D( ); + vecDelta.z = 0.0f; + float flExtrapolatedDist = Vector2DNormalize( vecDelta.AsVector2D() ); + if ((flDist > 64) && (flExtrapolatedDist > 64)) + { + return COND_TOO_FAR_TO_ATTACK; + } + + float flExtrapolatedDot = DotProduct2D( vecDelta.AsVector2D(), vecForward.AsVector2D() ); + if ((flDot < 0.7) && (flExtrapolatedDot < 0.7)) + { + return COND_NOT_FACING_ATTACK; + } + + return COND_CAN_MELEE_ATTACK1; +} + +#endif + + + +//----------------------------------------------------------------------------- +// Purpose: +//----------------------------------------------------------------------------- +void CWeaponHatchet::Drop( const Vector &vecVelocity ) +{ +#ifndef CLIENT_DLL + UTIL_Remove( this ); +#endif +} + +float CWeaponHatchet::GetRange( void ) +{ + return hatchet_RANGE; +} + +float CWeaponHatchet::GetFireRate( void ) +{ + return hatchet_REFIRE; +} + + diff --git a/mp/src/game/shared/sarena/weapon_hatchet.h b/mp/src/game/shared/sarena/weapon_hatchet.h new file mode 100644 index 00000000..3f8e131c --- /dev/null +++ b/mp/src/game/shared/sarena/weapon_hatchet.h @@ -0,0 +1,70 @@ +//========= Copyright Valve Corporation, All rights reserved. ============// +// +// Purpose: +// +// $Workfile: $ +// $Date: $ +// +//----------------------------------------------------------------------------- +// $Log: $ +// +// $NoKeywords: $ +//=============================================================================// + +#ifndef SARENA_WEAPON_HATCHET_H +#define SARENA_WEAPON_HATCHET_H +#pragma once + + +#include "weapon_hl2mpbasehlmpcombatweapon.h" +#include "weapon_hl2mpbasebasebludgeon.h" + + +#ifdef CLIENT_DLL +#define CWeaponHatchet C_WeaponHatchet +#endif + +//----------------------------------------------------------------------------- +// CWeaponHatchet +//----------------------------------------------------------------------------- + +class CWeaponHatchet : public CBaseHL2MPBludgeonWeapon +{ +public: + DECLARE_CLASS( CWeaponHatchet, CBaseHL2MPBludgeonWeapon ); + + DECLARE_NETWORKCLASS(); + DECLARE_PREDICTABLE(); + +#ifndef CLIENT_DLL + DECLARE_ACTTABLE(); +#endif + + CWeaponHatchet(); + + float GetRange( void ); + float GetFireRate( void ); + + void AddViewKick( void ); + float GetDamageForActivity( Activity hitActivity ); + void SecondaryAttack( void ) { return; } + + void Drop( const Vector &vecVelocity ); + + + // Animation event +#ifndef CLIENT_DLL + virtual void Operator_HandleAnimEvent( animevent_t *pEvent, CBaseCombatCharacter *pOperator ); + void HandleAnimEventMeleeHit( animevent_t *pEvent, CBaseCombatCharacter *pOperator ); + int WeaponMeleeAttack1Condition( float flDot, float flDist ); +#endif + + CWeaponHatchet( const CWeaponHatchet & ); + +private: + +}; + + +#endif // HL2MP_WEAPON_CROWBAR_H + diff --git a/mp/src/game/shared/sarena/weapon_lasergun.cpp b/mp/src/game/shared/sarena/weapon_lasergun.cpp new file mode 100644 index 00000000..8ae1ea2e --- /dev/null +++ b/mp/src/game/shared/sarena/weapon_lasergun.cpp @@ -0,0 +1,179 @@ +#include "cbase.h" +#include "npcevent.h" +#include "in_buttons.h" + + +#ifdef CLIENT_DLL +#include "c_hl2mp_player.h" +#else +#include "grenade_ar2.h" +#include "hl2mp_player.h" +#include "basegrenade_shared.h" +#endif + +#include "weapon_hl2mpbase.h" +#include "weapon_hl2mpbase_machinegun.h" + +#ifdef CLIENT_DLL +#define CWeaponLasergun C_WeaponLasergun +#endif + +#include "tier0\memdbgon.h" + +class CWeaponLasergun : public CHL2MPMachineGun +{ + + +public: + DECLARE_CLASS(CWeaponLasergun, CHL2MPMachineGun); + + + + CWeaponLasergun(); + DECLARE_NETWORKCLASS(); + DECLARE_PREDICTABLE(); + + void Precache(); + void ItemPreFrame(); + void ItemBusyFrame(); + void ItemPostFrame(); + void PrimaryAttack(); + void AddViewKick(); + void DryFire(); + virtual bool Reload(void); + virtual const Vector& GetBulletSpread() + { + static Vector cone = VECTOR_CONE_1DEGREES, npcCone = VECTOR_CONE_1DEGREES; + if (GetOwner() && GetOwner()->IsNPC()) //Always handle NPCs first + return npcCone; + else + return cone; + } + +#ifndef CLIENT_DLL + DECLARE_ACTTABLE(); + CWeaponLasergun(const CWeaponLasergun &); +#endif + + +private: + float m_flRateOfFire; +}; + + +IMPLEMENT_NETWORKCLASS_ALIASED( WeaponLasergun, DT_WeaponLasergun) + +BEGIN_NETWORK_TABLE( CWeaponLasergun, DT_WeaponLasergun) +END_NETWORK_TABLE() + +BEGIN_PREDICTION_DATA(CWeaponLasergun) +END_PREDICTION_DATA() + +LINK_ENTITY_TO_CLASS(weapon_lasergun, CWeaponLasergun); +PRECACHE_WEAPON_REGISTER(weapon_lasergun); + +#ifndef CLIENT_DLL +acttable_t CWeaponLasergun::m_acttable[] = +{ + { ACT_RANGE_ATTACK1, ACT_RANGE_ATTACK_SMG1, true }, + { ACT_RELOAD, ACT_RELOAD_SMG1, true }, + { ACT_IDLE, ACT_IDLE_SMG1, true }, + { ACT_IDLE_ANGRY, ACT_IDLE_ANGRY_SMG1, true }, + { ACT_WALK, ACT_WALK_RIFLE, true }, + { ACT_WALK_AIM, ACT_WALK_AIM_RIFLE, true }, +}; + +IMPLEMENT_ACTTABLE(CWeaponLasergun); +#endif + +CWeaponLasergun::CWeaponLasergun() +{ + m_fMinRange1 = 24; + m_fMaxRange1 = 3000; + m_bFiresUnderwater = true; +} +void CWeaponLasergun::Precache() +{ + m_flRateOfFire = 0.05f; +#ifndef CLIENT_DLL + PrecacheModel("models/weapons/v_lasergun.mdl", true); + PrecacheModel("models/weapons/w_lasergun.mdl", true); +#endif + BaseClass::Precache(); +} +void CWeaponLasergun::DryFire() +{ + WeaponSound(EMPTY); + SendWeaponAnim(ACT_VM_DRYFIRE); + + m_flNextPrimaryAttack = gpGlobals->curtime + SequenceDuration(); +} +void CWeaponLasergun::ItemPreFrame() +{ + BaseClass::ItemPreFrame(); +} + +void CWeaponLasergun::ItemBusyFrame() +{ + BaseClass::ItemBusyFrame(); +} + +void CWeaponLasergun::ItemPostFrame() +{ + BaseClass::ItemPostFrame(); +} +void CWeaponLasergun::PrimaryAttack() +{ + CBasePlayer* pPlayer = ToBasePlayer(GetOwner()); //This gets the current player holding the weapon + Vector vecSrc = pPlayer->Weapon_ShootPosition(); //This simply just gets the current position of the player. + Vector vecAim = pPlayer->GetAutoaimVector(0.0); //This gets where the player is looking, but also corrected by autoaim. + + FireBulletsInfo_t info(1, vecSrc, vecAim, vec3_origin, MAX_TRACE_LENGTH, m_iPrimaryAmmoType); + //if (m_iClip1 <= 0) + if (pPlayer->GetAmmoCount(m_iPrimaryAmmoType) <= 0) + { + if (!m_bFireOnEmpty) + { + Reload(); + } + else + { + WeaponSound(EMPTY); + m_flNextPrimaryAttack = 0.15; + } + + return; + } + pPlayer->FireBullets(info); + + //This is a lengthy one. All of the args in here are data for our bullet. We could simply use + //BaseClass::PrimaryAttack, but this gives us no control over how our weapon is fired. + //So instead, we use this and give it all our info for our bullet. + //The next 2 are just where the bullet is being fired from and where it should go. + //Next is how far the bullet is fired, and after that is what type of ammo we use. + //After this is the tracer freq, which really doesnt matter. + //Next is the id of the entity firing the weapon, and the attachment id. These 2 dont really matter. + //Next is how much damage each bullet should do, which is 30. + //Next is what entity is firing the bullet, again. + //The final 2 define wether our first shot should be accurate, and wether this is the primary attack. + WeaponSound(SINGLE); //This makes our weapon emit the single show sound. + SendWeaponAnim(ACT_VM_PRIMARYATTACK); //This sends the animation for us shooting. + m_flNextPrimaryAttack = gpGlobals->curtime + m_flRateOfFire; //This defines when our next attack should be + //m_iClip1--; + pPlayer->RemoveAmmo(1, m_iPrimaryAmmoType); + //AddViewKick(); //Don't forget to add our viewkick +} +void CWeaponLasergun::AddViewKick() +{ + CBasePlayer* pPlayer = ToBasePlayer(GetOwner()); + QAngle punch; + punch += QAngle(-0.2, 0.0, 0.0); + pPlayer->ViewPunch(punch); +} +bool CWeaponLasergun::Reload() +{ + bool fRet = DefaultReload(GetMaxClip1(), GetMaxClip2(), ACT_VM_RELOAD); + if (fRet) + WeaponSound(RELOAD); + return fRet; +} \ No newline at end of file diff --git a/mp/src/game/shared/sarena/weapon_railgun.cpp b/mp/src/game/shared/sarena/weapon_railgun.cpp new file mode 100644 index 00000000..88f76dfd --- /dev/null +++ b/mp/src/game/shared/sarena/weapon_railgun.cpp @@ -0,0 +1,177 @@ +#include "cbase.h" +#include "npcevent.h" +#include "in_buttons.h" + +#ifdef CLIENT_DLL +#include "c_hl2mp_player.h" +#else +#include "hl2mp_player.h" +#endif + +#include "weapon_hl2mpbasehlmpcombatweapon.h" +//#include "particle_parse.h" + +#ifdef CLIENT_DLL +#define CWeaponRailgun C_WeaponRailgun +#endif + + +//----------------------------------------------------------------------------- +// CWeaponRailgun +//----------------------------------------------------------------------------- + +class CWeaponRailgun : public CBaseHL2MPCombatWeapon +{ + DECLARE_CLASS(CWeaponRailgun, CBaseHL2MPCombatWeapon); +public: + + CWeaponRailgun(void); + + //void Precache(void); + + void PrimaryAttack(void); + DECLARE_NETWORKCLASS(); + DECLARE_PREDICTABLE(); + +#ifndef CLIENT_DLL + DECLARE_ACTTABLE(); +#endif + +private: + + CWeaponRailgun(const CWeaponRailgun&); +}; + + +IMPLEMENT_NETWORKCLASS_ALIASED(WeaponRailgun, DT_WeaponRailgun) + +BEGIN_NETWORK_TABLE(CWeaponRailgun, DT_WeaponRailgun) +END_NETWORK_TABLE() + +BEGIN_PREDICTION_DATA(CWeaponRailgun) +END_PREDICTION_DATA() + +LINK_ENTITY_TO_CLASS(weapon_railgun, CWeaponRailgun); +PRECACHE_WEAPON_REGISTER(weapon_railgun); + + + +#ifndef CLIENT_DLL +acttable_t CWeaponRailgun::m_acttable[] = +{ + { ACT_HL2MP_IDLE, ACT_HL2MP_IDLE_PISTOL, false }, + { ACT_HL2MP_RUN, ACT_HL2MP_RUN_PISTOL, false }, + { ACT_HL2MP_IDLE_CROUCH, ACT_HL2MP_IDLE_CROUCH_PISTOL, false }, + { ACT_HL2MP_WALK_CROUCH, ACT_HL2MP_WALK_CROUCH_PISTOL, false }, + { ACT_HL2MP_GESTURE_RANGE_ATTACK, ACT_HL2MP_GESTURE_RANGE_ATTACK_PISTOL, false }, + { ACT_HL2MP_GESTURE_RELOAD, ACT_HL2MP_GESTURE_RELOAD_PISTOL, false }, + { ACT_HL2MP_JUMP, ACT_HL2MP_JUMP_PISTOL, false }, + { ACT_RANGE_ATTACK1, ACT_RANGE_ATTACK_PISTOL, false }, +}; + + + +IMPLEMENT_ACTTABLE(CWeaponRailgun); + +#endif + + +//----------------------------------------------------------------------------- +// Purpose: Constructor +//----------------------------------------------------------------------------- +CWeaponRailgun::CWeaponRailgun(void) +{ + m_bReloadsSingly = false; + m_bFiresUnderwater = false; +} + +//void CWeaponRailgun::Precache(void) +//{ + //PrecacheParticleSystem("railbeam"); + + //BaseClass::Precache(); +//} + +//----------------------------------------------------------------------------- +// Purpose: +//----------------------------------------------------------------------------- +void CWeaponRailgun::PrimaryAttack(void) +{ + // Only the player fires this way so we can cast + CBasePlayer* pPlayer = ToBasePlayer(GetOwner()); + + if (!pPlayer) + { + return; + } + + //if (m_iClip1 <= 0) + if (pPlayer->GetAmmoCount(m_iPrimaryAmmoType) <=0) + { + if (!m_bFireOnEmpty) + { + Reload(); + } + else + { + WeaponSound(EMPTY); + m_flNextPrimaryAttack = 0.15; + } + + return; + } + + WeaponSound(SINGLE); + pPlayer->DoMuzzleFlash(); + + SendWeaponAnim(ACT_VM_PRIMARYATTACK); + pPlayer->SetAnimation(PLAYER_ATTACK1); + + m_flNextPrimaryAttack = gpGlobals->curtime + 1.5; + m_flNextSecondaryAttack = gpGlobals->curtime + 1.5; + + //m_iClip1--; + pPlayer->RemoveAmmo(1, m_iPrimaryAmmoType); + + Vector vecSrc = pPlayer->Weapon_ShootPosition(); + Vector vecAiming = pPlayer->GetAutoaimVector(AUTOAIM_5DEGREES); + + FireBulletsInfo_t info(1, vecSrc, vecAiming, vec3_origin, MAX_TRACE_LENGTH, m_iPrimaryAmmoType); + info.m_pAttacker = pPlayer; + + // Particle Tracer + //Vector vecShootOrigin2; //The origin of the shot + //QAngle angShootDir2; //The angle of the shot + //We need to figure out where to place the particle effect, so lookup where the muzzle is + //Vector vForward, vRight, vUp; + //CBasePlayer* pOwner = ToBasePlayer(GetOwner()); + //pOwner->EyeVectors(&vForward, &vRight, &vUp); + //Vector vecSrc = pPlayer->Weapon_ShootPosition() + vForward * 12.0f + vRight * 6.0f + vUp * -3.0f; + //Vector vecSrc = vecShootOrigin2 + vForward * 20.0f + vUp * 25.0f; + //GetAttachment(LookupAttachment("muzzle"), vecShootOrigin2, angShootDir2); + //DispatchParticleEffect("railbeam", pPlayer->Weapon_ShootPosition(), angShootDir2); + //CNewParticleEffect* pEffect = ParticleProp()->FindEffect("railbeam"); + //pEffect->SetControlPoint(1, vecShootOrigin2 + vForward * 100); + + // Fire the bullets, and force the first shot to be perfectly accuracy + pPlayer->FireBullets(info); + + //Disorient the player + QAngle angles = pPlayer->GetLocalAngles(); + + //angles.x += random->RandomInt(-1, 1); + //angles.y += random->RandomInt(-1, 1); + //angles.z = 0; + +#ifndef CLIENT_DLL + pPlayer->SnapEyeAngles(angles); +#endif + + //pPlayer->ViewPunch(QAngle(-8, random->RandomFloat(-2, 2), 0)); + + if (!m_iClip1 && pPlayer->GetAmmoCount(m_iPrimaryAmmoType) <= 0) + { + // HEV suit - indicate out of ammo condition + pPlayer->SetSuitUpdate("!HEV_AMO0", FALSE, 0); + } +} diff --git a/mp/src/game/shared/sarena/weapon_rocketlauncher.cpp b/mp/src/game/shared/sarena/weapon_rocketlauncher.cpp new file mode 100644 index 00000000..cf427f4a --- /dev/null +++ b/mp/src/game/shared/sarena/weapon_rocketlauncher.cpp @@ -0,0 +1,172 @@ +//========= Copyright Valve Corporation, All rights reserved. ============// +// +// Purpose: +// +//=============================================================================// + +#include "cbase.h" +#include "npcevent.h" +#include "in_buttons.h" + +#ifdef CLIENT_DLL +#include "c_hl2mp_player.h" +#else +#include "projectile_rocket.h" +#include "hl2mp_player.h" +#include "basegrenade_shared.h" +#endif + + +#include "weapon_hl2mpbase.h" +#include "weapon_hl2mpbase_machinegun.h" +#include "weapon_hl2mpbasehlmpcombatweapon.h" + + +#define PROJECTILE_ROCKET_DAMAGE 100.0f +#define PROJECTILE_ROCKET_RADIUS 250.0f + + +#ifdef CLIENT_DLL +#define CWeaponRocketlauncher C_WeaponRocketlauncher +#endif + + +// memdbgon must be the last include file in a .cpp file!!! +#include "tier0/memdbgon.h" + + + + + +//----------------------------------------------------------------------------- +// CWeaponRocketlauncher +//----------------------------------------------------------------------------- + +class CWeaponRocketlauncher : public CBaseHL2MPCombatWeapon +{ + DECLARE_CLASS(CWeaponRocketlauncher, CBaseHL2MPCombatWeapon); +public: + + CWeaponRocketlauncher(void); + + void PrimaryAttack(void); + DECLARE_NETWORKCLASS(); + DECLARE_PREDICTABLE(); + +#ifndef CLIENT_DLL + DECLARE_ACTTABLE(); +#endif + +private: + + CWeaponRocketlauncher(const CWeaponRocketlauncher&); +}; + +IMPLEMENT_NETWORKCLASS_ALIASED(WeaponRocketlauncher, DT_WeaponRocketlauncher) + +BEGIN_NETWORK_TABLE(CWeaponRocketlauncher, DT_WeaponRocketlauncher) +END_NETWORK_TABLE() + +BEGIN_PREDICTION_DATA(CWeaponRocketlauncher) +END_PREDICTION_DATA() + +LINK_ENTITY_TO_CLASS(weapon_Rocketlauncher, CWeaponRocketlauncher); +PRECACHE_WEAPON_REGISTER(weapon_Rocketlauncher); + + +#ifndef CLIENT_DLL +acttable_t CWeaponRocketlauncher::m_acttable[] = +{ + { ACT_HL2MP_IDLE, ACT_HL2MP_IDLE_PISTOL, false }, + { ACT_HL2MP_RUN, ACT_HL2MP_RUN_PISTOL, false }, + { ACT_HL2MP_IDLE_CROUCH, ACT_HL2MP_IDLE_CROUCH_PISTOL, false }, + { ACT_HL2MP_WALK_CROUCH, ACT_HL2MP_WALK_CROUCH_PISTOL, false }, + { ACT_HL2MP_GESTURE_RANGE_ATTACK, ACT_HL2MP_GESTURE_RANGE_ATTACK_PISTOL, false }, + { ACT_HL2MP_GESTURE_RELOAD, ACT_HL2MP_GESTURE_RELOAD_PISTOL, false }, + { ACT_HL2MP_JUMP, ACT_HL2MP_JUMP_PISTOL, false }, + { ACT_RANGE_ATTACK1, ACT_RANGE_ATTACK_PISTOL, false }, +}; + + + +IMPLEMENT_ACTTABLE(CWeaponRocketlauncher); + +#endif + +//----------------------------------------------------------------------------- +// Purpose: Constructor +//----------------------------------------------------------------------------- +CWeaponRocketlauncher::CWeaponRocketlauncher(void) +{ + m_bReloadsSingly = false; + m_bFiresUnderwater = false; +} + +//----------------------------------------------------------------------------- +// Purpose: +//----------------------------------------------------------------------------- +void CWeaponRocketlauncher::PrimaryAttack(void) +{ + // Only the player fires this way so we can cast + CBasePlayer* pPlayer = ToBasePlayer(GetOwner()); + + if (pPlayer == NULL) + return; + + //Must have ammo + if ((pPlayer->GetAmmoCount(m_iPrimaryAmmoType) <= 0) || (pPlayer->GetWaterLevel() == 3)) + { + SendWeaponAnim(ACT_VM_DRYFIRE); + BaseClass::WeaponSound(EMPTY); + m_flNextPrimaryAttack = gpGlobals->curtime + 0.5f; + return; + } + + if (m_bInReload) + m_bInReload = false; + + // MUST call sound before removing a round from the clip of a CMachineGun + BaseClass::WeaponSound(WPN_DOUBLE); + Vector vecShootOrigin2; + QAngle angShootDir2; + this->GetAttachment(LookupAttachment("muzzle"), vecShootOrigin2, angShootDir2); + + + + Vector vForward, vRight, vUp; + CBasePlayer* pOwner = ToBasePlayer(GetOwner()); + pOwner->EyeVectors(&vForward, &vRight, &vUp); + //Vector vecSrc = pPlayer->Weapon_ShootPosition() + vForward * 12.0f + vRight * 6.0f + vUp * -3.0f; + //Vector vecSrc = vecShootOrigin2 + vForward * 20.0f + vUp * 25.0f; + + Vector vecSrc = pPlayer->Weapon_ShootPosition(); + + Vector vecThrow; + // Don't autoaim on grenade tosses + AngleVectors(pPlayer->EyeAngles() + pPlayer->GetPunchAngle(), &vecThrow); + VectorScale(vecThrow, 2000.0f, vecThrow); + +#ifndef CLIENT_DLL + //Create the grenade + CProjectileRocket* pRocket = (CProjectileRocket*)Create("projectile_rocket", vecSrc, vec3_angle, pPlayer); + pRocket->SetAbsVelocity(vecThrow); + + pRocket->SetLocalAngularVelocity(RandomAngle(-400, 400)); + pRocket->SetMoveType(MOVETYPE_FLY, MOVECOLLIDE_FLY_BOUNCE); + pRocket->SetThrower(GetOwner()); + pRocket->SetDamage(PROJECTILE_ROCKET_DAMAGE); + pRocket->SetDamageRadius(PROJECTILE_ROCKET_RADIUS); +#endif + + SendWeaponAnim(ACT_VM_PRIMARYATTACK); + + // player "shoot" animation + pPlayer->SetAnimation(PLAYER_ATTACK1); + + // Decrease ammo + pPlayer->RemoveAmmo(1, m_iPrimaryAmmoType); + //m_nNumShotsFired++; + + // Can shoot again immediately + m_flNextPrimaryAttack = gpGlobals->curtime + 1.0f; +} diff --git a/mp/src/game/shared/sarena/weapon_shottie.cpp b/mp/src/game/shared/sarena/weapon_shottie.cpp new file mode 100644 index 00000000..8bf4800f --- /dev/null +++ b/mp/src/game/shared/sarena/weapon_shottie.cpp @@ -0,0 +1,192 @@ +//========= Copyright Valve Corporation, All rights reserved. ============// +// +// Purpose: +// +//=============================================================================// + +#include "cbase.h" +#include "npcevent.h" +#include "in_buttons.h" + +#ifdef CLIENT_DLL +#include "c_hl2mp_player.h" +#else +#include "hl2mp_player.h" +#endif + +#include "weapon_hl2mpbasehlmpcombatweapon.h" + +#ifdef CLIENT_DLL +#define CWeaponShottie C_WeaponShottie +#endif + +//extern ConVar sk_auto_reload_time; +//extern ConVar sk_plr_num_shotgun_pellets; + +class CWeaponShottie : public CBaseHL2MPCombatWeapon +{ +public: + DECLARE_CLASS(CWeaponShottie, CBaseHL2MPCombatWeapon); + + DECLARE_NETWORKCLASS(); + DECLARE_PREDICTABLE(); + +private: + + +public: + virtual const Vector& GetBulletSpread(void) + { + static Vector cone = VECTOR_CONE_10DEGREES; + return cone; + } + + virtual int GetMinBurst() { return 1; } + virtual int GetMaxBurst() { return 3; } + + void PrimaryAttack(void); + virtual float GetFireRate(void) { return 0.7; }; + +#ifndef CLIENT_DLL + DECLARE_ACTTABLE(); +#endif + + CWeaponShottie(void); + +private: + CWeaponShottie(const CWeaponShottie&); +}; + +IMPLEMENT_NETWORKCLASS_ALIASED(WeaponShottie, DT_WeaponShottie) + +BEGIN_NETWORK_TABLE(CWeaponShottie, DT_WeaponShottie) +#ifdef CLIENT_DLL + +#else + +#endif +END_NETWORK_TABLE() + +#ifdef CLIENT_DLL +BEGIN_PREDICTION_DATA(CWeaponShottie) + +END_PREDICTION_DATA() +#endif + +LINK_ENTITY_TO_CLASS(weapon_shottie, CWeaponShottie); +PRECACHE_WEAPON_REGISTER(weapon_shottie); + +#ifndef CLIENT_DLL +acttable_t CWeaponShottie::m_acttable[] = +{ + { ACT_HL2MP_IDLE, ACT_HL2MP_IDLE_SHOTGUN, false }, + { ACT_HL2MP_RUN, ACT_HL2MP_RUN_SHOTGUN, false }, + { ACT_HL2MP_IDLE_CROUCH, ACT_HL2MP_IDLE_CROUCH_SHOTGUN, false }, + { ACT_HL2MP_WALK_CROUCH, ACT_HL2MP_WALK_CROUCH_SHOTGUN, false }, + { ACT_HL2MP_GESTURE_RANGE_ATTACK, ACT_HL2MP_GESTURE_RANGE_ATTACK_SHOTGUN, false }, + { ACT_HL2MP_GESTURE_RELOAD, ACT_HL2MP_GESTURE_RELOAD_SHOTGUN, false }, + { ACT_HL2MP_JUMP, ACT_HL2MP_JUMP_SHOTGUN, false }, + { ACT_RANGE_ATTACK1, ACT_RANGE_ATTACK_SHOTGUN, false }, +}; + +IMPLEMENT_ACTTABLE(CWeaponShottie); + +#endif + + + +//----------------------------------------------------------------------------- +// Purpose: +//----------------------------------------------------------------------------- +void CWeaponShottie::PrimaryAttack(void) +{ + // Only the player fires this way so we can cast + CBasePlayer* pPlayer = ToBasePlayer(GetOwner()); + + if (!pPlayer) + { + return; + } + + //if (m_iClip1 <= 0) + if (pPlayer->GetAmmoCount(m_iPrimaryAmmoType) <= 0) + { + if (!m_bFireOnEmpty) + { + Reload(); + } + else + { + WeaponSound(EMPTY); + m_flNextPrimaryAttack = 0.15; + } + + return; + } + + WeaponSound(SINGLE); + pPlayer->DoMuzzleFlash(); + + SendWeaponAnim(ACT_VM_PRIMARYATTACK); + pPlayer->SetAnimation(PLAYER_ATTACK1); + + m_flNextPrimaryAttack = gpGlobals->curtime + 0.75; + m_flNextSecondaryAttack = gpGlobals->curtime + 0.75; + + //m_iClip1--; + pPlayer->RemoveAmmo(1, m_iPrimaryAmmoType); + // player "shoot" animation + pPlayer->SetAnimation(PLAYER_ATTACK1); + + Vector vecSrc = pPlayer->Weapon_ShootPosition(); + Vector vecAiming = pPlayer->GetAutoaimVector(AUTOAIM_10DEGREES); + + FireBulletsInfo_t info(7, vecSrc, vecAiming, GetBulletSpread(), MAX_TRACE_LENGTH, m_iPrimaryAmmoType); + info.m_pAttacker = pPlayer; + + pPlayer->FireBullets(info); + + + //pPlayer->ViewPunch(QAngle(-8, random->RandomFloat(-2, 2), 0)); + + if (!m_iClip1 && pPlayer->GetAmmoCount(m_iPrimaryAmmoType) <= 0) + { + // HEV suit - indicate out of ammo condition + pPlayer->SetSuitUpdate("!HEV_AMO0", FALSE, 0); + } +} + + +//----------------------------------------------------------------------------- +// Purpose: Constructor +//----------------------------------------------------------------------------- +CWeaponShottie::CWeaponShottie(void) +{ + //m_bReloadsSingly = true; + + + //m_fMinRange1 = 0.0; + //m_fMaxRange1 = 500; + //m_fMinRange2 = 0.0; + //m_fMaxRange2 = 200; +} + +//================================================== +// Purpose: +//================================================== +/* +void CWeaponShotgun::WeaponIdle( void ) +{ + //Only the player fires this way so we can cast + CBasePlayer *pPlayer = GetOwner() + + if ( pPlayer == NULL ) + return; + + //If we're on a target, play the new anim + if ( pPlayer->IsOnTarget() ) + { + SendWeaponAnim( ACT_VM_IDLE_ACTIVE ); + } +} +*/ diff --git a/mp/src/game/shared/takedamageinfo.cpp b/mp/src/game/shared/takedamageinfo.cpp index f3eb84c3..d4a999a0 100644 --- a/mp/src/game/shared/takedamageinfo.cpp +++ b/mp/src/game/shared/takedamageinfo.cpp @@ -52,6 +52,7 @@ void CTakeDamageInfo::Init( CBaseEntity *pInflictor, CBaseEntity *pAttacker, CBa m_bitsDamageType = bitsDamageType; m_iDamageCustom = iCustomDamage; + m_flBlastForce = 0; m_flMaxDamage = flDamage; m_vecDamageForce = damageForce; m_vecDamagePosition = damagePosition; diff --git a/mp/src/game/shared/takedamageinfo.h b/mp/src/game/shared/takedamageinfo.h index 43dfdf49..8ce10d27 100644 --- a/mp/src/game/shared/takedamageinfo.h +++ b/mp/src/game/shared/takedamageinfo.h @@ -73,6 +73,9 @@ public: Vector GetReportedPosition() const; void SetReportedPosition( const Vector &reportedPosition ); + void SetBlastForce( float flBlastForceAmount ); + float GetBlastForce( void ) const; + int GetDamageType() const; void SetDamageType( int bitsDamageType ); void AddDamageType( int bitsDamageType ); @@ -118,6 +121,7 @@ protected: EHANDLE m_hInflictor; EHANDLE m_hAttacker; EHANDLE m_hWeapon; + float m_flBlastForce; // Pushforce specifically for blast damage float m_flDamage; float m_flMaxDamage; float m_flBaseDamage; // The damage amount before skill leve adjustments are made. Used to get uniform damage forces. @@ -325,6 +329,16 @@ inline void CTakeDamageInfo::SetReportedPosition( const Vector &reportedPosition m_vecReportedPosition = reportedPosition; } +inline void CTakeDamageInfo::SetBlastForce(float flBlastForceAmount) +{ + m_flBlastForce = flBlastForceAmount; +} + +inline float CTakeDamageInfo::GetBlastForce() const +{ + return m_flBlastForce; +} + inline void CTakeDamageInfo::SetDamageType( int bitsDamageType ) { diff --git a/mp/src/game/shared/weapon_parse.cpp b/mp/src/game/shared/weapon_parse.cpp index c42ad7f1..4041d023 100644 --- a/mp/src/game/shared/weapon_parse.cpp +++ b/mp/src/game/shared/weapon_parse.cpp @@ -347,6 +347,7 @@ FileWeaponInfo_t::FileWeaponInfo_t() bShowUsageHint = false; m_bAllowFlipping = true; m_bBuiltRightHanded = true; + m_iOwnedPickupAmmo = 0; } #ifdef CLIENT_DLL @@ -411,6 +412,7 @@ void FileWeaponInfo_t::Parse( KeyValues *pKeyValuesData, const char *szWeaponNam m_bBuiltRightHanded = ( pKeyValuesData->GetInt( "BuiltRightHanded", 1 ) != 0 ) ? true : false; m_bAllowFlipping = ( pKeyValuesData->GetInt( "AllowFlipping", 1 ) != 0 ) ? true : false; m_bMeleeWeapon = ( pKeyValuesData->GetInt( "MeleeWeapon", 0 ) != 0 ) ? true : false; + m_iOwnedPickupAmmo = pKeyValuesData->GetInt("pickup_ammo", 0); #if defined(_DEBUG) && defined(HL2_CLIENT_DLL) // make sure two weapons aren't in the same slot & position diff --git a/mp/src/game/shared/weapon_parse.h b/mp/src/game/shared/weapon_parse.h index f1d4c924..0467b218 100644 --- a/mp/src/game/shared/weapon_parse.h +++ b/mp/src/game/shared/weapon_parse.h @@ -99,6 +99,8 @@ public: char szAmmo1[MAX_WEAPON_AMMO_NAME]; // "primary" ammo type char szAmmo2[MAX_WEAPON_AMMO_NAME]; // "secondary" ammo type + int m_iOwnedPickupAmmo; // How much ammo to give when picking a weapon the player already owns + // Sound blocks char aShootSounds[NUM_SHOOT_SOUND_TYPES][MAX_WEAPON_STRING];