diff --git a/reactivedrop/resource/swarmopedia.txt b/reactivedrop/resource/swarmopedia.txt index f20f1c901..3cb8fdaf6 100644 --- a/reactivedrop/resource/swarmopedia.txt +++ b/reactivedrop/resource/swarmopedia.txt @@ -765,11 +765,13 @@ "Skill" "ASW_MARINE_SKILL_ACCURACY" "SubSkill" "ASW_MARINE_SUBSKILL_ACCURACY_RIFLE_DMG" } + "StoppingPower" {} "BulletSpread" { "Base" "3" } "FireRate" {} "Ammo" {} + "ReloadTime" {} "Secondary" { "DamagePerShot" { "UseWeaponInfo" "0" @@ -778,6 +780,7 @@ "Skill" "ASW_MARINE_SKILL_GRENADES" "SubSkill" "ASW_MARINE_SUBSKILL_GRENADE_DMG" } + "StoppingPower" {} "Ammo" {} "HammerUnits" { "Icon" "swarm/swarmopedia/fact/projectile_speed" @@ -826,6 +829,7 @@ "Skill" "ASW_MARINE_SKILL_ACCURACY" "SubSkill" "ASW_MARINE_SUBSKILL_ACCURACY_PRIFLE_DMG" } + "StoppingPower" {} "BulletSpread" { "Base" "3" } @@ -836,6 +840,7 @@ "MinimumValue" "0.005" } "Ammo" {} + "ReloadTime" {} "Generic" { "Icon" "swarm/swarmopedia/fact/aim_assist" "Caption" "#rd_weapon_fact_aim_assist" @@ -847,6 +852,7 @@ "Caption" "#rd_weapon_fact_damage_per_shot_shock" "Base" "1" } + "StoppingPower" {} "Ammo" { "Icon" "swarm/swarmopedia/fact/ammo_shock" "Caption" "#rd_weapon_fact_ammo_shock" @@ -898,11 +904,13 @@ "Skill" "ASW_MARINE_SKILL_AUTOGUN" "SubSkill" "ASW_MARINE_SUBSKILL_AUTOGUN_DMG" } + "StoppingPower" {} "BulletSpread" { "Base" "7" } "FireRate" {} "Ammo" {} + "ReloadTime" {} "Generic" { "Icon" "swarm/swarmopedia/fact/heavy" "Caption" "#rd_weapon_fact_slow_movement_while_held" @@ -951,11 +959,13 @@ "Skill" "ASW_MARINE_SKILL_VINDICATOR" "SubSkill" "ASW_MARINE_SUBSKILL_VINDICATOR_DAMAGE" } + "StoppingPower" {} "BulletSpread" { "Base" "22" } "FireRate" {} "Ammo" {} + "ReloadTime" {} "Secondary" { "DamagePerShot" { "UseWeaponInfo" "0" @@ -964,6 +974,7 @@ "Skill" "ASW_MARINE_SKILL_GRENADES" "SubSkill" "ASW_MARINE_SUBSKILL_GRENADE_INCENDIARY_DMG" } + "StoppingPower" {} "Generic" { "Caption" "#rd_weapon_fact_ignites" } @@ -1029,6 +1040,7 @@ "Skill" "ASW_MARINE_SKILL_ACCURACY" "SubSkill" "ASW_MARINE_SUBSKILL_ACCURACY_PISTOL_DMG" } + "StoppingPower" {} "Generic" { "Icon" "swarm/swarmopedia/fact/specific_damage_bonus" "Caption" "#rd_weapon_fact_drone_bonus_damage" @@ -1041,6 +1053,7 @@ "Caption" "#rd_weapon_fact_can_be_fired_faster" } "Ammo" {} + "ReloadTime" {} } } "WEAPON" { @@ -1325,11 +1338,13 @@ "Skill" "ASW_MARINE_SKILL_ACCURACY" "SubSkill" "ASW_MARINE_SUBSKILL_ACCURACY_SHOTGUN_DMG" } + "StoppingPower" {} "BulletSpread" { "Base" "22" } "FireRate" {} "Ammo" {} + "ReloadTime" {} "Secondary" { "Generic" { "Caption" "#rd_weapon_fact_secondary_uses_primary_ammo" @@ -1369,8 +1384,10 @@ "Skill" "ASW_MARINE_SKILL_ACCURACY" "SubSkill" "ASW_MARINE_SUBSKILL_ACCURACY_TESLA_CANNON_DMG" } + "StoppingPower" {} "FireRate" {} "Ammo" {} + "ReloadTime" {} "HammerUnits" { "Icon" "swarm/swarmopedia/fact/range" "Caption" "#rd_weapon_fact_range" @@ -1417,7 +1434,9 @@ "Skill" "ASW_MARINE_SKILL_ACCURACY" "SubSkill" "ASW_MARINE_SUBSKILL_ACCURACY_RAILGUN_DMG" } + "StoppingPower" {} "Ammo" {} + "ReloadTime" {} } } "WEAPON" { @@ -1506,11 +1525,13 @@ "Skill" "ASW_MARINE_SKILL_ACCURACY" "SubSkill" "ASW_MARINE_SUBSKILL_ACCURACY_PDW_DMG" } + "StoppingPower" {} "BulletSpread" { "Base" "3" } "FireRate" {} "Ammo" {} + "ReloadTime" {} } } "WEAPON" { @@ -1546,6 +1567,7 @@ "Skill" "ASW_MARINE_SKILL_ACCURACY" "SubSkill" "ASW_MARINE_SUBSKILL_ACCURACY_FLAMER_DMG" } + "StoppingPower" {} "FireRate" {} "Generic" { "Caption" "#rd_weapon_fact_ignites" @@ -1554,6 +1576,7 @@ "Caption" "#rd_weapon_fact_burning_dps" } "Ammo" {} + "ReloadTime" {} "Secondary" { "Generic" { "RequireCVar" "rd_flamer_infinite_extinguisher" @@ -1671,6 +1694,7 @@ "Skill" "ASW_MARINE_SKILL_AUTOGUN" "SubSkill" "ASW_MARINE_SUBSKILL_AUTOGUN_MINIGUN_DMG" } + "StoppingPower" {} "BulletSpread" { "Base" "15" "Flattened" "1" @@ -1729,6 +1753,7 @@ "Skill" "ASW_MARINE_SKILL_ACCURACY" "SubSkill" "ASW_MARINE_SUBSKILL_ACCURACY_SNIPER_RIFLE_DMG" } + "StoppingPower" {} // TODO: this gun does 1/2/3 max penetrate when idle/zoomed/damage-amped. piercing chance is always 350%. need to figure out a good way to represent this. "Piercing" { "Base" "3.5" @@ -1739,6 +1764,7 @@ } "FireRate" {} "Ammo" {} + "ReloadTime" {} "Secondary" { "Numeric" { "Icon" "swarm/swarmopedia/fact/specific_damage_bonus" @@ -1863,6 +1889,7 @@ "BaseMultiplier" "0.5" "Precision" "1" } + "StoppingPower" {} "FireRate" { "UseWeaponInfo" "0" "Base" "0.1" @@ -1992,6 +2019,7 @@ "Skill" "ASW_MARINE_SKILL_GRENADES" "SubSkill" "ASW_MARINE_SUBSKILL_GRENADE_CLUSTER_DMG" } + "StoppingPower" {} "Numeric" { "Icon" "swarm/swarmopedia/fact/specific_damage_bonus" "Caption" "#rd_weapon_fact_direct_hit_damage_scale" @@ -2000,6 +2028,7 @@ } "FireRate" {} "Ammo" {} + "ReloadTime" {} "HammerUnits" { "Icon" "swarm/swarmopedia/fact/blast_radius" "Caption" "#rd_weapon_fact_blast_radius" @@ -2050,6 +2079,7 @@ "Skill" "ASW_MARINE_SKILL_ACCURACY" "SubSkill" "ASW_MARINE_SUBSKILL_ACCURACY_DEAGLE_DMG" } + "StoppingPower" {} "LargeAlienDamageScale" { "CVar" "rd_deagle_bigalien_dmg_scale" } @@ -2071,6 +2101,7 @@ } "FireRate" {} "Ammo" {} + "ReloadTime" {} } } "WEAPON" { @@ -2110,6 +2141,7 @@ "Skill" "ASW_MARINE_SKILL_ACCURACY" "SubSkill" "ASW_MARINE_SUBSKILL_ACCURACY_DEVASTATOR_DMG" } + "StoppingPower" {} "BulletSpread" { "Base" "11" } @@ -2120,6 +2152,7 @@ } "FireRate" {} "Ammo" {} + "ReloadTime" {} "Generic" { "Icon" "swarm/swarmopedia/fact/accurate_crouch" "Caption" "#rd_weapon_fact_more_accurate_while_crouching" @@ -2163,7 +2196,9 @@ "Skill" "ASW_MARINE_SKILL_ACCURACY" "SubSkill" "ASW_MARINE_SUBSKILL_ACCURACY_RIFLE_DMG" } + "StoppingPower" {} "Ammo" {} + "ReloadTime" {} "Secondary" { "ShotgunPellets" { "UseWeaponInfo" "0" @@ -2176,6 +2211,7 @@ "BaseMultiplier" "6" "SkillMultiplier" "6" } + "StoppingPower" {} "BulletSpread" { "Base" "30" } @@ -2281,6 +2317,7 @@ "Skill" "ASW_MARINE_SKILL_ACCURACY" "SubSkill" "ASW_MARINE_SUBSKILL_ACCURACY_HEAVY_RIFLE_DMG" } + "StoppingPower" {} "LargeAlienDamageScale" { "CVar" "rd_heavy_rifle_bigalien_dmg_scale" } @@ -2294,6 +2331,7 @@ } "FireRate" {} "Ammo" {} + "ReloadTime" {} "Secondary" { "Numeric" { "Icon" "swarm/swarmopedia/fact/duration" @@ -2359,11 +2397,13 @@ "Skill" "ASW_MARINE_SKILL_ACCURACY" "SubSkill" "ASW_MARINE_SUBSKILL_ACCURACY_MEDRIFLE_DMG" } + "StoppingPower" {} "BulletSpread" { "Base" "3" } "FireRate" {} "Ammo" {} + "ReloadTime" {} "Secondary" { "Ammo" { "RequireCVar" "rd_medgun_infinite_ammo" @@ -2446,6 +2486,7 @@ "BaseMultiplier" "2" "SkillMultiplier" "2" } + "StoppingPower" {} "Numeric" { "Icon" "swarm/swarmopedia/fact/duration" "Caption" "#rd_weapon_fact_charge_time" @@ -2457,6 +2498,7 @@ "Base" "0.2" } "Ammo" {} + "ReloadTime" {} } } "WEAPON" { @@ -2483,6 +2525,7 @@ "Skill" "ASW_MARINE_SKILL_ACCURACY" "SubSkill" "ASW_MARINE_SUBSKILL_ACCURACY_50CALMG_DMG" } + "StoppingPower" {} "BulletSpread" { "Base" "20" "Flattened" "1" @@ -2523,6 +2566,11 @@ "SubSkill" "ASW_MARINE_SUBSKILL_GRENADE_FLECHETTE_DMG" "BaseMultiplier" "0" } + "StoppingPower" { + "UseWeaponInfo" "0" + "Caption" "#rd_weapon_fact_stopping_power_blast" + "Base" "1" + } "Generic" { "Icon" "swarm/swarmopedia/fact/rocket_aim" "Caption" "#rd_weapon_fact_rockets_auto_aim" @@ -2559,11 +2607,13 @@ "Skill" "ASW_MARINE_SKILL_ACCURACY" "SubSkill" "ASW_MARINE_SUBSKILL_ACCURACY_RIFLE_DMG" } + "StoppingPower" {} "BulletSpread" { "Base" "3" } "FireRate" {} "Ammo" {} + "ReloadTime" {} "Secondary" {} } } @@ -2592,11 +2642,13 @@ "Skill" "ASW_MARINE_SKILL_ACCURACY" "SubSkill" "ASW_MARINE_SUBSKILL_ACCURACY_AR2_DMG" } + "StoppingPower" {} "BulletSpread" { "Base" "3" } "FireRate" {} "Ammo" {} + "ReloadTime" {} "Secondary" { "DamagePerShot" { "UseWeaponInfo" "0" @@ -2762,6 +2814,11 @@ "Base" "100" // rd_laser_mine_dmg "UseWeaponInfo" "0" } + "StoppingPower" { + "UseWeaponInfo" "0" + "Caption" "#rd_weapon_fact_stopping_power_blast" + "Base" "1" + } "Numeric" { "Icon" "swarm/swarmopedia/fact/grenade_cluster" "Caption" "#rd_weapon_fact_mines_per_use" @@ -2896,6 +2953,11 @@ "SubSkill" "ASW_MARINE_SUBSKILL_GRENADE_HORNET_DMG" "BaseMultiplier" "0" } + "StoppingPower" { + "UseWeaponInfo" "0" + "Caption" "#rd_weapon_fact_stopping_power_blast" + "Base" "1" + } "FireRate" { "UseWeaponInfo" "0" "Skill" "ASW_MARINE_SKILL_GRENADES" @@ -3019,6 +3081,11 @@ "Caption" "#rd_weapon_fact_damage_per_shot_shock" "Base" "5" // rd_tesla_trap_dmg } + "StoppingPower" { + "UseWeaponInfo" "0" + "Caption" "#rd_weapon_fact_stopping_power_shock" + "Base" "1" + } "FireRate" { "Base" "0.3" } @@ -3069,6 +3136,11 @@ "Icon" "swarm/swarmopedia/fact/damage_shock" "Caption" "#rd_weapon_fact_shocks_nearby_aliens" } + "StoppingPower" { + "UseWeaponInfo" "0" + "Caption" "#rd_weapon_fact_stopping_power_shock" + "Base" "1" + } "Generic" { "Icon" "swarm/swarmopedia/fact/heals_infestation" "Caption" "#rd_weapon_fact_prevents_and_reverses_infestation" @@ -3215,6 +3287,11 @@ "Skill" "ASW_MARINE_SKILL_GRENADES" "SubSkill" "ASW_MARINE_SUBSKILL_GRENADE_CLUSTER_DMG" } + "StoppingPower" { + "UseWeaponInfo" "0" + "Caption" "#rd_weapon_fact_stopping_power_blast" + "Base" "1" + } "Ammo" { "CVar" "asw_bonus_charges" } @@ -3299,6 +3376,11 @@ "SubSkill" "ASW_MARINE_SUBSKILL_GRENADE_HORNET_DMG" "BaseMultiplier" "0" } + "StoppingPower" { + "UseWeaponInfo" "0" + "Caption" "#rd_weapon_fact_stopping_power_blast" + "Base" "1" + } "FireRate" { "UseWeaponInfo" "0" "Skill" "ASW_MARINE_SKILL_GRENADES" @@ -3388,6 +3470,11 @@ "Caption" "#rd_weapon_fact_damage_per_shot_blast" "Base" "600" } + "StoppingPower" { + "UseWeaponInfo" "0" + "Caption" "#rd_weapon_fact_stopping_power_blast" + "Base" "1" + } "HammerUnits" { "Icon" "swarm/swarmopedia/fact/blast_radius" "Caption" "#rd_weapon_fact_blast_radius" @@ -3420,6 +3507,11 @@ "Icon" "swarm/swarmopedia/fact/damage_shock" "Caption" "#rd_weapon_fact_shocks_nearby_aliens" } + "StoppingPower" { + "UseWeaponInfo" "0" + "Caption" "#rd_weapon_fact_stopping_power_shock" + "Base" "1" + } } } "WEAPON" { diff --git a/src/game/client/swarm/rd_collections.h b/src/game/client/swarm/rd_collections.h index a74e2ddce..b0ca898ae 100644 --- a/src/game/client/swarm/rd_collections.h +++ b/src/game/client/swarm/rd_collections.h @@ -100,7 +100,6 @@ class CRD_Collection_Tab_Equipment : public TGD_Tab void SetBriefing( IBriefing *pBriefing, int nLobbySlot ); - RD_Swarmopedia::Collection *m_pCollection; CASW_Marine_Profile *m_pProfile; int m_nSkillValue[ASW_NUM_MARINE_SKILLS]; int m_nInventorySlot; @@ -140,7 +139,9 @@ class CRD_Collection_Entry_Equipment : public TGD_Entry void PostChildPaint() override; void ApplyEntry() override; - const RD_Swarmopedia::Weapon *m_pWeapon; + int m_iEquipIndex; + bool m_bExtra; + CUtlString m_szWeaponClass; ReactiveDropInventory::ItemInstance_t m_ItemInstance; bool m_bNoDirectEquip; @@ -173,8 +174,10 @@ class CRD_Collection_Panel_Equipment : public vgui::EditablePanel BaseModUI::GenericPanelList *m_pGplFacts; CNB_Button *m_pBtnEquip; + int m_iEquipIndex; + bool m_bExtra; + CUtlString m_szWeaponClass; CRD_Collection_Tab_Equipment *m_pTab; - const RD_Swarmopedia::Weapon *m_pWeapon; ReactiveDropInventory::ItemInstance_t m_ItemInstance; }; @@ -250,8 +253,6 @@ class CRD_Collection_Tab_Swarmopedia : public TGD_Tab TGD_Grid *CreateGrid() override; TGD_Details *CreateDetails() override; - - RD_Swarmopedia::Collection *m_pCollection; }; class CRD_Collection_Details_Swarmopedia : public TGD_Details @@ -283,11 +284,11 @@ class CRD_Collection_Entry_Swarmopedia : public TGD_Entry void ApplySchemeSettings( vgui::IScheme *pScheme ) override; void ApplyEntry() override; + const RD_Swarmopedia::Alien *GetAlien() const; vgui::ImagePanel *m_pIcon; vgui::Panel *m_pUnlockProgress; - - const RD_Swarmopedia::Alien *m_pAlien; + CUtlString m_AlienID; }; class CRD_Collection_Panel_Swarmopedia : public vgui::EditablePanel @@ -300,12 +301,13 @@ class CRD_Collection_Panel_Swarmopedia : public vgui::EditablePanel void PerformLayout() override; void OnCommand( const char *command ) override; void OnKeyCodePressed( vgui::KeyCode keycode ) override; + const RD_Swarmopedia::Alien *GetAlien() const; CRD_Swarmopedia_Model_Panel *m_pModelPanel; CNB_Button *m_pModelButton; vgui::Label *m_pLblNoModel; - vgui::RichText *m_pContent; + vgui::MultiFontRichText *m_pContent; - const RD_Swarmopedia::Alien *m_pAlien; + CUtlString m_AlienID; int m_iCurrentDisplay; }; diff --git a/src/game/client/swarm/rd_collections_equipment.cpp b/src/game/client/swarm/rd_collections_equipment.cpp index e09cc2585..db93052ee 100644 --- a/src/game/client/swarm/rd_collections_equipment.cpp +++ b/src/game/client/swarm/rd_collections_equipment.cpp @@ -113,7 +113,6 @@ CRD_Collection_Tab_Equipment::CRD_Collection_Tab_Equipment( TabbedGridDetails *p { Assert( MarineSkills() ); - m_pCollection = NULL; m_pProfile = pProfile; m_nInventorySlot = nInventorySlot; @@ -130,13 +129,6 @@ CRD_Collection_Tab_Equipment::CRD_Collection_Tab_Equipment( TabbedGridDetails *p CRD_Collection_Tab_Equipment::~CRD_Collection_Tab_Equipment() { - if ( m_pCollection ) - { - delete m_pCollection; - - m_pCollection = NULL; - } - if ( m_pBriefing ) { m_pBriefing->SetChangingWeaponSlot( -1, 0 ); @@ -147,22 +139,24 @@ TGD_Grid *CRD_Collection_Tab_Equipment::CreateGrid() { TGD_Grid *pGrid = BaseClass::CreateGrid(); - Assert( !m_pCollection ); - m_pCollection = new RD_Swarmopedia::Collection(); - m_pCollection->ReadFromFiles( m_nInventorySlot == ASW_INVENTORY_SLOT_EXTRA ? RD_Swarmopedia::Subset::ExtraWeapons : RD_Swarmopedia::Subset::RegularWeapons ); - CUtlVector instances; int iEquippedIndex = m_pBriefing ? m_pBriefing->GetMarineSelectedWeapon( m_nLobbySlot, m_nInventorySlot ) : -1; SteamItemInstanceID_t iEquippedItemID = m_pBriefing ? m_pBriefing->GetEquippedWeapon( m_nLobbySlot, m_nInventorySlot ).m_iItemInstanceID : k_SteamItemInstanceIDInvalid; - FOR_EACH_VEC( m_pCollection->Weapons, i ) + const RD_Swarmopedia::Collection &Swarmopedia = RD_Swarmopedia::Get(); + FOR_EACH_VEC( Swarmopedia.Weapons, i ) { - const RD_Swarmopedia::Weapon *pWeapon = m_pCollection->Weapons[i]; + const RD_Swarmopedia::Weapon *pWeapon = Swarmopedia.Weapons[i]; if ( pWeapon->EquipIndex == -1 && m_pBriefing ) { continue; // can't equip a weapon that isn't built in } + if ( pWeapon->Extra != ( m_nInventorySlot == ASW_INVENTORY_SLOT_EXTRA ) ) + { + continue; // can't equip a weapon that's not for this slot + } + CASW_EquipItem *pItem = pWeapon->Extra ? g_ASWEquipmentList.GetExtra( pWeapon->EquipIndex ) : g_ASWEquipmentList.GetRegular( pWeapon->EquipIndex ); Assert( pItem ); @@ -292,12 +286,22 @@ void CRD_Collection_Details_Equipment::DisplayEntry( TGD_Entry *pEntry ) return; } + const RD_Swarmopedia::Weapon *pWeapon = RD_Swarmopedia::FindWeapon( pEquip->m_iEquipIndex, pEquip->m_bExtra ); + if ( !pWeapon ) + { + pWeapon = RD_Swarmopedia::FindWeapon( pEquip->m_szWeaponClass ); + } + if ( !pWeapon ) + { + return; + } + // TODO: support arbitrary number of Display/Content per weapon - Assert( pEquip->m_pWeapon->Display.Count() == 1 ); - Assert( pEquip->m_pWeapon->Content.Count() == 1 ); + Assert( pWeapon->Display.Count() == 1 ); + Assert( pWeapon->Content.Count() == 1 ); wchar_t buf[1024]{}; - FOR_EACH_VEC( pEquip->m_pWeapon->Abilities, i ) + FOR_EACH_VEC( pWeapon->Abilities, i ) { int len = V_wcslen( buf ); if ( i != 0 ) @@ -306,18 +310,18 @@ void CRD_Collection_Details_Equipment::DisplayEntry( TGD_Entry *pEntry ) len = V_wcslen( buf ); } - TryLocalize( pEquip->m_pWeapon->Abilities[i]->Caption, &buf[len], sizeof( buf ) - len * sizeof( wchar_t ) ); + TryLocalize( pWeapon->Abilities[i]->Caption, &buf[len], sizeof( buf ) - len * sizeof( wchar_t ) ); } m_pWeaponAttrLabel->SetText( buf ); - if ( pEquip->m_pWeapon->Display.Count() == 1 ) + if ( pWeapon->Display.Count() == 1 ) { m_pModelPanel->m_bShouldPaint = true; m_pModelPanel->SetVisible( true ); - m_pModelPanel->SetDisplay( pEquip->m_pWeapon->Display[0] ); + m_pModelPanel->SetDisplay( pWeapon->Display[0] ); - m_pWeaponNameLabel->SetText( pEquip->m_pWeapon->Display[0]->Caption ); + m_pWeaponNameLabel->SetText( pWeapon->Display[0]->Caption ); } else { @@ -340,12 +344,12 @@ void CRD_Collection_Details_Equipment::DisplayEntry( TGD_Entry *pEntry ) if ( pEquip->m_pLockedLabel->IsVisible() ) { wchar_t wszRequiredLevel[12]{}; - V_snwprintf( wszRequiredLevel, ARRAYSIZE( wszRequiredLevel ), L"%d", pEquip->m_pWeapon->RequiredLevel ); + V_snwprintf( wszRequiredLevel, ARRAYSIZE( wszRequiredLevel ), L"%d", pWeapon->RequiredLevel ); wchar_t wszBuf[1024]{}; g_pVGuiLocalize->ConstructString( wszBuf, sizeof( wszBuf ), g_pVGuiLocalize->Find( "#rd_reach_level_to_unlock_weapon" ), 2, - wszRequiredLevel, g_pVGuiLocalize->FindSafe( pEquip->m_pWeapon->Name ) ); + wszRequiredLevel, g_pVGuiLocalize->FindSafe( pWeapon->Name ) ); m_pWeaponDescLabel->SetText( wszBuf ); } else @@ -355,9 +359,9 @@ void CRD_Collection_Details_Equipment::DisplayEntry( TGD_Entry *pEntry ) m_pWeaponDescLabel->SetText( L"" ); pEquip->m_ItemInstance.FormatDescription( m_pWeaponDescLabel ); } - else if ( pEquip->m_pWeapon->Content.Count() == 1 ) + else if ( pWeapon->Content.Count() == 1 ) { - m_pWeaponDescLabel->SetText( pEquip->m_pWeapon->Content[0]->Text ); + m_pWeaponDescLabel->SetText( pWeapon->Content[0]->Text ); } else { @@ -378,17 +382,17 @@ void CRD_Collection_Details_Equipment::DisplayEntry( TGD_Entry *pEntry ) pDaysLabel->SetContentAlignment( vgui::Label::a_east ); pDaysLabel->SetText( buf ); - FOR_EACH_VEC( pEquip->m_pWeapon->GlobalStats, i ) + FOR_EACH_VEC( pWeapon->GlobalStats, i ) { int nOK{}; int64 nStat[61]{}; if ( rd_swarmopedia_global_stat_window_days.GetInt() == 0 ) { - nOK = SteamUserStats()->GetGlobalStat( pEquip->m_pWeapon->GlobalStats[i]->StatName, &nStat[1] ) ? 1 : 0; + nOK = SteamUserStats()->GetGlobalStat( pWeapon->GlobalStats[i]->StatName, &nStat[1] ) ? 1 : 0; } else { - nOK = SteamUserStats()->GetGlobalStatHistory( pEquip->m_pWeapon->GlobalStats[i]->StatName, &nStat[1], sizeof( nStat ) - sizeof( nStat[0] ) ); + nOK = SteamUserStats()->GetGlobalStatHistory( pWeapon->GlobalStats[i]->StatName, &nStat[1], sizeof( nStat ) - sizeof( nStat[0] ) ); } for ( int j = 1; j <= nOK; j++ ) @@ -397,7 +401,7 @@ void CRD_Collection_Details_Equipment::DisplayEntry( TGD_Entry *pEntry ) } CRD_Collection_StatLine *pStatLine = m_pGplStats->AddPanelItem( "StatLine" ); - pStatLine->SetLabel( g_pVGuiLocalize->FindSafe( pEquip->m_pWeapon->GlobalStats[i]->Caption ) ); + pStatLine->SetLabel( g_pVGuiLocalize->FindSafe( pWeapon->GlobalStats[i]->Caption ) ); pStatLine->SetValue( nStat[0] ); } } @@ -443,7 +447,9 @@ void CRD_Collection_Details_Equipment::OnThink() CRD_Collection_Entry_Equipment::CRD_Collection_Entry_Equipment( TGD_Grid *parent, const char *panelName, const RD_Swarmopedia::Weapon *pWeapon, const ReactiveDropInventory::ItemInstance_t &itemInstance ) : BaseClass( parent, panelName ) { - m_pWeapon = pWeapon; + m_iEquipIndex = pWeapon->EquipIndex; + m_bExtra = pWeapon->Extra; + m_szWeaponClass = pWeapon->ClassName; m_ItemInstance = itemInstance; m_bNoDirectEquip = false; @@ -477,12 +483,22 @@ void CRD_Collection_Entry_Equipment::ApplySchemeSettings( vgui::IScheme *pScheme m_pInfoButton->SetImage( CBitmapButton::BUTTON_PRESSED, "vgui/swarm/swarmopedia/fact/generic", white ); m_pInfoButton->SetImage( CBitmapButton::BUTTON_DISABLED, "vgui/swarm/swarmopedia/fact/generic", transparent ); - m_pIcon->SetImage( m_pWeapon->Icon ); + const RD_Swarmopedia::Weapon *pWeapon = RD_Swarmopedia::FindWeapon( m_iEquipIndex, m_bExtra ); + if ( !pWeapon ) + { + pWeapon = RD_Swarmopedia::FindWeapon( m_szWeaponClass ); + } + if ( !pWeapon ) + { + return; + } + + m_pIcon->SetImage( pWeapon->Icon ); m_pClassIcon->SetVisible( true ); m_pClassLabel->SetVisible( true ); - switch ( m_pWeapon->RequiredClass ) + switch ( pWeapon->RequiredClass ) { case MARINE_CLASS_NCO: m_pClassIcon->SetImage( "swarm/ClassIcons/NCOClassIcon" ); @@ -508,13 +524,13 @@ void CRD_Collection_Entry_Equipment::ApplySchemeSettings( vgui::IScheme *pScheme CRD_Collection_Tab_Equipment *pTab = assert_cast< CRD_Collection_Tab_Equipment * >( m_pParent->m_pParent ); - bool bLevelLocked = !asw_unlock_all_weapons.GetBool() && !UTIL_ASW_CommanderLevelAtLeast( NULL, m_pWeapon->RequiredLevel - 1, -1 ); - if ( pTab->m_pBriefing && m_pWeapon->Builtin ) + bool bLevelLocked = !asw_unlock_all_weapons.GetBool() && !UTIL_ASW_CommanderLevelAtLeast( NULL, pWeapon->RequiredLevel - 1, -1 ); + if ( pTab->m_pBriefing && pWeapon->Builtin ) { - bLevelLocked = !pTab->m_pBriefing->IsWeaponUnlocked( m_pWeapon->ClassName ); + bLevelLocked = !pTab->m_pBriefing->IsWeaponUnlocked( pWeapon->ClassName ); } - const char *szCantEquipReason = pTab->m_pBriefing ? CantEquipReason( pTab, m_pWeapon ) : NULL; + const char *szCantEquipReason = pTab->m_pBriefing ? CantEquipReason( pTab, pWeapon ) : NULL; if ( szCantEquipReason ) { m_pCantEquipLabel->SetText( szCantEquipReason ); @@ -528,9 +544,9 @@ void CRD_Collection_Entry_Equipment::ApplySchemeSettings( vgui::IScheme *pScheme #ifdef RD_DISABLE_ALL_RELEASE_FLAGS #error This should be disabled for release! #endif - if ( m_pWeapon->EquipIndex != -1 ) + if ( m_iEquipIndex != -1 ) { - CASW_EquipItem *pItem = m_pWeapon->Extra ? g_ASWEquipmentList.GetExtra( m_pWeapon->EquipIndex ) : g_ASWEquipmentList.GetRegular( m_pWeapon->EquipIndex ); + CASW_EquipItem *pItem = m_bExtra ? g_ASWEquipmentList.GetExtra( m_iEquipIndex ) : g_ASWEquipmentList.GetRegular( m_iEquipIndex ); if ( pItem && pItem->m_bRequiresInventoryItem ) { m_pCantEquipLabel->SetText( "#rd_can_equip_beta" ); @@ -557,7 +573,7 @@ void CRD_Collection_Entry_Equipment::ApplySchemeSettings( vgui::IScheme *pScheme m_pCantEquipLabel->SetVisible( false ); wchar_t wszLevel[12]; - V_snwprintf( wszLevel, ARRAYSIZE( wszLevel ), L"%d", m_pWeapon->RequiredLevel ); + V_snwprintf( wszLevel, ARRAYSIZE( wszLevel ), L"%d", pWeapon->RequiredLevel ); m_pLockedLabel->SetText( wszLevel ); } else @@ -568,7 +584,7 @@ void CRD_Collection_Entry_Equipment::ApplySchemeSettings( vgui::IScheme *pScheme m_pIcon->SetVisible( true ); C_ASW_Medal_Store *pMedalStore = GetMedalStore(); - m_pNewLabel->SetVisible( pMedalStore && pMedalStore->IsWeaponNew( m_pWeapon->Extra, m_pWeapon->EquipIndex ) ); + m_pNewLabel->SetVisible( pMedalStore && pMedalStore->IsWeaponNew( pWeapon->Extra, pWeapon->EquipIndex ) ); } } @@ -641,6 +657,16 @@ void CRD_Collection_Entry_Equipment::ApplyEntry() return; } + const RD_Swarmopedia::Weapon *pWeapon = RD_Swarmopedia::FindWeapon( m_iEquipIndex, m_bExtra ); + if ( !pWeapon ) + { + pWeapon = RD_Swarmopedia::FindWeapon( m_szWeaponClass ); + } + if ( !pWeapon ) + { + return; + } + CRD_Collection_Tab_Equipment *pTab = assert_cast< CRD_Collection_Tab_Equipment * >( m_pParent->m_pParent ); TabbedGridDetails *pTGD = pTab->m_pParent; vgui::Panel *pPanel = pTGD->m_hOverridePanel; @@ -650,7 +676,7 @@ void CRD_Collection_Entry_Equipment::ApplyEntry() pPanel->MarkForDeletion(); } - pTGD->SetOverridePanel( new CRD_Collection_Panel_Equipment( pTGD, "EquipmentPanel", pTab, m_pWeapon, m_ItemInstance ) ); + pTGD->SetOverridePanel( new CRD_Collection_Panel_Equipment( pTGD, "EquipmentPanel", pTab, pWeapon, m_ItemInstance ) ); if ( !m_bNoDirectEquip && pTab->m_pBriefing ) { @@ -743,7 +769,6 @@ void CRD_Equipment_WeaponFact::ApplySchemeSettings( vgui::IScheme *pScheme ) bool bHasValue = true; bool bIsHammerUnits = false; bool bIgnoreCustomCaption = false; - bool bConVarIsOverride = false; bool bShowReciprocal = m_pFact->ShowReciprocal; switch ( m_pFact->Type ) @@ -766,7 +791,6 @@ void CRD_Equipment_WeaponFact::ApplySchemeSettings( vgui::IScheme *pScheme ) case Type_T::DamagePerShot: szIcon = "swarm/swarmopedia/fact/damage"; szCaption = "#rd_weapon_fact_damage_per_shot"; - bConVarIsOverride = true; break; case Type_T::LargeAlienDamageScale: szIcon = "swarm/swarmopedia/fact/large_alien_damage"; @@ -780,11 +804,19 @@ void CRD_Equipment_WeaponFact::ApplySchemeSettings( vgui::IScheme *pScheme ) szIcon = "swarm/swarmopedia/fact/piercing"; szCaption = "#rd_weapon_fact_piercing"; break; + case Type_T::StoppingPower: + szIcon = "swarm/swarmopedia/fact/stopping_power"; + szCaption = "#rd_weapon_fact_stopping_power"; + break; case Type_T::FireRate: szIcon = "swarm/swarmopedia/fact/fire_rate"; szCaption = "#rd_weapon_fact_fire_rate"; bShowReciprocal = !bShowReciprocal; break; + case Type_T::ReloadTime: + szIcon = "swarm/swarmopedia/fact/reload"; + szCaption = "#rd_weapon_fact_reload"; + break; case Type_T::Ammo: szIcon = "swarm/swarmopedia/fact/ammo"; szCaption = "#rd_weapon_fact_ammo"; @@ -871,46 +903,20 @@ void CRD_Equipment_WeaponFact::ApplySchemeSettings( vgui::IScheme *pScheme ) if ( !wszAfter ) wszAfter = L""; - float flBaseValue = m_pFact->Base; - if ( !m_pFact->CVar.IsEmpty() ) - { - ConVarRef var( m_pFact->CVar ); - if ( !bConVarIsOverride ) - { - flBaseValue += var.GetFloat(); - } - else if ( var.GetFloat() > 0 ) - { - flBaseValue = var.GetFloat(); - } - } - - flBaseValue *= m_pFact->BaseMultiplier; - FOR_EACH_VEC( m_pFact->BaseMultiplierCVar, i ) - { - ConVarRef var( m_pFact->BaseMultiplierCVar[i] ); - flBaseValue *= var.GetFloat(); - } - FOR_EACH_VEC( m_pFact->BaseDivisorCVar, i ) - { - ConVarRef var( m_pFact->BaseDivisorCVar[i] ); - flBaseValue /= var.GetFloat(); - } - - float flSkillValue = 0.0f; + int iSkillValue = -1; if ( m_pFact->Skill != ASW_MARINE_SKILL_INVALID ) { CFmtStr szSkillImage( "vgui/%s", MarineSkills()->GetSkillImage( m_pFact->Skill ) ); - m_pSkillIcon->SetImage( CBitmapButton::BUTTON_ENABLED, szSkillImage, color32{ 255, 255, 255, 255 } ); + m_pSkillIcon->SetImage( CBitmapButton::BUTTON_ENABLED, szSkillImage, color32{ 220, 220, 220, 255 } ); m_pSkillIcon->SetImage( CBitmapButton::BUTTON_ENABLED_MOUSE_OVER, szSkillImage, color32{ 255, 255, 255, 255 } ); m_pSkillIcon->SetImage( CBitmapButton::BUTTON_PRESSED, szSkillImage, color32{ 255, 255, 255, 255 } ); - m_pSkillIcon->SetImage( CBitmapButton::BUTTON_DISABLED, szSkillImage, color32{ 255, 255, 255, 255 } ); + m_pSkillIcon->SetImage( CBitmapButton::BUTTON_DISABLED, szSkillImage, color32{ 96, 96, 96, 255 } ); m_pSkillIcon->SetVisible( true ); m_pSkillIcon->SetEnabled( !m_pTab->m_pProfile ); GetControllerFocus()->AddToFocusList( m_pSkillIcon ); int iMaxSkillPoints = MarineSkills()->GetMaxSkillPoints( m_pFact->Skill ); - int iSkillValue = m_pTab->m_nSkillValue[m_pFact->Skill]; + iSkillValue = m_pTab->m_nSkillValue[m_pFact->Skill]; int x, y; m_pSkillIcon->GetPos( x, y ); @@ -925,30 +931,10 @@ void CRD_Equipment_WeaponFact::ApplySchemeSettings( vgui::IScheme *pScheme ) m_pSkillPips[i]->SetPos( x - YRES( 6 ), y + ( iMaxSkillPoints - i ) * m_pSkillIcon->GetTall() / ( iMaxSkillPoints + 2 ) ); } } - - flSkillValue = MarineSkills()->GetSkillBasedValue( m_pTab->m_pProfile, m_pFact->Skill, m_pFact->SubSkill, iSkillValue ); } - flSkillValue *= m_pFact->SkillMultiplier; - FOR_EACH_VEC( m_pFact->SkillMultiplierCVar, i ) - { - ConVarRef var( m_pFact->SkillMultiplierCVar[i] ); - flSkillValue *= var.GetFloat(); - } - FOR_EACH_VEC( m_pFact->SkillDivisorCVar, i ) - { - ConVarRef var( m_pFact->SkillDivisorCVar[i] ); - flSkillValue /= var.GetFloat(); - } - - if ( flBaseValue + flSkillValue < m_pFact->MinimumValue ) - { - flBaseValue = m_pFact->MinimumValue - flSkillValue; - } - else if ( flBaseValue + flSkillValue > m_pFact->MaximumValue ) - { - flBaseValue = m_pFact->MaximumValue - flSkillValue; - } + float flBaseValue, flSkillValue; + m_pFact->ComputeBaseAndSkill( flBaseValue, flSkillValue, m_pTab->m_pProfile, iSkillValue ); if ( bShowReciprocal ) { @@ -1136,7 +1122,9 @@ CRD_Collection_Panel_Equipment::CRD_Collection_Panel_Equipment( vgui::Panel *par m_pBtnEquip = new CNB_Button( this, "BtnEquip", "#asw_equip", this, "AcceptEquip" ); m_pTab = pTab; - m_pWeapon = pWeapon; + m_iEquipIndex = pWeapon->EquipIndex; + m_bExtra = pWeapon->Extra; + m_szWeaponClass = pWeapon->ClassName; m_ItemInstance = itemInstance; } @@ -1146,11 +1134,21 @@ void CRD_Collection_Panel_Equipment::ApplySchemeSettings( vgui::IScheme *pScheme BaseClass::ApplySchemeSettings( pScheme ); + const RD_Swarmopedia::Weapon *pWeapon = RD_Swarmopedia::FindWeapon( m_iEquipIndex, m_bExtra ); + if ( !pWeapon ) + { + pWeapon = RD_Swarmopedia::FindWeapon( m_szWeaponClass ); + } + if ( !pWeapon ) + { + return; + } + if ( m_pTab->m_pBriefing ) { m_pBtnEquip->SetVisible( true ); - const char *szReason = CantEquipReason( m_pTab, m_pWeapon ); + const char *szReason = CantEquipReason( m_pTab, pWeapon ); if ( szReason ) { m_pBtnEquip->SetText( szReason ); @@ -1169,9 +1167,9 @@ void CRD_Collection_Panel_Equipment::ApplySchemeSettings( vgui::IScheme *pScheme m_pGplFacts->RemoveAllPanelItems(); - FOR_EACH_VEC( m_pWeapon->Facts, i ) + FOR_EACH_VEC( pWeapon->Facts, i ) { - AddWeaponFact( m_pWeapon->Facts[i] ); + AddWeaponFact( pWeapon->Facts[i] ); } } @@ -1179,7 +1177,17 @@ void CRD_Collection_Panel_Equipment::OnCommand( const char *command ) { if ( FStrEq( command, "AcceptEquip" ) ) { - if ( CantEquipReason( m_pTab, m_pWeapon ) ) + const RD_Swarmopedia::Weapon *pWeapon = RD_Swarmopedia::FindWeapon( m_iEquipIndex, m_bExtra ); + if ( !pWeapon ) + { + pWeapon = RD_Swarmopedia::FindWeapon( m_szWeaponClass ); + } + if ( !pWeapon ) + { + return; + } + + if ( CantEquipReason( m_pTab, pWeapon ) ) { return; } @@ -1200,10 +1208,10 @@ void CRD_Collection_Panel_Equipment::OnCommand( const char *command ) if ( C_ASW_Medal_Store *pMedalStore = GetMedalStore() ) { - pMedalStore->OnSelectedEquipment( m_pWeapon->Extra, m_pWeapon->EquipIndex ); + pMedalStore->OnSelectedEquipment( m_bExtra, m_iEquipIndex ); } - m_pTab->m_pBriefing->SelectWeapon( m_pTab->m_nLobbySlot, m_pTab->m_nInventorySlot, m_pWeapon->EquipIndex, m_ItemInstance.ItemID ); + m_pTab->m_pBriefing->SelectWeapon( m_pTab->m_nLobbySlot, m_pTab->m_nInventorySlot, m_iEquipIndex, m_ItemInstance.ItemID ); m_pTab->m_pParent->MarkForDeletion(); } diff --git a/src/game/client/swarm/rd_collections_swarmopedia.cpp b/src/game/client/swarm/rd_collections_swarmopedia.cpp index 18c1fc1c8..5261df86a 100644 --- a/src/game/client/swarm/rd_collections_swarmopedia.cpp +++ b/src/game/client/swarm/rd_collections_swarmopedia.cpp @@ -14,6 +14,7 @@ #include "gameui/swarm/basemodpanel.h" #include "gameui/swarm/vgenericpanellist.h" #include "c_asw_steamstats.h" +#include "MultiFontRichText.h" // memdbgon must be the last include file in a .cpp file!!! #include "tier0/memdbgon.h" @@ -23,30 +24,20 @@ ConVar rd_swarmopedia_global_stat_window_days( "rd_swarmopedia_global_stat_windo CRD_Collection_Tab_Swarmopedia::CRD_Collection_Tab_Swarmopedia( TabbedGridDetails *parent, const char *szLabel ) : BaseClass( parent, szLabel ) { - m_pCollection = NULL; } CRD_Collection_Tab_Swarmopedia::~CRD_Collection_Tab_Swarmopedia() { - if ( m_pCollection ) - { - delete m_pCollection; - - m_pCollection = NULL; - } } TGD_Grid *CRD_Collection_Tab_Swarmopedia::CreateGrid() { TGD_Grid *pGrid = BaseClass::CreateGrid(); - Assert( !m_pCollection ); - m_pCollection = new RD_Swarmopedia::Collection(); - m_pCollection->ReadFromFiles( RD_Swarmopedia::Subset::Aliens ); - - FOR_EACH_VEC( m_pCollection->Aliens, i ) + const RD_Swarmopedia::Collection &Swarmopedia = RD_Swarmopedia::Get(); + FOR_EACH_VEC( Swarmopedia.Aliens, i ) { - pGrid->AddEntry( new CRD_Collection_Entry_Swarmopedia( pGrid, "CollectionEntrySwarmopedia", m_pCollection->Aliens[i] ) ); + pGrid->AddEntry( new CRD_Collection_Entry_Swarmopedia( pGrid, "CollectionEntrySwarmopedia", Swarmopedia.Aliens[i] ) ); } return pGrid; @@ -122,7 +113,12 @@ void CRD_Collection_Details_Swarmopedia::DisplayEntry( TGD_Entry *pEntry ) } CRD_Collection_Entry_Swarmopedia *pSwarmopediaEntry = assert_cast< CRD_Collection_Entry_Swarmopedia * >( pEntry ); - const RD_Swarmopedia::Alien *pAlien = pSwarmopediaEntry->m_pAlien; + const RD_Swarmopedia::Alien *pAlien = pSwarmopediaEntry->GetAlien(); + if ( !pAlien ) + { + DisplayEntry( NULL ); + return; + } if ( pAlien->GetOverallRequirementProgress() < 1.0f ) { @@ -262,7 +258,7 @@ void CRD_Collection_Details_Swarmopedia::DisplayEntryLocked( const RD_Swarmopedi CRD_Collection_Entry_Swarmopedia::CRD_Collection_Entry_Swarmopedia( TGD_Grid *parent, const char *panelName, const RD_Swarmopedia::Alien *pAlien ) : BaseClass( parent, panelName ) { - m_pAlien = pAlien; + m_AlienID = pAlien->ID; m_pIcon = new vgui::ImagePanel( this, "Icon" ); m_pUnlockProgress = new vgui::Panel( this, "UnlockProgress" ); @@ -272,12 +268,18 @@ void CRD_Collection_Entry_Swarmopedia::ApplySchemeSettings( vgui::IScheme *pSche { BaseClass::ApplySchemeSettings( pScheme ); - bool bUnlocked = m_pAlien->GetOverallRequirementProgress() >= 1.0f; + const RD_Swarmopedia::Alien *pAlien = GetAlien(); + if ( !pAlien ) + { + return; + } + + bool bUnlocked = pAlien->GetOverallRequirementProgress() >= 1.0f; - m_pUnlockProgress->SetWide( m_pHighlight->GetWide() * m_pAlien->GetOverallRequirementProgress() ); + m_pUnlockProgress->SetWide( m_pHighlight->GetWide() * pAlien->GetOverallRequirementProgress() ); m_pUnlockProgress->SetVisible( !bUnlocked ); - m_pIcon->SetImage( m_pAlien->Icon ); + m_pIcon->SetImage( pAlien->Icon ); m_pIcon->SetDrawColor( bUnlocked ? Color( 255, 255, 255, 255 ) : Color( 0, 0, 0, 255 ) ); } @@ -288,7 +290,7 @@ void CRD_Collection_Entry_Swarmopedia::ApplyEntry() if ( pPanel ) { CRD_Collection_Panel_Swarmopedia *pSwarmopediaPanel = dynamic_cast< CRD_Collection_Panel_Swarmopedia * >( pPanel ); - bool bStop = pSwarmopediaPanel && pSwarmopediaPanel->m_pAlien == m_pAlien; + bool bStop = pSwarmopediaPanel && pSwarmopediaPanel->m_AlienID == m_AlienID; pTGD->SetOverridePanel( NULL ); pPanel->MarkForDeletion(); @@ -299,23 +301,29 @@ void CRD_Collection_Entry_Swarmopedia::ApplyEntry() } } - if ( m_pAlien->GetOverallRequirementProgress() >= 1.0f ) + const RD_Swarmopedia::Alien *pAlien = GetAlien(); + if ( pAlien && pAlien->GetOverallRequirementProgress() >= 1.0f ) { - pPanel = new CRD_Collection_Panel_Swarmopedia( pTGD, "SwarmopediaPanel", m_pAlien ); + pPanel = new CRD_Collection_Panel_Swarmopedia( pTGD, "SwarmopediaPanel", pAlien ); pTGD->SetOverridePanel( pPanel ); } } +const RD_Swarmopedia::Alien *CRD_Collection_Entry_Swarmopedia::GetAlien() const +{ + return RD_Swarmopedia::FindAlien( m_AlienID ); +} + CRD_Collection_Panel_Swarmopedia::CRD_Collection_Panel_Swarmopedia( vgui::Panel *parent, const char *panelName, const RD_Swarmopedia::Alien *pAlien ) : BaseClass( parent, panelName ) { - m_pAlien = pAlien; + m_AlienID = pAlien->ID; m_iCurrentDisplay = 0; m_pModelPanel = new CRD_Swarmopedia_Model_Panel( this, "ModelPanel" ); m_pModelButton = new CNB_Button( this, "ModelButton", L"", this, "CycleDisplay" ); m_pLblNoModel = new vgui::Label( this, "LblNoModel", "#rd_so_display_no_model" ); - m_pContent = new vgui::RichText( this, "Content" ); + m_pContent = new vgui::MultiFontRichText( this, "Content" ); m_pModelPanel->SetMouseInputEnabled( false ); m_pModelButton->SetControllerButton( KEY_XBUTTON_X ); @@ -331,22 +339,36 @@ void CRD_Collection_Panel_Swarmopedia::ApplySchemeSettings( vgui::IScheme *pSche BaseClass::ApplySchemeSettings( pScheme ); - m_pContent->SetFont( pScheme->GetFont( "DefaultMedium", true ) ); + const RD_Swarmopedia::Alien *pAlien = GetAlien(); + if ( !pAlien ) + { + return; + } + + vgui::HFont hDefaultFont = pScheme->GetFont( "DefaultMedium", true ); + m_pContent->SetFont( hDefaultFont ); m_pContent->SetText( L"" ); - m_pModelButton->SetEnabled( m_pAlien->Display.Count() > 1 ); + m_pModelButton->SetEnabled( pAlien->Display.Count() > 1 ); wchar_t wszBuf[4096]{}; - FOR_EACH_VEC( m_pAlien->Content, i ) + FOR_EACH_VEC( pAlien->Content, i ) { - switch ( m_pAlien->Content[i]->Type ) + switch ( pAlien->Content[i]->Type ) { case RD_Swarmopedia::Content::Type_t::Paragraph: - TryLocalize( m_pAlien->Content[i]->Text, wszBuf, sizeof( wszBuf ) ); - m_pContent->InsertColorChange( m_pAlien->Content[i]->Color ); + TryLocalize( pAlien->Content[i]->Text, wszBuf, sizeof( wszBuf ) ); + m_pContent->InsertColorChange( pAlien->Content[i]->Color ); + m_pContent->InsertFontChange( pAlien->Content[i]->Font == vgui::INVALID_FONT ? hDefaultFont : pAlien->Content[i]->Font ); m_pContent->InsertString( wszBuf ); m_pContent->InsertString( L"\n\n" ); break; + case RD_Swarmopedia::Content::Type_t::ZbalermornaParagraph: + m_pContent->InsertColorChange( pAlien->Content[i]->Color ); + m_pContent->InsertFontChange( pAlien->Content[i]->Font == vgui::INVALID_FONT ? hDefaultFont : pAlien->Content[i]->Font ); + m_pContent->InsertZbalermornaString( pAlien->Content[i]->Text ); + m_pContent->InsertString( L"\n\n" ); + break; default: Assert( !"Unhandled content type" ); break; @@ -357,10 +379,10 @@ void CRD_Collection_Panel_Swarmopedia::ApplySchemeSettings( vgui::IScheme *pSche m_pContent->InsertString( g_pVGuiLocalize->FindSafe( "#rd_so_sources" ) ); m_pContent->InsertColorChange( Color{ 83, 148, 192, 255 } ); - FOR_EACH_VEC( m_pAlien->Sources, i ) + FOR_EACH_VEC( pAlien->Sources, i ) { m_pContent->InsertString( L"\n" ); - m_pContent->InsertString( g_ReactiveDropWorkshop.AddonName( m_pAlien->Sources[i] ) ); + m_pContent->InsertString( g_ReactiveDropWorkshop.AddonName( pAlien->Sources[i] ) ); } } @@ -368,13 +390,14 @@ void CRD_Collection_Panel_Swarmopedia::PerformLayout() { BaseClass::PerformLayout(); - if ( 0 <= m_iCurrentDisplay && m_iCurrentDisplay < m_pAlien->Display.Count() ) + const RD_Swarmopedia::Alien *pAlien = GetAlien(); + if ( pAlien && 0 <= m_iCurrentDisplay && m_iCurrentDisplay < pAlien->Display.Count() ) { - m_pModelPanel->SetDisplay( m_pAlien->Display[m_iCurrentDisplay] ); + m_pModelPanel->SetDisplay( pAlien->Display[m_iCurrentDisplay] ); m_pModelPanel->m_bShouldPaint = true; m_pModelPanel->SetVisible( true ); - m_pModelButton->SetText( m_pAlien->Display[m_iCurrentDisplay]->Caption ); + m_pModelButton->SetText( pAlien->Display[m_iCurrentDisplay]->Caption ); m_pModelButton->SetVisible( true ); m_pLblNoModel->SetVisible( false ); } @@ -392,9 +415,10 @@ void CRD_Collection_Panel_Swarmopedia::OnCommand( const char *command ) { if ( !V_strcmp( command, "CycleDisplay" ) ) { - if ( m_pAlien->Display.Count() ) + const RD_Swarmopedia::Alien *pAlien = GetAlien(); + if ( pAlien && pAlien->Display.Count() ) { - m_iCurrentDisplay = ( m_iCurrentDisplay + 1 ) % m_pAlien->Display.Count(); + m_iCurrentDisplay = ( m_iCurrentDisplay + 1 ) % pAlien->Display.Count(); InvalidateLayout(); } } @@ -431,3 +455,8 @@ void CRD_Collection_Panel_Swarmopedia::OnKeyCodePressed( vgui::KeyCode keycode ) break; } } + +const RD_Swarmopedia::Alien *CRD_Collection_Panel_Swarmopedia::GetAlien() const +{ + return RD_Swarmopedia::FindAlien( m_AlienID ); +} diff --git a/src/game/client/swarm/rd_swarmopedia.cpp b/src/game/client/swarm/rd_swarmopedia.cpp index ecaad019f..7c8083390 100644 --- a/src/game/client/swarm/rd_swarmopedia.cpp +++ b/src/game/client/swarm/rd_swarmopedia.cpp @@ -7,6 +7,8 @@ #include "asw_weapon_shared.h" #include "ammodef.h" #include "asw_ammo_drop_shared.h" +#include +#include // memdbgon must be the last include file in a .cpp file!!! #include "tier0/memdbgon.h" @@ -97,16 +99,77 @@ void Helpers::CopyUniqueVector( CUtlVectorAutoPurge &dst, const CUtlVectorA } } -Collection::Collection( const Collection © ) +static Collection *s_pSwarmopedia = NULL; + +const Collection &RD_Swarmopedia::Get() { - Helpers::CopyVector( Aliens, copy.Aliens ); - Helpers::CopyVector( Weapons, copy.Weapons ); + if ( !s_pSwarmopedia ) + { + Collection *pSwarmopedia = new Collection; + pSwarmopedia->ReadFromFiles(); + + s_pSwarmopedia = pSwarmopedia; + } + + return *s_pSwarmopedia; } -void Collection::ReadFromFiles( Subset subset ) +const Alien *RD_Swarmopedia::FindAlien( const char *id ) { - ReadSubset = subset; - UTIL_RD_LoadAllKeyValues( SWARMOPEDIA_PATH, "GAME", "Swarmopedia", &ReadHelper, this ); + const Collection &Swarmopedia = Get(); + FOR_EACH_VEC( Swarmopedia.Aliens, i ) + { + if ( Swarmopedia.Aliens[i]->ID == id ) + { + return Swarmopedia.Aliens[i]; + } + } + + return NULL; +} + +const Weapon *RD_Swarmopedia::FindWeapon( int iEquipIndex, bool bExtra ) +{ + const Collection &Swarmopedia = Get(); + FOR_EACH_VEC( Swarmopedia.Weapons, i ) + { + if ( Swarmopedia.Weapons[i]->EquipIndex == iEquipIndex && Swarmopedia.Weapons[i]->Extra == bExtra ) + { + return Swarmopedia.Weapons[i]; + } + } + + return NULL; +} + +const Weapon *RD_Swarmopedia::FindWeapon( const char *szClassName ) +{ + const Collection &Swarmopedia = Get(); + FOR_EACH_VEC( Swarmopedia.Weapons, i ) + { + if ( Swarmopedia.Weapons[i]->ClassName == szClassName ) + { + return Swarmopedia.Weapons[i]; + } + } + + return NULL; +} + +void RD_Swarmopedia::ClearCache() +{ + if ( s_pSwarmopedia ) + { + delete s_pSwarmopedia; + s_pSwarmopedia = NULL; + } +} + +CON_COMMAND( rd_swarmopedia_reload, "clear swarmopedia.txt cache" ) +{ + RD_Swarmopedia::ClearCache(); + // load it immediately so any console warnings are shown during the command + ( void )RD_Swarmopedia::Get(); } void Collection::ReadHelper( const char *pszPath, KeyValues *pKV, void *pUserData ) @@ -114,32 +177,36 @@ void Collection::ReadHelper( const char *pszPath, KeyValues *pKV, void *pUserDat static_cast< Collection * >( pUserData )->ReadFromFile( pszPath, pKV ); } +void Collection::ReadFromFiles() +{ + static bool s_bLoadWeaponDataOnce = true; + // make sure weapon ammo type data is loaded even if we accessed the Swarmopedia from the main menu + if ( s_bLoadWeaponDataOnce ) + { + if ( !engine->IsConnected() ) + { + g_ASWEquipmentList.LevelInitPreEntity(); + } + + s_bLoadWeaponDataOnce = false; + } + + UTIL_RD_LoadAllKeyValues( SWARMOPEDIA_PATH, "GAME", "Swarmopedia", &ReadHelper, this ); +} + void Collection::ReadFromFile( const char *pszPath, KeyValues *pKV ) { FOR_EACH_SUBKEY( pKV, pEntry ) { if ( FStrEq( pEntry->GetName(), "ALIEN" ) ) { - if ( int( ReadSubset ) & int( Subset::Aliens ) ) - { - Helpers::AddMerge( Aliens, pszPath, pEntry ); - } + Helpers::AddMerge( Aliens, pszPath, pEntry ); } else if ( FStrEq( pEntry->GetName(), "WEAPON" ) ) { - if ( int( ReadSubset ) & int( Subset::Weapons ) ) + if ( Weapon *pWeapon = Helpers::ReadFromFile( pszPath, pEntry ) ) { - if ( Weapon *pWeapon = Helpers::ReadFromFile( pszPath, pEntry ) ) - { - if ( int( ReadSubset ) & int( pWeapon->Extra ? Subset::ExtraWeapons : Subset::RegularWeapons ) ) - { - Helpers::AddMerge( Weapons, pWeapon ); - } - else - { - delete pWeapon; - } - } + Helpers::AddMerge( Weapons, pWeapon ); } } else @@ -738,6 +805,33 @@ bool Content::ReadFromFile( const char *pszPath, KeyValues *pKV ) { Text = pKV->GetString( "Text" ); Color = pKV->GetColor( "Color", Color ); + + if ( const char *szFont = pKV->GetString( "Font", NULL ) ) + { + vgui::HScheme hScheme = vgui::scheme()->LoadSchemeFromFileEx( NULL, "resource/SwarmSchemeNew.res", "SwarmSchemeNew" ); + Font = vgui::scheme()->GetIScheme( hScheme )->GetFont( szFont, true ); + } + } + else + { + Text = pKV->GetString(); + } + + return true; + } + else if ( FStrEq( pKV->GetName(), "ZbalermornaParagraph" ) ) + { + Type = Type_t::ZbalermornaParagraph; + if ( pKV->GetDataType() == KeyValues::TYPE_NONE ) + { + Text = pKV->GetString( "Text" ); + Color = pKV->GetColor( "Color", Color ); + + if ( const char *szFont = pKV->GetString( "Font", NULL ) ) + { + vgui::HScheme hScheme = vgui::scheme()->LoadSchemeFromFileEx( NULL, "resource/SwarmSchemeNew.res", "SwarmSchemeNew" ); + Font = vgui::scheme()->GetIScheme( hScheme )->GetFont( szFont, true ); + } } else { @@ -867,9 +961,42 @@ static void PostProcessBuiltin( WeaponFact *pFact, CASW_EquipItem *pItem, CASW_W break; case WeaponFact::Type_T::Piercing: break; + case WeaponFact::Type_T::StoppingPower: + { + int iDamageType = GetAmmoDef()->DamageType( bIsSecondary ? pItem->m_iAmmo2 : pItem->m_iAmmo1 ); + if ( iDamageType & DMG_SHOCK ) + { + Assert( bIsSecondary || pItem->m_flFlinchChance >= 1 ); + pFact->Base = 1; + pFact->Caption = "#rd_weapon_fact_stopping_power_shock"; + } + else if ( iDamageType & DMG_BLAST ) + { + Assert( bIsSecondary || pItem->m_flFlinchChance >= 1 ); + pFact->Base = 1; + pFact->Caption = "#rd_weapon_fact_stopping_power_blast"; + } + else + { + pFact->Base = pItem->m_flFlinchChance; + pFact->SkillMultiplier = pItem->m_flStoppingPowerFlinchBonus; + if ( pItem->m_flStoppingPowerFlinchBonus != 0.0f ) + { + pFact->Skill = ASW_MARINE_SKILL_STOPPING_POWER; + pFact->SubSkill = ASW_MARINE_SUBSKILL_STOPPING_POWER; + } + } + + break; + } case WeaponFact::Type_T::FireRate: pFact->Base += pItem->m_flFireRate; break; + case WeaponFact::Type_T::ReloadTime: + pFact->Skill = ASW_MARINE_SKILL_RELOADING; + pFact->SubSkill = ASW_MARINE_SUBSKILL_RELOADING_SPEED_SCALE; + pFact->SkillMultiplier = pWeaponInfo->m_flDisplayReloadTime > 0 ? pWeaponInfo->m_flDisplayReloadTime : pItem->m_flReloadTime; + break; case WeaponFact::Type_T::Ammo: pFact->Base += bIsSecondary ? pItem->DefaultAmmo2() : pItem->DefaultAmmo1(); @@ -1100,18 +1227,6 @@ bool Weapon::ReadFromFile( const char *pszPath, KeyValues *pKV ) Facts.InsertAfter( iNext++, Helpers::ReadFromFile( "INTERNAL", pFact ) ); } } - - if ( Facts[i]->UseWeaponInfo && Facts[i]->ClipSize ) - { - KeyValues::AutoDelete pFact( "Numeric" ); - pFact->SetString( "Icon", "swarm/swarmopedia/fact/reload" ); - pFact->SetString( "Caption", "#rd_weapon_fact_reload" ); - pFact->SetInt( "Precision", 2 ); - pFact->SetString( "Skill", "ASW_MARINE_SKILL_RELOADING" ); - pFact->SetString( "SubSkill", "ASW_MARINE_SUBSKILL_RELOADING_SPEED_SCALE" ); - pFact->SetFloat( "SkillMultiplier", pWeaponInfo->m_flDisplayReloadTime > 0 ? pWeaponInfo->m_flDisplayReloadTime : pItem->m_flReloadTime ); - Facts.InsertAfter( iNext++, Helpers::ReadFromFile( "INTERNAL", pFact ) ); - } } } } @@ -1159,6 +1274,71 @@ WeaponFact::WeaponFact( const WeaponFact © ) : Helpers::CopyVector( Facts, copy.Facts ); } +void WeaponFact::ComputeBaseAndSkill( float &flBase, float &flSkill, CASW_Marine_Profile *pProfile, int iSkillOverride ) const +{ + flBase = Base; + if ( !CVar.IsEmpty() ) + { + ConVarRef var( CVar ); + if ( Type != Type_T::DamagePerShot ) + { + flBase += var.GetFloat(); + } + else if ( var.GetFloat() > 0 ) + { + flBase = var.GetFloat(); + } + } + + flBase *= BaseMultiplier; + FOR_EACH_VEC( BaseMultiplierCVar, i ) + { + ConVarRef var( BaseMultiplierCVar[i] ); + flBase *= var.GetFloat(); + } + FOR_EACH_VEC( BaseDivisorCVar, i ) + { + ConVarRef var( BaseDivisorCVar[i] ); + flBase /= var.GetFloat(); + } + + flSkill = 0.0f; + float flBaseSkillBasedValue = 0.0f; + if ( Skill != ASW_MARINE_SKILL_INVALID ) + { + flSkill = MarineSkills()->GetSkillBasedValue( pProfile, Skill, SubSkill, iSkillOverride ); + + flBaseSkillBasedValue = MarineSkills()->GetSkillBasedValue( NULL, Skill, SubSkill, 0 ); + } + + flSkill *= SkillMultiplier; + flBaseSkillBasedValue *= SkillMultiplier; + FOR_EACH_VEC( SkillMultiplierCVar, i ) + { + ConVarRef var( SkillMultiplierCVar[i] ); + flSkill *= var.GetFloat(); + flBaseSkillBasedValue *= var.GetFloat(); + } + FOR_EACH_VEC( SkillDivisorCVar, i ) + { + ConVarRef var( SkillDivisorCVar[i] ); + flSkill /= var.GetFloat(); + flBaseSkillBasedValue /= var.GetFloat(); + } + + flSkill -= flBaseSkillBasedValue; + flBase += flBaseSkillBasedValue; + + if ( flBase + flSkill < MinimumValue ) + { + flBase = MinimumValue - flSkill; + } + else if ( flBase + flSkill > MaximumValue ) + { + flBase = MaximumValue - flSkill; + } +} + bool WeaponFact::ReadFromFile( const char *pszPath, KeyValues *pKV ) { const char *szName = pKV->GetName(); @@ -1198,11 +1378,21 @@ bool WeaponFact::ReadFromFile( const char *pszPath, KeyValues *pKV ) { Type = Type_T::Piercing; } + else if ( FStrEq( szName, "StoppingPower" ) ) + { + Type = Type_T::StoppingPower; + Precision = 2; + } else if ( FStrEq( szName, "FireRate" ) ) { Type = Type_T::FireRate; Precision = 2; } + else if ( FStrEq( szName, "ReloadTime" ) ) + { + Type = Type_T::ReloadTime; + Precision = 2; + } else if ( FStrEq( szName, "Ammo" ) ) { Type = Type_T::Ammo; @@ -1385,17 +1575,6 @@ void WeaponFact::Merge( const WeaponFact *pWeaponFact ) void RD_Swarmopedia::CheckArticleUnlock( const char *szStatName, int iStatBefore, int iStatAfter ) { - // We only load the Swarmopedia once per game run for unlock checking. - // This means if the player installs a mod that adds to the Swarmopedia - // after killing an alien and doesn't restart the game, they won't be - // notified if they unlock one of the new articles. Which is okay. - static Collection *s_pSwarmopediaForProgressChecking = NULL; - if ( !s_pSwarmopediaForProgressChecking ) - { - s_pSwarmopediaForProgressChecking = new Collection; - s_pSwarmopediaForProgressChecking->ReadFromFiles( Subset::Aliens ); - } - ISteamUserStats *pStats = SteamUserStats(); Assert( pStats ); if ( !pStats ) @@ -1403,9 +1582,10 @@ void RD_Swarmopedia::CheckArticleUnlock( const char *szStatName, int iStatBefore return; } - FOR_EACH_VEC( s_pSwarmopediaForProgressChecking->Aliens, i ) + const Collection &Swarmopedia = Get(); + FOR_EACH_VEC( Swarmopedia.Aliens, i ) { - Alien *pAlien = s_pSwarmopediaForProgressChecking->Aliens[i]; + Alien *pAlien = Swarmopedia.Aliens[i]; Assert( pAlien->Requirements.Count() <= 1 ); // if we ever use multiple requirements, we need to revisit this. FOR_EACH_VEC( pAlien->Requirements, j ) { diff --git a/src/game/client/swarm/rd_swarmopedia.h b/src/game/client/swarm/rd_swarmopedia.h index d1a43625b..6ee1d1137 100644 --- a/src/game/client/swarm/rd_swarmopedia.h +++ b/src/game/client/swarm/rd_swarmopedia.h @@ -37,32 +37,28 @@ namespace RD_Swarmopedia static void CopyUniqueVector( CUtlVectorAutoPurge &, const CUtlVectorAutoPurge & ); }; - enum class Subset - { - Aliens = 1 << 0, - RegularWeapons = 1 << 1, - ExtraWeapons = 1 << 2, - Weapons = RegularWeapons | ExtraWeapons, - All = Aliens | Weapons, - }; - struct Collection { - Collection() = default; - Collection( const Collection © ); - CUtlVectorAutoPurge Aliens{}; CUtlVectorAutoPurge Weapons{}; - void ReadFromFiles( Subset subset = Subset::All ); private: + Collection() = default; + Collection( const Collection © ) = delete; + friend struct Helpers; + friend const Collection &Get(); static void ReadHelper( const char *, KeyValues *, void * ); + void ReadFromFiles(); void ReadFromFile( const char *, KeyValues * ); - - Subset ReadSubset{}; }; + const Collection &Get(); + const Alien *FindAlien( const char *id ); + const Weapon *FindWeapon( int iEquipIndex, bool bExtra ); + const Weapon *FindWeapon( const char *szClassName ); + void ClearCache(); + struct Alien { Alien() = default; @@ -200,10 +196,12 @@ namespace RD_Swarmopedia enum class Type_t { Paragraph, + ZbalermornaParagraph, } Type{ Type_t::Paragraph }; CUtlString Text{}; Color Color{ 224, 224, 224, 255 }; + vgui::HFont Font{ vgui::INVALID_FONT }; private: friend struct Helpers; @@ -256,7 +254,9 @@ namespace RD_Swarmopedia LargeAlienDamageScale, BulletSpread, Piercing, + StoppingPower, FireRate, + ReloadTime, Ammo, Secondary, Deployed, @@ -302,6 +302,8 @@ namespace RD_Swarmopedia // Secondary CUtlVectorAutoPurge Facts{}; + void ComputeBaseAndSkill( float &flBase, float &flSkill, CASW_Marine_Profile *pProfile, int iSkillOverride = -1 ) const; + private: friend struct Helpers; bool ReadFromFile( const char *, KeyValues * ); diff --git a/src/game/client/swarm/vgui/nb_lobby_tooltip.cpp b/src/game/client/swarm/vgui/nb_lobby_tooltip.cpp index e6b1686c5..9841d4119 100644 --- a/src/game/client/swarm/vgui/nb_lobby_tooltip.cpp +++ b/src/game/client/swarm/vgui/nb_lobby_tooltip.cpp @@ -377,12 +377,13 @@ void CNB_Lobby_Tooltip::OnTick() { int nProfileIndex = pProfile->m_ProfileIndex; int nEquipIndex = Briefing()->GetProfileSelectedWeapon( nProfileIndex, m_nInventorySlot ); - m_pWeaponDetail0->SetWeaponDetails( nEquipIndex, m_nInventorySlot, nProfileIndex, 0 ); - m_pWeaponDetail1->SetWeaponDetails( nEquipIndex, m_nInventorySlot, nProfileIndex, 1 ); - m_pWeaponDetail2->SetWeaponDetails( nEquipIndex, m_nInventorySlot, nProfileIndex, 2 ); - m_pWeaponDetail3->SetWeaponDetails( nEquipIndex, m_nInventorySlot, nProfileIndex, 3 ); - m_pWeaponDetail4->SetWeaponDetails( nEquipIndex, m_nInventorySlot, nProfileIndex, 4 ); - m_pWeaponDetail5->SetWeaponDetails( nEquipIndex, m_nInventorySlot, nProfileIndex, 5 ); + + m_pWeaponDetail0->SetWeaponDetails( nEquipIndex, m_nInventorySlot, nProfileIndex, RD_Swarmopedia::WeaponFact::Type_T::DamagePerShot ); + m_pWeaponDetail1->SetWeaponDetails( nEquipIndex, m_nInventorySlot, nProfileIndex, RD_Swarmopedia::WeaponFact::Type_T::FireRate ); + m_pWeaponDetail2->SetWeaponDetails( nEquipIndex, m_nInventorySlot, nProfileIndex, RD_Swarmopedia::WeaponFact::Type_T::ReloadTime ); + m_pWeaponDetail3->SetWeaponDetails( nEquipIndex, m_nInventorySlot, nProfileIndex, RD_Swarmopedia::WeaponFact::Type_T::Ammo ); + m_pWeaponDetail4->SetWeaponDetails( nEquipIndex, m_nInventorySlot, nProfileIndex, RD_Swarmopedia::WeaponFact::Type_T::Secondary ); + m_pWeaponDetail5->SetWeaponDetails( nEquipIndex, m_nInventorySlot, nProfileIndex, RD_Swarmopedia::WeaponFact::Type_T::Generic ); // uses the attributes string for the weapon } m_pTitle->SetText( pItem->m_szLongName ); diff --git a/src/game/client/swarm/vgui/nb_weapon_detail.cpp b/src/game/client/swarm/vgui/nb_weapon_detail.cpp index 942377270..8686e0551 100644 --- a/src/game/client/swarm/vgui/nb_weapon_detail.cpp +++ b/src/game/client/swarm/vgui/nb_weapon_detail.cpp @@ -11,6 +11,7 @@ #include "asw_marine_skills.h" #include "c_asw_game_resource.h" #include "c_asw_marine_resource.h" +#include "rd_swarmopedia.h" // memdbgon must be the last include file in a .cpp file!!! #include "tier0/memdbgon.h" @@ -75,333 +76,241 @@ void CNB_Weapon_Detail::OnThink() } } -void CNB_Weapon_Detail::SetWeaponDetails( int nEquipIndex, int nInventorySlot, int nProfileIndex, int nDetailIndex ) +void CNB_Weapon_Detail::SetWeaponDetails( int nEquipIndex, int nInventorySlot, int nProfileIndex, RD_Swarmopedia::WeaponFact::Type_T eWeaponFactType ) { m_nEquipIndex = nEquipIndex; m_nInventorySlot = nInventorySlot; m_nProfileIndex = nProfileIndex; - m_nDetailIndex = nDetailIndex; + m_eWeaponFactType = eWeaponFactType; } void CNB_Weapon_Detail::UpdateLabels( CASW_EquipItem *pItem, CASW_WeaponInfo *pWeaponData ) { + m_pTitleLabel->SetVisible( false ); + m_pValueLabel->SetVisible( false ); + m_pStatsBar->SetVisible( false ); + C_ASW_Player *pPlayer = C_ASW_Player::GetLocalASWPlayer(); if ( !pPlayer ) return; CASW_Marine_Profile *pProfile = Briefing()->GetMarineProfileByProfileIndex( m_nProfileIndex ); - switch( m_nDetailIndex ) + const RD_Swarmopedia::Weapon *pWeapon = RD_Swarmopedia::FindWeapon( pItem->m_iItemIndex, pItem->m_bIsExtra ); + if ( !pWeapon ) { - case 0: - { - // for the chainsaw (which uses melee damage as a skill modifier), it applies a base value to the specified number in the script file - // even if the skill is at 0 - because of this, we have to make a special case for the chainsaw and shift those values from the - // "bonus" side to the "base" side because the base bonus always exists - confused yet? - float flBaseSkillDmgShift = 0; - int nBonusDmg = 0; - int nPellets = pItem->m_nNumPellets; - if ( pProfile ) - { - if ( FStrEq("asw_weapon_prifle", pWeaponData->szClassName) ) - nBonusDmg = MarineSkills()->GetSkillBasedValue(pProfile, ASW_MARINE_SKILL_ACCURACY, ASW_MARINE_SUBSKILL_ACCURACY_PRIFLE_DMG); - else if ( FStrEq("asw_weapon_shotgun", pWeaponData->szClassName) ) - nBonusDmg = MarineSkills()->GetSkillBasedValue(pProfile, ASW_MARINE_SKILL_ACCURACY, ASW_MARINE_SUBSKILL_ACCURACY_SHOTGUN_DMG); - else if ( FStrEq("asw_weapon_railgun", pWeaponData->szClassName) ) - nBonusDmg = MarineSkills()->GetSkillBasedValue(pProfile, ASW_MARINE_SKILL_ACCURACY, ASW_MARINE_SUBSKILL_ACCURACY_RAILGUN_DMG); - else if ( FStrEq("asw_weapon_flamer", pWeaponData->szClassName) || FStrEq("asw_weapon_sentry_flamer", pWeaponData->szClassName) ) - nBonusDmg = MarineSkills()->GetSkillBasedValue(pProfile, ASW_MARINE_SKILL_ACCURACY, ASW_MARINE_SUBSKILL_ACCURACY_FLAMER_DMG); - else if ( FStrEq("asw_weapon_pistol", pWeaponData->szClassName) ) - nBonusDmg = MarineSkills()->GetSkillBasedValue(pProfile, ASW_MARINE_SKILL_ACCURACY, ASW_MARINE_SUBSKILL_ACCURACY_PISTOL_DMG); - else if ( FStrEq( "asw_weapon_deagle", pWeaponData->szClassName ) ) - nBonusDmg = MarineSkills()->GetSkillBasedValue( pProfile, ASW_MARINE_SKILL_ACCURACY, ASW_MARINE_SUBSKILL_ACCURACY_DEAGLE_DMG ); - else if ( FStrEq("asw_weapon_pdw", pWeaponData->szClassName) ) - nBonusDmg = MarineSkills()->GetSkillBasedValue(pProfile, ASW_MARINE_SKILL_ACCURACY, ASW_MARINE_SUBSKILL_ACCURACY_PDW_DMG); - else if ( FStrEq("asw_weapon_sniper_rifle", pWeaponData->szClassName) ) - nBonusDmg = MarineSkills()->GetSkillBasedValue(pProfile, ASW_MARINE_SKILL_ACCURACY, ASW_MARINE_SUBSKILL_ACCURACY_SNIPER_RIFLE_DMG); - else if ( FStrEq("asw_weapon_tesla_gun", pWeaponData->szClassName) ) - nBonusDmg = 0.5f + MarineSkills()->GetSkillBasedValue(pProfile, ASW_MARINE_SKILL_ACCURACY, ASW_MARINE_SUBSKILL_ACCURACY_TESLA_CANNON_DMG); - else if ( FStrEq("asw_weapon_chainsaw", pWeaponData->szClassName) ) - { - flBaseSkillDmgShift = MarineSkills()->GetSkillBasedValue( NULL, ASW_MARINE_SKILL_MELEE, ASW_MARINE_SUBSKILL_MELEE_DMG, 0 ); - nBonusDmg = MarineSkills()->GetSkillBasedValue(pProfile, ASW_MARINE_SKILL_MELEE, ASW_MARINE_SUBSKILL_MELEE_DMG); - } - else if ( FStrEq("asw_weapon_vindicator", pWeaponData->szClassName) ) - { - nBonusDmg = MarineSkills()->GetSkillBasedValue(pProfile, ASW_MARINE_SKILL_VINDICATOR, ASW_MARINE_SUBSKILL_VINDICATOR_DAMAGE); - nPellets = MarineSkills()->GetSkillBasedValue(pProfile, ASW_MARINE_SKILL_VINDICATOR, ASW_MARINE_SUBSKILL_VINDICATOR_PELLETS); - } - else if ( FStrEq("asw_weapon_autogun", pWeaponData->szClassName) || FStrEq("asw_weapon_minigun", pWeaponData->szClassName) ) - nBonusDmg = MarineSkills()->GetSkillBasedValue(pProfile, ASW_MARINE_SKILL_AUTOGUN, ASW_MARINE_SUBSKILL_AUTOGUN_DMG); - else if ( FStrEq("asw_weapon_grenade_launcher", pWeaponData->szClassName) ) - nBonusDmg = MarineSkills()->GetSkillBasedValue(pProfile, ASW_MARINE_SKILL_GRENADES, ASW_MARINE_SUBSKILL_GRENADE_CLUSTER_DMG); - else if ( FStrEq("asw_weapon_sentry_cannon", pWeaponData->szClassName) ) - nBonusDmg = MarineSkills()->GetSkillBasedValue(pProfile, ASW_MARINE_SKILL_GRENADES, ASW_MARINE_SUBSKILL_GRENADE_CLUSTER_DMG) * 0.5f; - else if ( FStrEq( "asw_weapon_heavy_rifle", pWeaponData->szClassName ) ) - nBonusDmg = MarineSkills()->GetSkillBasedValue( pProfile, ASW_MARINE_SKILL_ACCURACY, ASW_MARINE_SUBSKILL_ACCURACY_HEAVY_RIFLE_DMG ); - else if ( FStrEq( "asw_weapon_medrifle", pWeaponData->szClassName ) ) - nBonusDmg = MarineSkills()->GetSkillBasedValue( pProfile, ASW_MARINE_SKILL_ACCURACY, ASW_MARINE_SUBSKILL_ACCURACY_MEDRIFLE_DMG ); - else - nBonusDmg = MarineSkills()->GetSkillBasedValue(pProfile, ASW_MARINE_SKILL_ACCURACY, ASW_MARINE_SUBSKILL_ACCURACY_RIFLE_DMG); - - } - - // fire power - static wchar_t wszPowerLine[32]; - int iDamValue = ( pItem->m_flBaseDamage * pItem->m_nNumPellets ) + flBaseSkillDmgShift; - int nTotalBonusDmg = ( nBonusDmg * nPellets ) - flBaseSkillDmgShift; - Q_snwprintf( wszPowerLine, ARRAYSIZE( wszPowerLine ), L"%s", g_pVGuiLocalize->Find( "#asw_weapon_details_firepower" ) ); - wchar_t wzDamValue[10]; - if ( iDamValue <= 0 ) - { - Q_snwprintf( wzDamValue, ARRAYSIZE( wzDamValue ), L"%s", g_pVGuiLocalize->Find( "#asw_weapon_altfire_NA" ) ); - } - else if ( nTotalBonusDmg > 0 ) - { - Q_snwprintf( wzDamValue, ARRAYSIZE( wzDamValue ), L"%d (+%d)", iDamValue, nTotalBonusDmg ); - } - else - { - Q_snwprintf( wzDamValue, ARRAYSIZE( wzDamValue ), L"%d", iDamValue ); - } + m_pTitleLabel->SetVisible( true ); + m_pTitleLabel->SetText( pItem->m_szEquipClass ); + m_pValueLabel->SetVisible( true ); + m_pValueLabel->SetText( L"MISSING SWARMOPEDIA ARTICLE" ); // this is not translated because it should not ever show up in the released game + return; + } - m_pTitleLabel->SetText( wszPowerLine ); + if ( m_eWeaponFactType == RD_Swarmopedia::WeaponFact::Type_T::Generic ) + { + if ( const wchar_t *wszAttributesValue = g_pVGuiLocalize->Find( pItem->m_szAttributeDescription ) ) + { m_pTitleLabel->SetVisible( true ); - m_pValueLabel->SetText( wzDamValue ); + m_pTitleLabel->SetText( g_pVGuiLocalize->Find( "#asw_weapon_details_notes" ) ); m_pValueLabel->SetVisible( true ); - - float flDamage = iDamValue + nTotalBonusDmg; - float flCurrent = 0.0f; - if ( flDamage > 60 ) - flCurrent = 1.0f; - else if ( iDamValue > 0 ) - flCurrent = MAX( (flDamage-5.0f) / 55.0f, 0.05f ); - - if ( flDamage <= 0.0f ) - { - m_pValueLabel->SetText( "#asw_weapon_altfire_NA" ); - m_pStatsBar->SetVisible( false ); - } - else - { - m_pStatsBar->Init( flCurrent, flCurrent, 0.1f, false, false ); - m_pStatsBar->SetVisible( true ); - } + m_pValueLabel->SetText( wszAttributesValue ); + } + + return; + } + const RD_Swarmopedia::WeaponFact *pFact = NULL; + FOR_EACH_VEC( pWeapon->Facts, i ) + { + if ( pWeapon->Facts[i]->Type == m_eWeaponFactType ) + { + pFact = pWeapon->Facts[i]; break; } + } - case 1: - { - // fire rate - static wchar_t wszRateLine[32]; - Q_snwprintf( wszRateLine, ARRAYSIZE( wszRateLine ), L"%s", g_pVGuiLocalize->Find( "#asw_weapon_details_firerate" ) ); - m_pTitleLabel->SetText( wszRateLine ); - m_pTitleLabel->SetVisible( true ); + m_pTitleLabel->SetVisible( true ); + if ( m_eWeaponFactType == RD_Swarmopedia::WeaponFact::Type_T::DamagePerShot ) + { + m_pTitleLabel->SetText( "#asw_weapon_details_firepower" ); + } + else if ( m_eWeaponFactType == RD_Swarmopedia::WeaponFact::Type_T::FireRate ) + { + m_pTitleLabel->SetText( "#asw_weapon_details_firerate" ); + } + else if ( m_eWeaponFactType == RD_Swarmopedia::WeaponFact::Type_T::ReloadTime ) + { + m_pTitleLabel->SetText( "#asw_weapon_details_reload" ); + } + else if ( m_eWeaponFactType == RD_Swarmopedia::WeaponFact::Type_T::Ammo ) + { + m_pTitleLabel->SetText( "#asw_weapon_details_clipsize" ); + } + else if ( m_eWeaponFactType == RD_Swarmopedia::WeaponFact::Type_T::Secondary ) + { + m_pTitleLabel->SetText( "#asw_weapon_details_altfire" ); + } - float flRate = pItem->m_flFireRate; - wchar_t wzFireValue[32]; + if ( !pFact ) + { + m_pValueLabel->SetVisible( true ); + m_pValueLabel->SetText( m_eWeaponFactType == RD_Swarmopedia::WeaponFact::Type_T::Secondary ? "#asw_weapon_altfire_none" : "#asw_weapon_altfire_NA" ); + return; + } - if ( FStrEq( "asw_weapon_prifle", pWeaponData->szClassName ) ) - { - flRate -= MarineSkills()->GetSkillBasedValue( pProfile, ASW_MARINE_SKILL_ENGINEERING, ASW_MARINE_SUBSKILL_ENGINEERING_FIRERATE ); - flRate = MAX(0.005, flRate); //0.07 is default - } + float flBase, flSkill; + pFact->ComputeBaseAndSkill( flBase, flSkill, pProfile ); - float flCurrent = 0.0f; - if ( flRate <= 0 ) - { - Q_snwprintf( wzFireValue, ARRAYSIZE( wzFireValue ), L"%s", g_pVGuiLocalize->Find( "#asw_weapon_altfire_NA" ) ); - } - else + if ( m_eWeaponFactType == RD_Swarmopedia::WeaponFact::Type_T::DamagePerShot ) + { + const RD_Swarmopedia::WeaponFact *pPellets = NULL; + FOR_EACH_VEC( pWeapon->Facts, i ) + { + if ( pWeapon->Facts[i]->Type == RD_Swarmopedia::WeaponFact::Type_T::ShotgunPellets ) { - Q_snwprintf( wzFireValue, ARRAYSIZE( wzFireValue ), L"%.1f / %s", (1.0f/flRate), g_pVGuiLocalize->Find( "#asw_weapon_details_seconds" ) ); - if ( flRate <= 0.125f ) - flCurrent = 1.0f - MIN( ( ( pItem->m_flFireRate - 0.03f ) / 0.125f ) * 0.5f, 0.48f ); - else - flCurrent = 1.0f - MIN( ( ( pItem->m_flFireRate - 0.5f ) / 0.65f ) + 0.5f, 0.98f ); + pPellets = pWeapon->Facts[i]; + break; } - - m_pValueLabel->SetText( wzFireValue ); - m_pValueLabel->SetVisible( true ); - m_pStatsBar->Init( flCurrent, flCurrent, 0.1f, false, false ); - m_pStatsBar->SetVisible( true ); - - break; } - case 2: + if ( pPellets ) { - // the skill modifies the base reload time by this amount so all of the numbers in the script files are incorrect for displaying base amount - float flBaseSkillModifier = MarineSkills()->GetSkillBasedValue( NULL, ASW_MARINE_SKILL_RELOADING, ASW_MARINE_SUBSKILL_RELOADING_SPEED_SCALE, 0 ); - // reload time - static wchar_t wszReloadLine[32]; - Q_snwprintf( wszReloadLine, ARRAYSIZE( wszReloadLine ), L"%s", g_pVGuiLocalize->Find( "#asw_weapon_details_reload" ) ); - float flBaseReload = pItem->m_flReloadTime; - if ( pWeaponData->m_flDisplayReloadTime >= 0 ) - flBaseReload = pWeaponData->m_flDisplayReloadTime; - - float flCurrent = flBaseReload; - float flRealReload = flBaseReload; - wchar_t wzReloadValue[32]; - if ( flBaseReload <= 0 ) - { - Q_snwprintf( wzReloadValue, ARRAYSIZE( wzReloadValue ), L"%s", g_pVGuiLocalize->Find( "#asw_weapon_altfire_NA" ) ); - } - else - { - float fSpeedScale = 1; - float flReloadDiff = 0; - if ( pProfile ) - { - fSpeedScale = MarineSkills()->GetSkillBasedValue(pProfile, ASW_MARINE_SKILL_RELOADING, ASW_MARINE_SUBSKILL_RELOADING_SPEED_SCALE); - if ( fSpeedScale != 1 ) - { - flRealReload = flBaseReload * fSpeedScale; - - // to get an accurate difference, we need to multiply the script defined base reload amount by the base modifier that the Skill does - flReloadDiff = flRealReload - (flBaseReload * flBaseSkillModifier); - } - } - - if ( flReloadDiff != 0 ) - Q_snwprintf( wzReloadValue, ARRAYSIZE( wzReloadValue ), L"%.1f %s (%s%.1f)", (flBaseReload*flBaseSkillModifier), g_pVGuiLocalize->Find( "#asw_weapon_details_seconds" ), (flReloadDiff>0)?L"+":L"", flReloadDiff ); - else - Q_snwprintf( wzReloadValue, ARRAYSIZE( wzReloadValue ), L"%.1f %s", (flBaseReload*flBaseSkillModifier), g_pVGuiLocalize->Find( "#asw_weapon_details_seconds" ) ); - flCurrent = 1.0f - MIN( (flRealReload-0.75f)/2.5f, 0.99f ); - } + float flBasePellets, flSkillPellets; + pPellets->ComputeBaseAndSkill( flBasePellets, flSkillPellets, pProfile ); - m_pTitleLabel->SetText( wszReloadLine ); - m_pTitleLabel->SetVisible( true ); - m_pValueLabel->SetText( wzReloadValue ); - m_pValueLabel->SetVisible( true ); - m_pStatsBar->Init( flCurrent, flCurrent, 0.1f, false, false ); - m_pStatsBar->SetVisible( true ); - break; + int iPellets = flBasePellets + flSkillPellets; + + flBase *= iPellets; + flSkill *= iPellets; } - case 3: + wchar_t wzDamValue[10]; + if ( flBase + flSkill <= 0 ) { - // clip capacity - static wchar_t wszClipLine[32]; - Q_snwprintf( wszClipLine, ARRAYSIZE( wszClipLine ), L"%s", g_pVGuiLocalize->Find( "#asw_weapon_details_clipsize" ) ); - int iClipValue = pItem->MaxAmmo1(); - int nMaxBulletsPerGun = GetAmmoDef()->MaxCarry( pItem->m_iAmmo1, NULL ); - int iNumClips = ( nMaxBulletsPerGun / iClipValue ) + 1; - if ( pWeaponData->m_bShowClipsDoubled ) - { - iNumClips *= 2; - } + V_snwprintf( wzDamValue, ARRAYSIZE( wzDamValue ), L"%s", g_pVGuiLocalize->Find( "#asw_weapon_altfire_NA" ) ); + } + else if ( flSkill > 0 ) + { + V_snwprintf( wzDamValue, ARRAYSIZE( wzDamValue ), L"%d (+%d)", int( flBase + flSkill ), int( flSkill ) ); + } + else + { + V_snwprintf( wzDamValue, ARRAYSIZE( wzDamValue ), L"%d", int( flBase ) ); + } - if ( pWeaponData->m_iDisplayClipSize >= 0 ) - iClipValue = pWeaponData->m_iDisplayClipSize; + m_pValueLabel->SetVisible( true ); + m_pValueLabel->SetText( wzDamValue ); - wchar_t wzClipValue[10]; - if ( iClipValue == 111 ) // magic number for infinite ammo - { - // this displays an "infinity" symbol in the neosans font - wzClipValue[0] = 0x221E; - wzClipValue[1] = L'\0'; - } - else if ( pWeaponData->m_bShowClipsInWeaponDetail ) - { - Q_snwprintf( wzClipValue, ARRAYSIZE( wzClipValue ), L"%d x %d", iClipValue, iNumClips ); - } - else - { - Q_snwprintf( wzClipValue, ARRAYSIZE( wzClipValue ), L"%d", iClipValue ); - } - float flCurrent = MIN( (float)iClipValue/200.0f, 1.0f ); + float flDamage = flBase + flSkill; + float flCurrent = 0.0f; + if ( flDamage > 60 ) + flCurrent = 1.0f; + else if ( flBase > 0 ) + flCurrent = MAX( ( flDamage - 5.0f ) / 55.0f, 0.05f ); - m_pTitleLabel->SetText( wszClipLine ); - m_pTitleLabel->SetVisible( true ); - m_pValueLabel->SetText( wzClipValue ); - m_pValueLabel->SetVisible( true ); - m_pStatsBar->Init( flCurrent, flCurrent, 0.1f, false, false ); + if ( flDamage <= 0.0f ) + { + m_pValueLabel->SetText( "#asw_weapon_altfire_NA" ); + } + else + { m_pStatsBar->SetVisible( true ); - break; + m_pStatsBar->Init( flCurrent, flCurrent, 0.1f, false, false ); } + } + else if ( m_eWeaponFactType == RD_Swarmopedia::WeaponFact::Type_T::FireRate ) + { + wchar_t wzFireValue[32]; - case 4: - { - // alt fire - static wchar_t wszAltLine[32]; - Q_snwprintf( wszAltLine, ARRAYSIZE( wszAltLine ), L"%s", g_pVGuiLocalize->Find( "#asw_weapon_details_altfire" ) ); - wchar_t wzAltValue[64]; - bool bHighlightText = false; - - if ( !g_pVGuiLocalize->Find( pItem->m_szAltFireDescription ) ) - V_snwprintf( wzAltValue, ARRAYSIZE( wzAltValue ), L"%s", g_pVGuiLocalize->Find( "#asw_weapon_altfire_none" ) ); - else - { - int iAltFire = pItem->DefaultAmmo2(); - if ( iAltFire > 0 ) - Q_snwprintf( wzAltValue, ARRAYSIZE( wzAltValue ), L"%d %s", iAltFire, g_pVGuiLocalize->Find( pItem->m_szAltFireDescription ) ); - else - Q_snwprintf( wzAltValue, ARRAYSIZE( wzAltValue ), L"%s", g_pVGuiLocalize->Find( pItem->m_szAltFireDescription ) ); - bHighlightText = true; - } + float flTotal = flBase + flSkill; - m_pTitleLabel->SetText( wszAltLine ); - m_pTitleLabel->SetVisible( true ); - m_pValueLabel->SetText( wzAltValue ); - m_pValueLabel->SetVisible( true ); - m_pStatsBar->SetVisible( false ); - break; + float flCurrent = 0.0f; + if ( flTotal <= 0 ) + { + V_snwprintf( wzFireValue, ARRAYSIZE( wzFireValue ), L"%s", g_pVGuiLocalize->Find( "#asw_weapon_altfire_NA" ) ); } - - case 5: + else { - // attributes - static wchar_t wszAttributesLine[32]; - Q_snwprintf( wszAttributesLine, ARRAYSIZE( wszAttributesLine ), L"%s", g_pVGuiLocalize->Find( "#asw_weapon_details_notes" ) ); - bool bHighlightText = false; - const wchar_t *wszAttributesValue = g_pVGuiLocalize->Find( pItem->m_szAttributeDescription ); - if ( !wszAttributesValue ) + float flTotalReciprocal = 1.0f / flTotal; + float flBaseReciprocal = 1.0f / flBase; + + if ( flSkill == 0.0f ) { - m_pTitleLabel->SetVisible( false ); - m_pValueLabel->SetVisible( false ); + V_snwprintf( wzFireValue, ARRAYSIZE( wzFireValue ), L"%.1f / %s", flTotalReciprocal, g_pVGuiLocalize->Find( "#asw_weapon_details_seconds" ) ); } else { - bHighlightText = true; - m_pTitleLabel->SetText( wszAttributesLine ); - m_pTitleLabel->SetVisible( true ); - m_pValueLabel->SetText( wszAttributesValue ); - m_pValueLabel->SetVisible( true ); + V_snwprintf( wzFireValue, ARRAYSIZE( wzFireValue ), L"%.1f (%+.1f) / %s", flTotalReciprocal, flTotalReciprocal - flBaseReciprocal, g_pVGuiLocalize->Find( "#asw_weapon_details_seconds" ) ); } - m_pStatsBar->SetVisible( false ); - - break; + if ( flTotal <= 0.125f ) + flCurrent = 1.0f - MIN( ( ( flTotal - 0.03f ) / 0.125f ) * 0.5f, 0.48f ); + else + flCurrent = 1.0f - MIN( ( ( flTotal - 0.5f ) / 0.65f ) + 0.5f, 0.98f ); } - case 6: - { - int nRequiredLevel = pPlayer->GetWeaponLevelRequirement( pWeaponData->szClassName ); - if ( nRequiredLevel == -1 ) - { - m_pTitleLabel->SetVisible( false ); - m_pValueLabel->SetVisible( false ); - m_pStatsBar->SetVisible( false ); - return; - } + m_pValueLabel->SetVisible( true ); + m_pValueLabel->SetText( wzFireValue ); + m_pStatsBar->SetVisible( true ); + m_pStatsBar->Init( flCurrent, flCurrent, 0.1f, false, false ); + } + else if ( m_eWeaponFactType == RD_Swarmopedia::WeaponFact::Type_T::ReloadTime ) + { + wchar_t wszReloadValue[32]; + if ( flSkill != 0.0f ) + V_snwprintf( wszReloadValue, ARRAYSIZE( wszReloadValue ), L"%.1f (%+.1f) %s", flBase + flSkill, flSkill, g_pVGuiLocalize->Find( "#asw_weapon_details_seconds" ) ); + else + V_snwprintf( wszReloadValue, ARRAYSIZE( wszReloadValue ), L"%.1f %s", flBase, g_pVGuiLocalize->Find( "#asw_weapon_details_seconds" ) ); + + float flCurrent = 1.0f - MIN( ( flBase + flSkill - 0.75f ) / 2.5f, 0.99f ); + + m_pValueLabel->SetVisible( true ); + m_pValueLabel->SetText( wszReloadValue ); + m_pStatsBar->SetVisible( true ); + m_pStatsBar->Init( flCurrent, flCurrent, 0.1f, false, false ); + } + else if ( m_eWeaponFactType == RD_Swarmopedia::WeaponFact::Type_T::Ammo ) + { + int iClipValue = pItem->MaxAmmo1(); + int nMaxBulletsPerGun = GetAmmoDef()->MaxCarry( pItem->m_iAmmo1, NULL ); + Assert( nMaxBulletsPerGun % iClipValue == 0 ); + int iNumClips = ( nMaxBulletsPerGun / iClipValue ) + 1; - // required level - static wchar_t wszAltLine[32]; - Q_snwprintf( wszAltLine, ARRAYSIZE( wszAltLine ), L"%s", g_pVGuiLocalize->Find( "#asw_weapon_details_required_level" ) ); + if ( pWeaponData->m_iDisplayClipSize >= 0 ) + iClipValue = pWeaponData->m_iDisplayClipSize; - nRequiredLevel++; // for display it's actually 1 higher (levels start from 0 in code) - wchar_t wzAltValue[64]; - Q_snwprintf( wzAltValue, ARRAYSIZE( wzAltValue ), L"%d", nRequiredLevel ); + wchar_t wszClipValue[10]; + if ( iClipValue == 111 ) // magic number for infinite ammo + { + // this displays an "infinity" symbol in the neosans font + V_snwprintf( wszClipValue, ARRAYSIZE( wszClipValue ), L"\u221E" ); + } + else if ( pWeaponData->m_bShowClipsInWeaponDetail ) + { + V_snwprintf( wszClipValue, ARRAYSIZE( wszClipValue ), L"%d \u00d7 %d", iClipValue, iNumClips ); + } + else + { + V_snwprintf( wszClipValue, ARRAYSIZE( wszClipValue ), L"%d", iClipValue ); + } + float flCurrent = MIN( ( float )iClipValue / 200.0f, 1.0f ); - m_pTitleLabel->SetText( wszAltLine ); - m_pTitleLabel->SetVisible( true ); - m_pValueLabel->SetText( wzAltValue ); - m_pValueLabel->SetVisible( true ); - m_pStatsBar->SetVisible( false ); + m_pValueLabel->SetVisible( true ); + m_pValueLabel->SetText( wszClipValue ); + m_pStatsBar->SetVisible( true ); + m_pStatsBar->Init( flCurrent, flCurrent, 0.1f, false, false ); + } + else if ( m_eWeaponFactType == RD_Swarmopedia::WeaponFact::Type_T::Secondary ) + { + wchar_t wszAltValue[64]; - break; - } - } + int iAltFire = pItem->DefaultAmmo2(); + if ( iAltFire > 0 ) + V_snwprintf( wszAltValue, ARRAYSIZE( wszAltValue ), L"%d %s", iAltFire, g_pVGuiLocalize->Find( pItem->m_szAltFireDescription ) ); + else + V_snwprintf( wszAltValue, ARRAYSIZE( wszAltValue ), L"%s", g_pVGuiLocalize->Find( pItem->m_szAltFireDescription ) ); + + m_pValueLabel->SetVisible( true ); + m_pValueLabel->SetText( wszAltValue ); + } } diff --git a/src/game/client/swarm/vgui/nb_weapon_detail.h b/src/game/client/swarm/vgui/nb_weapon_detail.h index 98d1f0b4c..cf6a5c1ba 100644 --- a/src/game/client/swarm/vgui/nb_weapon_detail.h +++ b/src/game/client/swarm/vgui/nb_weapon_detail.h @@ -6,6 +6,7 @@ #include #include +#include "rd_swarmopedia.h" // == MANAGED_CLASS_DECLARATIONS_START: Do not edit by hand == class vgui::Label; @@ -25,7 +26,7 @@ class CNB_Weapon_Detail : public vgui::EditablePanel virtual void PerformLayout(); virtual void OnThink(); - void SetWeaponDetails( int nEquipIndex, int nInventorySlot, int nProfileIndex, int nDetailIndex ); + void SetWeaponDetails( int nEquipIndex, int nInventorySlot, int nProfileIndex, RD_Swarmopedia::WeaponFact::Type_T eWeaponFactType ); void UpdateLabels( CASW_EquipItem *pItem, CASW_WeaponInfo *pWeaponData ); @@ -38,7 +39,7 @@ class CNB_Weapon_Detail : public vgui::EditablePanel bool m_bHidden; int m_nEquipIndex; int m_nInventorySlot; - int m_nDetailIndex; + RD_Swarmopedia::WeaponFact::Type_T m_eWeaponFactType; int m_nProfileIndex; }; diff --git a/src/game/shared/swarm/asw_marine_skills.cpp b/src/game/shared/swarm/asw_marine_skills.cpp index 0591aef9a..59e4e24fc 100644 --- a/src/game/shared/swarm/asw_marine_skills.cpp +++ b/src/game/shared/swarm/asw_marine_skills.cpp @@ -126,9 +126,9 @@ enum AMSC_RELOADING_STEP, AMSC_RELOADING_FAST_STEP, AMSC_AGILITY_MOVESPEED_STEP, - AMSC_AGILITY_RELOAD_STEP, + AMSC_AGILITY_RELOAD_STEP, // unused AMSC_MINES_FIRES_BASE, - AMSC_MINES_FIRES_STEP, + AMSC_MINES_FIRES_STEP, // unused AMSC_MINES_DURATION_BASE, AMSC_MINES_DURATION_STEP, AMSC_ACCURACY_RIFLE_DMG_BASE, @@ -143,8 +143,8 @@ enum AMSC_ACCURACY_FLAMER_DMG_STEP, AMSC_ACCURACY_PISTOL_DMG_BASE, AMSC_ACCURACY_PISTOL_DMG_STEP, - AMSC_ACCURACY_DEAGLE_DMG_BASE, - AMSC_ACCURACY_DEAGLE_DMG_STEP, + AMSC_ACCURACY_BULLDOG_DMG_BASE, + AMSC_ACCURACY_BULLDOG_DMG_STEP, AMSC_ACCURACY_PDW_DMG_BASE, AMSC_ACCURACY_PDW_DMG_STEP, AMSC_MUZZLE_FLASH_BASE, @@ -174,175 +174,124 @@ enum AMSC_LASER_MINES_BASE, AMSC_LASER_MINES_MODERATE, AMSC_LASER_MINES_EXPERT, + AMSC_VINDICATOR_MUZZLE_FLASH_BASE, + AMSC_VINDICATOR_MUZZLE_FLASH_STEP, + AMSC_MINES_FIRES_MODERATE, + AMSC_MINES_FIRES_EXPERT, // ^^ Always add new entries here! ^^ }; -// base convars -GameRulesConVar( s_ASWMarineSkillsConVars, AMSC_LEADERSHIP_ACCURACY_CHANCE_BASE, asw_skill_leadership_accuracy_chance_base, 0, "" ); -GameRulesConVar( s_ASWMarineSkillsConVars, AMSC_LEADERSHIP_DAMAGE_RESIST_BASE, asw_skill_leadership_damage_resist_base, 0, "" ); -GameRulesConVar( s_ASWMarineSkillsConVars, AMSC_VINDICATOR_DMG_BASE, asw_skill_vindicator_dmg_base, 0, "" ); -GameRulesConVar( s_ASWMarineSkillsConVars, AMSC_VINDICATOR_PELLETS_BASE, asw_skill_vindicator_pellets_base, 7, "" ); - -GameRulesConVar( s_ASWMarineSkillsConVars, AMSC_AUTOGUN_BASE, asw_skill_autogun_base, 0, "" ); -GameRulesConVar( s_ASWMarineSkillsConVars, AMSC_AUTOGUN_MINIGUN_DMG_BASE, asw_skill_autogun_minigun_dmg_base, 0, "" ); -GameRulesConVar( s_ASWMarineSkillsConVars, AMSC_AUTOGUN_CRYO_SPINUP_BASE, asw_skill_autogun_cryo_spinup_base, 0.25, "" ); -GameRulesConVar( s_ASWMarineSkillsConVars, AMSC_AUTOGUN_CRYO_FREEZE_BASE, asw_skill_autogun_cryo_freeze_base, 0.15, "" ); -GameRulesConVar( s_ASWMarineSkillsConVars, AMSC_AUTOGUN_CRYO_RADIUS_BASE, asw_skill_autogun_cryo_radius_base, 64, "" ); -GameRulesConVar( s_ASWMarineSkillsConVars, AMSC_PIERCING_BASE, asw_skill_piercing_base, 0, "" ); -GameRulesConVar( s_ASWMarineSkillsConVars, AMSC_STOPPING_POWER_AIRBLAST_STRENGTH_BASE, asw_skill_stopping_power_airblast_strength_base, 0, "" ); - -GameRulesConVar( s_ASWMarineSkillsConVars, AMSC_HEALING_CHARGES_BASE, asw_skill_healing_charges_base, 4, "" ); -GameRulesConVar( s_ASWMarineSkillsConVars, AMSC_SELF_HEALING_CHARGES_BASE, asw_skill_self_healing_charges_base, 2, "" ); -GameRulesConVar( s_ASWMarineSkillsConVars, AMSC_HEALING_MEDRIFLE_HEALING_CHARGES_BASE, asw_skill_healing_medrifle_healing_charges_base, 50, "" ); -GameRulesConVar( s_ASWMarineSkillsConVars, AMSC_HEALING_MEDKIT_HPS_BASE, asw_skill_healing_medkit_hps_base, 50, "" ); -GameRulesConVar( s_ASWMarineSkillsConVars, AMSC_HEALING_HPS_BASE, asw_skill_healing_hps_base, 25, "" ); -GameRulesConVar( s_ASWMarineSkillsConVars, AMSC_HEALING_GRENADE_BASE, asw_skill_healing_grenade_base, 120, "" ); -GameRulesConVar( s_ASWMarineSkillsConVars, AMSC_HEALING_GUN_CHARGES_BASE, asw_skill_healing_gun_charges_base, 40, "" ); -GameRulesConVar( s_ASWMarineSkillsConVars, AMSC_HEALING_GUN_BASE, asw_skill_healing_gun_base, 5, "" ); -GameRulesConVar( s_ASWMarineSkillsConVars, AMSC_HEALING_AMP_GUN_CHARGES_BASE, asw_skill_healing_amp_gun_charges_base, 20, "" ); -GameRulesConVar( s_ASWMarineSkillsConVars, AMSC_XENOWOUNDS_BASE, asw_skill_xenowounds_base, 100, "" ); -GameRulesConVar( s_ASWMarineSkillsConVars, AMSC_DRUGS_BASE, asw_skill_drugs_base, 5, "" ); -GameRulesConVar( s_ASWMarineSkillsConVars, AMSC_DRUGS_HEALAMP_BASE, asw_skill_drugs_healamp_base, 90, "" ); - -GameRulesConVar( s_ASWMarineSkillsConVars, AMSC_HACKING_SPEED_BASE, asw_skill_hacking_speed_base, 2.0, "" ); -GameRulesConVar( s_ASWMarineSkillsConVars, AMSC_SCANNER_BASE, asw_skill_scanner_base, 600, "" ); -GameRulesConVar( s_ASWMarineSkillsConVars, AMSC_ENGINEERING_WELDING_BASE, asw_skill_engineering_welding_base, 0.8, "" ); -GameRulesConVar( s_ASWMarineSkillsConVars, AMSC_ENGINEERING_SENTRY_BASE, asw_skill_engineering_sentry_base, 1.0, "" ); -GameRulesConVar( s_ASWMarineSkillsConVars, AMSC_ENGINEERING_FIRERATE_BASE, asw_skill_engineering_firerate_base, 0.0, "" ); -GameRulesConVar( s_ASWMarineSkillsConVars, AMSC_ENGINEERING_SHIELD_HEALTH_BASE, asw_skill_engineering_shield_health_base, 300, "" ); -GameRulesConVar( s_ASWMarineSkillsConVars, AMSC_ENGINEERING_SHIELD_DURATION_BASE, asw_skill_engineering_shield_duration_base, 6, "" ); - -GameRulesConVar( s_ASWMarineSkillsConVars, AMSC_GRENADES_RADIUS_BASE, asw_skill_grenades_radius_base, 280, "" ); -GameRulesConVar( s_ASWMarineSkillsConVars, AMSC_GRENADES_DMG_BASE, asw_skill_grenades_dmg_base, 128, "" ); -GameRulesConVar( s_ASWMarineSkillsConVars, AMSC_GRENADES_INCENDIARY_DMG_BASE, asw_skill_grenades_incendiary_dmg_base, 20, "" ); -GameRulesConVar( s_ASWMarineSkillsConVars, AMSC_GRENADES_CLUSTER_DMG_BASE, asw_skill_grenades_cluster_dmg_base, 0, "" ); -GameRulesConVar( s_ASWMarineSkillsConVars, AMSC_GRENADES_CLUSTERS_BASE, asw_skill_grenades_clusters_base, 0, "" ); -GameRulesConVar( s_ASWMarineSkillsConVars, AMSC_GRENADES_FLECHETTE_DMG_BASE, asw_skill_grenades_flechette_dmg_base, 10, "" ); -GameRulesConVar( s_ASWMarineSkillsConVars, AMSC_GRENADES_HORNET_DMG_BASE, asw_skill_grenades_hornet_dmg_base, 50, "" ); -GameRulesConVar( s_ASWMarineSkillsConVars, AMSC_GRENADES_HORNET_COUNT_BASE, asw_skill_grenades_hornet_count_base, 8, "" ); -GameRulesConVar( s_ASWMarineSkillsConVars, AMSC_GRENADES_HORNET_INTERVAL_BASE, asw_skill_grenades_hornet_interval_base, 0.09, "" ); -GameRulesConVar( s_ASWMarineSkillsConVars, AMSC_GRENADES_FREEZE_RADIUS_BASE, asw_skill_grenades_freeze_radius_base, 210, "" ); -GameRulesConVar( s_ASWMarineSkillsConVars, AMSC_GRENADES_FREEZE_DURATION_BASE, asw_skill_grenades_freeze_duration_base, 3.0, "" ); -GameRulesConVar( s_ASWMarineSkillsConVars, AMSC_GRENADES_SMART_COUNT_BASE, asw_skill_grenades_smart_count_base, 32, "" ); -GameRulesConVar( s_ASWMarineSkillsConVars, AMSC_GRENADES_SMART_INTERVAL_BASE, asw_skill_grenades_smart_interval_base, 0.09, "" ); - -GameRulesConVar( s_ASWMarineSkillsConVars, AMSC_HEALTH_BASE, asw_skill_health_base, 80, "" ); -GameRulesConVar( s_ASWMarineSkillsConVars, AMSC_MELEE_DMG_BASE, asw_skill_melee_dmg_base, 30, "" ); -GameRulesConVar( s_ASWMarineSkillsConVars, AMSC_MELEE_FORCE_BASE, asw_skill_melee_force_base, 10, "" ); -GameRulesConVar( s_ASWMarineSkillsConVars, AMSC_MELEE_SPEED_BASE, asw_skill_melee_speed_base, 1.0, "" ); -GameRulesConVar( s_ASWMarineSkillsConVars, AMSC_RELOADING_BASE, asw_skill_reloading_base, 1.4, "" ); -GameRulesConVar( s_ASWMarineSkillsConVars, AMSC_RELOADING_FAST_BASE, asw_skill_reloading_fast_base, 1.0, "" ); -GameRulesConVar( s_ASWMarineSkillsConVars, AMSC_AGILITY_MOVESPEED_BASE, asw_skill_agility_movespeed_base, 290, "" ); - -// step convars -GameRulesConVar( s_ASWMarineSkillsConVars, AMSC_LEADERSHIP_ACCURACY_CHANCE_STEP, asw_skill_leadership_accuracy_chance_step, 0.03, "" ); -GameRulesConVar( s_ASWMarineSkillsConVars, AMSC_LEADERSHIP_DAMAGE_RESIST_STEP, asw_skill_leadership_damage_resist_step, 0.06, "" ); -GameRulesConVar( s_ASWMarineSkillsConVars, AMSC_VINDICATOR_DMG_STEP, asw_skill_vindicator_dmg_step, 2.0, "" ); -GameRulesConVar( s_ASWMarineSkillsConVars, AMSC_VINDICATOR_PELLETS_STEP, asw_skill_vindicator_pellets_step, 0, "" ); - -GameRulesConVar( s_ASWMarineSkillsConVars, AMSC_AUTOGUN_STEP, asw_skill_autogun_step, 1, "" ); -GameRulesConVar( s_ASWMarineSkillsConVars, AMSC_AUTOGUN_MINIGUN_DMG_STEP, asw_skill_autogun_minigun_dmg_step, 1, "" ); -GameRulesConVar( s_ASWMarineSkillsConVars, AMSC_AUTOGUN_CRYO_SPINUP_STEP, asw_skill_autogun_cryo_spinup_step, 0.25, "" ); -GameRulesConVar( s_ASWMarineSkillsConVars, AMSC_AUTOGUN_CRYO_FREEZE_STEP, asw_skill_autogun_cryo_freeze_step, 0, "" ); -GameRulesConVar( s_ASWMarineSkillsConVars, AMSC_AUTOGUN_CRYO_RADIUS_STEP, asw_skill_autogun_cryo_radius_step, 0, "" ); -GameRulesConVar( s_ASWMarineSkillsConVars, AMSC_PIERCING_STEP, asw_skill_piercing_step, 0.20, "" ); -GameRulesConVar( s_ASWMarineSkillsConVars, AMSC_STOPPING_POWER_AIRBLAST_STRENGTH_STEP, asw_skill_stopping_power_airblast_strength_step, 0, "" ); - -GameRulesConVar( s_ASWMarineSkillsConVars, AMSC_HEALING_CHARGES_STEP, asw_skill_healing_charges_step, 1, "" ); -GameRulesConVar( s_ASWMarineSkillsConVars, AMSC_SELF_HEALING_CHARGES_STEP, asw_skill_self_healing_charges_step, 0.5, "" ); -GameRulesConVar( s_ASWMarineSkillsConVars, AMSC_HEALING_MEDRIFLE_HEALING_CHARGES_STEP, asw_skill_healing_medrifle_healing_charges_step, 0, "" ); -GameRulesConVar( s_ASWMarineSkillsConVars, AMSC_HEALING_HPS_STEP, asw_skill_healing_hps_step, 8, "" ); -GameRulesConVar( s_ASWMarineSkillsConVars, AMSC_HEALING_GRENADE_STEP, asw_skill_healing_grenade_step, 30, "" ); -GameRulesConVar( s_ASWMarineSkillsConVars, AMSC_HEALING_GUN_CHARGES_STEP, asw_skill_healing_gun_charges_step, 10, "" ); -GameRulesConVar( s_ASWMarineSkillsConVars, AMSC_HEALING_GUN_STEP, asw_skill_healing_gun_step, 1, "" ); -GameRulesConVar( s_ASWMarineSkillsConVars, AMSC_HEALING_AMP_GUN_CHARGES_STEP, asw_skill_healing_amp_gun_charges_step, 5, "" ); -GameRulesConVar( s_ASWMarineSkillsConVars, AMSC_HEALING_MEDKIT_HPS_STEP, asw_skill_healing_medkit_hps_step, 5, "" ); -GameRulesConVar( s_ASWMarineSkillsConVars, AMSC_XENOWOUNDS_STEP, asw_skill_xenowounds_step, -25, "" ); -GameRulesConVar( s_ASWMarineSkillsConVars, AMSC_DRUGS_STEP, asw_skill_drugs_step, 0.8, "" ); -GameRulesConVar( s_ASWMarineSkillsConVars, AMSC_DRUGS_HEALAMP_STEP, asw_skill_drugs_healamp_step, 20, "" ); - -GameRulesConVar( s_ASWMarineSkillsConVars, AMSC_HACKING_SPEED_STEP, asw_skill_hacking_speed_step, 0.1, "" ); -GameRulesConVar( s_ASWMarineSkillsConVars, AMSC_SCANNER_STEP, asw_skill_scanner_step, 150, "" ); -GameRulesConVar( s_ASWMarineSkillsConVars, AMSC_ENGINEERING_WELDING_STEP, asw_skill_engineering_welding_step, 0.5, "" ); -GameRulesConVar( s_ASWMarineSkillsConVars, AMSC_ENGINEERING_SENTRY_STEP, asw_skill_engineering_sentry_step, 0.25, "" ); -GameRulesConVar( s_ASWMarineSkillsConVars, AMSC_ENGINEERING_FIRERATE_STEP, asw_skill_engineering_firerate_step, 0.005, "" ); -GameRulesConVar( s_ASWMarineSkillsConVars, AMSC_ENGINEERING_SHIELD_HEALTH_STEP, asw_skill_engineering_shield_health_step, 50, "" ); -GameRulesConVar( s_ASWMarineSkillsConVars, AMSC_ENGINEERING_SHIELD_DURATION_STEP, asw_skill_engineering_shield_duration_step, 1, "" ); - -GameRulesConVar( s_ASWMarineSkillsConVars, AMSC_GRENADES_RADIUS_STEP, asw_skill_grenades_radius_step, 20, "" ); -GameRulesConVar( s_ASWMarineSkillsConVars, AMSC_GRENADES_DMG_STEP, asw_skill_grenades_dmg_step, 20, "" ); -GameRulesConVar( s_ASWMarineSkillsConVars, AMSC_GRENADES_INCENDIARY_DMG_STEP, asw_skill_grenades_incendiary_dmg_step, 0, "" ); -GameRulesConVar( s_ASWMarineSkillsConVars, AMSC_GRENADES_CLUSTER_DMG_STEP, asw_skill_grenades_cluster_dmg_step, 10, "" ); -GameRulesConVar( s_ASWMarineSkillsConVars, AMSC_GRENADES_CLUSTERS_STEP, asw_skill_grenades_clusters_step, 1, "" ); -GameRulesConVar( s_ASWMarineSkillsConVars, AMSC_GRENADES_FLECHETTE_DMG_STEP, asw_skill_grenades_flechette_dmg_step, 1, "" ); -GameRulesConVar( s_ASWMarineSkillsConVars, AMSC_GRENADES_HORNET_DMG_STEP, asw_skill_grenades_hornet_dmg_step, 1, "" ); -GameRulesConVar( s_ASWMarineSkillsConVars, AMSC_GRENADES_HORNET_COUNT_STEP, asw_skill_grenades_hornet_count_step, 0, "" ); -GameRulesConVar( s_ASWMarineSkillsConVars, AMSC_GRENADES_HORNET_INTERVAL_STEP, asw_skill_grenades_hornet_interval_step, 0, "" ); -GameRulesConVar( s_ASWMarineSkillsConVars, AMSC_GRENADES_FREEZE_RADIUS_STEP, asw_skill_grenades_freeze_radius_step, 0, "" ); -GameRulesConVar( s_ASWMarineSkillsConVars, AMSC_GRENADES_FREEZE_DURATION_STEP, asw_skill_grenades_freeze_duration_step, 0.3, "" ); -GameRulesConVar( s_ASWMarineSkillsConVars, AMSC_GRENADES_SMART_COUNT_STEP, asw_skill_grenades_smart_count_step, 0, "" ); -GameRulesConVar( s_ASWMarineSkillsConVars, AMSC_GRENADES_SMART_INTERVAL_STEP, asw_skill_grenades_smart_interval_step, 0, "" ); - -GameRulesConVar( s_ASWMarineSkillsConVars, AMSC_HEALTH_STEP, asw_skill_health_step, 15, "" ); -GameRulesConVar( s_ASWMarineSkillsConVars, AMSC_MELEE_DMG_STEP, asw_skill_melee_dmg_step, 6, "" ); -GameRulesConVar( s_ASWMarineSkillsConVars, AMSC_MELEE_FORCE_STEP, asw_skill_melee_force_step, 1.0, "" ); -GameRulesConVar( s_ASWMarineSkillsConVars, AMSC_MELEE_SPEED_STEP, asw_skill_melee_speed_step, 0.1, "" ); -GameRulesConVar( s_ASWMarineSkillsConVars, AMSC_RELOADING_STEP, asw_skill_reloading_step, -0.14, "" ); -GameRulesConVar( s_ASWMarineSkillsConVars, AMSC_RELOADING_FAST_STEP, asw_skill_reloading_fast_step, 0.05, "" ); -GameRulesConVar( s_ASWMarineSkillsConVars, AMSC_AGILITY_MOVESPEED_STEP, asw_skill_agility_movespeed_step, 10, "" ); -GameRulesConVar( s_ASWMarineSkillsConVars, AMSC_AGILITY_RELOAD_STEP, asw_skill_agility_reload_step, 0, "" ); - -GameRulesConVar( s_ASWMarineSkillsConVars, AMSC_MINES_FIRES_BASE, asw_skill_mines_fires_base, 1, "" ); -GameRulesConVar( s_ASWMarineSkillsConVars, AMSC_MINES_FIRES_STEP, asw_skill_mines_fires_step, 0.5, "" ); -GameRulesConVar( s_ASWMarineSkillsConVars, AMSC_MINES_DURATION_BASE, asw_skill_mines_duration_base, 10.0, "" ); -GameRulesConVar( s_ASWMarineSkillsConVars, AMSC_MINES_DURATION_STEP, asw_skill_mines_duration_step, 5.0, "" ); - -// accuracy convars -GameRulesConVar( s_ASWMarineSkillsConVars, AMSC_ACCURACY_RIFLE_DMG_BASE, asw_skill_accuracy_rifle_dmg_base, 0, "" ); -GameRulesConVar( s_ASWMarineSkillsConVars, AMSC_ACCURACY_RIFLE_DMG_STEP, asw_skill_accuracy_rifle_dmg_step, 1, "" ); -GameRulesConVar( s_ASWMarineSkillsConVars, AMSC_ACCURACY_PRIFLE_DMG_BASE, asw_skill_accuracy_prifle_dmg_base, 0, "" ); -GameRulesConVar( s_ASWMarineSkillsConVars, AMSC_ACCURACY_PRIFLE_DMG_STEP, asw_skill_accuracy_prifle_dmg_step, 1, "" ); -GameRulesConVar( s_ASWMarineSkillsConVars, AMSC_ACCURACY_SHOTGUN_DMG_BASE, asw_skill_accuracy_shotgun_dmg_base, 0, "" ); -GameRulesConVar( s_ASWMarineSkillsConVars, AMSC_ACCURACY_SHOTGUN_DMG_STEP, asw_skill_accuracy_shotgun_dmg_step, 2, "" ); -GameRulesConVar( s_ASWMarineSkillsConVars, AMSC_ACCURACY_RAILGUN_DMG_BASE, asw_skill_accuracy_railgun_dmg_base, 0, "" ); -GameRulesConVar( s_ASWMarineSkillsConVars, AMSC_ACCURACY_RAILGUN_DMG_STEP, asw_skill_accuracy_railgun_dmg_step, 10, "" ); -GameRulesConVar( s_ASWMarineSkillsConVars, AMSC_ACCURACY_FLAMER_DMG_BASE, asw_skill_accuracy_flamer_dmg_base, 0, "" ); -GameRulesConVar( s_ASWMarineSkillsConVars, AMSC_ACCURACY_FLAMER_DMG_STEP, asw_skill_accuracy_flamer_dmg_step, 0.5, "" ); -GameRulesConVar( s_ASWMarineSkillsConVars, AMSC_ACCURACY_PISTOL_DMG_BASE, asw_skill_accuracy_pistol_dmg_base, 0, "" ); -GameRulesConVar( s_ASWMarineSkillsConVars, AMSC_ACCURACY_PISTOL_DMG_STEP, asw_skill_accuracy_pistol_dmg_step, 4, "" ); -GameRulesConVar( s_ASWMarineSkillsConVars, AMSC_ACCURACY_DEAGLE_DMG_BASE, asw_skill_accuracy_deagle_dmg_base, 0, "" ); -GameRulesConVar( s_ASWMarineSkillsConVars, AMSC_ACCURACY_DEAGLE_DMG_STEP, asw_skill_accuracy_deagle_dmg_step, 0, "" ); -GameRulesConVar( s_ASWMarineSkillsConVars, AMSC_ACCURACY_PDW_DMG_BASE, asw_skill_accuracy_pdw_dmg_base, 0, "" ); -GameRulesConVar( s_ASWMarineSkillsConVars, AMSC_ACCURACY_PDW_DMG_STEP, asw_skill_accuracy_pdw_dmg_step, 1.0, "" ); -GameRulesConVar( s_ASWMarineSkillsConVars, AMSC_MUZZLE_FLASH_BASE, asw_skill_muzzle_flash_base, 1.0, "" ); -GameRulesConVar( s_ASWMarineSkillsConVars, AMSC_MUZZLE_FLASH_STEP, asw_skill_muzzle_flash_step, 0.2, "" ); -GameRulesConVar( s_ASWMarineSkillsConVars, AMSC_ACCURACY_SNIPER_RIFLE_DMG_BASE, asw_skill_accuracy_sniper_rifle_dmg_base, 0, "" ); -GameRulesConVar( s_ASWMarineSkillsConVars, AMSC_ACCURACY_SNIPER_RIFLE_DMG_STEP, asw_skill_accuracy_sniper_rifle_dmg_step, 20, "" ); -GameRulesConVar( s_ASWMarineSkillsConVars, AMSC_ACCURACY_TESLA_CANNON_DMG_BASE, asw_skill_accuracy_tesla_cannon_dmg_base, 0, "" ); -GameRulesConVar( s_ASWMarineSkillsConVars, AMSC_ACCURACY_TESLA_CANNON_DMG_STEP, asw_skill_accuracy_tesla_cannon_dmg_step, 0.25, "" ); -GameRulesConVar( s_ASWMarineSkillsConVars, AMSC_ACCURACY_HEAVY_RIFLE_DMG_BASE, asw_skill_accuracy_heavy_rifle_dmg_base, 0, "" ); -GameRulesConVar( s_ASWMarineSkillsConVars, AMSC_ACCURACY_HEAVY_RIFLE_DMG_STEP, asw_skill_accuracy_heavy_rifle_dmg_step, 2, "" ); -GameRulesConVar( s_ASWMarineSkillsConVars, AMSC_ACCURACY_MEDRIFLE_DMG_BASE, asw_skill_accuracy_medrifle_dmg_base, 0, "" ); -GameRulesConVar( s_ASWMarineSkillsConVars, AMSC_ACCURACY_MEDRIFLE_DMG_STEP, asw_skill_accuracy_medrifle_dmg_step, 2, "" ); -GameRulesConVar( s_ASWMarineSkillsConVars, AMSC_ACCURACY_AR2_DMG_BASE, asw_skill_accuracy_ar2_dmg_base, 0, "" ); -GameRulesConVar( s_ASWMarineSkillsConVars, AMSC_ACCURACY_AR2_DMG_STEP, asw_skill_accuracy_ar2_dmg_step, 2, "" ); -GameRulesConVar( s_ASWMarineSkillsConVars, AMSC_ACCURACY_DEVASTATOR_DMG_BASE, asw_skill_accuracy_devastator_dmg_base, 0, "" ); -GameRulesConVar( s_ASWMarineSkillsConVars, AMSC_ACCURACY_DEVASTATOR_DMG_STEP, asw_skill_accuracy_devastator_dmg_step, 1, "" ); -GameRulesConVar( s_ASWMarineSkillsConVars, AMSC_ACCURACY_50CALMG_DMG_BASE, asw_skill_accuracy_50calmg_dmg_base, 0, "" ); -GameRulesConVar( s_ASWMarineSkillsConVars, AMSC_ACCURACY_50CALMG_DMG_STEP, asw_skill_accuracy_50calmg_dmg_step, 1, "" ); -GameRulesConVar( s_ASWMarineSkillsConVars, AMSC_ACCURACY_MINING_LASER_DMG_BASE, asw_skill_accuracy_mining_laser_dmg_base, 0, "" ); -GameRulesConVar( s_ASWMarineSkillsConVars, AMSC_ACCURACY_MINING_LASER_DMG_STEP, asw_skill_accuracy_mining_laser_dmg_step, 1, "" ); -GameRulesConVar( s_ASWMarineSkillsConVars, AMSC_ACCURACY_SHIELD_RIFLE_DMG_BASE, asw_skill_accuracy_shield_rifle_dmg_base, 0, "" ); -GameRulesConVar( s_ASWMarineSkillsConVars, AMSC_ACCURACY_SHIELD_RIFLE_DMG_STEP, asw_skill_accuracy_shield_rifle_dmg_step, 2, "" ); -GameRulesConVar( s_ASWMarineSkillsConVars, AMSC_ACCURACY_CRYO_DMG_BASE, asw_skill_accuracy_cryo_dmg_base, 0, "" ); -GameRulesConVar( s_ASWMarineSkillsConVars, AMSC_ACCURACY_CRYO_DMG_STEP, asw_skill_accuracy_cryo_dmg_step, 0.5, "" ); -GameRulesConVar( s_ASWMarineSkillsConVars, AMSC_ACCURACY_SHIELD_DAMAGE_BASE, asw_skill_accuracy_shield_damage_base, 30, "" ); -GameRulesConVar( s_ASWMarineSkillsConVars, AMSC_ACCURACY_SHIELD_DAMAGE_STEP, asw_skill_accuracy_shield_damage_step, 20, "" ); - -GameRulesConVarClamp( s_ASWMarineSkillsConVars, AMSC_LASER_MINES_BASE, asw_skill_laser_mines_base, 1, "Number of laser mines to deploy by marines with no Explosives skills", 1, 10 ); -GameRulesConVarClamp( s_ASWMarineSkillsConVars, AMSC_LASER_MINES_MODERATE, asw_skill_laser_mines_moderate, 2, "Number of laser mines to deploy by marines with moderate(>1) Explosives skills", 1, 10 ); -GameRulesConVarClamp( s_ASWMarineSkillsConVars, AMSC_LASER_MINES_EXPERT, asw_skill_laser_mines_expert, 3, "Number of laser mines to deploy by marines with expert(>3) Explosives skills. Currently only Jaeger have it", 1, 10 ); +// Leadership (Officer) +GameRulesConVarSkill( s_ASWMarineSkillsConVars, AMSC_LEADERSHIP_ACCURACY_CHANCE, asw_skill_leadership_accuracy_chance, 0, 0.03, "", ASW_MARINE_SKILL_LEADERSHIP, ASW_MARINE_SUBSKILL_LEADERSHIP_ACCURACY_CHANCE ); +GameRulesConVarSkill( s_ASWMarineSkillsConVars, AMSC_LEADERSHIP_DAMAGE_RESIST, asw_skill_leadership_damage_resist, 0, 0.06, "", ASW_MARINE_SKILL_LEADERSHIP, ASW_MARINE_SUBSKILL_LEADERSHIP_DAMAGE_RESIST ); + +// Vindicator Damage (Officer) +GameRulesConVarSkill( s_ASWMarineSkillsConVars, AMSC_VINDICATOR_DMG, asw_skill_vindicator_dmg, 0, 2.0, "", ASW_MARINE_SKILL_VINDICATOR, ASW_MARINE_SUBSKILL_VINDICATOR_DAMAGE ); +GameRulesConVarSkill( s_ASWMarineSkillsConVars, AMSC_VINDICATOR_PELLETS, asw_skill_vindicator_pellets, 7, 0, "", ASW_MARINE_SKILL_VINDICATOR, ASW_MARINE_SUBSKILL_VINDICATOR_PELLETS ); +GameRulesConVarSkill( s_ASWMarineSkillsConVars, AMSC_VINDICATOR_MUZZLE_FLASH, asw_skill_vindicator_muzzle_flash, 1.0, 0.2, "", ASW_MARINE_SKILL_VINDICATOR, ASW_MARINE_SUBSKILL_VINDICATOR_MUZZLE ); + +// Heavy Weapons (Special Weapons) +GameRulesConVarSkill( s_ASWMarineSkillsConVars, AMSC_AUTOGUN, asw_skill_autogun, 0, 1, "", ASW_MARINE_SKILL_AUTOGUN, ASW_MARINE_SUBSKILL_AUTOGUN_DMG ); +GameRulesConVarSkill( s_ASWMarineSkillsConVars, AMSC_AUTOGUN_MINIGUN_DMG, asw_skill_autogun_minigun_dmg, 0, 1, "", ASW_MARINE_SKILL_AUTOGUN, ASW_MARINE_SUBSKILL_AUTOGUN_MINIGUN_DMG ); +GameRulesConVarSkill( s_ASWMarineSkillsConVars, AMSC_AUTOGUN_CRYO_SPINUP, asw_skill_autogun_cryo_spinup, 0.25, 0.25, "", ASW_MARINE_SKILL_AUTOGUN, ASW_MARINE_SUBSKILL_AUTOGUN_CRYO_SPINUP ); +GameRulesConVarSkill( s_ASWMarineSkillsConVars, AMSC_AUTOGUN_CRYO_FREEZE, asw_skill_autogun_cryo_freeze, 0.15, 0, "", ASW_MARINE_SKILL_AUTOGUN, ASW_MARINE_SUBSKILL_AUTOGUN_CRYO_FREEZE ); +GameRulesConVarSkill( s_ASWMarineSkillsConVars, AMSC_AUTOGUN_CRYO_RADIUS, asw_skill_autogun_cryo_radius, 64, 0, "", ASW_MARINE_SKILL_AUTOGUN, ASW_MARINE_SUBSKILL_AUTOGUN_CRYO_RADIUS ); + +// Stopping Power (Special Weapons) +// ASW_MARINE_SUBSKILL_STOPPING_POWER is handled per weapon +GameRulesConVarSkill( s_ASWMarineSkillsConVars, AMSC_PIERCING, asw_skill_piercing, 0, 0.20, "", ASW_MARINE_SKILL_STOPPING_POWER, ASW_MARINE_SUBSKILL_PIERCING_CHANCE ); +GameRulesConVarSkill( s_ASWMarineSkillsConVars, AMSC_STOPPING_POWER_AIRBLAST_STRENGTH, asw_skill_stopping_power_airblast_strength, 0, 0, "", ASW_MARINE_SKILL_STOPPING_POWER, ASW_MARINE_SUBSKILL_AIRBLAST_STRENGTH ); + +// Healing (Medic) +GameRulesConVarSkill( s_ASWMarineSkillsConVars, AMSC_HEALING_CHARGES, asw_skill_healing_charges, 4, 1, "", ASW_MARINE_SKILL_HEALING, ASW_MARINE_SUBSKILL_HEALING_CHARGES ); +GameRulesConVarSkill( s_ASWMarineSkillsConVars, AMSC_SELF_HEALING_CHARGES, asw_skill_self_healing_charges, 2, 0.5, "", ASW_MARINE_SKILL_HEALING, ASW_MARINE_SUBSKILL_SELF_HEALING_CHARGES ); +GameRulesConVarSkill( s_ASWMarineSkillsConVars, AMSC_HEALING_HPS, asw_skill_healing_hps, 25, 8, "", ASW_MARINE_SKILL_HEALING, ASW_MARINE_SUBSKILL_HEALING_HPS ); +GameRulesConVarSkill( s_ASWMarineSkillsConVars, AMSC_HEALING_MEDKIT_HPS, asw_skill_healing_medkit_hps, 50, 5, "", ASW_MARINE_SKILL_HEALING, ASW_MARINE_SUBSKILL_HEALING_MEDKIT_HPS ); +GameRulesConVarSkill( s_ASWMarineSkillsConVars, AMSC_HEALING_GRENADE, asw_skill_healing_grenade, 120, 30, "", ASW_MARINE_SKILL_HEALING, ASW_MARINE_SUBSKILL_HEAL_GRENADE_HEAL_AMOUNT ); +GameRulesConVarSkill( s_ASWMarineSkillsConVars, AMSC_HEALING_GUN_CHARGES, asw_skill_healing_gun_charges, 40, 5, "", ASW_MARINE_SKILL_HEALING, ASW_MARINE_SUBSKILL_HEAL_GUN_CHARGES ); +GameRulesConVarSkill( s_ASWMarineSkillsConVars, AMSC_HEALING_GUN, asw_skill_healing_gun, 5, 1, "", ASW_MARINE_SKILL_HEALING, ASW_MARINE_SUBSKILL_HEAL_GUN_HEAL_AMOUNT ); +GameRulesConVarSkill( s_ASWMarineSkillsConVars, AMSC_HEALING_AMP_GUN_CHARGES, asw_skill_healing_amp_gun_charges, 20, 5, "", ASW_MARINE_SKILL_HEALING, ASW_MARINE_SUBSKILL_HEALAMP_GUN_CHARGES ); +GameRulesConVarSkill( s_ASWMarineSkillsConVars, AMSC_HEALING_MEDRIFLE_HEALING_CHARGES, asw_skill_healing_medrifle_healing_charges, 50, 0, "", ASW_MARINE_SKILL_HEALING, ASW_MARINE_SUBSKILL_MEDRIFLE_HEALING_CHARGES ); + +// Infestation Curing (Medic) +GameRulesConVarSkill( s_ASWMarineSkillsConVars, AMSC_XENOWOUNDS, asw_skill_xenowounds, 100, -25, "", ASW_MARINE_SKILL_XENOWOUNDS, ASW_MARINE_SUBSKILL_XENOWOUNDS_INFESTATION_CURING ); + +// Combat Drugs (Medic) +GameRulesConVarSkill( s_ASWMarineSkillsConVars, AMSC_DRUGS, asw_skill_drugs, 5, 0.8, "", ASW_MARINE_SKILL_DRUGS, ASW_MARINE_SUBSKILL_STIM_DURATION ); +GameRulesConVarSkill( s_ASWMarineSkillsConVars, AMSC_DRUGS_HEALAMP, asw_skill_drugs_healamp, 90, 20, "", ASW_MARINE_SKILL_DRUGS, ASW_MARINE_SUBSKILL_HEALAMP_GUN_AMP_CHARGES ); + +// Hacking (Tech) +GameRulesConVarSkill( s_ASWMarineSkillsConVars, AMSC_HACKING_SPEED, asw_skill_hacking_speed, 2.0, 0.1, "", ASW_MARINE_SKILL_HACKING, ASW_MARINE_SUBSKILL_HACKING_SPEED_SCALE ); +// TODO: ASW_MARINE_SUBSKILL_HACKING_TUMBLER_COUNT_REDUCTION +// TODO: ASW_MARINE_SUBSKILL_HACKING_ENTRIES_PER_TUMBLER_REDUCTION + +// Scanner (Tech) +GameRulesConVarSkill( s_ASWMarineSkillsConVars, AMSC_SCANNER, asw_skill_scanner, 600, 150, "", ASW_MARINE_SKILL_SCANNER, ASW_MARINE_SUBSKILL_SCANNER_RANGE ); + +// Engineering (Tech) +GameRulesConVarSkill( s_ASWMarineSkillsConVars, AMSC_ENGINEERING_WELDING, asw_skill_engineering_welding, 0.8, 0.5, "", ASW_MARINE_SKILL_ENGINEERING, ASW_MARINE_SUBSKILL_ENGINEERING_WELDING ); +GameRulesConVarSkill( s_ASWMarineSkillsConVars, AMSC_ENGINEERING_SENTRY, asw_skill_engineering_sentry, 1.0, 0.25, "", ASW_MARINE_SKILL_ENGINEERING, ASW_MARINE_SUBSKILL_ENGINEERING_SENTRY ); +GameRulesConVarSkill( s_ASWMarineSkillsConVars, AMSC_ENGINEERING_FIRERATE, asw_skill_engineering_firerate, 0.0, 0.005, "", ASW_MARINE_SKILL_ENGINEERING, ASW_MARINE_SUBSKILL_ENGINEERING_FIRERATE ); +GameRulesConVarSkill( s_ASWMarineSkillsConVars, AMSC_ENGINEERING_SHIELD_HEALTH, asw_skill_engineering_shield_health, 300, 50, "", ASW_MARINE_SKILL_ENGINEERING, ASW_MARINE_SUBSKILL_ENGINEERING_SHIELD_HEALTH ); +GameRulesConVarSkill( s_ASWMarineSkillsConVars, AMSC_ENGINEERING_SHIELD_DURATION, asw_skill_engineering_shield_duration, 6, 1, "", ASW_MARINE_SKILL_ENGINEERING, ASW_MARINE_SUBSKILL_ENGINEERING_SHIELD_DURATION ); + +// Damage Bonus +GameRulesConVarSkill( s_ASWMarineSkillsConVars, AMSC_ACCURACY_RIFLE_DMG, asw_skill_accuracy_rifle_dmg, 0, 1, "", ASW_MARINE_SKILL_ACCURACY, ASW_MARINE_SUBSKILL_ACCURACY_RIFLE_DMG ); +GameRulesConVarSkill( s_ASWMarineSkillsConVars, AMSC_ACCURACY_PRIFLE_DMG, asw_skill_accuracy_prifle_dmg, 0, 1, "", ASW_MARINE_SKILL_ACCURACY, ASW_MARINE_SUBSKILL_ACCURACY_PRIFLE_DMG ); +GameRulesConVarSkill( s_ASWMarineSkillsConVars, AMSC_ACCURACY_SHOTGUN_DMG, asw_skill_accuracy_shotgun_dmg, 0, 2, "", ASW_MARINE_SKILL_ACCURACY, ASW_MARINE_SUBSKILL_ACCURACY_SHOTGUN_DMG ); +GameRulesConVarSkill( s_ASWMarineSkillsConVars, AMSC_ACCURACY_RAILGUN_DMG, asw_skill_accuracy_railgun_dmg, 0, 10, "", ASW_MARINE_SKILL_ACCURACY, ASW_MARINE_SUBSKILL_ACCURACY_RAILGUN_DMG ); +GameRulesConVarSkill( s_ASWMarineSkillsConVars, AMSC_ACCURACY_FLAMER_DMG, asw_skill_accuracy_flamer_dmg, 0, 0.5, "", ASW_MARINE_SKILL_ACCURACY, ASW_MARINE_SUBSKILL_ACCURACY_FLAMER_DMG ); +GameRulesConVarSkill( s_ASWMarineSkillsConVars, AMSC_ACCURACY_PISTOL_DMG, asw_skill_accuracy_pistol_dmg, 0, 4, "", ASW_MARINE_SKILL_ACCURACY, ASW_MARINE_SUBSKILL_ACCURACY_PISTOL_DMG ); +GameRulesConVarSkill( s_ASWMarineSkillsConVars, AMSC_ACCURACY_PDW_DMG, asw_skill_accuracy_pdw_dmg, 0, 1.0, "", ASW_MARINE_SKILL_ACCURACY, ASW_MARINE_SUBSKILL_ACCURACY_PDW_DMG ); +GameRulesConVarSkill( s_ASWMarineSkillsConVars, AMSC_ACCURACY_SNIPER_RIFLE_DMG, asw_skill_accuracy_sniper_rifle_dmg, 0, 20, "", ASW_MARINE_SKILL_ACCURACY, ASW_MARINE_SUBSKILL_ACCURACY_SNIPER_RIFLE_DMG ); +GameRulesConVarSkill( s_ASWMarineSkillsConVars, AMSC_ACCURACY_TESLA_CANNON_DMG, asw_skill_accuracy_tesla_cannon_dmg, 0, 0.25, "", ASW_MARINE_SKILL_ACCURACY, ASW_MARINE_SUBSKILL_ACCURACY_TESLA_CANNON_DMG ); +GameRulesConVarSkill( s_ASWMarineSkillsConVars, AMSC_ACCURACY_HEAVY_RIFLE_DMG, asw_skill_accuracy_heavy_rifle_dmg, 0, 2, "", ASW_MARINE_SKILL_ACCURACY, ASW_MARINE_SUBSKILL_ACCURACY_HEAVY_RIFLE_DMG ); +GameRulesConVarSkill( s_ASWMarineSkillsConVars, AMSC_ACCURACY_MEDRIFLE_DMG, asw_skill_accuracy_medrifle_dmg, 0, 2, "", ASW_MARINE_SKILL_ACCURACY, ASW_MARINE_SUBSKILL_ACCURACY_MEDRIFLE_DMG ); +GameRulesConVarSkill( s_ASWMarineSkillsConVars, AMSC_MUZZLE_FLASH, asw_skill_muzzle_flash, 1.0, 0.2, "", ASW_MARINE_SKILL_ACCURACY, ASW_MARINE_SUBSKILL_ACCURACY_MUZZLE ); +GameRulesConVarSkill( s_ASWMarineSkillsConVars, AMSC_ACCURACY_BULLDOG_DMG, asw_skill_accuracy_deagle_dmg, 0, 0, "", ASW_MARINE_SKILL_ACCURACY, ASW_MARINE_SUBSKILL_ACCURACY_DEAGLE_DMG ); +GameRulesConVarSkill( s_ASWMarineSkillsConVars, AMSC_ACCURACY_AR2_DMG, asw_skill_accuracy_ar2_dmg, 0, 2, "", ASW_MARINE_SKILL_ACCURACY, ASW_MARINE_SUBSKILL_ACCURACY_AR2_DMG ); +GameRulesConVarSkill( s_ASWMarineSkillsConVars, AMSC_ACCURACY_DEVASTATOR_DMG, asw_skill_accuracy_devastator_dmg, 0, 1, "", ASW_MARINE_SKILL_ACCURACY, ASW_MARINE_SUBSKILL_ACCURACY_DEVASTATOR_DMG ); +GameRulesConVarSkill( s_ASWMarineSkillsConVars, AMSC_ACCURACY_50CALMG_DMG, asw_skill_accuracy_50calmg_dmg, 0, 1, "", ASW_MARINE_SKILL_ACCURACY, ASW_MARINE_SUBSKILL_ACCURACY_50CALMG_DMG ); +GameRulesConVarSkill( s_ASWMarineSkillsConVars, AMSC_ACCURACY_MINING_LASER_DMG, asw_skill_accuracy_mining_laser_dmg, 0, 1, "", ASW_MARINE_SKILL_ACCURACY, ASW_MARINE_SUBSKILL_ACCURACY_MINING_LASER_DMG ); +GameRulesConVarSkill( s_ASWMarineSkillsConVars, AMSC_ACCURACY_SHIELD_RIFLE_DMG, asw_skill_accuracy_shield_rifle_dmg, 0, 2, "", ASW_MARINE_SKILL_ACCURACY, ASW_MARINE_SUBSKILL_ACCURACY_SHIELD_RIFLE_DMG ); +GameRulesConVarSkill( s_ASWMarineSkillsConVars, AMSC_ACCURACY_CRYO_DMG, asw_skill_accuracy_cryo_dmg, 0, 0.5, "", ASW_MARINE_SKILL_ACCURACY, ASW_MARINE_SUBSKILL_ACCURACY_CRYO_DMG ); +GameRulesConVarSkill( s_ASWMarineSkillsConVars, AMSC_ACCURACY_SHIELD_DAMAGE, asw_skill_accuracy_shield_damage, 30, 20, "", ASW_MARINE_SKILL_ACCURACY, ASW_MARINE_SUBSKILL_ACCURACY_SHIELD_DAMAGE ); + +// Explosives Bonus +GameRulesConVarSkill( s_ASWMarineSkillsConVars, AMSC_GRENADES_RADIUS, asw_skill_grenades_radius, 280, 20, "", ASW_MARINE_SKILL_GRENADES, ASW_MARINE_SUBSKILL_GRENADE_RADIUS ); +GameRulesConVarSkill( s_ASWMarineSkillsConVars, AMSC_GRENADES_DMG, asw_skill_grenades_dmg, 128, 20, "", ASW_MARINE_SKILL_GRENADES, ASW_MARINE_SUBSKILL_GRENADE_DMG ); +GameRulesConVarSkill( s_ASWMarineSkillsConVars, AMSC_GRENADES_INCENDIARY_DMG, asw_skill_grenades_incendiary_dmg, 20, 0, "", ASW_MARINE_SKILL_GRENADES, ASW_MARINE_SUBSKILL_GRENADE_INCENDIARY_DMG ); +GameRulesConVarSkill( s_ASWMarineSkillsConVars, AMSC_GRENADES_CLUSTER_DMG, asw_skill_grenades_cluster_dmg, 0, 10, "", ASW_MARINE_SKILL_GRENADES, ASW_MARINE_SUBSKILL_GRENADE_CLUSTER_DMG ); +GameRulesConVarSkill( s_ASWMarineSkillsConVars, AMSC_GRENADES_CLUSTERS, asw_skill_grenades_clusters, 0, 1, "", ASW_MARINE_SKILL_GRENADES, ASW_MARINE_SUBSKILL_GRENADE_CLUSTERS ); +GameRulesConVarSkill( s_ASWMarineSkillsConVars, AMSC_GRENADES_FLECHETTE_DMG, asw_skill_grenades_flechette_dmg, 10, 1, "", ASW_MARINE_SKILL_GRENADES, ASW_MARINE_SUBSKILL_GRENADE_FLECHETTE_DMG ); +GameRulesConVarSkill( s_ASWMarineSkillsConVars, AMSC_GRENADES_HORNET_DMG, asw_skill_grenades_hornet_dmg, 50, 1, "", ASW_MARINE_SKILL_GRENADES, ASW_MARINE_SUBSKILL_GRENADE_HORNET_DMG ); +GameRulesConVarSkill( s_ASWMarineSkillsConVars, AMSC_GRENADES_HORNET_COUNT, asw_skill_grenades_hornet_count, 8, 0, "", ASW_MARINE_SKILL_GRENADES, ASW_MARINE_SUBSKILL_GRENADE_HORNET_COUNT ); +GameRulesConVarSkill( s_ASWMarineSkillsConVars, AMSC_GRENADES_HORNET_INTERVAL, asw_skill_grenades_hornet_interval, 0.09, 0, "", ASW_MARINE_SKILL_GRENADES, ASW_MARINE_SUBSKILL_GRENADE_HORNET_INTERVAL ); +GameRulesConVarSkill( s_ASWMarineSkillsConVars, AMSC_GRENADES_FREEZE_RADIUS, asw_skill_grenades_freeze_radius, 210, 0, "", ASW_MARINE_SKILL_GRENADES, ASW_MARINE_SUBSKILL_GRENADE_FREEZE_RADIUS ); +GameRulesConVarSkill( s_ASWMarineSkillsConVars, AMSC_GRENADES_FREEZE_DURATION, asw_skill_grenades_freeze_duration, 3.0, 0.3, "", ASW_MARINE_SKILL_GRENADES, ASW_MARINE_SUBSKILL_GRENADE_FREEZE_DURATION ); +GameRulesConVarSkill( s_ASWMarineSkillsConVars, AMSC_GRENADES_SMART_COUNT, asw_skill_grenades_smart_count, 32, 0, "", ASW_MARINE_SKILL_GRENADES, ASW_MARINE_SUBSKILL_GRENADE_SMART_BOMB_COUNT ); +GameRulesConVarSkill( s_ASWMarineSkillsConVars, AMSC_GRENADES_SMART_INTERVAL, asw_skill_grenades_smart_interval, 0.09, 0, "", ASW_MARINE_SKILL_GRENADES, ASW_MARINE_SUBSKILL_GRENADE_SMART_BOMB_INTERVAL ); +GameRulesConVarSkill5_2( s_ASWMarineSkillsConVars, AMSC_LASER_MINES, asw_skill_laser_mines, 1, 2, 3, "number of laser mines to deploy per Explosives Bonus skill", ASW_MARINE_SKILL_GRENADES, ASW_MARINE_SUBSKILL_GRENADE_LASER_MINES ); +GameRulesConVarSkill5_2( s_ASWMarineSkillsConVars, AMSC_MINES_FIRES, asw_skill_mines_fires, 1, 2, 3, "number of additional incendiary mine fires on each side per Explosives Bonus skill", ASW_MARINE_SKILL_GRENADES, ASW_MARINE_SUBSKILL_GRENADE_MINES_FIRES ); +GameRulesConVarSkill( s_ASWMarineSkillsConVars, AMSC_MINES_DURATION, asw_skill_mines_duration, 10.0, 5.0, "", ASW_MARINE_SKILL_GRENADES, ASW_MARINE_SUBSKILL_GRENADE_MINES_DURATION ); + +// Health Bonus +GameRulesConVarSkill( s_ASWMarineSkillsConVars, AMSC_HEALTH, asw_skill_health, 80, 15, "", ASW_MARINE_SKILL_HEALTH, ASW_MARINE_SUBSKILL_HEALTH ); + +// Melee Damage Bonus +GameRulesConVarSkill( s_ASWMarineSkillsConVars, AMSC_MELEE_DMG, asw_skill_melee_dmg, 30, 6, "", ASW_MARINE_SKILL_MELEE, ASW_MARINE_SUBSKILL_MELEE_DMG ); +GameRulesConVarSkill( s_ASWMarineSkillsConVars, AMSC_MELEE_FORCE, asw_skill_melee_force, 10, 1.0, "", ASW_MARINE_SKILL_MELEE, ASW_MARINE_SUBSKILL_MELEE_FORCE ); +// TODO: ASW_MARINE_SUBSKILL_MELEE_FLINCH +GameRulesConVarSkill( s_ASWMarineSkillsConVars, AMSC_MELEE_SPEED, asw_skill_melee_speed, 1.0, 0.1, "", ASW_MARINE_SKILL_MELEE, ASW_MARINE_SUBSKILL_MELEE_SPEED ); + +// Reload Speed Bonus +GameRulesConVarSkill( s_ASWMarineSkillsConVars, AMSC_RELOADING, asw_skill_reloading, 1.4, -0.14, "", ASW_MARINE_SKILL_RELOADING, ASW_MARINE_SUBSKILL_RELOADING_SPEED_SCALE ); +// TODO: ASW_MARINE_SUBSKILL_RELOADING_SOUND +GameRulesConVarSkill( s_ASWMarineSkillsConVars, AMSC_RELOADING_FAST, asw_skill_reloading_fast, 1.0, 0.05, "", ASW_MARINE_SKILL_RELOADING, ASW_MARINE_SUBSKILL_RELOADING_FAST_WIDTH_SCALE ); + +// Speed Bonus +GameRulesConVarSkill( s_ASWMarineSkillsConVars, AMSC_AGILITY_MOVESPEED, asw_skill_agility_movespeed, 290, 10, "", ASW_MARINE_SKILL_AGILITY, ASW_MARINE_SUBSKILL_AGILITY_MOVE_SPEED ); CASW_Marine_Skills::CASW_Marine_Skills() { @@ -408,7 +357,7 @@ float CASW_Marine_Skills::GetSkillBasedValue( CASW_Marine_Profile *pProfile, ASW case ASW_MARINE_SUBSKILL_VINDICATOR_PELLETS: return asw_skill_vindicator_pellets_base.GetFloat() + asw_skill_vindicator_pellets_step.GetFloat() * iSkillPoints; case ASW_MARINE_SUBSKILL_VINDICATOR_MUZZLE: - return asw_skill_muzzle_flash_base.GetFloat() + asw_skill_muzzle_flash_step.GetFloat() * iSkillPoints; + return asw_skill_vindicator_muzzle_flash_base.GetFloat() + asw_skill_vindicator_muzzle_flash_step.GetFloat() * iSkillPoints; default: Assert( 0 ); return 0.0f; @@ -609,7 +558,11 @@ float CASW_Marine_Skills::GetSkillBasedValue( CASW_Marine_Profile *pProfile, ASW return asw_skill_laser_mines_moderate.GetFloat(); return asw_skill_laser_mines_base.GetFloat(); case ASW_MARINE_SUBSKILL_GRENADE_MINES_FIRES: - return asw_skill_mines_fires_base.GetFloat() + asw_skill_mines_fires_step.GetFloat() * iSkillPoints; + if ( iSkillPoints >= 4 ) + return asw_skill_mines_fires_expert.GetFloat(); + if ( iSkillPoints >= 2 ) + return asw_skill_mines_fires_moderate.GetFloat(); + return asw_skill_mines_fires_base.GetFloat(); case ASW_MARINE_SUBSKILL_GRENADE_MINES_DURATION: return asw_skill_mines_duration_base.GetFloat() + asw_skill_mines_duration_step.GetFloat() * iSkillPoints; default: diff --git a/src/game/shared/swarm/rd_gamerules_convar.h b/src/game/shared/swarm/rd_gamerules_convar.h index 3370fda3b..0341bc6f5 100644 --- a/src/game/shared/swarm/rd_gamerules_convar.h +++ b/src/game/shared/swarm/rd_gamerules_convar.h @@ -21,6 +21,13 @@ class CRD_GameRulesConVarCollection #define GameRulesConVarMax( collection, index, name, defaultValue, helpString, maxValue ) CRD_GameRulesConVarFloat name( collection, index, #name, #defaultValue, helpString, false, 0, true, maxValue ) #define GameRulesConVarClamp( collection, index, name, defaultValue, helpString, minValue, maxValue ) CRD_GameRulesConVarFloat name( collection, index, #name, #defaultValue, helpString, true, minValue, true, maxValue ) #define GameRulesConVarBool( collection, index, name, defaultValue, helpString ) CRD_GameRulesConVarBool name( collection, index, #name, defaultValue ? "1" : "0", helpString ) +#define GameRulesConVarSkill( collection, index, name, defaultBaseValue, defaultStepValue, helpString, skill, subskill ) \ + CRD_GameRulesConVarFloat name##_base( collection, index##_BASE, #name "_base", #defaultBaseValue, helpString, false, 0, false, 0 ); \ + CRD_GameRulesConVarFloat name##_step( collection, index##_STEP, #name "_step", #defaultStepValue, helpString, false, 0, false, 0 ) +#define GameRulesConVarSkill5_2( collection, index, name, defaultBaseValue, defaultModerateValue, defaultExpertValue, helpString, skill, subskill ) \ + CRD_GameRulesConVarFloat name##_base( collection, index##_BASE, #name "_base", #defaultBaseValue, helpString " (for 0-1 points)", false, 0, false, 0 ); \ + CRD_GameRulesConVarFloat name##_moderate( collection, index##_MODERATE, #name "_moderate", #defaultModerateValue, helpString " (for 2-3 point)", false, 0, false, 0 ); \ + CRD_GameRulesConVarFloat name##_expert( collection, index##_EXPERT, #name "_expert", #defaultExpertValue, helpString " (for 4-5 points)", false, 0, false, 0 ) class CRD_GameRulesConVar {