commit 3a6f9681b6fbdf729ebd828f443872736e40ee9d Author: diamante0018 Date: Sun Nov 16 21:44:07 2025 +0100 init diff --git a/LICENSE b/LICENSE new file mode 100644 index 0000000..6e58633 --- /dev/null +++ b/LICENSE @@ -0,0 +1,29 @@ +BSD 3-Clause License + +Copyright (c) 2026, AlterWare +All rights reserved. + +Redistribution and use in source and binary forms, with or without +modification, are permitted provided that the following conditions are met: + +1. Redistributions of source code must retain the above copyright notice, this + list of conditions and the following disclaimer. + +2. Redistributions in binary form must reproduce the above copyright notice, + this list of conditions and the following disclaimer in the documentation + and/or other materials provided with the distribution. + +3. Neither the name of the copyright holder nor the names of its + contributors may be used to endorse or promote products derived from + this software without specific prior written permission. + +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" +AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE +DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE +FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL +DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR +SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER +CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, +OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. diff --git a/README.md b/README.md new file mode 100644 index 0000000..2b67f02 --- /dev/null +++ b/README.md @@ -0,0 +1,7 @@ +# T7 Rawfiles +This repo contains the T7 Rawfiles for T7x. + +Contributions are welcome! Please follow the guidelines below: + +- Sign [AlterWare CLA](https://alterware.dev/cla) and send a pull request or email your patch at patches@alterware.dev +- Make sure that PRs have only one commit, and deal with one issue only diff --git a/data/gamesettings/mp/gamesettings_escort.cfg b/data/gamesettings/mp/gamesettings_escort.cfg new file mode 100644 index 0000000..5b713e1 --- /dev/null +++ b/data/gamesettings/mp/gamesettings_escort.cfg @@ -0,0 +1,26 @@ +gametype_setting timelimit 5 +gametype_setting scorelimit 0 +gametype_setting roundscorelimit 1 +gametype_setting roundwinlimit 2 +gametype_setting roundlimit 2 +gametype_setting preroundperiod 10 +gametype_setting teamCount 2 + +gametype_setting shutdownDamage 3 +gametype_setting bootTime 5 +gametype_setting rebootTime 15 +gametype_setting rebootPlayers 0 +gametype_setting movePlayers 1 +gametype_setting robotSpeed 1 +gametype_setting robotShield 0 + + +gametype_setting scoreHeroPowerGainFactor 0.788 //Score earned towards Hero Weapons and Abilities are multiplied by this factor +gametype_setting scoreHeroPowerTimeFactor 0.788 + +gametype_setting spawntraptriggertime 5 + +gametype_setting disableVehicleSpawners 1 + +gametype_setting gameAdvertisementRuleTimeLeft 3.5 +gametype_setting gameAdvertisementRuleRound 3 diff --git a/data/launcher/bigboiii.jpg b/data/launcher/bigboiii.jpg new file mode 100644 index 0000000..da49e9f Binary files /dev/null and b/data/launcher/bigboiii.jpg differ diff --git a/data/launcher/main.html b/data/launcher/main.html new file mode 100644 index 0000000..cbe85e0 --- /dev/null +++ b/data/launcher/main.html @@ -0,0 +1,146 @@ + + + + + + T7x + + + + + +
+ +
+

+ BOIII +

+
Play
+
+ About +
+
+ + + + diff --git a/data/launcher/noise.jpg b/data/launcher/noise.jpg new file mode 100644 index 0000000..073a702 Binary files /dev/null and b/data/launcher/noise.jpg differ diff --git a/data/lookup_tables/dvar_list.txt b/data/lookup_tables/dvar_list.txt new file mode 100644 index 0000000..b118711 --- /dev/null +++ b/data/lookup_tables/dvar_list.txt @@ -0,0 +1,7026 @@ +AmmoBoxPickupTime +BotCount +ClickToContinue +GameDescription +HTTPD_CmdFence +HTTPD_Port +HTTPD_StaticRoot +MapName +MaxPlayerCount +ParallaxHUD +ServerName +ServerPassword +ShakeHUD +TestIntervalJitter +UI_enabled +UI_highlightScaledText +UI_safeAreaOverride +UI_showSafeArea +ViewAngleOverride_cameraInputDeadTimeMs +ViewAngleOverride_cameraInputThreshold +accelspeed +actors_walkable +addMapPackFlagsUserInfo +addfavourite +adsZeroSpread +ai_ShowCanSeeChecks +ai_ShowCanshootChecks +ai_accu_player_lateral_speed +ai_accuracyDistScale +ai_accuracy_attackerCountDecrease +ai_accuracy_attackerCountMax +ai_adjustOffMeshNodes +ai_allowCachedConditions +ai_allowFrameLimitedApi +ai_allowLerpedCooldownTimers +ai_angularYawAccelRate +ai_angularYawDecelFactor +ai_angularYawEnabled +ai_arrivalLookaheadDistance +ai_avoidNavBoundaries +ai_avoidOthersAtCloseDist +ai_awarenessEnabled +ai_badPathSpam +ai_clampToNavMeshEnabled +ai_clientFacialCullDist +ai_codeGameskill +ai_corpseCount +ai_coverDistanceOffset +ai_coverFlankCheckRad +ai_coverFlankDistToCover +ai_coverFlankMaxAngle +ai_coverHeightOffset +ai_coverScore_coverType +ai_coverScore_dangerousNode +ai_coverScore_distance +ai_coverScore_engagement +ai_coverScore_flanking +ai_coverScore_nodeAngle +ai_coverScore_playerLos +ai_coverScore_priority +ai_coverScore_targetDir +ai_coverScore_visibility +ai_coverSearchInterval +ai_coverSpacingDistance +ai_debugAccuracy +ai_debugAnimDeltas +ai_debugAnimScripted +ai_debugArrivals +ai_debugCodeBehaviorTree +ai_debugCoverEntityNum +ai_debugCoverSelection +ai_debugCoverTool +ai_debugEntIndex +ai_debugEntLock +ai_debugFindPath +ai_debugFindPathDirect +ai_debugFindPathLock +ai_debugFindPathWidth +ai_debugFlyingPath +ai_debugGrenadeHintArc +ai_debugMayMove +ai_debugMeleeAttackSpots +ai_debugTargets +ai_debugThreatSelection +ai_debugTurnRate +ai_debugVolumeTool +ai_debug_dynamic_nodes +ai_disableSpawn +ai_doNotDamageTeammates +ai_dogMeleeHeight +ai_dogMeleeRange +ai_dogMeleeWidth +ai_enableBadPlaces +ai_eventDistBadPlace +ai_exitLookaheadDistance +ai_findNavExternalFaces +ai_foliageIngoreDist +ai_foliageSeeThroughDist +ai_friendlyFireBlockDuration +ai_friendlySuppression +ai_friendlySuppressionDist +ai_generateNavmeshRegions +ai_instantNoSolidOnDeath +ai_maxAttackerCount +ai_meleeDamage +ai_meleeHeight +ai_meleeRange +ai_meleeWidth +ai_moveOrientMode +ai_navDisplay_Alpha +ai_navDisplay_FontSize +ai_navDisplay_X +ai_navDisplay_Y +ai_navDraw_DepthTest +ai_navDraw_Height +ai_navVolumeLayerIndex +ai_navVolume_Cave +ai_navVolume_fillCells +ai_navVolume_labelCells +ai_navVolume_showCellBorders +ai_navVolume_showEdgeConnections +ai_navVoume_colorCellsRandomly +ai_noDodge +ai_pathChokePointCost +ai_pathMomentum +ai_pathNegotiationOverlapCost +ai_pathRandomPercent +ai_pathSuppressionEnabled +ai_perfInfoSortType +ai_playerFarAccuracy +ai_playerFarRange +ai_playerLOSHalfWidth +ai_playerNearAccuracy +ai_playerNearRange +ai_scaleSightUpdateLatency +ai_secondaryThreats +ai_showClaimedNode +ai_showClearanceCeiling +ai_showCount +ai_showCoverScore +ai_showDodge +ai_showExternalFaceByIndex +ai_showExternalFaceWithEdge +ai_showExternalFaces +ai_showLastKnownEnemyPos +ai_showNavMemory +ai_showNavMesh +ai_showNavMeshBadEdges +ai_showNavMeshRegions +ai_showNavMeshSeeds +ai_showNavMeshSilhouettes +ai_showNavMeshTriggers +ai_showNavPaths +ai_showNavStats +ai_showNavVolume +ai_showNavVolumeStats +ai_showNearestNode +ai_showNodes +ai_showNodesDist +ai_showOffMeshNodes +ai_showPathFindNodes +ai_showPaths +ai_showPerfInfo +ai_showPotentialCoverLocations +ai_showPotentialThreatDir +ai_showSuppression +ai_showVisData +ai_showVisDataDist +ai_showVolume +ai_simplifyExternalEdges +ai_slowdownMaxYawDiff +ai_slowdownMinRate +ai_slowdownMinYawDiff +ai_slowdownRateBlendFactor +ai_stumbleSightFOV +ai_stumbleSightRange +ai_tacticalInfluencersDebug +ai_tacticalInfluencersThreatDebug +ai_testEdgeForCover +ai_testVertexForNearbyFaces +ai_threatUpdateInterval +ai_trim_path_zigzags +ai_useBetterLookahead +ai_useFacingTranslation +ai_useLeanRunAnimations +ai_useTacticalInfluencers +ai_validateBehaviorTree +ai_warnMissingNavVolume +ai_weaponCamoEnabled +aim_DebugTopDownAssist +aim_accel_turnrate_debug +aim_accel_turnrate_enabled +aim_accel_turnrate_lerp +aim_aimAssistRangeScale +aim_alternate_lockon_deflection +aim_alternate_lockon_pitch_strength +aim_alternate_lockon_region_height +aim_alternate_lockon_region_width +aim_alternate_lockon_strength +aim_assist_min_target_distance +aim_assist_script_disable +aim_assist_sniperADS_lock_on +aim_autoAimRangeScale +aim_autoaim_debug +aim_autoaim_enabled +aim_autoaim_lerp +aim_autoaim_region_height +aim_autoaim_region_width +aim_autograpple_lerp +aim_automelee_armblade_lunge_region_height +aim_automelee_armblade_lunge_region_width +aim_automelee_debug +aim_automelee_enabled +aim_automelee_lerp +aim_automelee_move_limit +aim_automelee_move_limit_angle +aim_automelee_move_limit_range +aim_automelee_region_height +aim_automelee_region_width +aim_input_graph_debug +aim_input_graph_enabled +aim_input_graph_index +aim_linkto_autorecenter_delay +aim_linkto_autorecenter_rate +aim_lockon_debug +aim_lockon_deflection +aim_lockon_enabled +aim_lockon_height_change_strength +aim_lockon_pitch_strength +aim_lockon_region_height +aim_lockon_region_width +aim_lockon_strength +aim_scale_view_axis +aim_slowdown_debug +aim_slowdown_enabled +aim_slowdown_pitch_scale +aim_slowdown_pitch_scale_ads +aim_slowdown_region_extended_height +aim_slowdown_region_extended_width +aim_slowdown_region_height +aim_slowdown_region_width +aim_slowdown_yaw_scale +aim_slowdown_yaw_scale_ads +aim_t7_assassinationmode_lerp +aim_t7_strongautomelee_lerp +aim_t7_weakautomelee_lerp +aim_target_actor_min_distance +aim_target_aim_tag_fast_update_interval +aim_target_aim_tag_slow_update_interval +aim_target_alternate_frustum_min_distance +aim_target_closest_first +aim_target_fixed_actor_size +aim_target_frustum_expand_fast_updates +aim_target_frustum_min_distance +aim_target_ignore_team_checking +aim_target_player_enabled +aim_target_sentient_half_height +aim_target_sentient_radius +aim_target_smp +aim_turnrate_pitch +aim_turnrate_pitch_ads +aim_turnrate_yaw +aim_turnrate_yaw_ads +aim_view_sensitivity_component +aim_view_sensitivity_override +airburstAdjustDistance +allClientDvarsEnabled +allCollectiblesUnlocked +allEmblemsPurchased +allEmblemsUnlocked +allItemsPurchased +allItemsUnlocked +all_players_are_connected +allocTracker_log +allocTracker_print +allocTracker_printstack +allocTracker_track +allowAllNAT +allowDLCWeaponsByOwnership +allowGuestSplitScreenOnline +allowHost_matchesHostedRatio +allowHost_matchesHostedStreak +allowHost_matchesPlayedRatio +allowHost_matchesPlayedStreak +allowTaskManagerRSU +allow_weapon_switch_during_swimming +amd_useShaderExtension +animScript_listAnims +anim_debugSpeeds +anim_deltas_debug +anim_intro +anim_visualization_enable +animscript_debug +animscript_xcam_debug +arena_bonusStarStreak +arena_defaultPlaylist +arena_enableArenaChallenges +arena_enableListenHosting +arena_giveBonusStar +arena_lobbyReloadSearchDelayMax +arena_lobbyReloadSearchDelayMin +arena_maintenance +arena_maxPregameCryptoSeconds +arena_minHostSkillRange +arena_minPlayTime +arena_minPregameCryptoSeconds +arena_qosBrodenSkillFrequency +arena_qosBrodenSkillStep +arena_qosSkillStart +arena_seasonOverride +arena_seasonVetChallengeWins +arena_unfairTeamGap +armblade_lunge_region_height +armblade_lunge_region_width +art_review +asm_animDeltaParamsThresh +asm_codeLevel +asm_debugAimLayer +asm_debugLevel +asm_debugPrimaryDeltaLayer +asm_debugShootLayer +asm_disableTransitions +asm_footMatching +asm_useNetworkFrameDelta +assassination +assassination_cinematic +assassination_counter +assassination_debug +assassination_debug_slowmo +assassination_default +assassination_height_limit +assassination_max_height_displacement +assassination_mode +attachment_exclusion_0 +autoExecDemoConfig +autojoin +balances_fakeFail +balances_retry_delay +balances_retry_max +banclient +bandwidth_retry_interval +banuser +beamDrawCurveVerts +beamDrawNodes +beamDrawSlackInfo +beamDrawWaveVerts +beamKillBeam +beamLaunchBeam +beamReset +beast_blur_radius_inner +beast_blur_radius_outer +beast_blur_time_in +beast_blur_time_out +beast_jump_blur_amount +behaviorTrackerVersionNumber +beta_special +betty_activation_delay +betty_damage_cylinder_height +betty_damage_max +betty_damage_min +betty_damage_radius +betty_detect_radius +betty_grace_period +betty_jump_height_onground +betty_jump_height_wall +betty_jump_time +betty_onground_angle_threshold +bgCachePrintValues +bg_ads +bg_aimSpreadMoveSpeedThreshold +bg_allowPlayerRoleTemplateButtonOverrides +bg_anim_blend_angle +bg_anim_blend_anim1 +bg_anim_blend_anim2 +bg_anim_blend_force_time +bg_anim_blend_fudge_time_offset +bg_anim_blend_ratio +bg_anim_blend_set +bg_anim_blend_speed_frac +bg_anim_blend_timing1a +bg_anim_blend_timing1b +bg_anim_blend_timing2a +bg_anim_blend_timing2b +bg_anim_blend_turn_speed +bg_anim_blend_turn_speed_max +bg_anim_blend_use_dvar_timings +bg_aqs +bg_aqsStyle +bg_arenaSlot +bg_blendTimeOverride +bg_bobMax +bg_bobTransTime +bg_bobcycleResetThreshold +bg_bulletPenetrationTreatVoidsAsSolid +bg_chargeShotAutoDischargeDelay +bg_chargeShotAutoFireDelay +bg_chargeShotCenterSpeedReductionPerBullet +bg_chargeShotDamageIncreasePerBullet +bg_chargeShotDischargeWhenQueueReachesMax +bg_chargeShotExponentialAmmoPerChargeLevel +bg_chargeShotMaxBulletQueueOnEMP +bg_chargeShotMaxViewKick +bg_chargeShotMinCenterSpeed +bg_chargeShotPenetrationMultiplier +bg_chargeShotUseOneAmmoForMultipleBullets +bg_chargeShotViewKickIncreasePerBullet +bg_counterMeleeTime +bg_debugNotifies +bg_deferScriptMissileDetonation +bg_disablePaintshopBaseIconTransform +bg_disableWeaponPlantingGroundTrace +bg_disableWeaponPlantingInWater +bg_dog_swim_enabled +bg_dog_swim_water_max +bg_dog_swim_water_min +bg_drawGrenadeInHand +bg_drawProximity +bg_enableIKActiveFix +bg_fallDamageMaxHeight +bg_fallDamageMinHeight +bg_foliagesnd_fastinterval +bg_foliagesnd_maxspeed +bg_foliagesnd_minspeed +bg_foliagesnd_resetinterval +bg_foliagesnd_slowinterval +bg_forceAnimOverrideTimerCheck +bg_forceDurationOverride +bg_forceExplosiveBullets +bg_force_idle_scale +bg_freeCamClipToHeliPatch +bg_friendlyFire +bg_friendlyFireMode +bg_friendlyfireDist +bg_grappleRequiresEquippedWeapon +bg_gravity +bg_grenadeMinimumThrowbackTime +bg_gunXOffset +bg_heavyWeaponsAlwaysPlayFirstRaise +bg_isolateDamageFlash +bg_legYawCrouchTolerance +bg_legYawProneTolerance +bg_legYawTolerance +bg_limitGrenadeImpacts +bg_lowGravity +bg_maxGrenadeIndicatorSpeed +bg_maxWeaponAnimScale +bg_meleePreLungeTime +bg_moonGravity +bg_movingPlatformPitchScale +bg_overridePlayerEmblemIcon +bg_perksCacheTestOld +bg_plantInWaterDepth +bg_playStandToCrouchAnims +bg_playerAnimStanceAllowMovementInteruptTime +bg_proneSwingSpeed +bg_prone_yawcap +bg_scriptCanDisableStances +bg_serverDelayDamageKickForPing +bg_shieldHitEncodeHeightVM +bg_shieldHitEncodeHeightWorld +bg_shieldHitEncodeWidthVM +bg_shieldHitEncodeWidthWorld +bg_slopeFrames +bg_specialOffhandInventoryAllowBallSwitch +bg_specialOffhandInventorySwitch +bg_swingSpeed +bg_t7BlockMeleeUsageTime +bg_t7MeleeControlScheme +bg_t7MeleeHeightCheck +bg_t7MeleeQuadrantMaxAngle +bg_t7MeleeQuadrantMinAngle +bg_t7MeleeUseAssassinationState +bg_teleportAlignTime +bg_ufospeedscale +bg_ufoviewscale +bg_useCharacterTable +bg_useClientDamageKick +bg_useT7Melee +bg_useThrowButtonForDetonatorGrenades +bg_vehicle_gravity +bg_vehicle_ground_max_normal +bg_vehicle_ground_min_normal +bg_vehicle_helicopter_dogfight_roll_control_scale +bg_vehicle_helicopter_focus_target_control_leeway +bg_vehicle_helicopter_focus_target_damping_angle +bg_vehicle_helicopter_focus_target_damping_exponent +bg_vehicle_max_body_pitch +bg_vehicle_max_body_roll +bg_vehicle_max_pitch +bg_vehicle_max_roll +bg_vehicle_overclip +bg_vehicle_pitch_track +bg_vehicle_placement_debug +bg_vehicle_plane_invert_pitch +bg_vehicle_plane_jet_controls +bg_vehicle_plane_turn_assist_decay_rate +bg_vehicle_roll_track +bg_vehicle_slide_min_normal +bg_vehicle_sphere_bounds_offset_z +bg_vehicle_stepsize +bg_vehicle_tangential_clip_max_scale +bg_vehicle_tangential_clip_vel_scale +bg_vehicle_trace_offset +bg_viewBobAmplitudeDtp +bg_viewBobAmplitudeDucked +bg_viewBobAmplitudeDuckedAds +bg_viewBobAmplitudeJuke +bg_viewBobAmplitudeJukeAds +bg_viewBobAmplitudeProne +bg_viewBobAmplitudeRoll +bg_viewBobAmplitudeSlide +bg_viewBobAmplitudeSprinting +bg_viewBobAmplitudeStanding +bg_viewBobAmplitudeStandingAds +bg_viewBobAmplitudeSwimming +bg_viewBobAmplitudeWallRun +bg_viewKickDeflectTime +bg_viewKickDeflectTimeAds +bg_viewKickMax +bg_viewKickMaxAds +bg_viewKickMin +bg_viewKickMinAds +bg_viewKickRandom +bg_viewKickRecoverTime +bg_viewKickRecoverTimeAds +bg_viewKickScale +bg_viewKickScaleAds +bg_viewanglesDebug +bg_vsmode_hud +bg_warmode_version +bg_waterGravity +bg_weaponBobAmplitudeBase +bg_weaponBobFrequencySwimming +bg_weaponButtMeleeCharge +bg_weaponCompatibleIfSharedAmmo +bg_weaponOffscreenReloadScale +bg_weaponSubtractFrameTimeRemainder +bg_weaponSwitchHero +bg_weaponSwitchHeroHoldTime +bg_zm_dlc1_chargeShotMultipleBulletsForFullCharge +bg_zombiePlayerUsesUtilityClip +bgcache_checksum_validation +bgcache_checksum_validation_demo +bgcache_disablewarninghints +bgcache_displaychecksum +bgcache_loaddevitems +bgcache_mark_used_assets +bgcache_skip_mychanges +bind +bind2 +blackboxBandwidthLimited +blackboxHighVolumeProbability +blackboxMode +blurpain +boostcheatBitchHKRatioCoef +boostcheatBitchHKRatioMean +boostcheatBitchHKRatioStddev +boostcheatBitchKillTimestampsAnomalyCoef +boostcheatBitchKillTimestampsAnomalyMean +boostcheatBitchKillTimestampsAnomalyStddev +boostcheatBitchKillsRatioCoef +boostcheatBitchKillsRatioMean +boostcheatBitchKillsRatioStddev +boostcheatBitchKillsTotalCoef +boostcheatBitchKillsTotalMean +boostcheatBitchKillsTotalStddev +boostcheatHeadshotsTotalCoef +boostcheatHeadshotsTotalMean +boostcheatHeadshotsTotalStddev +boostcheatIntercept +boostcheatKillerXAnomalyCoef +boostcheatKillerXAnomalyMean +boostcheatKillerXAnomalyStddev +boostcheatKillerYAnomalyCoef +boostcheatKillerYAnomalyMean +boostcheatKillerYAnomalyStddev +boostcheatMeanBitchLifetimeMillisecondsCoef +boostcheatMeanBitchLifetimeMillisecondsMean +boostcheatMeanBitchLifetimeMillisecondsStddev +boostcheatMeanDistanceBitchTraveledCoef +boostcheatMeanDistanceBitchTraveledMean +boostcheatMeanDistanceBitchTraveledStddev +boostcheatMeanDistanceVictimTraveledCoef +boostcheatMeanDistanceVictimTraveledMean +boostcheatMeanDistanceVictimTraveledStddev +boostcheatVictimXAnomalyCoef +boostcheatVictimXAnomalyMean +boostcheatVictimXAnomalyStddev +boostcheatVictimYAnomalyCoef +boostcheatVictimYAnomalyMean +boostcheatVictimYAnomalyStddev +bot_AllowAiming +bot_AllowAttack +bot_AllowGrenades +bot_AllowHeroGadgets +bot_AllowKillstreaks +bot_AllowMelee +bot_AllowMeleeCharge +bot_AllowMovement +bot_AllowSprint +bot_Debug +bot_DebugX +bot_DebugY +bot_DrawPerks +bot_ForceCrouch +bot_ForceFire +bot_ForceMelee +bot_ForceProne +bot_ForceStand +bot_Fov +bot_FovAds +bot_PitchSensitivity +bot_PitchSpeed +bot_PitchSpeedAds +bot_PredictCorners +bot_PressAttackBtn +bot_PressMeleeBtn +bot_SnapshotDebug +bot_UseFriendNames +bot_YawSensitivity +bot_YawSpeed +bot_YawSpeedAds +bot_difficulty +bot_enableWallrun +bot_enemies +bot_friends +bot_maxAllies +bot_maxAxis +bot_maxFree +bot_maxJumpDistance +bot_maxMantleHeight +bot_maxWaterMantleHeight +bot_recordButtons +bot_recordGoal +bot_recordGoalInfo +bot_recordHealth +bot_recordPathing +bot_recordPlayerFlags +bot_recordThreat +bot_supported +bot_traverseUnderwater +bow_launcher_bounce_max_scale +bow_launcher_charge_snap_percent +bow_launcher_minimum_reticle_scale +bow_launcher_rebound_scale +breadcrumbDistanceImportance +breadcrumbThreshold +breadcrumbTimeImportance +bullet_enterWater +bullet_penetrationEnabled +bullet_penetrationMinFxDist +bullet_ricochetBaseChance +bulletrange +cameraShakeRemoteHelo_Angles +cameraShakeRemoteHelo_Freqs +cameraShakeRemoteHelo_SpeedRange +cameraShakeRemoteMissile_Angles +cameraShakeRemoteMissile_Freqs +cameraShakeRemoteMissile_SpeedRange +cg_BallisticArc_BeginAlpha +cg_BallisticArc_BeginWidth +cg_BallisticArc_Debug +cg_BallisticArc_DrawDelay +cg_BallisticArc_EndAlpha +cg_BallisticArc_EndWidth +cg_BallisticArc_ForceHitIndicator +cg_BallisticArc_ImpactRadius +cg_BallisticArc_MaxBounces +cg_BallisticArc_MinBounces +cg_BallisticArc_Offset +cg_BallisticArc_PerpStep +cg_BallisticArc_VerticalOffset +cg_DrawOnScreenFriendlyAI +cg_DrawOnlyFriendlyPlayerNamesWhileInVehicle +cg_DrawPlayerNamesWhileInVehicle +cg_DrawRemoteVehiclePlayerNames +cg_EnableAdaptiveSkinLodScale +cg_InfraredFadeoutTime +cg_ScoresColor_Free +cg_ScoresColor_Gamertag_0 +cg_ScoresColor_Gamertag_1 +cg_ScoresColor_Gamertag_2 +cg_ScoresColor_Gamertag_3 +cg_ScoresColor_Spectator +cg_ScoresPing_Interval +cg_ScoresPing_MaxBars +cg_VelocityArrow_MaxSegmentLength +cg_VelocityArrow_MinSegmentLength +cg_VelocityArrow_RateOfChange +cg_WeaponButtAttackerCameraShakeDuration +cg_WeaponButtAttackerHitCameraShakeScale +cg_WeaponButtAttackerMissCameraShakeScale +cg_WeaponButtVictimCameraShakeDuration +cg_WeaponButtVictimCameraShakeScale +cg_adsZScaleMax +cg_adsZoomToggleStyle +cg_aggressiveCullRadius +cg_ai_useServerAnims +cg_allPlayerNamesVisible +cg_altDofTrace +cg_animInfoCornerOffset +cg_animMonitorEnt +cg_animMonitorFilter +cg_artilleryKillCamBackDist +cg_artilleryKillCamFov +cg_artilleryKillCamGroundBackDist +cg_artilleryKillCamGroundUpDist +cg_artilleryKillCamUpDist +cg_artilleryKillCamWallOutDist +cg_artilleryKillCamWallSideDist +cg_assignRandomPaintshops +cg_bloodLimit +cg_bloodLimitMsec +cg_blur_time +cg_brass +cg_cameraRollOverride +cg_cameraSpikeEnemyColor +cg_cameraSpikeHighlightBrightness +cg_cameraUnderwaterLens +cg_cameraVehicleExitTweenTime +cg_cameraVzoomToggleTime +cg_cameraWaterClip +cg_canSeeFriendlyFrustumExpand +cg_canSeeFriendlyFrustumMinDistance +cg_canSeeFriendlyFrustumUpdateInterval +cg_cancelChargeShotTime +cg_centertime +cg_chatHeight +cg_cinematicFullscreen +cg_circularMinimapWhenSquare +cg_clampFrameInterpolation +cg_clanNameDebug +cg_clientSideGlassTouch +cg_combatRobotKillCamDistFromEyes +cg_combatRobotKillCamForwardDist +cg_combatRobotKillCamFov +cg_combatRobotKillCamSideDist +cg_combatRobotKillCamUpDist +cg_combatRobotKillMinDistFromTarget +cg_connectionIconSize +cg_constantSizeHeadIcons +cg_corpseHighlightFadeTime +cg_cropFactor +cg_crosshairAlpha +cg_crosshairAlphaMin +cg_crosshairDynamic +cg_crosshairEnemyColor +cg_crosshairVehicleSentientCheck +cg_cullBulletAngle +cg_cullBullets +cg_cursorHints +cg_damageIndicatorAngle +cg_damageIndicatorMinDelay +cg_damageIndicatorShowAfterDeathTime +cg_deathCamAboveWater +cg_deathScreenFadeInTime +cg_deathScreenFadeOutTime +cg_debugCacheEnabled +cg_debugCinematicCamera +cg_debugDrawSafeAreas +cg_debugDynamicLadderSight +cg_debugEllipsesOffset +cg_debugEntCount +cg_debugEvents +cg_debugFace +cg_debugInfoCornerOffset +cg_debugMounting +cg_debugPosition +cg_debugTargetEntNumber +cg_debugThirdPersonCamera +cg_debug_exploders +cg_debug_overlay_viewport +cg_debug_triggers +cg_debugevents +cg_debugposition +cg_descriptiveText +cg_destructibleKillCamCloseXYDist +cg_destructibleKillCamCloseZDist +cg_destructibleKillCamFarBlur +cg_destructibleKillCamFarBlurDist +cg_destructibleKillCamFarBlurStart +cg_destructibleKillCamFov +cg_destructibleKillCamNearBlur +cg_destructibleKillCamNearBlurEnd +cg_destructibleKillCamNearBlurStart +cg_destructibleKillCamRegularHeight +cg_destructibleKillCamZIncrease +cg_destructible_radius_damage_enabled +cg_development +cg_disableearthquake +cg_disableplayernames +cg_dogKillCamDistFromEyes +cg_dogKillCamForwardDist +cg_dogKillCamFov +cg_dogKillCamSideDist +cg_dogKillCamUpDist +cg_dogKillMinDistFromTarget +cg_draw2D +cg_draw2d +cg_drawAnimAttachTags +cg_drawArtFPS +cg_drawBonesEntNum +cg_drawBreathHint +cg_drawBudgets +cg_drawBulletHitPosNormal +cg_drawBulletPenetration +cg_drawCrosshair +cg_drawCrosshairCooker +cg_drawCrosshairNames +cg_drawCrosshairNamesPosX +cg_drawCrosshairNamesPosY +cg_drawDecalSort +cg_drawFPS +cg_drawFPSLabels +cg_drawFPSScale +cg_drawFramePerformanceWarnings +cg_drawFriendlyNames +cg_drawGun +cg_drawHoldBreathHint +cg_drawIdentifierDebug +cg_drawJobsPerf +cg_drawLagometer +cg_drawLightingDebugText +cg_drawMantleHint +cg_drawMaterial +cg_drawMaterialImageName +cg_drawMaterialImageNum +cg_drawMemoryInfo +cg_drawMinimap +cg_drawModelAxis +cg_drawNetTiming +cg_drawPerformanceSweepInfo +cg_drawPerformanceWarnings +cg_drawPhotosensorOverlay +cg_drawRenderFrame +cg_drawRumbleDebug +cg_drawScriptUsage +cg_drawShellshock +cg_drawSnapshot +cg_drawSpectatorMessages +cg_drawTalk +cg_drawThroughWalls +cg_drawVersion +cg_drawVersionX +cg_drawVersionY +cg_drawVisibleCounts +cg_drawWVisDebug +cg_drawWaterTrail +cg_drawXCamInfo +cg_drawYouInKillCamAsWaypoint +cg_drawfps +cg_drawgun +cg_drawlagometer +cg_drawpaused +cg_drawrumbledebug +cg_droneKillCamBackDist +cg_droneKillCamUpDist +cg_dumpAnims +cg_enableHelicopterNoCullLodOut +cg_enemyNameFadeIn +cg_enemyNameFadeOut +cg_errorDecay +cg_explosiveKillCamBackDist +cg_explosiveKillCamGroundBackDist +cg_explosiveKillCamGroundUpDist +cg_explosiveKillCamStopDecelDist +cg_explosiveKillCamStopDist +cg_explosiveKillCamUpDist +cg_explosiveKillCamWallOutDist +cg_explosiveKillCamWallSideDist +cg_fakefireWizbyChance +cg_fastApe +cg_fastFakeApe +cg_fast_lui +cg_firstPersonTracerChance +cg_flareVisionSetFadeDuration +cg_flipTeamVisuals +cg_focalDistance +cg_focalDistanceChangeSpeed +cg_focalLength +cg_footprints +cg_footprintsDebug +cg_footprintsDistortWater +cg_footsteps +cg_forceEmp +cg_forceInfrared +cg_forceInvalidPaintshops +cg_forceNoCullLodOut +cg_fov +cg_fovExtraCam +cg_fovMin +cg_fovScale +cg_fov_comp_max +cg_fov_default +cg_fov_default_nocomp +cg_fov_default_thirdperson +cg_friendlyNameFadeIn +cg_friendlyNameFadeOut +cg_fstop +cg_fullscreenFinalKillcam +cg_gameBoldMessageWidth +cg_gameMessageWidth +cg_gamemessageiconscale +cg_gun_fovcomp_x +cg_gun_fovcomp_y +cg_gun_fovcomp_z +cg_gun_move_f +cg_gun_move_minspeed +cg_gun_move_r +cg_gun_move_rate +cg_gun_move_u +cg_gun_ofs_f +cg_gun_ofs_r +cg_gun_ofs_u +cg_gun_pitch +cg_gun_roll +cg_gun_rot_minspeed +cg_gun_rot_p +cg_gun_rot_r +cg_gun_rot_rate +cg_gun_rot_y +cg_gun_x +cg_gun_y +cg_gun_yaw +cg_gun_z +cg_headIconMinScreenRadius +cg_healthPerBar +cg_heliKillCamFarBlur +cg_heliKillCamFarBlurDist +cg_heliKillCamFarBlurStart +cg_heliKillCamFov +cg_heliKillCamNearBlur +cg_heliKillCamNearBlurEnd +cg_heliKillCamNearBlurStart +cg_hideHighDetail +cg_hideViewmodelInUFOMode +cg_hintFadeTime +cg_hitmarkerFrameSpacing +cg_hudChatIntermissionPosition +cg_hudChatPosition +cg_hudDamageDirectionalIconTime +cg_hudDamageIconHeight +cg_hudDamageIconInScope +cg_hudDamageIconOffset +cg_hudDamageIconTime +cg_hudDamageIconWidth +cg_hudFriendlyIndicatorHeight +cg_hudFriendlyIndicatorWidth +cg_hudGrenadeIconEnabledFlash +cg_hudGrenadeIconHeight +cg_hudGrenadeIconInScope +cg_hudGrenadeIconMaxHeight +cg_hudGrenadeIconMaxRangeFlash +cg_hudGrenadeIconMaxRangeFrag +cg_hudGrenadeIconMaxScale +cg_hudGrenadeIconMaxScaleDistance +cg_hudGrenadeIconMinScale +cg_hudGrenadeIconMinScaleDistance +cg_hudGrenadeIconOffset +cg_hudGrenadeIconWidth +cg_hudGrenadeIndicatorFadeUp +cg_hudGrenadeIndicatorStartColor +cg_hudGrenadeIndicatorTargetColor +cg_hudGrenadePointerHeight +cg_hudGrenadePointerPivot +cg_hudGrenadePointerPulseFreq +cg_hudGrenadePointerPulseMax +cg_hudGrenadePointerPulseMin +cg_hudGrenadePointerWidth +cg_hudLegacySplitscreenScale +cg_hudMapBorderWidth +cg_hudMapFriendlyHeight +cg_hudMapFriendlyWidth +cg_hudMapPlayerHeight +cg_hudMapPlayerWidth +cg_hudMapRadarLineThickness +cg_hudProneY +cg_hudSayPosition +cg_hudSplitscreenBannerScoreboardScale +cg_hudSplitscreenCompassElementScale +cg_hudSplitscreenCompassScale +cg_hudSplitscreenOffsetsUseScale +cg_hudSplitscreenScoreboardScale +cg_hudSplitscreenStanceScale +cg_hudStanceHintPrints +cg_hudVotePosition +cg_infraredBlur +cg_infraredBlurTime +cg_infraredFriendlies +cg_infraredHighlightOffset +cg_infraredHighlightScale +cg_infraredUseDefaultMaterial +cg_ingnoreValidateWeaponOnDeath +cg_inputLagTestAvgThreshold +cg_inputLagTestMaxThreshold +cg_inputLagTestNumRuns +cg_inputLagTestTimePerRun +cg_invalidCmdHintBlinkInterval +cg_invalidCmdHintDelay +cg_invalidCmdHintDuration +cg_isGameplayActive +cg_killcamdebug +cg_lagometer_pos +cg_laserLight +cg_laserSightMaxDistance +cg_lastSpectatorSelectedThirdPerson +cg_latencyTestMode +cg_loadScripts +cg_luiDebug +cg_mapLocationSelectionCursorSpeed +cg_mapLocationSelectionRotationSpeed +cg_marks_ents_player_only +cg_marqueeTimeScale +cg_maxExplosionRadius +cg_maxPlayerHighlightTargetSize +cg_minCullBulletDist +cg_minicon +cg_minimapCorruptionMaskScale +cg_minimapMaskPadding +cg_minimapPadding +cg_minimapPopOutZoom +cg_missile_FOV +cg_noPlayerShadows +cg_objectiveIndicatorColor +cg_objectiveIndicatorFarDist +cg_objectiveIndicatorFarFadeDist +cg_objectiveIndicatorFarScale +cg_objectiveIndicatorNearDist +cg_objectiveIndicatorNearFadeDist +cg_objectiveIndicatorNoDrawDistance +cg_objectiveIndicatorPerkFarFadeDist +cg_objectiveIndicatorSize +cg_objectiveListWrapCountStandard +cg_objectiveListWrapCountWidescreen +cg_oneFriendlyHeadTracePerFrame +cg_onscreenErrors +cg_opticAttachmentViewmodelSwitch +cg_opticCamoHidesShadow +cg_overheadArmorHeight +cg_overheadArmorOffset +cg_overheadHealthDebug +cg_overheadHealthHeight +cg_overheadHealthOffset +cg_overheadHealthWidth +cg_overheadIconSize +cg_overheadNamesDamagedEntityNameRetainTime +cg_overheadNamesDrawOnADS +cg_overheadNamesDrawOnDamage +cg_overheadNamesFarDist +cg_overheadNamesFarScale +cg_overheadNamesFont +cg_overheadNamesGlow +cg_overheadNamesMaxDist +cg_overheadNamesNearDist +cg_overheadNamesSize +cg_overheadNamesTagUpdateInterval +cg_overheadRankSize +cg_overheadiconsize +cg_overheadnamessize +cg_overheadranksize +cg_packetAnalysisClient +cg_packetAnalysisEntTextScale +cg_packetAnalysisEntTextY +cg_packetAnalysisEntityIndex +cg_packetAnalysisEntitySelectionDepth +cg_packetAnalysisEntityTypeIndex +cg_packetAnalysisPaused +cg_packetAnalysisServerMode +cg_packetAnalysisTextScale +cg_packetAnalysisTextY +cg_paintshopCalcTweaks +cg_paintshopEnableCompression +cg_paintshopEnableTweaks +cg_paintshopForceClearDiskCache +cg_paintshopImageHeight +cg_paintshopImagePosition +cg_paintshopImageScale +cg_paintshopImageWidth +cg_paintshopIncreasePlayerRes +cg_paintshopReadDiskCache +cg_paintshopShowGrid +cg_paintshopShowGridEdge +cg_paintshopShowImages +cg_paintshopShowTweaks +cg_paintshopWriteDiskCache +cg_playerBeastGrapHintSizeMax +cg_playerBeastGrapHintSizeMin +cg_playerBeastHintSizeMax +cg_playerBeastHintSizeMin +cg_playerFrustumHalfHeight +cg_playerHighlightBlinkTime +cg_playerHighlightBrightness +cg_playerHighlightEnemyColor +cg_playerHighlightMinFade +cg_playerHighlightPivotLineFlash +cg_playerHighlightPivotLineWidth +cg_playerHighlightPivotScale +cg_playerHighlightSpreadExp +cg_playerHighlightSpreadScale +cg_playerHighlightTargetInner +cg_playerHighlightTargetOuter +cg_playerHighlightTargetScale +cg_playerHighlightTargetSize +cg_playerLockonReticleSize +cg_playerRenderSmp +cg_playerVRGame +cg_playersInViewMinDot +cg_predictItems +cg_profile_physics +cg_proneFeetCollisionHull +cg_rangeFinderActiveColor +cg_rangeFinderActiveHeight +cg_rangeFinderActiveReticleIndex +cg_rangeFinderActiveWidth +cg_rangeFinderColorChangeDelay +cg_rangeFinderDefaultColor +cg_rangeFinderDefaultDisplayStr +cg_rangeFinderDefaultReticleIndex +cg_rangeFinderDiamondIndicator +cg_rangeFinderDiamondSize +cg_rangeFinderMinEnemySpottingDist +cg_rangeFinderPlayerTargetSize +cg_rangeFinderSelectActors +cg_rangeFinderSelectPlayers +cg_rangefinderIndicatorGap +cg_rangefinderIndicatorSize +cg_reflect_impactfx +cg_reflect_impactfx_mindotclamp +cg_resetWeaponPaintshops +cg_retrieveHintTime +cg_retrieveHintTimeStuck +cg_rocketKillCamBackDist +cg_rocketKillCamUpDist +cg_rumble_devgui_duration +cg_rumble_devgui_loop +cg_scoreboardBannerHeight +cg_scoreboardHeight +cg_scoreboardItemHeight +cg_scoreboardPingGraph +cg_scoreboardPingHeight +cg_scoreboardPingText +cg_scoreboardPingWidth +cg_scoreboardQuarterscreenWidth +cg_scoreboardScrollStep +cg_scoreboardSplitscreenWidth +cg_scoreboardWidth +cg_scriptIconSize +cg_scriptedKillCamCloseXYDist +cg_scriptedKillCamCloseZDist +cg_scriptedKillCamFarBlur +cg_scriptedKillCamFarBlurDist +cg_scriptedKillCamFarBlurStart +cg_scriptedKillCamFov +cg_scriptedKillCamNearBlur +cg_scriptedKillCamNearBlurEnd +cg_scriptedKillCamNearBlurStart +cg_scriptmover_useServerAnims +cg_seatHintFadeTime +cg_sensorGrenadeCrouchZOffset +cg_sensorGrenadeExplosionTrackTimeMs +cg_sensorGrenadeLaserActiveTimeMs +cg_sensorGrenadeLaserRadius +cg_sensorGrenadeProneZOffset +cg_sensorGrenadePulsePeriodMs +cg_sensorGrenadeRampAlpha +cg_sensorGrenadeRange +cg_sensorGrenadeZOffset +cg_showLoadedFF +cg_showQosResults +cg_showZombieControls +cg_showZombieMap +cg_showmiss +cg_smp_weapon_visibility +cg_speedBlurScaleBeast +cg_speedBlurScaleDoubleJump +cg_speedBlurScaleGrapple +cg_speedBlurScaleJuke +cg_speedBlurScaleLunge +cg_speedBlurScaleSlam +cg_speedBlurScaleSlide +cg_speedBlurScaleSpeedBurst +cg_splitscreen2pOffset +cg_splitscreenLetterboxSize +cg_splitscreenSpectatorScaleIncrease +cg_sprintMeterDisabledColor +cg_sprintMeterEmptyColor +cg_sprintMeterFullColor +cg_streamLowDetailCamos +cg_subtitleMinTime +cg_subtitleWidthStandard +cg_subtitleWidthWidescreen +cg_t7HealthOverlay +cg_t7HealthOverlay_Threshold1 +cg_t7HealthOverlay_Threshold2 +cg_t7HealthOverlay_Threshold3 +cg_tagCacheEnabled +cg_teamChatsOnly +cg_thirdPerson +cg_thirdPersonAngle +cg_thirdPersonCamLerpScale +cg_thirdPersonCamOffsetUp +cg_thirdPersonFocusDist +cg_thirdPersonFocusOffsetUp +cg_thirdPersonFootstepsFromNotetracks +cg_thirdPersonLastStand +cg_thirdPersonMode +cg_thirdPersonPaintshop +cg_thirdPersonRange +cg_thirdPersonRoll +cg_thirdPersonSideOffset +cg_thirdPersonUpOffset +cg_threatDetectorDebug +cg_threatDetectorRadius +cg_timedDamageDuration +cg_traversalLerpInTime +cg_traversalLerpOutTime +cg_treadmarks +cg_turretBipodOffset +cg_updateScoreboardAfterGameEnded +cg_usNewEventQueueScheme +cg_useNewEventQueueScheme +cg_useSafeSpectatorCam +cg_useWeaponBasedVariableZoom +cg_useWeaponSwitchReloadCancel +cg_use_colored_smoke +cg_usercmdBursting +cg_usingClientScripts +cg_vehNPCThrottleMultiplier +cg_vehicleCamAboveWater +cg_vehicleFocusEntDistanceMax +cg_vehicleFocusEntDistanceMin +cg_vehicleFocusEntFocalLengthMax +cg_vehicleFocusEntFocalLengthMin +cg_vehicleFocusEntFocalLengthSpeedAdjust +cg_vehicleFocusEntFstop +cg_vehicleFocusEntLerpTime +cg_vehicleVRMechGame +cg_vehicle_piece_damagesfx_threshold +cg_viewVehicleInfluenceGunner +cg_viewVehicleInfluenceGunnerFiring +cg_viewVehicleInfluenceGunner_mode +cg_viewZSmoothingMax +cg_viewZSmoothingMin +cg_viewZSmoothingTime +cg_viewmodelAnimatedFalls +cg_viewmodelAnimatedJumps +cg_visionSetLerpMaxDecreasePerFrame +cg_visionSetLerpMaxIncreasePerFrame +cg_voiceIconSize +cg_waterPerturbForceScale +cg_waterPerturbRadiusScale +cg_waterTrailRippleFrequency +cg_waterTrailRippleVariance +cg_watersheeting +cg_weaponCycleDelay +cg_weaponHeat +cg_weaponHintsCoD1Style +cg_weaponSimulateFireAnims +cg_youInKillCamSize +cg_zbarrierStreamAllWeapons +cgprintentities +chain_melee_attack_angle_cosine_limit +chain_melee_chargeThroughVelocity +chain_melee_enabled +chain_melee_endAnimEarlyTime +challenge +challengeResponseResendBackoffInterval +challengeResponseResendInterval +charge_melee_finishCloseThreshold +chatClientEnabled +cheapSpawns +checkEmblemForRank +checkXUIDBeforeStatsUpload +cl_allowDownload +cl_analog_attack_threshold +cl_anglespeedkey +cl_autojoin +cl_avidemo +cl_bitfieldmismatchFatal +cl_bspmismatchFatal +cl_compositeDebugStringMode +cl_connectTimeout +cl_connectionAttempts +cl_dblTapMaxDelayTime +cl_dblTapMaxHoldTime +cl_deathMessageWidth +cl_debugMessageKey +cl_disableHeroRenders +cl_disablePaintshopBaseIconTransform +cl_dpadLeftHeavyWeapon +cl_dtpHoldTime +cl_fakeLagMS +cl_forceavidemo +cl_freelook +cl_gamepadCheatsEnabled +cl_hudDrawsBehindUI +cl_ingame +cl_jqprof_continuous +cl_jqprof_enabled +cl_jqprof_frequency +cl_jqprof_profileCheckpointFrames +cl_jqprof_threshold +cl_maxPing +cl_maxpackets +cl_migrationPingTime +cl_motdString +cl_mouseAccel +cl_nodelta +cl_noprint +cl_packetdup +cl_paused +cl_pitchspeed +cl_playerPrestige +cl_playerRank +cl_profileTextHeight +cl_profileTextY +cl_profileWriteLimiter +cl_rumble +cl_secondaryPlayerMenuControlDisable +cl_serverStatusResendTime +cl_showMouseRate +cl_showSend +cl_showServerCommands +cl_showTimeDelta +cl_shownet +cl_shownuments +cl_smoothSnapInterval +cl_socketpool_enabled +cl_socketpool_size +cl_specialOffhand +cl_specialOffhandDelay +cl_specialOffhandInput +cl_specialOffhandInventorySwitch +cl_splitscreenGamestateHack +cl_sprintOnStick +cl_sprintOnStick_threshold +cl_stanceHoldTime +cl_tacticalHud +cl_timeout +cl_useMapPreloading +cl_userTestBuild +cl_voice +cl_weapNextHoldEnable +cl_weapNextHoldTime +cl_wwwDownload +cl_yawspeed +clanAbbrev +clanAbbrev_IsEliteValidated +clear +clearAllLoadoutSlots +clearAllLoadoutSlotsCPOffline +clearAllLoadoutSlotsMPCustom +clearAllLoadoutSlotsMPOffline +clearAllLoadoutSlotsZMOffline +clearKeyStates +clearLoadoutSlot +clearLoadoutSlotCPOffline +clearLoadoutSlotMPCustom +clearLoadoutSlotMPOffline +clearLoadoutSlotZMOffline +clientkick +climb_cameraAlignmentEaseMode +climb_cameraRotateTimeMs +climb_centerAllowedThreshold +climb_centerTranslateSpeed +climb_ladderMoveDefaultSpeed +climb_ladderMoveScale +climb_ladderSlideDownDefaultSpeed +climb_ladderSlideDownThreshold +climb_pitchDownClamp +climb_pitchUpClamp +climb_yawClamp +cmdlist +com_allowModeSpecificBitFields +com_animCheck +com_clientFieldsDebug +com_cpu_profile +com_desiredMenu +com_developer +com_disable_popups +com_drawFPS_PC +com_enablePaintshopInCP +com_fixedtime +com_fixedtime_float +com_forceSVLockStep +com_freemoveScale +com_introPlayed +com_logfile +com_maxFrameTime +com_maxclients +com_maxfps +com_pauseSupported +com_pgraph_mode +com_profileLoadingForceSend +com_report_syserrors +com_saveSnapshotProfile +com_script_debugger_smoke_test +com_script_error_recovery +com_script_recordeventintervalms +com_script_recordeventprobability_client +com_script_recordeventprobability_server +com_skipMovies +com_smoothFrames +com_sortteamclientsbyname +com_statmon +com_sv_running +com_timescale +com_useEmptyBitFields +com_voip_bandwidth_restricted +com_voip_disable_threshold +com_voip_resume_time +com_waitForInitial +com_waitForInitialFrontend +com_waitForStreamer +com_wideScreen +comerror_enableDelayedComError +comerror_enableTaskCallbackSysError +compass +compassAlwaysShowEnemyVehicles +compassBehaviorAwarenessEnabled +compassClampIcons +compassCloneColor +compassCoords +compassDebug +compassDoubleJumpAlpha +compassDrawHackerPing +compassDrawLastStandIcon +compassECoordCutoff +compassEnableColorBlindPlayerIcons +compassEnemyFootstepEnabled +compassEnemyFootstepMaxRange +compassEnemyFootstepMaxZ +compassEnemyFootstepMinSpeed +compassForcePlayerIcon +compassFriendlyAIColor +compassFriendlyColor +compassFriendlyFogVisionBrightness +compassFriendlyHeight +compassFriendlyWidth +compassGridAlign +compassGridCols +compassGridEnabled +compassGridRows +compassIconOtherVehHeight +compassIconOtherVehWidth +compassIconTankHeight +compassIconTankScale +compassIconTankWidth +compassLocalRadarRadius +compassLocalRadarUpdateTime +compassMaxRange +compassMinRadius +compassMinRange +compassObituaryHeight +compassObituaryWidth +compassObjectiveHeight +compassObjectiveIconHeight +compassObjectiveIconWidth +compassObjectiveMaxHeight +compassObjectiveMaxRange +compassObjectiveMinAlpha +compassObjectiveMinDistRange +compassObjectiveMinHeight +compassObjectiveNearbyDist +compassObjectiveWidth +compassPartialType +compassPingFiringTime +compassPingGunnerFiringTime +compassPlayerColor +compassPlayerHeight +compassPlayerWidth +compassRadarLineThickness +compassRadarPingFadeTime +compassRadarUpdateFastTime +compassRadarUpdateTime +compassRotation +compassSatellitePingFadeTime +compassSatelliteScanTime +compassSatelliteStaticImageFadeTime +compassShowAIWhileFiring +compassShowEnemies +compassSize +compassSoundPingFadeTime +compassSpectatorsSeeEnemies +compassStaticImageUpdateTime +compassmaxrange +comscore_backoff +comscore_debug +comscore_enabled +comscore_eventThreshholdSize +comscore_filtercategories +con_MiniConSplitscreenScale +con_channelhide +con_channelshow +con_default_console_filter +con_echo +con_errormessagetime +con_gameMsgWindow0FadeInTime +con_gameMsgWindow0FadeOutTime +con_gameMsgWindow0Filter +con_gameMsgWindow0LineCount +con_gameMsgWindow0MsgTime +con_gameMsgWindow0ScrollTime +con_gameMsgWindow0SplitscreenScale +con_gameMsgWindow1FadeInTime +con_gameMsgWindow1FadeOutTime +con_gameMsgWindow1Filter +con_gameMsgWindow1LineCount +con_gameMsgWindow1MsgTime +con_gameMsgWindow1ScrollTime +con_gameMsgWindow1SplitscreenScale +con_gameMsgWindow2FadeInTime +con_gameMsgWindow2FadeOutTime +con_gameMsgWindow2Filter +con_gameMsgWindow2LineCount +con_gameMsgWindow2MsgTime +con_gameMsgWindow2ScrollTime +con_gameMsgWindow2SplitscreenScale +con_gameMsgWindow3FadeInTime +con_gameMsgWindow3FadeOutTime +con_gameMsgWindow3Filter +con_gameMsgWindow3LineCount +con_gameMsgWindow3MsgTime +con_gameMsgWindow3ScrollTime +con_gameMsgWindow3SplitscreenScale +con_hidelabel +con_inputBoxColor +con_inputHintBoxColor +con_label_filter_mask +con_labellist +con_matchPrefixOnly +con_miniconlines +con_minicontime +con_outputBarColor +con_outputSliderColor +con_outputWindowColor +con_restricted +con_restricted_access +con_showlabel +con_typewriterColorBase +con_typewriterColorGlowCheckpoint +con_typewriterColorGlowCompleted +con_typewriterColorGlowFailed +con_typewriterColorGlowUpdated +con_typewriterDecayDuration +con_typewriterDecayStartTime +con_typewriterEnabledSounds +con_typewriterPrintSpeed +connect +consoleGame +constBaseline_allow +constBaseline_bigEndian +constBaseline_throwError +content_trialcontentpackbits +contracts_daily_duration +contracts_disable_schedule +contracts_enabled_mp +contracts_now +contracts_rows_in_set +contracts_start_time +contracts_verbose +cookbookDebug +cookbookUseTestData +counterDownloadInterval +counterUploadInterval +cp_queued_level +creditsScrollScale +ctx_cover_ads_walk_speed_scale +ctx_cover_angle_threshold +ctx_cover_control_scheme +ctx_cover_debug +ctx_cover_enable +ctx_cover_ls_engage_threshold +ctx_cover_ls_maintain_threshold +ctx_cover_play3rdPersonAnims +ctx_cover_post_move_pause +ctx_cover_test_high +ctx_cover_test_high_length +ctx_cover_test_low +ctx_cover_test_low_length +ctx_cover_test_radius +ctx_cover_walk_speed_scale +cullGlassShards +currentDifficulty +currentLiveEvent +curveBallBackFactor +curveBallDownFactor +curveBallForwardFactor +curveBallUpFactor +custom_killstreak_mode +cybercom_enabled +cybercom_fastswitch_enabled +daily_contract_cryptokey_reward_count +db_keyserver1 +db_keyserver2 +db_warnformissingasset +db_xassetdebug +db_xassetdebugname +db_xassetdebugtype +dbg_switch_00 +dbg_switch_01 +dbg_switch_02 +dbg_switch_03 +dbg_switch_04 +dbg_switch_05 +dbg_switch_06 +dbg_switch_07 +dcacheSimulateNoHDD +dcache_enabled +ddlAssertOnMismatch +ddlRatDone +debugAnimScript +debugCurves +debugOverlay +debugOverlayClient +debugRenderCollision +debugRenderCollisionDistance +debugRenderMask +debugRenderPlayerCollision +debugSplit +debug_anim_shared +debug_audio +debug_brushClipTintVariation +debug_brushClipTinting +debug_bulletPenetration +debug_color_pallete +debug_crash_type +debug_litBrushes +debug_missileImpactNoDamage +debug_missileStickAngle +debug_mover +debug_physicsGunObjCount +debug_protocol +debug_ragdollSpawnObjCount +debug_reflection +debug_reflection_matte +debug_rope +debug_scene +debug_scene_skip +debug_show_viewpos +debug_trace +debug_triggers +defaultClassSetCount +defaultDamageDuration +defaultDamageInterval +defaultHitDamage +default_emblems_max_count +defragGlassIndices +defragGlassMemory +demigod +demoRenderDuration +demoRenderSizeX +demoRenderSizeY +demo_autoDollyCameraPathFrequency +demo_bookmarkEventThresholdTime +demo_bytesPerSecondMax +demo_bytesPerSecondMin +demo_cameraLensFStop +demo_cameraLensFocalDistance +demo_cameraLensFocalLength +demo_client +demo_debug +demo_desiredClient +demo_desiredTime +demo_desiredclient +demo_desiredtime +demo_dollycamHighlightThreshholdDistance +demo_dollycamLeaveAtPreviousMarker +demo_dollycamMarkerInformationFarDist +demo_dollycamMarkerInformationFarScale +demo_dollycamMarkerInformationNearDist +demo_dollycamMarkerInformationThreshholdDistance +demo_dollycamMarkerTimeScaleMode +demo_dollycamMarkerTimeScaleValue +demo_dollycamTrackWidth +demo_downloadEntireFile +demo_downloadLiveStreamThrottleTime +demo_downloadStreamDataBlockRequestSize +demo_downloadStreamDataBlockThrottleTime +demo_downloadStreamMaxRetryAttemps +demo_downloadStreamRetryWaitTime +demo_downloadStreamThrottleTime +demo_drawdebuginformation +demo_enableAdvancedCameraControls +demo_enableAutoDollyCameraPath +demo_enableCameraLens +demo_enableClipRecordEvent +demo_enableDeferredMatchRecord +demo_enableDollyCam +demo_enableSvBandwidthLimitThrottle +demo_enabled +demo_errormessage +demo_errortitle +demo_extraNetworkProfileData +demo_fileblockWriteRate +demo_filesizeLimit +demo_filmStartInformationScreenStayTime +demo_filmStartInformationScreenStayTime_Freerun +demo_freeCameraLockOnHighlightThreshholdDistance +demo_freeCameraLockOnMissileAllowed +demo_freeCameraLockOnOrbitRadius +demo_freeCameraShowLockableObjectsAlways +demo_freeCameraUseHeliHeightLockAsCeiling +demo_hide3rdPersonPlayerModel +demo_highlightReelGameResultFilter +demo_highlightReelMinimumStarsFilter +demo_highlightReelNumberOfSegments +demo_highlightReelPlayerFilter +demo_highlightReelStylesFilter +demo_highlightReelTransitionFilter +demo_inGameThrottleBandwidthPercent +demo_inLobbyThrottleBandwidthPercent +demo_keyframerate +demo_lightmanMarkerLightAttenuation +demo_lightmanMarkerLightColorB +demo_lightmanMarkerLightColorG +demo_lightmanMarkerLightColorR +demo_lightmanMarkerLightIntensity +demo_lightmanMarkerLightMode +demo_lightmanMarkerLightRange +demo_livestreaming +demo_matchRecordEventOnPlaylists +demo_maxTimeScale +demo_nodeath +demo_oldposInsteadOfMapCenter +demo_packetsPerSecondMax +demo_packetsPerSecondMin +demo_pause +demo_pauseOnNextSnapshot +demo_playbackClientXUID +demo_profiling +demo_recordOfflineMatch +demo_recordPrivateMatch +demo_recordStaticEntityPositions +demo_recordSystemlinkMatch +demo_recordingrate +demo_refreshDollyCamFxEveryFrame +demo_save_smp +demo_selectedSegmentIndex +demo_sendEventOnFailure +demo_skipBuildingDemoSnapshotDuringCinematicPlayback +demo_streamUploadKeepAliveFrequency +demo_streamingAdjustmentFactor +demo_streamingSendSocketBuffSizeForOtherUploads +demo_streamingSendSocketBuffSizeForRecording +demo_summaryReadEnabled +demo_svBandwidthLimitThrottleMaxBytesPercent +demo_svBandwidthLimitThrottleTimeout +demo_useDefaultVehicleDefIndexIfInvalid +demo_useMapNameAsDefaultName +demo_usefilesystem +demo_viewTraceMask +demo_writePaintShopInformation +demoname +dev_timescale +devdlc +developer +devgui_bevelShade +devgui_colorBgnd +devgui_colorBgndGray +devgui_colorBgndGraySel +devgui_colorBgndSel +devgui_colorGraphKnotEditing +devgui_colorGraphKnotNormal +devgui_colorGraphKnotSelected +devgui_colorSliderBgnd +devgui_colorSliderKnob +devgui_colorSliderKnobSel +devgui_colorText +devgui_colorTextGray +devgui_colorTextGraySel +devgui_colorTextSel +devgui_favMenuEnabled +devgui_scale +devgui_showOnlyFavMenu +devgui_warningSpam +devgui_warningSpan +devgui_zoomEnabled +devmap +devmaponline +disableHost_matchesHostedRatio +disableHost_matchesHostedStreak +disableHost_matchesPlayedRatio +disableHost_matchesPlayedStreak +disableLookAtEntityLogic +disable_aivsai_melee +disable_fx +disable_rope +disconnect +disconnected_ctrls +dive_debug +dive_enabled +dive_groundTraceDist +dive_min_distance_ratio +dive_traceForward +dlc2_fix_scripted_looping_linked_animations +dlc2_show_damage_feedback_when_drowning +dlc3_veh_UpdateYawEvenWhileStationary +doAutoExecDevConfig +doAutoExecUserConfig +doMaintenance +dog_MeleeDamage +dog_checkObstaceInPathWhenMoving +dog_checkShouldTurnWhenMoving +dog_repathDistSq +dog_traceMask +dog_turn180_angle +dog_turn90_angle +dog_turn_min_goal_dist +door_breach_weapondrop +doubleJump_accel +doubleJump_accelerationThreshold +doubleJump_ads_enabled +doubleJump_allow_while_swimming +doubleJump_fire_disabled_angles +doubleJump_fire_enabled +doubleJump_frictionMax +doubleJump_frictionMin +doubleJump_frictionScale +doubleJump_fx_enabled +doubleJump_hud_border +doubleJump_hud_is_vertical +doubleJump_maxUpwardsVelocity +doubleJump_minimapClip +doubleJump_minimapFadeTime +doubleJump_minimapRevealEnabled +doubleJump_minimapRevealEnemies +doubleJump_minimapRevealFriendlies +doubleJump_minimapRevealMaxDistance +doubleJump_minimapRevealSelf +doubleJump_minimapRevealSpeed +doubleJump_minimapRevealTime +doubleJump_requirejump +doubleJump_rumble_enabled +doubleJump_shake_duration +doubleJump_shake_duration_ads +doubleJump_shake_duration_ads_spam +doubleJump_shake_duration_spam +doubleJump_shake_enabled +doubleJump_shake_scale +doubleJump_shake_scale_ads +doubleJump_shake_scale_ads_spam +doubleJump_shake_scale_spam +doubleJump_shellshocked_accel +doubleJump_shellshocked_maxUpwardsVelocity +doubleJump_shellshocked_speed +doubleJump_shellshocked_upBoostAccel +doubleJump_speed +doubleJump_tap_enabled +doubleJump_upBoostAccel +doubleJump_viewAngleMaxPitch +doubleJump_viewAngleMaxRoll +doubleJump_viewAnglePitchSpeed +doubleJump_viewAngleRollSpeed +doubleJump_viewMovementEnabled +doubleJump_viewmodel_anim_enabled +doublejump_animCosAngle +doublejump_blur_amount +doublejump_blur_enabled +doublejump_blur_radius_inner +doublejump_blur_radius_outer +doublejump_blur_time_in +doublejump_blur_time_out +doublejump_control_scheme +doublejump_enabled +doublejump_hud +doublejump_rechargeInAir +doublejump_rechargeInWater +doublejump_requirekeyup +doublejump_requirekeyup_in_water +doublejump_time_before_recharge +doublejump_time_before_recharge_emp +doublejump_time_before_recharge_fast +doublescreen +doublesided_raycasts +drawEntityCount +drawEntityCountPos +drawEntityCountSize +drawGlassBBox +drawGlassDebug +drawKillcamData +drawKillcamDataPos +drawKillcamDataSize +drawLagometer +drawServerBandwidth +drawServerBandwidthPos +drawServerBandwidthSize +drawShardOutline +dtp +dtp_debug +dtp_exhaustion_window +dtp_fall_damage_max_height +dtp_fall_damage_min_height +dtp_max_apex_duration +dtp_max_slide_addition +dtp_max_slide_duration +dtp_min_speed +dtp_new_trajectory +dtp_new_trajectory_multiplier +dtp_post_move_pause +dtp_startup_delay +dumpimages +dumpmateriallist +dumpmodels +durangoGame +dvarConfigEnabled +dvarConfigFatal +dvar_maxCallbackTimeMS +dvardump +dvarlist +dvr_enable +dwConsideredConnectedTime +dwFileFetchTryIntervalBase +dwFileFetchTryIntervalMax +dwFileFetchTryMaxAttempts +dwKVSWriteLocally +dwNetMaxWaitMs +dwStreamingSendSocketBuffSize +dwTitle +dw_defaultDTLSAssociationTimeout +dw_popup +dw_sendBufSize +dynEnt_bulletForce +dynEnt_damageRadiusScale +dynEnt_delete_expensive +dynEnt_disable_rb_collision +dynEnt_explodeForce +dynEnt_explodeMaxEnts +dynEnt_explodeMinForce +dynEnt_explodeSpinScale +dynEnt_explodeUpbias +dynEnt_sentientAutoActivate +dynEnt_shouldCullEntitiesForSplitscreen +dynEnt_small_cylinder_dimension +dynEnt_small_cylinder_max_avel +dynEnt_spawnedLimit +dynsnaps_debugspew +emblem +emblemVersion +emblem_scroll_delay_first +emblem_scroll_delay_rest +emblems_enabled +emblems_max_count +enableChallengeResponse +enableDLCWeapons +enableTacticalArrival +enable_camo_materials_tab +enable_cheap_ents +enable_frame_sampling +enable_global_wind +enable_grass_wind +enable_moving_paths +enable_new_prone_check +enable_retail_incentive +enable_season_pass_incentive +enable_sp_exploit_check +enable_weapon_contract +energyShieldActorMagneticAccuracy +energyShieldReflectDamageMultiplier +energyShieldReflectLerpToNormalFrac +entitlementsActive +entitycount +equipClass +equipDefaultClass +equipDefaultClassToProfile +equipDefaultCustomMatchClass +equipDefaultItemToSlot +equipLoadoutSlot +equipLoadoutSlotCPOffline +equipLoadoutSlotMPCustom +equipLoadoutSlotMPOffline +equipLoadoutSlotZMOffline +equipLoadoutWeaponSlot +equipLoadoutWeaponSlotCPOffline +equipLoadoutWeaponSlotMPCustom +equipLoadoutWeaponSlotMPOffline +equipLoadoutWeaponSlotZMOffline +equipmentAltModeEnabled +equipmentAsGadgets +equipmentMods +equipment_enable_threat_detector +excellentPing +exec +facepaintLodDist +fakeEmblemCount +fast_restart +fastfile_allowNoAuth +fastfile_warnMeWhenOutOfSync +ffotdtempfixHostLaunchPump +fileshareAllowDownload +fileshareAllowDownloadingOthersFiles +fileshareAllowEmblemDownload +fileshareAllowPaintjobDownload +fileshareAllowVariantDownload +fileshareRetry +fileshareShowFailure +fileshareXuidOverride +fileshare_enabled +fileshare_fakeFail +fileshare_tier +filterdedicatedserverresults +fire_audio_random_max_duration +fire_audio_repeat_duration +fire_burn_time +fire_debug +fire_world_damage +fire_world_damage_duration +fire_world_damage_rate +firstPersonLegs +firstPersonLegsInWater +firstPersonLegsOffset +firstPersonLegsOffsetMax +firstPersonLegsOffsetMin +firstPersonLegsZmax +firstPersonLegsZmin +firstPersonShadow +fixNegativeLosses +fixedtime +fixedtime_float +flameVar_editingFlameTable +flameVar_lastFlameTable +flame_debug_render +flame_kick_offset +flame_kick_recover_speed +flame_kick_speed +flame_render +flame_team_damage +flame_test +flame_use_new_beam_system +flareDisableEffects +footstep_sounds_cutoff +forceEliteFounder +forceElitePopups +forceEliteSubscription +forceFullScreenMap +forceHost +forceLiveEvent +force_cac +force_no_cac +fpsTool_drawInfo +fpsTool_drawPoints +fpsTool_forceAsyncCompute +fpsTool_headings +fpsTool_includeMapSamplePoints +fpsTool_loadTest +fpsTool_maxSamples +fpsTool_note +fpsTool_randomRotate +fpsTool_receiveSamples +fpsTool_run +fpsTool_showGun")" +fpsTool_showGun +fpsTool_takeScreenshots +frame_sampling_rate +freezeShards +friction +friendlyContentOutlines +friendlyNameFontColor +friendlyNameFontGlowColor +friendlyNameFontObjective +friendlyNameSplitScreenFontSize +friendlyfire_enabled +friendsNewsLastFetchTime +fsShowStreamingGraph +fsSlotEmptyHiddenColor +fsSlotEmptyMainColor +fsSlotEmptyNotSubscribedColor +fsSlotEmptyShowColor +fsSlotEmptyShowColorBg +fsSlotHighlightedColor +fsSlotHighlightedColorNoSel +fsSlotMainColor +fsSlotNumMainColor +fsSlotNumNoSubsribeColor +fsStarAvgColor +fsStarHighlightColor +fs_basegame +fs_basepath +fs_debug +fs_game +fs_homepath +fs_ignoreLocalized +fs_restrict +fs_usedevdir +fshCustomGameName +fshEnableRender +fshFileDebug +fshMtxName +fshOldItemColor +fshRecentsXUID +fshRenderSuccessURL +fshRenderWriteTimeout +fshRetryDelay +fshSearchTaskDelay +fshSkipFileStats +fshStaffXuid +fshSummaryDelay +fshThrottleEnabled +fshThrottleKBytesPerSec +fudgefactor +fx_alphacull_enable +fx_attempt_trail_reconstruction +fx_attempt_trail_reconstruction_debug +fx_attempt_trail_reconstruction_lerp_ratio +fx_attempt_trail_reconstruction_lerp_time_ms +fx_compute_sprites_debug_draw +fx_compute_sprites_enable +fx_compute_sprites_enable_all +fx_compute_sprites_only +fx_compute_sprites_shadow +fx_compute_sprites_show_lmap +fx_count +fx_cull_effect_spawn +fx_cull_elem_draw +fx_cull_elem_spawn +fx_debugBolt +fx_depth_test_bounding_boxes +fx_disable_exclusion_volumes +fx_draw +fx_drawClouds +fx_draw_dvar +fx_draw_exclusion_volumes +fx_draw_weapon_tags +fx_enable +fx_enable_bounding_boxes +fx_enable_portal_culling +fx_force_bounding_boxes +fx_force_portal_culling +fx_freeze +fx_gpufx_debug_enable +fx_gpufx_draw_enable +fx_gpufx_elem_limit +fx_gpufx_library_enable +fx_gpufx_no_water +fx_gpufx_sort_enable +fx_gpufx_sprite_limit +fx_gpufx_update_enable +fx_limit_spawn_workers +fx_liveupdate +fx_liveupdate_kb +fx_liveupdate_verbose +fx_logging +fx_mark_profile +fx_marks +fx_marks_debug_text +fx_marks_draw +fx_marks_draw_impact_axis +fx_marks_ents +fx_marks_forward_vol_marks_enable +fx_marks_grid_debug +fx_marks_grid_enable +fx_marks_range +fx_marks_smodels +fx_max_per_frame_distance +fx_occlusion_max_player_count +fx_occlusion_query_profile +fx_priority_debug +fx_priority_enable +fx_process_clouds +fx_profile +fx_show_bounding_boxes +fx_show_distances +fx_show_names_range +fx_use_ground_entity +fx_visMinTraceDist +fx_warn_on_version +fxfrustumCutoff +g_FactionName_Allies +g_FactionName_Axis +g_FactionName_allies +g_FactionName_axis +g_FactionName_free +g_ScoresColor_Allies +g_ScoresColor_Axis +g_ScoresColor_EnemyTeam +g_ScoresColor_Free +g_ScoresColor_MyTeam +g_ScoresColor_Spectator +g_TeamColor_Allies +g_TeamColor_Axis +g_TeamColor_EnemyTeam +g_TeamColor_EnemyTeamAlt +g_TeamColor_Free +g_TeamColor_MyTeam +g_TeamColor_MyTeamAlt +g_TeamColor_MyTeamAlt_Party +g_TeamColor_Party +g_TeamColor_Spectator +g_TeamIcon_Allies +g_TeamIcon_Axis +g_TeamIcon_Free +g_TeamIcon_Spectator +g_TeamName_Allies +g_TeamName_Axis +g_TeamName_Three +g_TeamName_allies +g_TeamName_axis +g_TeamName_free +g_actorAndVehicleAntilag +g_actorAndVehicleAntilagDebug +g_ai +g_aiEventDump +g_allowLastStandForActiveClients +g_allowVote +g_allowvote +g_animMonitorEnt +g_animMonitorFilter +g_antilag +g_antilagRestoreOnDamage +g_antilagTimeCap +g_avoidEnabled +g_bDebugGrappleTrace +g_bDebugRenderBrushes +g_bDebugRenderBulletCollision +g_bDebugRenderBulletMeshes +g_bDebugRenderCollision +g_bDebugRenderCollisionDistance +g_bDebugRenderColoredPatches +g_bDebugRenderEntityBrushes +g_bDebugRenderMeshType +g_bDebugRenderPatches +g_bDebugRenderStaticModelsBounds +g_banIPs +g_broadcastLocalSound +g_campaign_mode +g_changelevel_time +g_clientSideLinkingEnabled +g_clonePlayerMaxVelocity +g_compassShowEnemies +g_customTeamName_Allies +g_customTeamName_Axis +g_customTeamName_Three +g_deadChat +g_deathDelay +g_deathcameratraceheight +g_debugAccuracy +g_debugBehaviorStateMachine +g_debugBulletDuration +g_debugBulletEntityType +g_debugBullets +g_debugCacheEnabled +g_debugDamage +g_debugHitBrush +g_debugHitSurface +g_debugLocDamage +g_debugLocDamageEntity +g_debugLocHit +g_debugLocHitTime +g_debugPlayerAnimScript +g_debugRankXP +g_debugRenderGjkTraceGeom +g_debugRenderMask +g_debugServerAiming +g_debugWeaponXP +g_destructibleDraw +g_drawDebugInfoVolumes +g_drawDebugInfoVolumesInverse +g_drawGrenadeHints +g_dropForwardSpeed +g_dropHorzSpeedRand +g_dropUpSpeedBase +g_dropUpSpeedRand +g_droppedWeaponPhysics +g_dumpAIEvents +g_dumpAnims +g_dumpAnimsCommands +g_dumpAnimsReduceSpam +g_dumpStaticModels +g_entinfo +g_entinfo_AItext +g_entinfo_maxdist +g_entinfo_scale +g_entinfo_type +g_entsInSnapshot +g_erroronpathsnotconnected +g_fast_devmap +g_fogColorReadOnly +g_fogHalfDistReadOnly +g_fogStartDistReadOnly +g_friendlyNameDist +g_gameEnded +g_gametype +g_knockback +g_lagged_damage_threshold +g_listEntity +g_listEntityCounts +g_loadScripts +g_log +g_logSync +g_logTimeStampInSeconds +g_mantleBlockTimeBuffer +g_maxDroppedWeapons +g_maxEntsInSnapshot +g_minGrenadeDamageSpeed +g_minimumAvgCollisionArea +g_motd +g_oldAnimCmdNetwork +g_password +g_pickupPromptsForDroppedWeapons +g_playerCollisionEjectSpeed +g_playerRespawnTime +g_playerVRGame +g_processDamageAfterFullBullet +g_quadrotorFlyHeight +g_redCrosshairs +g_reviveTime +g_scrDebugHudElems +g_smoothClients +g_spawnai +g_speed +g_synchronousClients +g_tagCacheEnabled +g_teamColor_EnemyTeam +g_teamColor_EnemyTeamAlt +g_teamColor_MyTeam +g_teamColor_MyTeamAlt +g_teamColor_Squad +g_throttleTempEnts +g_turretBipodOffset +g_turretServerPitchMax +g_turretServerPitchMin +g_useholdspawndelay +g_useholdtime +g_validateBehaviorStateMachine +g_vehicleBypassFriendlyFire +g_vehicleDebug +g_vehicleDrawPath +g_vehicleDrawSplines +g_vehiclePlaneCurveTime +g_vehicleVRMechGame +g_voiceChatTalkingDuration +g_voteAbstainWeight +gadgetActivateDuringWeaponChange +gadgetEnabled +gadgetFlickerDurationDefault +gadgetFlickerWhizbyMaxDistance +gadgetPowerInitEmpty +gadgetPowerOverchargePerkScoreFactor +gadgetPowerOverchargePerkTimeFactor +gadgetPowerOverrideFactor +gadgetPowerUnlimited +gadgetPulseOrbShareEnemy +gadgetPulseOrbShareFriendly +gadgetThiefKillFullPowerMultiplier +gadgetThiefKillPowerGain +gadgetThiefRechargeRate +gadgetThiefShutdownFullCharge +gadget_blur_enabled +gadget_castShaderDuration +gadget_flashbackMinimapFudgeFactor +gadget_flashbackResetsWallrunTime +gadget_flashbackUsesPriorAngles +gadget_flashbackWhiteAlphaRatio +gadget_flashbackWhiteFlash +gadget_force_slots +gadget_resurrectHeavyWeaponsFatal +gadget_resurrectHeroWeaponsFatal +gadget_speedBurstBaseGlow +gadget_speedBurstBaseGlowScalar +gadget_speedBurstBlurScalar +gadget_speedBurstDesatClamp +gadget_speedBurstDesatRampSpeed +gadget_speedBurstDoesJuke +gadget_speedBurstGlowPulseDuration +gadget_speedBurstWallRunJumpVelocity +gadget_visionPulseFriendlyMinimap +gadget_visionPulseFriendlyMinimapColor +gadget_visionPulseMinimapFadeTime +gadget_visionPulseRevealsCamo +gamedate +gamename +gamesettings_generateconfig +gametype_setting +geographicalMatchmakingOverride +give +glassBroom +glassCanBreakFromSlide +glassCanBreakFromSprint +glassCanBreakFromWallrun +glassCrackedDamageRateRange +glassDamageMultiplier +glassExtraAngVelocity +glassExtraLinVelocity +glassForceAttenuation +glassForceMultiplier +glassForceOriginMult +glassFreeBuffersDelay +glassLinVelMultiplier +glassLowLodDist +glassMaxShardLife +glassMinVelocityLowest +glassMinVelocityToBreakFromJump +glassMinVelocityToBreakFromSlide +glassMinVelocityToBreakFromSprint +glassMinVelocityToBreakFromWallrun +glassPlayShatterFX +glassPlayerPredictTime +glassPredictTime +god +goodPing +gpad_button_deadzone +gpad_button_lstick_deflect_max +gpad_button_rstick_deflect_max +gpad_debug +gpad_enabled +gpad_fake_vita +gpad_lightbar_test +gpad_menu_scroll_delay_first +gpad_menu_scroll_delay_rest +gpad_stick_deadzone_max +gpad_stick_deadzone_min +gpad_stick_pressed +gpad_stick_pressed_hysteresis +grapple_blur_amount +grapple_blur_radius_inner +grapple_blur_radius_outer +grapple_blur_time_in +grapple_blur_time_out +grapple_early_yank_anim_start_time +grenadeAllowRigidBodyPhysics +grenadeAnimatedFlatCosine +grenadeAnimatedFrictionHigh +grenadeAnimatedFrictionLow +grenadeAnimatedMinDotBeforeRolling +grenadeAnimatedMinDotBeforeRollingOnFlat +grenadeAnimatedRollDegree +grenadeBounceRestitutionMax +grenadeBumpFreq +grenadeBumpMag +grenadeBumpMax +grenadeCurveMax +grenadeFrictionHigh +grenadeFrictionLow +grenadeFrictionMaxThresh +grenadeMinDotBeforeRolling +grenadeParallelBounceOverride +grenadePerpendicularBounceOverride +grenadeRestThreshold +grenadeRollDegree +grenadeRollRadius +grenadeRollingEnabled +grenadeUseRigidBodyPhysics +grenadeVelocityDampFactor +grenadeWaterFrictionHigh +grenadeWaterFrictionLow +grenadeWaterFrictionThresh +grenadeWobbleFreq +grenadeWobbleFwdMag +grenadeWobbleSideDamp +grenadeWobbleSideMag +grenade_indicators_enabled +grenade_waterDebug +grenade_waterEnterRotationScalar +grenade_waterEnterScalar +grenade_waterExitRotationScalar +grenade_waterExitScalar +grenade_waterSpawnRotationScalar +grenade_waterSpawnScalar +groupCountsVisible +groupDownloadInterval +groupUploadInterval +groupZeroCountsVisible +groups_admins_refresh_time +groups_applications_refresh_time +groups_enabled +groups_invites_refresh_time +groups_presence_refresh_time +groups_quickjoin_players_refresh_time +groups_self_groups_refresh_time +groups_service_failure_backoff_time +groups_wait_on_dw +gts_validation_enabled +gunXPGroups +gunsmithVersion +gunsmith_enable_toggle_variant +gunsmith_enabled +gunsmith_totalvariants +h +hackMultiLauncherHorizontalOffset +hackMultiLauncherVerticleOffset +hackerTool_debug +hatch_check_enable +hatch_mantle_fwd +hatch_mantle_up +hiDef +highlightedPlayerName +hkai_actorClampToNavMeshFudgeFactor +hkai_additionalPathfindIterationLimit +hkai_badPlaceEdgeCostMultiplier +hkai_debugActors +hkai_debugAvoidanceCollisionPenalty +hkai_debugAvoidanceDodgingPenalty +hkai_debugAvoidanceGoalDistToleranceScale +hkai_debugAvoidanceLeftTurnRadiusScale +hkai_debugAvoidanceMaxAccel +hkai_debugAvoidanceMaxDecel +hkai_debugAvoidanceMaxNeighbors +hkai_debugAvoidanceMaxSpeed +hkai_debugAvoidanceMinSpeed +hkai_debugAvoidancePenetrationPenalty +hkai_debugAvoidanceRadius +hkai_debugAvoidanceRightTurnRadiusScale +hkai_debugAvoidanceSensorSizeScale +hkai_debugAvoidanceSidednessChangingPenalty +hkai_debugAvoidanceVelocityHysteresis +hkai_debugAvoidanceWallFollowingAngle +hkai_debugBadPlaces +hkai_debugCharacterParameters +hkai_debugCharacters +hkai_debugCornerPredictor +hkai_debugFailedPathFind +hkai_debugManualControl +hkai_debugObstacleSizeScale +hkai_debugObstacles +hkai_debugPointNearBoundary +hkai_debugPositionQuery +hkai_debugPositionqueryPerformance_cellLength +hkai_debugPositionqueryPerformance_faceLength +hkai_debugTurnRate +hkai_debugTurnVelocityScale +hkai_deferredPathfindsEnabled +hkai_dumpMemoryLeaks +hkai_maxClearanceRecalcFaces +hkai_maxPathLengthChecksEnabled +hkai_maxPathLengthMultiplier +hkai_navMeshTriggersEnabled +hkai_navMeshUseHierarchialPathFind +hkai_pathfindIterationLimit +hkai_recordWorldAndPath +hkai_recordWorldAndPathTimeLimit +hkai_repathUsingIncompleteRepathSegments +hkai_resetTimers +hkai_showTimers +hkai_stairsEdgeCostMultiplier +hkai_storeClearanceRecalcStats +hkai_storePathfindResults +hkai_timerTestActive +hkai_warnPathFindFailures +hkai_warningPopupsEnabled +hls_anti_dos_sites +hls_anti_dos_time +hls_audio_volume +hls_debug_draw +hls_quality +hls_quality_autodetected +hls_quality_available +hls_reserved_bandwidth +hls_start_offset +hopper_enabled +hostileNameFontColor +hostileNameFontGlowColor +httpnetfs +hudElemPausedBrightness +hud_deathQuoteFadeTime +hud_enable +hud_fade_ammoDisplay +hud_fade_compass +hud_fade_healthbar +hud_fade_offhand +hud_fade_stance +hud_fade_vehiclecontrols +hud_flash_period_offhand +hud_flash_time_offhand +hud_healthOverlay_phaseEnd_fromAlpha +hud_healthOverlay_phaseEnd_pulseDuration +hud_healthOverlay_phaseEnd_toAlpha +hud_healthOverlay_phaseOne_pulseDuration +hud_healthOverlay_phaseOne_toAlphaAdd +hud_healthOverlay_phaseThree_pulseDuration +hud_healthOverlay_phaseThree_toAlphaMultiplier +hud_healthOverlay_phaseTwo_pulseDuration +hud_healthOverlay_phaseTwo_toAlphaMultiplier +hud_healthOverlay_pulseStart +hud_healthOverlay_pulseStop +hud_healthOverlay_regenPauseTime +hud_health_startpulse_injured +i +ik_ai_hand_get_data +ik_ai_hand_offset_vec +ik_ai_hand_rotation_vec +ik_ai_hand_tuning +ik_ai_pool_size +ik_ai_range_max +ik_debug +ik_dvar_ai_aim_tracking_rate +ik_dvar_lookatentity_eyes_scale +ik_dvar_lookatentity_notorso +ik_dvar_lookatentity_tracking_rate +ik_dvar_lookatpos_eyes_scale +ik_dvar_lookatpos_notorso +ik_dvar_lookatpos_tracking_rate +ik_enable +ik_enable_ai_hand +ik_enable_ai_terrain +ik_enable_player_hand +ik_enable_player_terrain +ik_foot_test +ik_hand_test +ik_left_hand_lerp_test +ik_lookatentity_head_scale +ik_lookatpos_head_scale +ik_paranoid_matrix_checks +ik_pelvis_test +ik_pitch_limit_max +ik_pitch_limit_thresh +ik_right_hand_lerp_test +ik_roll_limit_max +ik_roll_limit_thresh +ik_yaw_limit_max +ik_yaw_limit_thresh +in_mouse +incentive_rare_drop_id +incentive_weapon_drop_id +initial_cod_points_id +interactivePromptAnimLen +interactivePromptNearToDist +interactivePromptNextToDist +inventory_blocking +inventory_enabled +inventory_fakeExtraSlots +inventory_fakeFail +inventory_fetch_cooloff +inventory_itemsPerPage +inventory_maxPages +inventory_retry_delay +inventory_retry_max +inventory_test_button_visible +invited +item_exclusion_0 +join_agreementWindow +join_completionWindow +join_devHostBusyChance +join_devSloMo +join_devSloMoFrame +join_handshakeWindow +join_infoProbeWindow +join_reservationWindow +join_retryCount +join_retryDelay +juke_air_accel +juke_air_enabled +juke_air_frictionMax +juke_air_frictionMin +juke_air_maxUpwardsVelocity +juke_air_speed +juke_air_upBoostAccel +juke_anim_offset +juke_blur_amount +juke_blur_enabled +juke_blur_radius_inner +juke_blur_radius_outer +juke_blur_time_in +juke_blur_time_out +juke_buttonup_jump +juke_buttonup_sprint +juke_clearance_check_dist +juke_clearance_check_radius +juke_cybercom +juke_debug +juke_debug_distance +juke_enabled +juke_forward_no_stick_input +juke_fx_enabled +juke_ms_for_deceleration +juke_ms_to_fullspeed +juke_player_trace_offset +juke_programmatic_animation +juke_rumble_enabled +juke_slide_enabled +juke_snap_angle_backward +juke_snap_angle_forward +juke_snap_angle_side +juke_speed +juke_sprintspeedratio +juke_stick_intensity_threshold +juke_time_ms +juke_wallrun_enabled +juke_weapon_angles_backward +juke_weapon_angles_forward +juke_weapon_angles_left +juke_weapon_angles_right +juke_weapon_side_movement +jump_height +jump_ladderPushVel +jump_max_velocity +jump_slowdownEnable +jump_spreadAdd +jump_stepSize +key_bindsDebug +keyarchiveWriteDelay +kick +kill +killOnlyTrailFX +killserver +ks_emp_ammowidget_maxRadiusMinStatic +ks_emp_ammowidget_maxStaticValue +ks_emp_ammowidget_minRadiusMaxStatic +ks_emp_ammowidget_minStaticValue +ks_emp_fullscreen_maxRadiusMinStatic +ks_emp_fullscreen_maxStaticValue +ks_emp_fullscreen_minRadiusMaxStatic +ks_emp_fullscreen_minStaticValue +ks_emp_minimap_maxRadiusMinStatic +ks_emp_minimap_maxStaticValue +ks_emp_minimap_minRadiusMaxStatic +ks_emp_minimap_minStaticValue +ks_emp_scorewidget_maxRadiusMinStatic +ks_emp_scorewidget_maxStaticValue +ks_emp_scorewidget_minRadiusMaxStatic +ks_emp_scorewidget_minStaticValue +laggedDamageTagThreshold +lagometer_pos +landing_crouchViewDip +language +laserAlpha +laserDebug +laserFadeADS +laserFlarePct +laserForceOn +laserKillImpactDelta +laserLightBeginOffset +laserLightBodyTweak +laserLightEndOffset +laserLightRadius +laserLightRadius_alt +laserLightRangePlayer +laserRadius +laserRadius_alt +lastStandSwayAccel +lastStandSwayMaxDrift +lastStandSwayMaxDriftVel +lastStand_cameraAlignmentEaseMode +lastStand_cameraPitchOffset +lastStand_cameraRotateTimeMs +launchGame +lbTaskDelay +leaveWithPartyEnabled +listallassets +listassetpool +listcustomgametypes +listdefaultassets +liveDedicatedOnly +liveDedicatedonly +liveNeverHostServer +liveNewsMaxCounters +liveSessionTaskTimeoutCreate +liveSessionTaskTimeoutDelete +liveSessionTaskTimeoutSearch +liveSessionTaskTimeoutUpdate +liveVoteErrorBackoff +liveVoteTaskDelay +live_CODPointCheckRequired +live_LPCFFOTDMode +live_allowDisconnectOnSignOut +live_anticheatBoostingPolicy +live_anticheatGlitchingPolicy +live_anticheatLootRecoveryPolicy +live_anticheatOffensiveBehaviorPolicy +live_anticheatOffensiveUGCPolicy +live_anticheatPeripheralsPolicy +live_anticheatPiracyPolicy +live_anticheatThirdPartyPolicy +live_anticheatUnlockableContentPolicy +live_autoEventEnabled +live_autoEventPumpDelay +live_autoEventPumpTime +live_connect_mode +live_connectionStatusChange_timeout +live_debugDailyChallengesDay +live_debugDailyChallengesHour +live_debugDailyChallengesMinute +live_dedicatedLookForPlatformPlaylists +live_disconnected_timeout +live_enableCounters +live_enableDailyChallengeUpdate +live_enableDailyChallengesDebugTimestamp +live_enablePolls +live_exchange_enable +live_exchange_enableErrorMessages +live_exchange_enableExchangeFailureTracking +live_exchange_enableTracking +live_exchange_processProductAttempts +live_exchange_processProductInterval +live_exchange_processProductIntervalMultiplier +live_experimentsEnabled +live_fakeReportConsoleFailure +live_featuredEnabled +live_friends_batch_size +live_friends_enabled +live_friends_features +live_friends_max +live_friends_sort +live_friends_unified +live_friends_update_interval +live_groups_min_task_callback_ms +live_inSyncDDLsRequired +live_leaderboardResetTime +live_leaderboardisRowEmptyCheck +live_motdEnabled +live_newsAddOwnNewsToTicker +live_presence_debug +live_presence_features +live_presence_incremental_fail_delay +live_presence_max_ms_between_updates +live_presence_min_ms_between_updates +live_presence_party +live_presence_platform +live_pubSemaphoreCheckIntervalSeconds +live_pubSemaphoreForceChange +live_pubSemaphoreJitterSeconds +live_pubSemaphoreUserTriggerTime +live_publishervariables_maxupdateattempts +live_readPublisherStorageLocally +live_readSplitFfotd +live_readUserStorageLocally +live_registrationEndURL +live_registrationEndURL_DEV +live_registrationEndURL_RETAIL +live_registrationStartURL +live_registrationStartURL_DEV +live_registrationStartURL_RETAIL +live_social_quickjoin +live_social_quickjoin_cache +live_social_quickjoin_count +live_statscaching +live_steam_server_client_checks_interval +live_steam_server_description +live_steam_server_name +live_steam_server_password +live_store_disable_lang +live_store_disable_region +live_store_enable +live_store_enable_inventory +live_store_entitlementcheck_enable +live_store_show_details +live_systemSurveyCaptureDelta +live_systemsurvey +live_testValue +live_timewarp +live_umbrella_maxUmbrellaLoginAttempts +live_useInGameRegistration +live_useLPC +live_usePublisherVariables +live_useUmbrella +live_useUno +live_username +live_whitelistFatal +livestats_checkNonPrimaryXUIDPS3 +livestats_giveCPXP +livestats_skipFirstTime +livestorage_fakeNoob +livestorage_waitOnContent +livestorage_waitOnContentTimeout +loadoutVersion +loadoutVersionCP +loadoutVersionMP +loadoutVersionZM +lobbyAdvertiseConfig +lobbyAdvertiseDirty +lobbyAdvertiseEmptySlots +lobbyAdvertiseGameType +lobbyAdvertiseGeo1 +lobbyAdvertiseGeo2 +lobbyAdvertiseGeo3 +lobbyAdvertiseGeo4 +lobbyAdvertiseIsEmpty +lobbyAdvertiseLatencyBand +lobbyAdvertiseMap +lobbyAdvertiseMapPacks +lobbyAdvertiseMaxPlayers +lobbyAdvertiseNetcodeVersion +lobbyAdvertiseNumPlayers +lobbyAdvertisePin +lobbyAdvertisePlaylistNumber +lobbyAdvertisePlaylistVersion +lobbyAdvertiseServerLocation +lobbyAdvertiseServerName +lobbyAdvertiseServerType +lobbyAdvertiseShowInMatchmaking +lobbyAdvertiseSkill +lobbyAdvertiseSkip +lobbyAdvertiseTeamSizeMax +lobbyCPTimerStartInterval +lobbyCPZMTimerStartInterval +lobbyDebugLogJoinSuccess +lobbyDebugLogJoins +lobbyDedicatedSearchSkip +lobbyLaunch_fadeToBlackDelay +lobbyLaunch_fadeToBlackDelayOnConnect +lobbyLaunch_gameLaunchDelay +lobbyLaunch_gameLaunchDelayOnConnect +lobbyLaunch_waitForClientAckDelay +lobbyMapVotePrevMapPlayCount +lobbyMergeDedicatedEnabled +lobbyMergeEnabled +lobbyMergeInterval +lobbyMigrate_Enabled +lobbyMigrate_EnabledLAN +lobbyMigrate_considerStreamingForHostMigration +lobbyMigrate_dedicatedOnly +lobbyMigrate_migrateToBestGameHostEnabled +lobbyProbedXuidOverride +lobbySearchBaseSkillRange +lobbySearchDatacenterType +lobbySearchDatacenterTypeGeo +lobbySearchDatacenterTypeOverride +lobbySearchDediUnparkPingLimit +lobbySearchDedicatedGeoMin +lobbySearchDelay +lobbySearchExperimentDatacenter +lobbySearchForceLocation +lobbySearchForceUnparkLobbySize +lobbySearchForceXuid +lobbySearchGameSecurityId +lobbySearchGeo1 +lobbySearchGeo1Weight +lobbySearchGeo2 +lobbySearchGeo2Weight +lobbySearchGeo3 +lobbySearchGeo3Weight +lobbySearchGeo4 +lobbySearchGeo4Weight +lobbySearchGeoMin +lobbySearchIsEmpty +lobbySearchMapPacks +lobbySearchMaxLatencyBandDiff +lobbySearchMinDediSearchClientAdd +lobbySearchMinDediSearchTime +lobbySearchNetcodeVersion +lobbySearchPingBand +lobbySearchPingBandEnabled +lobbySearchPingBandWeight1 +lobbySearchPingBandWeight2 +lobbySearchPingBandWeight3 +lobbySearchPingBandWeight4 +lobbySearchPingBandWeight5 +lobbySearchPlaylistNumber +lobbySearchPlaylistVersion +lobbySearchQueryId +lobbySearchServerLocation1 +lobbySearchServerLocation2 +lobbySearchServerLocation3 +lobbySearchServerLocation4 +lobbySearchServerLocation5 +lobbySearchServerType +lobbySearchShowInMatchmaking +lobbySearchSkill +lobbySearchSkillRangeMultiplier +lobbySearchSkillWeight +lobbySearchSkip +lobbySearchSkipDLCProbability +lobbySearchSkipUnparkProbability +lobbySearchTeamSize +lobbyTimerStartInterval +lobbyTimerStatusBeginInterval +lobbyTimerStatusPostGameInterval +lobbyTimerStatusStartInterval +lobbyTimerStatusVotingInterval +lobbyTimerStatusVotingInterval_Arena +lobbyTimerZMStartInterval +lobby_MatchmakingLoggingChance +lobby_MatchmakingLoggingLevel +lobby_ban +lobby_beginPlay +lobby_clientContentTimeout +lobby_clientEndCooloffTime +lobby_clientEndFakeSendLoss +lobby_clientLoadingIntoUICheck +lobby_clientTimeout +lobby_clientWarnTimeout +lobby_enableLoadoutDataStreamingInGame +lobby_enablePSDataStreamingInGame +lobby_enablePSDataStreamingInLobby +lobby_fillserverlist +lobby_forceLAN +lobby_forceOffline +lobby_hostBots +lobby_hostContentTimeout +lobby_hostIntervalHeartbeat +lobby_hostIntervalState +lobby_hostJoinRequestReject +lobby_hostPSFragmentRetryInterval +lobby_hostTimeout +lobby_ingamePSDataStreamingBW +lobby_kick +lobby_list +lobby_maxLocalPlayers +lobby_moveLobby +lobby_nextmap +lobby_ptptimeout +lobby_readyUpPercentRequired +lobby_setgametype +lobby_setmap +lobby_showSVDebug +lobby_unban +lobbymigrate_HostWaitMS +lobbymigrate_MaxBWPackets +lobbymigrate_MaxPacketWaitTime +lobbymigrate_MinScoreDiff +lobbymigrate_NomineeRecalcInterval +lobbymigrate_NomineeWaitMS +lobbymigrate_TestInterval +lobbymigrate_TestIntervalJitter +lobbymigrate_WirelessLatencyIncrease +lobbymigrate_useStdDev +lobbymsg_prints +lobbyvm_forceGC +loc_availableLanguages +loc_forceEnglish +loc_language +loc_languageSaved +loc_systemLanguage +loc_translate +loc_warnings +loc_warningsAsErrors +local_media_tier +log_append +log_filename +logfile +long_blocking_call +loot_bribeCrate_dwid +loot_burnBatchSize +loot_burnCommonRefund +loot_burnCooloff +loot_burnEpicRefund +loot_burnLegendaryRefund +loot_burnMinMegaRequired +loot_burnMinRareRequired +loot_burnMinUltraRequired +loot_burnRareRefund +loot_burnRefetchOnSuccess +loot_commonCrate_dwid +loot_cryptoCheckDelay +loot_cryptokeyCost +loot_cryptokeySku +loot_earnMax +loot_earnMin +loot_earnPlayThreshold +loot_earnTime +loot_emblems_max_count +loot_enabled +loot_experimentpromo_active +loot_fakeAll +loot_fakeItem +loot_fakeNoBonus +loot_fakeRarity +loot_missedIMChance +loot_mpItemVersions +loot_rareCrate_dwid +loot_recipe_distill_cost +loot_taskMaxAttempts +loot_taskWindow +loot_testAll +loot_testIndex +loot_winBonusPercent +loot_zmItemVersions +lootxp_bonus_multiplier +lootxp_multiplier +lowAmmoWarningPulseFreq +lowAmmoWarningPulseMax +lowAmmoWarningPulseMin +lpc_forceDownloadFiles +lpc_maxattempts +ls_demoauthor +ls_demoduration +ls_demotitle +ls_gametype +ls_maplocation +ls_mapname +ls_status +lua_systemTest +lunge_blur_amount +lunge_blur_enabled +lunge_blur_radius_inner +lunge_blur_radius_outer +lunge_blur_time_in +lunge_blur_time_out +lunge_debug +m_filter +m_forward +m_mouseAcceleration +m_mouseFilter +m_mouseSensitivity +m_pitch +m_side +m_yaw +magic_chest_movable +manifestfs +mantle_adjustment_mp +mantle_check_angle +mantle_check_glass_extra_range +mantle_check_radius +mantle_check_range +mantle_check_range_mp +mantle_debug +mantle_enable +mantle_enabled +mantle_view_yawcap +mantle_weapon_anim_height +mantle_weapon_height +map +map_restart +map_rotate +mapcrc +mapname +marketing_autorefresh +marketing_enabled +marketing_refreshTime +marketing_simulatefakemotd +marketing_waitTimeOnLogin +matchmaking_debug +maxAIGlassHits +maxAttachmentsPerWeapon +maxDailyZMDoubleXP +maxGlassShatters +maxLossesValue +maxMetPlayerListCount +maxShardSplit +maxSplitSizeRatio +maxStatsBackupInterval +maxVoicePacketsPerFrame +melee_allowQueuedMelee +melee_attachmentMultiplier +melee_cameraSway_enabled +melee_debug +melee_debug_fromBehind +melee_fromBehindDebug +melee_fromBehindMaxAngle +melee_fromBehindUseBonesForDirection +melee_maxAutoPitch +melee_maxAutoYaw +melee_victimCamSwayAngle +melee_victimCameraLerpTime +melee_victimEffectDuration +melee_victimMoveScale +melee_victimPitchSpeed +melee_victimTransScale +melee_victimYawSpeed +menuMapMaxRange +metPlayerInGameOnly +metPlayerListCleanupInterval +metPlayerListRemoveFriends +metPlayerListUpdateInterval +metPlayerListUploadInterval +metPlayerPlatformGamertag +metPlayerPlatformPresence +microwave_turret_placement_trace_maxs +microwave_turret_placement_trace_mins +microwave_turretplacement_traceOffset +migrating +migration_blocksperframe +migration_forceHost +migration_limit +migration_minclientcount +migration_msgtimeout +migration_soak +migration_timeBetween +minDelayForOtherPlayerStatsFetch +miniscoreboardhide +missileDebugAttractors +missileDebugDraw +missileDebugText +missileDroneAccelClimb +missileDroneAccelDescend +missileDroneClimbAngleDirect +missileDroneClimbAngleTop +missileDroneClimbCeilingDirect +missileDroneClimbCeilingTop +missileDroneClimbHeightDirect +missileDroneClimbHeightTop +missileDroneClimbMaxDist +missileDroneClimbToOwner +missileDroneDistSqTargetAvoidanceDisabled +missileDroneDistanceAvoidance +missileDroneDistanceAvoidanceSec +missileDroneSpeedLimitClimb +missileDroneSpeedLimitDescend +missileDroneSpeedMin +missileDroneTurnDecel +missileDroneTurnMaxRate +missileDroneTurnMaxRoll +missileDroneTurnMaxRollChange +missileDroneTurnRateAscent +missileDroneTurnRateAvoidance +missileDroneTurnRateDecent +missileDroneTurnRateSmallAdjustments +missileDroneflattenRollRatio +missileHellfireMaxSlope +missileHellfireUpAccel +missileJavAccelClimb +missileJavAccelDescend +missileJavClimbAngleDirect +missileJavClimbAngleTop +missileJavClimbCeilingDirect +missileJavClimbCeilingTop +missileJavClimbHeightDirect +missileJavClimbHeightTop +missileJavClimbToOwner +missileJavSpeedLimitClimb +missileJavSpeedLimitDescend +missileJavTurnDecel +missileJavTurnRateDirect +missileJavTurnRateTop +missileMolotovBlobNum +missileMolotovBlobTime +missilePlantableSize +missileSoftLaunchSpeedScale +missileTVGuidedBoost +missileTVGuidedBoostSpeedDown +missileTVGuidedBoostSpeedUp +missileTVGuidedFlatteningRollAccel +missileTVGuidedMPSpecific +missileTVGuidedMaxRollAngle +missileTVGuidedStickDeadzone +missileTVGuidedTurnRate +missileTVGuidedTurningRollAccel +missingCommandWillError +mlg_active_stream_query_interval +mlg_audio_volume +mlg_client_id +mlg_config_query_interval +mlg_enable +mlg_google_analythics_id +mlg_google_analythics_perc +mlg_google_analythics_url +mlg_inactive_stream_query_interval +mlg_league +mlg_metadata_title_entry +mlg_min_islive_interval +mlg_mixpanel_token +mlg_mixpanel_url +mlg_platform_name +mlg_show_hidden +mm_KeyframeMeterDebug +mm_KeyframeUsageDebug +mm_KeyframeUsageReset +mm_animation_driven_movement +mm_debug +mm_debugKeyframe +mm_doLegYawOffset +mm_enable +mm_inputSet +mm_keyframeInterval +mm_keyframeMeterIsClient +mm_keyframeMeter_clientNum +mm_keyframeMeter_pos +mm_keyframeUsageAnimIndex +mm_keyframeUsage_pos +mm_optimizations +mm_simulateClientPmoves +modPrvAnimDumpInTime +modPrvAnimDumpOutTime +modPrvCurrAndMaxFrameIndexes +modPrvUseAnimDump +mods_DisableStats +mods_SavePlayerBindingsToMod +mods_enabled +modvar +mortarStrikesLeft +motdDelay +motd_enabled +mp_blackjack_consumable_wait +mp_prototype +msg_dumpEnts +msg_hudelemspew +msg_logPredictionPositionErrors +msg_printEntityNums +msg_zlibCompress +msg_zlibCompressOutput +n +name +narrowShardRatio +neo_PTELimit +net_broadcast +net_broadcast_ip +net_debug_server_time_error +net_emu_client +net_emu_jitter +net_emu_latency +net_emu_packet_loss +net_emu_server +net_ip +net_logSnapshotTiming +net_minigraph +net_noudp +net_port +net_profile +net_showprofile +net_socksEnabled +net_socksPassword +net_socksPort +net_socksServer +net_socksUsername +netchan_ackInterval +netchan_debugSpew +netchan_debugSpewChan +netchan_doSwap +netchan_drawGraph +netchan_dropFragChance +netchan_emergencyFreePercent +netchan_fakeLoad +netchan_firstAckWait +netchan_jqprofEnabled +netchan_jqprofThreshold +netchan_logToFile +netchan_mainThreadWaitMs +netchan_msgLifeTime +netchan_nackWaitMs +netchan_statsResetInterval +netfieldchk +netstats_dummy_tracker_data +nextarena +nextmap +noCheapSpawns +noDW +noai +noclip +notarget +nv_textureReleaseFrameDelay +nv_textureReleaseMaxPerFrame +oldShotgunSpread +onlinegame +onlykick +oob_damage_interval_ms +oob_damage_per_interval +oob_max_distance_before_black +oob_time_remaining_before_black +oob_timekeep_ms +oob_timelimit_ms +orbisGame +orbis_PTELimit +orbis_authBypass +orbis_checkpsn_interval +orbis_checkpsplus_interval +orbislive_reduceCheckNetConnection +p +packetDebug +paintjobVersion +partyChatDisallowed +partyMigrate_NomineeRecalcInterval +partyMigrate_TestInterval +partyMigrate_maxBWPackets +partyPrivacyCheckInterval +partyPrivacyEnabled +partyPrivacyPumpEnabled +party_autoteams +party_debug +party_debugMembers +party_maxplayers +party_minplayers +party_reliableMigrate +password +path_alwaysFindNearestNode +path_boundsFudge +path_checkDangerousNodes +path_double_wide_checks +path_minzBias +pc_newversionavailable +pcache_privacy +pclive_updateFriends +penetrationCount +penetrationCount_allies +penetrationCount_axis +perk_armorPiercing +perk_armorVest +perk_armorpiercing +perk_blackbirdShowsGpsJammer +perk_bulletDamage +perk_bulletPenetrationMultiplier +perk_damageKickReduction +perk_deathStreakCountRequired +perk_delayExplosiveTime +perk_directionalfire_clipped_show_direction +perk_disarmExplosiveTime +perk_dogsAttackGhost +perk_extraBreath +perk_fastLadderClimbMultiplier +perk_fireproof +perk_flakJacket +perk_flakJacket_hardcore +perk_gpsjammer_alpha +perk_gpsjammer_fade_time +perk_gpsjammer_graceperiods +perk_gpsjammer_min_distance +perk_gpsjammer_min_speed +perk_gpsjammer_time_period +perk_grenadeDeath +perk_grenadeTossBackTimer +perk_healthRegenMultiplier +perk_interactSpeedMultiplier +perk_killstreakAnteUpResetValue +perk_killstreakDeathPenaltyMultiplier +perk_killstreakMomentumMultiplier +perk_killstreakReduction +perk_mantleReduction +perk_marksmanEnemyNameFadeIn +perk_marksmanEnemyNameFadeOut +perk_nottargetedbyai_graceperiod +perk_nottargetedbyai_min_speed +perk_requireScavengerPerk +perk_scavenger_clip_multiplier +perk_scavenger_lethal_proc +perk_scavenger_tactical_proc +perk_sgjammer_alpha +perk_sgjammer_fade_time +perk_sgjammer_graceperiods +perk_sgjammer_min_distance +perk_sgjammer_min_speed +perk_sgjammer_time_period +perk_shellShockReduction +perk_spawn_ping_duration_ms +perk_speedMultiplier +perk_sprintFireRecoveryMultiplier +perk_sprintMultiplier +perk_sprintMultiplierExtra +perk_sprintRecoveryMultiplier +perk_throwbackInnerRadius +perk_tracker_fx_fly_height +perk_tracker_fx_foot_height +perk_weapAdsMultiplier +perk_weapEquipmentUseMultiplier +perk_weapMeleeMultiplier +perk_weapRateMultiplier +perk_weapReloadMultiplier +perk_weapSpreadMultiplier +perk_weapSwitchMultiplier +perk_weapTossMultiplier +phys_ai_collision_mode +phys_bulletSpinScale +phys_bulletUpBias +phys_buoyancy +phys_buoyancyDistanceCutoff +phys_buoyancyFastComputation +phys_buoyancyFloatHeightOffset +phys_buoyancyRippleFrequency +phys_buoyancyRippleVariance +phys_debugBigQueries +phys_debugCallback +phys_debugDangerousRigidBodies +phys_debugExceededGjkPrims +phys_debugExpensivePushout +phys_disableEntsAndDynEntsCollision +phys_dragAngular +phys_dragLinear +phys_drawCollisionObj +phys_drawConstraints +phys_drawNitrousVehicle +phys_drawNitrousVehicleEffects +phys_drawNitrousVehicleEngine +phys_drawcontacts +phys_entityCollision +phys_floatTimeVariance +phys_fluid +phys_gravity +phys_gravity_dir +phys_impact_distance_cutoff +phys_impact_fx +phys_impact_intensity_limit +phys_impact_max_pfx_per_frame +phys_impact_max_sfx_per_frame +phys_impact_render +phys_impact_silence_window +phys_maxFloatTime +phys_msecStep +phys_piecesSpawnDistanceCutoff +phys_player_collision_adjust_height +phys_player_collision_mode +phys_player_step_on_actors +phys_player_step_on_actors_zm +phys_ragdoll_buoyancy +phys_ragdoll_joint_damp_scale +phys_reeval_frequency +phys_usePhysicsForLocalClientIfPossible +phys_userRigidBodies +phys_vehicleDamageFroceScale +phys_vehicleFriction +phys_vehicleGravityMultiplier +phys_vehicleWheelEntityCollision +phys_verbose +phys_waterDragAngular +phys_waterDragLinear +phys_wind_debug +phys_wind_distance_cutoff +phys_wind_enabled +phys_wind_force_direction +phys_wind_force_speed +phys_wind_vehicle_scale +pickShards +pickupPrints +pitchAccelerationTime +pitchDecelerationThreshold +platformSessionDebugInfo +platformSessionEnabled +platformSessionImg +platformSessionImgPath +platformSessionInviteMessage +platformSessionLaunchInviteJoinProcessDelay +platformSessionName +platformSessionOrbisCreateTimeout +platformSessionOrbisGetInviteInfoTimeout +platformSessionOrbisGetSessionInfoTimeout +platformSessionOrbisImg +platformSessionOrbisImgPath +platformSessionOrbisInviteMessage +platformSessionOrbisInviteTimeout +platformSessionOrbisJoinTimeout +platformSessionOrbisLeaveTimeout +platformSessionOrbisLockFlag +platformSessionOrbisMigrationFlag +platformSessionOrbisName +platformSessionOrbisSearchTimeout +platformSessionOrbisSessionTypeFlag +platformSessionOrbisStatus +platformSessionOrbisUpdateTimeout +platformSessionPartyPrivacy +platformSessionShowErrorCodes +platformSessionStatus +platformSessionUpdateIntervalOrbis +platformSessionsOrbis +platformSessionsOrbisPlayTogetherEnabled +playedWithUpdateInterval +playerCount +playerEnenergy_enabled +playerEnergy_EMPAffectsBoost +playerEnergy_EMPDrain +playerEnergy_boostUpRate +playerEnergy_boostUpRate_emp +playerEnergy_boostUpRate_fast +playerEnergy_doubleJumpCostRatio +playerEnergy_enabled +playerEnergy_jukeCostRatio +playerEnergy_jukeEnergyEnabled +playerEnergy_maxReserve +playerEnergy_minReserve +playerEnergy_rechargeDuringSprint +playerEnergy_restRate +playerEnergy_restRate_emp +playerEnergy_restRate_fast +playerEnergy_restRate_sprint +playerEnergy_restRate_sprintEmp +playerEnergy_restRate_sprintFast +playerEnergy_slideCostRatio +playerEnergy_slideCostRatio_emp +playerEnergy_slideEnergyEnabled +playerEnergy_slowRechargeDuringSprint +playerEnergy_sprintEnergyEnabled +playerEnergy_sprintRate +playerEnergy_sprintRate_emp +playerEnergy_sprintRate_fast +playerEnergy_sprintRechargeDelayMs +playerEnergy_wallRunDelayMs +playerEnergy_wallRunEnergyEnabled +playerEnergy_wallRunRate +playerJetEnergy_boostDownRate +playerJetEnergy_boostUpRate +playerJetEnergy_deployCost +playerJetEnergy_enabled +playerJetEnergy_hoverRate +playerJetEnergy_maxReserve +playerJetEnergy_minReserve +playerJetEnergy_restRate +playerJet_accel +playerJet_downBoostAccel +playerJet_enabled +playerJet_frictionMax +playerJet_frictionMin +playerJet_fx_a +playerJet_fx_b +playerJet_fx_c +playerJet_fx_d +playerJet_hoverAccel +playerJet_initHeight +playerJet_preHoverAccel +playerJet_speed +playerJet_tag_left_back +playerJet_tag_left_front +playerJet_tag_right_back +playerJet_tag_right_front +playerJet_upBoostAccel +playerJet_upSaveBoostAccel +playerPushAmount +playerSounds_rotationAngleThresholdLoop +playerSounds_rotationAngleThresholdStep +playerWeaponRaisePostIGC +player_AimBlend_Back_Low +player_AimBlend_Back_Mid +player_AimBlend_Back_Up +player_AimBlend_Head +player_AimBlend_Neck +player_AimBlend_Pelvis +player_MGUseRadius +player_ProneLaststandFreeMove +player_ProneMinPitchDiff +player_ZVelocityThresholdThirdPerson +player_ZVelocityThreshold_fast +player_ZVelocityThreshold_med +player_ZVelocityThreshold_rapid +player_ZVelocityThreshold_slow +player_adsExitDelay +player_animRunThreshhold +player_animWalkThreshhold +player_armPulseEnabled +player_backSpeedScale +player_bodylights +player_bodylightsCorpseFadeTime +player_bodylightshdr +player_breath_fire_delay +player_breath_gasp_lerp +player_breath_gasp_scale +player_breath_gasp_time +player_breath_hold_lerp +player_breath_hold_time +player_breath_snd_delay +player_breath_snd_lerp +player_chestWaterFrictionScale +player_clipSizeMultiplier +player_deathInvulnerableTime +player_debug +player_debugHeadOffset +player_debugHeadOffsetTolerance +player_debugHealth +player_debugSprint +player_deepWaterWadeScale +player_disableUnderwaterVisionset +player_disableWeaponsInWater +player_disableWeaponsOnVehicle +player_dmgtimer_flinchTime +player_dmgtimer_maxTime +player_dmgtimer_minScale +player_dmgtimer_stumbleTime +player_dmgtimer_timePerPoint +player_dpad_gadget_scheme +player_enableShuffleAnims +player_enduranceSpeedScale +player_fallImpact_camImpact_enabled +player_fallImpact_camLateralTranslateScale +player_fallImpact_camSwingDuration +player_fallImpact_camUpTranslateScale +player_fallImpact_rumble_enabled +player_fallImpact_shake_base_scale +player_fallImpact_shake_duration +player_fallImpact_shake_enabled +player_fallImpact_viewMovementPitch +player_fallImpact_viewMovementRoll +player_fallImpact_viewMovementYaw +player_fallWindZVelocityThreshold +player_fallWindZVelocityThresholdThirdPerson +player_fall_rumble_enabled +player_firstPersonDeaths +player_floatSpeed +player_footstepsThreshhold +player_forceGibs +player_forceRedCrosshair +player_idleToMoveAnimSpeed +player_knockbackMoveThreshhold +player_lastStandBleedoutTime +player_lastStandBleedoutTimeNoRevive +player_lastStandCrawlTransition +player_lastStandDistScale +player_lastStandHealthOverlayTime +player_lastStandSuicideDelay +player_lean_rotate +player_lean_rotate_crouch +player_lean_shift +player_lean_shift_crouch +player_lens_enabled +player_lookAtEntityAllowChildren +player_meleeChargeCancelOnVictimDeath +player_meleeChargeFriction +player_meleeChargeHeightTolerance +player_meleeChargeMaxSpeed +player_meleeChargeMinSpeed +player_meleeHeight +player_meleeHeightChargeAir +player_meleeIdealEndDistance +player_meleeInterruptFrac +player_meleeLungeAcceleration +player_meleeLungeDamageScalar +player_meleeLungeDeviationCutoff +player_meleeLungeSpeedCutoff +player_meleeLungeTimeCutoff +player_meleeLungeUnderwaterSpeedScale +player_meleeRangeChargeAirDefault +player_meleeRangeChargeDefault +player_meleeRangeDefault +player_meleeWidth +player_meleeWidthChargeAir +player_moveSoundThresholdAccel +player_moveSoundThresholdDecel +player_moveSoundThresholdRatio +player_moveThreshhold +player_move_factor_on_torso +player_name +player_revivePlayerListCycleTime +player_reviveTriggerRadius +player_runThreshhold +player_runbkThreshhold +player_scopeExitOnDamage +player_shallowWaterFrictionScale +player_shallowWaterHeightRatio +player_shallowWaterWadeScale +player_slick_accel +player_slick_invspeed +player_slick_wishspeed +player_sliding_friction +player_sliding_velocity_cap +player_sliding_wishspeed +player_slopeAnimAngle +player_spectateSpeedScale +player_sprintCameraBob +player_sprintFallAnim +player_sprintForwardMinimum +player_sprintJumpAnimRate +player_sprintJumpDropWeaponScaler +player_sprintMinTime +player_sprintRechargePause +player_sprintSpeedScale +player_sprintStrafeSpeedScale +player_sprintTime +player_sprintUnlimited +player_standingViewHeight +player_strafeAnimCosAngle +player_strafeSpeedScale +player_sustainAmmo +player_swimAcceleration +player_swimAllowGrenades +player_swimAnimMinSpeed +player_swimCombatOutADSStopAnimRatio +player_swimDamage +player_swimDamagerInterval +player_swimFallOffAngle +player_swimFocalLength +player_swimFootstepWaterDuration +player_swimForwardAnimCatchupMax +player_swimForwardAnimCatchupMin +player_swimForwardMinAngle +player_swimForwardMinSpeed +player_swimForwardSettleTime +player_swimForwardWarmupTime +player_swimFrictionHigh +player_swimFrictionLow +player_swimFrictionVerticalThreshold +player_swimHeightRatio +player_swimLensEnabled +player_swimLensInTransRate +player_swimMaxMovePitchWhileTreading +player_swimMaxSprintPitchWhileTreading +player_swimMaxZ +player_swimMovementShellshockScale +player_swimMovingAnimSpeed +player_swimMovingStopAnimRatio +player_swimSpeed +player_swimSpeedupIdleAnimMinSpeed +player_swimSprintAnimSpeed +player_swimSprintFocalLength +player_swimSprintLensEnabled +player_swimSprintLensInTransRate +player_swimSprintSpeedScale +player_swimSprintStopAnimRatio +player_swimSurfaceSmoothingDepth +player_swimSurfaceSmoothingScalar +player_swimTime +player_swimUnderwaterHeightRatio +player_swimVerticalAcceleration +player_swimVerticalSpeedMax +player_swimViewHeight +player_swimWaterPlaneDistance +player_swimallowshooting +player_swimallowshootingmoving +player_swimcantraverse +player_swimforcesurface +player_swimming_control_scheme +player_swimming_enabled +player_t7MeleeDeathFromAboveRange +player_throwbackInnerRadius +player_throwbackOuterRadius +player_tmodeSightEnabled +player_topDownCursorDist +player_topDownCursorPos +player_turnAnims +player_turnRateScale +player_underwaterWalkJumpHeight +player_underwaterWalkSpeedScale +player_underwaterWalkSprint +player_underwatercantraverse +player_useRadius +player_useRadius_zm +player_useSlopeAnims +player_useTouchScore +player_useWaterFriction +player_useWaterWadeScale +player_viewLockEnt +player_viewRateScale +player_view_pitch_down +player_view_pitch_up +player_view_swim_pitch_down +player_view_swim_pitch_up +player_waistWaterFrictionScale +player_waistWaterWadeScale +player_waterSpeedScale +player_waterWadeScaleUnderwater +player_zombieMeleeHeight +player_zombieMeleeRange +player_zombieMeleeWidth +player_zombieSpeedScale +player_zombieSprintSpeedScale +playgo_profiling +playgo_refreshinterval +playlist_allowdevmaps +playlist_autoEvent +playlist_autoEventsEnabled +playlist_autoevent +playlist_debug +playlist_excludeGametype +playlist_excludeGametypeMap +playlist_excludeMap +playlist_forceEvent +playlist_linearMapCycle +playlist_linearMapCycleRandom +popInLetterFXTime +printCACValidationErrors +printCACValidationSuccesses +printentities +probation_league_dashboardScalar +probation_league_enabled +probation_league_forgiveCount +probation_league_kickScalar +probation_league_kickcalar +probation_league_matchHistoryWindow +probation_league_probationThreshold +probation_league_probationTime +probation_league_quitScalar +probation_league_timeoutScalar +probation_league_warningThreshold +probation_public_enabled +probation_public_forgiveCount +probation_public_kickScalar +probation_public_matchHistoryWindow +probation_public_probationThreshold +probation_public_probationTime +probation_public_quitScalar +probation_public_timeoutScalar +probation_public_warningThreshold +probation_version +prof_disableGameplayGfx +prof_gameplayGfx +prof_selectCameraPosition +prof_selectCameraPositionTeleport +profileDirtyInterval +profileDwUpdateInterval +profileGetInterval +profile_reset +profile_show_loading +prone_bipod_enable +prone_crawlLoopTime +protocol +ps3Game +ps4_swapcirclex +purchasedClassSetCount +qosLocklessQueue +qosMaxAllowedPing +qosPreferredPing +qos_echo_chance +qos_firstUpdateMS +qos_lastUpdateMS +qos_maxProbeWait +qos_minEchoServers +qos_minPercent +qos_minProbes +qos_packetLossPercent +qos_simulateLongQoS +qport +queue_actions_enabled +quit +quit_on_error +r_DFE +r_EOTF1886 +r_EOTFLb +r_EOTFLw +r_EOTFgamma +r_FilmIsoMax +r_FilmIsoMin +r_FilmIsoNoise +r_FilmIsoNoiseEnable +r_LensAbbe +r_LensDistortionGL +r_LensDistortionK1 +r_LensDistortionK2 +r_LensDistortionK3 +r_LensDistortionKS +r_LensOpticalLength +r_MaterialParameterTweak +r_OIT +r_OIT_Debug +r_OIT_MaxEntries +r_POMLODEnd +r_POMLODStart +r_PurkinjeHue +r_PurkinjeMax +r_PurkinjeMin +r_ST2084 +r_ST2084debug +r_ST2084debugWipe +r_ST2084debugWipeWhite +r_ST2084debugWipeWhiteMeasure +r_aaAllowTemporalMultiGpu +r_aaTechnique +r_aberrationFX_enable +r_activeLensID +r_actorShadowCount +r_actorShadowFade +r_addLightWorker +r_adsBloomDownsample +r_adsWorldFocalDistanceMax +r_adsWorldFocalDistanceMin +r_adsWorldFocalDistanceTrackBackScale +r_alphaMap +r_anaglyphFX_enable +r_applyOIT +r_asyncCompute +r_atmosphere_densityM +r_atmosphere_densityR +r_atmosphere_enable +r_atmosphere_groundLevel +r_atmosphere_scatterG +r_atmosphereextinctionstrength +r_atmospherefogcolor +r_atmospherefogdensity +r_atmospherehazebasedist +r_atmospherehazecolor +r_atmospherehazedensity +r_atmospherehazefadedist +r_atmospherehazespread +r_atmosphereinscatterstrength +r_atmospherepbramount +r_atmospheresunstrength +r_autoLodCullRadius +r_autoLodScale +r_autoResolutionControllerIdle +r_autoResolutionScale +r_autoResolutionThreshold +r_autoResolutionTune +r_autoResolutionUIThreshold +r_autoResolutionUITune +r_backBufferCount +r_backendSwapBuffersAssistRelease +r_bc7CompressAsync +r_blinkCullNone +r_blinkForwardSSS +r_blinkGbuffer +r_blinkGbufferDecal +r_blinkGbufferEnt +r_blinkGbufferViewmodel +r_blinkGbufferViewmodelDecal +r_blinkGbufferVolDecal +r_blinkOIT +r_blinkTrans +r_bloomEnable +r_bloomUseLutALT +r_blur +r_blurAndTintEnable +r_blurAndTintLevel +r_brushLimit +r_cachedSpotShadowCopyMode +r_cameraInfo +r_catsEyeAberation +r_catsEyeBlur +r_catsEyeBlurTint +r_catsEyeDecolor +r_catsEyeDistortion +r_catsEyeFX_enable +r_catsEyeNoise +r_catsEyeReset +r_catsEyeTexture +r_chaserFX_enable +r_chkbDiffWeight +r_chkbMode +r_chkbSameWeight +r_chkbTexLodBias +r_circleMaskRadius +r_classifyAsync +r_clear +r_clearAllGBuffers +r_clearColor +r_clearColor2 +r_clearView +r_clothPrimaryTint +r_clothSecondaryTint +r_cmdbuf_worker +r_cmdlistChain +r_codeImageDrawDebug +r_codeImageDrawDebugInfo +r_codeImageDrawImage +r_codeImageDrawImageSize +r_colorMap +r_computeSpritesAsync +r_convergence +r_createLutAsync +r_cubicUpsampleParam +r_cullLightsAsync +r_cullLightsAsyncHighPriority +r_currentMonitor +r_deadOps +r_deadOpsActive +r_debugDisableLocalProbes +r_debugImage +r_debugImageAdvanced +r_debugImageInfo +r_debugMaterial +r_debugMetalStorm +r_debugModel +r_debugShowCoronas +r_debugShowDynamicLights +r_debugShowLightBoundsSelect +r_debugShowPrimaryLights +r_debugShowProbeBlends +r_debugShowProbes +r_debugShowProbesBoundsSelect +r_dedicatedPlayerShadow +r_dedicatedPlayerShadowCull +r_dedicatedPlayerShadowCullAngle +r_dedicatedPlayerSpotOmniShadowResolution +r_dedicatedPlayerSunShadowPenumbraScale +r_dedicatedPlayerSunShadowResolution +r_dedicatedShadowsUmbra +r_deferredBilateralUpsampleSSAO +r_deferredBlurBacklit +r_deferredCullLights +r_deferredDebugDrawAttenuationVolumes +r_deferredDrawPrimaries +r_deferredDrawPrimaryIndex +r_deferredDrawPrimaryOmnis +r_deferredDrawPrimarySpots +r_deferredDrawProbeIndex +r_deferredDrawProbes +r_deferredDrawSceneLights +r_deferredEnableAO +r_deferredForceShadowNeverUpdate +r_deferredIgnoreShadowUpdate +r_deferredMaxVisibleLights +r_deferredMaxVisibleProbes +r_deferredPermuteShowClassification +r_deferredPermuteTiles +r_deferredPermuteTilesSwizzle +r_deferredSSTOptims +r_deferredShowAO +r_deferredShowInfo +r_deferredShowSunVis +r_deferredUseAttenuationVolumes +r_deferredViewmodel +r_depthPrime +r_diffuseProbeDebug +r_disableGenericFilter +r_dobjLimit +r_dofFocusPeaking +r_dofMode +r_dofQuality +r_dofTweak +r_dof_aperture_override +r_dof_enable +r_dof_farBlur +r_dof_farEnd +r_dof_farStart +r_dof_max_override +r_dof_min_override +r_dof_nearBlur +r_dof_nearEnd +r_dof_nearStart +r_dof_showdebug +r_dof_tweak +r_dof_viewModelEnd +r_dof_viewModelStart +r_drawBModels +r_drawBsp +r_drawDebugFogParams +r_drawDynEnts +r_drawFrameDurationGraph +r_drawFxOnProbes +r_drawInfo +r_drawModelsGobo +r_drawPlayersInDynamicProbe +r_drawPrimCap +r_drawPrimFloor +r_drawPrimHistogram +r_drawSModels +r_drawSceneEnts +r_drawSceneModels +r_drawSun +r_drawTerrain +r_drawWorld +r_drawXModels +r_dualPlayEnable +r_dumpRenderTargetFormats +r_dynamicProbeDebugColors +r_dynamicProbeInitBounceCount +r_dynamicProbePrefilter +r_dynamicSceneResolution +r_dynamicSceneResolutionMode +r_eacPathFX_enable +r_eacPath_Posn +r_eacPath_Radius +r_eacPath_Step +r_emulateSlowOrHitchyPresent +r_enableCubicUpsample +r_enableGlassDpvs +r_enableOccluders +r_enablePlayerShadow +r_enableVolDecals +r_ev_distance +r_ev_edgethickness +r_ev_edgewidth +r_ev_geometryrange +r_ev_random_edge +r_ev_random_ground +r_ev_rate +r_ev_screen_scale +r_ev_screen_threshold +r_ev_targetrange +r_ev_targetwidth +r_ev_testenable +r_ev_width +r_expAWB +r_expAuto +r_expCmp +r_expMax +r_expMin +r_expSigma +r_expSigmaAlpha +r_expSigmaBeta +r_expSigmaMax +r_expSigmaMin +r_expandInstancesToDrawIndirect +r_exposureAdaptation +r_exposureAdaptationTweak +r_exposureAsync +r_exposureEyeWeight +r_exposureTweak +r_exposureValue +r_extracamDisable +r_extracam_add_debug_cam +r_extracam_add_debug_cam_width +r_extracam_custom_aspectratio +r_extracam_remove_debug_cam +r_extracam_show_axis +r_extracam_show_render_targets +r_farClip +r_filmLut +r_filmTweakEnable +r_filmTweakLut +r_filmUseTweaks +r_finalShiftX +r_finalShiftY +r_flameFX_FPS +r_flameFX_distortionScaleFactor +r_flameFX_enable +r_flameFX_fadeDuration +r_flameFX_magnitude +r_flameScaler +r_flame_allowed +r_fog +r_fogBaseDist +r_fogBaseHeight +r_fogColor +r_fogHalfDist +r_fogHalfHeight +r_fogIntensity +r_fogOpacity +r_fogSkyHalfHeightOffset +r_fogSunColor +r_fogSunInner +r_fogSunIntensity +r_fogSunOpacity +r_fogSunOuter +r_fogSunPitchOffset +r_fogSunYawOffset +r_fogTweak +r_fog_disable +r_fontResolution +r_font_cache_debug_display +r_forceAdapter +r_forceGbufferVertexOnly +r_forceLod +r_forceMaxTextureSize +r_forceMonitorTV +r_forceTextureAniso +r_forcedModelLods +r_foveaAcuityColorMax +r_foveaAcuityColorMin +r_foveaAcuityVisualMax +r_foveaAcuityVisualMin +r_framesyncThreshold +r_fullHDRrendering +r_fullbright +r_fullscreen +r_fuzzSceneWidth +r_fxShadows +r_fx_backlighting_amount +r_fxaaContrastThreshold +r_fxaaDebug +r_fxaaSubpixelRemoval +r_gbufferDepthSort +r_gbufferDepthSortStaticModels +r_gbufferOccluderMinSize +r_gbufferShowContent +r_genericFilter_enable +r_genericSceneVector0 +r_genericSceneVector1 +r_genericSceneVector2 +r_genericSceneVector3 +r_genericSceneVector_debug +r_glossMap +r_gpuCullingDebugShowDepth +r_gpuCullingDisableDepthTest +r_gpuCullingUseGpuResultForPrimaryLight +r_gpuCullingUseLateDepth +r_gpuCullingUseWorker +r_gpuFrameHistogram +r_gpuTimers +r_graphicContentBlur +r_grassEnable +r_heatPulseFX_enable +r_hotZone_angle1 +r_hotZone_angle2 +r_hotZone_fadedn +r_hotZone_fadeup +r_hotZone_heightlim +r_hotZone_radius1 +r_hotZone_radius2 +r_hotZone_zgradiant +r_hybridPreferDeferred +r_ignore +r_ignorehwgamma +r_instancedVolumeDecals +r_jqprof_capture +r_lateAllocLimit +r_lensAbberation +r_lensApertureAngle +r_lensApertureBlade +r_lensFlaresDebug +r_lightPickerFreeze +r_lightingDebugOverlay +r_lightingDebugOverlayAlpha +r_lightingDebugOverlayScale +r_lightingEnableAggressiveShadowEviction +r_lightingOmniShadowForceSize +r_lightingOmniShadowPenumbraOverride +r_lightingReflectionProbeMipDrop +r_lightingShadowFiltering +r_lightingSpotOmniShadowMaxQuality +r_lightingSpotShadowDropSizeDistance +r_lightingSpotShadowForceSize +r_lightingSpotShadowPenumbraOverride +r_lightingSunShadowCacheDynamicSiegeDistance +r_lightingSunShadowCacheEnable +r_lightingSunShadowCacheEnableUmbra +r_lightingSunShadowCacheEnableUnusedTracking +r_lightingSunShadowCacheForceOff +r_lightingSunShadowCullingToggle +r_lightingSunShadowDebugDrawAABBs +r_lightingSunShadowDisableDynamicDraw +r_lightingSunShadowDobjMovementTracking +r_lightingSunShadowDynamicSplitCount +r_lightingSunShadowDynentMovementTracking +r_lightingSunShadowEnableAsync +r_lightingSunShadowForceSSTOnly +r_lightingSunShadowPenumbraOverride +r_lightingSunShadowSSTMipDrop +r_lightingSunShadowSkipSplits +r_lightingSunShadowSplitScreenEmulate +r_litfog_bank_select +r_litfog_max_visible_volume_count +r_litfog_volume_count +r_litfog_volume_start +r_lockFrameRateTo30Hz +r_lockFrameRateTo30Hz_dynResOff +r_lockFrameRateTo30Hz_enable +r_lockFrameRateTo30Hz_force +r_lockPvs +r_lockPvsInCode +r_lodBiasRigid +r_lodScaleRigid +r_lodThresholdPixelArea +r_lodUseDynamicResolution +r_lowResolutionMode +r_makeDark_enable +r_marksDebugWorldbrushNormal +r_materialLab +r_materialXYZ +r_maxPOMSamples +r_maxSpotShadowUpdates +r_mode +r_modelLimit +r_modelLodBias +r_modelLodLimit +r_modelSkelWorker +r_monitor +r_monitorCalibrate +r_monitorCount +r_monitorTV +r_motionBlurEnable +r_motionBlurMode +r_motionBlurQuality +r_motionBlurStrength +r_motionVectorDebugDisplay +r_motionVectorGenerateEnable +r_motionVectorStaticComputeAsync +r_motionVectorStaticWithMB +r_newLensFlares +r_newLensFlares_offscreen_buffer_size +r_newLensFlares_show_outlines +r_newLensFlares_show_sources +r_norefresh +r_normalMap +r_num_viewports +r_objSpaceViewModelDObj +r_occQueryDebug +r_occlusionMap +r_oit +r_omniShadowRes +r_p4x_capture +r_paperWhite +r_pbgBank +r_pbgFogBank +r_pbrfog_enable +r_picmip +r_pix_material +r_pix_sortkey +r_pixelShaderGPRReallocation +r_poisonFX_blurMax +r_poisonFX_blurMin +r_poisonFX_debug_amount +r_poisonFX_debug_enable +r_poisonFX_dvisionA +r_poisonFX_dvisionX +r_poisonFX_dvisionY +r_poisonFX_pulse +r_poisonFX_warpX +r_poisonFX_warpY +r_polygonOffsetBiasInt +r_polygonOffsetClamp +r_polygonOffsetScale +r_polygonOffsetTweakEnable +r_portalOccluderTest +r_postFxIndex +r_postFxKeylineFrontEnd +r_postFxSubIndex +r_postFxUseTweaks +r_postFxWobble +r_previousFullscreen +r_primaryLightTweakDiffuseStrength +r_primaryLightTweakSpecularStrength +r_primaryLightUseTweaks +r_qrcode_debug_display +r_qrcode_debug_display_size +r_radioactiveBlur +r_radioactiveFX_enable +r_radioactiveIntensity +r_radioactiveSpeed +r_refreshRate +r_removeSystemReservation +r_rendertarget_debug_display +r_resetLightingDebug +r_resolveMethod +r_reviveFX_debug +r_reviveFX_edgeAmount +r_reviveFX_edgeColorTemp +r_reviveFX_edgeContrast +r_reviveFX_edgeMaskAdjust +r_reviveFX_edgeOffset +r_reviveFX_edgeSaturation +r_reviveFX_edgeScale +r_saveDefaultRenderImages +r_scaleViewport +r_sceneGamma +r_sceneResolution +r_sceneResolutionMultiplier +r_shaderDebug +r_shader_constant_set_debug_range +r_shader_constant_set_enable +r_showBModelNamesDist +r_showBounds +r_showCollision +r_showCollisionDepthTest +r_showCollisionDist +r_showCollisionGroups +r_showCollisionPolyType +r_showCullBModels +r_showCullDistDebug +r_showCullSModels +r_showCullXModels +r_showCullXmodelsEntNum +r_showDObjModelNamesDist +r_showDuplicateRenderInfoDist +r_showDynEntModelNames +r_showEntModelNamesDist +r_showExposureZones +r_showForceNoCull +r_showImpactVolDecalDebug +r_showLodInfo +r_showLodInfoMaxDistance +r_showModelNamesPlacement +r_showOccluders +r_showOverdraw +r_showOverdrawAlpha +r_showOverdrawMax +r_showOverdrawNumLayers +r_showPBRCheck +r_showPenetration +r_showSModelNames +r_showSiegeDObjModleNames +r_showSiegeModelNames +r_showSunDirectionDebug +r_showSurfCounts +r_showTextureOverrideInfo +r_showTriCounts +r_showTriDensity +r_showTris +r_showVertCounts +r_showWorldVolDecalDebug +r_siege_debug_scale +r_siege_info +r_siege_notetrack_debug +r_skipDrawTris +r_skipPvs +r_skipXModelZeroSizedBones +r_skyBoxColorIDX +r_skyRotation +r_skyTransition +r_smaa +r_smaaCompute +r_smaaHighQuality +r_smaaQuincunx +r_smodel_combineWorkers +r_smodel_partialSortWorkers +r_smodel_splitWorkers +r_smp_backend +r_smp_worker_threads +r_sortBackToFront +r_sortDrawSurfsBsp +r_sortDrawSurfsStaticModel +r_sortTrans +r_specularGlossMap +r_specularMap +r_speedBlurAmount +r_speedBlurFX_enable +r_splitScreenExpandFull +r_splitscreenBlurEdges +r_spotLightEntityShadows +r_spotLightSModelShadows +r_spotLightShadows +r_spotMeter +r_spotShadowRes +r_ssaoAsync +r_ssaoCompareRefTechnique +r_ssaoEnable +r_ssaoRefTechnique +r_ssaoShowDebug +r_ssaoTechnique +r_ssao_gtaoHigh +r_ssao_gtaoLow +r_ssao_gtaoMid +r_ssao_gtaoStrength +r_ssao_gtaoTweak +r_ssao_hbaoFalloff +r_ssao_hbaoIntensity +r_ssao_hbaoNormalScale +r_ssao_hbaoRadius +r_ssao_hbaoSharpness +r_ssao_hbaoTanAngleBias +r_ssao_hdaoAcceptAngle +r_ssao_hdaoAcceptRadius +r_ssao_hdaoIntensity +r_ssao_hdaoNormalScale +r_ssao_hdaoRadius +r_ssao_hdaoRejectRadius +r_ssao_hdaoSharpness +r_ssao_hemiAOBlurTolerance +r_ssao_hemiAOCombineBeforeBlur +r_ssao_hemiAOCombineResWithMul +r_ssao_hemiAOHierarchyDepth +r_ssao_hemiAONoiseFilterTolerance +r_ssao_hemiAOQuality +r_ssao_hemiAORejectionFalloff +r_ssao_hemiAOSensitivity +r_ssao_hemiAOUpsampleTolerance +r_ssao_ohaoIntensity +r_ssao_ohaoRadius +r_ssao_ohaoSharpness +r_ssao_s1aoDepthScale +r_ssao_s1aoGapFalloff +r_ssao_s1aoGradiantFalloff +r_ssao_s1aoIntensity +r_ssao_s1aoRadius +r_ssao_s1aoSharpness +r_ssao_saoBias +r_ssao_saoEpsilon +r_ssao_saoIntensity +r_ssao_saoRadius +r_ssao_saoSharpness +r_ssao_saov2Bias +r_ssao_saov2Falloff +r_ssao_saov2Intensity +r_ssao_saov2Radius +r_ssao_saov2Sharpness +r_ssao_t7aoFalloff +r_ssao_t7aoIntensity +r_ssao_t7aoRadius +r_ssao_t7aoSelfOcclusion +r_ssao_t7aoSharpness +r_ssao_voaoFalloff +r_ssao_voaoIntensity +r_ssao_voaoRadius +r_ssao_voaoSharpness +r_ssao_voaoThickness +r_sssblurEnable +r_stereo3DAvailable +r_stereo3DEyeSeparation +r_stereo3DEyeSeparationScaler +r_stereo3DMode +r_stereo3DOn +r_stereo3DRightEyeReuseLeftEyeShadows +r_stereoFocusDepth +r_stereoGunShift +r_stereoTurretShift +r_stream +r_streamCheckAabb +r_streamClear +r_streamDistanceMax +r_streamDumpCurrentUsage +r_streamDumpDistance +r_streamDumpImageUsage +r_streamDumpInitial +r_streamDumpSortedImageList +r_streamFreezeState +r_streamHiddenPush +r_streamHidePlayer +r_streamHighPriorityThreshold +r_streamLowDetail +r_streamPaintDiffuse +r_streamProfile +r_streamReadLog +r_streamReflectionProbes +r_streamRemoveHimips +r_streamShowHints +r_streamShowLoadingMaterial +r_streamShowReadSpeeds +r_streamShowVolumes +r_streamTextureMemoryMax +r_streamTouchLookahead +r_submitDoneThreshold +r_sunColor +r_sunFilterInches +r_sunFlareTint +r_sunPitch +r_sunShadowSplitDistance +r_sunStops +r_sunTweak +r_tacScanFX_enable +r_tacScan_Eps +r_tacScan_FadeEnd +r_tacScan_FadeStart +r_tacScan_HotZone +r_tacScan_Layout +r_tacScan_Paths +r_tacScan_Popups +r_tacScan_Scale +r_tacScan_Traces +r_takeScreenShot +r_texFilterQuality +r_textureMipLodBias +r_textureMode +r_tilingHighlight +r_tilingLightCount +r_tilingProbeCount +r_tilingSunShadow +r_tmodeServerActive +r_triDensityPointAlpha +r_triDensityPointOnSmallTris +r_triDensityPointOnTriCenter +r_triDensityPointOnVerts +r_triDensityPointSize +r_triDensityScalePointAlpha +r_triDensityScalePointSize +r_triDensityShowOriginalGeo +r_triDensitySmallTriArea +r_uberResolveAsync +r_uhdMode +r_ui3d_debug_display +r_ui3d_h +r_ui3d_use_debug_values +r_ui3d_w +r_ui3d_x +r_ui3d_y +r_uiHudFX_enable +r_umbraAccurateOcclusionThreshold +r_umbraAllowDatabaseThread +r_umbraDisableForScene +r_umbraDisableForSceneZeroUmbraWork +r_umbraDisableForSpotOmniShadow +r_umbraDistanceScale +r_umbraDrawDebug +r_umbraEnable +r_umbraEnableDebugDisplay +r_umbraEnableParameterVolumes +r_umbraFilter +r_umbraGridHeight +r_umbraGridWidth +r_umbraLightVis +r_umbraMinRelativeContribution +r_umbraNearDistance +r_umbraQueryLocalLights +r_umbraTomeTriggerDebug +r_umbraVerbose +r_umrbaEnableParameterVolumes +r_underwaterAbsorptionRGB +r_underwaterHalfDistance +r_underwaterOutputMix +r_underwaterTweak +r_updateDynamicProbes +r_updateSingleDynamicProbe +r_updateSingleDynamicProbeFace +r_useBindlessMaterialKeyMerge +r_useBindlessTechnique +r_useCachedSpotShadow +r_useDynamicProbeTextures +r_useHidePartbits +r_useLensFov +r_useSimpleDObj +r_useStrict30HzConditions +r_validateCommandBuffers +r_vid_align +r_videoMode +r_viewModelSpotOmniShadowResolution +r_viewModelSunShadowResolution +r_viewmodelSelfShadow +r_viewportBackingColor +r_volumetric_lighting_blur_depth_threshold +r_volumetric_lighting_buffers_size_ratio +r_volumetric_lighting_density_scaler +r_volumetric_lighting_enable_probes +r_volumetric_lighting_enable_spot +r_volumetric_lighting_enable_sun +r_volumetric_lighting_enable_tweaks +r_volumetric_lighting_enabled +r_volumetric_lighting_fog_base_distance +r_volumetric_lighting_fog_base_height +r_volumetric_lighting_fog_half_distance +r_volumetric_lighting_fog_half_height +r_volumetric_lighting_force +r_volumetric_lighting_half_res_apply +r_volumetric_lighting_lights_skip_samples +r_volumetric_lighting_max_lit_omni_spot_fog_distance +r_volumetric_lighting_max_lit_sun_fog_distance +r_volumetric_lighting_max_spot_samples +r_volumetric_lighting_max_sun_samples +r_volumetric_lighting_mode +r_volumetric_lighting_phase_distribution +r_volumetric_lighting_probe_contribution_scaler +r_volumetric_lighting_scattering_albedo +r_volumetric_lighting_sun_intensity_scale +r_volumetric_lighting_sun_skip_samples +r_volumetric_lighting_sun_step_size +r_volumetric_lighting_uber_depth_resolve_enabled +r_volumetric_lighting_upsample_depth_threshold +r_vsync +r_vsync_tear_window_enable +r_vsync_tear_window_lower +r_vsync_tear_window_upper +r_warningRepeatDelay +r_waterFogTest +r_waterSheetingFX_allowed +r_waterSheetingFX_distortionScaleFactor +r_waterSheetingFX_enable +r_waterSheetingFX_magnitude +r_waterSheetingFX_radius +r_watersim_enabled +r_waveWaterActors +r_waveWaterDebugDraw +r_waveWaterDrawOnlyLevel +r_waveWaterFreeze +r_waveWaterGeneratorTweakIndex +r_waveWaterHeightOverride +r_waveWaterHeightOverrideEnable +r_waveWaterPoke +r_waveWaterPokeSize +r_waveWaterPrint +r_waveWaterTweakEnable +r_waveWaterZero +r_worldfogskysize +r_xanim_disableCosmeticBones +r_xanim_disableExtraChannel +r_xanim_drawBones +r_xcamsEnabled +r_xdebug +r_zfar +r_znear_depthhack +r_zombieNameAllowDevList +r_zombieNameAllowFriendsList +r_zombiesShooterSpotted +radius_damage_debug +ragdoll_activationVelocitySq +ragdoll_baselerp_time +ragdoll_bullet_force +ragdoll_bullet_upbias +ragdoll_debug +ragdoll_dump_anims +ragdoll_enable +ragdoll_explode_force +ragdoll_explode_upbias +ragdoll_fps +ragdoll_gravityScale +ragdoll_jitter_scale +ragdoll_jointlerp_time +ragdoll_max_life +ragdoll_max_simulating +ragdoll_musclePowerScale +ragdoll_reactivation_cutoff +ragdoll_rotvel_scale +ragdoll_self_collision_scale +rare_crate_bundle_id +rat_hostdir +rat_instanceid +rat_playback_enabled +rat_testid +rate +rb_drawCullWorkerDebugText +rb_drawSonarDebugText +rcon +rcon_password +reconnect +recordPointsSpent +recorder_bufferSize +recorder_channelAccuracy +recorder_channelAiCode +recorder_channelAiProfile +recorder_channelAlex +recorder_channelAnimation +recorder_channelAnimscript +recorder_channelCover +recorder_channelGrenades +recorder_channelMessaging +recorder_channelNone +recorder_channelPathFind +recorder_channelPerception +recorder_channelPhysics +recorder_channelScript +recorder_channelScriptedAnim +recorder_channelSpawning +recorder_channelSuppression +recorder_channelThreat +recorder_debugMemory +recorder_enableRec +recorder_recordAllVehicles +recorder_streamDObjects +recorder_stringScaleBase +recorder_textScale +recorder_textScaleDistBase +recorder_textScaleDistMax +redactionDisplayTime +redactionFadeDuration +redactionStartStrokeTime +redactionStrokeTime +reliableResendTime +reliableTimeoutTime +remote_missile_boost_acceleration +remote_missile_boost_shake_duration +remote_missile_boost_shake_radius +remote_missile_boost_shake_scale +remote_missile_boost_speed +remote_missile_brake_deceleration +remote_missile_brake_shake_duration +remote_missile_brake_shake_radius +remote_missile_brake_shake_scale +remote_missile_brake_speed +remote_missile_coast_speed +remote_missile_speed +render_actor_collision +render_bpi_env_collision +render_fake_ents +render_player_collision +render_script_movers +reportUserInterval +restrict_attachment +restrict_item +retail_incentive_id +reviveWidgetClampedScale +reviveWidgetEndDistance +reviveWidgetEndScale +reviveWidgetOffset +reviveWidgetRevivingScale +reviveWidgetStartDistance +reviveWidgetStartScale +revive_time_taken +revive_trigger_radius +riotshield_assist_time +riotshield_bullet_damage_scale +riotshield_damage_score_max +riotshield_damage_score_threshold +riotshield_debug +riotshield_deploy_limit_radius +riotshield_deploy_pitch_max +riotshield_deploy_roll_max +riotshield_deploy_zdiff_max +riotshield_deployed_health +riotshield_destroyed_cleanup_time +riotshield_explosive_damage_scale +riotshield_melee_damage_scale +riotshield_placement_foffset +riotshield_placement_maxs +riotshield_projectile_damage_scale +rootMotion_debugMode +s +safeArea_horizontal +safeArea_vertical +saveLocalMatchRecordBinaryFile +saved_gameskill +say +say_team +scene_debug_player +scene_hide_player +scrFatalScriptErrors +scrShowStrUsage +scrShowVarUseage +scrVmEnableScripts +scr_RequiredMapAspectratio +scr_airsupportHeightScale +scr_allies +scr_allow_killstreak_building +scr_axis +scr_codPointsCap +scr_codpointsmatchscale +scr_codpointsperchallenge +scr_codpointsxpscale +scr_coop_friendlyFireDelayTime +scr_coop_hud_showobjicons +scr_coop_score_accolade_infection_score +scr_coop_score_assist_amws_25 +scr_coop_score_assist_amws_50 +scr_coop_score_assist_amws_75 +scr_coop_score_assist_aqu_quadtank_25 +scr_coop_score_assist_aqu_quadtank_50 +scr_coop_score_assist_aqu_quadtank_75 +scr_coop_score_assist_aqu_vtol_25 +scr_coop_score_assist_aqu_vtol_50 +scr_coop_score_assist_aqu_vtol_75 +scr_coop_score_assist_assault_25 +scr_coop_score_assist_assault_50 +scr_coop_score_assist_assault_75 +scr_coop_score_assist_concussion +scr_coop_score_assist_cqb_25 +scr_coop_score_assist_cqb_50 +scr_coop_score_assist_cqb_75 +scr_coop_score_assist_dannyli_25 +scr_coop_score_assist_dannyli_50 +scr_coop_score_assist_dannyli_75 +scr_coop_score_assist_depth_charge_25 +scr_coop_score_assist_depth_charge_50 +scr_coop_score_assist_depth_charge_75 +scr_coop_score_assist_direwolf_25 +scr_coop_score_assist_direwolf_50 +scr_coop_score_assist_direwolf_75 +scr_coop_score_assist_emp +scr_coop_score_assist_flash +scr_coop_score_assist_gomin_25 +scr_coop_score_assist_gomin_50 +scr_coop_score_assist_gomin_75 +scr_coop_score_assist_goxiulan_25 +scr_coop_score_assist_goxiulan_50 +scr_coop_score_assist_goxiulan_75 +scr_coop_score_assist_hunter_25 +scr_coop_score_assist_hunter_50 +scr_coop_score_assist_hunter_75 +scr_coop_score_assist_lotus_gunship_25 +scr_coop_score_assist_lotus_gunship_50 +scr_coop_score_assist_lotus_gunship_75 +scr_coop_score_assist_macv_25 +scr_coop_score_assist_macv_50 +scr_coop_score_assist_macv_75 +scr_coop_score_assist_pamws_25 +scr_coop_score_assist_pamws_50 +scr_coop_score_assist_pamws_75 +scr_coop_score_assist_parasite_25 +scr_coop_score_assist_parasite_50 +scr_coop_score_assist_parasite_75 +scr_coop_score_assist_prologue_robot_25 +scr_coop_score_assist_prologue_robot_50 +scr_coop_score_assist_prologue_robot_75 +scr_coop_score_assist_prologue_vtol_25 +scr_coop_score_assist_prologue_vtol_50 +scr_coop_score_assist_prologue_vtol_75 +scr_coop_score_assist_proximity +scr_coop_score_assist_quadtank_25 +scr_coop_score_assist_quadtank_50 +scr_coop_score_assist_quadtank_75 +scr_coop_score_assist_raps_25 +scr_coop_score_assist_raps_50 +scr_coop_score_assist_raps_75 +scr_coop_score_assist_robotcqb_25 +scr_coop_score_assist_robotcqb_50 +scr_coop_score_assist_robotcqb_75 +scr_coop_score_assist_robotdemo_25 +scr_coop_score_assist_robotdemo_50 +scr_coop_score_assist_robotdemo_75 +scr_coop_score_assist_robotrocketeer_25 +scr_coop_score_assist_robotrocketeer_50 +scr_coop_score_assist_robotrocketeer_75 +scr_coop_score_assist_robotsapper_25 +scr_coop_score_assist_robotsapper_50 +scr_coop_score_assist_robotsapper_75 +scr_coop_score_assist_robotsniper_25 +scr_coop_score_assist_robotsniper_50 +scr_coop_score_assist_robotsniper_75 +scr_coop_score_assist_robotsoldier_25 +scr_coop_score_assist_robotsoldier_50 +scr_coop_score_assist_robotsoldier_75 +scr_coop_score_assist_robotsuppressor_25 +scr_coop_score_assist_robotsuppressor_50 +scr_coop_score_assist_robotsuppressor_75 +scr_coop_score_assist_rocketeer_25 +scr_coop_score_assist_rocketeer_50 +scr_coop_score_assist_rocketeer_75 +scr_coop_score_assist_siegebot_25 +scr_coop_score_assist_siegebot_50 +scr_coop_score_assist_siegebot_75 +scr_coop_score_assist_sniper_25 +scr_coop_score_assist_sniper_50 +scr_coop_score_assist_sniper_75 +scr_coop_score_assist_suppressor_25 +scr_coop_score_assist_suppressor_50 +scr_coop_score_assist_suppressor_75 +scr_coop_score_assist_technical_25 +scr_coop_score_assist_technical_50 +scr_coop_score_assist_technical_75 +scr_coop_score_assist_theia_25 +scr_coop_score_assist_theia_50 +scr_coop_score_assist_theia_75 +scr_coop_score_assist_tiger_tank_25 +scr_coop_score_assist_tiger_tank_50 +scr_coop_score_assist_tiger_tank_75 +scr_coop_score_assist_turret_25 +scr_coop_score_assist_turret_50 +scr_coop_score_assist_turret_75 +scr_coop_score_assist_vtol_25 +scr_coop_score_assist_vtol_50 +scr_coop_score_assist_vtol_75 +scr_coop_score_assist_warlord_25 +scr_coop_score_assist_warlord_50 +scr_coop_score_assist_warlord_75 +scr_coop_score_assist_wasp_25 +scr_coop_score_assist_wasp_50 +scr_coop_score_assist_wasp_75 +scr_coop_score_assist_zombie_25 +scr_coop_score_assist_zombie_50 +scr_coop_score_assist_zombie_75 +scr_coop_score_award_accolade +scr_coop_score_award_calling_card +scr_coop_score_complete_mission_hardened +scr_coop_score_complete_mission_heroic +scr_coop_score_complete_mission_recruit +scr_coop_score_complete_mission_regular +scr_coop_score_complete_mission_veteran +scr_coop_score_completed_match +scr_coop_score_completed_training_sim_rating +scr_coop_score_death +scr_coop_score_debug_give_score +scr_coop_score_kill_amws +scr_coop_score_kill_aqu_quadtank +scr_coop_score_kill_aqu_vtol +scr_coop_score_kill_assault +scr_coop_score_kill_cqb +scr_coop_score_kill_dannyli +scr_coop_score_kill_depth_charge +scr_coop_score_kill_direwolf +scr_coop_score_kill_gomin +scr_coop_score_kill_goxiulan +scr_coop_score_kill_hunter +scr_coop_score_kill_lotus_gunship +scr_coop_score_kill_macv +scr_coop_score_kill_meatball +scr_coop_score_kill_pamws +scr_coop_score_kill_parasite +scr_coop_score_kill_prologue_robot +scr_coop_score_kill_prologue_vtol +scr_coop_score_kill_quadtank +scr_coop_score_kill_raps +scr_coop_score_kill_robotcqb +scr_coop_score_kill_robotdemo +scr_coop_score_kill_robotrocketeer +scr_coop_score_kill_robotsapper +scr_coop_score_kill_robotsniper +scr_coop_score_kill_robotsoldier +scr_coop_score_kill_robotsuppressor +scr_coop_score_kill_rocketeer +scr_coop_score_kill_siegebot +scr_coop_score_kill_sniper +scr_coop_score_kill_spider +scr_coop_score_kill_suppressor +scr_coop_score_kill_technical +scr_coop_score_kill_theia +scr_coop_score_kill_tiger_tank +scr_coop_score_kill_turret +scr_coop_score_kill_vtol +scr_coop_score_kill_warlord +scr_coop_score_kill_wasp +scr_coop_score_kill_zombie +scr_coop_score_killnone +scr_coop_score_melee_kill_amws +scr_coop_score_melee_kill_aqu_quadtank +scr_coop_score_melee_kill_aqu_vtol +scr_coop_score_melee_kill_assault +scr_coop_score_melee_kill_cqb +scr_coop_score_melee_kill_dannyli +scr_coop_score_melee_kill_depth_charge +scr_coop_score_melee_kill_direwolf +scr_coop_score_melee_kill_gomin +scr_coop_score_melee_kill_goxiulan +scr_coop_score_melee_kill_hunter +scr_coop_score_melee_kill_lotus_gunship +scr_coop_score_melee_kill_macv +scr_coop_score_melee_kill_meatball +scr_coop_score_melee_kill_pamws +scr_coop_score_melee_kill_parasite +scr_coop_score_melee_kill_prologue_robot +scr_coop_score_melee_kill_prologue_vtol +scr_coop_score_melee_kill_quadtank +scr_coop_score_melee_kill_raps +scr_coop_score_melee_kill_robotcqb +scr_coop_score_melee_kill_robotdemo +scr_coop_score_melee_kill_robotrocketeer +scr_coop_score_melee_kill_robotsapper +scr_coop_score_melee_kill_robotsniper +scr_coop_score_melee_kill_robotsoldier +scr_coop_score_melee_kill_robotsuppressor +scr_coop_score_melee_kill_rocketeer +scr_coop_score_melee_kill_siegebot +scr_coop_score_melee_kill_sniper +scr_coop_score_melee_kill_suppressor +scr_coop_score_melee_kill_technical +scr_coop_score_melee_kill_theia +scr_coop_score_melee_kill_tiger_tank +scr_coop_score_melee_kill_turret +scr_coop_score_melee_kill_vtol +scr_coop_score_melee_kill_warlord +scr_coop_score_melee_kill_wasp +scr_coop_score_melee_kill_zombie +scr_coop_score_multikill_2 +scr_coop_score_multikill_3 +scr_coop_score_multikill_4 +scr_coop_score_multikill_5 +scr_coop_score_multikill_6 +scr_coop_score_multikill_7 +scr_coop_score_multikill_8 +scr_coop_score_multikill_more_than_8 +scr_coop_score_picked_up_collectible +scr_coop_score_player_did_revived +scr_coop_score_scavenger_assist +scr_coop_score_scavenger_pickup +scr_coop_score_scavenger_streak +scr_coop_score_shield_blocked_damage +scr_coop_score_shield_blocked_damage_reduced +scr_coop_score_suicide +scr_coop_weapon_allowbetty +scr_coop_weapon_allowflash +scr_coop_weapon_allowfrag +scr_coop_weapon_allowrpgs +scr_coop_weapon_allowsatchel +scr_coop_weapon_allowsmoke +scr_csmode +scr_custom_score_assist +scr_debug_heat_wave_traces +scr_debug_leaks +scr_deleteexplosivesonspawn +scr_dirt_enable_explosion +scr_dirt_enable_fall_damage +scr_dirt_enable_gravity_spikes +scr_dirt_enable_slide +scr_disableChallenges +scr_disableSetDStat +scr_disableStatTracking +scr_disable_air_death_ragdoll +scr_disable_team_selection +scr_disable_weapondrop +scr_disableunifiedspawning +scr_drawfriend +scr_dynamic_source_loading +scr_emergency_reserve_timer +scr_emergency_reserve_timer_upgraded +scr_fireflyPartialMovePercent +scr_fireflyPodActivationTime +scr_fireflyPodDetectionRadius +scr_fireflyPodGracePeriod +scr_firefly_attack_attack_speed_scale +scr_firefly_collision_check_interval +scr_firefly_debug +scr_firefly_emit_time +scr_firefly_min_speed +scr_firefly_pod_timeout +scr_firstGumFree +scr_free +scr_game_arcadescoring +scr_game_difficulty +scr_game_friendlyFireDelay +scr_game_medalsenabled +scr_game_pinups +scr_game_rankenabled +scr_gunxpscale +scr_gunxpscaleCP +scr_gunxpscaleMP +scr_gunxpscaleZM +scr_gunxpscalecp +scr_gunxpscalemp +scr_gunxpscalezm +scr_hardcore +scr_hardpoint_allowauto_turret +scr_hardpoint_allowcounteruav +scr_hardpoint_allowdogs +scr_hardpoint_allowhelicopter_comlink +scr_hardpoint_allowradar +scr_hardpoint_allowradardirection +scr_hardpoint_allowrcbomb +scr_hardpoint_allowuav +scr_health_debug +scr_heli_armor +scr_heli_armor_bulletdamage +scr_heli_armored_maxhealth +scr_heli_attract_range +scr_heli_attract_strength +scr_heli_debug +scr_heli_debug_crash +scr_heli_dest_wait +scr_heli_health_degrade +scr_heli_loopmax +scr_heli_maxhealth +scr_heli_missile_friendlycare +scr_heli_missile_max +scr_heli_missile_range +scr_heli_missile_regen_time +scr_heli_missile_reload_time +scr_heli_missile_rof +scr_heli_missile_target_cone +scr_heli_missile_valid_target_cone +scr_heli_protect_pos_time +scr_heli_protect_radius +scr_heli_protect_time +scr_heli_target_recognition +scr_heli_target_spawnprotection +scr_heli_targeting_delay +scr_heli_turretClipSize +scr_heli_turretReloadTime +scr_heli_turret_angle_tan +scr_heli_turret_spinup_delay +scr_heli_turret_target_cone +scr_heli_visual_range +scr_heli_warning_distance +scr_helicopterTurretMaxAngle +scr_hostmigrationtest +scr_incendiaryDamageRadius +scr_incendiaryfireDamage +scr_incendiaryfireDamageHardcore +scr_incendiaryfireDamageTickTime +scr_incendiaryfireDuration +scr_incendiaryfxDuration +scr_killcam +scr_lightningGunKillcamDecelPercent +scr_lightningGunKillcamOffset +scr_lightningGunKillcamTime +scr_mapsize +scr_max_rank +scr_max_simLocks +scr_maxinventory_scorestreaks +scr_min_prestige +scr_minimap_height +scr_missileDudDeleteDelay +scr_mod_enable_devblock +scr_motd +scr_no_checkpoints +scr_numLives +scr_oldschool +scr_playerInvulTimeScale +scr_player_allowrevive +scr_player_sprinttime +scr_proximityChainBoltSpeed +scr_proximityChainDebug +scr_proximityChainGracePeriod +scr_proximityGrenadeActivationTime +scr_proximityGrenadeDOTDamageAmount +scr_proximityGrenadeDOTDamageAmountHardcore +scr_proximityGrenadeDOTDamageInstances +scr_proximityGrenadeDOTDamageTime +scr_proximityGrenadeDetectionRadius +scr_proximityGrenadeDuration +scr_proximityGrenadeGracePeriod +scr_proximityGrenadeProtectedTime +scr_rampagebonusscale +scr_rankXpCap +scr_requiredMapAspectRatio +scr_satchel_detonation_delay +scr_scorestreaks +scr_scorestreaks_maxstacking +scr_selecting_location +scr_showperksonspawn +scr_sideBetTimer +scr_sitrepscan1_enable +scr_sitrepscan1_setdesat +scr_sitrepscan1_setfalloff +scr_sitrepscan1_setlinewidth +scr_sitrepscan1_setoutline +scr_sitrepscan1_setradius +scr_sitrepscan1_setsolid +scr_sitrepscan2_enable +scr_sitrepscan2_setdesat +scr_sitrepscan2_setfalloff +scr_sitrepscan2_setlinewidth +scr_sitrepscan2_setoutline +scr_sitrepscan2_setradius +scr_sitrepscan2_setsolid +scr_skip_devblock +scr_spawn_enemyavoiddist +scr_spawn_enemyavoidweight +scr_spawn_force_unified +scr_tdm_friendlyFireDelayTime +scr_tdm_killstreak_allowcounteruav +scr_tdm_killstreak_allowradar +scr_tdm_killstreak_allowradardirection +scr_tdm_score_aircraft_destruction_assist_25 +scr_tdm_score_aircraft_destruction_assist_50 +scr_tdm_score_aircraft_destruction_assist_75 +scr_tdm_score_aircraft_flare_assist +scr_tdm_score_aitank_kill +scr_tdm_score_annihilator_kill +scr_tdm_score_annihilator_multikill +scr_tdm_score_annihilator_multikill_2 +scr_tdm_score_annihilator_stolen +scr_tdm_score_armblades_kill +scr_tdm_score_armblades_multikill +scr_tdm_score_armblades_multikill_2 +scr_tdm_score_armblades_stolen +scr_tdm_score_assist_25 +scr_tdm_score_assist_50 +scr_tdm_score_assist_75 +scr_tdm_score_assist_concussion +scr_tdm_score_assist_emp +scr_tdm_score_assist_flash +scr_tdm_score_assist_proximity +scr_tdm_score_assisted_suicide +scr_tdm_score_backstabber_kill +scr_tdm_score_ball_capture_assist +scr_tdm_score_ball_capture_carry +scr_tdm_score_ball_capture_throw +scr_tdm_score_ball_intercept +scr_tdm_score_bomb_detonated +scr_tdm_score_bounce_hatchet_kill +scr_tdm_score_bowlauncher_kill +scr_tdm_score_bowlauncher_multikill +scr_tdm_score_bowlauncher_multikill_2 +scr_tdm_score_bowlauncher_stolen +scr_tdm_score_c4_multikill +scr_tdm_score_capture_enemy_crate +scr_tdm_score_clean_assist_collect +scr_tdm_score_clean_enemy_collect +scr_tdm_score_clean_enemy_deposit +scr_tdm_score_clean_friendly_collect +scr_tdm_score_clean_kill_enemy_carrying_tacos +scr_tdm_score_clean_multi_deny_tacos +scr_tdm_score_clean_multi_deposit_big +scr_tdm_score_clean_multi_deposit_normal +scr_tdm_score_clean_own_collect +scr_tdm_score_cleanse_kill +scr_tdm_score_clear_2_attackers +scr_tdm_score_combat_efficiency_bonus_1 +scr_tdm_score_combat_efficiency_bonus_2 +scr_tdm_score_combat_efficiency_bonus_3 +scr_tdm_score_combat_robot_kill +scr_tdm_score_comeback_from_deathstreak +scr_tdm_score_completed_match +scr_tdm_score_counter_uav_assist +scr_tdm_score_dart_kill +scr_tdm_score_death +scr_tdm_score_defend_flag_carrier +scr_tdm_score_defend_hq_last_man_alive +scr_tdm_score_defused_bomb +scr_tdm_score_defused_bomb_last_man_alive +scr_tdm_score_destroyed_aitank +scr_tdm_score_destroyed_bouncingbetty +scr_tdm_score_destroyed_c4 +scr_tdm_score_destroyed_claymore +scr_tdm_score_destroyed_combat_robot +scr_tdm_score_destroyed_counter_uav +scr_tdm_score_destroyed_dart +scr_tdm_score_destroyed_drone_strike +scr_tdm_score_destroyed_emp +scr_tdm_score_destroyed_fireflyhive +scr_tdm_score_destroyed_helicopter_agr_drop +scr_tdm_score_destroyed_helicopter_comlink +scr_tdm_score_destroyed_helicopter_giunit_drop +scr_tdm_score_destroyed_helicopter_supply_drop +scr_tdm_score_destroyed_heliopter_giunit_drop +scr_tdm_score_destroyed_hover_rcxd +scr_tdm_score_destroyed_microwave_turret +scr_tdm_score_destroyed_motion_sensor +scr_tdm_score_destroyed_plane_mortar +scr_tdm_score_destroyed_proxy +scr_tdm_score_destroyed_raps_deployship +scr_tdm_score_destroyed_remote_missile +scr_tdm_score_destroyed_rolling_thunder_all_drones +scr_tdm_score_destroyed_rolling_thunder_drone +scr_tdm_score_destroyed_satellite +scr_tdm_score_destroyed_sentinel +scr_tdm_score_destroyed_sentry_gun +scr_tdm_score_destroyed_shield +scr_tdm_score_destroyed_siegebot +scr_tdm_score_destroyed_siegebot_assist +scr_tdm_score_destroyed_tac_insert +scr_tdm_score_destroyed_trophy_system +scr_tdm_score_destroyed_uav +scr_tdm_score_destroyed_vtol_mothership +scr_tdm_score_disabled_robot +scr_tdm_score_disarm_hacked_care_package +scr_tdm_score_dom_point_neutral_b_secured +scr_tdm_score_dom_point_neutral_secured +scr_tdm_score_dom_point_neutralized_neutralizing +scr_tdm_score_dom_point_secured +scr_tdm_score_dom_point_secured_neutralizing +scr_tdm_score_downed_player +scr_tdm_score_drone_strike_kill +scr_tdm_score_electrified +scr_tdm_score_eliminate_oic +scr_tdm_score_elimination_and_last_player_alive +scr_tdm_score_emp_assist +scr_tdm_score_end_enemy_armblades_attack +scr_tdm_score_end_enemy_gravity_spike_attack +scr_tdm_score_end_enemy_psychosis +scr_tdm_score_end_enemy_specialist_weapon +scr_tdm_score_escort_robot_disable +scr_tdm_score_escort_robot_disable_assist_25 +scr_tdm_score_escort_robot_disable_assist_50 +scr_tdm_score_escort_robot_disable_near_goal +scr_tdm_score_escort_robot_escort +scr_tdm_score_escort_robot_escort_goal +scr_tdm_score_escort_robot_reboot +scr_tdm_score_final_kill_elimination +scr_tdm_score_first_kill +scr_tdm_score_flag_capture +scr_tdm_score_flag_carrier_kill_return_close +scr_tdm_score_flag_grab +scr_tdm_score_flag_return +scr_tdm_score_flamethrower_kill +scr_tdm_score_flamethrower_multikill +scr_tdm_score_flamethrower_multikill_2 +scr_tdm_score_flamethrower_stolen +scr_tdm_score_flashback_kill +scr_tdm_score_focus_earn_multiscorestreak +scr_tdm_score_focus_earn_scorestreak +scr_tdm_score_frag_multikill +scr_tdm_score_gelgun_kill +scr_tdm_score_gelgun_multikill +scr_tdm_score_gelgun_multikill_2 +scr_tdm_score_gelgun_stolen +scr_tdm_score_gravityspikes_kill +scr_tdm_score_gravityspikes_multikill +scr_tdm_score_gravityspikes_multikill_2 +scr_tdm_score_gravityspikes_stolen +scr_tdm_score_hack_3_agrs +scr_tdm_score_hacked +scr_tdm_score_hacked_ai_tank +scr_tdm_score_hacked_autoturret +scr_tdm_score_hacked_combat_robot +scr_tdm_score_hacked_counteruav +scr_tdm_score_hacked_dart +scr_tdm_score_hacked_emp +scr_tdm_score_hacked_helicopter_comlink +scr_tdm_score_hacked_killstreak_protection +scr_tdm_score_hacked_microwaveturret +scr_tdm_score_hacked_mothership +scr_tdm_score_hacked_raps +scr_tdm_score_hacked_rcbomb +scr_tdm_score_hacked_satellite +scr_tdm_score_hacked_sentinel +scr_tdm_score_hacked_supply_drop +scr_tdm_score_hacked_uav +scr_tdm_score_hacker_drone_hacked +scr_tdm_score_hacker_drone_killed +scr_tdm_score_hardpoint_kill +scr_tdm_score_hatchet_kill +scr_tdm_score_headshot +scr_tdm_score_heatwave_kill +scr_tdm_score_helicopter_comlink_kill +scr_tdm_score_hover_rcxd_kill +scr_tdm_score_hpm_suppress +scr_tdm_score_hq_destroyed +scr_tdm_score_hq_secure +scr_tdm_score_humiliation_gun +scr_tdm_score_kill +scr_tdm_score_kill_ball_carrier +scr_tdm_score_kill_confirmed +scr_tdm_score_kill_confirmed_multi +scr_tdm_score_kill_denied +scr_tdm_score_kill_enemies_one_bullet +scr_tdm_score_kill_enemy_after_death +scr_tdm_score_kill_enemy_grenade_throwback +scr_tdm_score_kill_enemy_injuring_teammate +scr_tdm_score_kill_enemy_one_bullet +scr_tdm_score_kill_enemy_that_heatwaved_you +scr_tdm_score_kill_enemy_that_is_in_air +scr_tdm_score_kill_enemy_that_is_using_optic_camo +scr_tdm_score_kill_enemy_that_is_wallrunning +scr_tdm_score_kill_enemy_that_pulsed_you +scr_tdm_score_kill_enemy_that_used_resurrect +scr_tdm_score_kill_enemy_when_injured +scr_tdm_score_kill_enemy_while_both_in_air +scr_tdm_score_kill_enemy_while_capping_dom +scr_tdm_score_kill_enemy_while_capping_hq +scr_tdm_score_kill_enemy_while_carrying_ball +scr_tdm_score_kill_enemy_while_flashbanged +scr_tdm_score_kill_enemy_while_in_air +scr_tdm_score_kill_enemy_while_sliding +scr_tdm_score_kill_enemy_while_stunned +scr_tdm_score_kill_enemy_while_using_psychosis +scr_tdm_score_kill_enemy_while_wallrunning +scr_tdm_score_kill_enemy_who_has_flashbacked +scr_tdm_score_kill_enemy_who_has_full_power +scr_tdm_score_kill_enemy_who_has_high_score +scr_tdm_score_kill_enemy_who_has_powerarmor +scr_tdm_score_kill_enemy_who_is_speedbursting +scr_tdm_score_kill_enemy_who_is_using_focus +scr_tdm_score_kill_enemy_who_killed_teammate +scr_tdm_score_kill_enemy_with_care_package_crush +scr_tdm_score_kill_enemy_with_fists +scr_tdm_score_kill_enemy_with_gunbutt +scr_tdm_score_kill_enemy_with_hacked_care_package +scr_tdm_score_kill_enemy_with_more_ammo_oic +scr_tdm_score_kill_enemy_with_siegebot_crush +scr_tdm_score_kill_enemy_with_their_hero_ability +scr_tdm_score_kill_enemy_with_their_hero_weapon +scr_tdm_score_kill_enemy_with_their_weapon +scr_tdm_score_kill_flag_carrier +scr_tdm_score_kill_gun +scr_tdm_score_kill_hacker +scr_tdm_score_kill_hacker_then_hack +scr_tdm_score_kill_in_3_seconds_gun +scr_tdm_score_kill_sd +scr_tdm_score_kill_underwater_enemy_explosive +scr_tdm_score_kill_x2_score_shrp +scr_tdm_score_killed_annihilator_enemy +scr_tdm_score_killed_armblades_enemy +scr_tdm_score_killed_attacker +scr_tdm_score_killed_bomb_defuser +scr_tdm_score_killed_bomb_planter +scr_tdm_score_killed_bowlauncher_enemy +scr_tdm_score_killed_clone_enemy +scr_tdm_score_killed_defender +scr_tdm_score_killed_dog +scr_tdm_score_killed_dog_assist +scr_tdm_score_killed_enemy_while_carrying_flag +scr_tdm_score_killed_flamethrower_enemy +scr_tdm_score_killed_gelgun_enemy +scr_tdm_score_killed_gravityspikes_enemy +scr_tdm_score_killed_lightninggun_enemy +scr_tdm_score_killed_minigun_enemy +scr_tdm_score_killed_pineapple_enemy +scr_tdm_score_killed_raps +scr_tdm_score_killed_raps_assist +scr_tdm_score_killstreak_10 +scr_tdm_score_killstreak_11 +scr_tdm_score_killstreak_12 +scr_tdm_score_killstreak_13 +scr_tdm_score_killstreak_14 +scr_tdm_score_killstreak_15 +scr_tdm_score_killstreak_16 +scr_tdm_score_killstreak_17 +scr_tdm_score_killstreak_18 +scr_tdm_score_killstreak_19 +scr_tdm_score_killstreak_2 +scr_tdm_score_killstreak_20 +scr_tdm_score_killstreak_21 +scr_tdm_score_killstreak_22 +scr_tdm_score_killstreak_23 +scr_tdm_score_killstreak_24 +scr_tdm_score_killstreak_25 +scr_tdm_score_killstreak_26 +scr_tdm_score_killstreak_27 +scr_tdm_score_killstreak_28 +scr_tdm_score_killstreak_29 +scr_tdm_score_killstreak_3 +scr_tdm_score_killstreak_30 +scr_tdm_score_killstreak_4 +scr_tdm_score_killstreak_5 +scr_tdm_score_killstreak_6 +scr_tdm_score_killstreak_7 +scr_tdm_score_killstreak_8 +scr_tdm_score_killstreak_9 +scr_tdm_score_killstreak_more_than_30 +scr_tdm_score_knife_with_ammo_oic +scr_tdm_score_koth_secure +scr_tdm_score_lightninggun_kill +scr_tdm_score_lightninggun_multikill +scr_tdm_score_lightninggun_multikill_2 +scr_tdm_score_lightninggun_stolen +scr_tdm_score_longshot_kill +scr_tdm_score_melee_kill +scr_tdm_score_melee_leader_gun +scr_tdm_score_microwave_turret_assist +scr_tdm_score_microwave_turret_kill +scr_tdm_score_minigun_kill +scr_tdm_score_minigun_multikill +scr_tdm_score_minigun_multikill_2 +scr_tdm_score_minigun_stolen +scr_tdm_score_most_points_shrp +scr_tdm_score_mothership_assist_kill +scr_tdm_score_multikill_2 +scr_tdm_score_multikill_3 +scr_tdm_score_multikill_4 +scr_tdm_score_multikill_5 +scr_tdm_score_multikill_6 +scr_tdm_score_multikill_7 +scr_tdm_score_multikill_8 +scr_tdm_score_multikill_more_than_8 +scr_tdm_score_optic_camo_capture_objective +scr_tdm_score_optic_camo_kill +scr_tdm_score_pineapple_kill +scr_tdm_score_pineapple_multikill +scr_tdm_score_pineapple_multikill_2 +scr_tdm_score_pineapple_stolen +scr_tdm_score_plane_mortar_kill +scr_tdm_score_planted_bomb +scr_tdm_score_power_armor_kill +scr_tdm_score_quickly_secure_point +scr_tdm_score_raps_kill +scr_tdm_score_reboot_robot +scr_tdm_score_remote_missile_kill +scr_tdm_score_rescue_flag_carrier +scr_tdm_score_resurrect_kill +scr_tdm_score_retrieve_own_tags +scr_tdm_score_revenge_kill +scr_tdm_score_satellite_assist +scr_tdm_score_sentinel_kill +scr_tdm_score_sentry_gun_kill +scr_tdm_score_share_care_package +scr_tdm_score_shield_assist +scr_tdm_score_shield_blocked_damage +scr_tdm_score_shield_blocked_damage_reduced +scr_tdm_score_siegebot_killstreak_5 +scr_tdm_score_speed_burst_kill +scr_tdm_score_stick_explosive_kill +scr_tdm_score_stop_enemy_killstreak +scr_tdm_score_suicide +scr_tdm_score_survivor +scr_tdm_score_team_kill +scr_tdm_score_teammate_kill_confirmed +scr_tdm_score_thief_shutdown_enemy +scr_tdm_score_traversal_kill +scr_tdm_score_trophy_defense +scr_tdm_score_uav_assist +scr_tdm_score_uninterrupted_obit_feed_kills +scr_tdm_score_vision_pulse_kill +scr_tdm_score_vtol_mothership_kill +scr_tdm_score_wager_melee_kill +scr_tdm_score_won_match +scr_tdm_score_x2_score_shrp +scr_tdm_weapon_allowbetty +scr_tdm_weapon_allowflash +scr_tdm_weapon_allowfrag +scr_tdm_weapon_allowrpgs +scr_tdm_weapon_allowsatchel +scr_tdm_weapon_allowsmoke +scr_team_fftype +scr_team_teamkillerplaylistbanpenalty +scr_team_teamkillerplaylistbanquantum +scr_teambalance +scr_timeplayedcap +scr_use_digital_blood_enabled +scr_veh_alive_cleanuptimemax +scr_veh_alive_cleanuptimemin +scr_veh_cleanupabandoned +scr_veh_cleanupdebugprint +scr_veh_cleanupdrifted +scr_veh_cleanupmaxspeedmph +scr_veh_cleanupmindistancefeet +scr_veh_cleanuptime_dmgfactor_deadtread +scr_veh_cleanuptime_dmgfactor_max +scr_veh_cleanuptime_dmgfactor_min +scr_veh_cleanuptime_dmgfraction_curve_begin +scr_veh_cleanuptime_dmgfraction_curve_end +scr_veh_dead_cleanuptimemax +scr_veh_dead_cleanuptimemin +scr_veh_disableoverturndamage +scr_veh_disablerespawn +scr_veh_disappear_maxpreventdistancefeet +scr_veh_disappear_maxpreventvisibilityfeet +scr_veh_disappear_maxwaittime +scr_veh_driversarehidden +scr_veh_driversareinvulnerable +scr_veh_explode_on_cleanup +scr_veh_explosion_doradiusdamage +scr_veh_explosion_husk_forcepointvariance +scr_veh_explosion_husk_horzvelocityvariance +scr_veh_explosion_husk_vertvelocitymax +scr_veh_explosion_husk_vertvelocitymin +scr_veh_explosion_maxdamage +scr_veh_explosion_mindamage +scr_veh_explosion_radius +scr_veh_explosion_spawnfx +scr_veh_health_jeep +scr_veh_health_tank +scr_veh_ondeath_createhusk +scr_veh_ondeath_usevehicleashusk +scr_veh_respawnafterhuskcleanup +scr_veh_respawntimemax +scr_veh_respawntimemin +scr_veh_respawnwait_iterationwaitseconds +scr_veh_respawnwait_maxiterations +scr_veh_waittillstoppedandmindist_maxtime +scr_veh_waittillstoppedandmindist_maxtimeenabledistfeet +scr_vehicle_damage_scalar +scr_vialsAwardedScale +scr_wagerBet +scr_wagerPool +scr_wagerSideBet +scr_wager_firstPayout +scr_wager_firstPlayer +scr_wager_secondPayout +scr_wager_secondPlayer +scr_wager_thirdPayout +scr_wager_thirdPlayer +scr_weapon_allowbetty +scr_weapon_allowc4 +scr_weapon_allowflash +scr_weapon_allowfrags +scr_weapon_allowmines +scr_weapon_allowrpgs +scr_weapon_allowsatchel +scr_weapon_allowsmoke +scr_weaponobject_coneangle +scr_weaponobject_debug +scr_weaponobject_graceperiod +scr_weaponobject_mindist +scr_weaponobject_radius +scr_writeConfigStrings +scr_writeconfigstrings +scr_xpscale +scr_xpscaleCP +scr_xpscaleMP +scr_xpscaleZM +scr_xpscaleZMPromo +scr_xpscalecp +scr_xpscalemp +scr_xpscalezm +scr_zclassic_friendlyFireDelayTime +scr_zclassic_grenadeLauncherDudTime +scr_zclassic_killstreakDelayTime +scr_zclassic_score_alive_at_round_end_1 +scr_zclassic_score_alive_at_round_end_10 +scr_zclassic_score_alive_at_round_end_11 +scr_zclassic_score_alive_at_round_end_12 +scr_zclassic_score_alive_at_round_end_13 +scr_zclassic_score_alive_at_round_end_14 +scr_zclassic_score_alive_at_round_end_15 +scr_zclassic_score_alive_at_round_end_16 +scr_zclassic_score_alive_at_round_end_17 +scr_zclassic_score_alive_at_round_end_18 +scr_zclassic_score_alive_at_round_end_19 +scr_zclassic_score_alive_at_round_end_2 +scr_zclassic_score_alive_at_round_end_20 +scr_zclassic_score_alive_at_round_end_3 +scr_zclassic_score_alive_at_round_end_4 +scr_zclassic_score_alive_at_round_end_5 +scr_zclassic_score_alive_at_round_end_6 +scr_zclassic_score_alive_at_round_end_7 +scr_zclassic_score_alive_at_round_end_8 +scr_zclassic_score_alive_at_round_end_9 +scr_zclassic_score_headshot +scr_zclassic_score_kill +scr_zclassic_score_kill_margwa +scr_zclassic_score_kill_meatball +scr_zclassic_score_kill_mechz +scr_zclassic_score_kill_parasite +scr_zclassic_score_kill_raz +scr_zclassic_score_kill_sentinel +scr_zclassic_score_kill_spider +scr_zclassic_score_kill_thrasher +scr_zclassic_score_main_EE_quest +scr_zclassic_score_main_EE_quest_castle +scr_zclassic_score_main_EE_quest_factory +scr_zclassic_score_main_EE_quest_genesis +scr_zclassic_score_main_EE_quest_island +scr_zclassic_score_main_EE_quest_stalingrad +scr_zclassic_score_main_EE_quest_stalingrad_dragon +scr_zclassic_score_main_ee_quest_all +scr_zclassic_score_main_quest +scr_zclassic_score_melee_kill +scr_zclassic_score_melee_kill_meatball +scr_zclassic_score_melee_kill_parasite +scr_zclassic_score_open_door +scr_zclassic_score_revive_an_ally +scr_zclassic_score_solo_challenge_stalingrad +scr_zclassic_score_team_challenge_stalingrad +scr_zclassic_thrownGrenadeDudTime +scr_zm_enable_bots +scr_zm_use_code_enemy_selection +searchSessionDedicatedGeoMin +searchSessionDedicatedMaxPing +searchSessionGeo1Weight +searchSessionGeo2Weight +searchSessionGeo3Weight +searchSessionGeo4Weight +searchSessionGeoMin +searchSessionIsEmpty +searchSessionMapPackFlags +searchSessionNextTaskDelay +searchSessionSkillWeight +season_pass_incentive_id +season_pass_incentive_max +secondScreenClient +selectedFriendIndex +selectedFriendName +selectedPlayerXuid +sensitivity +serverbrowser_show +serverinfo +sessionSearchMaxAttempts +sessionTaskFailDebug +session_nonblocking +set_gametype +setliveevent +settings_allowGibbing +settings_defaultSubtitles +setviewpos +shardEdgeSize +shardShatterSizeLimitScale +shardSplitDir +shardSplitDir2 +shatterFxMaxDist +shatterFxMinEdgeLength +shieldBlastDamageProtection_120 +shieldBlastDamageProtection_180 +shieldBlastDamageProtection_30 +shieldBlastDamageProtection_60 +shieldDeployShakeDuration +shieldDeployShakeScale +shieldImpactBulletShakeDuration +shieldImpactBulletShakeScale +shieldImpactExplosionHighShakeDuration +shieldImpactExplosionHighShakeScale +shieldImpactExplosionLowShakeDuration +shieldImpactExplosionLowShakeScale +shieldImpactExplosionThreshold +shieldImpactMissileShakeDuration +shieldImpactMissileShakeScale +shieldPlayerBulletProtectionDegrees +shortversion +shoutcastHighlightedClient +shoutcastSelectedClient +showMapErrors +showVisionSetDebugInfo +show_reticle_during_swimming +showdrop +showevents +showpackets +skill_onboardingAdjustOnExit +skill_onboardingEnabled +skill_onboardingEnter +skill_onboardingExit +skill_onboardingGames +skill_onboardingThreshold +skill_scoreBeta +skill_scoreRange +skill_teamBeta +skill_teamRange +skipChunkCheck +skip_contract_rewards +skipto +skipto_complete +skipto_jump +slam_air_accel +slam_air_downward_angle +slam_air_enabled +slam_air_frictionMax +slam_air_frictionMin +slam_air_maxUpwardsVelocity +slam_air_speed +slam_air_upBoostAccel +slam_air_view_delta +slam_blur_amount +slam_blur_enabled +slam_blur_radius_inner +slam_blur_radius_outer +slam_blur_time_in +slam_blur_time_out +slam_clearance_check_dist +slam_clearance_check_radius +slam_debug +slam_enabled +slam_player_trace_offset +slam_time_in_air_timeout_ms +slam_time_ms +slam_wallrun_enabled +slide_allowEarlyMoveTime +slide_allow_hold_for_prone +slide_allow_shooting +slide_angle1 +slide_angle2 +slide_blur_amount +slide_blur_enabled +slide_blur_radius_inner +slide_blur_radius_outer +slide_blur_time_in +slide_blur_time_out +slide_cameraAlignmentEaseMode +slide_cameraClamp +slide_cameraPitchOffset +slide_cameraPitchRate +slide_cameraRotateTimeMs +slide_clearance_check_dist +slide_clearance_check_radius +slide_deadzoneTweek +slide_debug +slide_delayTime +slide_downhillFriction_amount +slide_enable +slide_enable_tweak_left_right +slide_fallDamageReduction +slide_forceBaseSlide +slide_frictionScale +slide_friction_amount +slide_friction_duration_ms +slide_hold_change_stance_time_air_ms +slide_hold_change_stance_time_ms +slide_jetFxDuration +slide_lensInTransRate +slide_lensOutTransRate +slide_maxTime +slide_maxTimeBase +slide_maxTimeReduced +slide_min_continue_velocity +slide_min_required_airVelocity +slide_min_required_velocity +slide_min_sprint_time_ms +slide_outAllowSprint +slide_outShouldScaleSpeed +slide_outSpeedScale +slide_player_trace_offset +slide_required_airAngle +slide_speed +slide_speedBase +slide_speedReduced +slide_subsequentSlideScale +slide_subsequentSlideTime +slide_tap_button_to_slide +slide_to_sprint_friction_time_scale +slide_under_geo_trace_dist +slide_under_geo_trace_radius +slide_uphillFriction_amount +slide_viewMovementEnabled +slide_view_angles +slide_view_anglesTransitionTime +slide_view_bounceAngles +slide_view_bounceAnglesPeriod +slide_view_slide_height +sm_enableViewmodel +sm_fastSunShadow +sm_lightScore_eyeProjectDist +sm_lightScore_spotProjectFrac +sm_showFXShadowmap +sm_showLightShadowmap +sm_showLightShadowmapScale +sm_showSpotAxis +sm_showSunOverlay +sm_showSunOverlayScaleBias +sm_showTris +sm_showViewmodelShadowmap +sm_spotPolygonOffsetBias +sm_spotPolygonOffsetScale +sm_spotShadowLargeRadiusScale +sm_strictCull +sm_sunAlwaysCastsShadow +sm_sunPolygonOffsetBias +sm_sunPolygonOffsetScale +smpDraw2D +smpGlass +smpScanForCrosshairEntity +smpUpdatePlayerNames +snaps +snd_assert_on_animation_prime +snd_assert_on_duck_stop +snd_assert_on_enqueue +snd_assert_on_play +snd_assert_on_stop +snd_autoSim +snd_autosim_window +snd_boat_current_rpm +snd_boat_engine_off +snd_boat_lerp_rpm +snd_boat_pitch_high_max +snd_boat_pitch_high_min +snd_boat_pitch_idle_max +snd_boat_pitch_idle_min +snd_boat_pitch_low_max +snd_boat_pitch_low_min +snd_boat_pitch_med_max +snd_boat_pitch_med_min +snd_boat_rpm_high_fin_end +snd_boat_rpm_high_start +snd_boat_rpm_idle_end +snd_boat_rpm_idle_fout_start +snd_boat_rpm_low_end +snd_boat_rpm_low_fin_end +snd_boat_rpm_low_fout_start +snd_boat_rpm_low_start +snd_boat_rpm_med_end +snd_boat_rpm_med_fin_end +snd_boat_rpm_med_fout_start +snd_boat_rpm_med_start +snd_boat_rpm_scalar +snd_boat_using_lerp_rpm +snd_boat_water_fast_min +snd_boat_water_idle_max +snd_boat_water_pitch_max +snd_boat_water_slow_max +snd_boat_water_slow_min +snd_debug_alias_filter +snd_debug_context_type +snd_debug_context_value +snd_debug_duck +snd_disable_ducks +snd_disable_play_once +snd_dlpf_attenuation +snd_dlpf_max_distance +snd_dlpf_min_distance +snd_dopplerRate +snd_dopplerScale +snd_draw3D +snd_dry_scale +snd_dsp_futz +snd_dsp_meters +snd_earlyverb_force +snd_earlyverb_scale +snd_enable_pitch +snd_farverb_force +snd_farverb_scale +snd_flux_separation +snd_force_pfutz +snd_futz_distance_ratio +snd_futz_force +snd_gfutz_override +snd_global_pitch +snd_isbig_distance +snd_jetgun_loop_start +snd_jetgun_pitch_end +snd_jetgun_pitch_start +snd_levelFadeTime +snd_losOcclusion +snd_master_override +snd_max_ram_voice +snd_max_stream_voice +snd_minigun_loop_start +snd_minigun_pitch_end +snd_minigun_pitch_start +snd_music_stress +snd_mute_alias_substring +snd_nearfar_max +snd_nearfar_min +snd_nearverb_force +snd_nearverb_scale +snd_occlusion_attenuation +snd_occlusion_rate +snd_pitch_timescale +snd_playing_priority_boost +snd_reverb_override +snd_reverb_prefader +snd_skip_muted_sounds +snd_solo_alias_substring +snd_solo_loaded +snd_solo_snapshot_group +snd_solo_streams +snd_speakerConfiguration +snd_start_alias +snd_start_alias_distance +snd_stop_alias +snd_stress +snd_throttle_reduce_vol +snd_throttle_time_held_down +snd_timescale_filter +snd_vo_implementation_mode +snd_voice_duck_override +snd_wet_scale +spawnPingPerkFadeTime +spawnsystem_allow_culling +spawnsystem_allow_non_team_spawns +spawnsystem_badspawn_aggression_delay +spawnsystem_badspawn_damage_delay +spawnsystem_badspawn_force_record +spawnsystem_convert_spawns_to_structs +spawnsystem_danger_time +spawnsystem_debug +spawnsystem_debug_archive +spawnsystem_debug_best_points +spawnsystem_debug_current_player +spawnsystem_debug_explored +spawnsystem_debug_influencer_pulse +spawnsystem_debug_influencer_types +spawnsystem_debug_influencers +spawnsystem_debug_list +spawnsystem_debug_liveedit +spawnsystem_debug_player +spawnsystem_debug_point_weights +spawnsystem_debug_points +spawnsystem_debug_reduced_logging +spawnsystem_debug_showclients +spawnsystem_debug_sideswitched +spawnsystem_debug_team +spawnsystem_debug_visibility +spawnsystem_debug_visibility_time +spawnsystem_demo_enable_parsing +spawnsystem_demo_max_written +spawnsystem_influencer_sight_line +spawnsystem_influencer_sight_line_min_length +spawnsystem_influencer_sight_line_push_through +spawnsystem_influencer_sight_line_update_interval +spawnsystem_old_vis_mask +spawnsystem_pause_weight_update +spawnsystem_player_explored_radius +spawnsystem_score_cull_min_points +spawnsystem_score_cull_percent +spawnsystem_score_cull_time_max +spawnsystem_score_cull_time_min +spawnsystem_sight_check_dual_point +spawnsystem_sight_check_dual_point_radius +spawnsystem_sight_check_max_distance +spawnsystem_sight_check_max_distance_ai +spawnsystem_sight_check_sentient_ai +spawnsystem_sight_check_sentient_players +spawnsystem_sight_height_offset +spawnsystem_sight_use_player_current_view_height +spawnsystem_use_code_point_enabled +spawnsystem_user_selects_spawn +speedburst_blur_amount +speedburst_blur_enabled +speedburst_blur_radius_inner +speedburst_blur_radius_outer +speedburst_blur_time_in +speedburst_blur_time_out +splitscreen +splitscreen_controller +splitscreen_horizontal +splitscreen_playerCount +spmode +sprintLeap_enabled +sprintLeap_forwardVelocityScale +sprintLeap_groundTraceDist +sprintLeap_height +sprintLeap_minSprintTimeMs +sprintLeap_minVolumeTimeMs +sprintLeap_traceForwardIncrament +sprintLeap_traceForwardMax +sprint_allowRechamber +sprint_allowReload +sprint_allowRestore +sprint_capSpeedEnabled +sprint_controlScheme +sprint_focalLength +sprint_fx_enabled +sprint_lensEnabled +sprint_lensInTransRate +sprint_lensOutTransRate +sprint_maxTime +sprint_minTime +sprint_minVelocity +sprint_minVelocitySwimming +sprint_rampIn +sprint_recoveryDelay +sprint_recoveryExtraDelay +sprint_recoveryTime +sprint_rollDeg +sprint_rollEnabled +sprint_rollTransTime +sprint_rumble_enabled +sprint_shake_duration +sprint_shake_enabled +sprint_shake_scale +sprint_stopOnWeaponRest +sprint_weaponScalarEnabled +sprintleap_check_dist +st_LODDistScale +st_forceLOD +standardPrimaryAttachmentCount +standardSecondaryAttachmentCount +stat_version +statsCheckXuidBeforeStatsUpload +statsErrorBackup +statsErrorNormal +statsErrorOtherPlayer +statsErrorStable +statsLocationFatal +statsVersionCP +statsVersionFR +statsVersionMP +statsVersionZM +stats_version_check +status +steamLobby_frameEnable +steamLobby_frameFailInterval +steamLobby_frameInterval +steamLobby_frameKeepAliveInterval +steamP2P_Enable +steamWorkshop_Enable +stopspeed +storage_auto_reset +storage_backoff +storage_maxfailures +storage_offline +storeMapPackMaskToStats +store_item_viewed_timer +streamMBPerSecond +survey_chance +survey_count +sv_FFCheckSums +sv_FFNames +sv_FakeRemoteClient +sv_SnapshotPeek +sv_allowAnonymous +sv_allowDownload +sv_antilagAnim +sv_archiveClientsPositions +sv_assistWorkers +sv_authenticating +sv_bitfieldTracking +sv_botThinkType +sv_botsPressAttackBtn +sv_bullet_range +sv_capture_ping_data +sv_cheats +sv_clientArchive +sv_clientFpsLimit +sv_clientFrameRateFix +sv_clientSideBullets +sv_clientSideVehicles +sv_clientUpdateDistance +sv_clientside +sv_connectTimeout +sv_connectionLogProbability +sv_connectionLogSamplesPerSecond +sv_connecttimeout +sv_debugAntiLagRewind +sv_debugConstantConfigStrings +sv_debugMessageKey +sv_debugPacketContents +sv_debugPacketContentsForClientThisFrame +sv_debugPacketContentsQuick +sv_debugPlayerstate +sv_debugRate +sv_debugReliableCmds +sv_detailedScriptErrors +sv_disableClientConsole +sv_dwlsgerror +sv_dynsnaps +sv_earlyEndSnapshots +sv_endGameIfISuck +sv_endmatch +sv_error_on_baseline_failure +sv_expensive_bullet_time +sv_fakeServerLoad +sv_fakeServerLoadRand +sv_floodProtect +sv_forceUpdateInterval +sv_forcelicensetype +sv_forceunranked +sv_fx_blockMinDist +sv_generateConstBaselines +sv_greedylock +sv_hitFXFrustumCutoff +sv_hostname +sv_ignorePing +sv_iwdNames +sv_iwds +sv_jqprof_continuous +sv_jqprof_enabled +sv_jqprof_frequency +sv_jqprof_profileCheckpointFrames +sv_jqprof_threshold +sv_keywords +sv_kickBanTime +sv_leaderboardwriteInterval +sv_loadMyChanges +sv_mapRotation +sv_mapRotationCurrent +sv_mapSwitch +sv_mapSwitchPerloadFrontendReserveMB +sv_mapSwitchPerloadFrontendReservePagesPerFrame +sv_mapSwitchPerloadFrontendStreamerFrames +sv_mapSwitchPreloadFrontend +sv_mapSwitch_rat +sv_mapcrc +sv_mapname +sv_maprotationcurrent +sv_mapswitch +sv_maxHappyPingTime +sv_maxPhysExplosionSpheres +sv_maxRate +sv_maxclients +sv_maxping +sv_momentumPercent +sv_network_fps +sv_nextmap +sv_noname +sv_onlineHostSnapshotRateThrottled +sv_packet_info +sv_padPackets +sv_paused +sv_penetrationCount +sv_playlistFetchInterval +sv_potm_debug +sv_printMessageSize +sv_privateClients +sv_privateClientsForClients +sv_privatePassword +sv_privateclients +sv_pure +sv_rateBoosting +sv_rateBoostingAllowUnackDeltas +sv_rateBoostingDebugForceSuspend +sv_rateBoostingMaxUploadUsage +sv_rateBoostingMinUploadScale +sv_rateBoostingRecoverTime +sv_rateBoostingSuspendBadFramesCPU +sv_rateBoostingSuspendBadFramesCPUThreshold +sv_rateBoostingSuspendBadFramesCPUTimeout +sv_rateBoostingSuspendedMaxUploadUsage +sv_reconnectlimit +sv_referencedFFCheckSums +sv_referencedFFNames +sv_referencedIwdNames +sv_referencedIwds +sv_restrictedTempEnts +sv_running +sv_saveGameSkipto +sv_sendCmdAngles +sv_serverLogClientPings +sv_showAverageBPS +sv_showCommands +sv_showHuffmanData +sv_showPingSpam +sv_skipto +sv_snapshot_skip_count +sv_timeout +sv_useAnimCulling +sv_useMapPreloading +sv_userCmdLimiter +sv_vac +sv_voice +sv_voiceQuality +sv_writeConfigStrings +sv_wwwBaseURL +sv_wwwDlDisconnected +sv_wwwDownload +sv_zlib_threshold +sv_zombietime +sys_threadWatchdogTimeoutLive +systemUiActive +systeminfo +systemlink +tacticalWalkDirection +take +teamOpsEnabled +teamOpsKillsCountTrigger +teamOpsName +teamOpsPreanounceTime +teamOpsStartDelay +teamsplitter_verbose +tell +tempCPOnline +tempbanclient +tempbanuser +terriblePing +testMissingContentPacks +test_levels_selection +tgraph_debugClearancePointId +tgraph_debugDrawPointNavFace +tgraph_debugDrawPoints +tgraph_debugShowStats +tgraph_debugTargetPointId +tgraph_debugVisMapDrawNonVisible +tgraph_debugVisMapPointId +throwback_enabled +tickerStandardWidth +tickerWidescreenWidth +ticker_menu_context +timeUntilDropRange +timescale +tm_currentErrorPage +tm_failsThreshold +tm_logTimeLimit +tm_pendingeThreshold +tm_startedThreshold +tm_succeedsThreshold +tm_taskManagerDebug +tm_taskTrackerOn +tm_typeToDisplay +totalCoverage_blockFriendlyMinimap +totalCoverage_debug +totalCoverage_enemy_minimap +totalCoverage_friendly_minimap +totalCoverage_higherGroundTest +totalCoverage_offsetToCoverage +totalCoverage_smokeInTime +totalCoverage_smokeOutTime +totalSampleClientTrack +totalSampleRateBlackBox +totalSampleRateQoS +totalSampleRateSurvey +total_paintjobs +tquery_drawQuery +tquery_drawQueryDuration +tracer_debugDraw +tracer_explosiveColor1 +tracer_explosiveColor2 +tracer_explosiveColor3 +tracer_explosiveColor4 +tracer_explosiveColor5 +tracer_explosiveOverride +tracer_explosiveWidth +tracer_firstPersonMaxWidth +tracer_stoppingPowerColor1 +tracer_stoppingPowerColor2 +tracer_stoppingPowerColor3 +tracer_stoppingPowerColor4 +tracer_stoppingPowerColor5 +tracer_stoppingPowerColor6 +tracer_stoppingPowerOverride +tracer_stoppingPowerWidth +tracer_thermalWidthMult +traverse_mode +trm_adsDisablesAutoComplete +trm_alignViewToSurfaceTime +trm_autoCompleteJumpTimeMs +trm_autocomplete_require_jump +trm_checkRadius +trm_checkRange +trm_checkRangeVault +trm_clearanceTraceZEpsilon +trm_clearanceWidthAdd +trm_deadZone +trm_debug +trm_doublejumpPreventReengageTime +trm_doublejump_out_frac_on_high_forward_100 +trm_doublejump_out_frac_on_high_forward_140 +trm_doublejump_out_frac_on_low_forward +trm_doublejump_out_frac_on_low_left +trm_doublejump_out_frac_on_low_right +trm_doublejump_out_frac_on_med_forward +trm_doublejump_out_frac_on_med_left +trm_doublejump_out_frac_on_med_right +trm_doublejump_out_frac_over_high_forward_100 +trm_doublejump_out_frac_over_high_forward_140 +trm_doublejump_out_frac_over_high_forward_75 +trm_doublejump_out_frac_over_low_forward +trm_doublejump_out_frac_over_low_forward_vault +trm_doublejump_out_frac_over_low_left +trm_doublejump_out_frac_over_low_right +trm_doublejump_out_frac_step +trm_enable +trm_enableDoubleJumpOut +trm_enabled +trm_entitiesBlockForwardTrace +trm_fastmantle_scalar +trm_highPitchDegrees +trm_highYawDegrees +trm_initMinForwardMove +trm_initMinSideMove +trm_input +trm_inputRange +trm_inputRangeBack +trm_inputRangeSide +trm_ledgeAngleOffset +trm_ledgeCapsuleRadius +trm_ledgeHeight_onHigh +trm_ledgeHeight_onLow +trm_ledgeHeight_onMed +trm_ledgeHeight_overHigh +trm_ledgeHeight_overLow +trm_ledgeHeight_overMed +trm_ledgeHeight_step +trm_maxBackMantleHeight +trm_maxHurdleDistance +trm_maxSideMantleHeight +trm_maxVerticalityRatio +trm_minFacingRatio +trm_minLedgeHeight +trm_movefrac_on_high_forward_100 +trm_movefrac_on_high_forward_140 +trm_movefrac_on_low_forward +trm_movefrac_on_low_left +trm_movefrac_on_low_right +trm_movefrac_on_med_forward +trm_movefrac_on_med_left +trm_movefrac_on_med_right +trm_movefrac_over_high_forward_100 +trm_movefrac_over_high_forward_140 +trm_movefrac_over_high_forward_75 +trm_movefrac_over_low_forward +trm_movefrac_over_low_forward_vault +trm_movefrac_over_low_left +trm_movefrac_over_low_right +trm_movefrac_step +trm_pitchRecenterTime +trm_safeHurdleZ +trm_stepDistance +trm_step_contact_frac +trm_timescale_on_high_forward_100 +trm_timescale_on_high_forward_140 +trm_timescale_on_low_forward +trm_timescale_on_low_left +trm_timescale_on_low_right +trm_timescale_on_med_forward +trm_timescale_on_med_left +trm_timescale_on_med_right +trm_timescale_over_high_forward_100 +trm_timescale_over_high_forward_140 +trm_timescale_over_high_forward_75 +trm_timescale_over_low_forward +trm_timescale_over_low_forward_vault +trm_timescale_over_low_left +trm_timescale_over_low_right +trm_timescale_step +trm_viewCenterStart +trm_viewCenterTimeMs +trm_weaponRaisedelayMs +tu10_ClearWeapNextHeldInputOnSwitchWeaponCmd +tu10_cleanupRagdollsOnExit +tu10_enableCyclicalDailyChallenges +tu10_enableHighestAvailableDLCEntitlementCheck +tu10_metPlayerClearOnUserSignedOut +tu10_mpSwitchSpecialistWeaponExploitFix +tu10_validationFatal +tu11_AllowIgnoreDisabledWeaponCyclingInActionSlotUsageAllowed +tu11_IgnoreItemsWithPLevel100InIsItemLockedForChallenge +tu11_cleanupRagdollsOnDemoJump +tu11_clearMpVehicleWaterMaterial +tu11_dontUpdateWeaponPosFracWhenLinked +tu11_enableClassicMode +tu11_enableVehicleMode +tu11_fixForMultishotRechamberWeaponSwitchIssue +tu11_lootCryptoAutoRetry +tu11_matchmakingPriorityDOA +tu11_matchmakingPriorityDOAIgnoreTime +tu11_matchmakingPriorityMP +tu11_matchmakingPriorityMPIgnoreTime +tu11_maxQuadCacheAlloc +tu11_mpNewCodCasterKeyline +tu11_mpReconstructTrailsForStationaryEntities +tu11_programaticallyColoredGameFX +tu11_uploadStreamFailureFlag +tu11_useLootXPDueStat +tu12_delayFFOTD +tu12_mpMaintainMissileSpeed +tu12_switchToWeaponImmediateFix +tu12_zmHideLegsWithViewmodel +tu13_recordContentAvailable +tu14_skipPrimaryGroupCheck +tu16_SLFreeStringFix +tu16_physicsPushOutThreshold +tu19_orbis_presence_localizations +tu1_aiPathableMaterials +tu1_build +tu1_pickupParentlessGrenade +tu1_queuedEventInterval +tu1_saveGameAiProximityCheck +tu1_vehicleCollisionCacheSetup +tu1_zombiePaintJobsEnabled +tu2_catchMissingRbEndFrame +tu2_cscGetDStatCP +tu2_disableChallengesForLockedItemsInArena +tu2_forceConnectionStateTransitionSpinnerOn +tu2_logLootToKVS +tu3_lobby_dropRejoiningClients +tu3_onlineSavegameErrorFatal +tu4_burnDuplicates +tu4_enableBonusCryptokeysHint +tu4_enableCodPoints +tu4_enableMeleeWeaponFlourish +tu4_firstValidCurrencyID +tu4_newSysInfo +tu4_newSysInfoUpdateRate +tu4_partyPrivacyLuaCheck +tu4_partyPrivacyUseGlobal +tu4_refetchBalanceOnUpdate +tu4_skipStatStatusCache +tu4_storageClearTargetQueue +tu4_storageControllerSwapProtection +tu4_zmChangePlayerStandOnSentients +tu5_defaultMaxHeroAttachmentsToZero +tu5_dwNetFatalErrors +tu5_enableVialsOwed +tu5_gadgetThiefSupport +tu5_live_friends_signedin_fetch +tu5_partyStatusGetInterval +tu5_recordXuidMismatch +tu5_vialsOwedCheckDelay +tu5_zmChangeOffhandGearWeaponChange +tu5_zmChangeSlamUseWalkable +tu5_zmEnableClipOnlyWeaponFlourish +tu5_zmPathDistanceCheckTolarance +tu6_doublePistolSpreadAmmo +tu6_mpMeleeAttachmentObitIcon +tu6_mpReconstructTrailForOtherPlayers +tu6_mpReconstructTrailForTriboltCrossbow +tu6_mpStackFirePitchChange +tu6_player_shallowWaterHeight +tu7_enableBundles +tu7_mpDoNotSetBallisticAnglesWhenLinked +tu7_mpNoVehicleNeutralTeamTargetHighlight +tu7_mpUseImprovedMissileStickAngles +tu7_mpUseNewBounceMissileMayStopFleshLogic +tu7_zmInAirDisabledTimeoutTime +tu8_ai_enableBTInterruptPriority +tu8_animTimeResetInterval +tu8_enableDurableProductsExchange +tu8_mpChallengesGroupPrereqFix +tu8_mpLootWeaponPurchasedCheckEnabled +tu8_mtx_enabled +tu8_platformSessionOrbisValidateNpEventResult +tu8_trmRestrictionLevel +tu8_yySlideExploitFix +tu9_backupBadDecompress +tu9_backupBadSpace +tu9_canSplitInProgressUnbalancedTeams +tu9_entryExitImpactSurfaceNormalFix +tu9_fileshareCommunityIncludeEmptyDescriptors +tu9_highestAvailableDLC +tu9_hostLaunchCheckMinPlayer +tu9_hostLaunchCheckUnbalancedTeams +tu9_hostPrivateSessions +tu9_jitterModExploitFix +tu9_skipPerlocalClientAllocation +tu9_ui_zmLobbyEEEnabled +tu9_yySlideExploitFix +tu9_zmDisableMeleeChargeJump +turretPlayerAvoidScale +turret_placement_debug +turret_placement_feet_offset +turret_placement_feet_trace_dist_z +turret_placement_trace_dist +turret_placement_trace_dist_wallmount +turret_placement_trace_dist_zm +turret_placement_trace_maxs +turret_placement_trace_min_normal +turret_placement_trace_mins +turret_placement_trace_pitch +turret_placement_trace_radius_canon_safety +turretplacement_traceOffset +turretplacement_useTraceOffset +twitch_app_version +twitch_audio_volume +twitch_client_id +twitch_mixpanel_token +twitch_platform_name +twitch_player_name +twitch_stats_update_interval +typeWriterCod7LetterFXTime +ufo +ui_DSPPromotionInterval +ui_SPReminderPopupInterval +ui_abortKeyboardOnUIChange +ui_allowDisplayContinue +ui_allow_classchange +ui_allow_controlschange +ui_allow_teamchange +ui_allowvote +ui_autoContinue +ui_autoControlledPlayer +ui_badWordMaxTaskWaits +ui_badWordSeverity +ui_bigFont +ui_blocksaves +ui_blurAmount +ui_blurDarkenAmount +ui_blurTime +ui_borderLowLightScale +ui_buildLocation +ui_buildSize +ui_busyBlockIngameMenu +ui_checksum_enabled +ui_cinematicsTimestamp +ui_codexindex_unlocked +ui_combatCurrScrollBarPos +ui_creditSkipTo +ui_creditsScrollScale +ui_currFocusList +ui_currFocusStates +ui_currMenuNameList +ui_currentNetMap +ui_custom_name +ui_customerServiceURL +ui_damage_widget_hide_delay +ui_deadquote +ui_dedicated +ui_demoname +ui_detailedMM +ui_disablePSControlWidgets +ui_disable_blur +ui_disable_lan +ui_display_aar +ui_doa_unlocked +ui_drawBuildNumber +ui_drawCrosshair +ui_drawSpinnerAfterMovie +ui_dropdownListMax +ui_dropdownMax +ui_emblemDisableGroups +ui_enableAllHeroes +ui_enableConnectionMetricGraphs +ui_enableDSPPromotion +ui_enableSPReminderPopup +ui_enableZMHDFeaturedCard +ui_enabled +ui_errorMessage +ui_errorMessageDebug +ui_errorTitle +ui_errorUndefLocals +ui_error_callstack_ship +ui_error_report +ui_error_report_delay +ui_execdemo +ui_execdemo_beta +ui_execdemo_cp +ui_execdemo_e3 +ui_execdemo_gamescom +ui_execdemo_gamescom_host +ui_extraBigFont +ui_fakeCurrentMap +ui_forceQueue +ui_framesBetweenButtonPromptTraces +ui_framesBetweenObjectiveLOSTraces +ui_freeCursorAcceleration +ui_freeCursorParallax +ui_freeCursorSpeed_Focus +ui_freeCursorSpeed_NoFocus +ui_friendlyfire +ui_friendsListOpen +ui_fxFontFalloff +ui_fxFontGlowSize +ui_fxFontOutlineSize +ui_fxFontShadowOffset +ui_fxFontShadowSize +ui_fxFontTweaks +ui_gametype +ui_generic_status_bar +ui_guncycle +ui_heatMapColor +ui_heatMapColorForPlayer +ui_heroExtracamResolution +ui_hideLeaderboards +ui_hideMiniLeaderboards +ui_hostname +ui_hud_hardcore +ui_hud_minimap_hide +ui_hud_obituaries +ui_hud_showobjicons +ui_hud_visible +ui_inGameStoreVisible +ui_isDLCPopupEnabled +ui_keepLoadingScreenUntilAllPlayersConnected +ui_keyboard_dvar_edit +ui_keyboardtitle +ui_levelEra +ui_level_sv +ui_liveEventViewerOpen +ui_lobbyDebugAgreeCountLoc +ui_lobbyDebugAgreementLoc +ui_lobbyDebugBaseX +ui_lobbyDebugBaseY +ui_lobbyDebugClients +ui_lobbyDebugDWSessionLoc +ui_lobbyDebugExtraInfoLoc +ui_lobbyDebugGameClientSessionLoc +ui_lobbyDebugGameHostSessionLoc +ui_lobbyDebugJoinLoc +ui_lobbyDebugLobbyTasksLoc +ui_lobbyDebugMsgLoc +ui_lobbyDebugOverlay +ui_lobbyDebugPlatformSessionLoc +ui_lobbyDebugPrivateClientSessionLoc +ui_lobbyDebugPrivateHostSessionLoc +ui_lobbyDebugResCountLoc +ui_lobbyDebugReservationLoc +ui_lobbyDebugSessionSQJ +ui_lobbyDebugVis +ui_lobbyDebugVoice +ui_lobbyDebugVoiceClientLoc +ui_lobbyDebugVoiceHostLoc +ui_lobbypopup +ui_mapname +ui_menuLvlNotify +ui_motd +ui_mousePitch +ui_mpTheaterEnabled +ui_mpWagerMatchEnabled +ui_netSource +ui_newStartMenu +ui_numTacticalWidgets +ui_options_open +ui_paintshopEditDarkening +ui_playLogoMovie +ui_playerListOpen +ui_playerNemesisColor +ui_playerSquadColor +ui_playlistPopulationRefreshTime +ui_readingSaveDevice +ui_safearea +ui_saveMessageMinTime +ui_scorelimit +ui_scrollSpeed +ui_sessionModeLocation +ui_showFocus +ui_showGameModeHistory +ui_showList +ui_showNewestLeaderboards +ui_showSessionMode +ui_showmap +ui_singlemission +ui_smallFont +ui_smp_hud_models +ui_snapToNearestPixel +ui_splitscreen +ui_storeButtonPressed +ui_supportURL +ui_ten_classes +ui_textPaddingOverride +ui_text_endreason +ui_timelimit +ui_timescale +ui_totalDLCReleased +ui_tu11_splitscreen_scoreboard_snap_check +ui_useloadingmovie +ui_useoutromovie +ui_usingFreeCursor +ui_weakpointIndicatorMedium +ui_weakpointIndicatorNear +ui_weapon_tiers +ui_zm_gamemodegroup +ui_zm_mapstartlocation +uiscript_debug +unbanuser +unbind +unbind2 +unbindall +unbindall2 +unifiedLens_enabled +unifiedLens_minFocalLength +unifiedLens_minVelocityThreshold +unifiedLens_scaleFinal +unifiedLens_scaleInitial +unifiedLens_transTimeIn +unifiedLens_transTimeOut +unsubscriptionCooloffTimer +upload_bps_dedicated +upload_bps_demosystem +upload_bps_perplayer +useClassSets +useFakeEmblems +useFastFile +useForceEliteCmds +useLargeRadius +useMapPreloading +usePaintshopData +useRadius +useSvMapPreloading +useWalkPathnodesMode +vc_LUT +vc_SNAP +vehControlMode +vehGunnerSplashDamage +vehHelicopterAlwaysFaceCamera +vehHelicopterAlwaysFaceCameraRate +vehHelicopterHeadSwayDontSwayTheTurret +vehHelicopterJitterJerkyness +vehLocationalVehicleSeatEntry +vehLockTurretToPlayerView +vehNPCThrottleMultiplier +vehPlaneFakeLiftForce +vehPlaneGravityForce +vehPlaneInvertPitch +vehPlaneJetControls +vehPlaneLiftForce +vehPlaneLowSpeed +vehPlanePitchAccel +vehPlaneRollAccel +vehPlaneRollDeadZone +vehPlaneYawFromRollScale +vehPlaneYawSpeed +vehRecenterDelay +vehanim_debug +vehanim_enable +vehicleMouseExtraTurnSpeed +vehicle_collision_prediction_crash_time +vehicle_collision_prediction_time +vehicle_damage_max_shielding +vehicle_damage_zone_front +vehicle_damage_zone_rear +vehicle_damage_zone_side +vehicle_damage_zone_under +vehicle_destructible_damage_bouncing_betty +vehicle_destructible_damage_bouncing_betty_radius +vehicle_destructible_damage_grenade +vehicle_destructible_damage_grenade_radius +vehicle_destructible_damage_projectile_radius +vehicle_destructible_damage_satchel_charge +vehicle_destructible_damage_satchel_charge_radius +vehicle_destructible_damage_sticky_grenade +vehicle_destructible_damage_sticky_grenade_radius +vehicle_infinite_boost +vehicle_perk_boost_duration_seconds +vehicle_piece_damagesfx_threshold +vehicle_push_during_mantle +vehicle_riding +vehicle_selfCollision +vehicle_sounds_cutoff +vehicle_spline_arrows +vehicle_strafe_control_dead_zone +vehicle_switch_seat_delay +vehicle_useRadius +version +vid_xpos +vid_ypos +viewpos +vm_sendNotifyAndCallbackOnSpawn +voiceDegrade +voice_debug +voice_enabled +vote +waitForInitial +waitForStreamer +waitOnStatsTimeout +walkMove_avoidanceDot +walkMove_avoidanceEnabled +walkMove_avoidanceMinSpeedScale +walkMove_avoidanceProbeDistance +walkMove_avoidanceSpeedDifferentialThreshold +wallRun_avoidanceEnabled +wallRun_avoidanceMinMaintainSpeed +wallRun_avoidanceMinSpeedScale +wallRun_avoidanceProbeDistance +wallRun_beginFallOnDamage +wallRun_cameraAlignmentEaseMode +wallRun_cameraAutoCurveAngleFactor +wallRun_cameraAutoCurveEnabled +wallRun_cameraAutoCurveTimeMs +wallRun_cameraAutoCurveTraceDistance +wallRun_cameraClamp +wallRun_cameraInputDeadTimeMs +wallRun_cameraRollSpeed +wallRun_cameraRotateTimeMs +wallRun_cameraYaw +wallRun_cameraYawOffset +wallRun_cameraYawRate +wallRun_combatEnable +wallRun_debug +wallRun_downStepVelocity +wallRun_enabled +wallRun_exitMoveDampening +wallRun_facingMaxPitch +wallRun_facingMinSin +wallRun_fallGroundPitchMax +wallRun_fallGroundPitchMin +wallRun_fallStageTimeMs +wallRun_fallingRollScalar +wallRun_firingInStateDelay +wallRun_frictionScale +wallRun_handTraceEnable +wallRun_initialAnimDelayMs +wallRun_initialCameraInputDeadTimeMs +wallRun_jumpHeight +wallRun_jumpVelocity +wallRun_maxHeight +wallRun_maxTimeMs +wallRun_minForwardMove +wallRun_minHeightOffGround +wallRun_minJumpHeight +wallRun_minJumpHeightEnable +wallRun_minMaintainSpeed +wallRun_minTriggerSpeed +wallRun_minVelocityAlignment +wallRun_minZVel +wallRun_moveMode +wallRun_normalFacingRatio +wallRun_obtuseSlopeTolerance +wallRun_peakTest +wallRun_peakTest_zm +wallRun_pitchTimeMs +wallRun_rollDeg +wallRun_rollInTimeMs +wallRun_rollOutTimeMs +wallRun_sameSurfaceDelayPeriodMs +wallRun_sameSurfaceWallrun +wallRun_sightTraceDistance +wallRun_speedScale +wallRun_speedScaleADS +wallRun_sweepTraceDistance +wallRun_sweepTraceEnable +wallRun_traceDistance +wallRun_traceMode +wallRun_tracePitch +wallRun_universalRollEnable +wallRun_viewmodelAnimEnable +wallRun_weaponBobFrequency +wallmount_turret_placement_trace_maxs +wallmount_turret_placement_trace_mins +wallrun_additiveWalkAnimScale +wallrun_additiveWalkAnimScaleADS +wallrun_avoidanceDot +wallrun_enabled +wallrun_jumpLateralLimit +wallrun_peakTestMinVelocity +wallrun_slopeQuotient +war_a +war_b +war_c +war_d +war_e +waterbrush_entity +waypointAlphaFractionUnderMinimap +waypointCombatAlpha +waypointDebugDraw +waypointDistFade +waypointDistScaleRangeMax +waypointDistScaleRangeMin +waypointDistScaleSmallest +waypointForceDrawDistance +waypointIconHeight +waypointIconWidth +waypointMaxDrawDist +waypointOffscreenCornerRadius +waypointOffscreenDistanceThresholdAlpha +waypointOffscreenPadBottom +waypointOffscreenPadLeft +waypointOffscreenPadRight +waypointOffscreenPadTop +waypointOffscreenPointerDistance +waypointOffscreenPointerHeight +waypointOffscreenPointerWidth +waypointOffscreenRoundedCorners +waypointOffscreenScaleLength +waypointOffscreenScaleSmallest +waypointPlayerOffsetCrouch +waypointPlayerOffsetProne +waypointPlayerOffsetRevive +waypointPlayerOffsetStand +waypointSplitscreenScale +waypointTimeFade +waypointTweakY +waypointVerticalSeparation +weaponCamoLodDist +weaponClanTagLodDist +weaponClanTagShieldLodDist +weaponEmblemLodDist +weaponEmblemShieldLodDist +weapon_contract_incentive_id +weapon_contract_max +weapon_contract_target_value +weaponrest_check_radius +weaponrest_check_range +weaponrest_debug +weaponrest_enabled +weaponrest_removepitch +weaponrest_updatemsec +webm_encAllowCamera +weekly_contract_blackjack_contract_reward_count +weekly_contract_cryptokey_reward_count +welcome_shown +wideScreen +wiiuGame +wiiuIkEnabled +wind_debug_display +wind_global_hi_altitude +wind_global_low_altitude +wind_global_low_strength_percent +wind_global_vector +wind_grass_gust_distance +wind_grass_gust_radius +wind_grass_gust_speed +wind_grass_gust_strength +wind_grass_gustinterval +wind_grass_scale +wind_grass_tension +wind_leaf_scale +winvoice_loopback +winvoice_mic_mute +winvoice_mic_reclevel +winvoice_mic_scaler +winvoice_save_voice +winvoice_voice_level +xPGroupMask +xPGroups +xanim_debug +xanim_debugNotetracks +xanim_monitorEnt +xanim_monitorFilter +xblive_clanListChanged +xblive_clanmatch +xblive_loggedin +xblive_mappacks +xblive_matchEndingSoon +xblive_privatematch +xblive_rankedmatch +xblive_theater +xblive_wagermatch +xenonGame +xenon_maxVoicePacketsPerSec +xenon_maxVoicePacketsPerSecForServer +xuid +yawAccelerationTime +yawDecelerationThreshold +zero_idle_movement +zero_stats_check +zm_private_rankedmatch +zm_rand_loc +zm_rand_mode +zm_vials_3_id +zm_vials_6_id +zm_vials_9_id +zm_wasp_open_spawning +zombie_cheat +zombie_debug +zombie_devgui +zombie_kill_timer +zombie_kills +zombiemode_debug_zombie_count \ No newline at end of file diff --git a/data/scripts/mp/bots/_bot.gsc b/data/scripts/mp/bots/_bot.gsc new file mode 100644 index 0000000..7f793a6 Binary files /dev/null and b/data/scripts/mp/bots/_bot.gsc differ diff --git a/data/scripts/mp/bots/_bot.gsc_raw b/data/scripts/mp/bots/_bot.gsc_raw new file mode 100644 index 0000000..8206b45 --- /dev/null +++ b/data/scripts/mp/bots/_bot.gsc_raw @@ -0,0 +1,1125 @@ +#using scripts\codescripts\struct; + +#using scripts\shared\array_shared; +#using scripts\shared\callbacks_shared; +#using scripts\shared\killstreaks_shared; +#using scripts\shared\math_shared; +#using scripts\shared\rank_shared; +#using scripts\shared\system_shared; +#using scripts\shared\util_shared; +#using scripts\shared\weapons_shared; + +#using scripts\shared\weapons\_weapons; + +#using scripts\shared\bots\_bot; +#using scripts\shared\bots\_bot_combat; +#using scripts\shared\bots\bot_buttons; +#using scripts\shared\bots\bot_traversals; + +#using scripts\mp\bots\_bot_ball; +#using scripts\mp\bots\_bot_clean; +#using scripts\mp\bots\_bot_combat; +#using scripts\mp\bots\_bot_conf; +#using scripts\mp\bots\_bot_ctf; +#using scripts\mp\bots\_bot_dem; +#using scripts\mp\bots\_bot_dom; +#using scripts\mp\bots\_bot_escort; +#using scripts\mp\bots\_bot_hq; +#using scripts\mp\bots\_bot_koth; +#using scripts\mp\bots\_bot_loadout; +#using scripts\mp\bots\_bot_sd; + +#using scripts\mp\killstreaks\_ai_tank; +#using scripts\mp\killstreaks\_airsupport; +#using scripts\mp\killstreaks\_combat_robot; +#using scripts\mp\killstreaks\_counteruav; +#using scripts\mp\killstreaks\_dart; +#using scripts\mp\killstreaks\_dogs; +#using scripts\mp\killstreaks\_drone_strike; +#using scripts\mp\killstreaks\_emp; +#using scripts\mp\killstreaks\_flak_drone; +#using scripts\mp\killstreaks\_helicopter; +#using scripts\mp\killstreaks\_helicopter_gunner; +#using scripts\mp\killstreaks\_killstreak_bundles; +#using scripts\mp\killstreaks\_killstreak_detect; +#using scripts\mp\killstreaks\_killstreak_hacking; +#using scripts\mp\killstreaks\_killstreakrules; +#using scripts\mp\killstreaks\_killstreaks; +#using scripts\mp\killstreaks\_microwave_turret; +#using scripts\mp\killstreaks\_planemortar; +#using scripts\mp\killstreaks\_qrdrone; +#using scripts\mp\killstreaks\_raps; +#using scripts\mp\killstreaks\_rcbomb; +#using scripts\mp\killstreaks\_remote_weapons; +#using scripts\mp\killstreaks\_remotemissile; +#using scripts\mp\killstreaks\_satellite; +#using scripts\mp\killstreaks\_sentinel; +#using scripts\mp\killstreaks\_supplydrop; +#using scripts\mp\killstreaks\_turret; +#using scripts\mp\killstreaks\_uav; + +#using scripts\mp\teams\_teams; +#using scripts\mp\_util; + +#insert scripts\shared\shared.gsh; +#insert scripts\mp\bots\_bot.gsh; + +#define MAX_LOCAL_PLAYERS 10 +#define MAX_ONLINE_PLAYERS 18 +#define MAX_ONLINE_PLAYERS_PER_TEAM 6 + +#define RESPAWN_DELAY 0.1 +#define RESPAWN_INTERVAL 0.1 + +#namespace bot; + +#precache("eventstring", "mpl_killstreak_cruisemissile"); +#precache("eventstring", "mpl_killstreak_raps"); + +REGISTER_SYSTEM("bot_mp", &__init__, undefined) + +function __init__() +{ + callback::on_start_gametype(&init); + + level.getBotSettings = &get_bot_settings; + + level.onBotConnect = &on_bot_connect; + level.onBotSpawned = &on_bot_spawned; + level.onBotKilled = &on_bot_killed; + + level.botIdle = &bot_idle; + + level.botThreatLost = &bot_combat::chase_threat; + + level.botPreCombat = &bot_combat::mp_pre_combat; + level.botCombat = &bot_combat::combat_think; + level.botPostCombat = &bot_combat::mp_post_combat; + + level.botIgnoreThreat = &bot_combat::bot_ignore_threat; + + level.enemyEmpActive = &emp::enemyEmpActive; + +/* +/# + level.botDevguiCmd = &bot_devgui_cmd; + level thread system_devgui_gadget_think(); +#/ +*/ + setDvar("bot_enableWallrun", 1); +} + +function init() +{ + level endon("game_ended"); + + level.botSoak = is_bot_soak(); + if (!init_bot_gametype()) + { + return; + } + + wait_for_host(); + + level thread populate_bots(); +} + +// Init Utils +//======================================== + +function is_bot_soak() +{ + return getDvarInt("sv_botsoak", 0); +} + +function wait_for_host() +{ + level endon("game_ended"); + + host = util::getHostPlayerForBots(); + + while (!isdefined(host)) + { + wait(0.25); + host = util::getHostPlayerForBots(); + } +} + +function get_host_team() +{ + host = util::getHostPlayerForBots(); + + if (!isdefined(host) || host.team == "spectator") + { + return "allies"; + } + + return host.team; +} + +function is_bot_comp_stomp() +{ + return false; +} + +// Bot Events +//======================================== + +function on_bot_connect() +{ + self endon("disconnect"); + level endon("game_ended"); + + if (IS_TRUE(level.disableClassSelection)) + { + self set_rank(); + + // Doesn't work if we don't do it in this order + self bot_loadout::pick_hero_gadget(); + self bot_loadout::pick_killstreaks(); + + return; + } + + if (!IS_TRUE(self.pers["bot_loadout"])) + { + self set_rank(); + + // Doesn't work if we don't do it in this order + self bot_loadout::build_classes(); + self bot_loadout::pick_hero_gadget(); + self bot_loadout::pick_killstreaks(); + + self.pers["bot_loadout"] = true; + } + + self bot_loadout::pick_classes(); + self choose_class(); +} + +function on_bot_spawned() +{ + self.bot.goalTag = undefined; +/* +/# + weapon = undefined; + + if (getDvarInt("scr_botsHasPlayerWeapon") != 0) + { + player = util::getHostPlayer(); + weapon = player getCurrentWeapon(); + } + + if (getDvarString("devgui_bot_weapon", "") != "") + { + weapon = getWeapon(getDvarString("devgui_bot_weapon")); + } + + if (isdefined(weapon) && level.weaponNone != weapon) + { + self weapons::detach_all_weapons(); + self takeAllWeapons(); + self giveWeapon(weapon); + self switchToWeapon(weapon); + self setSpawnWeapon(weapon); + + self teams::set_player_model(self.team, weapon); + } +#/ +*/ +} + +function on_bot_killed() +{ + self endon("disconnect"); + level endon("game_ended"); + self endon("spawned"); + self waittill("death_delay_finished"); + + wait RESPAWN_DELAY; + + if (self choose_class() && level.playerForceRespawn) + { + return; + } + + self thread respawn(); +} + +function respawn() +{ + self endon("spawned"); + self endon("disconnect"); + level endon("game_ended"); + + while (1) + { + self bot::tap_use_button(); + + wait RESPAWN_INTERVAL; + } +} + +function bot_idle() +{ + if (self do_supplydrop()) + { + return; + } + + // TODO: Look for an enemy radar blip + // TODO: Get points on navmesh and feed into the spawn system to see if an enemy is likely to spawn there + self bot::navmesh_wander(); + self bot::sprint_to_goal(); +} + +// Crate maxs: 23.1482 +#define CRATE_GOAL_RADIUS 39 +#define CRATE_USE_RADIUS 62 // Wild guess on usable radius + +function do_supplydrop(maxRange = 1400) // A little under minimap width +{ + crates = getEntArray("care_package", "script_noteworthy"); + + maxRangeSq = maxRange * maxRange; + + useRadiusSq = CRATE_USE_RADIUS * CRATE_USE_RADIUS; + + closestCrate = undefined; + closestCrateDistSq = undefined; + + foreach(crate in crates) + { + if (!crate isOnGround()) + { + continue; + } + + crateDistSq = distance2DSquared(self.origin, crate.origin); + + if (crateDistSq > maxRangeSq) + { + continue; + } + + inUse = isdefined(crate.useEnt) && IS_TRUE(crate.useEnt.inUse); + + if (crateDistSq <= useRadiusSq) + { + if (inUse && !self useButtonPressed()) + { + continue; + } + + self bot::press_use_button(); + return true; + } + + if (!self has_minimap() && !self botSightTracePassed(crate)) + { + continue; + } + + if (!isdefined(closestCrate) || crateDistSq < closestCrateDistSq) + { + closestCrate = crate; + closestCrateDistSq = crateDistSq; + } + } + + if (isdefined(closestCrate)) + { + randomAngle = (0, randomInt(360), 0); + randomVec = AnglesToForward(randomAngle); + + point = closestCrate.origin + randomVec * CRATE_GOAL_RADIUS; + + if (self botSetGoal(point)) + { + self thread watch_crate(closestCrate); + return true; + } + } + + return false; +} + +function watch_crate(crate) +{ + self endon("death"); + self endon("bot_goal_reached"); + level endon("game_ended"); + + while (isdefined(crate) && !self bot_combat::has_threat()) + { + wait level.botSettings.thinkInterval; + } + + self botSetGoal(self.origin); +} + +// Bot Team Population +//======================================== + +function populate_bots() +{ + level endon("game_ended"); + + if (level.teambased) + { + maxAllies = getDvarInt("bot_maxAllies", 0); + maxAxis = getDvarInt("bot_maxAxis", 0); + + level thread monitor_bot_team_population(maxAllies, maxAxis); + } + else + { + maxFree = getDvarInt("bot_maxFree", 0); + + level thread monitor_bot_population(maxFree); + } +} + +function monitor_bot_team_population(maxAllies, maxAxis) +{ + level endon("game_ended"); + + if (!maxAllies && !maxAxis) + { + return; + } + + fill_balanced_teams(maxAllies, maxAxis); + + while (1) + { + wait 3; + + // TODO: Get a player count that includes 'CON_CONNECTING' players + allies = getPlayers("allies"); + axis = getPlayers("axis"); + + if (allies.size > maxAllies && + remove_best_bot(allies)) + { + continue; + } + + if (axis.size > maxAxis && + remove_best_bot(axis)) + { + continue; + } + + if (allies.size < maxAllies || axis.size < maxAxis) + { + add_balanced_bot(allies, maxAllies, axis, maxAxis); + } + } +} + +function fill_balanced_teams(maxAllies, maxAxis) +{ + allies = getPlayers("allies"); + axis = getPlayers("axis"); + + while ((allies.size < maxAllies || axis.size < maxAxis) && + add_balanced_bot(allies, maxAllies, axis, maxAxis)) + { + WAIT_SERVER_FRAME; + + allies = getPlayers("allies"); + axis = getPlayers("axis"); + } +} + +function add_balanced_bot(allies, maxAllies, axis, maxAxis) +{ + bot = undefined; + + if (allies.size < maxAllies && + (allies.size <= axis.size || axis.size >= maxAxis)) + { + bot = add_bot("allies"); + } + else if (axis.size < maxAxis) + { + bot = add_bot("axis"); + } + + return isdefined(bot); +} + +function monitor_bot_population(maxFree) +{ + level endon("game_ended"); + + if (!maxFree) + { + return; + } + + // Initial Fill + players = getPlayers(); + while (players.size < maxFree) + { + add_bot(); + WAIT_SERVER_FRAME; + players = getPlayers(); + } + + while (1) + { + wait 3; + + // TODO: Get a player count that includes 'CON_CONNECTING' players + players = getPlayers(); + + if (players.size < maxFree) + { + add_bot(); + } + else if (players.size > maxFree) + { + remove_best_bot(players); + } + } +} + +function remove_best_bot(players) +{ + bots = filter_bots(players); + + if (!bots.size) + { + return false; + } + + // Prefer non-combat bots + bestBots = []; + + foreach(bot in bots) + { + // Don't kick bots in the process of connecting + if (bot.sessionstate == "spectator") + { + continue; + } + + if (bot.sessionstate == "dead" || !bot bot_combat::has_threat()) + { + bestBots[bestBots.size] = bot; + } + } + + if (bestBots.size) + { + remove_bot(bestBots[randomInt(bestBots.size)]); + } + else + { + remove_bot(bots[randomInt(bots.size)]); + } + + return true; +} + +// Bot Loadouts +//======================================== + +function choose_class() +{ + if (IS_TRUE(level.disableClassSelection)) + { + return false; + } + + currClass = self bot_loadout::get_current_class(); + + if (!isdefined(currClass) || randomInt(100) < VAL(level.botSettings.changeClassWeight, 0)) + { + classIndex = randomInt(self.loadoutClasses.size); + className = self.loadoutClasses[classIndex].name; + } + + if (!isdefined(className) || className == currClass) + { + return false; + } + + self notify("menuresponse", MENU_CHANGE_CLASS, className); + + return true; +} + +// Killstreaks +//======================================== + +function use_killstreak() +{ + if (!level.loadoutKillstreaksEnabled || + self emp::enemyEmpActive()) + { + return; + } + + weapons = self getWeaponsList(); + inventoryWeapon = self getInventoryWeapon(); + + foreach(weapon in weapons) + { + killstreak = killstreaks::get_killstreak_for_weapon(weapon); + + if (!isdefined(killstreak)) + { + continue; + } + + if (weapon != inventoryWeapon && !self getWeaponAmmoClip(weapon)) + { + continue; + } + + if (self killstreakrules::isKillstreakAllowed(killstreak, self.team)) + { + useWeapon = weapon; + break; + } + } + + if (!isdefined(useWeapon)) + { + return; + } + + killstreak_ref = killstreaks::get_menu_name(killstreak); + + switch (killstreak_ref) + { + case "killstreak_uav": + case "killstreak_counteruav": + case "killstreak_satellite": + case "killstreak_helicopter_player_gunner": + case "killstreak_raps": + case "killstreak_sentinel": + { + self switchToWeapon(useWeapon); + break; + } + case "killstreak_ai_tank_drop": + { + self use_supply_drop(weapon); + break; + } + case "killstreak_remote_missile": + { + self switchToWeapon(weapon); + self waittill("weapon_change_complete"); + wait 1.5; + self bot::press_attack_button(); + return; + } + } +} + +function get_closest_enemy(origin, on_radar) +{ + enemies = self get_enemies(on_radar); + enemies = arraysort(enemies, origin); + + if (enemies.size) + return enemies[0]; + + return undefined; +} + +function use_supply_drop(weapon) +{ + if (weapon == "inventory_supplydrop_mp" || weapon == "supplydrop_mp") + { + if (gettime() - self.spawntime > 5000) + return; + } + + yaw = (0, self.angles[1], 0); + dir = anglestoforward(yaw); + dir = vectornormalize(dir); + drop_point = self.origin + vectorscale(dir, 384); + end = drop_point + vectorscale((0, 0, 1), 2048.0); + + if (!sighttracepassed(drop_point, end, 0, undefined)) + return; + + if (!sighttracepassed(self.origin, end, 0, undefined)) + return; + + end = drop_point - vectorscale((0, 0, 1), 32.0); + + if (bullettracepassed(drop_point, end, 0, undefined)) + return; + + self addgoal(self.origin, 24, 4, "killstreak"); + + if (weapon == "missile_drone_mp" || weapon == "inventory_missile_drone_mp") + self lookat(drop_point + vectorscale((0, 0, 1), 384.0)); + else + self lookat(drop_point); + + wait 0.5; + + if (self getCurrentWeapon() != weapon) + { + self thread weapon_switch_failsafe(); + self switchToWeapon(weapon); + + self waittill("weapon_change_complete"); + } + + use_item(weapon); + self switchToWeapon(self.lastnonkillstreakweapon); + self clearlookat(); + self cancelgoal("killstreak"); +} + +function use_item(weapon) +{ + self bot::press_attack_button(); + wait 0.5; + + for (i = 0; i < 10; i++) + { + if (self getCurrentWeapon() == weapon || self getCurrentWeapon() == "none") + self bot::press_attack_button(); + else + return; + + wait 0.5; + } +} + +function killstreak_location(num, weapon) +{ + enemies = get_enemies(); + + if (!enemies.size) + return; + + if (!self switchToWeapon(weapon)) + return; + + self waittill("weapon_change"); + + self util::freeze_player_controls(true); + wait_time = 1; + + while (!isdefined(self.selectinglocation) || self.selectinglocation == 0) + { + wait 0.05; + wait_time -= 0.05; + + if (wait_time <= 0) + { + self util::freeze_player_controls(false); + self switchToWeapon(self.lastnonkillstreakweapon); + return; + } + } + + wait 2; + + for (i = 0; i < num; i++) + { + enemies = get_enemies(); + + if (enemies.size) + { + enemy = randomInt(enemies); + self notify("confirm_location", enemy.origin, 0); + } + + wait 0.25; + } + + self util::freeze_player_controls(false); +} + +function weapon_switch_failsafe() +{ + self endon("death"); + self endon("disconnect"); + self endon("weapon_change_complete"); + wait 10; + self notify("weapon_change_complete"); +} + +function has_radar() +{ + if (level.teambased) + { + return (uav::HasUAV(self.team) || satellite::HasSatellite(self.team)); + } + + return (uav::HasUAV(self.entnum) || satellite::HasSatellite(self.entnum)); +} + +function has_minimap() +{ + if (self IsEmpJammed()) + { + return false; + } + + if (IS_TRUE(level.hardcoreMode)) + { + return self has_radar(); + } + + return true; +} + +function get_enemies(on_radar) +{ + if (!isdefined(on_radar)) + { + on_radar = false; + } + + enemies = self GetEnemies(); + +/* +/# + for (i = 0; i < enemies.size; i++) + { + if (isplayer(enemies[i]) && enemies[i] isInMoveMode("ufo", "noclip")) + { + arrayRemoveIndex(enemies, i); + i--; + } + } +#/ +*/ + + if (on_radar && !self has_radar()) + { + for (i = 0; i < enemies.size; i++) + { + if (!isdefined(enemies[i].lastFireTime)) + { + arrayRemoveIndex(enemies, i); + i--; + } + else if (GetTime() - enemies[i].lastFireTime > 2000) + { + arrayRemoveIndex(enemies, i); + i--; + } + } + } + + return enemies; +} + +function set_rank() +{ + players = getPlayers(); + + ranks = []; + bot_ranks = []; + human_ranks = []; + + for (i = 0; i < players.size; i++) + { + if (players[i] == self) + continue; + + if (isdefined(players[i].pers["rank"])) + { + if (players[i] util::is_bot()) + { + bot_ranks[bot_ranks.size] = players[i].pers["rank"]; + } + else + { + human_ranks[human_ranks.size] = players[i].pers["rank"]; + } + } + } + + if (!human_ranks.size) + human_ranks[human_ranks.size] = 10; + + human_avg = math::array_average(human_ranks); + + while (bot_ranks.size + human_ranks.size < 5) + { + // add some random ranks for better random number distribution + r = human_avg + randomIntRange(-5, 5); + rank = math::clamp(r, 0, level.maxRank); + human_ranks[human_ranks.size] = rank; + } + + ranks = arrayCombine(human_ranks, bot_ranks, true, false); + + avg = math::array_average(ranks); + s = math::array_std_deviation(ranks, avg); + + rank = Int(math::random_normal_distribution(avg, s, 0, level.maxRank)); + + while (!isdefined(self.pers["codpoints"])) + { + wait 0.1; + } + + self.pers["rank"] = rank; + self.pers["rankxp"] = rank::getRankInfoMinXP(rank); + + self setRank(rank); + self rank::syncXPStat(); +} + +function init_bot_gametype() +{ + switch (level.gameType) + { + case "ball": + bot_ball::init(); + return true; + case "conf": + bot_conf::init(); + return true; + case "ctf": + bot_ctf::init(); + return true; + case "dem": + bot_dem::init(); + return true; + case "dm": + return true; + case "dom": + bot_dom::init(); + return true; + case "escort": + bot_escort::init(); + return true; +// case "infect": +// return true; + case "gun": + return true; + case "koth": + bot_koth::init(); + return true; + case "sd": + bot_sd::init(); + return true; + case "clean": + bot_clean::init(); + return true; + case "tdm": + return true; + case "sas": + return true; + case "prop": + return true; + case "sniperonly": + return true; + } + + return false; +} + +function get_bot_settings() +{ + switch (getDvarInt("bot_difficulty", 1)) + { + case 0: + bundleName = "bot_mp_easy"; + break; + + case 1: + bundleName = "bot_mp_normal"; + break; + case 2: + bundleName = "bot_mp_hard"; + break; + case 3: + default: + bundleName = "bot_mp_veteran"; + break; + } + + return struct::get_script_bundle("botsettings", bundleName); +} + +function friend_goal_in_radius(goal_name, origin, radius) +{ + return 0; +} + +function friend_in_radius(goal_name, origin, radius) +{ + return false; +} + +function get_friends() +{ + return[]; +} + +function bot_vehicle_weapon_ammo(weaponName) +{ + return false; +} + +function navmesh_points_visible(origin, point) +{ + return false; +} + +function dive_to_prone(exit_stance) +{ + +} + +/* +/# + +// Devgui +//======================================== + +function bot_devgui_cmd(cmd) +{ + cmdTokens = strtok(cmd, " "); + + if (cmdTokens.size == 0) + { + return false; + } + + host = util::getHostPlayerForBots(); + team = get_host_team(); + + switch (cmdTokens[0]) + { + case "spawn_enemy": + team = util::getotherteam(team); + case "spawn_friendly": + count = 1; + if (cmdTokens.size > 1) + { + count = int(cmdTokens[1]); + } + for (i = 0; i < count; i++) + { + add_bot(team); + } + return true; + case "remove_enemy": + team = util::getotherteam(team); + case "remove_friendly": + remove_bots(undefined, team); + return true; + case "fixed_spawn_enemy": + team = util::getotherteam(team); + case "fixed_spawn_friendly": + bot = add_bot_at_eye_trace(team); + if (isdefined(bot)) + { + bot thread fixed_spawn_override(); + } + return true; + + case "player_weapon": + players = getPlayers(); + foreach(player in players) + { + if (!player util::is_bot()) + { + continue; + } + + weapon = host getCurrentWeapon(); + + player weapons::detach_all_weapons(); + player takeAllWeapons(); + player giveWeapon(weapon); + player switchToWeapon(weapon); + player setSpawnWeapon(weapon); + + player teams::set_player_model(player.team, weapon); + } + return true; + } + + return false; +} + +function system_devgui_gadget_think() +{ + setDvar("devgui_bot_gadget", ""); + + for (;; ) + { + wait(1); + + gadget = getDvarString("devgui_bot_gadget"); + + if (gadget.size == 0) + { + bot_turn_on_gadget(getWeapon(gadget)); + setDvar("devgui_bot_gadget", ""); + } + } +} + +function bot_turn_on_gadget(gadget) +{ + players = getPlayers(); + + foreach(player in players) + { + if (!player util::is_bot()) + { + continue; + } + + host = util::getHostPlayer(); + weapon = host getCurrentWeapon(); + + if (!isdefined(weapon) || weapon == level.weaponNone || weapon == level.weaponNull) + { + weapon = getWeapon("smg_standard"); + } + + player weapons::detach_all_weapons(); + player takeAllWeapons(); + player giveWeapon(weapon); + player switchToWeapon(weapon); + player setSpawnWeapon(weapon); + + player teams::set_player_model(player.team, weapon); + + player giveWeapon(gadget); + slot = player gadgetGetSlot(gadget); + player gadgetPowerSet(slot, 100.0); + player botPressButtonForGadget(gadget); + } +} + +function fixed_spawn_override() +{ + self endon("disconnect"); + + spawnOrigin = self.origin; + spawnAngles = self.angles; + + while (1) + { + self waittill("spawned_player"); + + self setOrigin(spawnOrigin); + self setPlayerAngles(spawnAngles); + } +} + +#/ +*/ diff --git a/data/scripts/mp/bots/_bot_loadout.gsc b/data/scripts/mp/bots/_bot_loadout.gsc new file mode 100644 index 0000000..1dce334 Binary files /dev/null and b/data/scripts/mp/bots/_bot_loadout.gsc differ diff --git a/data/scripts/mp/bots/_bot_loadout.gsc_raw b/data/scripts/mp/bots/_bot_loadout.gsc_raw new file mode 100644 index 0000000..3b48b7f --- /dev/null +++ b/data/scripts/mp/bots/_bot_loadout.gsc_raw @@ -0,0 +1,854 @@ +#using scripts\shared\array_shared; +#using scripts\shared\rank_shared; + +#insert scripts\shared\shared.gsh; +#insert scripts\shared\statstable_shared.gsh; + +#using scripts\mp\killstreaks\_killstreaks; + +#using scripts\mp\bots\_bot; + +#define BOT_ALLOCATION_MAX 100 +#define BOT_ALLOCATION_UNLOCK_MAX 3 +#define BOT_RANK_ALL_OPTIONS_AVAILABLE 20 +#define BOT_RANK_OPTIONS_MULTIPLIER 4 + +#namespace bot_loadout; + +// Item Whitelist +//======================================== + +function in_whitelist( itemName ) +{ + if ( !isdefined( itemName ) ) + return false; + + switch( itemName ) + { + // Secondaries + case "WEAPON_KNIFE_LOADOUT": + case "WEAPON_PISTOL_STANDARD": + case "WEAPON_PISTOL_BURST": + case "WEAPON_PISTOL_FULLAUTO": + case "WEAPON_LAUNCHER_STANDARD": + case "WEAPON_LAUNCHER_LOCKONLY": + + // Primaries + case "WEAPON_SMG_STANDARD": + case "WEAPON_SMG_BURST": + case "WEAPON_SMG_FASTFIRE": + case "WEAPON_SMG_LONGRANGE": + case "WEAPON_SMG_VERSATILE": + case "WEAPON_SMG_CAPACITY": + case "WEAPON_AR_STANDARD": + case "WEAPON_AR_ACCURATE": + case "WEAPON_AR_CQB": + case "WEAPON_AR_DAMAGE": + case "WEAPON_AR_FASTBURST": + case "WEAPON_AR_LONGBURST": + case "WEAPON_AR_MARKSMAN": + case "WEAPON_LMG_CQB": + case "WEAPON_LMG_HEAVY": + case "WEAPON_LMG_LIGHT": + case "WEAPON_LMG_SLOWFIRE": + case "WEAPON_SNIPER_FASTBOLT": + case "WEAPON_SNIPER_FASTSEMI": + case "WEAPON_SNIPER_POWERBOLT": + case "WEAPON_SNIPER_CHARGESHOT": + case "WEAPON_SHOTGUN_FULLAUTO": + case "WEAPON_SHOTGUN_PRECISION": + case "WEAPON_SHOTGUN_PUMP": + case "WEAPON_SHOTGUN_SEMIAUTO": + + // Lethals + case "WEAPON_FRAGGRENADE": + case "WEAPON_HATCHET": + case "WEAPON_STICKY_GRENADE": + case "WEAPON_SATCHEL_CHARGE": + case "WEAPON_BOUNCINGBETTY": + case "WEAPON_INCENDIARY_GRENADE": + + // Tacticals + case "WEAPON_WILLY_PETE": + case "WEAPON_STUN_GRENADE": + case "WEAPON_EMPGRENADE": + case "WEAPON_FLASHBANG": + case "WEAPON_PROXIMITY_GRENADE": + case "WEAPON_PDA_HACK": + case "WEAPON_TROPHY_SYSTEM": + + // Killstreaks + //case "KILLSTREAK_RCBOMB": + case "KILLSTREAK_RECON": + case "KILLSTREAK_COUNTER_UAV": + //case "KILLSTREAK_SUPPLY_DROP": + //case "KILLSTREAK_MICROWAVE_TURRET": + case "KILLSTREAK_REMOTE_MISSILE": + //case "KILLSTREAK_PLANEMORTAR": + //case "KILLSTREAK_AUTO_TURRET": + case "KILLSTREAK_AI_TANK_DROP": + //case "KILLSTREAK_HELICOPTER_COMLINK": + case "KILLSTREAK_SATELLITE": + //case "KILLSTREAK_EMP": + //case "KILLSTREAK_HELICOPTER_GUNNER": + case "KILLSTREAK_RAPS": + //case "KILLSTREAK_DRONE_STRIKE": + //case "KILLSTREAK_DART": + case "KILLSTREAK_SENTINEL": + + // TU Something Weapons + case "WEAPON_MELEE_KNUCKLES": + case "WEAPON_MELEE_BUTTERFLY": + case "WEAPON_MELEE_WRENCH": + + // TU 6 Weapons + case "WEAPON_PISTOL_SHOTGUN": + case "WEAPON_AR_GARAND": + case "WEAPON_SPECIAL_CROSSBOW": + case "WEAPON_MELEE_CROWBAR": + case "WEAPON_MELEE_SWORD": + case "WEAPON_MELEE_BOXING": + case "WEAPON_SMG_AK74U": + case "WEAPON_SMG_MP40": + case "WEAPON_SMG_RECHAMBER": + case "WEAPON_SMG_NAILGUN": + case "WEAPON_AR_AN94": + case "WEAPON_AR_FAMAS": + case "WEAPON_SMG_MSMC": + case "WEAPON_LMG_INFINITE": + case "WEAPON_AR_PULSE": + case "WEAPON_AR_M16": + case "WEAPON_SMG_PPSH": + case "WEAPON_LAUNCHER_EX41": + case "WEAPON_SHOTGUN_OLYMPIA": + case "WEAPON_SNIPER_QUICKSCOPE": + case "WEAPON_SNIPER_DOUBLE": + case "WEAPON_SMG_STEN": + case "WEAPON_AR_GALIL": + case "WEAPON_LMG_RPK": + case "WEAPON_AR_M14": + case "WEAPON_SHOTGUN_ENERGY": + case "WEAPON_SPECIAL_CROSSBOW_DW": + case "WEAPON_AR_PEACEKEEPER": + case "WEAPON_MELEE_CHAINSAW": + case "WEAPON_SPECIAL_KNIFE_BALLISTIC": + case "WEAPON_MELEE_CRESCENT": + case "WEAPON_SPECIAL_DISCGUN": + return true; + } + + return false; +} + +// Classes +//======================================== + +function build_classes() +{ + primaryWeapons = self get_available_items( undefined, "primary" ); + secondaryWeapons = self get_available_items( undefined, "secondary" ); + lethals = self get_available_items( undefined, "primarygadget" ); + tacticals = self get_available_items( undefined, "secondarygadget" ); + if ( IS_TRUE( level.perksEnabled ) ) + { + specialties1 = self get_available_items( undefined, "specialty1" ); + specialties2 = self get_available_items( undefined, "specialty2" ); + specialties3 = self get_available_items( undefined, "specialty3" ); + } + + foreach( className, classValue in level.classMap ) + { + if ( !isSubstr( className, "custom" ) ) + { + continue; + } + + classIndex = int( className[className.size-1] ); + + pickedItems = []; + + pick_item( pickedItems, primaryWeapons ); + + if ( RandomInt( 100 ) < 95 ) // 5% chance to be a boxer for Scronce + { + pick_item( pickedItems, secondaryWeapons ); + } + + // Shuffle these selections around a bit so the classes don't all look the same when the allocation is low + otherItems = Array ( lethals, tacticals, specialties1, specialties2, specialties3 ); + otherItems = array::randomize( otherItems ); + + for ( i = 0; i < otherItems.size; i ++ ) + { + pick_item( pickedItems, otherItems[i] ); + } + + // Add items up to the max allocation + for ( i = 0; i < pickedItems.size && i < level.maxAllocation; i++ ) + { + self BotClassAddItem( classIndex, pickedItems[i] ); + } + + // TODO: Pick primary/secondary attachments, extra perks, extra lethal, extra tactical, overkill +/* + primaryWeapon = self GetLoadoutWeapon( classIndex, "primary" ); + + if ( primaryWeapon != level.weaponNone && primaryWeapon.supportedAttachments.size ) + { + attachment = array::random( primaryWeapon.supportedAttachments ); + self BotClassAddAttachment( classIndex, primaryWeapon, attachment, "primary" ); + } + + secondaryWeapon = self GetLoadoutWeapon( classIndex, "secondary" ); + + if ( secondaryWeapon != level.weaponNone && secondaryWeapon.supportedAttachments.size ) + { + attachment = array::random( secondaryWeapon.supportedAttachments ); + self BotClassAddAttachment( classIndex, secondaryWeapon, attachment, "secondary" ); + } +*/ + } +} + +function pick_item( &pickedItems, items ) +{ + if ( !isdefined( items ) || items.size <= 0 ) + { + return; + } + + pickedItems[pickedItems.size] = array::random( items ); +} + +function pick_classes() +{ + self.loadoutClasses = []; + self.launcherClassCount = 0; + + foreach( className, classValue in level.classMap ) + { + if ( isSubstr( className, "custom" ) ) + { + if ( level.disableCAC ) + { + continue; + } + + classIndex = int( className[className.size-1] ); + } + else + { + // Things bots could use better in the default classes: + // C4, Trophy System, Lock on only launcher + classIndex = level.classToClassNum[ classValue ]; + } + + primary = self GetLoadoutWeapon( classIndex, "primary" ); + secondary = self GetLoadoutWeapon( classIndex, "secondary" ); + + botClass = SpawnStruct(); + botClass.name = className; + botClass.index = classIndex; + botClass.value = classValue; + botClass.primary = primary; + botClass.secondary = secondary; + + if ( botClass.secondary.isRocketLauncher ) + { + self.launcherClassCount++; + } + + self.loadoutClasses[ self.loadoutClasses.size ] = botClass; + } +} + +function get_current_class() +{ + currValue = self.pers["class"]; + if ( !isdefined( currValue ) ) + { + return undefined; + } + + foreach( botClass in self.loadoutClasses ) + { + if ( botClass.value == currValue ) + { + return botClass; + } + } + + return undefined; +} + +// Specialists +//======================================== + +function pick_hero_gadget() +{ + if ( RandomInt( 2 ) < 1 || !self pick_hero_ability() ) + { + self pick_hero_weapon(); + } +} + +function pick_hero_weapon() +{ + heroWeaponRef = self GetHeroWeaponName(); + + if ( IsItemRestricted( heroWeaponRef ) ) + { + return false; + } + + heroWeaponName = self get_item_name( heroWeaponRef ); + self BotClassAddItem( 0, heroWeaponName ); + + return true; +} + +function pick_hero_ability() +{ + heroAbilityRef = self GetHeroAbilityName(); + + if ( IsItemRestricted( heroAbilityRef ) ) + { + return false; + } + + heroAbilityName = self get_item_name( heroAbilityRef ); + self BotClassAddItem( 0, heroAbilityName ); + + return true; +} + +// Killstreaks +//======================================== + +function pick_killstreaks() +{ + killstreaks = array::randomize( self get_available_items( "killstreak" ) ); + + for( i = 0; i < 3 && i < killstreaks.size; i++ ) + { + self BotClassAddItem( 0, killstreaks[i] ); + } +} + + +// Get Items +//======================================== + +function get_available_items( filterGroup, filterSlot ) +{ + // Get unlocked and unrestricted items + items = []; + + for( i = 0; i < STATS_TABLE_MAX_ITEMS; i++ ) + { + row = tableLookupRowNum( level.statsTableID, STATS_TABLE_COL_NUMBERING, i ); + + if ( row < 0 ) + { + continue; + } + + name = tableLookupColumnForRow( level.statsTableID, row, STATS_TABLE_COL_NAME ); + + if ( name == "" || !in_whitelist( name ) ) + { + continue; + } + + allocation = Int( tableLookupColumnForRow( level.statsTableID, row, STATS_TABLE_COL_ALLOCATION ) ); + + if ( allocation < 0 ) + { + continue; + } + + ref = tableLookupColumnForRow( level.statsTableId, row, STATS_TABLE_COL_REFERENCE ); + + if ( IsItemRestricted( ref ) ) + { + continue; + } + + number = Int( tableLookupColumnForRow( level.statsTableID, row, STATS_TABLE_COL_NUMBERING ) ); +/* + if ( SessionModeIsPrivate() && self IsItemLocked( number ) ) + { + continue; + } +*/ + if ( isdefined( filterGroup ) ) + { + group = tableLookupColumnForRow( level.statsTableID, row, STATS_TABLE_COL_GROUP ); + + if ( group != filterGroup ) + { + continue; + } + } + + if ( isdefined( filterSlot ) ) + { + slot = tableLookupColumnForRow( level.statsTableID, row, STATS_TABLE_COL_SLOT ); + + if ( slot != filterSlot ) + { + continue; + } + } + + items[items.size] = name; + } + + return items; +} + +function get_item_name( itemReference ) +{ + for( i = 0; i < STATS_TABLE_MAX_ITEMS; i++ ) + { + row = tableLookupRowNum( level.statsTableID, STATS_TABLE_COL_NUMBERING, i ); + + if ( row < 0 ) + { + continue; + } + + reference = tableLookupColumnForRow( level.statsTableID, row, STATS_TABLE_COL_REFERENCE ); + + if ( reference != itemReference ) + { + continue; + } + + name = tableLookupColumnForRow( level.statsTableID, row, STATS_TABLE_COL_NAME ); + + return name; + } + + return undefined; +} + +// Not in use + +function init() +{ + level endon( "game_ended" ); + + level.bot_banned_killstreaks = Array ( "KILLSTREAK_RCBOMB", + "KILLSTREAK_QRDRONE", + /* "KILLSTREAK_REMOTE_MISSILE",*/ + "KILLSTREAK_REMOTE_MORTAR", + "KILLSTREAK_HELICOPTER_GUNNER" ); + for ( ;; ) + { + level waittill( "connected", player ); + + if ( !player IsTestClient() ) + { + continue; + } + + player thread on_bot_connect(); + } +} + +function on_bot_connect() +{ + self endon( "disconnect" ); + + if ( isdefined( self.pers[ "bot_loadout" ] ) ) + { + return; + } + + wait( 0.10 ); + + if ( self GetEntityNumber() % 2 == 0 ) + { + WAIT_SERVER_FRAME; + } + + self bot::set_rank(); + + self BotSetRandomCharacterCustomization(); + + + max_allocation = BOT_ALLOCATION_MAX; +/* + if ( SessionModeIsPrivate() ) + { + for ( i = 1; i <= BOT_ALLOCATION_UNLOCK_MAX; i++ ) + { + if ( self IsItemLocked( rank::GetItemIndex( "feature_allocation_slot_" + i ) ) ) + { + max_allocation--; + } + } + } +*/ + self construct_loadout( max_allocation ); + self.pers[ "bot_loadout" ] = true; +} + +function construct_loadout( allocation_max ) +{ +/* if ( SessionModeIsPrivate() && self IsItemLocked( rank::GetItemIndex( "feature_cac" ) ) ) + { + // cac still locked + return; + } +*/ + pixbeginevent( "bot_construct_loadout" ); + + item_list = build_item_list(); + +// item_list["primary"] = []; +// item_list["primary"][0] = "WEAPON_RIOTSHIELD"; + + construct_class( 0, item_list, allocation_max ); + construct_class( 1, item_list, allocation_max ); + construct_class( 2, item_list, allocation_max ); + construct_class( 3, item_list, allocation_max ); + construct_class( 4, item_list, allocation_max ); + + killstreaks = item_list["killstreak1"]; + + if ( isdefined( item_list["killstreak2"] ) ) + { + killstreaks = ArrayCombine( killstreaks, item_list["killstreak2"], true, false ); + } + + if ( isdefined( item_list["killstreak3"] ) ) + { + killstreaks = ArrayCombine( killstreaks, item_list["killstreak3"], true, false ); + } + + if ( isdefined( killstreaks ) && killstreaks.size ) + { + choose_weapon( 0, killstreaks ); + choose_weapon( 0, killstreaks ); + choose_weapon( 0, killstreaks ); + } + + self.claimed_items = undefined; + pixendevent(); +} + +function construct_class( constructclass, items, allocation_max ) +{ + allocation = 0; + + claimed_count = build_claimed_list( items ); + self.claimed_items = []; + + // primary + weapon = choose_weapon( constructclass, items["primary"] ); + claimed_count["primary"]++; + allocation++; + + // secondary + weapon = choose_weapon( constructclass, items["secondary"] ); + choose_weapon_option( constructclass, "camo", 1 ); +} + +function make_choice( chance, claimed, max_claim ) +{ + return ( claimed < max_claim && RandomInt( 100 ) < chance ); +} + +function chose_action( action1, chance1, action2, chance2, action3, chance3, action4, chance4 ) +{ + chance1 = Int( chance1 / 10 ); + chance2 = Int( chance2 / 10 ); + chance3 = Int( chance3 / 10 ); + chance4 = Int( chance4 / 10 ); + + actions = []; + + for( i = 0; i < chance1; i++ ) + { + actions[ actions.size ] = action1; + } + + for( i = 0; i < chance2; i++ ) + { + actions[ actions.size ] = action2; + } + + for( i = 0; i < chance3; i++ ) + { + actions[ actions.size ] = action3; + } + + for( i = 0; i < chance4; i++ ) + { + actions[ actions.size ] = action4; + } + + return array::random( actions ); +} + +function item_is_claimed( item ) +{ + foreach( claim in self.claimed_items ) + { + if ( claim == item ) + { + return true; + } + } + + return false; +} + +function choose_weapon( weaponclass, items ) +{ + if ( !isdefined( items ) || !items.size ) + { + return undefined; + } + + start = RandomInt( items.size ); + + for( i = 0; i < items.size; i++ ) + { + weapon = items[ start ]; + + if ( !item_is_claimed( weapon ) ) + { + break; + } + + start = ( start + 1 ) % items.size; + } + + self.claimed_items[ self.claimed_items.size ] = weapon; + + self BotClassAddItem( weaponclass, weapon ); + return weapon; +} + +function build_weapon_options_list( optionType ) +{ + level.botWeaponOptionsId[optionType] = []; + level.botWeaponOptionsProb[optionType] = []; + + csv_filename = "gamedata/weapons/common/attachmentTable.csv"; + prob = 0; + for ( row = 0 ; row < 255 ; row++ ) + { + if ( tableLookupColumnForRow( csv_filename, row, ATTACHMENT_TABLE_COL_TYPE ) == optionType ) + { + index = level.botWeaponOptionsId[optionType].size; + level.botWeaponOptionsId[optionType][index] = Int( tableLookupColumnForRow( csv_filename, row, ATTACHMENT_TABLE_COL_NUMBERING ) ); + prob += Int( tableLookupColumnForRow( csv_filename, row, ATTACHMENT_TABLE_COL_BOT_PROB ) ); + level.botWeaponOptionsProb[optionType][index] = prob; + } + } +} + +function choose_weapon_option( weaponclass, optionType, primary ) +{ + if ( !isdefined( level.botWeaponOptionsId ) ) + { + level.botWeaponOptionsId = []; + level.botWeaponOptionsProb = []; + + build_weapon_options_list( "camo" ); + build_weapon_options_list( "reticle" ); + } + + // weapon options cannot be set in local matches + if ( !level.onlineGame && !level.systemLink ) + return; + + // Increase the range of the probability to reduce the chances of picking the option when the bot's level is less than BOT_RANK_ALL_OPTIONS_AVAILABLE + // (in system link all options are available) + numOptions = level.botWeaponOptionsProb[optionType].size; + maxProb = level.botWeaponOptionsProb[optionType][numOptions-1]; + if ( !level.systemLink && self.pers[ "rank" ] < BOT_RANK_ALL_OPTIONS_AVAILABLE ) + maxProb += BOT_RANK_OPTIONS_MULTIPLIER * maxProb * ( ( BOT_RANK_ALL_OPTIONS_AVAILABLE - self.pers[ "rank" ] ) / BOT_RANK_ALL_OPTIONS_AVAILABLE ); + + rnd = RandomInt( Int( maxProb ) ); + for (i=0 ; i rnd ) + { + self BotClassSetWeaponOption( weaponclass, primary, optionType, level.botWeaponOptionsId[optionType][i] ); + break; + } + } +} + +function choose_primary_attachments( weaponclass, weapon, allocation, allocation_max ) +{ + attachments = weapon.supportedAttachments; + remaining = allocation_max - allocation; + + if ( !attachments.size || !remaining ) + { + return 0; + } + + attachment_action = chose_action( "3_attachments", 25, "2_attachments", 65, "1_attachments", 10, "none", 5 ); + + if ( remaining >= 4 && attachment_action == "3_attachments" ) + { + a1 = array::random( attachments ); + self BotClassAddAttachment( weaponclass, weapon, a1, "primaryattachment1" ); + count = 1; + + attachments = GetWeaponAttachments( weapon, a1 ); + + if ( attachments.size ) + { + a2 = array::random( attachments ); + self BotClassAddAttachment( weaponclass, weapon, a2, "primaryattachment2" ); + count++; + + attachments = GetWeaponAttachments( weapon, a1, a2 ); + + if ( attachments.size ) + { + a3 = array::random( attachments ); + self BotClassAddItem( weaponclass, "BONUSCARD_PRIMARY_GUNFIGHTER" ); + self BotClassAddAttachment( weaponclass, weapon, a3, "primaryattachment3" ); + return 4; + } + } + + return count; + } + else if ( remaining >= 2 && attachment_action == "2_attachments" ) + { + a1 = array::random( attachments ); + self BotClassAddAttachment( weaponclass, weapon, a1, "primaryattachment1" ); + + attachments = GetWeaponAttachments( weapon, a1 ); + + if ( attachments.size ) + { + a2 = array::random( attachments ); + self BotClassAddAttachment( weaponclass, weapon, a2, "primaryattachment2" ); + return 2; + } + + return 1; + } + else if ( remaining >= 1 && attachment_action == "1_attachments" ) + { + a = array::random( attachments ); + self BotClassAddAttachment( weaponclass, weapon, a, "primaryattachment1" ); + return 1; + } + + return 0; +} + +function choose_secondary_attachments( weaponclass, weapon, allocation, allocation_max ) +{ + attachments = weapon.supportedAttachments ; + remaining = allocation_max - allocation; + + if ( !attachments.size || !remaining ) + { + return 0; + } + + attachment_action = chose_action( "2_attachments", 10, "1_attachments", 40, "none", 50, "none", 0 ); + + if ( remaining >= 3 && attachment_action == "2_attachments" ) + { + a1 = array::random( attachments ); + self BotClassAddAttachment( weaponclass, weapon, a1, "secondaryattachment1" ); + + attachments = GetWeaponAttachments( weapon, a1 ); + + if ( attachments.size ) + { + a2 = array::random( attachments ); + self BotClassAddItem( weaponclass, "BONUSCARD_SECONDARY_GUNFIGHTER" ); + self BotClassAddAttachment( weaponclass, weapon, a2, "secondaryattachment2" ); + return 3; + } + + return 1; + } + else if ( remaining >= 1 && attachment_action == "1_attachments" ) + { + a = array::random( attachments ); + self BotClassAddAttachment( weaponclass, weapon, a, "secondaryattachment1" ); + return 1; + } + + return 0; +} + +function build_item_list() +{ + items = []; + + for( i = 0; i < STATS_TABLE_MAX_ITEMS; i++ ) + { + row = tableLookupRowNum( level.statsTableID, STATS_TABLE_COL_NUMBERING, i ); + + if ( row > -1 ) + { + slot = tableLookupColumnForRow( level.statsTableID, row, STATS_TABLE_COL_SLOT ); + + if ( slot == "" ) + { + continue; + } + + number = Int( tableLookupColumnForRow( level.statsTableID, row, STATS_TABLE_COL_NUMBERING ) ); +/* + if ( SessionModeIsPrivate() && self IsItemLocked( number ) ) + { + continue; + } +*/ + allocation = Int( tableLookupColumnForRow( level.statsTableID, row, STATS_TABLE_COL_ALLOCATION ) ); + + if ( allocation < 0 ) + { + continue; + } + + name = tableLookupColumnForRow( level.statsTableID, row, STATS_TABLE_COL_NAME ); +/* + if ( item_is_banned( slot, name ) ) + { + continue; + } +*/ + if ( !isdefined( items[slot] ) ) + { + items[slot] = []; + } + + items[ slot ][ items[slot].size ] = name; + } + } + + return items; +} + + +function build_claimed_list( items ) +{ + claimed = []; + keys = GetArrayKeys( items ); + + foreach( key in keys ) + { + claimed[ key ] = 0; + } + + return claimed; +} \ No newline at end of file diff --git a/data/scripts/mp/gametypes/_globallogic_player.gsc b/data/scripts/mp/gametypes/_globallogic_player.gsc new file mode 100644 index 0000000..b067305 Binary files /dev/null and b/data/scripts/mp/gametypes/_globallogic_player.gsc differ diff --git a/data/scripts/mp/gametypes/_globallogic_player.gsc_raw b/data/scripts/mp/gametypes/_globallogic_player.gsc_raw new file mode 100644 index 0000000..6b8e3a8 --- /dev/null +++ b/data/scripts/mp/gametypes/_globallogic_player.gsc_raw @@ -0,0 +1,4524 @@ +#using scripts\shared\abilities\_ability_player; +#using scripts\shared\abilities\_ability_power; +#using scripts\shared\abilities\_ability_util; +#using scripts\shared\callbacks_shared; +#using scripts\shared\challenges_shared; +#using scripts\shared\clientfield_shared; +#using scripts\shared\damagefeedback_shared; +#using scripts\shared\demo_shared; +#using scripts\shared\flag_shared; +#using scripts\shared\hostmigration_shared; +#using scripts\shared\hud_message_shared; +#using scripts\shared\hud_util_shared; +#using scripts\shared\killstreaks_shared; +#using scripts\shared\math_shared; +#using scripts\shared\medals_shared; +#using scripts\shared\persistence_shared; +#using scripts\shared\player_shared; +#using scripts\shared\rank_shared; +#using scripts\shared\scoreevents_shared; +#using scripts\shared\tweakables_shared; +#using scripts\shared\util_shared; +#using scripts\shared\weapons_shared; +#using scripts\shared\weapons\_weapon_utils; +#using scripts\shared\weapons\_weapons; +#using scripts\shared\ai\systems\gib; + +#using scripts\mp\gametypes\_battlechatter; +#using scripts\mp\gametypes\_deathicons; +#using scripts\mp\gametypes\_globallogic; +#using scripts\mp\gametypes\_globallogic_audio; +#using scripts\mp\gametypes\_globallogic_score; +#using scripts\mp\gametypes\_globallogic_spawn; +#using scripts\mp\gametypes\_globallogic_ui; +#using scripts\mp\gametypes\_globallogic_utils; +#using scripts\mp\gametypes\_globallogic_vehicle; +#using scripts\mp\gametypes\_hostmigration; +#using scripts\mp\gametypes\_hud_message; +#using scripts\mp\gametypes\_killcam; +#using scripts\mp\gametypes\_loadout; +#using scripts\mp\gametypes\_spawning; +#using scripts\mp\gametypes\_spawnlogic; +#using scripts\mp\gametypes\_spectating; +#using scripts\mp\gametypes\_weapons; + +#using scripts\mp\_armor; +#using scripts\mp\_behavior_tracker; +#using scripts\shared\_burnplayer; +#using scripts\mp\_challenges; +#using scripts\mp\_contracts; +#using scripts\mp\_gamerep; +#using scripts\mp\_laststand; +#using scripts\mp\_teamops; +#using scripts\mp\_util; +#using scripts\mp\_vehicle; +#using scripts\mp\killstreaks\_killstreaks; +#using scripts\mp\teams\_teams; + +#namespace globallogic_player; + +function on_joined_team() +{ + // for cod caster update the top scorers + if ( !level.rankedMatch && !level.teambased ) + { + level thread update_ffa_top_scorers(); + } +} + +function freezePlayerForRoundEnd() +{ + self util::clearLowerMessage(); + + self closeInGameMenu(); + + self util::freeze_player_controls( true ); + + if( !SessionModeIsZombiesGame() ) + { + currentWeapon = self GetCurrentWeapon(); + if ( killstreaks::is_killstreak_weapon( currentWeapon ) && !currentWeapon.isCarriedKillstreak ) + self takeWeapon( currentWeapon ); + } + + //self util::_disableWeapon(); +} + +function ArrayToString( inputArray ) +{ + targetString = ""; + for (i=0; i < inputArray.size; i++) + { + targetString += inputArray[i]; + if (i != inputArray.size-1) + targetString += ","; + } + return targetString; +} + + +function recordEndGameComScoreEventForPlayer( player, result ) +{ + lpselfnum = player getEntityNumber(); + lpXuid = player getxuid(true); + bbPrint( "global_leave", "name %s client %s xuid %s", player.name, lpselfnum, lpXuid ); + + weeklyAContractId = 0; + weeklyAContractTarget = 0; + weeklyAContractCurrent = 0; + weeklyAContractCompleted = 0; + + weeklyBContractId = 0; + weeklyBContractTarget = 0; + weeklyBContractCurrent = 0; + weeklyBContractCompleted = 0; + + dailyContractId = 0; + dailyContractTarget = 0; + dailyContractCurrent = 0; + dailyContractCompleted = 0; + + specialContractId = 0; + specialContractTarget = 0; + specialContractCurent = 0; + specialContractCompleted = 0; + + if ( player util::is_bot() ) + { + currXP = 0; + prevXP = 0; + } + else + { + currXP = player rank::getRankXpStat(); + prevXP = player.pers["rankxp"]; + + if ( globallogic_score::canUpdateWeaponContractStats( player ) ) + { + specialContractId = 1; // this is a one-off contract. Use any non-zero value to indicate that it is populated. + specialContractTarget = GetDvarInt( "weapon_contract_target_value", 100 ); + specialContractCurent = player GetDStat( "weaponContractData", "currentValue" ); + if ( (isdefined(player GetDStat( "weaponContractData", "completeTimestamp" ))?player GetDStat( "weaponContractData", "completeTimestamp" ):0) != 0 ) + { + specialContractCompleted = 1; + } + } + + if ( player contracts::can_process_contracts() ) + { + contractId = player contracts::get_contract_stat( 0, "index" ); + if ( player contracts::is_contract_active( contractId ) ) + { + weeklyAContractId = contractId; + weeklyAContractTarget = player.pers[ "contracts" ][ weeklyAContractId ].target_value; + weeklyAContractCurrent = player contracts::get_contract_stat( 0, "progress" ); + weeklyAContractCompleted = player contracts::get_contract_stat( 0, "award_given" ); + } + + contractId = player contracts::get_contract_stat( 1, "index" ); + if ( player contracts::is_contract_active( contractId ) ) + { + weeklyBContractId = contractId; + weeklyBContractTarget = player.pers["contracts" ][ weeklyBContractId ].target_value; + weeklyBContractCurrent = player contracts::get_contract_stat( 1, "progress" ); + weeklyBContractCompleted = player contracts::get_contract_stat( 1, "award_given" ); + } + + contractId = player contracts::get_contract_stat( 2, "index" ); + if ( player contracts::is_contract_active( contractId ) ) + { + dailyContractId = contractId; + dailyContractTarget = player.pers[ "contracts" ][ dailyContractId ].target_value; + dailyContractCurrent = player contracts::get_contract_stat( 2, "progress" ); + dailyContractCompleted = player contracts::get_contract_stat( 2, "award_given" ); + } + } + } + + if ( !isdefined( prevXP ) ) + { + // most likely the player never fully connected in the first place + // it is possible to specify a default value for prevXP, + // however, the call to RecordComScoreEvent() will SRE as most of player.pers[] is missing + return; + } + + resultStr = result; + if ( isDefined(player.team) && result == player.team ) + resultStr ="win"; + else if ( result == "allies" || result == "axis" ) + resultStr = "lose"; + + xpEarned = currXP - prevXP; + + perkStr = ArrayToString( player GetPerks() ); + + primaryWeaponName = ""; + primaryWeaponAttachStr=""; + secondaryWeaponName = ""; + secondaryWeaponAttachStr=""; + grenadePrimaryName = ""; + grenadeSecondaryName = ""; + + + + if (isdefined( player.primaryLoadoutWeapon )) + { + primaryWeaponName = player.primaryLoadoutWeapon.name; + primaryWeaponAttachStr = ArrayToString( GetArrayKeys(player.primaryLoadoutWeapon.attachments) ); + } + if (isdefined( player.secondaryLoadoutWeapon )) + { + secondaryWeaponName = player.secondaryLoadoutWeapon.name; + secondaryWeaponAttachStr = ArrayToString( GetArrayKeys(player.secondaryLoadoutWeapon.attachments) ); + } + + if (isdefined( player.grenadeTypePrimary )) + grenadePrimaryName = player.grenadeTypePrimary.name; + if (isdefined( player.grenadeTypeSecondary )) + grenadeSecondaryName = player.grenadeTypeSecondary.name; + + killStreakStr = ArrayToString( player.killstreak ); + + gameLength = game["timepassed"] / 1000; + timePlayed = player globallogic::getTotalTimePlayed( gameLength ); + + totalKills = 0; + totalHits = 0; + totalDeaths = 0; + totalWins = 0; + totalXP = 0; + + if ( level.gametype != "fr" ) + { + totalKills = player GetDStat( "playerstatslist", "kills", "statValue" ); + totalHits = player GetDStat( "playerstatslist", "hits", "statValue" ); + totalDeaths = player GetDStat( "playerstatslist", "deaths", "statValue" ); + totalWins = player GetDStat( "playerstatslist", "wins", "statValue" ); + totalXP = player GetDStat( "playerstatslist", "rankxp", "statValue" ); + } + + killCount = 0; + hitCount = 0; + + if( level.mpCustomMatch ) + { + killCount = player.kills; + hitCount = player.shotshit; + } + else + { + if ( isdefined( player.startKills ) ) + killCount = totalKills - player.startKills; + + if ( isdefined( player.startHits ) ) + hitCount = totalHits - player.startHits; + } + + bestScore = "0"; + if ( isdefined( player.pers["lastHighestScore"] ) && player.score > player.pers["lastHighestScore"] ) + bestScore = "1"; + + bestKills = "0"; + if ( isdefined( player.pers["lastHighestKills"] ) && killCount > player.pers["lastHighestKills"] ) + bestKills = "1"; + + totalMatchShots = 0; + if ( isdefined( player.totalMatchShots) ) + totalMatchShots = player.totalMatchShots; + + deaths = player.deaths; + if (deaths == 0) + deaths = 1; + kdRatio = player.kills*1000/deaths; + bestKDRatio = "0"; + if ( isdefined( player.pers["lastHighestKDRatio"] ) && kdRatio > player.pers["lastHighestKDRatio"] ) + bestKDRatio = "1"; + + showcaseWeapon = player GetPlayerShowcaseWeapon(); + + RecordComScoreEvent( "end_match", + "match_id", getDemoFileID(), + "game_variant", "mp", + "game_mode", level.gametype, + "private_match", SessionModeIsPrivate(), + "esports_flag", level.leagueMatch, + "ranked_play_flag", level.arenaMatch, + "league_team_id", player getLeagueTeamID(), + "game_map", GetDvarString( "mapname" ), + "player_xuid", player getxuid(true), + "player_ip", player getipaddress(), + "match_kills", killCount, + "match_deaths", player.deaths, + "match_xp", xpEarned, + "match_score", player.score, + "match_streak", player.pers["best_kill_streak"], + "match_captures", player.pers["captures"], + "match_defends", player.pers["defends"], + "match_headshots", player.pers["headshots"], + "match_longshots", player.pers["longshots"], + "match_objtime", player.pers["objtime"], + "match_plants", player.pers["plants"], + "match_defuses", player.pers["defuses"], + "match_throws", player.pers["throws"], + "match_carries", player.pers["carries"], + "match_returns", player.pers["returns"], + "prestige_max", player.pers["plevel"], + "level_max", player.pers["rank"], + "match_result", resultStr, + "match_duration", timePlayed, + "match_shots", totalMatchShots, + "match_hits", hitCount, + "player_gender", player GetPlayerGenderType( CurrentSessionMode() ), + "specialist_kills", player.heroweaponKillCount, + "specialist_used", player GetMpDialogName(), + "season_pass_owned", player HasSeasonPass(0), + "loadout_perks", perkStr, + "loadout_lethal", grenadePrimaryName, + "loadout_tactical", grenadeSecondaryName, + "loadout_scorestreaks", killStreakStr, + "loadout_primary_weapon", primaryWeaponName, + "loadout_secondary_weapon", secondaryWeaponName, + "dlc_owned", player GetDLCAvailable(), + "loadout_primary_attachments", primaryWeaponAttachStr, + "loadout_secondary_attachments",secondaryWeaponAttachStr, + "best_score", bestScore, + "best_kills", bestKills, + "best_kd", bestKDRatio, + "total_kills", totalKills, + "total_deaths", totalDeaths, + "total_wins", totalWins, + "total_xp", totalXP, + "daily_contract_id", dailyContractId, + "daily_contract_target", dailyContractTarget, + "daily_contract_current", dailyContractCurrent, + "daily_contract_completed", dailyContractCompleted, + "weeklyA_contract_id", weeklyAContractId, + "weeklyA_contract_target", weeklyAContractTarget, + "weeklyA_contract_current", weeklyAContractCurrent, + "weeklyA_contract_completed", weeklyAContractCompleted, + "weeklyB_contract_id", weeklyBContractId, + "weeklyB_contract_target", weeklyBContractTarget, + "weeklyB_contract_current", weeklyBContractCurrent, + "weeklyB_contract_completed", weeklyBContractCompleted, + "special_contract_id ", specialContractId, + "special_contract_target", specialContractTarget, + "special_contract_curent", specialContractCurent, + "special_contract_completed", specialContractCompleted, + "specialist_power", player.heroabilityname, + "specialist_head", player GetCharacterHelmetModel(), + "specialist_body", player GetCharacterBodyModel(), + "specialist_taunt", player GetPlayerSelectedTauntName( 0 ), + "specialist_goodgame", player GetPlayerSelectedGestureName( 0 ), + "specialist_threaten", player GetPlayerSelectedGestureName( 1 ), + "specialist_boast", player GetPlayerSelectedGestureName( 2 ), + "specialist_showcase", showcaseWeapon.weapon.name + ); +} + +function player_monitor_travel_dist() +{ + self endon ( "death" ); + self endon ( "disconnect" ); + waitTime = 1; + minimumMoveDistance = 16; + + //Ignore data immediatly after spawn + wait 4; + + prevpos = self.origin; + positionPTM = self.origin; + while( 1 ) + { + wait waitTime; + + if (self util::isUsingRemote()) + { + self waittill ("stopped_using_remote"); + prevpos = self.origin; + positionPTM = self.origin; + continue; + } + + distance = distance( self.origin, prevpos ); + self.pers["total_distance_travelled"] += distance; + self.pers["movement_Update_Count"]++; + prevpos = self.origin; + + if ((self.pers["movement_Update_Count"] % 5) == 0) + { + distanceMoving = distance(self.origin, positionPTM); + positionPTM = self.origin; + if ( distanceMoving > minimumMoveDistance ) + { + self.pers["num_speeds_when_moving_entries"]++; + self.pers["total_speeds_when_moving"] += ( distanceMoving / waitTime ); + self.pers["time_played_moving"] += waitTime; + } + } + + + } +} + +function record_special_move_data_for_life( killer ) +{ + // safe to assume fields on self exist? + if( !isDefined( self.lastSwimmingStartTime) || !isDefined( self.lastWallRunStartTime) || !isDefined( self.lastSlideStartTime) || !isDefined( self.lastDoubleJumpStartTime) || + !isDefined( self.timeSpentSwimmingInLife) || !isDefined( self.timeSpentWallRunningInLife) || !isDefined( self.numberOfDoubleJumpsInLife) || !isDefined( self.numberOfSlidesInLife) ) + { + /# + println( "record_special_move_data_for_life - fields on self not defined!"); + #/ + return; + } + + if( isDefined(killer) ) + { + if( !isDefined( killer.lastSwimmingStartTime) || !isDefined( killer.lastWallRunStartTime) || !isDefined( killer.lastSlideStartTime) || !isDefined( killer.lastDoubleJumpStartTime) ) + { + /# + println( "record_special_move_data_for_life - fields one killer not defined!"); + #/ + return; + } + matchRecordLogSpecialMoveDataForLife( self, self.lastSwimmingStartTime, self.lastWallRunStartTime, self.lastSlideStartTime, self.lastDoubleJumpStartTime, + self.timeSpentSwimmingInLife, self.timeSpentWallRunningInLife, self.numberOfDoubleJumpsInLife, self.numberOfSlidesInLife, + killer, killer.lastSwimmingStartTime, killer.lastWallRunStartTime, killer.lastSlideStartTime, killer.lastDoubleJumpStartTime ); + } + else + { + matchRecordLogSpecialMoveDataForLife( self, self.lastSwimmingStartTime, self.lastWallRunStartTime, self.lastSlideStartTime, self.lastDoubleJumpStartTime, + self.timeSpentSwimmingInLife, self.timeSpentWallRunningInLife, self.numberOfDoubleJumpsInLife, self.numberOfSlidesInLife ); + } + +} + +function player_monitor_wall_run() +{ + self endon ( "disconnect" ); + + // make sure no other stray threads running on this dude + self notify("stop_player_monitor_wall_run"); + self endon("stop_player_monitor_wall_run"); + + self.lastWallRunStartTime = 0; + self.timeSpentWallRunningInLife = 0; + while ( true ) + { + notification = self util::waittill_any_return( "wallrun_begin", "death", "disconnect", "stop_player_monitor_wall_run" ); + if( notification == "death" ) + break; // end thread + + self.lastWallRunStartTime = getTime(); + + notification = self util::waittill_any_return( "wallrun_end", "death", "disconnect", "stop_player_monitor_wall_run" ); + + self.timeSpentWallRunningInLife += (getTime() - self.lastWallRunStartTime); + + if( notification == "death" ) + break; // end thread + + } +} + +function player_monitor_swimming() +{ + self endon ( "disconnect" ); + + // make sure no other stray threads running on this dude + self notify("stop_player_monitor_swimming"); + self endon("stop_player_monitor_swimming"); + + self.lastSwimmingStartTime = 0; + self.timeSpentSwimmingInLife = 0; + while ( true ) + { + notification = self util::waittill_any_return( "swimming_begin", "death", "disconnect", "stop_player_monitor_swimming" ); + if( notification == "death" ) + break; // end thread + + self.lastSwimmingStartTime = getTime(); + + notification = self util::waittill_any_return( "swimming_end", "death", "disconnect", "stop_player_monitor_swimming" ); + + self.timeSpentSwimmingInLife += (getTime() - self.lastSwimmingStartTime); + + if( notification == "death" ) + break; // end thread + + } +} + +function player_monitor_slide() +{ + self endon ( "disconnect" ); + + // make sure no other stray threads running on this dude + self notify("stop_player_monitor_slide"); + self endon("stop_player_monitor_slide"); + + self.lastSlideStartTime = 0; + self.numberOfSlidesInLife = 0; + while ( true ) + { + notification = self util::waittill_any_return( "slide_begin", "death", "disconnect", "stop_player_monitor_slide" ); + if( notification == "death" ) + break; // end thread + + self.lastSlideStartTime = getTime(); + self.numberOfSlidesInLife++; + + notification = self util::waittill_any_return( "slide_end", "death", "disconnect", "stop_player_monitor_slide" ); + + if( notification == "death" ) + break; // end thread + } +} + +function player_monitor_doublejump() +{ + self endon ( "disconnect" ); + + // make sure no other stray threads running on this dude + self notify("stop_player_monitor_doublejump"); + self endon("stop_player_monitor_doublejump"); + + self.lastDoubleJumpStartTime = 0; + self.numberOfDoubleJumpsInLife = 0; + while ( true ) + { + notification = self util::waittill_any_return( "doublejump_begin", "death", "disconnect", "stop_player_monitor_doublejump" ); + if( notification == "death" ) + break; // end thread + + self.lastDoubleJumpStartTime = getTime(); + self.numberOfDoubleJumpsInLife++; + + notification = self util::waittill_any_return( "doublejump_end", "death", "disconnect", "stop_player_monitor_doublejump" ); + + if( notification == "death" ) + break; // end thread + } +} + + +function player_monitor_inactivity() +{ + self endon ( "disconnect" ); + + self notify( "player_monitor_inactivity" ); + self endon( "player_monitor_inactivity" ); + + wait 10; + + while( true ) + { + if ( isdefined( self ) ) + { + if ( self isRemoteControlling() || self util::isUsingRemote() ) + { + self ResetInactivityTimer(); + } + } + wait 5; + } +} + +function Callback_PlayerConnect() +{ + thread notifyConnecting(); + + self.statusicon = "hud_status_connecting"; + self waittill( "begin" ); + + if( isdefined( level.reset_clientdvars ) ) + self [[level.reset_clientdvars]](); + + waittillframeend; + self.statusicon = ""; + + self.guid = self getXuid(); + + self.killstreak = []; + + self.leaderDialogQueue = []; + self.killstreakDialogQueue = []; + + profilelog_begintiming( 4, "ship" ); + + level notify( "connected", self ); + callback::callback( #"on_player_connect" ); + + if ( self IsHost() ) + self thread globallogic::listenForGameEnd(); + + // only print that we connected if we haven't connected in a previous round + if( !level.splitscreen && !isdefined( self.pers["score"] ) ) + { + iPrintLn(&"MP_CONNECTED", self); + } + + if( !isdefined( self.pers["score"] ) ) + { + self thread persistence::adjust_recent_stats(); + self persistence::set_after_action_report_stat( "valid", 0 ); + if ( GameModeIsMode( 3 ) && !( self IsHost() ) ) + self persistence::set_after_action_report_stat( "wagerMatchFailed", 1 ); + else + self persistence::set_after_action_report_stat( "wagerMatchFailed", 0 ); + } + + // track match and hosting stats once per match + if( ( level.rankedMatch || level.wagerMatch || level.leagueMatch ) && !isdefined( self.pers["matchesPlayedStatsTracked"] ) ) + { + gameMode = util::GetCurrentGameMode(); + self globallogic::IncrementMatchCompletionStat( gameMode, "played", "started" ); + + if ( !isdefined( self.pers["matchesHostedStatsTracked"] ) && self IsLocalToHost() ) + { + self globallogic::IncrementMatchCompletionStat( gameMode, "hosted", "started" ); + self.pers["matchesHostedStatsTracked"] = true; + } + + self.pers["matchesPlayedStatsTracked"] = true; + self thread persistence::upload_stats_soon(); + } + + self gamerep::gameRepPlayerConnected(); + + lpselfnum = self getEntityNumber(); + lpGuid = self getXuid(); + lpXuid = self getxuid(true); + + if (self util::is_bot()) + { + lpGuid = "bot0"; + } + + logPrint("J;" + lpGuid + ";" + lpselfnum + ";" + self.name + "\n"); + bbPrint( "global_joins", "name %s client %s xuid %s", self.name, lpselfnum, lpXuid ); + + // needed for cross-referencing into player breadcrumb buffer + // will get out of sync with self.clientId with disconnects/connects + recordPlayerStats( self, "codeClientNum", lpselfnum); + + if( !SessionModeIsZombiesGame() ) // it will be set after intro screen is faded out for zombie + { + self setClientUIVisibilityFlag( "hud_visible", 1 ); + self setClientUIVisibilityFlag( "weapon_hud_visible", 1 ); + } + + self SetClientPlayerSprintTime( level.playerSprintTime ); + self SetClientNumLives( level.numLives ); + + //makeDvarServerInfo( "cg_drawTalk", 1 ); + + if ( level.hardcoreMode ) + { + self SetClientDrawTalk( 3 ); + } + + if( SessionModeIsZombiesGame() ) + { + // initial zombies stats + self [[level.player_stats_init]](); + } + else + { + + self globallogic_score::initPersStat( "score" ); + if ( level.resetPlayerScoreEveryRound ) + { + self.pers["score"] = 0; + } + self.score = self.pers["score"]; + + self globallogic_score::initPersStat( "pointstowin" ); + if ( level.scoreRoundWinBased ) + { + self.pers["pointstowin"] = 0; + } + self.pointstowin = self.pers["pointstowin"]; + + self globallogic_score::initPersStat( "momentum", false ); + self.momentum = self globallogic_score::getPersStat( "momentum" ); + + self globallogic_score::initPersStat( "suicides" ); + self.suicides = self globallogic_score::getPersStat( "suicides" ); + + self globallogic_score::initPersStat( "headshots" ); + self.headshots = self globallogic_score::getPersStat( "headshots" ); + + self globallogic_score::initPersStat( "challenges" ); + self.challenges = self globallogic_score::getPersStat( "challenges" ); + + self globallogic_score::initPersStat( "kills" ); + self.kills = self globallogic_score::getPersStat( "kills" ); + + self globallogic_score::initPersStat( "deaths" ); + self.deaths = self globallogic_score::getPersStat( "deaths" ); + + self globallogic_score::initPersStat( "assists" ); + self.assists = self globallogic_score::getPersStat( "assists" ); + + self globallogic_score::initPersStat( "defends", false ); + self.defends = self globallogic_score::getPersStat( "defends" ); + + self globallogic_score::initPersStat( "offends", false ); + self.offends = self globallogic_score::getPersStat( "offends" ); + + self globallogic_score::initPersStat( "plants", false ); + self.plants = self globallogic_score::getPersStat( "plants" ); + + self globallogic_score::initPersStat( "defuses", false ); + self.defuses = self globallogic_score::getPersStat( "defuses" ); + + self globallogic_score::initPersStat( "returns", false ); + self.returns = self globallogic_score::getPersStat( "returns" ); + + self globallogic_score::initPersStat( "captures", false ); + self.captures = self globallogic_score::getPersStat( "captures" ); + + self globallogic_score::initPersStat( "objtime", false ); + self.objtime = self globallogic_score::getPersStat( "objtime" ); + + self globallogic_score::initPersStat( "carries", false ); + self.carries = self globallogic_score::getPersStat( "carries" ); + + self globallogic_score::initPersStat( "throws", false ); + self.throws = self globallogic_score::getPersStat( "throws" ); + + self globallogic_score::initPersStat( "destructions", false ); + self.destructions = self globallogic_score::getPersStat( "destructions" ); + + self globallogic_score::initPersStat( "disables", false ); + self.disables = self globallogic_score::getPersStat( "disables" ); + + self globallogic_score::initPersStat( "escorts", false ); + self.escorts = self globallogic_score::getPersStat( "escorts" ); + + self globallogic_score::initPersStat( "infects", false ); + self.infects = self globallogic_score::getPersStat( "infects" ); + + self globallogic_score::initPersStat( "sbtimeplayed", false ); + self.sbtimeplayed = self globallogic_score::getPersStat( "sbtimeplayed" ); + + self globallogic_score::initPersStat( "backstabs", false ); + self.backstabs = self globallogic_score::getPersStat( "backstabs" ); + + self globallogic_score::initPersStat( "longshots", false ); + self.longshots = self globallogic_score::getPersStat( "longshots" ); + + self globallogic_score::initPersStat( "survived", false ); + self.survived = self globallogic_score::getPersStat( "survived" ); + + self globallogic_score::initPersStat( "stabs", false ); + self.stabs = self globallogic_score::getPersStat( "stabs" ); + + self globallogic_score::initPersStat( "tomahawks", false ); + self.tomahawks = self globallogic_score::getPersStat( "tomahawks" ); + + self globallogic_score::initPersStat( "humiliated", false ); + self.humiliated = self globallogic_score::getPersStat( "humiliated" ); + + self globallogic_score::initPersStat( "x2score", false ); + self.x2score = self globallogic_score::getPersStat( "x2score" ); + + self globallogic_score::initPersStat( "agrkills", false ); + self.x2score = self globallogic_score::getPersStat( "agrkills" ); + + self globallogic_score::initPersStat( "hacks", false ); + self.x2score = self globallogic_score::getPersStat( "hacks" ); + + self globallogic_score::initPersStat( "killsconfirmed", false ); + self.killsconfirmed = self globallogic_score::getPersStat( "killsconfirmed" ); + + self globallogic_score::initPersStat( "killsdenied", false ); + self.killsdenied = self globallogic_score::getPersStat( "killsdenied" ); + + self globallogic_score::initPersStat( "rescues", false ); + self.rescues = self globallogic_score::getPersStat( "rescues" ); + + self globallogic_score::initPersStat( "shotsfired", false ); + self.shotsfired = self globallogic_score::getPersStat( "shotsfired" ); + + self globallogic_score::initPersStat( "shotshit", false ); + self.shotshit = self globallogic_score::getPersStat( "shotshit" ); + + self globallogic_score::initPersStat( "shotsmissed", false ); + self.shotsmissed = self globallogic_score::getPersStat( "shotsmissed" ); + + self globallogic_score::initPersStat( "cleandeposits", false ); + self.cleandeposits = self globallogic_score::getPersStat( "cleandeposits" ); + + self globallogic_score::initPersStat( "cleandenies", false ); + self.cleandenies = self globallogic_score::getPersStat( "cleandenies" ); + + self globallogic_score::initPersStat( "victory", false ); + self.victory = self globallogic_score::getPersStat( "victory" ); + + self globallogic_score::initPersStat( "sessionbans", false ); + self.sessionbans = self globallogic_score::getPersStat( "sessionbans" ); + self globallogic_score::initPersStat( "gametypeban", false ); + self globallogic_score::initPersStat( "time_played_total", false ); + self globallogic_score::initPersStat( "time_played_alive", false ); + + self globallogic_score::initPersStat( "teamkills", false ); + self globallogic_score::initPersStat( "teamkills_nostats", false ); + + // used by match recorder for analyzing play styles + self globallogic_score::initPersStat( "kill_distances", false ); + self globallogic_score::initPersStat( "num_kill_distance_entries", false ); + self globallogic_score::initPersStat( "time_played_moving", false ); + self globallogic_score::initPersStat( "total_speeds_when_moving", false ); + self globallogic_score::initPersStat( "num_speeds_when_moving_entries", false ); + self globallogic_score::initPersStat( "total_distance_travelled", false ); + self globallogic_score::initPersStat( "movement_Update_Count", false ); + + self.teamKillPunish = false; + if ( level.minimumAllowedTeamKills >= 0 && self.pers["teamkills_nostats"] > level.minimumAllowedTeamKills ) + self thread reduceTeamKillsOverTime(); + + self behaviorTracker::Initialize(); + } + + self.killedPlayersCurrent = []; + + if ( !isdefined( self.pers["totalTimePlayed"] ) ) + { + self setEnterTime( getTime() ); + self.pers["totalTimePlayed"] = 0; + } + + if ( !isdefined( self.pers["totalMatchBonus"] ) ) + { + self.pers["totalMatchBonus"] = 0; + } + + if( !isdefined( self.pers["best_kill_streak"] ) ) + { + self.pers["killed_players"] = []; + self.pers["killed_by"] = []; + self.pers["nemesis_tracking"] = []; + self.pers["artillery_kills"] = 0; + self.pers["dog_kills"] = 0; + self.pers["nemesis_name"] = ""; + self.pers["nemesis_rank"] = 0; + self.pers["nemesis_rankIcon"] = 0; + self.pers["nemesis_xp"] = 0; + self.pers["nemesis_xuid"] = ""; + self.pers["killed_players_with_specialist"] = []; + + /*self.killstreakKills["artillery"] = 0; + self.killstreakKills["dogs"] = 0; + self.killstreaksUsed["radar"] = 0; + self.killstreaksUsed["artillery"] = 0; + self.killstreaksUsed["dogs"] = 0;*/ + self.pers["best_kill_streak"] = 0; + } + +// Adding Music tracking per player CDC + if( !isdefined( self.pers["music"] ) ) + { + self.pers["music"] = spawnstruct(); + self.pers["music"].spawn = false; + self.pers["music"].inque = false; + self.pers["music"].currentState = "SILENT"; + self.pers["music"].previousState = "SILENT"; + self.pers["music"].nextstate = "UNDERSCORE"; + self.pers["music"].returnState = "UNDERSCORE"; + + } + + if ( self.team != "spectator" ) + { + self thread globallogic_audio::set_music_on_player( "spawnPreLoop" ); + } + + if ( !isdefined( self.pers["cur_kill_streak"] ) ) + { + self.pers["cur_kill_streak"] = 0; + } + + if ( !isdefined( self.pers["cur_total_kill_streak"] ) ) + { + self.pers["cur_total_kill_streak"] = 0; + self setplayercurrentstreak( 0 ); + } + + if ( !isdefined( self.pers["totalKillstreakCount"] ) ) + self.pers["totalKillstreakCount"] = 0; + + //Keep track of how many killstreaks have been earned in the current streak + if ( !isdefined( self.pers["killstreaksEarnedThisKillstreak"] ) ) + self.pers["killstreaksEarnedThisKillstreak"] = 0; + + if ( isdefined( level.usingScoreStreaks ) && level.usingScoreStreaks && !isdefined( self.pers["killstreak_quantity"] ) ) + self.pers["killstreak_quantity"] = []; + + if ( isdefined( level.usingScoreStreaks ) && level.usingScoreStreaks && !isdefined( self.pers["held_killstreak_ammo_count"] ) ) + self.pers["held_killstreak_ammo_count"] = []; + + if ( IsDefined( level.usingScoreStreaks ) && level.usingScoreStreaks && !IsDefined( self.pers["held_killstreak_clip_count"] ) ) + self.pers["held_killstreak_clip_count"] = []; + + if( !isDefined( self.pers["changed_class"] ) ) + self.pers["changed_class"] = false; + + if( !isDefined( self.pers["lastroundscore"] ) ) + self.pers["lastroundscore"] = 0; + + self.lastKillTime = 0; + + self.cur_death_streak = 0; + self disabledeathstreak(); + self.death_streak = 0; + self.kill_streak = 0; + self.gametype_kill_streak = 0; + self.spawnQueueIndex = -1; + self.deathTime = 0; + + self.aliveTimes = []; + for( index = 0; index < level.aliveTimeMaxCount; index++ ) + { + self.aliveTimes[index] = 0; + } + + self.aliveTimeCurrentIndex = 0; + + if ( level.onlineGame && !( isdefined( level.freerun ) && level.freerun ) ) + { + self.death_streak = self getDStat( "HighestStats", "death_streak" ); + self.kill_streak = self getDStat( "HighestStats", "kill_streak" ); + self.gametype_kill_streak = self persistence::stat_get_with_gametype( "kill_streak" ); + } + + self.lastGrenadeSuicideTime = -1; + + self.teamkillsThisRound = 0; + + if ( !isdefined( level.livesDoNotReset ) || !level.livesDoNotReset || !isdefined( self.pers["lives"] ) ) + { + self.pers["lives"] = level.numLives; + } + + // multi round FFA games in custom game mode should maintain team in-between rounds + if ( !level.teamBased ) + { + self.pers["team"] = undefined; + } + + self.hasSpawned = false; + self.waitingToSpawn = false; + self.wantSafeSpawn = false; + self.deathCount = 0; + + self.wasAliveAtMatchStart = false; + + level.players[level.players.size] = self; + + if( level.splitscreen ) + SetDvar( "splitscreen_playerNum", level.players.size ); + // removed underscore for debug CDC + // When joining a game in progress, if the game is at the post game state (scoreboard) the connecting player should spawn into intermission + if ( game["state"] == "postgame" ) + { + self.pers["needteam"] = 1; + self.pers["team"] = "spectator"; + self.team = self.sessionteam; + + self setClientUIVisibilityFlag( "hud_visible", 0 ); + + self [[level.spawnIntermission]](); + self closeInGameMenu(); + profilelog_endtiming( 4, "gs=" + game["state"] + " zom=" + SessionModeIsZombiesGame() ); + return; + } + + // don't count losses for CTF and S&D and War at each round. + if ( ( level.rankedMatch || level.wagerMatch || level.leagueMatch ) && !isdefined( self.pers["lossAlreadyReported"] ) ) + { + if ( level.leagueMatch ) + { + self recordLeaguePreLoser(); + } + + globallogic_score::updateLossStats( self ); + + self.pers["lossAlreadyReported"] = true; + } + if ((level.rankedMatch || level.leagueMatch) && !isDefined( self.pers["lateJoin"] ) ) + { + if (game["state"] == "playing" && !level.inPrematchPeriod ) + { + self.pers["lateJoin"] = true; + } + else + { + self.pers["lateJoin"] = false; + } + } + + // don't redo winstreak save to pers array for each round of round based games. + if ( !isdefined( self.pers["winstreakAlreadyCleared"] ) ) + { + self globallogic_score::backupAndClearWinStreaks(); + self.pers["winstreakAlreadyCleared"] = true; + } + + if( self istestclient() ) + { + self.pers[ "isBot" ] = true; + recordPlayerStats( self, "isBot", true); + } + + if ( level.rankedMatch || level.leagueMatch ) + { + self persistence::set_after_action_report_stat( "demoFileID", "0" ); + } + + level endon( "game_ended" ); + + if ( isdefined( level.hostMigrationTimer ) ) + self thread hostmigration::hostMigrationTimerThink(); + + if ( isdefined( self.pers["team"] ) ) + self.team = self.pers["team"]; + + if ( isdefined( self.pers["class"] ) ) + self.curClass = self.pers["class"]; + + if ( !isdefined( self.pers["team"] ) || isdefined( self.pers["needteam"] ) ) + { + // Don't set .sessionteam until we've gotten the assigned team from code, + // because it overrides the assigned team. + self.pers["needteam"] = undefined; + self.pers["team"] = "spectator"; + self.team = "spectator"; + self.sessionstate = "dead"; + + self globallogic_ui::updateObjectiveText(); + + [[level.spawnSpectator]](); + + [[level.autoassign]]( false ); + if ( level.rankedMatch || level.leagueMatch ) + { + self thread globallogic_spawn::kickIfDontSpawn(); + } + + if ( self.pers["team"] == "spectator" ) + { + self.sessionteam = "spectator"; + self thread spectate_player_watcher(); + } + + if ( level.teamBased ) + { + // set team and spectate permissions so the map shows waypoint info on connect + self.sessionteam = self.pers["team"]; + if ( !isAlive( self ) ) + self.statusicon = "hud_status_dead"; + self thread spectating::set_permissions(); + } + } + else if ( self.pers["team"] == "spectator" ) + { + self SetClientScriptMainMenu( game[ "menu_start_menu" ] ); + [[level.spawnSpectator]](); + self.sessionteam = "spectator"; + self.sessionstate = "spectator"; + self thread spectate_player_watcher(); + } + else + { + self.sessionteam = self.pers["team"]; + self.sessionstate = "dead"; + + self globallogic_ui::updateObjectiveText(); + + [[level.spawnSpectator]](); + + if ( globallogic_utils::isValidClass( self.pers["class"] ) || util::IsPropHuntGametype() ) + { + if ( !globallogic_utils::isValidClass( self.pers["class"] ) ) + { + self.pers["class"] = level.defaultClass; + self.curClass = level.defaultClass; + self SetClientScriptMainMenu( game[ "menu_start_menu" ] ); + } + self thread [[level.spawnClient]](); + } + else + { + self globallogic_ui::showMainMenuForTeam(); + } + + self thread spectating::set_permissions(); + } + + if ( self.sessionteam != "spectator" ) + { + self thread spawning::onSpawnPlayer(true); + } + + if ( level.forceRadar == 1 ) // radar always sweeping + { + self.pers["hasRadar"] = true; + self.hasSpyplane = true; + + if ( level.teambased ) + { + level.activeUAVs[self.team]++; + } + else + { + level.activeUAVs[self getEntityNumber()]++; + } + + level.activePlayerUAVs[self getEntityNumber()]++; + } + + if ( level.forceRadar == 2 ) // radar constant + { + self setClientUIVisibilityFlag( "g_compassShowEnemies", level.forceRadar ); + } + else + { + self SetClientUIVisibilityFlag( "g_compassShowEnemies", 0 ); + } + + profilelog_endtiming( 4, "gs=" + game["state"] + " zom=" + SessionModeIsZombiesGame() ); + + if ( isdefined( self.pers["isBot"] ) ) + return; + + self record_global_mp_stats_for_player_at_match_start(); + + //T7 - moved from load_shared to make sure this doesn't get set on CP until level.players is ready + num_con = getnumconnectedplayers(); + num_exp = getnumexpectedplayers(); + /#println( "all_players_connected(): getnumconnectedplayers=", num_con, "getnumexpectedplayers=", num_exp );#/ + + if(num_con == num_exp && (num_exp != 0)) + { + level flag::set( "all_players_connected" ); + // CODER_MOD: GMJ (08/28/08): Setting dvar for use by code + SetDvar( "all_players_are_connected", "1" ); + } + + globallogic_score::updateWeaponContractStart( self ); +} + +function record_global_mp_stats_for_player_at_match_start() +{ + // not sure if we even want/need this test + // if ( level.onlinegame && !SessionModeIsPrivate() ) ? + // if ( level.rankedMatch ) ? + // + // just copy from mp_stats, and it will do what it's supposed to + // (i.e. return something or 0) + + if( isdefined( level.disableStatTracking ) && level.disableStatTracking == true ) + { + return; + } + + startKills = self GetDStat( "playerstatslist", "kills", "statValue" ); + startDeaths = self GetDStat( "playerstatslist", "deaths", "statValue" ); + startWins = self GetDStat( "playerstatslist", "wins", "statValue" ); + startLosses = self GetDStat( "playerstatslist", "losses", "statValue" ); + startHits = self GetDStat( "playerstatslist", "hits", "statValue" ); + startMisses = self GetDStat( "playerstatslist", "misses", "statValue" ); + startTimePlayedTotal = self GetDStat( "playerstatslist", "time_played_total", "statValue" ); + startScore = self GetDStat( "playerstatslist", "score", "statValue" ); + startPrestige = self GetDStat( "playerstatslist", "plevel", "statValue" ); + startUnlockPoints = self GetDStat( "unlocks", 0); + + ties = self GetDStat( "playerstatslist", "ties", "statValue" ); + startGamesPlayed = startWins + startLosses + ties; + + self.startKills = startKills; + self.startHits = startHits; + self.totalMatchShots = 0; + + // note: xp_start - already exists - written in code - reads RANKXP + + recordPlayerStats( self, "startKills", startKills ); + recordPlayerStats( self, "startDeaths", startDeaths ); + recordPlayerStats( self, "startWins", startWins ); + recordPlayerStats( self, "startLosses", startLosses ); + recordPlayerStats( self, "startHits", startHits ); + recordPlayerStats( self, "startMisses", startMisses ); + recordPlayerStats( self, "startTimePlayedTotal", startTimePlayedTotal ); + recordPlayerStats( self, "startScore", startScore ); + recordPlayerStats( self, "startPrestige", startPrestige ); + recordPlayerStats( self, "startUnlockPoints", startUnlockPoints ); + recordPlayerStats( self, "startGamesPlayed", startGamesPlayed ); + + // temp commenting out; the getdstat calls here fail + lootXPBeforeMatch = self GetDStat( "AfterActionReportStats", "lootXPBeforeMatch" ); + cryptoKeysBeforeMatch = self GetDStat( "AfterActionReportStats", "cryptoKeysBeforeMatch" ); + recordPlayerStats( self, "lootXPBeforeMatch", lootXPBeforeMatch ); + recordPlayerStats( self, "cryptoKeysBeforeMatch", cryptoKeysBeforeMatch ); + +} + +function record_global_mp_stats_for_player_at_match_end() +{ + if( isdefined( level.disableStatTracking ) && level.disableStatTracking == true ) + { + return; + } + + endKills = self GetDStat( "playerstatslist", "kills", "statValue" ); + endDeaths = self GetDStat( "playerstatslist", "deaths", "statValue" ); + endWins = self GetDStat( "playerstatslist", "wins", "statValue" ); + endLosses = self GetDStat( "playerstatslist", "losses", "statValue" ); + endHits = self GetDStat( "playerstatslist", "hits", "statValue" ); + endMisses = self GetDStat( "playerstatslist", "misses", "statValue" ); + endTimePlayedTotal = self GetDStat( "playerstatslist", "time_played_total", "statValue" ); + endScore = self GetDStat( "playerstatslist", "score", "statValue" ); + endPrestige = self GetDStat( "playerstatslist", "plevel", "statValue" ); + endUnlockPoints = self GetDStat( "unlocks", 0); + + ties = self GetDStat( "playerstatslist", "ties", "statValue" ); + endGamesPlayed = endWins + endLosses + ties; + + // note: xp_end - already exists - written in code - reads RANKXP + + recordPlayerStats( self, "endKills", endKills ); + recordPlayerStats( self, "endDeaths", endDeaths ); + recordPlayerStats( self, "endWins", endWins ); + recordPlayerStats( self, "endLosses", endLosses ); + recordPlayerStats( self, "endHits", endHits ); + recordPlayerStats( self, "endMisses", endMisses ); + recordPlayerStats( self, "endTimePlayedTotal", endTimePlayedTotal ); + recordPlayerStats( self, "endScore", endScore ); + recordPlayerStats( self, "endPrestige", endPrestige ); + recordPlayerStats( self, "endUnlockPoints", endUnlockPoints ); + recordPlayerStats( self, "endGamesPlayed", endGamesPlayed ); + +} + +function record_misc_player_stats() +{ + if( isdefined( level.disableStatTracking ) && level.disableStatTracking == true ) + { + return; + } + + // common either for match end or on disconnect + recordPlayerStats( self, "UTCEndTimeSeconds", getUTC() ); + if( isdefined( self.weaponPickupsCount ) ) + { + recordPlayerStats( self, "weaponPickupsCount", self.weaponPickupsCount ); + } + if( isdefined( self.killcamsSkipped) ) + { + recordPlayerStats( self, "totalKillcamsSkipped", self.killcamsSkipped ); + } + if( isdefined( self.matchBonus) ) + { + recordPlayerStats( self, "matchXp", self.matchBonus ); + } + if( isdefined( self.killsdenied ) ) + { + recordPlayerStats( self, "killsDenied", self.killsdenied ); + } + if( isdefined( self.killsconfirmed ) ) + { + recordPlayerStats( self, "killsConfirmed", self.killsconfirmed ); + } + if( self IsSplitscreen() ) + { + recordPlayerStats( self, "isSplitscreen", true ); + } + if( self.objtime ) + { + recordPlayerStats( self, "objectiveTime", self.objtime ); + } + if( self.escorts ) + { + recordPlayerStats( self, "escortTime", self.escorts ); + } +} + +function spectate_player_watcher() +{ + self endon( "disconnect" ); + + // Setup the perks hud elem for the spectator if its not yet initalized + // We have to do it here, since the perk hudelem is generally initalized only on spawn, and the spectator will not able able to + // look at the perk loadout of some player. + if ( !level.splitscreen && !level.hardcoreMode && GetDvarint( "scr_showperksonspawn" ) == 1 && game["state"] != "postgame" && !isdefined( self.perkHudelem ) ) + { + if ( level.perksEnabled == 1 ) + { + self hud::showPerks( ); + } + } + + self.watchingActiveClient = true; + self.waitingForPlayersText = undefined; + + while ( 1 ) + { + if ( self.pers["team"] != "spectator" || level.gameEnded ) + { + self hud_message::clearShoutcasterWaitingMessage(); + if ( !( isdefined( level.inPrematchPeriod ) && level.inPrematchPeriod ) ) + { + self FreezeControls( false ); + } + self.watchingActiveClient = false; + break; + } + else + { + count = 0; + for ( i = 0; i < level.players.size; i++ ) + { + if ( level.players[i].team != "spectator" ) + { + count++; + break; + } + } + + if ( count > 0 ) + { + if ( !self.watchingActiveClient ) + { + self hud_message::clearShoutcasterWaitingMessage(); + self FreezeControls( false ); + + // Make sure that the player spawned notify happens when we start watching a player. + self LUINotifyEvent( &"player_spawned", 0 ); + } + + self.watchingActiveClient = true; + } + else + { + if ( self.watchingActiveClient ) + { + [[level.onSpawnSpectator]](); + self FreezeControls( true ); + self hud_message::setShoutcasterWaitingMessage(); + } + + self.watchingActiveClient = false; + } + + wait( 0.5 ); + } + } +} + +function Callback_PlayerMigrated() +{ +/# println( "Player " + self.name + " finished migrating at time " + gettime() ); #/ + + if ( isdefined( self.connected ) && self.connected ) + { + self globallogic_ui::updateObjectiveText(); +// self globallogic_ui::updateObjectiveText(); +// self updateMainMenu(); + +// if ( level.teambased ) +// self updateScores(); + } + + level.hostMigrationReturnedPlayerCount++; + if ( level.hostMigrationReturnedPlayerCount >= level.players.size * 2 / 3 ) + { + /# println( "2/3 of players have finished migrating" ); #/ + level notify( "hostmigration_enoughplayers" ); + } +} + +function Callback_PlayerDisconnect() +{ + profilelog_begintiming( 5, "ship" ); + + if ( game["state"] != "postgame" && !level.gameEnded ) + { + gameLength = game["timepassed"]; + self globallogic::bbPlayerMatchEnd( gameLength, "MP_PLAYER_DISCONNECT", 0 ); + + if( util::isRoundBased() ) + { + recordPlayerStats( self, "playerQuitRoundNumber", game["roundsplayed"] + 1 ); + } + + if( level.teambased ) + { + ourTeam = self.team; // only expecting: "allies" or "axis" + if( ourTeam == "allies" || ourTeam == "axis" ) + { + theirTeam = ""; + if( ourTeam == "allies" ) + { + theirTeam = "axis"; + } + else if( ourTeam == "axis" ) + { + theirTeam = "allies"; + } + recordPlayerStats( self, "playerQuitTeamScore", getTeamScore( ourTeam ) ); + recordPlayerStats( self, "playerQuitOpposingTeamScore", getTeamScore( theirTeam ) ); + } + } + + recordEndGameComScoreEventForPlayer( self, "disconnect" ); + + } + + self behaviorTracker::Finalize(); + + ArrayRemoveValue( level.players, self ); + + if ( level.splitscreen ) + { + players = level.players; + + if ( players.size <= 1 ) + level thread globallogic::forceEnd(); + + // passing number of players to menus in splitscreen to display leave or end game option + SetDvar( "splitscreen_playerNum", players.size ); + } + + if ( isdefined( self.score ) && isdefined( self.pers["team"] ) ) + { + /#print( "team: score " + self.pers["team"] + ":" + self.score );#/ + level.dropTeam += 1; + } + + [[level.onPlayerDisconnect]](); + + lpselfnum = self getEntityNumber(); + lpGuid = self getXuid(); + + if (self util::is_bot()) + { + lpGuid = "bot0"; + } + + logPrint("Q;" + lpGuid + ";" + lpselfnum + ";" + self.name + "\n"); + + self record_global_mp_stats_for_player_at_match_end(); + self record_special_move_data_for_life( undefined ); + + self record_misc_player_stats(); + + self gamerep::gameRepPlayerDisconnected(); + + for ( entry = 0; entry < level.players.size; entry++ ) + { + if ( level.players[entry] == self ) + { + while ( entry < level.players.size-1 ) + { + level.players[entry] = level.players[entry+1]; + entry++; + } + level.players[entry] = undefined; + break; + } + } + for ( entry = 0; entry < level.players.size; entry++ ) + { + if ( isdefined( level.players[entry].pers["killed_players"][self.name] ) ) + level.players[entry].pers["killed_players"][self.name] = undefined; + + if ( isdefined( level.players[entry].pers["killed_players_with_specialist"][self.name] ) ) + level.players[entry].pers["killed_players_with_specialist"][self.name] = undefined; + + if ( isdefined( level.players[entry].killedPlayersCurrent[self.name] ) ) + level.players[entry].killedPlayersCurrent[self.name] = undefined; + + if ( isdefined( level.players[entry].pers["killed_by"][self.name] ) ) + level.players[entry].pers["killed_by"][self.name] = undefined; + + if ( isdefined( level.players[entry].pers["nemesis_tracking"][self.name] ) ) + level.players[entry].pers["nemesis_tracking"][self.name] = undefined; + + // player that disconnected was our nemesis + if ( level.players[entry].pers["nemesis_name"] == self.name ) + { + level.players[entry] chooseNextBestNemesis(); + } + } + + if ( level.gameEnded ) + self globallogic::removeDisconnectedPlayerFromPlacement(); + + level thread globallogic::updateTeamStatus(); + level thread globallogic::updateAllAliveTimes(); + + profilelog_endtiming( 5, "gs=" + game["state"] + " zom=" + SessionModeIsZombiesGame() ); +} + +function Callback_PlayerMelee( eAttacker, iDamage, weapon, vOrigin, vDir, boneIndex, shieldHit, fromBehind ) +{ + hit = true; + + if ( level.teamBased && self.team == eAttacker.team ) + { + if ( level.friendlyfire == 0 ) // no one takes damage + { + hit = false; + } + } + + self finishMeleeHit( eAttacker, weapon, vOrigin, vDir, boneIndex, shieldHit, hit, fromBehind ); +} + +function chooseNextBestNemesis() +{ + nemesisArray = self.pers["nemesis_tracking"]; + nemesisArrayKeys = getArrayKeys( nemesisArray ); + nemesisAmount = 0; + nemesisName = ""; + + if ( nemesisArrayKeys.size > 0 ) + { + for ( i = 0; i < nemesisArrayKeys.size; i++ ) + { + nemesisArrayKey = nemesisArrayKeys[i]; + if ( nemesisArray[nemesisArrayKey] > nemesisAmount ) + { + nemesisName = nemesisArrayKey; + nemesisAmount = nemesisArray[nemesisArrayKey]; + } + + } + } + + self.pers["nemesis_name"] = nemesisName; + + if ( nemesisName != "" ) + { + playerIndex = 0; + for( ; playerIndex < level.players.size; playerIndex++ ) + { + if ( level.players[playerIndex].name == nemesisName ) + { + nemesisPlayer = level.players[playerIndex]; + self.pers["nemesis_rank"] = nemesisPlayer.pers["rank"]; + self.pers["nemesis_rankIcon"] = nemesisPlayer.pers["rankxp"]; + self.pers["nemesis_xp"] = nemesisPlayer.pers["prestige"]; + self.pers["nemesis_xuid"] = nemesisPlayer GetXUID(); + break; + } + } + } + else + { + self.pers["nemesis_xuid"] = ""; + } +} + +function custom_gamemodes_modified_damage( victim, eAttacker, iDamage, sMeansOfDeath, weapon, eInflictor, sHitLoc ) +{ + // regular public matches should early out + if ( level.onlinegame && !SessionModeIsPrivate() ) + { + return iDamage; + } + + if( isdefined( eAttacker) && isdefined( eAttacker.damageModifier ) ) + { + iDamage *= eAttacker.damageModifier; + } + if ( ( sMeansOfDeath == "MOD_PISTOL_BULLET" ) || ( sMeansOfDeath == "MOD_RIFLE_BULLET" ) ) + { + iDamage = int( iDamage * level.bulletDamageScalar ); + } + + return iDamage; +} + +function figure_out_attacker( eAttacker ) +{ + if ( isdefined(eAttacker) ) + { + if( isai(eAttacker) && isdefined( eAttacker.script_owner ) ) + { + team = self.team; + + if ( eAttacker.script_owner.team != team ) + eAttacker = eAttacker.script_owner; + } + + if( eAttacker.classname == "script_vehicle" && isdefined( eAttacker.owner ) ) + eAttacker = eAttacker.owner; + else if( eAttacker.classname == "auto_turret" && isdefined( eAttacker.owner ) ) + eAttacker = eAttacker.owner; + else if( eAttacker.classname == "actor_spawner_bo3_robot_grunt_assault_mp" && isdefined( eAttacker.owner ) ) + eAttacker = eAttacker.owner; + } + + return eAttacker; +} + +function player_damage_figure_out_weapon( weapon, eInflictor ) +{ + // explosive barrel/car detection + if ( weapon == level.weaponNone && isdefined( eInflictor ) ) + { + if ( isdefined( eInflictor.targetname ) && eInflictor.targetname == "explodable_barrel" ) + { + weapon = GetWeapon( "explodable_barrel" ); + } + else if ( isdefined( eInflictor.destructible_type ) && isSubStr( eInflictor.destructible_type, "vehicle_" ) ) + { + weapon = GetWeapon( "destructible_car" ); + } + else if( isdefined( eInflictor.scriptvehicletype ) ) + { + veh_weapon = GetWeapon( eInflictor.scriptvehicletype ); + if( isdefined( veh_weapon ) ) + { + weapon = veh_weapon; + } + } + } + + if ( isdefined( eInflictor ) && isdefined( eInflictor.script_noteworthy ) ) + { + if ( IsDefined( level.overrideWeaponFunc ) ) + { + weapon = [[level.overrideWeaponFunc]]( weapon, eInflictor.script_noteworthy ); + } + } + + return weapon; +} + +function figure_out_friendly_fire( victim ) +{ + if ( level.hardcoreMode && level.friendlyfire > 0 && isdefined( victim ) && victim.is_capturing_own_supply_drop === true ) + { + return 2; // FF 2 = reflect; design wants reflect friendly fire whenever a player is capturing their own supply drop + } + + if ( killstreaks::is_ricochet_protected( victim ) ) + { + return 2; + } + + // note, keep, non-gametype specific friendly fire logic above this line + + if ( isdefined( level.figure_out_gametype_friendly_fire ) ) + { + return [[ level.figure_out_gametype_friendly_fire ]]( victim ); + } + + return level.friendlyfire; +} + +function isPlayerImmuneToKillstreak( eAttacker, weapon ) +{ + if ( level.hardcoreMode ) + return false; + + if ( !isdefined( eAttacker ) ) + return false; + + if ( self != eAttacker ) + return false; + + return weapon.doNotDamageOwner; +} + + +function should_do_player_damage( eAttacker, weapon, sMeansOfDeath, iDFlags ) +{ + if ( game["state"] == "postgame" ) + return false; + + if ( self.sessionteam == "spectator" ) + return false; + + if ( isdefined( self.canDoCombat ) && !self.canDoCombat ) + return false; + + if ( isdefined( eAttacker ) && isPlayer( eAttacker ) && isdefined( eAttacker.canDoCombat ) && !eAttacker.canDoCombat ) + return false; + + if ( isdefined( level.hostMigrationTimer ) ) + return false; + + if ( level.onlyHeadShots ) + { + if ( sMeansOfDeath == "MOD_PISTOL_BULLET" || sMeansOfDeath == "MOD_RIFLE_BULLET" ) + return false; + } + + // Make all vehicle drivers invulnerable to bullets + if ( self vehicle::player_is_occupant_invulnerable( sMeansOfDeath ) ) + return false; + + if ( weapon.isSupplyDropWeapon && !weapon.isGrenadeWeapon && ( smeansofdeath != "MOD_TRIGGER_HURT" ) ) + return false; + + if ( self.scene_takedamage === false ) + return false; + + // prevent spawn kill wall bangs + if ( (iDFlags & 8) && self player::is_spawn_protected() ) + return false; + +return true; +} + +function apply_damage_to_armor( eInflictor, eAttacker, iDamage, sMeansOfDeath, weapon, sHitLoc, friendlyFire, ignore_round_start_friendly_fire ) +{ + victim = self; + + if ( friendlyFire && !player_damage_does_friendly_fire_damage_victim( ignore_round_start_friendly_fire ) ) + return iDamage; + + // Handle armor damage + if( IsDefined( victim.lightArmorHP ) ) + { + if ( weapon.ignoresLightArmor && sMeansOfDeath != "MOD_MELEE" ) + { + return iDamage; + } + else if ( weapon.meleeIgnoresLightArmor && sMeansOfDeath == "MOD_MELEE" ) + { + return iDamage; + } + // anything stuck to the player does health damage + else if( IsDefined( eInflictor ) && IsDefined( eInflictor.stuckToPlayer ) && eInflictor.stuckToPlayer == victim ) + { + iDamage = victim.health; + } + else + { + // Handle Armor Damage + // no armor damage in case of falling, melee, fmj or head shots + if ( sMeansOfDeath != "MOD_FALLING" + && !weapon_utils::isMeleeMOD( sMeansOfDeath ) + && !globallogic_utils::isHeadShot( weapon, sHitLoc, sMeansOfDeath, eAttacker ) + ) + { + victim armor::setLightArmorHP( victim.lightArmorHP - ( iDamage ) ); + + iDamage = 0; + if ( victim.lightArmorHP <= 0 ) + { + // since the light armor is gone, adjust the damage to be the excess damage that happens after the light armor hp is reduced + iDamage = abs( victim.lightArmorHP ); + armor::unsetLightArmor(); + } + } + } + } + + return iDamage; +} + +function make_sure_damage_is_not_zero( iDamage ) +{ + // Make sure at least one point of damage is done & give back 1 health because of this if you have power armor + if ( iDamage < 1 ) + { + if( ( self ability_util::gadget_power_armor_on() ) && isDefined( self.maxHealth ) && ( self.health < self.maxHealth ) ) + { + self.health += 1; + } + iDamage = 1; + } + + return int(iDamage); +} + +function modify_player_damage_friendlyfire( iDamage ) +{ + friendlyfire = [[ level.figure_out_friendly_fire ]]( self ); + + // half damage + if ( friendlyfire == 2 || friendlyfire == 3 ) + { + iDamage = int(iDamage * .5); + } + + return iDamage; +} + +function modify_player_damage( eInflictor, eAttacker, iDamage, iDFlags, sMeansOfDeath, weapon, vPoint, vDir, sHitLoc, psOffsetTime, boneIndex ) +{ + if ( isdefined( self.overridePlayerDamage ) ) + { + iDamage = self [[self.overridePlayerDamage]]( eInflictor, eAttacker, iDamage, iDFlags, sMeansOfDeath, weapon, vPoint, vDir, sHitLoc, psOffsetTime, boneIndex ); + } + else if ( isdefined( level.overridePlayerDamage ) ) + { + iDamage = self [[level.overridePlayerDamage]]( eInflictor, eAttacker, iDamage, iDFlags, sMeansOfDeath, weapon, vPoint, vDir, sHitLoc, psOffsetTime, boneIndex ); + } + + assert(isdefined(iDamage), "You must return a value from a damage override function."); + + if ( isdefined( eAttacker ) ) + { + iDamage = loadout::cac_modified_damage( self, eAttacker, iDamage, sMeansOfDeath, weapon, eInflictor, sHitLoc ); + + if( isdefined( eAttacker.pickup_damage_scale ) && eAttacker.pickup_damage_scale_time > GetTime() ) + { + iDamage = iDamage * eAttacker.pickup_damage_scale; + } + } + iDamage = custom_gamemodes_modified_damage( self, eAttacker, iDamage, sMeansOfDeath, weapon, eInflictor, sHitLoc ); + + if ( level.onPlayerDamage != &globallogic::blank ) + { + modifiedDamage = [[level.onPlayerDamage]]( eInflictor, eAttacker, iDamage, iDFlags, sMeansOfDeath, weapon, vPoint, vDir, sHitLoc, psOffsetTime ); + + if ( isdefined( modifiedDamage ) ) + { + if ( modifiedDamage <= 0 ) + return; + + iDamage = modifiedDamage; + } + } + + if ( level.onlyHeadShots ) + { + if ( sMeansOfDeath == "MOD_HEAD_SHOT" ) + iDamage = 150; + } + + if ( weapon.damageAlwaysKillsPlayer ) + { + iDamage = self.maxHealth + 1; + } + + if ( sHitLoc == "riotshield" ) + { + if ( iDFlags & 32 ) + { + if ( !(iDFlags & 64) ) + { + iDamage *= 0.0; + } + } + else if ( iDFlags & 128 ) + { + if ( isdefined( eInflictor ) && isdefined( eInflictor.stuckToPlayer ) && eInflictor.stuckToPlayer == self ) + { + //does enough damage to shield carrier to ensure death + iDamage = self.maxhealth + 1; + } + } + } + + return int(iDamage); +} + +function modify_player_damage_meansofdeath( eInflictor, eAttacker, sMeansOfDeath, weapon, sHitLoc ) +{ + if ( globallogic_utils::isHeadShot( weapon, sHitLoc, sMeansOfDeath, eInflictor ) && isPlayer(eAttacker) && !weapon_utils::ismeleemod( sMeansOfDeath ) ) + { + sMeansOfDeath = "MOD_HEAD_SHOT"; + } + + if ( isdefined( eInflictor ) && isdefined( eInflictor.script_noteworthy ) ) + { + if ( eInflictor.script_noteworthy == "ragdoll_now" ) + { + sMeansOfDeath = "MOD_FALLING"; + } + } + + return sMeansOfDeath; +} + +function player_damage_update_attacker( eInflictor, eAttacker, sMeansOfDeath ) +{ + if ( isdefined( eInflictor ) && isPlayer( eAttacker ) && eAttacker == eInflictor ) + { + if ( sMeansOfDeath == "MOD_HEAD_SHOT" || sMeansOfDeath == "MOD_PISTOL_BULLET" || sMeansOfDeath == "MOD_RIFLE_BULLET" ) + { + //if ( isPlayer( eAttacker ) ) already tested for above + { + eAttacker.hits++; + } + } + } + + if ( isPlayer( eAttacker ) ) + eAttacker.pers["participation"]++; +} + +function player_is_spawn_protected_from_explosive( eInflictor, weapon, sMeansOfDeath ) +{ + if ( !self player::is_spawn_protected() ) + return false; + + // if we are using this as a impact damage only projectile then no protection + // we should probably add a bool to the weapon to indicate that it spawn protects + if ( weapon.explosionradius == 0 ) + return false; + + distSqr = ( ( isdefined( eInflictor ) && isdefined( self.lastSpawnPoint ) ) ? DistanceSquared( eInflictor.origin, self.lastSpawnPoint.origin ) : 0 ); + + // protect players from spawnkill grenades, tabun and incendiary + if ( distSqr < ( (250) * (250) ) ) + { + if ( sMeansOfDeath == "MOD_GRENADE" || sMeansOfDeath == "MOD_GRENADE_SPLASH" ) + { + return true; + } + + if ( sMeansOfDeath == "MOD_PROJECTILE" || sMeansOfDeath == "MOD_PROJECTILE_SPLASH" ) + { + return true; + } + + if ( sMeansOfDeath == "MOD_EXPLOSIVE" ) + { + return true; + } + } + + if ( killstreaks::is_killstreak_weapon( weapon ) ) + { + return true; + } + + return false; +} + +function player_damage_update_explosive_info( eInflictor, eAttacker, iDamage, iDFlags, sMeansOfDeath, weapon, vPoint, vDir, sHitLoc, psOffsetTime, boneIndex ) +{ + is_explosive_damage = loadout::isExplosiveDamage( sMeansOfDeath ); + + if ( is_explosive_damage ) + { + // protect players from spawnkill grenades, tabun, incendiaries, and scorestreaks + if ( self player_is_spawn_protected_from_explosive( eInflictor, weapon, sMeansOfDeath ) ) + { + return false; + } + + // protect players from their own non-player controlled killstreaks + if ( self isPlayerImmuneToKillstreak( eAttacker, weapon ) ) + { + return false; + } + } + + if ( isdefined( eInflictor ) && ( sMeansOfDeath == "MOD_GAS" || is_explosive_damage ) ) + { + self.explosiveInfo = []; + self.explosiveInfo["damageTime"] = getTime(); + self.explosiveInfo["damageId"] = eInflictor getEntityNumber(); + self.explosiveInfo["originalOwnerKill"] = false; + self.explosiveInfo["bulletPenetrationKill"] = false; + self.explosiveInfo["chainKill"] = false; + self.explosiveInfo["damageExplosiveKill"] = false; + self.explosiveInfo["chainKill"] = false; + self.explosiveInfo["cookedKill"] = false; + self.explosiveInfo["weapon"] = weapon; + self.explosiveInfo["originalowner"] = eInflictor.originalowner; + + isFrag = ( weapon.rootweapon.name == "frag_grenade" ); + + if ( isdefined( eAttacker ) && eAttacker != self ) + { + if ( isdefined( eAttacker ) && isdefined( eInflictor.owner ) && (weapon.name == "satchel_charge" || weapon.name == "claymore" || weapon.name == "bouncingbetty") ) + { + self.explosiveInfo["originalOwnerKill"] = (eInflictor.owner == self); + self.explosiveInfo["damageExplosiveKill"] = isdefined( eInflictor.wasDamaged ); + self.explosiveInfo["chainKill"] = isdefined( eInflictor.wasChained ); + self.explosiveInfo["wasJustPlanted"] = isdefined( eInflictor.wasJustPlanted ); + self.explosiveInfo["bulletPenetrationKill"] = isdefined( eInflictor.wasDamagedFromBulletPenetration ); + self.explosiveInfo["cookedKill"] = false; + } + if ( isdefined( eInflictor ) && isdefined( eInflictor.stuckToPlayer ) && weapon.projExplosionType == "grenade" ) + { + self.explosiveInfo["stuckToPlayer"] = eInflictor.stuckToPlayer; + } + if ( weapon.doStun ) + { + self.lastStunnedBy = eAttacker; + self.lastStunnedTime = self.iDFlagsTime; + } + if ( isdefined( eAttacker.lastGrenadeSuicideTime ) && eAttacker.lastGrenadeSuicideTime >= gettime() - 50 && isFrag ) + { + self.explosiveInfo["suicideGrenadeKill"] = true; + } + else + { + self.explosiveInfo["suicideGrenadeKill"] = false; + } + } + + if ( isFrag ) + { + self.explosiveInfo["cookedKill"] = isdefined( eInflictor.isCooked ); + self.explosiveInfo["throwbackKill"] = isdefined( eInflictor.threwBack ); + } + + if( isdefined( eAttacker ) && isPlayer( eAttacker ) && eAttacker != self ) + { + self globallogic_score::setInflictorStat( eInflictor, eAttacker, weapon ); + } + } + + if( sMeansOfDeath == "MOD_IMPACT" && isdefined( eAttacker ) && isPlayer( eAttacker ) && eAttacker != self ) + { + if ( weapon != level.weaponBallisticKnife ) + { + self globallogic_score::setInflictorStat( eInflictor, eAttacker, weapon ); + } + + if ( weapon.rootweapon.name == "hatchet" && isdefined( eInflictor ) ) + { + self.explosiveInfo["projectile_bounced"] = isdefined( eInflictor.bounced ); + } + } + + return true; +} + +function player_damage_is_friendly_fire_at_round_start() +{ + //check for friendly fire at the begining of the match. apply the damage to the attacker only + if( level.friendlyFireDelay && level.friendlyFireDelayTime >= ( ( ( gettime() - level.startTime ) - level.discardTime ) / 1000 ) ) + { + return true; + } + + return false; +} + +function player_damage_does_friendly_fire_damage_attacker( eAttacker, ignore_round_start_friendly_fire ) +{ + if ( !IsAlive( eAttacker ) ) + return false; + + friendlyfire = [[ level.figure_out_friendly_fire ]]( self ); + + if ( friendlyfire == 1 ) // the friendly takes damage + { + //check for friendly fire at the begining of the match. apply the damage to the attacker only + if ( player_damage_is_friendly_fire_at_round_start() && ( ignore_round_start_friendly_fire == false ) ) + { + return true; + } + } + + if ( friendlyfire == 2 ) // only the attacker takes damage + { + return true; + } + + if ( friendlyfire == 3 ) // both friendly and attacker take damage + { + return true; + } + + return false; +} + +function player_damage_does_friendly_fire_damage_victim( ignore_round_start_friendly_fire ) +{ + friendlyfire = [[ level.figure_out_friendly_fire ]]( self ); + + if ( friendlyfire == 1 ) // the friendly takes damage + { + //check for friendly fire at the begining of the match. apply the damage to the attacker only + if ( player_damage_is_friendly_fire_at_round_start() && ( ignore_round_start_friendly_fire == false ) ) + { + return false; + } + + return true; + } + + if ( friendlyfire == 3 ) // both friendly and attacker take damage + { + return true; + } + + return false; +} + +function player_damage_riotshield_hit( eAttacker, iDamage, sMeansOfDeath, weapon, attackerIsHittingTeammate) +{ + if (( sMeansOfDeath == "MOD_PISTOL_BULLET" || sMeansOfDeath == "MOD_RIFLE_BULLET" ) && + ( !killstreaks::is_killstreak_weapon( weapon )) && + ( !attackerIsHittingTeammate ) ) + { + if ( self.hasRiotShieldEquipped ) + { + if ( isPlayer( eAttacker )) + { + eAttacker.lastAttackedShieldPlayer = self; + eAttacker.lastAttackedShieldTime = getTime(); + } + + previous_shield_damage = self.shieldDamageBlocked; + self.shieldDamageBlocked += iDamage; + + if (( self.shieldDamageBlocked % 400 /*riotshield_damage_score_threshold*/ ) < ( previous_shield_damage % 400 /*riotshield_damage_score_threshold*/ )) + { + score_event = "shield_blocked_damage"; + + if (( self.shieldDamageBlocked > 2000 /*riotshield_damage_score_max*/ )) + { + score_event = "shield_blocked_damage_reduced"; + } + + if ( isdefined( level.scoreInfo[ score_event ]["value"] ) ) + { + // need to get the actual riot shield weapon here + self AddWeaponStat( level.weaponRiotshield, "score_from_blocked_damage", level.scoreInfo[ score_event ]["value"] ); + } + + scoreevents::processScoreEvent( score_event, self ); + } + } + } + +} + +function does_player_completely_avoid_damage(iDFlags, sHitLoc, weapon, friendlyFire, attackerIsHittingSelf, sMeansOfDeath ) +{ + if( iDFlags & 2048 ) + return true; + + if ( friendlyFire && level.friendlyfire == 0 ) + return true; + + if ( sHitLoc == "riotshield" ) + { + if ( !(iDFlags & (32|128)) ) + return true; + } + + + if( weapon.isEmp && sMeansOfDeath == "MOD_GRENADE_SPLASH" ) + { + if( self hasperk("specialty_immuneemp") ) + return true; + } + + if ( isdefined( level.playerAvoidDamageGameMode ) && self [[ level.playerAvoidDamageGameMode ]]( iDFlags, sHitLoc, weapon, friendlyFire, attackerIsHittingSelf, sMeansOfDeath ) ) + return true; + + return false; +} + +function player_damage_log( eInflictor, eAttacker, iDamage, iDFlags, sMeansOfDeath, weapon, vPoint, vDir, sHitLoc, psOffsetTime, boneIndex ) +{ + pixbeginevent( "PlayerDamage log" ); + +/# + // Do debug print if it's enabled + if(GetDvarint( "g_debugDamage")) + println("client:" + self getEntityNumber() + " health:" + self.health + " attacker:" + eAttacker.clientid + " inflictor is player:" + isPlayer(eInflictor) + " damage:" + iDamage + " hitLoc:" + sHitLoc); +#/ + + if(self.sessionstate != "dead") + { + lpselfnum = self getEntityNumber(); + lpselfname = self.name; + lpselfteam = self.team; + lpselfGuid = self getXuid(); + + if (self util::is_bot()) + { + lpselfGuid = "bot0"; + } + + lpattackerteam = ""; + lpattackerorigin = ( 0, 0, 0 ); + + if(isPlayer(eAttacker)) + { + lpattacknum = eAttacker getEntityNumber(); + lpattackGuid = eAttacker getXuid(); + + if (eAttacker util::is_bot()) + { + lpattackGuid = "bot0"; + } + + lpattackname = eAttacker.name; + lpattackerteam = eAttacker.team; + lpattackerorigin = eAttacker.origin; + isusingheropower = 0; + + if ( eAttacker ability_player::is_using_any_gadget() ) + isusingheropower = 1; + + bbPrint( "mpattacks", "gametime %d attackerspawnid %d attackerweapon %s attackerx %d attackery %d attackerz %d victimspawnid %d victimx %d victimy %d victimz %d damage %d damagetype %s damagelocation %s death %d isusingheropower %d", + gettime(), getplayerspawnid( eAttacker ), weapon.name, lpattackerorigin, getplayerspawnid( self ), self.origin, iDamage, sMeansOfDeath, sHitLoc, 0, isusingheropower ); + } + else + { + lpattacknum = -1; + lpattackGuid = ""; + lpattackname = ""; + lpattackerteam = "world"; + bbPrint( "mpattacks", "gametime %d attackerweapon %s victimspawnid %d victimx %d victimy %d victimz %d damage %d damagetype %s damagelocation %s death %d isusingheropower %d", + gettime(), weapon.name, getplayerspawnid( self ), self.origin, iDamage, sMeansOfDeath, sHitLoc, 0, 0 ); + } + logPrint("D;" + lpselfGuid + ";" + lpselfnum + ";" + lpselfteam + ";" + lpselfname + ";" + lpattackGuid + ";" + lpattacknum + ";" + lpattackerteam + ";" + lpattackname + ";" + weapon.name + ";" + iDamage + ";" + sMeansOfDeath + ";" + sHitLoc + "\n"); + } + + pixendevent(); // "END: PlayerDamage log" +} + +function should_allow_postgame_damage( sMeansOfDeath ) +{ + if ( sMeansOfDeath == "MOD_TRIGGER_HURT" || sMeansOfDeath == "MOD_CRUSH" ) + return true; + + return false; +} + +function do_post_game_damage( eInflictor, eAttacker, iDamage, iDFlags, sMeansOfDeath, weapon, vPoint, vDir, sHitLoc, vDamageOrigin, psOffsetTime, boneIndex, vSurfaceNormal ) +{ + if ( game["state"] != "postgame" ) + return; + + if ( !should_allow_postgame_damage( sMeansOfDeath ) ) + return; + + // just pass it along + self finishPlayerDamage( eInflictor, eAttacker, iDamage, iDFlags, "MOD_POST_GAME", weapon, vPoint, vDir, sHitLoc, vDamageOrigin, psOffsetTime, boneIndex, vSurfaceNormal ); +} + +function Callback_PlayerDamage( eInflictor, eAttacker, iDamage, iDFlags, sMeansOfDeath, weapon, vPoint, vDir, sHitLoc, vDamageOrigin, psOffsetTime, boneIndex, vSurfaceNormal ) +{ + profilelog_begintiming( 6, "ship" ); + + do_post_game_damage( eInflictor, eAttacker, iDamage, iDFlags, sMeansOfDeath, weapon, vPoint, vDir, sHitLoc, vDamageOrigin, psOffsetTime, boneIndex, vSurfaceNormal ); + + if ( sMeansOfDeath == "MOD_CRUSH" && isdefined( eInflictor ) && ( eInflictor.deal_no_crush_damage === true ) ) + { + return; + } + + if ( isdefined( eInflictor ) && eInflictor.killstreakType === "siegebot" ) + { + if ( eInflictor.team === "neutral" ) + return; + } + + self.iDFlags = iDFlags; + self.iDFlagsTime = getTime(); + + // determine if we should treat owner damage as friendly fire + if ( !IsPlayer( eAttacker ) && isdefined( eAttacker ) && eAttacker.owner === self ) + { + treat_self_damage_as_friendly_fire = eAttacker.treat_owner_damage_as_friendly_fire; + } + + // determine if we should ignore_round_start_friendly_fire + ignore_round_start_friendly_fire = ( isdefined( eInflictor ) && ( sMeansOfDeath == "MOD_CRUSH" ) || sMeansOfDeath == "MOD_HIT_BY_OBJECT" ); + + eAttacker = figure_out_attacker( eAttacker ); + + // no damage from people who have dropped into laststand + if ( IsPlayer( eAttacker ) && ( isdefined( eAttacker.laststand ) && eAttacker.laststand ) ) + { + return; + } + + sMeansOfDeath = modify_player_damage_meansofdeath( eInflictor, eAttacker, sMeansOfDeath, weapon, sHitLoc ); + + if ( !(self should_do_player_damage( eAttacker, weapon, sMeansOfDeath, iDFlags )) ) + return; + + player_damage_update_attacker( eInflictor, eAttacker, sMeansOfDeath ); + + weapon = player_damage_figure_out_weapon( weapon, eInflictor ); + + pixbeginevent( "PlayerDamage flags/tweaks" ); + + // Don't do knockback if the damage direction was not specified + if( !isdefined( vDir ) ) + iDFlags |= 4; + + attackerIsHittingTeammate = isPlayer( eAttacker ) && ( self util::IsEnemyPlayer( eAttacker ) == false ); + attackerIsHittingSelf = IsPlayer( eAttacker ) && (self == eAttacker); + + friendlyFire = ( ( attackerIsHittingSelf && treat_self_damage_as_friendly_fire === true ) // some killstreaks treak owner damage as friendly-fire + || ( level.teamBased && !attackerIsHittingSelf && attackerIsHittingTeammate ) ); // teammates are always friendly-fire, but self is handled above + + pixendevent(); // "END: PlayerDamage flags/tweaks" + + iDamage = modify_player_damage( eInflictor, eAttacker, iDamage, iDFlags, sMeansOfDeath, weapon, vPoint, vDir, sHitLoc, psOffsetTime, boneIndex ); + if ( friendlyFire ) + { + iDamage = modify_player_damage_friendlyfire( iDamage ); + } + + if( ( isdefined( self.power_armor_took_damage ) && self.power_armor_took_damage ) ) + { + iDFlags |= 1024; + } + + if ( sHitLoc == "riotshield" ) + { + // do we want all of the damage modifiers that get applied for the player to get applied to this damage? + // or friendly fire? + player_damage_riotshield_hit( eAttacker, iDamage, sMeansOfDeath, weapon, attackerIsHittingTeammate); + } + + // check for completely getting out of the damage + if ( self does_player_completely_avoid_damage(iDFlags, sHitLoc, weapon, friendlyFire, attackerIsHittingSelf, sMeansOfDeath ) ) + { + return; + } + + // do we want this called pre or post damage application? + self callback::callback( #"on_player_damage" ); + + armor = self armor::getArmor(); + + iDamage = apply_damage_to_armor( eInflictor, eAttacker, iDamage, sMeansOfDeath, weapon, sHitLoc, friendlyFire, ignore_round_start_friendly_fire ); + iDamage = make_sure_damage_is_not_zero( iDamage ); + + armor_damaged = (armor != self armor::getArmor()); + + // this must be below the damage modification functions as they use this to determine riotshield hits + if ( sHitLoc == "riotshield" ) + { + sHitLoc = "none"; // code ignores any damage to a "shield" bodypart. + } + + if ( !player_damage_update_explosive_info( eInflictor, eAttacker, iDamage, iDFlags, sMeansOfDeath, weapon, vPoint, vDir, sHitLoc, psOffsetTime, boneIndex ) ) + return; + + prevHealthRatio = self.health / self.maxhealth; + + if ( friendlyFire ) + { + pixmarker( "BEGIN: PlayerDamage player" ); // profs automatically end when the function returns + + if ( player_damage_does_friendly_fire_damage_victim( ignore_round_start_friendly_fire ) ) + { + self.lastDamageWasFromEnemy = false; + + self finishPlayerDamageWrapper(eInflictor, eAttacker, iDamage, iDFlags, sMeansOfDeath, weapon, vPoint, vDir, sHitLoc, vDamageOrigin, psOffsetTime, boneIndex, vSurfaceNormal); + } + else if ( weapon.forceDamageShellshockAndRumble ) + { + self damageShellshockAndRumble( eAttacker, eInflictor, weapon, sMeansOfDeath, iDamage ); + } + + if ( player_damage_does_friendly_fire_damage_attacker( eAttacker, ignore_round_start_friendly_fire ) ) + { + eAttacker.lastDamageWasFromEnemy = false; + + eAttacker.friendlydamage = true; + eAttacker finishPlayerDamageWrapper(eInflictor, eAttacker, iDamage, iDFlags, sMeansOfDeath, weapon, vPoint, vDir, sHitLoc, vDamageOrigin, psOffsetTime, boneIndex, vSurfaceNormal); + eAttacker.friendlydamage = undefined; + } + + pixmarker( "END: PlayerDamage player" ); + } + else + { + behaviorTracker::UpdatePlayerDamage( eAttacker, self, iDamage ); + + self.lastAttackWeapon = weapon; + + giveAttackerAndInflictorOwnerAssist( eAttacker, eInflictor, iDamage, sMeansOfDeath, weapon ); + + if ( isdefined( eAttacker ) ) + level.lastLegitimateAttacker = eAttacker; + + if ( ( sMeansOfDeath == "MOD_GRENADE" || sMeansOfDeath == "MOD_GRENADE_SPLASH" ) && isdefined( eInflictor ) && isdefined( eInflictor.isCooked ) ) + self.wasCooked = getTime(); + else + self.wasCooked = undefined; + + self.lastDamageWasFromEnemy = (isdefined( eAttacker ) && (eAttacker != self)); + + if ( self.lastDamageWasFromEnemy ) + { + if ( isplayer( eAttacker ) ) + { + if ( isdefined ( eAttacker.damagedPlayers[ self.clientId ] ) == false ) + eAttacker.damagedPlayers[ self.clientId ] = spawnstruct(); + + eAttacker.damagedPlayers[ self.clientId ].time = getTime(); + eAttacker.damagedPlayers[ self.clientId ].entity = self; + } + } + + if( isPlayer( eAttacker ) && isDefined(weapon.gadget_type) && weapon.gadget_type == 14 ) + { + if( isDefined(eAttacker.heroweaponHits) ) + { + eAttacker.heroweaponHits++; + } + } + + self finishPlayerDamageWrapper(eInflictor, eAttacker, iDamage, iDFlags, sMeansOfDeath, weapon, vPoint, vDir, sHitLoc, vDamageOrigin, psOffsetTime, boneIndex, vSurfaceNormal); + } + + if ( isdefined( eAttacker ) && !attackerIsHittingSelf ) + { + if ( damagefeedback::doDamageFeedback( weapon, eInflictor, iDamage, sMeansOfDeath ) ) + { + // the perk feedback should be shown only if the enemy is damaged and not killed. + if ( iDamage > 0 && self.health > 0 ) + { + perkFeedback = doPerkFeedBack( self, weapon, sMeansOfDeath, eInflictor, armor_damaged ); + } + + eAttacker thread damagefeedback::update( sMeansOfDeath, eInflictor, perkFeedback, weapon, self, psOffsetTime, sHitLoc ); + } + } + + if( !isdefined(eAttacker) || !friendlyFire || ( isdefined( level.hardcoreMode ) && level.hardcoreMode ) ) + { + if ( isdefined( level.customPlayPainSound ) ) + self [[ level.customPlayPainSound ]]( sMeansOfDeath ); + else + self battlechatter::pain_vox( sMeansOfDeath ); + } + + self.hasDoneCombat = true; + + if( weapon.isEmp && sMeansOfDeath == "MOD_GRENADE_SPLASH" ) + { + if( !self hasperk("specialty_immuneemp") ) + { + self notify( "emp_grenaded", eAttacker, vPoint ); + } + } + + if ( isdefined( eAttacker ) && eAttacker != self && !friendlyFire ) + level.useStartSpawns = false; + + player_damage_log( eInflictor, eAttacker, iDamage, iDFlags, sMeansOfDeath, weapon, vPoint, vDir, sHitLoc, psOffsetTime, boneIndex ); + + profilelog_endtiming( 6, "gs=" + game["state"] + " zom=" + SessionModeIsZombiesGame() ); +} + +function resetAttackerList() +{ + self.attackers = []; + self.attackerData = []; + self.attackerDamage = []; + self.firstTimeDamaged = 0; +} + +function resetAttackersThisSpawnList() +{ + self.attackersThisSpawn = []; +} + +function doPerkFeedBack( player, weapon, sMeansOfDeath, eInflictor, armor_damaged ) +{ + perkFeedback = undefined; + hasTacticalMask = loadout::hasTacticalMask( player ); + hasFlakJacket = ( player HasPerk( "specialty_flakjacket" ) ); + isExplosiveDamage = loadout::isExplosiveDamage( sMeansOfDeath ); + isFlashOrStunDamage = weapon_utils::isFlashOrStunDamage( weapon, sMeansOfDeath ); + + if ( isFlashOrStunDamage && hasTacticalMask ) + { + perkFeedback = "tacticalMask"; + } + else if ( player HasPerk( "specialty_fireproof" ) && loadout::isFireDamage( weapon, sMeansOfDeath ) ) + { + perkFeedback = "flakjacket"; + } + else if ( isExplosiveDamage && hasFlakJacket && !weapon.ignoresFlakJacket && ( !isAIKillstreakDamage( weapon, eInflictor ) ) ) + { + perkFeedback = "flakjacket"; + } + else if ( armor_damaged ) + { + perkFeedback = "armor"; + } + + return perkFeedback; +} + +function isAIKillstreakDamage( weapon, eInflictor ) +{ + if ( weapon.isAIKillstreakDamage ) + { + if ( weapon.name != "ai_tank_drone_rocket" || isdefined( eInflictor.firedByAI ) ) + { + return true; + } + } + + return false; +} + +function finishPlayerDamageWrapper( eInflictor, eAttacker, iDamage, iDFlags, sMeansOfDeath, weapon, vPoint, vDir, sHitLoc, vDamageOrigin, psOffsetTime, boneIndex, vSurfaceNormal ) +{ + pixbeginevent("finishPlayerDamageWrapper"); + + if( !level.console && iDFlags & 8 && isplayer ( eAttacker ) ) + { + /# + println("penetrated:" + self getEntityNumber() + " health:" + self.health + " attacker:" + eAttacker.clientid + " inflictor is player:" + isPlayer(eInflictor) + " damage:" + iDamage + " hitLoc:" + sHitLoc); + #/ + eAttacker AddPlayerStat( "penetration_shots", 1 ); + } + + if ( GetDvarString( "scr_csmode" ) != "" ) + self shellShock( "damage_mp", 0.2 ); + + if ( isdefined( level.customDamageShellshockAndRumble ) ) + self [[ level.customDamageShellshockAndRumble ]]( eAttacker, eInflictor, weapon, sMeansOfDeath, iDamage, vPoint ); + else + self damageShellshockAndRumble( eAttacker, eInflictor, weapon, sMeansOfDeath, iDamage ); + + self ability_power::power_loss_event_took_damage( eAttacker, eInflictor, weapon, sMeansOfDeath, iDamage ); + + if( isPlayer( eAttacker) ) + { + self.lastShotBy = eAttacker.clientid; + } + + if ( sMeansOfDeath == "MOD_BURNED" ) + { + self burnplayer::TakingBurnDamage( eAttacker, weapon, sMeansOfDeath ); + } + + self.gadget_was_active_last_damage = self GadgetIsActive( 0 ); + + self finishPlayerDamage( eInflictor, eAttacker, iDamage, iDFlags, sMeansOfDeath, weapon, vPoint, vDir, sHitLoc, vDamageOrigin, psOffsetTime, boneIndex, vSurfaceNormal ); + + pixendevent(); +} + +function allowedAssistWeapon( weapon ) +{ + if ( !killstreaks::is_killstreak_weapon( weapon ) ) + return true; + + if (killstreaks::is_killstreak_weapon_assist_allowed( weapon ) ) + return true; + + return false; +} + +function PlayerKilled_Killstreaks( attacker, weapon ) +{ + if( !isdefined( self.switching_teams ) ) + { + // if team killed we reset kill streak, but dont count death and death streak + if ( isPlayer( attacker ) && level.teamBased && ( attacker != self ) && ( self.team == attacker.team ) ) + { + + self.pers["cur_kill_streak"] = 0; + self.pers["cur_total_kill_streak"] = 0; + self.pers["totalKillstreakCount"] = 0; + self.pers["killstreaksEarnedThisKillstreak"] = 0; + self setplayercurrentstreak( 0 ); + } + else + { + self globallogic_score::incPersStat( "deaths", 1, true, true ); + self.deaths = self globallogic_score::getPersStat( "deaths" ); + self UpdateStatRatio( "kdratio", "kills", "deaths" ); + + if( self.pers["cur_kill_streak"] > self.pers["best_kill_streak"] ) + self.pers["best_kill_streak"] = self.pers["cur_kill_streak"]; + + // need to keep the current killstreak to see if this was a buzzkill later + self.pers["kill_streak_before_death"] = self.pers["cur_kill_streak"]; + + + self.pers["cur_kill_streak"] = 0; + self.pers["cur_total_kill_streak"] = 0; + self.pers["totalKillstreakCount"] = 0; + self.pers["killstreaksEarnedThisKillstreak"] = 0; + self setplayercurrentstreak( 0 ); + + self.cur_death_streak++; + + if ( self.cur_death_streak > self.death_streak ) + { + if ( level.rankedMatch && !level.disableStatTracking ) + { + self setDStat( "HighestStats", "death_streak", self.cur_death_streak ); + } + self.death_streak = self.cur_death_streak; + } + + if( self.cur_death_streak >= GetDvarint( "perk_deathStreakCountRequired" ) ) + { + self enabledeathstreak(); + } + } + } + else + { + self.pers["totalKillstreakCount"] = 0; + self.pers["killstreaksEarnedThisKillstreak"] = 0; + } + + if ( !SessionModeIsZombiesGame() && killstreaks::is_killstreak_weapon( weapon ) ) + { + level.globalKillstreaksDeathsFrom++; + } +} + +function PlayerKilled_WeaponStats( attacker, weapon, sMeansOfDeath, wasInLastStand, lastWeaponBeforeDroppingIntoLastStand, inflictor ) +{ + // Don't increment weapon stats for team kills or deaths + if ( isPlayer( attacker ) && attacker != self && ( !level.teamBased || ( level.teamBased && self.team != attacker.team ) ) ) + { + attackerWeaponPickedUp = false; + if( isdefined( attacker.pickedUpWeapons ) && isdefined( attacker.pickedUpWeapons[weapon] ) ) + { + attackerWeaponPickedUp = true; + } + self AddWeaponStat( weapon, "deaths", 1, self.class_num, attackerWeaponPickedUp, undefined, self.primaryLoadoutGunSmithVariantIndex, self.secondaryLoadoutGunSmithVariantIndex ); + + if ( wasInLastStand && isdefined( lastWeaponBeforeDroppingIntoLastStand ) ) + victim_weapon = lastWeaponBeforeDroppingIntoLastStand; + else + victim_weapon = self.lastdroppableweapon; + + if ( isdefined( victim_weapon ) ) + { + victimWeaponPickedUp = false; + if( isdefined( self.pickedUpWeapons ) && isdefined( self.pickedUpWeapons[victim_weapon] ) ) + { + victimWeaponPickedUp = true; + } + self AddWeaponStat( victim_weapon, "deathsDuringUse", 1, self.class_num, victimWeaponPickedUp, undefined, self.primaryLoadoutGunSmithVariantIndex, self.secondaryLoadoutGunSmithVariantIndex ); + } + + + recordWeaponStatKills = true; + if ( ( attacker.isThief === true ) && isdefined( weapon ) && ( weapon.isHeroWeapon === true ) ) + { + recordWeaponStatKills = false; // Blackjack's Rogue kills are tracked as specialiststats[9].stats.kills_weapon + } + + if ( sMeansOfDeath != "MOD_FALLING" && recordWeaponStatKills ) + { + if ( weapon.name == "explosive_bolt" && IsDefined( inflictor ) && IsDefined( inflictor.ownerWeaponAtLaunch ) && inflictor.ownerAdsAtLaunch ) + { + inflictorOwnerWeaponAtLaunchPickedUp = false; + if( isdefined( attacker.pickedUpWeapons ) && isdefined( attacker.pickedUpWeapons[inflictor.ownerWeaponAtLaunch] ) ) + { + inflictorOwnerWeaponAtLaunchPickedUp = true; // ever the case? + } + attacker AddWeaponStat( inflictor.ownerWeaponAtLaunch, "kills", 1, attacker.class_num, inflictorOwnerWeaponAtLaunchPickedUp, true, attacker.primaryLoadoutGunSmithVariantIndex, attacker.secondaryLoadoutGunSmithVariantIndex ); + } + else + { + if ( isdefined( attacker ) && isdefined( attacker.class_num ) ) + attacker AddWeaponStat( weapon, "kills", 1, attacker.class_num, attackerWeaponPickedUp, undefined, attacker.primaryLoadoutGunSmithVariantIndex, attacker.secondaryLoadoutGunSmithVariantIndex ); + } + } + + if ( sMeansOfDeath == "MOD_HEAD_SHOT" ) + { + attacker AddWeaponStat( weapon, "headshots", 1, attacker.class_num, attackerWeaponPickedUp, undefined, attacker.primaryLoadoutGunSmithVariantIndex, attacker.secondaryLoadoutGunSmithVariantIndex ); + } + + if ( sMeansOfDeath == "MOD_PROJECTILE" || ( ( sMeansOfDeath == "MOD_GRENADE" || sMeansOfDeath == "MOD_IMPACT" ) && weapon.rootWeapon.statIndex == level.weaponLauncherEx41.statIndex ) ) + { + attacker AddWeaponStat( weapon, "direct_hit_kills", 1 ); + } + + victimIsRoulette = ( self.isRoulette === true ); + if ( self ability_player::gadget_CheckHeroAbilityKill( attacker ) && !victimIsRoulette ) + { + attacker AddWeaponStat( attacker.heroAbility, "kills_while_active", 1 ); + } + } +} + +function PlayerKilled_Obituary( attacker, eInflictor, weapon, sMeansOfDeath ) +{ + if ( !isplayer( attacker ) || ( self util::IsEnemyPlayer( attacker ) == false ) || ( isdefined ( weapon ) && killstreaks::is_killstreak_weapon( weapon ) ) ) + { + level notify( "reset_obituary_count" ); + level.lastObituaryPlayerCount = 0; + level.lastObituaryPlayer = undefined; + } + else + { + if ( isdefined( level.lastObituaryPlayer ) && level.lastObituaryPlayer == attacker ) + { + level.lastObituaryPlayerCount++; + } + else + { + level notify( "reset_obituary_count" ); + level.lastObituaryPlayer = attacker; + level.lastObituaryPlayerCount = 1; + } + + level thread scoreevents::decrementLastObituaryPlayerCountAfterFade(); + + if ( level.lastObituaryPlayerCount >= 4 ) + { + level notify( "reset_obituary_count" ); + level.lastObituaryPlayerCount = 0; + level.lastObituaryPlayer = undefined; + self thread scoreevents::uninterruptedObitFeedKills( attacker, weapon ); + } + } + + if ( !isplayer( attacker ) || ( isdefined( weapon ) && !killstreaks::is_killstreak_weapon( weapon ) ) ) + { + behaviorTracker::UpdatePlayerKilled( attacker, self ); + } + + overrideEntityCamera = killstreaks::should_override_entity_camera_in_demo( attacker, weapon ); + + if( isdefined( eInflictor ) && ( eInflictor.archetype === "robot" ) ) + { + if( sMeansOfDeath == "MOD_HIT_BY_OBJECT" ) + weapon = GetWeapon( "combat_robot_marker" ); + sMeansOfDeath = "MOD_RIFLE_BULLET"; + } + // send out an obituary message to all clients about the kill + if( level.teamBased && isdefined( attacker.pers ) && self.team == attacker.team && sMeansOfDeath == "MOD_GRENADE" && level.friendlyfire == 0 ) + { + obituary(self, self, weapon, sMeansOfDeath); + demo::bookmark( "kill", gettime(), self, self, 0, eInflictor, overrideEntityCamera ); + } + else + { + obituary(self, attacker, weapon, sMeansOfDeath); + demo::bookmark( "kill", gettime(), attacker, self, 0, eInflictor, overrideEntityCamera ); + } +} + +function PlayerKilled_Suicide( eInflictor, attacker, sMeansOfDeath, weapon, sHitLoc ) +{ + awardAssists = false; + self.suicide = false; + + // switching teams + if ( isdefined( self.switching_teams ) ) + { + + if ( !level.teamBased && ( isdefined( level.teams[ self.leaving_team ] ) && isdefined( level.teams[ self.joining_team ] ) && level.teams[ self.leaving_team ] != level.teams[ self.joining_team ] ) ) + { + playerCounts = self teams::count_players(); + playerCounts[self.leaving_team]--; + playerCounts[self.joining_team]++; + + if( (playerCounts[self.joining_team] - playerCounts[self.leaving_team]) > 1 ) + { + scoreevents::processScoreEvent( "suicide", self ); + self thread rank::giveRankXP( "suicide" ); + self globallogic_score::incPersStat( "suicides", 1 ); + self.suicides = self globallogic_score::getPersStat( "suicides" ); + self.suicide = true; + } + } + } + else + { + scoreevents::processScoreEvent( "suicide", self ); + self globallogic_score::incPersStat( "suicides", 1 ); + self.suicides = self globallogic_score::getPersStat( "suicides" ); + + if ( sMeansOfDeath == "MOD_SUICIDE" && sHitLoc == "none" && self.throwingGrenade ) + { + self.lastGrenadeSuicideTime = gettime(); + } + + if ( level.maxSuicidesBeforeKick > 0 && level.maxSuicidesBeforeKick <= self.suicides ) + { + // should change "teamKillKicked" to just kicked for the next game + self notify( "teamKillKicked" ); + self SuicideKick(); + } + + //Check for player death related battlechatter + thread battlechatter::on_player_suicide_or_team_kill( self, "suicide" ); //Play suicide battlechatter + + //check if assist points should be awarded + awardAssists = true; + self.suicide = true; + } + + if( isdefined( self.friendlydamage ) ) + { + self iPrintLn(&"MP_FRIENDLY_FIRE_WILL_NOT"); + if ( level.teamKillPointLoss ) + { + scoreSub = self [[level.getTeamKillScore]]( eInflictor, attacker, sMeansOfDeath, weapon); + + score = globallogic_score::_getPlayerScore( attacker ) - scoreSub; + + if ( score < 0 ) + score = 0; + + globallogic_score::_setPlayerScore( attacker, score ); + } + } + + return awardAssists; +} + +function PlayerKilled_TeamKill( eInflictor, attacker, sMeansOfDeath, weapon, sHitLoc ) +{ + scoreevents::processScoreEvent( "team_kill", attacker ); + + self.teamKilled = true; + + if ( !IgnoreTeamKills( weapon, sMeansOfDeath, eInflictor ) ) + { + teamkill_penalty = self [[level.getTeamKillPenalty]]( eInflictor, attacker, sMeansOfDeath, weapon); + + attacker globallogic_score::incPersStat( "teamkills_nostats", teamkill_penalty, false ); + attacker globallogic_score::incPersStat( "teamkills", 1 ); //save team kills to player stats + attacker.teamkillsThisRound++; + + if ( level.teamKillPointLoss ) + { + scoreSub = self [[level.getTeamKillScore]]( eInflictor, attacker, sMeansOfDeath, weapon); + + score = globallogic_score::_getPlayerScore( attacker ) - scoreSub; + + if ( score < 0 ) + { + score = 0; + } + + globallogic_score::_setPlayerScore( attacker, score ); + } + + if ( globallogic_utils::getTimePassed() < 5000 ) + teamKillDelay = 1; + else if ( attacker.pers["teamkills_nostats"] > 1 && globallogic_utils::getTimePassed() < (8000 + (attacker.pers["teamkills_nostats"] * 1000)) ) + teamKillDelay = 1; + else + teamKillDelay = attacker TeamKillDelay(); + + if ( teamKillDelay > 0 ) + { + attacker.teamKillPunish = true; + attacker thread wait_and_suicide(); // can't eject the teamkilling player same frame bc it purges EV_FIRE_WEAPON fx + + if ( attacker ShouldTeamKillKick(teamKillDelay) ) + { + // should change "teamKillKicked" to just kicked for the next game + attacker notify( "teamKillKicked" ); + attacker thread TeamKillKick(); + } + + attacker thread reduceTeamKillsOverTime(); + } + + //Play teamkill battlechatter + if( isPlayer( attacker ) ) + thread battlechatter::on_player_suicide_or_team_kill( attacker, "teamkill" ); + } +} + +function wait_and_suicide() // self == player +{ + self endon( "disconnect" ); + self util::freeze_player_controls( true ); + + wait .25; + + self suicide(); +} + +function PlayerKilled_AwardAssists( eInflictor, attacker, weapon, lpattackteam ) +{ + pixbeginevent( "PlayerKilled assists" ); + + if ( isdefined( self.attackers ) ) + { + for ( j = 0; j < self.attackers.size; j++ ) + { + player = self.attackers[j]; + + if ( !isdefined( player ) ) + continue; + + if ( player == attacker ) + continue; + + if ( player.team != lpattackteam ) + continue; + + damage_done = self.attackerDamage[player.clientId].damage; + player thread globallogic_score::processAssist( self, damage_done, self.attackerDamage[player.clientId].weapon ); + } + } + + if ( level.teamBased ) + { + self globallogic_score::processKillstreakAssists( attacker, eInflictor, weapon ); + } + + if ( isdefined( self.lastAttackedShieldPlayer ) && isdefined( self.lastAttackedShieldTime ) && self.lastAttackedShieldPlayer != attacker ) + { + if ( gettime() - self.lastAttackedShieldTime < 4000 ) + { + self.lastAttackedShieldPlayer thread globallogic_score::processShieldAssist( self ); + } + } + + pixendevent(); //"END: PlayerKilled assists" +} + +function PlayerKilled_Kill( eInflictor, attacker, sMeansOfDeath, weapon, sHitLoc ) +{ + if( !isdefined( killstreaks::get_killstreak_for_weapon( weapon ) ) || ( isdefined( level.killstreaksGiveGameScore ) && level.killstreaksGiveGameScore ) ) + globallogic_score::incTotalKills(attacker.team); + + if( GetDvarInt( "teamOpsEnabled" ) == 1 ) + { + if( isdefined( eInflictor ) && ( isdefined( eInflictor.teamops ) && eInflictor.teamops ) ) + { + if( !isdefined( killstreaks::get_killstreak_for_weapon( weapon ) ) || ( isdefined( level.killstreaksGiveGameScore ) && level.killstreaksGiveGameScore ) ) + globallogic_score::giveTeamScore( "kill", attacker.team, undefined, self ); + return; + } + } + + attacker thread globallogic_score::giveKillStats( sMeansOfDeath, weapon, self ); + + + if ( isAlive( attacker ) ) + { + pixbeginevent("killstreak"); + + if ( !isdefined( eInflictor ) || !isdefined( eInflictor.requiredDeathCount ) || attacker.deathCount == eInflictor.requiredDeathCount ) + { + shouldGiveKillstreak = killstreaks::should_give_killstreak( weapon ); + //attacker thread _properks::earnedAKill(); + + if ( shouldGiveKillstreak ) + { + attacker killstreaks::add_to_killstreak_count( weapon ); + } + + attacker.pers["cur_total_kill_streak"]++; + attacker setplayercurrentstreak( attacker.pers["cur_total_kill_streak"] ); + + //Kills gotten through killstreak weapons should not the players killstreak + if ( isdefined( level.killstreaks ) && shouldGiveKillstreak ) + { + attacker.pers["cur_kill_streak"]++; + + if ( attacker.pers["cur_kill_streak"] >= 2 ) + { + if ( attacker.pers["cur_kill_streak"] == 10 ) + { + attacker challenges::killstreakTen(); + } + if ( attacker.pers["cur_kill_streak"] <= 30 ) + { + scoreevents::processScoreEvent( "killstreak_" + attacker.pers["cur_kill_streak"], attacker, self, weapon ); + + if ( attacker.pers["cur_kill_streak"] == 30 ) + { + attacker challenges::killstreak_30_noscorestreaks(); + } + } + else + { + scoreevents::processScoreEvent( "killstreak_more_than_30", attacker, self, weapon ); + } + } + + if ( !isdefined( level.usingMomentum ) || !level.usingMomentum ) + { + if( GetDvarInt( "teamOpsEnabled" ) == 0 ) + attacker thread killstreaks::give_for_streak(); + } + } + } + + pixendevent(); // "killstreak" + } + + if ( attacker.pers["cur_kill_streak"] > attacker.kill_streak ) + { + if ( level.rankedMatch && !level.disableStatTracking ) + { + attacker setDStat( "HighestStats", "kill_streak", attacker.pers["totalKillstreakCount"] ); + } + attacker.kill_streak = attacker.pers["cur_kill_streak"]; + } + + + if ( attacker.pers["cur_kill_streak"] > attacker.gametype_kill_streak ) + { + attacker persistence::stat_set_with_gametype( "kill_streak", attacker.pers["cur_kill_streak"] ); + attacker.gametype_kill_streak = attacker.pers["cur_kill_streak"]; + } + + killstreak = killstreaks::get_killstreak_for_weapon( weapon ); + + if ( isdefined( killstreak ) ) + { + if ( scoreevents::isRegisteredEvent( killstreak ) ) + { + scoreevents::processScoreEvent( killstreak, attacker, self, weapon ); + } + + if( isdefined( eInflictor ) && ( killstreak == "dart" || killstreak == "inventory_dart" ) ) + { + eInflictor notify( "veh_collision" ); + } + } + else + { + scoreevents::processScoreEvent( "kill", attacker, self, weapon ); + + // if ( sMeansOfDeath == "MOD_HEAD_SHOT" || ( sMeansOfDeath == "MOD_IMPACT" && sHitLoc == "head" ) ) // TODO: add back when applicable LOOT6 weapon is ready + if ( sMeansOfDeath == "MOD_HEAD_SHOT" ) + { + scoreevents::processScoreEvent( "headshot", attacker, self, weapon ); + attacker util::player_contract_event( "headshot" ); + } + else if ( weapon_utils::isMeleeMOD( sMeansOfDeath ) ) + { + scoreevents::processScoreEvent( "melee_kill", attacker, self, weapon ); + } + } + + attacker thread globallogic_score::trackAttackerKill( self.name, self.pers["rank"], self.pers["rankxp"], self.pers["prestige"], self getXuid(), weapon ); + + attackerName = attacker.name; + self thread globallogic_score::trackAttackeeDeath( attackerName, attacker.pers["rank"], attacker.pers["rankxp"], attacker.pers["prestige"], attacker getXuid() ); + self thread medals::setLastKilledBy( attacker ); + + attacker thread globallogic_score::incKillstreakTracker( weapon ); + + // to prevent spectator gain score for team-spectator after throwing a granade and killing someone before he switched + if ( level.teamBased && attacker.team != "spectator") + { + if( !isdefined( killstreak ) || ( isdefined( level.killstreaksGiveGameScore ) && level.killstreaksGiveGameScore ) ) + globallogic_score::giveTeamScore( "kill", attacker.team, attacker, self ); + } + + scoreSub = level.deathPointLoss; + if ( scoreSub != 0 ) + { + globallogic_score::_setPlayerScore( self, globallogic_score::_getPlayerScore( self ) - scoreSub ); + } + + level thread playKillBattleChatter( attacker, weapon, self, eInflictor ); +} + +function should_allow_postgame_death( sMeansOfDeath ) +{ + if ( sMeansOfDeath == "MOD_POST_GAME" ) + return true; + + return false; +} + +function do_post_game_death(eInflictor, attacker, iDamage, sMeansOfDeath, weapon, vDir, sHitLoc, psOffsetTime, deathAnimDuration) +{ + if ( !should_allow_postgame_death( sMeansOfDeath ) ) + return; + + self weapons::detach_carry_object_model(); + + self.sessionstate = "dead"; + self.spectatorclient = -1; + self.killcamentity = -1; + self.archivetime = 0; + self.psoffsettime = 0; + + clone_weapon = weapon; + + // we do not want the weapon death fx to play if this is not a melee weapon and its a melee attack + // ideally the mod be passed to the client side and let it decide but this is post ship t7 and this is safest + if ( weapon_utils::isMeleeMOD(sMeansOfDeath) && clone_weapon.type != "melee" ) + { + clone_weapon = level.weaponNone; + } + body = self clonePlayer( deathAnimDuration, clone_weapon, attacker ); + + if ( isdefined( body ) ) + { + self createDeadBody( attacker, iDamage, sMeansOfDeath, weapon, sHitLoc, vDir, (0,0,0), deathAnimDuration, eInflictor, body ); + } +} + +function Callback_PlayerKilled(eInflictor, attacker, iDamage, sMeansOfDeath, weapon, vDir, sHitLoc, psOffsetTime, deathAnimDuration, enteredResurrect = false) +{ + profilelog_begintiming( 7, "ship" ); + + self endon( "spawned" ); + + + if ( game["state"] == "postgame" ) + { + do_post_game_death(eInflictor, attacker, iDamage, sMeansOfDeath, weapon, vDir, sHitLoc, psOffsetTime, deathAnimDuration); + return; + } + + if ( self.sessionteam == "spectator" ) + return; + + self notify( "killed_player" ); + self callback::callback( #"on_player_killed" ); + + self needsRevive( false ); + + if ( isdefined( self.burning ) && self.burning == true ) + { + self setburn( 0 ); + } + + self.suicide = false; + self.teamKilled = false; + + if ( isdefined( level.takeLivesOnDeath ) && ( level.takeLivesOnDeath == true ) ) + { + if ( self.pers["lives"] ) + { + self.pers["lives"]--; + if ( self.pers["lives"] == 0 ) + { + level notify( "player_eliminated" ); + self notify( "player_eliminated" ); + } + } + if ( game[self.team + "_lives"] ) + { + game[self.team + "_lives"]--; + if ( game[self.team + "_lives"] == 0 ) + { + level notify( "player_eliminated" ); + self notify( "player_eliminated" ); + } + } + } + + self thread globallogic_audio::flush_leader_dialog_key_on_player( "equipmentDestroyed" ); + //self thread globallogic_audio::flush_leader_dialog_key_on_player( "equipmentHacked" ); + + weapon = updateWeapon( eInflictor, weapon ); + + pixbeginevent( "PlayerKilled pre constants" ); + + wasInLastStand = false; + bledOut = false; + deathTimeOffset = 0; + lastWeaponBeforeDroppingIntoLastStand = undefined; + attackerStance = undefined; + self.lastStandThisLife = undefined; + self.vAttackerOrigin = undefined; + + // need to get this before changing the sessionstate + weapon_at_time_of_death = self GetCurrentWeapon(); + + if ( isdefined( self.useLastStandParams ) && enteredResurrect == false ) + { + self.useLastStandParams = undefined; + + assert( isdefined( self.lastStandParams ) ); + if ( !level.teamBased || ( !isdefined( attacker ) || !isplayer( attacker ) || attacker.team != self.team || attacker == self ) ) + { + eInflictor = self.lastStandParams.eInflictor; + attacker = self.lastStandParams.attacker; + attackerStance = self.lastStandParams.attackerStance; + iDamage = self.lastStandParams.iDamage; + sMeansOfDeath = self.lastStandParams.sMeansOfDeath; + weapon = self.lastStandParams.sWeapon; + vDir = self.lastStandParams.vDir; + sHitLoc = self.lastStandParams.sHitLoc; + self.vAttackerOrigin = self.lastStandParams.vAttackerOrigin; + self.killcam_entity_info_cached = self.lastStandParams.killcam_entity_info_cached; + deathTimeOffset = (gettime() - self.lastStandParams.lastStandStartTime) / 1000; + bledOut = true; + if ( isdefined( self.previousPrimary ) ) + { + wasInLastStand = true; + lastWeaponBeforeDroppingIntoLastStand = self.previousPrimary; + } + } + self.lastStandParams = undefined; + } + + self StopSounds(); + + bestPlayer = undefined; + bestPlayerMeansOfDeath = undefined; + obituaryMeansOfDeath = undefined; + bestPlayerWeapon = undefined; + obituaryWeapon = weapon; + assistedSuicide = false; + + if ( isdefined( level.gameModeAssistedSuicide ) ) + { + result = self [[ level.gameModeAssistedSuicide ]]( attacker, sMeansOfDeath, weapon ); + if ( isdefined( result ) ) + { + bestPlayer = result["bestPlayer"]; + bestPlayerMeansOfDeath = result["bestPlayerMeansOfDeath"]; + bestPlayerWeapon = result["bestPlayerWeapon"]; + } + } + + if ( (!isdefined( attacker ) || attacker.classname == "trigger_hurt" || attacker.classname == "worldspawn" || ( isdefined( attacker.isMagicBullet ) && attacker.isMagicBullet == true ) || attacker == self ) && isdefined( self.attackers ) && !self IsPlayerUnderwater() ) + { + if ( !isdefined(bestPlayer) ) + { + for ( i = 0; i < self.attackers.size; i++ ) + { + player = self.attackers[i]; + if ( !isdefined( player ) ) + continue; + + if (!isdefined( self.attackerDamage[ player.clientId ] ) || ! isdefined( self.attackerDamage[ player.clientId ].damage ) ) + continue; + + if ( player == self || (level.teamBased && player.team == self.team ) ) + continue; + + if ( self.attackerDamage[ player.clientId ].lasttimedamaged + 2500 < getTime() ) + continue; + + if ( !allowedAssistWeapon( self.attackerDamage[ player.clientId ].weapon ) ) + continue; + + if ( self.attackerDamage[ player.clientId ].damage > 1 && ! isdefined( bestPlayer ) ) + { + bestPlayer = player; + bestPlayerMeansOfDeath = self.attackerDamage[ player.clientId ].meansOfDeath; + bestPlayerWeapon = self.attackerDamage[ player.clientId ].weapon; + } + else if ( isdefined( bestPlayer ) && self.attackerDamage[ player.clientId ].damage > self.attackerDamage[ bestPlayer.clientId ].damage ) + { + bestPlayer = player; + bestPlayerMeansOfDeath = self.attackerDamage[ player.clientId ].meansOfDeath; + bestPlayerWeapon = self.attackerDamage[ player.clientId ].weapon; + } + } + } + if ( isdefined ( bestPlayer ) ) + { + scoreevents::processScoreEvent( "assisted_suicide", bestPlayer, self, weapon ); + self RecordKillModifier("assistedsuicide"); + assistedSuicide = true; + } + } + + if ( isdefined ( bestPlayer ) ) + { + attacker = bestPlayer; + obituaryMeansOfDeath = bestPlayerMeansOfDeath; + obituaryWeapon = bestPlayerWeapon; + if ( isdefined( bestPlayerWeapon ) ) + { + weapon = bestPlayerWeapon; + } + } + + if ( isplayer( attacker ) && isdefined( attacker.damagedPlayers ) ) + attacker.damagedPlayers[self.clientid] = undefined; + + if ( enteredResurrect == false ) + { + globallogic::DoWeaponSpecificKillEffects(eInflictor, attacker, iDamage, sMeansOfDeath, weapon, vDir, sHitLoc, psOffsetTime); + } + + self.deathTime = getTime(); + + if ( attacker != self && (!level.teamBased || attacker.team != self.team )) + { + assert( IsDefined( self.lastspawntime ) ); + self.aliveTimes[self.aliveTimeCurrentIndex] = self.deathTime - self.lastspawntime; + self.aliveTimeCurrentIndex = (self.aliveTimeCurrentIndex + 1) % level.aliveTimeMaxCount; + } + + attacker = updateAttacker( attacker, weapon ); + eInflictor = updateInflictor( eInflictor ); + + sMeansOfDeath = self PlayerKilled_UpdateMeansOfDeath( attacker, eInflictor, weapon, sMeansOfDeath, sHitLoc ); + + if ( !isdefined( obituaryMeansOfDeath ) ) + obituaryMeansOfDeath = sMeansOfDeath; + + self.hasRiotShield = false; + self.hasRiotShieldEquipped = false; + + self thread updateGlobalBotKilledCounter(); + + self PlayerKilled_WeaponStats( attacker, weapon, sMeansOfDeath, wasInLastStand, lastWeaponBeforeDroppingIntoLastStand, eInflictor ); + + if ( bledOut == false ) + { + if( GetDvarInt( "teamOpsEnabled" ) == 1 && ( isdefined( eInflictor ) && ( isdefined( eInflictor.teamops ) && eInflictor.teamops ) ) ) + { + self PlayerKilled_Obituary( eInflictor, eInflictor, obituaryWeapon, obituaryMeansOfDeath ); + } + else + { + self PlayerKilled_Obituary( attacker, eInflictor, obituaryWeapon, obituaryMeansOfDeath ); + } + } + + if ( enteredResurrect == false ) + { +// spawnlogic::death_occured(self, attacker); + + self.sessionstate = "dead"; + self.statusicon = "hud_status_dead"; + } + + self.pers["weapon"] = undefined; + + self.killedPlayersCurrent = []; + + self.deathCount++; + +/# + println( "players("+self.clientId+") death count ++: " + self.deathCount ); +#/ + + if ( bledout == false ) + { + self PlayerKilled_Killstreaks( attacker, weapon ); + } + + lpselfnum = self getEntityNumber(); + lpselfname = self.name; + lpattackGuid = ""; + lpattackname = ""; + lpselfteam = self.team; + lpselfguid = self getXuid(); + + if (self util::is_bot()) + { + lpselfGuid = "bot0"; + } + + lpattackteam = ""; + lpattackorigin = ( 0, 0, 0 ); + + lpattacknum = -1; + + //check if we should award assist points + awardAssists = false; + wasTeamKill = false; + wasSuicide = false; + + pixendevent(); // "PlayerKilled pre constants" ); + + scoreevents::processScoreEvent( "death", self, self, weapon ); + self.pers["resetMomentumOnSpawn"] = level.scoreResetOnDeath; + + + if( isPlayer( attacker ) ) + { + lpattackGuid = attacker getXuid(); + + if (attacker util::is_bot()) + { + lpattackGuid = "bot0"; + } + + lpattackname = attacker.name; + lpattackteam = attacker.team; + lpattackorigin = attacker.origin; + + if ( attacker == self || assistedSuicide == true ) // killed himself + { + doKillcam = false; + wasSuicide = true; + + awardAssists = self PlayerKilled_Suicide( eInflictor, attacker, sMeansOfDeath, weapon, sHitLoc ); + if( assistedSuicide == true ) + attacker thread globallogic_score::giveKillStats( sMeansOfDeath, weapon, self ); + } + else + { + pixbeginevent( "PlayerKilled attacker" ); + + lpattacknum = attacker getEntityNumber(); + + doKillcam = true; + + if ( level.teamBased && self.team == attacker.team && sMeansOfDeath == "MOD_GRENADE" && level.friendlyfire == 0 ) + { + } + else if ( level.teamBased && self.team == attacker.team ) // killed by a friendly + { + wasTeamKill = true; + + self PlayerKilled_TeamKill( eInflictor, attacker, sMeansOfDeath, weapon, sHitLoc ); + } + else + { + if ( bledOut == false ) + { + self PlayerKilled_Kill( eInflictor, attacker, sMeansOfDeath, weapon, sHitLoc ); + + if ( level.teamBased ) + { + //check if assist points should be awarded + awardAssists = true; + } + } + } + + pixendevent(); //"PlayerKilled attacker" + } + } + else if ( isdefined( attacker ) && ( attacker.classname == "trigger_hurt" || attacker.classname == "worldspawn" ) ) + { + doKillcam = false; + + lpattacknum = -1; + lpattackguid = ""; + lpattackname = ""; + lpattackteam = "world"; + + scoreevents::processScoreEvent( "suicide", self ); + self globallogic_score::incPersStat( "suicides", 1 ); + self.suicides = self globallogic_score::getPersStat( "suicides" ); + + self.suicide = true; + + //Check for player death related battlechatter + thread battlechatter::on_player_suicide_or_team_kill( self, "suicide" ); //Play suicide battlechatter + + //check if assist points should be awarded + awardAssists = true; + + if ( level.maxSuicidesBeforeKick > 0 && level.maxSuicidesBeforeKick <= self.suicides ) + { + // should change "teamKillKicked" to just kicked for the next game + self notify( "teamKillKicked" ); + self SuicideKick(); + } + } + else + { + doKillcam = false; + + lpattacknum = -1; + lpattackguid = ""; + lpattackname = ""; + lpattackteam = "world"; + + wasSuicide = true; + + // we may have a killcam on an world entity like the rocket in cosmodrome + if ( isdefined( eInflictor ) && isdefined( eInflictor.killCamEnt ) ) + { + doKillcam = true; + lpattacknum = self getEntityNumber(); + wasSuicide = false; + } + + // even if the attacker isn't a player, it might be on a team + if ( isdefined( attacker ) && isdefined( attacker.team ) && ( isdefined( level.teams[attacker.team] ) ) ) + { + if ( attacker.team != self.team ) + { + if ( level.teamBased ) + { + if( !isdefined( killstreaks::get_killstreak_for_weapon( weapon ) ) || ( isdefined( level.killstreaksGiveGameScore ) && level.killstreaksGiveGameScore ) ) + globallogic_score::giveTeamScore( "kill", attacker.team, attacker, self ); + } + + wasSuicide = false; + } + } + + //check if assist points should be awarded + awardAssists = true; + } + + if ( !level.inGracePeriod && enteredResurrect == false ) + { + if ( sMeansOfDeath != "MOD_GRENADE" && sMeansOfDeath != "MOD_GRENADE_SPLASH" && sMeansOfDeath != "MOD_EXPLOSIVE" && sMeansOfDeath != "MOD_EXPLOSIVE_SPLASH" && sMeansOfDeath != "MOD_PROJECTILE_SPLASH" && sMeansOfDeath != "MOD_FALLING" ) + { + if ( weapon.name != "incendiary_fire" ) + { + self weapons::drop_scavenger_for_death( attacker ); + } + } + + if ( should_drop_weapon_on_death( wasTeamkill, wasSuicide, weapon_at_time_of_death, sMeansOfDeath ) ) + { + self weapons::drop_for_death( attacker, weapon, sMeansOfDeath ); + } + } + + //award assist points if needed + if( awardAssists ) + { + self PlayerKilled_AwardAssists( eInflictor, attacker, weapon, lpattackteam ); + } + + pixbeginevent( "PlayerKilled post constants" ); + + self.lastAttacker = attacker; + self.lastDeathPos = self.origin; + + if ( isdefined( attacker ) && isPlayer( attacker ) && attacker != self && (!level.teambased || attacker.team != self.team) ) + { + attacker notify( "killed_enemy_player", self, weapon ); + if( isDefined( attacker.gadget_thief_kill_callback ) ) + { + attacker [[attacker.gadget_thief_kill_callback]]( self, weapon ); + } + self thread challenges::playerKilled(eInflictor, attacker, iDamage, sMeansOfDeath, weapon, sHitLoc, attackerStance, bledOut ); + } + else + { + + self notify("playerKilledChallengesProcessed"); + } + + if ( isdefined ( self.attackers )) + self.attackers = []; + + + // minimize repeat checks of things like isPlayer + killerHeroPowerActive = 0; + killer = undefined; + killerLoadoutIndex = -1; + killerWasADS = false; + killerInVictimFOV = false; + victimInKillerFOV = false; + + if( isPlayer( attacker ) ) + { + attacker.lastKillTime = gettime(); + + killer = attacker; + if ( isdefined( attacker.class_num ) ) + killerLoadoutIndex = attacker.class_num; + killerWasADS = attacker playerADS() >= 1; + + killerInVictimFOV = util::within_fov( self.origin, self.angles, attacker.origin, self.fovcosine ); + victimInKillerFOV = util::within_fov( attacker.origin, attacker.angles, self.origin, attacker.fovcosine ); + + if ( attacker ability_player::is_using_any_gadget() ) + killerHeroPowerActive = 1; + + if( killstreaks::is_killstreak_weapon( weapon ) ) + { + killstreak = killstreaks::get_killstreak_for_weapon_for_stats( weapon ); + + bbPrint( "mpattacks", "gametime %d attackerspawnid %d attackerweapon %s attackerx %d attackery %d attackerz %d victimspawnid %d victimx %d victimy %d victimz %d damage %d damagetype %s damagelocation %s death %d isusingheropower %d killstreak %s", + gettime(), getplayerspawnid( attacker ), weapon.name, lpattackorigin, getplayerspawnid( self ), self.origin, iDamage, sMeansOfDeath, sHitLoc, 1, killerHeroPowerActive, killstreak ); + } + else + { + bbPrint( "mpattacks", "gametime %d attackerspawnid %d attackerweapon %s attackerx %d attackery %d attackerz %d victimspawnid %d victimx %d victimy %d victimz %d damage %d damagetype %s damagelocation %s death %d isusingheropower %d", + gettime(), getplayerspawnid( attacker ), weapon.name, lpattackorigin, getplayerspawnid( self ), self.origin, iDamage, sMeansOfDeath, sHitLoc, 1, killerHeroPowerActive ); + } + + attacker thread weapons::bestweapon_kill( weapon ); + } + else + { + bbPrint( "mpattacks", "gametime %d attackerweapon %s victimspawnid %d victimx %d victimy %d victimz %d damage %d damagetype %s damagelocation %s death %d isusingheropower %d", + gettime(), weapon.name, getplayerspawnid( self ), self.origin, iDamage, sMeansOfDeath, sHitLoc, 1, 0 ); + } + + victimWeapon = undefined; + victimWeaponPickedUp = false; + victimKillstreakWeaponIndex = 0; + if( isdefined( weapon_at_time_of_death ) ) + { + victimWeapon = weapon_at_time_of_death; + if( isdefined( self.pickedUpWeapons ) && isdefined( self.pickedUpWeapons[victimWeapon] ) ) + { + victimWeaponPickedUp = true; + } + + if( killstreaks::is_killstreak_weapon( victimWeapon ) ) + { + killstreak = killstreaks::get_killstreak_for_weapon_for_stats( victimWeapon ); + if( isdefined( level.killstreaks[killstreak].menuname ) ) + { + victimKillstreakWeaponIndex = level.killstreakindices[level.killstreaks[killstreak].menuname]; + } + } + } + victimWasADS = self playerADS() >= 1; + victimHeroPowerActive = self ability_player::is_using_any_gadget(); + + killerWeaponPickedUp = false; + killerKillstreakWeaponIndex = 0; + killerKillstreakEventIndex = 125; // 125 = not a killstreak + if( isdefined( weapon ) ) + { + if( isdefined( killer ) && isdefined( killer.pickedUpWeapons ) && isdefined( killer.pickedUpWeapons[weapon] ) ) + { + killerWeaponPickedUp = true; + } + + if( killstreaks::is_killstreak_weapon( weapon ) ) + { + killstreak = killstreaks::get_killstreak_for_weapon_for_stats( weapon ); + if( isdefined( level.killstreaks[killstreak].menuname ) ) + { + killerKillstreakWeaponIndex = level.killstreakindices[level.killstreaks[killstreak].menuname]; + + if( isdefined( killer.killstreakEvents ) && isdefined( killer.killstreakEvents[ killerkillstreakweaponindex ] ) ) + { + killerKillstreakEventIndex = killer.killstreakEvents[killerkillstreakweaponindex]; + } + else + { + killerkillstreakeventindex = 126; // 126 = was a killstreak but no event index + } + } + } + } + + // + // Log additional stuff in match record on death. + // Mostly values we can't easily access in the existing MatchRecordDeath function in code. + // + + matchRecordLogAdditionalDeathInfo( self, killer, victimWeapon, weapon, + self.class_num, victimWeaponPickedUp, victimWasADS, + killerLoadoutIndex, killerWeaponPickedUp, killerWasADS, + victimHeroPowerActive, killerHeroPowerActive, + victimInKillerFOV, killerInVictimFOV, + killerKillstreakWeaponIndex, victimKillstreakWeaponIndex, + killerkillstreakeventindex); + + + self record_special_move_data_for_life( killer ); + + self.pickedUpWeapons = []; // reset on each death + + + logPrint( "K;" + lpselfguid + ";" + lpselfnum + ";" + lpselfteam + ";" + lpselfname + ";" + lpattackguid + ";" + lpattacknum + ";" + lpattackteam + ";" + lpattackname + ";" + weapon.name + ";" + iDamage + ";" + sMeansOfDeath + ";" + sHitLoc + "\n" ); + attackerString = "none"; + if ( isPlayer( attacker ) ) // attacker can be the worldspawn if it's not a player + attackerString = attacker getXuid() + "(" + lpattackname + ")"; + /#print( "d " + sMeansOfDeath + "(" + weapon.name + ") a:" + attackerString + " d:" + iDamage + " l:" + sHitLoc + " @ " + int( self.origin[0] ) + " " + int( self.origin[1] ) + " " + int( self.origin[2] ) );#/ + + // for cod caster update the top scorers + if ( !level.rankedMatch && !level.teambased ) + { + level thread update_ffa_top_scorers(); + } + + level thread globallogic::updateTeamStatus(); + level thread globallogic::updateAliveTimes(self.team); + + if ( isdefined( self.killcam_entity_info_cached ) ) + { + killcam_entity_info = self.killcam_entity_info_cached; + self.killcam_entity_info_cached = undefined; + } + else + { + killcam_entity_info = killcam::get_killcam_entity_info( attacker, eInflictor, weapon ); + } + + + // no killcam if the player is still involved with a killstreak + if ( isdefined( self.killstreak_delay_killcam ) ) + doKillcam = false; + + self weapons::detach_carry_object_model(); + + pixendevent(); //"END: PlayerKilled post constants" + + pixbeginevent( "PlayerKilled body and gibbing" ); + vAttackerOrigin = undefined; + if ( isdefined( attacker ) ) + { + vAttackerOrigin = attacker.origin; + } + + if ( enteredResurrect == false ) + { + clone_weapon = weapon; + + // we do not want the weapon death fx to play if this is not a melee weapon and its a melee attack + // ideally the mod be passed to the client side and let it decide but this is post ship t7 and this is safest + if ( weapon_utils::isMeleeMOD(sMeansOfDeath) && clone_weapon.type != "melee" ) + { + clone_weapon = level.weaponNone; + } + body = self clonePlayer( deathAnimDuration, clone_weapon, attacker ); + + if ( isdefined( body ) ) + { + self createDeadBody( attacker, iDamage, sMeansOfDeath, weapon, sHitLoc, vDir, vAttackerOrigin, deathAnimDuration, eInflictor, body ); + + if ( isdefined( level.customPlayDeathSound ) ) + self [[ level.customPlayDeathSound ]]( body, attacker, weapon, sMeansOfDeath ); + else + self battlechatter::play_death_vox( body, attacker, weapon, sMeansOfDeath ); + + globallogic::DoWeaponSpecificCorpseEffects(body, eInflictor, attacker, iDamage, sMeansOfDeath, weapon, vDir, sHitLoc, psOffsetTime); + } + } + + + pixendevent();// "END: PlayerKilled body and gibbing" + + if ( enteredResurrect ) + { + thread globallogic_spawn::spawnQueuedClient( self.team, attacker ); + } + + self.switching_teams = undefined; + self.joining_team = undefined; + self.leaving_team = undefined; + + if ( bledOut == false ) // handled in PlayerLastStand + { + self thread [[level.onPlayerKilled]](eInflictor, attacker, iDamage, sMeansOfDeath, weapon, vDir, sHitLoc, psOffsetTime, deathAnimDuration); + } + + if ( isdefined( level.teamopsOnPlayerKilled ) ) + { + self [[level.teamopsOnPlayerKilled]]( eInflictor, attacker, iDamage, sMeansOfDeath, weapon, vDir, sHitLoc, psOffsetTime, deathAnimDuration); + } + + for ( iCB = 0; iCB < level.onPlayerKilledExtraUnthreadedCBs.size; iCB++ ) + { + self [[ level.onPlayerKilledExtraUnthreadedCBs[ iCB ] ]]( + eInflictor, + attacker, + iDamage, + sMeansOfDeath, + weapon, + vDir, + sHitLoc, + psOffsetTime, + deathAnimDuration ); + } + + self.wantSafeSpawn = false; + perks = []; + // perks = globallogic::getPerks( attacker ); + killstreaks = globallogic::getKillstreaks( attacker ); + + if( !isdefined( self.killstreak_delay_killcam ) ) + { + // start the prediction now so the client gets updates while waiting to spawn + self thread [[level.spawnPlayerPrediction]](); + } + + profilelog_endtiming( 7, "gs=" + game["state"] + " zom=" + SessionModeIsZombiesGame() ); + + // record the kill cam values for the final kill cam + if ( wasTeamKill == false && assistedSuicide == false && sMeansOfDeath != "MOD_SUICIDE" && !( !isdefined( attacker ) || attacker.classname == "trigger_hurt" || attacker.classname == "worldspawn" || attacker == self || isdefined ( attacker.disableFinalKillcam ) ) ) + { + level thread killcam::record_settings( lpattacknum, self getEntityNumber(), weapon, sMeansOfDeath, self.deathTime, deathTimeOffset, psOffsetTime, killcam_entity_info, perks, killstreaks, attacker ); + } + if ( enteredResurrect ) + { + return; + } + + // let the player watch themselves die + wait ( 0.25 ); + + //check if killed by a sniper + weaponClass = util::getWeaponClass( weapon ); + if( isdefined( weaponClass ) && weaponClass == "weapon_sniper" ) + { + self thread battlechatter::killed_by_sniper( attacker ); + } + else + { + self thread battlechatter::player_killed( attacker, killstreak ); + } + self.cancelKillcam = false; + self thread killcam::cancel_on_use(); + + // initial death cam + self playerkilled_watch_death(weapon, sMeansOfDeath, deathAnimDuration); + + // killcam +/# + if ( GetDvarint( "scr_forcekillcam" ) != 0 ) + { + doKillcam = true; + + if ( lpattacknum < 0 ) + lpattacknum = self getEntityNumber(); + } +#/ + + if ( game["state"] != "playing" ) + { + return; + } + + self.respawnTimerStartTime = gettime(); + keep_deathcam = false; + if ( isdefined( self.overridePlayerDeadStatus ) ) + { + keep_deathcam = self [[ self.overridePlayerDeadStatus ]](); + } + + if ( !self.cancelKillcam && doKillcam && level.killcam && ( wasTeamKill == false ) ) + { + livesLeft = !(level.numLives && !self.pers["lives"]) && !(level.numTeamLives && !game[self.team+"_lives"]); + timeUntilSpawn = globallogic_spawn::TimeUntilSpawn( true ); + willRespawnImmediately = livesLeft && (timeUntilSpawn <= 0) && !level.playerQueuedRespawn; + + self killcam::killcam( lpattacknum, self getEntityNumber(), killcam_entity_info, weapon, sMeansOfDeath, self.deathTime, deathTimeOffset, psOffsetTime, willRespawnImmediately, globallogic_utils::timeUntilRoundEnd(), perks, killstreaks, attacker, keep_deathcam ); + } + else if( self.cancelKillcam ) + { + // copy of code from wait_skip_killcam_button + // because fast button mashers (not hard to do) will "skip" the killcam + // before it even starts + if( isdefined( self.killcamsSkipped) ) + { + self.killcamsSkipped++; + } + else + { + self.killcamsSkipped = 1; + } + } + + // secondary deathcam for resurrection + + secondary_deathcam = 0.0; + + timeUntilSpawn = globallogic_spawn::TimeUntilSpawn( true ); + shouldDoSecondDeathCam = timeUntilSpawn > 0; + + if ( shouldDoSecondDeathCam && IsDefined(self.secondaryDeathCamTime) ) + { + secondary_deathcam = self [[self.secondaryDeathCamTime]](); + } + + if ( secondary_deathcam > 0.0 && !self.cancelKillcam ) + { + self.spectatorclient = -1; + self.killcamentity = -1; + self.archivetime = 0; + self.psoffsettime = 0; + self.spectatekillcam = false; + globallogic_utils::waitForTimeOrNotify( secondary_deathcam, "end_death_delay" ); + self notify ( "death_delay_finished" ); + } + + // secondary deathcam is complete + + if ( !self.cancelKillcam && doKillcam && level.killcam && keep_deathcam ) + { + self.sessionstate = "dead"; + self.spectatorclient = -1; + self.killcamentity = -1; + self.archivetime = 0; + self.psoffsettime = 0; + self.spectatekillcam = false; + } + + if ( game["state"] != "playing" ) + { + self.sessionstate = "dead"; + self.spectatorclient = -1; + self.killcamtargetentity = -1; + self.killcamentity = -1; + self.archivetime = 0; + self.psoffsettime = 0; + self.spectatekillcam = false; + return; + } + + WaitTillKillStreakDone(); + useRespawnTime = true; + if( isDefined( level.hostMigrationTimer ) ) + { + useRespawnTime = false; + } + hostmigration::waittillHostMigrationCountDown(); + //if ( isDefined( level.hostMigrationTimer ) ) + //return; + + // class may be undefined if we have changed teams + if ( globallogic_utils::isValidClass( self.curClass ) ) + { + timePassed = undefined; + + if ( isdefined( self.respawnTimerStartTime ) && useRespawnTime ) + { + timePassed = (gettime() - self.respawnTimerStartTime) / 1000; + } + + self thread [[level.spawnClient]]( timePassed ); + self.respawnTimerStartTime = undefined; + } +} + +function update_ffa_top_scorers() +{ + waittillframeend; + + if ( !level.players.size || level.gameEnded ) + return; + + placement = []; + foreach ( player in level.players ) + { + if ( player.team != "spectator" ) + placement[placement.size] = player; + } + + for ( i = 1; i < placement.size; i++ ) + { + player = placement[i]; + playerScore = player.pointstowin; + for ( j = i - 1; j >= 0 && (playerScore > placement[j].pointstowin || (playerScore == placement[j].pointstowin && player.deaths < placement[j].deaths) || (playerScore == placement[j].pointstowin && player.deaths == placement[j].deaths && player.lastKillTime > placement[j].lastKillTime)); j-- ) + placement[j + 1] = placement[j]; + placement[j + 1] = player; + } + + ClearTopScorers(); + for ( i = 0; i < placement.size && i < 3; i++ ) + { + SetTopScorer( i, placement[i], 0, 0, 0, 0, level.weaponNone ); + } +} + +function playerkilled_watch_death(weapon, sMeansOfDeath, deathAnimDuration) +{ + defaultPlayerDeathWatchTime = 1.75; + if ( sMeansOfDeath == "MOD_MELEE_ASSASSINATE" || 0 > weapon.deathCamTime ) + { + defaultPlayerDeathWatchTime = (deathAnimDuration * 0.001) + 0.5; + } + else if ( 0 < weapon.deathCamTime ) + { + defaultPlayerDeathWatchTime = weapon.deathCamTime; + } + + if ( isdefined ( level.overridePlayerDeathWatchTimer ) ) + { + defaultPlayerDeathWatchTime = [[level.overridePlayerDeathWatchTimer]]( defaultPlayerDeathWatchTime ); + } + + globallogic_utils::waitForTimeOrNotify( defaultPlayerDeathWatchTime, "end_death_delay" ); + + self notify ( "death_delay_finished" ); +} + +function should_drop_weapon_on_death( wasTeamKill, wasSuicide, current_weapon, sMeansOfDeath ) +{ + // to avoid exploits dont allow weapon drops on suicide or teamkills. + if ( wasTeamKill ) + return false; + + if ( wasSuicide ) + return false; + + // assuming this means that they are in a death trigger out of bounds and falling + if ( sMeansOfDeath == "MOD_TRIGGER_HURT" && !self IsOnGround()) + return false; + + // dont drop any weapon if they were holding a hero weapon + if ( IsDefined(current_weapon) && current_weapon.isHeroWeapon ) + return false; + + return true; +} + +function updateGlobalBotKilledCounter() +{ + if ( isdefined( self.pers["isBot"] ) ) + { + level.globalLarrysKilled++; + } +} + + +function WaitTillKillStreakDone() +{ + if( isdefined( self.killstreak_delay_killcam ) ) + { + while( isdefined( self.killstreak_delay_killcam ) ) + { + wait( 0.1 ); + } + + //Plus a small amount so we can see our dead body + wait( 2.0 ); + + self killstreaks::reset_killstreak_delay_killcam(); + } +} + +function SuicideKick() +{ + self globallogic_score::incPersStat( "sessionbans", 1 ); + + self endon("disconnect"); + waittillframeend; + + globallogic::gameHistoryPlayerKicked(); + + ban( self getentitynumber() ); + globallogic_audio::leader_dialog( "gamePlayerKicked" ); +} + +function TeamKillKick() +{ + self globallogic_score::incPersStat( "sessionbans", 1 ); + + self endon("disconnect"); + waittillframeend; + + //for test purposes lets lock them out of certain game type for 2mins + + playlistbanquantum = tweakables::getTweakableValue( "team", "teamkillerplaylistbanquantum" ); + playlistbanpenalty = tweakables::getTweakableValue( "team", "teamkillerplaylistbanpenalty" ); + if ( playlistbanquantum > 0 && playlistbanpenalty > 0 ) + { + timeplayedtotal = self GetDStat( "playerstatslist", "time_played_total", "StatValue" ); + minutesplayed = timeplayedtotal / 60; + + freebees = 2; + + banallowance = int( floor(minutesplayed / playlistbanquantum) ) + freebees; + + if ( self.sessionbans > banallowance ) + { + self SetDStat( "playerstatslist", "gametypeban", "StatValue", timeplayedtotal + (playlistbanpenalty * 60) ); + } + } + + globallogic::gameHistoryPlayerKicked(); + + ban( self getentitynumber() ); + globallogic_audio::leader_dialog( "gamePlayerKicked" ); +} + +function TeamKillDelay() +{ + teamkills = self.pers["teamkills_nostats"]; + if ( level.minimumAllowedTeamKills < 0 || teamkills <= level.minimumAllowedTeamKills ) + return 0; + + exceeded = (teamkills - level.minimumAllowedTeamKills); + return level.teamKillSpawnDelay * exceeded; +} + + +function ShouldTeamKillKick(teamKillDelay) +{ + if ( teamKillDelay && ( level.minimumAllowedTeamKills >= 0 ) ) + { + // if its more then 5 seconds into the match and we have a delay then just kick them + if ( globallogic_utils::getTimePassed() >= 5000 ) + { + return true; + } + + // if its under 5 seconds into the match only kick them if they have killed more then one players so far + if ( self.pers["teamkills_nostats"] > 1 ) + { + return true; + } + } + + return false; +} + +function reduceTeamKillsOverTime() +{ + timePerOneTeamkillReduction = 20.0; + reductionPerSecond = 1.0 / timePerOneTeamkillReduction; + + while(1) + { + if ( isAlive( self ) ) + { + self.pers["teamkills_nostats"] -= reductionPerSecond; + if ( self.pers["teamkills_nostats"] < level.minimumAllowedTeamKills ) + { + self.pers["teamkills_nostats"] = level.minimumAllowedTeamKills; + break; + } + } + wait 1; + } +} + + +function IgnoreTeamKills( weapon, sMeansOfDeath, eInflictor ) +{ + if ( weapon_utils::isMeleeMOD( sMeansOfDeath ) ) + return false; + + if ( weapon.ignoreTeamKills ) + return true; + + if ( isdefined( eInflictor ) && eInflictor.ignore_team_kills === true ) + return true; + + if( isDefined( eInflictor ) && isDefined( eInflictor.destroyedBy ) && isDefined( eInflictor.owner ) && eInflictor.destroyedBy != eInflictor.owner ) + return true; + + if ( isDefined( eInflictor ) && eInflictor.classname == "worldspawn" ) + return true; + + return false; +} + + +function Callback_PlayerLastStand( eInflictor, eAttacker, iDamage, sMeansOfDeath, weapon, vDir, sHitLoc, psOffsetTime, deathAnimDuration ) +{ + laststand::PlayerLastStand( eInflictor, eAttacker, iDamage, sMeansOfDeath, weapon, vDir, sHitLoc, psOffsetTime, deathAnimDuration ); +} + +function damageShellshockAndRumble( eAttacker, eInflictor, weapon, sMeansOfDeath, iDamage ) +{ + self thread weapons::on_damage( eAttacker, eInflictor, weapon, sMeansOfDeath, iDamage ); + + if ( !self util::isUsingRemote() ) + { + self PlayRumbleOnEntity( "damage_heavy" ); + } +} + + +function createDeadBody( attacker, iDamage, sMeansOfDeath, weapon, sHitLoc, vDir, vAttackerOrigin, deathAnimDuration, eInflictor, body ) +{ + if ( sMeansOfDeath == "MOD_HIT_BY_OBJECT" && self GetStance() == "prone" ) + { + self.body = body; + if ( !isdefined( self.switching_teams ) ) + thread deathicons::add( body, self, self.team, 5.0 ); + + return; + } + + ragdoll_now = false; + if( isdefined(self.usingvehicle) && self.usingvehicle && isdefined(self.vehicleposition) && self.vehicleposition == 1 ) + { + ragdoll_now = true; + } + + if ( isdefined( level.ragdoll_override ) && self [[level.ragdoll_override]]( iDamage, sMeansOfDeath, weapon, sHitLoc, vDir, vAttackerOrigin, deathAnimDuration, eInflictor, ragdoll_now, body ) ) + { + return; + } + + if ( ( ragdoll_now ) || self isOnLadder() || self isMantling() || sMeansOfDeath == "MOD_CRUSH" || sMeansOfDeath == "MOD_HIT_BY_OBJECT" ) + body startRagDoll(); + + if ( !self IsOnGround() && sMeansOfDeath != "MOD_FALLING" ) + { + if ( GetDvarint( "scr_disable_air_death_ragdoll" ) == 0 ) + { + body startRagDoll(); + } + } + + if( sMeansOfDeath == "MOD_MELEE_ASSASSINATE" && !attacker isOnGround() ) + { + body start_death_from_above_ragdoll( vDir ); + } + + if ( self is_explosive_ragdoll( weapon, eInflictor ) ) + { + body start_explosive_ragdoll( vDir, weapon ); + } + + thread delayStartRagdoll( body, sHitLoc, vDir, weapon, eInflictor, sMeansOfDeath ); + + if ( sMeansOfDeath == "MOD_CRUSH" ) + { + body globallogic_vehicle::vehicleCrush(); + } + + self.body = body; + if ( !isdefined( self.switching_teams ) ) + thread deathicons::add( body, self, self.team, 5.0 ); +} + +function is_explosive_ragdoll( weapon, inflictor ) +{ + if ( !isdefined( weapon ) ) + { + return false; + } + + // destructible explosives + if ( weapon.name == "destructible_car" || weapon.name == "explodable_barrel" ) + { + return true; + } + + // special explosive weapons + if ( weapon.projExplosionType == "grenade" ) + { + if ( isdefined( inflictor ) && isdefined( inflictor.stuckToPlayer ) ) + { + if ( inflictor.stuckToPlayer == self ) + { + return true; + } + } + } + + return false; +} + +function start_explosive_ragdoll( dir, weapon ) +{ + if ( !isdefined( self ) ) + { + return; + } + + x = RandomIntRange( 50, 100 ); + y = RandomIntRange( 50, 100 ); + z = RandomIntRange( 10, 20 ); + + if ( isdefined( weapon ) && (weapon.name == "sticky_grenade" || weapon.name == "explosive_bolt") ) + { + if ( isdefined( dir ) && LengthSquared( dir ) > 0 ) + { + x = dir[0] * x; + y = dir[1] * y; + } + } + else + { + if ( math::cointoss() ) + { + x = x * -1; + } + if ( math::cointoss() ) + { + y = y * -1; + } + } + + self StartRagdoll(); + self LaunchRagdoll( ( x, y, z ) ); +} + +function start_death_from_above_ragdoll( dir ) +{ + if ( !isdefined( self ) ) + { + return; + } + + self StartRagdoll(); + self LaunchRagdoll( ( 0, 0, -100 ) ); +} + + +function notifyConnecting() +{ + waittillframeend; + + if( isdefined( self ) ) + { + level notify( "connecting", self ); + } + + callback::callback( #"on_player_connecting" ); +} + + +function delayStartRagdoll( ent, sHitLoc, vDir, weapon, eInflictor, sMeansOfDeath ) +{ + if ( isdefined( ent ) ) + { + deathAnim = ent getcorpseanim(); + if ( animhasnotetrack( deathAnim, "ignore_ragdoll" ) ) + return; + } + + waittillframeend; + + if ( !isdefined( ent ) ) + return; + + if ( ent isRagDoll() ) + return; + + deathAnim = ent getcorpseanim(); + + startFrac = 0.35; + + if ( animhasnotetrack( deathAnim, "start_ragdoll" ) ) + { + times = getnotetracktimes( deathAnim, "start_ragdoll" ); + if ( isdefined( times ) ) + startFrac = times[0]; + } + + waitTime = startFrac * getanimlength( deathAnim ); + + //waitTime -= 0.2; // account for the wait above + if( waitTime > 0 ) + wait( waitTime ); + + if ( isdefined( ent ) ) + { + ent startragdoll(); + } +} + +function trackAttackerDamage( eAttacker, iDamage, sMeansOfDeath, weapon ) +{ + if( !IsDefined( eAttacker ) ) + return; + + if ( !IsPlayer( eAttacker ) ) + return; + + if ( self.attackerData.size == 0 ) + { + self.firstTimeDamaged = getTime(); + } + if ( !isdefined( self.attackerData[eAttacker.clientid] ) ) + { + self.attackerDamage[eAttacker.clientid] = spawnstruct(); + self.attackerDamage[eAttacker.clientid].damage = iDamage; + self.attackerDamage[eAttacker.clientid].meansOfDeath = sMeansOfDeath; + self.attackerDamage[eAttacker.clientid].weapon = weapon; + self.attackerDamage[eAttacker.clientid].time = getTime(); + + self.attackers[ self.attackers.size ] = eAttacker; + + // we keep an array of attackers by their client ID so we can easily tell + // if they're already one of the existing attackers in the above if(). + // we store in this array data that is useful for other things, like challenges + self.attackerData[eAttacker.clientid] = false; + } + else + { + self.attackerDamage[eAttacker.clientid].damage += iDamage; + self.attackerDamage[eAttacker.clientid].meansOfDeath = sMeansOfDeath; + self.attackerDamage[eAttacker.clientid].weapon = weapon; + if ( !isdefined( self.attackerDamage[eAttacker.clientid].time ) ) + self.attackerDamage[eAttacker.clientid].time = getTime(); + } + + if ( IsArray( self.attackersThisSpawn ) ) + { + self.attackersThisSpawn[ eAttacker.clientid ] = eAttacker; + } + + self.attackerDamage[eAttacker.clientid].lasttimedamaged = getTime(); + if ( weapons::is_primary_weapon( weapon ) ) + self.attackerData[eAttacker.clientid] = true; +} + +function giveAttackerAndInflictorOwnerAssist( eAttacker, eInflictor, iDamage, sMeansOfDeath, weapon ) +{ + if ( !allowedAssistWeapon( weapon ) ) + return; + + self trackAttackerDamage( eAttacker, iDamage, sMeansOfDeath, weapon ); + + if ( !isdefined( eInflictor ) ) + return; + + if ( !isdefined( eInflictor.owner ) ) + return; + + if ( !isdefined( eInflictor.ownerGetsAssist ) ) + return; + + if ( !eInflictor.ownerGetsAssist ) + return; + + // if attacker and inflictor owner are the same no additional points + // I dont ever know if they are different + if ( isdefined( eAttacker ) && eAttacker == eInflictor.owner ) + return; + + self trackAttackerDamage( eInflictor.owner, iDamage, sMeansOfDeath, weapon ); +} + +function PlayerKilled_UpdateMeansOfDeath( attacker, eInflictor, weapon, sMeansOfDeath, sHitLoc ) +{ + if( globallogic_utils::isHeadShot( weapon, sHitLoc, sMeansOfDeath, eInflictor ) && isPlayer( attacker ) && !weapon_utils::ismeleemod( sMeansOfDeath ) ) + { + return "MOD_HEAD_SHOT"; + } + + // we do not want the melee icon to show up for dog attacks + switch( weapon.name ) + { + case "dog_bite": + sMeansOfDeath = "MOD_PISTOL_BULLET"; + break; + case "destructible_car": + sMeansOfDeath = "MOD_EXPLOSIVE"; + break; + case "explodable_barrel": + sMeansOfDeath = "MOD_EXPLOSIVE"; + break; + } + + return sMeansOfDeath; +} + +function updateAttacker( attacker, weapon ) +{ + if( isai(attacker) && isdefined( attacker.script_owner ) ) + { + // if the person who called the dogs in switched teams make sure they don't + // get penalized for the kill + if ( !level.teambased || attacker.script_owner.team != self.team ) + attacker = attacker.script_owner; + } + + if( attacker.classname == "script_vehicle" && isdefined( attacker.owner ) ) + { + attacker notify("killed",self); + + attacker = attacker.owner; + } + + if( isai(attacker) ) + attacker notify("killed",self); + + if ( ( isdefined ( self.capturingLastFlag ) ) && ( self.capturingLastFlag == true ) ) + { + attacker.lastCapKiller = true; + } + + if( isdefined( attacker ) && attacker != self && isdefined( weapon ) ) + { + if ( weapon.name == "planemortar" ) + { + if(!isdefined(attacker.planeMortarBda))attacker.planeMortarBda=0; + attacker.planeMortarBda++; + } + else if( weapon.name == "dart" || + weapon.name == "dart_turret" ) + { + if(!isdefined(attacker.dartBda))attacker.dartBda=0; + attacker.dartBda++; + } + else if( weapon.name == "straferun_rockets" || weapon.name == "straferun_gun") + { + if( isdefined( attacker.strafeRunbda ) ) + { + attacker.strafeRunbda++; + } + } + else if ( weapon.name == "remote_missile_missile" || weapon.name == "remote_missile_bomblet" ) + { + if(!isdefined(attacker.remotemissileBda))attacker.remotemissileBda=0; + attacker.remotemissileBda++; + } + } + + return attacker; +} + +function updateInflictor( eInflictor ) +{ + if( isdefined( eInflictor ) && eInflictor.classname == "script_vehicle" ) + { + eInflictor notify("killed",self); + + if ( isdefined( eInflictor.bda ) ) + { + eInflictor.bda++; + } + } + + return eInflictor; +} + +function updateWeapon( eInflictor, weapon ) +{ + // explosive barrel/car detection + if ( weapon == level.weaponNone && isdefined( eInflictor ) ) + { + if ( isdefined( eInflictor.targetname ) && eInflictor.targetname == "explodable_barrel" ) + weapon = GetWeapon( "explodable_barrel" ); + else if ( isdefined( eInflictor.destructible_type ) && isSubStr( eInflictor.destructible_type, "vehicle_" ) ) + weapon = GetWeapon( "destructible_car" ); + } + + return weapon; +} + +function playKillBattleChatter( attacker, weapon, victim, eInflictor ) +{ + if( IsPlayer( attacker ) ) + { + if ( !killstreaks::is_killstreak_weapon( weapon ) ) + { + level thread battlechatter::say_kill_battle_chatter( attacker, weapon, victim, eInflictor ); + } + } + + if( isdefined( eInflictor ) ) + { + eInflictor notify( "bhtn_action_notify", "attack_kill" ); + } +} diff --git a/data/scripts/mp/gametypes/_serversettings.gsc b/data/scripts/mp/gametypes/_serversettings.gsc new file mode 100644 index 0000000..bf3985a Binary files /dev/null and b/data/scripts/mp/gametypes/_serversettings.gsc differ diff --git a/data/scripts/mp/gametypes/_serversettings.gsc_raw b/data/scripts/mp/gametypes/_serversettings.gsc_raw new file mode 100644 index 0000000..e420ca3 --- /dev/null +++ b/data/scripts/mp/gametypes/_serversettings.gsc_raw @@ -0,0 +1,209 @@ +#using scripts\codescripts\struct; + +#using scripts\shared\callbacks_shared; +#using scripts\shared\system_shared; + +#namespace serversettings; + +function autoexec __init__sytem__() { system::register("serversettings",&__init__,undefined,undefined); } + +function __init__() +{ + callback::on_start_gametype( &init ); +} + +function init() +{ + level.hostname = GetDvarString( "sv_hostname"); + if(level.hostname == "") + level.hostname = "CoDHost"; + SetDvar("sv_hostname", level.hostname); + SetDvar("ui_hostname", level.hostname); + //makeDvarServerInfo("ui_hostname", "CoDHost"); + + level.motd = GetDvarString( "scr_motd" ); + if(level.motd == "") + level.motd = ""; + SetDvar("scr_motd", level.motd); + SetDvar("ui_motd", level.motd); + //makeDvarServerInfo("ui_motd", ""); + + level.allowvote = GetDvarString( "g_allowvote" ); + if(level.allowvote == "") + level.allowvote = "1"; + SetDvar("g_allowvote", level.allowvote); + SetDvar("ui_allowvote", level.allowvote); + //makeDvarServerInfo("ui_allowvote", "1"); + + level.allow_teamchange = "1"; + SetDvar("ui_allow_teamchange", level.allow_teamchange); + + level.friendlyfire = GetGametypeSetting( "friendlyfiretype" ); + + SetDvar("ui_friendlyfire", level.friendlyfire); + //makeDvarServerInfo("ui_friendlyfire", "0"); + + if(GetDvarString( "scr_mapsize") == "") + SetDvar("scr_mapsize", "64"); + else if(GetDvarfloat( "scr_mapsize") >= 64) + SetDvar("scr_mapsize", "64"); + else if(GetDvarfloat( "scr_mapsize") >= 32) + SetDvar("scr_mapsize", "32"); + else if(GetDvarfloat( "scr_mapsize") >= 16) + SetDvar("scr_mapsize", "16"); + else + SetDvar("scr_mapsize", "8"); + level.mapsize = GetDvarfloat( "scr_mapsize"); + + constrain_gametype(GetDvarString( "g_gametype")); + constrain_map_size(level.mapsize); + + thread setup_callbacks(); + + for(;;) + { + update(); + wait 5; + } +} + +function update() +{ + sv_hostname = GetDvarString( "sv_hostname"); + if(level.hostname != sv_hostname) + { + level.hostname = sv_hostname; + SetDvar("ui_hostname", level.hostname); + } + + scr_motd = GetDvarString( "scr_motd"); + if(level.motd != scr_motd) + { + level.motd = scr_motd; + SetDvar("ui_motd", level.motd); + } + + g_allowvote = GetDvarString( "g_allowvote" ); + if(level.allowvote != g_allowvote) + { + level.allowvote = g_allowvote; + SetDvar("ui_allowvote", level.allowvote); + } + + scr_friendlyfire = GetGametypeSetting( "friendlyfiretype" ); + if(level.friendlyfire != scr_friendlyfire) + { + level.friendlyfire = scr_friendlyfire; + SetDvar("ui_friendlyfire", level.friendlyfire); + } +} + +function constrain_gametype(gametype) +{ + entities = getentarray(); + for(i = 0; i < entities.size; i++) + { + entity = entities[i]; + + if(gametype == "dm") + { + if(isdefined(entity.script_gametype_dm) && entity.script_gametype_dm != "1") + { + //iprintln("DELETED(GameType): ", entity.classname); + entity delete(); + } + } + else if(gametype == "tdm") + { + if(isdefined(entity.script_gametype_tdm) && entity.script_gametype_tdm != "1") + { + //iprintln("DELETED(GameType): ", entity.classname); + entity delete(); + } + } + else if(gametype == "ctf") + { + if(isdefined(entity.script_gametype_ctf) && entity.script_gametype_ctf != "1") + { + //iprintln("DELETED(GameType): ", entity.classname); + entity delete(); + } + } + else if(gametype == "hq") + { + if(isdefined(entity.script_gametype_hq) && entity.script_gametype_hq != "1") + { + //iprintln("DELETED(GameType): ", entity.classname); + entity delete(); + } + } + else if(gametype == "sd") + { + if(isdefined(entity.script_gametype_sd) && entity.script_gametype_sd != "1") + { + //iprintln("DELETED(GameType): ", entity.classname); + entity delete(); + } + } + else if(gametype == "koth") + { + if(isdefined(entity.script_gametype_koth) && entity.script_gametype_koth != "1") + { + //iprintln("DELETED(GameType): ", entity.classname); + entity delete(); + } + } + } +} + +function constrain_map_size(mapsize) +{ + entities = getentarray(); + for(i = 0; i < entities.size; i++) + { + entity = entities[i]; + + if(int(mapsize) == 8) + { + if(isdefined(entity.script_mapsize_08) && entity.script_mapsize_08 != "1") + { + //iprintln("DELETED(MapSize): ", entity.classname); + entity delete(); + } + } + else if(int(mapsize) == 16) + { + if(isdefined(entity.script_mapsize_16) && entity.script_mapsize_16 != "1") + { + //iprintln("DELETED(MapSize): ", entity.classname); + entity delete(); + } + } + else if(int(mapsize) == 32) + { + if(isdefined(entity.script_mapsize_32) && entity.script_mapsize_32 != "1") + { + //iprintln("DELETED(MapSize): ", entity.classname); + entity delete(); + } + } + else if(int(mapsize) == 64) + { + if(isdefined(entity.script_mapsize_64) && entity.script_mapsize_64 != "1") + { + //iprintln("DELETED(MapSize): ", entity.classname); + entity delete(); + } + } + } +} + +function setup_callbacks() +{ + level.onForfeit = &default_onForfeit; +} + +function default_onForfeit() +{ + level.gameForfeited = false; +} \ No newline at end of file diff --git a/data/scripts/mp/teams/_teams.gsc b/data/scripts/mp/teams/_teams.gsc new file mode 100644 index 0000000..bb53019 Binary files /dev/null and b/data/scripts/mp/teams/_teams.gsc differ diff --git a/data/scripts/mp/teams/_teams.gsc_raw b/data/scripts/mp/teams/_teams.gsc_raw new file mode 100644 index 0000000..1260a17 --- /dev/null +++ b/data/scripts/mp/teams/_teams.gsc_raw @@ -0,0 +1,670 @@ +#using scripts\codescripts\struct; + +#using scripts\shared\callbacks_shared; +#using scripts\shared\persistence_shared; +#using scripts\shared\system_shared; +#using scripts\shared\util_shared; + +#insert scripts\shared\shared.gsh; + +#using scripts\mp\gametypes\_globallogic_ui; +#using scripts\mp\gametypes\_spectating; + +#using scripts\mp\_util; + +#precache( "material", "mpflag_spectator" ); +#precache( "string", "MP_AUTOBALANCE_NOW" ); + +#namespace teams; + +REGISTER_SYSTEM( "teams", &__init__, undefined ) + +function __init__() +{ + callback::on_start_gametype( &init ); + + level.getEnemyTeam = &getEnemyTeam; + level.use_team_based_logic_for_locking_on = true; +} + +function init() +{ + game["strings"]["autobalance"] = &"MP_AUTOBALANCE_NOW"; + + if(GetDvarString( "scr_teambalance") == "") + SetDvar("scr_teambalance", "0"); + level.teambalance = GetDvarint( "scr_teambalance"); + level.teambalancetimer = 0; + + if(GetDvarString( "scr_timeplayedcap") == "") + SetDvar("scr_timeplayedcap", "1800"); + level.timeplayedcap = int(GetDvarint( "scr_timeplayedcap")); + + level.freeplayers = []; + + if( level.teamBased ) + { + level.alliesplayers = []; + level.axisplayers = []; + + callback::on_connect( &on_player_connect ); + callback::on_joined_team( &on_joined_team ); + callback::on_joined_spectate( &on_joined_spectators ); + level thread update_team_balance(); + + wait .15; + + level thread update_player_times(); + + } + else + { + callback::on_connect( &on_free_player_connect ); + + wait .15; + + level thread update_player_times(); + + } +} + +function on_player_connect() +{ + self thread track_played_time(); +} + +function on_free_player_connect() +{ + self thread track_free_played_time(); +} + +function on_joined_team() +{ + /#println( "joined team: " + self.pers["team"] );#/ + self update_time(); +} + +function on_joined_spectators() +{ + self.pers["teamTime"] = undefined; +} + +function track_played_time() +{ + self endon( "disconnect" ); + + if ( !isdefined( self.pers["totalTimePlayed"] ) ) + { + self.pers["totalTimePlayed"] = 0; + } + + foreach ( team in level.teams ) + { + self.timePlayed[team] = 0; + } + self.timePlayed["free"] = 0; + self.timePlayed["other"] = 0; + self.timePlayed["alive"] = 0; + + // dont reset time played in War when going into final fight, this is used for calculating match bonus + if ( !isdefined( self.timePlayed["total"] ) || !( (level.gameType == "twar") && (0 < game["roundsplayed"]) && (0 < self.timeplayed["total"]) ) ) + self.timePlayed["total"] = 0; + + while ( level.inPrematchPeriod ) + WAIT_SERVER_FRAME; + + for ( ;; ) + { + if ( game["state"] == "playing" ) + { + if ( isdefined( level.teams[self.sessionteam] ) ) + { + self.timePlayed[self.sessionteam]++; + self.timePlayed["total"]++; + + if ( level.mpCustomMatch ) + { + self.pers["sbtimeplayed"] = self.timeplayed["total"]; + self.sbtimeplayed = self.pers["sbtimeplayed"]; + } + + if ( IsAlive( self ) ) + self.timePlayed["alive"]++; + } + else if ( self.sessionteam == "spectator" ) + { + self.timePlayed["other"]++; + } + } + + wait ( 1.0 ); + } +} + + +function update_player_times() +{ + const minWait = 10.0; + const step = 1.0; + varWait = minWait; + + nextToUpdate = 0; + for ( ;; ) + { + varWait = varWait - step; + nextToUpdate++; + + if ( nextToUpdate >= level.players.size ) + { + nextToUpdate = 0; + + if ( varWait > 0 ) + { + wait ( varWait ); + } + + varWait = minWait; + } + + if ( isdefined( level.players[nextToUpdate] ) ) + { + level.players[nextToUpdate] update_played_time(); + level.players[nextToUpdate] persistence::check_contract_expirations(); + } + + wait ( step ); + } +} + +function update_played_time() +{ + pixbeginevent("updatePlayedTime"); + + if ( level.rankedMatch || level.leagueMatch ) + { + foreach( team in level.teams ) + { + if ( self.timePlayed[team] ) + { + if ( level.teambased ) + { + self AddPlayerStat( "time_played_"+team, int( min( self.timePlayed[team], level.timeplayedcap ) ) ); + } + + self AddPlayerStatWithGameType( "time_played_total", int( min( self.timePlayed[team], level.timeplayedcap ) ) ); + } + } + + if ( self.timePlayed["other"] ) + { + self AddPlayerStat( "time_played_other", int( min( self.timePlayed["other"], level.timeplayedcap ) ) ); + self AddPlayerStatWithGameType( "time_played_total", int( min( self.timePlayed["other"], level.timeplayedcap ) ) ); + } + + if ( self.timePlayed["alive"] ) + { + timeAlive = int( min( self.timePlayed["alive"], level.timeplayedcap ) ); + self persistence::increment_contract_times( timeAlive ); + self AddPlayerStat( "time_played_alive", timeAlive ); + } + } + + if ( level.onlineGame ) + { + timeAlive = int( min( self.timePlayed["alive"], level.timeplayedcap ) ); + self.pers["time_played_alive"] += timeAlive; + } + + pixendevent(); + + if ( game["state"] == "postgame" ) + return; + + foreach( team in level.teams ) + { + self.timePlayed[team] = 0; + } + self.timePlayed["other"] = 0; + self.timePlayed["alive"] = 0; +} + + +function update_time() +{ + if ( game["state"] != "playing" ) + return; + + self.pers["teamTime"] = getTime(); +} + +function update_balance_dvar() +{ + for(;;) + { + teambalance = GetDvarint( "scr_teambalance"); + if(level.teambalance != teambalance) + level.teambalance = GetDvarint( "scr_teambalance"); + + timeplayedcap = GetDvarint( "scr_timeplayedcap"); + if(level.timeplayedcap != timeplayedcap) + level.timeplayedcap = int(GetDvarint( "scr_timeplayedcap")); + + wait 1; + } +} + + +function update_team_balance() +{ + level thread update_balance_dvar(); + + wait .15; + + if ( level.teamBalance && util::isRoundBased() && level.numlives ) + { + if ( isDefined( game["BalanceTeamsNextRound"] ) ) + iPrintLnbold( &"MP_AUTOBALANCE_NEXT_ROUND" ); + + level waittill( "game_ended" ); + wait 1; + + if ( isDefined( game["BalanceTeamsNextRound"] ) ) + { + level balance_teams(); + game["BalanceTeamsNextRound"] = undefined; + } + else if ( !get_team_balance() ) + { + game["BalanceTeamsNextRound"] = true; + } + } + else + { + level endon ( "game_ended" ); + + for ( ;; ) + { + if ( level.teamBalance ) + { + if ( !get_team_balance() ) + { + iPrintLnBold( &"MP_AUTOBALANCE_SECONDS", 15 ); + wait 15.0; + + if ( !get_team_balance() ) + level balance_teams(); + } + + wait 59.0; + } + + wait 1.0; + } + } + +} + + +function get_team_balance() +{ + level.team["allies"] = 0; + level.team["axis"] = 0; + + players = level.players; + + for ( i = 0; i < players.size; i++ ) + { + if ( ( isdefined( players[i].pers["team"] ) ) && ( players[i].pers["team"] == "allies" ) ) + level.team["allies"]++; + else if ( ( isdefined( players[i].pers["team"] ) ) && ( players[i].pers["team"] == "axis" ) ) + level.team["axis"]++; + } + + if ( ( level.team["allies"] > ( level.team["axis"] + level.teamBalance ) ) || ( level.team["axis"] > ( level.team["allies"] + level.teamBalance ) ) ) + return false; + else + return true; +} + + +function balance_teams() +{ + iPrintLnBold( game["strings"]["autobalance"] ); + //Create/Clear the team arrays + AlliedPlayers = []; + AxisPlayers = []; + + // Populate the team arrays + players = level.players; + + for ( i = 0; i < players.size; i++ ) + { + if ( !isdefined( players[i].pers["teamTime"] ) ) + continue; + + if ( ( isdefined( players[i].pers["team"] ) ) && ( players[i].pers["team"] == "allies" ) ) + AlliedPlayers[AlliedPlayers.size] = players[i]; + else if ( ( isdefined( players[i].pers["team"] ) ) && ( players[i].pers["team"] == "axis" ) ) + AxisPlayers[AxisPlayers.size] = players[i]; + } + + MostRecent = undefined; + + while ( ( AlliedPlayers.size > ( AxisPlayers.size + 1 ) ) || ( AxisPlayers.size > ( AlliedPlayers.size + 1 ) ) ) + { + if ( AlliedPlayers.size > ( AxisPlayers.size + 1 ) ) + { + // Move the player that's been on the team the shortest ammount of time (highest teamTime value) + // Ignore players capturing or carrying objects + for ( j = 0; j < AlliedPlayers.size; j++ ) + { + + if ( !isdefined( MostRecent ) ) + MostRecent = AlliedPlayers[j]; + else if ( AlliedPlayers[j].pers["teamTime"] > MostRecent.pers["teamTime"] ) + MostRecent = AlliedPlayers[j]; + } + + if ( isdefined( MostRecent ) ) + MostRecent change( "axis" ); + else + { + // Move the player that's been on the team the shortest ammount of time + for ( j = 0; j < AlliedPlayers.size; j++ ) + { + if ( !isdefined( MostRecent ) ) + MostRecent = AlliedPlayers[j]; + else if ( AlliedPlayers[j].pers["teamTime"] > MostRecent.pers["teamTime"] ) + MostRecent = AlliedPlayers[j]; + } + + MostRecent change( "axis" ); + } + } + else if ( AxisPlayers.size > ( AlliedPlayers.size + 1 ) ) + { + // Move the player that's been on the team the shortest ammount of time (highest teamTime value) + // Ignore players capturing or carrying objects + for ( j = 0; j < AxisPlayers.size; j++ ) + { + + if ( !isdefined( MostRecent ) ) + MostRecent = AxisPlayers[j]; + else if ( AxisPlayers[j].pers["teamTime"] > MostRecent.pers["teamTime"] ) + MostRecent = AxisPlayers[j]; + } + + if ( isdefined( MostRecent ) ) + MostRecent change( "allies" ); + else + { + // Move the player that's been on the team the shortest ammount of time + for ( j = 0; j < AxisPlayers.size; j++ ) + { + if ( !isdefined( MostRecent ) ) + MostRecent = AxisPlayers[j]; + else if ( AxisPlayers[j].pers["teamTime"] > MostRecent.pers["teamTime"] ) + MostRecent = AxisPlayers[j]; + } + + MostRecent change( "allies" ); + } + } + + MostRecent = undefined; + AlliedPlayers = []; + AxisPlayers = []; + + players = level.players; + + for ( i = 0; i < players.size; i++ ) + { + if ( ( isdefined( players[i].pers["team"] ) ) && ( players[i].pers["team"] == "allies" ) ) + AlliedPlayers[AlliedPlayers.size] = players[i]; + else if ( ( isdefined( players[i].pers["team"] ) ) && ( players[i].pers["team"] == "axis" ) ) + AxisPlayers[AxisPlayers.size] = players[i]; + } + } +} + + +function change( team ) +{ + if (self.sessionstate != "dead") + { + // Set a flag on the player to they aren't robbed points for dying - the callback will remove the flag + self.switching_teams = true; + self.switchedTeamsResetGadgets = true; + self.joining_team = team; + self.leaving_team = self.pers["team"]; + + // Suicide the player so they can't hit escape and fail the team balance + self suicide(); + } + + self.pers["team"] = team; + self.team = team; + self.pers["weapon"] = undefined; + self.pers["spawnweapon"] = undefined; + self.pers["savedmodel"] = undefined; + self.pers["teamTime"] = undefined; + self.sessionteam = self.pers["team"]; + + self globallogic_ui::updateObjectiveText(); + + // update spectator permissions immediately on change of team + self spectating::set_permissions(); + + self SetClientScriptMainMenu( game[ "menu_start_menu" ] ); + self openMenu(game[ "menu_start_menu" ]); + + self notify("end_respawn"); +} + +function count_players() +{ + players = level.players; + + playerCounts = []; + foreach( team in level.teams ) + { + playerCounts[team] = 0; + } + + foreach( player in level.players ) + { + if( player == self ) + continue; + + team = player.pers["team"]; + if( isdefined(team) && isdefined( level.teams[team] ) ) + playerCounts[team]++; + } + return playerCounts; +} + + +function track_free_played_time() +{ + self endon( "disconnect" ); + + foreach( team in level.teams ) + { + self.timePlayed[team] = 0; + } + + self.timePlayed["other"] = 0; + self.timePlayed["total"] = 0; + self.timePlayed["alive"] = 0; + + for ( ;; ) + { + if ( game["state"] == "playing" ) + { + team = self.pers["team"]; + if ( isdefined( team ) && isdefined( level.teams[team] ) && self.sessionteam != "spectator" ) + { + self.timePlayed[team]++; + self.timePlayed["total"]++; + if ( IsAlive( self ) ) + self.timePlayed["alive"]++; + } + else + { + self.timePlayed["other"]++; + } + } + + wait ( 1.0 ); + } +} + +function set_player_model( team, weapon ) +{ + self DetachAll(); + self SetMoveSpeedScale( 1 ); + self SetSprintDuration( 4 ); + self SetSprintCooldown( 0 ); +} + +function get_flag_model( teamRef ) +{ + assert(isdefined(game["flagmodels"])); + assert(isdefined(game["flagmodels"][teamRef])); + return ( game["flagmodels"][teamRef] ); +} + +function get_flag_carry_model( teamRef ) +{ + assert(isdefined(game["carry_flagmodels"])); + assert(isdefined(game["carry_flagmodels"][teamRef])); + return ( game["carry_flagmodels"][teamRef] ); +} + +function getTeamIndex( team ) +{ + if( !isdefined( team ) ) + { + return TEAM_FREE; + } + + if( team == "free" ) + { + return TEAM_FREE; + } + + if( team == "allies" ) + { + return TEAM_ALLIES; + } + + if( team == "axis" ) + { + return TEAM_AXIS; + } + + return TEAM_FREE; +} + +function getEnemyTeam( player_team ) +{ + foreach( team in level.teams ) + { + if ( team == player_team ) + continue; + + if ( team == "spectator" ) + continue; + + return team; + } + + return util::getOtherTeam( player_team ); +} + +function GetEnemyPlayers() +{ + enemies = []; + + foreach( player in level.players ) + { + if( player.team == "spectator" ) + { + continue; + } + + if( ( level.teamBased && player.team != self.team ) || ( !level.teamBased && player != self ) ) + { + ARRAY_ADD( enemies, player ); + } + } + + return enemies; +} + +function GetFriendlyPlayers() +{ + friendlies = []; + + foreach( player in level.players ) + { + if( ( player.team == self.team ) && ( player != self ) ) + { + ARRAY_ADD( friendlies, player ); + } + } + + return friendlies; +} + +function WaitUntilTeamChange( player, callback, arg, end_condition1, end_condition2, end_condition3 ) +{ + if( isdefined( end_condition1 ) ) + self endon( end_condition1 ); + if( isdefined( end_condition2 ) ) + self endon( end_condition2 ); + if( isdefined( end_condition3 ) ) + self endon( end_condition3 ); + + event = player util::waittill_any( "joined_team", "disconnect", "joined_spectators" ); + + if( isdefined( callback ) ) + { + self [[ callback ]]( arg, event ); + } +} + + +function WaitUntilTeamChangeSingleTon( player, singletonString, callback, arg, end_condition1, end_condition2, end_condition3 ) +{ + self notify( singletonString ); + self endon( singletonString ); + if( isdefined( end_condition1 ) ) + self endon( end_condition1 ); + if( isdefined( end_condition2 ) ) + self endon( end_condition2 ); + if( isdefined( end_condition3 ) ) + self endon( end_condition3 ); + + event = player util::waittill_any( "joined_team", "disconnect", "joined_spectators" ); + + if( isdefined( callback ) ) + { + self thread [[ callback ]]( arg, event ); + } +} + + +function HideToSameTeam() +{ + if( level.teambased ) + { + self SetVisibleToAllExceptTeam( self.team ); + } + else + { + self SetVisibleToAll(); + self SetInvisibleToPlayer( self.owner ); + } +} + diff --git a/data/ui_scripts/doubleclick_join_server/__init__.lua b/data/ui_scripts/doubleclick_join_server/__init__.lua new file mode 100644 index 0000000..71c4808 --- /dev/null +++ b/data/ui_scripts/doubleclick_join_server/__init__.lua @@ -0,0 +1,118 @@ +if Engine.GetCurrentMap() ~= "core_frontend" then + return +end + +require( "ui.uieditor.widgets.PC.ServerBrowser.ServerBrowserRowInternal" ) +require( "ui.uieditor.widgets.Lobby.Common.FE_FocusBarContainer" ) + +CoD.ServerBrowserRow = InheritFrom( LUI.UIElement ) +CoD.ServerBrowserRow.new = function ( menu, controller ) + local self = LUI.UIElement.new() + if PreLoadFunc then + PreLoadFunc( self, controller ) + end + self:setUseStencil( false ) + self:setClass( CoD.ServerBrowserRow ) + self.id = "ServerBrowserRow" + self.soundSet = "default" + self:setLeftRight( true, false, 0, 700 ) + self:setTopBottom( true, false, 0, 22 ) + self:makeFocusable() + self:setHandleMouse( true ) + + if CoD.isPC then + self:registerEventHandler( "leftmousedown", function () + if self:isInFocus() then + ServerBrowserCancelRequest( self ) + JoinServerBrowser( self, self, controller, menu ) + end + end ) + end + self.anyChildUsesUpdateState = true + + local background = LUI.UIImage.new() + background:setLeftRight( true, true, 0, 0 ) + background:setTopBottom( true, true, 0, 0 ) + background:setRGB( 0.2, 0.2, 0.2 ) + background:setAlpha( 0.8 ) + self:addElement( background ) + self.background = background + + local rowItems = CoD.ServerBrowserRowInternal.new( menu, controller ) + rowItems:setLeftRight( true, false, 0, 700 ) + rowItems:setTopBottom( true, false, 0, 22 ) + rowItems:linkToElementModel( self, nil, false, function ( model ) + rowItems:setModel( model, controller ) + end ) + self:addElement( rowItems ) + self.rowItems = rowItems + + local FocusBarB = CoD.FE_FocusBarContainer.new( menu, controller ) + FocusBarB:setLeftRight( true, true, -2, 2 ) + FocusBarB:setTopBottom( false, true, -1, 3 ) + FocusBarB:setAlpha( 0 ) + FocusBarB:setZoom( 1 ) + self:addElement( FocusBarB ) + self.FocusBarB = FocusBarB + + local FocusBarT = CoD.FE_FocusBarContainer.new( menu, controller ) + FocusBarT:setLeftRight( true, true, -2, 2 ) + FocusBarT:setTopBottom( true, false, -2, 2 ) + FocusBarT:setAlpha( 0 ) + FocusBarT:setZoom( 1 ) + self:addElement( FocusBarT ) + self.FocusBarT = FocusBarT + + self.clipsPerState = { + DefaultState = { + DefaultClip = function () + self:setupElementClipCounter( 3 ) + background:completeAnimation() + self.background:setRGB( 0.2, 0.2, 0.2 ) + self.clipFinished( background, {} ) + FocusBarB:completeAnimation() + self.FocusBarB:setAlpha( 0 ) + self.clipFinished( FocusBarB, {} ) + FocusBarT:completeAnimation() + self.FocusBarT:setAlpha( 0 ) + self.clipFinished( FocusBarT, {} ) + end, + Focus = function () + self:setupElementClipCounter( 3 ) + background:completeAnimation() + self.background:setRGB( 0.2, 0.2, 0.2 ) + self.clipFinished( background, {} ) + FocusBarB:completeAnimation() + self.FocusBarB:setAlpha( 1 ) + self.clipFinished( FocusBarB, {} ) + FocusBarT:completeAnimation() + self.FocusBarT:setAlpha( 1 ) + self.clipFinished( FocusBarT, {} ) + end, + Over = function () + self:setupElementClipCounter( 3 ) + background:completeAnimation() + self.background:setRGB( 0.39, 0.39, 0.39 ) + self.clipFinished( background, {} ) + FocusBarB:completeAnimation() + self.FocusBarB:setAlpha( 0 ) + self.clipFinished( FocusBarB, {} ) + FocusBarT:completeAnimation() + self.FocusBarT:setAlpha( 0 ) + self.clipFinished( FocusBarT, {} ) + end + } + } + LUI.OverrideFunction_CallOriginalSecond( self, "close", function ( element ) + element.rowItems:close() + element.FocusBarB:close() + element.FocusBarT:close() + element.m_leftMouseDown = nil + end ) + + if PostLoadFunc then + PostLoadFunc( self, controller, menu ) + end + + return self +end \ No newline at end of file diff --git a/data/ui_scripts/frontend_menus/__init__.lua b/data/ui_scripts/frontend_menus/__init__.lua new file mode 100644 index 0000000..e9e83a6 --- /dev/null +++ b/data/ui_scripts/frontend_menus/__init__.lua @@ -0,0 +1,156 @@ +if Engine.GetCurrentMap() ~= "core_frontend" then + return +end + +local enableLobbyMapVote = true -- toggle map vote in public lobby +local enableLargeServerBrowserButton = true -- toggle large server browser button + +local utils = require("utils") +require("datasources_start_menu_tabs") +require("datasources_change_map_categories") +require("datasources_gamesettingsflyout_buttons") + +CoD.LobbyButtons.MP_PUBLIC_MATCH = { + stringRef = "MENU_PLAY_CAPS", + action = NavigateToLobby_SelectionList, + param = "MPLobbyOnline", + customId = "btnPublicMatch", +} + +CoD.LobbyButtons.MP_FIND_MATCH = { + stringRef = "MPUI_BASICTRAINING_CAPS", + action = OpenFindMatch, + customId = "btnFindMatch", +} + +CoD.LobbyButtons.STATS = { + stringRef = "STATS", + action = function(self, element, controller, param, menu) + SetPerControllerTableProperty(controller, "disableGameSettingsOptions", true) + OpenPopup(menu, "T7xStatsMenu", controller) + end, + customId = "btnMPStats" +} + +CoD.LobbyButtons.MP_START_GAME = { + stringRef = "MENU_START_GAME_CAPS", + action = function(self, element, controller, param, menu) + Engine.SetDvar("party_minplayers", 1) + Engine.Exec(nil, "launchgame") + end, + customId = "btnStartGame" +} + +CoD.LobbyButtons.SETTING_UP_BOTS = { + stringRef = "MENU_SETUP_BOTS_CAPS", + action = function(self, element, controller, param, menu) + SetPerControllerTableProperty(controller, "disableGameSettingsOptions", true) + OpenPopup(menu, "GameSettings_Bots", controller) + end, + customId = "btnSettingUpBots" +} + +CoD.LobbyButtons.GameSettingsFlyoutArenas = { + stringRef = "MPUI_SETUP_GAME_CAPS", + action = function(self, element, controller, param, menu) + SetPerControllerTableProperty(controller, "disableGameSettingsOptions", true) + OpenPopup(menu, "GameSettingsFlyoutMP", controller) + end, + customId = "btnGameSettingsFlyoutMP" +} + +CoD.LobbyButtons.GameSettingsFlyoutMP = { + stringRef = "MPUI_SETUP_GAME_CAPS", + action = function(self, element, controller, param, menu) + SetPerControllerTableProperty(controller, "disableGameSettingsOptions", true) + OpenPopup(menu, "GameSettingsFlyoutMPCustom", controller) + end, + customId = "btnGameSettingsFlyoutMPCustom" +} + +CoD.LobbyButtons.SERVER_BROWSER = { + stringRef = "MENU_SERVER_BROWSER_CAPS", + action = function(self, element, controller, param, menu) + SetPerControllerTableProperty(controller, "disableGameSettingsOptions", true) + OpenPopup(menu, "LobbyServerBrowserOnline", controller) + end, + customId = "btnDedicated" +} + +local shouldShowMapVote = enableLobbyMapVote +local lobbyMapVote = function(lobbyMapVoteIsEnabled) + if lobbyMapVoteIsEnabled == true then + Engine.Exec(nil, "LobbyStopDemo") + end +end + +local addCustomButtons = function(controller, menuId, buttonTable, isLeader) + if menuId == LobbyData.UITargets.UI_MPLOBBYMAIN.id then + utils.RemoveSpaces(buttonTable) + local theaterIndex = utils.GetButtonIndex(buttonTable, CoD.LobbyButtons.THEATER_MP) + if theaterIndex ~= nil then + utils.AddSpacer(buttonTable, theaterIndex - 1) + end + end + + if menuId == LobbyData.UITargets.UI_MPLOBBYONLINE.id or menuId == LobbyData.UITargets.UI_ZMLOBBYONLINE.id then + utils.AddSmallButton(controller, buttonTable, CoD.LobbyButtons.STATS) + end + + if menuId == LobbyData.UITargets.UI_MPLOBBYONLINE.id or menuId == LobbyData.UITargets.UI_ZMLOBBYONLINE.id or menuId == LobbyData.UITargets.UI_MPLOBBYMAIN.id or menuId == LobbyData.UITargets.UI_MPLOBBYLANGAME.id then + Engine.Mods_Lists_UpdateUsermaps() + end + + if menuId == LobbyData.UITargets.UI_MPLOBBYONLINE.id then + shouldShowMapVote = enableLobbyMapVote + if enableLargeServerBrowserButton then + utils.AddLargeButton(controller, buttonTable, CoD.LobbyButtons.SERVER_BROWSER, 1) + end + elseif menuId == LobbyData.UITargets.UI_MPLOBBYONLINEPUBLICGAME.id then + utils.RemoveButton(buttonTable, CoD.LobbyButtons.MP_PUBLIC_LOBBY_LEADERBOARD) + + utils.AddLargeButton(controller, buttonTable, CoD.LobbyButtons.MP_START_GAME, 1) + utils.AddSmallButton(controller, buttonTable, CoD.LobbyButtons.GameSettingsFlyoutMP, 2) + utils.AddSpacer(buttonTable, utils.GetButtonIndex(buttonTable, CoD.LobbyButtons.GameSettingsFlyoutMP)) + + lobbyMapVote(shouldShowMapVote) + shouldShowMapVote = false + elseif menuId == LobbyData.UITargets.UI_MPLOBBYONLINEARENAGAME.id then + utils.AddLargeButton(controller, buttonTable, CoD.LobbyButtons.MP_START_GAME, 1) + utils.AddSmallButton(controller, buttonTable, CoD.LobbyButtons.GameSettingsFlyoutArenas, 2) + + utils.AddSpacer(buttonTable, utils.GetButtonIndex(buttonTable, CoD.LobbyButtons.GameSettingsFlyoutArenas)) + end + + if menuId == LobbyData.UITargets.UI_ZMLOBBYONLINE.id then + utils.RemoveButton(buttonTable, CoD.LobbyButtons.THEATER_ZM) + utils.AddLargeButton(controller, buttonTable, CoD.LobbyButtons.THEATER_ZM) + + utils.RemoveSpaces(buttonTable) + utils.AddSpacer(buttonTable, utils.GetButtonIndex(buttonTable, CoD.LobbyButtons.SERVER_BROWSER)) + local bgbIndex = utils.GetButtonIndex(buttonTable, CoD.LobbyButtons.ZM_BUBBLEGUM_BUFFS) + if bgbIndex ~= nil then + utils.AddSpacer(buttonTable, bgbIndex - 1) + end + utils.AddSpacer(buttonTable, utils.GetButtonIndex(buttonTable, CoD.LobbyButtons.STATS)) + end +end + +local oldAddButtonsForTarget = CoD.LobbyMenus.AddButtonsForTarget +CoD.LobbyMenus.AddButtonsForTarget = function(controller, id) + local model = nil + if Engine.IsLobbyActive(Enum.LobbyType.LOBBY_TYPE_GAME) then + model = Engine.GetModel(DataSources.LobbyRoot.getModel(controller), "gameClient.isHost") + else + model = Engine.GetModel(DataSources.LobbyRoot.getModel(controller), "privateClient.isHost") + end + local isLeader = nil + if model ~= nil then + isLeader = Engine.GetModelValue(model) + else + isLeader = 1 + end + local result = oldAddButtonsForTarget(controller, id) + addCustomButtons(controller, id, result, isLeader) + return result +end diff --git a/data/ui_scripts/frontend_menus/datasources_change_map_categories.lua b/data/ui_scripts/frontend_menus/datasources_change_map_categories.lua new file mode 100644 index 0000000..468c6bf --- /dev/null +++ b/data/ui_scripts/frontend_menus/datasources_change_map_categories.lua @@ -0,0 +1,96 @@ +local f0_local0 = function(f1_arg0, f1_arg1) + if not CoD.useMouse then + return + else + LUI.OverrideFunction_CallOriginalFirst(f1_arg0, "setState", function(element, controller) + if IsSelfInState(f1_arg0, "SelectingMap") then + f1_arg0.mapList:setMouseDisabled(false) + f1_arg0.mapCategoriesList:setMouseDisabled(true) + f1_arg0.m_categorySet = false + else + f1_arg0.mapList:setMouseDisabled(true) + f1_arg0.mapCategoriesList:setMouseDisabled(false) + end + end) + f1_arg0.mapList:setMouseDisabled(true) + f1_arg0.mapList:registerEventHandler("leftclick_outside", function(element, event) + if IsSelfInState(f1_arg0, "SelectingMap") and f1_arg0.m_categorySet then + CoD.PCUtil.SimulateButtonPress(f1_arg1, Enum.LUIButton.LUI_KEY_XBB_PSCIRCLE) + end + f1_arg0.m_categorySet = true + return true + end) + end +end + +local PostLoadFunc = function(f4_arg0, f4_arg1) + f0_local0(f4_arg0, f4_arg1) +end + +local f0_local2 = 10000 +local f0_local3 = 10001 +local f0_local4 = function(f5_arg0) + local f5_local0 = CoD.mapsTable[f5_arg0] + if CoD.CONTENT_DLC6_INDEX <= f5_local0.dlc_pack or f5_arg0 == "mp_redwood_ice" or f5_arg0 == "mp_veiled_heyday" then + return f0_local3 + elseif f5_local0.dlc_pack > 0 then + return f0_local2 + else + return f5_local0.dlc_pack + end +end + +DataSources.ChangeMapCategories = DataSourceHelpers.ListSetup("ChangeMapCategories", function(f6_arg0) + local f6_local0 = {} + local f6_local1 = CoD.GetMapValue(Engine.DvarString(nil, "ui_mapname"), "dlc_pack", CoD.CONTENT_ORIGINAL_MAP_INDEX) + local f6_local2 = function(f7_arg0, f7_arg1) + return { + models = { + text = Engine.Localize("MPUI_MAP_CATEGORY_" .. f7_arg0 .. "_CAPS"), + buttonText = Engine.Localize("MPUI_MAP_CATEGORY_" .. f7_arg0 .. "_CAPS"), + image = "playlist_map", + description = Engine.Localize("MPUI_MAP_CATEGORY_" .. f7_arg0 .. "_DESC") + }, + properties = { + category = f7_arg1, + selectIndex = f6_local1 == f7_arg1 + } + } + end + + CoD.mapsTable = Engine.GetGDTMapsTable() + local f6_local3 = function(f8_arg0) + for f8_local3, f8_local4 in pairs(CoD.mapsTable) do + if f8_local4.session_mode == CoD.gameModeEnum and f0_local4(f8_local3) == f8_arg0 and (ShowPurchasableMap(f6_arg0, f8_local3) or Engine.IsMapValid(f8_local3)) then + return true + end + end + return false + end + + if CoD.isCampaign == true then + table.insert(f6_local0, f6_local2("missions", CoD.CONTENT_ORIGINAL_MAP_INDEX)) + table.insert(f6_local0, f6_local2("dev", CoD.CONTENT_DEV_MAP_INDEX)) + else + table.insert(f6_local0, f6_local2("standard", CoD.CONTENT_ORIGINAL_MAP_INDEX)) + if not Dvar.ui_execdemo:get() and f6_local3(f0_local2) then + table.insert(f6_local0, f6_local2("dlc", f0_local2)) + end + if not Dvar.ui_execdemo:get() and f6_local3(f0_local3) then + table.insert(f6_local0, f6_local2("dlc_bonus", f0_local3)) + end + if Mods_Enabled() then --and Engine.Mods_Lists_GetInfoEntries( LuaEnums.USERMAP_BASE_PATH, 0, Engine.Mods_Lists_GetInfoEntriesCount( LuaEnums.USERMAP_BASE_PATH ) ) ~= nil then + local f9_local11 = Engine.Mods_Lists_GetInfoEntries(LuaEnums.USERMAP_BASE_PATH, 0, + Engine.Mods_Lists_GetInfoEntriesCount(LuaEnums.USERMAP_BASE_PATH)) + if f9_local11 then + for f9_local12 = 0, #f9_local11, 1 do + local f9_local17 = f9_local11[f9_local12] + if LUI.startswith(f9_local17.internalName, "mp_") then + table.insert(f6_local0, f6_local2("mods", CoD.CONTENT_MODS_INDEX)) + end + end + end + end + end + return f6_local0 +end, true) diff --git a/data/ui_scripts/frontend_menus/datasources_gamesettingsflyout_buttons.lua b/data/ui_scripts/frontend_menus/datasources_gamesettingsflyout_buttons.lua new file mode 100644 index 0000000..497efef --- /dev/null +++ b/data/ui_scripts/frontend_menus/datasources_gamesettingsflyout_buttons.lua @@ -0,0 +1,260 @@ +local f0_local0 = function(f1_arg0, f1_arg1) + if not CoD.useMouse then + return + else + f1_arg0.Options:setHandleMouse(true) + f1_arg0.Options:registerEventHandler("leftclick_outside", function(element, event) + CoD.PCUtil.SimulateButtonPress(event.controller, Enum.LUIButton.LUI_KEY_XBB_PSCIRCLE) + return true + end) + end +end + +local PostLoadFunc = function(f3_arg0, f3_arg1) + f0_local0(f3_arg0, f3_arg1) + f3_arg0.disableBlur = true + f3_arg0.disablePopupOpenCloseAnim = true + Engine.SetModelValue(Engine.CreateModel(Engine.GetGlobalModel(), "GameSettingsFlyoutOpen"), true) + LUI.OverrideFunction_CallOriginalSecond(f3_arg0, "close", function(element) + Engine.SetModelValue(Engine.CreateModel(Engine.GetGlobalModel(), "GameSettingsFlyoutOpen"), false) + end) + f3_arg0:registerEventHandler("occlusion_change", function(element, event) + local f5_local0 = element:getParent() + if f5_local0 then + local f5_local1 = f5_local0:getFirstChild() + while f5_local1 ~= nil do + if f5_local1.menuName == "Lobby" then + break + end + f5_local1 = f5_local1:getNextSibling() + end + if f5_local1 then + if event.occluded == true then + f5_local1:setAlpha(0) + end + f5_local1:setAlpha(1) + end + end + element:OcclusionChange(event) + end) + f3_arg0:subscribeToModel(Engine.CreateModel(Engine.GetGlobalModel(), "lobbyRoot.lobbyNav", true), function(model) + local f6_local0 = f3_arg0.occludedBy + while f6_local0 do + if f6_local0.occludedBy ~= nil then + f6_local0 = f6_local0.occludedBy + end + while f6_local0 and f6_local0.menuName ~= "Lobby" do + f6_local0 = GoBack(f6_local0, f3_arg1) + end + Engine.SendClientScriptNotify(f3_arg1, "menu_change" .. Engine.GetLocalClientNum(f3_arg1), "Main", + "closeToMenu") + return + end + GoBack(f3_arg0, f3_arg1) + end, false) +end + +DataSources.GameSettingsFlyoutButtonsCustom = DataSourceHelpers.ListSetup("GameSettingsFlyoutButtonsCustom", +function(f7_arg0) + local f7_local0 = { + { + optionDisplay = "MPUI_CHANGE_MAP_CAPS", + customId = "btnChangeMap", + action = OpenChangeMap + }, + -- { + -- optionDisplay = "MPUI_CHANGE_GAME_MODE_CAPS", + -- customId = "btnChangeGameMode", + -- action = OpenChangeGameMode + -- }, + { + optionDisplay = "MENU_SETUP_BOTS_CAPS", + customId = "btnSetupBots", + action = OpenBotSettings + }, + { + optionDisplay = "MPUI_EDIT_GAME_RULES_CAPS", + customId = "btnEditGameRules", + action = OpenEditGameRules + } + } + -- if CoD.isPC and IsServerBrowserEnabled() then + -- table.insert( f7_local0, { + -- optionDisplay = "PLATFORM_SERVER_SETTINGS_CAPS", + -- customID = "btnServerSettings", + -- action = OpenServerSettings + -- } ) + -- end + local f7_local1 = {} + for f7_local5, f7_local6 in ipairs(f7_local0) do + table.insert(f7_local1, { + models = { + displayText = Engine.Localize(f7_local6.optionDisplay), + customId = f7_local6.customId, + disabled = f7_local6.disabled + }, + properties = { + title = f7_local6.optionDisplay, + desc = f7_local6.desc, + action = f7_local6.action, + actionParam = f7_local6.actionParam + } + }) + end + return f7_local1 +end, nil, nil, nil) + +LUI.createMenu.GameSettingsFlyoutMPCustom = function(controller) + local self = CoD.Menu.NewForUIEditor("GameSettingsFlyoutMPCustom") + if PreLoadFunc then + PreLoadFunc(self, controller) + end + self.soundSet = "default" + self:setOwner(controller) + self:setLeftRight(true, true, 0, 0) + self:setTopBottom(true, true, 0, 0) + self:playSound("menu_open", controller) + self.buttonModel = Engine.CreateModel(Engine.GetModelForController(controller), "GameSettingsFlyoutMP.buttonPrompts") + self.anyChildUsesUpdateState = true + + local Options = LUI.UIList.new(self, controller, -2, 0, nil, false, false, 0, 0, false, false) + Options:makeFocusable() + Options:setLeftRight(true, false, 243.43, 523.43) + Options:setTopBottom(true, false, 177.56, 329.56) + Options:setYRot(25) + Options:setWidgetType(CoD.FE_List1ButtonLarge_PH) + Options:setVerticalCount(3) + Options:setSpacing(-2) + Options:setDataSource("GameSettingsFlyoutButtonsCustom") + Options:registerEventHandler("gain_focus", function(element, event) + local f9_local0 = nil + if element.gainFocus then + f9_local0 = element:gainFocus(event) + elseif element.super.gainFocus then + f9_local0 = element.super:gainFocus(event) + end + CoD.Menu.UpdateButtonShownState(element, self, controller, Enum.LUIButton.LUI_KEY_XBA_PSCROSS) + return f9_local0 + end) + Options:registerEventHandler("lose_focus", function(element, event) + local f10_local0 = nil + if element.loseFocus then + f10_local0 = element:loseFocus(event) + elseif element.super.loseFocus then + f10_local0 = element.super:loseFocus(event) + end + return f10_local0 + end) + self:AddButtonCallbackFunction(Options, controller, Enum.LUIButton.LUI_KEY_XBA_PSCROSS, "ENTER", + function(element, menu, controller, model) + ProcessListAction(self, element, controller) + return true + end, function(element, menu, controller) + CoD.Menu.SetButtonLabel(menu, Enum.LUIButton.LUI_KEY_XBA_PSCROSS, "MENU_SELECT") + return true + end, false) + self:addElement(Options) + self.Options = Options + + self:mergeStateConditions({ + { + stateName = "Local", + condition = function(menu, element, event) + return IsLobbyNetworkModeLAN() + end + } + }) + self:subscribeToModel(Engine.GetModel(Engine.GetGlobalModel(), "lobbyRoot.lobbyNetworkMode"), function(model) + local f14_local0 = self + local f14_local1 = { + controller = controller, + name = "model_validation", + modelValue = Engine.GetModelValue(model), + modelName = "lobbyRoot.lobbyNetworkMode" + } + CoD.Menu.UpdateButtonShownState(f14_local0, self, controller, Enum.LUIButton.LUI_KEY_XBY_PSTRIANGLE) + end) + self:subscribeToModel(Engine.GetModel(Engine.GetGlobalModel(), "lobbyRoot.lobbyNav"), function(model) + local f15_local0 = self + local f15_local1 = { + controller = controller, + name = "model_validation", + modelValue = Engine.GetModelValue(model), + modelName = "lobbyRoot.lobbyNav" + } + CoD.Menu.UpdateButtonShownState(f15_local0, self, controller, Enum.LUIButton.LUI_KEY_XBY_PSTRIANGLE) + end) + self:AddButtonCallbackFunction(self, controller, Enum.LUIButton.LUI_KEY_XBB_PSCIRCLE, nil, + function(element, menu, controller, model) + GoBack(self, controller) + ClearMenuSavedState(menu) + return true + end, function(element, menu, controller) + CoD.Menu.SetButtonLabel(menu, Enum.LUIButton.LUI_KEY_XBB_PSCIRCLE, "") + return false + end, false) + self:AddButtonCallbackFunction(self, controller, Enum.LUIButton.LUI_KEY_START, "M", + function(element, menu, controller, model) + GoBackAndOpenOverlayOnParent(self, "StartMenu_Main", controller) + return true + end, function(element, menu, controller) + CoD.Menu.SetButtonLabel(menu, Enum.LUIButton.LUI_KEY_START, "MENU_MENU") + return true + end, false) + self:AddButtonCallbackFunction(self, controller, Enum.LUIButton.LUI_KEY_XBY_PSTRIANGLE, "S", + function(element, menu, controller, model) + if not IsLAN() and not IsPlayerAGuest(controller) and IsPlayerAllowedToPlayOnline(controller) then + GoBackAndOpenOverlayOnParent(self, "Social_Main", controller) + return true + else + + end + end, function(element, menu, controller) + if not IsLAN() and not IsPlayerAGuest(controller) and IsPlayerAllowedToPlayOnline(controller) then + CoD.Menu.SetButtonLabel(menu, Enum.LUIButton.LUI_KEY_XBY_PSTRIANGLE, "") + return false + else + return false + end + end, false) + self:AddButtonCallbackFunction(self, controller, Enum.LUIButton.LUI_KEY_LB, nil, + function(element, menu, controller, model) + SendButtonPressToOccludedMenu(menu, controller, model, Enum.LUIButton.LUI_KEY_LB) + return true + end, function(element, menu, controller) + CoD.Menu.SetButtonLabel(menu, Enum.LUIButton.LUI_KEY_LB, "") + return false + end, false) + self:AddButtonCallbackFunction(self, controller, Enum.LUIButton.LUI_KEY_RB, nil, + function(element, menu, controller, model) + SendButtonPressToOccludedMenu(menu, controller, model, Enum.LUIButton.LUI_KEY_RB) + return true + end, function(element, menu, controller) + CoD.Menu.SetButtonLabel(menu, Enum.LUIButton.LUI_KEY_RB, "") + return false + end, false) + Options.id = "Options" + self:processEvent({ + name = "menu_loaded", + controller = controller + }) + self:processEvent({ + name = "update_state", + menu = self + }) + if not self:restoreState() then + self.Options:processEvent({ + name = "gain_focus", + controller = controller + }) + end + LUI.OverrideFunction_CallOriginalSecond(self, "close", function(element) + element.Options:close() + Engine.UnsubscribeAndFreeModel(Engine.GetModel(Engine.GetModelForController(controller), + "GameSettingsFlyoutMP.buttonPrompts")) + end) + if PostLoadFunc then + PostLoadFunc(self, controller) + end + return self +end diff --git a/data/ui_scripts/frontend_menus/datasources_start_menu_tabs.lua b/data/ui_scripts/frontend_menus/datasources_start_menu_tabs.lua new file mode 100644 index 0000000..7776726 --- /dev/null +++ b/data/ui_scripts/frontend_menus/datasources_start_menu_tabs.lua @@ -0,0 +1,217 @@ +DataSources.StartMenuTabs = ListHelper_SetupDataSource("StartMenuTabs", function(f44_arg0) + local f44_local0 = {} + table.insert(f44_local0, { + models = { + tabIcon = CoD.buttonStrings.shoulderl + }, + properties = { + m_mouseDisabled = true + } + }) + if Engine.IsDemoPlaying() then + local f44_local1 = "CoD.StartMenu_GameOptions" + if Engine.IsZombiesGame() then + f44_local1 = "CoD.StartMenu_GameOptions_ZM" + end + table.insert(f44_local0, { + models = { + tabName = Engine.Localize("MENU_THEATER_CAPS"), + tabWidget = f44_local1, + tabIcon = "" + }, + properties = { + tabId = "gameOptions" + } + }) + elseif Engine.IsInGame() then + if IsGameTypeDOA() and not InSafehouse() then + table.insert(f44_local0, { + models = { + tabName = "DOA", + tabWidget = "CoD.StartMenu_GameOptions_DOA", + tabIcon = "" + }, + properties = { + tabId = "gameOptions" + } + }) + elseif CoD.isCampaign then + table.insert(f44_local0, { + models = { + tabName = SessionModeToUnlocalizedSessionModeCaps(Engine.CurrentSessionMode()), + tabWidget = "CoD.StartMenu_GameOptions_CP", + tabIcon = "" + }, + properties = { + tabId = "gameOptions" + } + }) + if not Engine.IsCampaignModeZombies() then + if CoD.isSafehouse and CoD.isOnlineGame() and not IsInTrainingSim(f44_arg0) and Dvar.ui_safehousebarracks:get() and not IsPlayerAGuest(f44_arg0) then + table.insert(f44_local0, { + models = { + tabName = "CPUI_BARRACKS_CAPS", + tabWidget = "CoD.CombatRecordCP_Contents", + tabIcon = "" + }, + properties = { + tabId = "combatRecord" + } + }) + end + if HighestMapReachedGreaterThan(f44_arg0, 1) or LUI.DEV ~= nil then + table.insert(f44_local0, { + models = { + tabName = "CPUI_TACTICAL_MODE_CAPS", + tabWidget = "CoD.StartMenu_TacticalMode", + tabIcon = "" + }, + properties = { + tabId = "tacticalMode" + } + }) + end + if not CoD.isSafehouse and not IsPlayerAGuest(f44_arg0) then + table.insert(f44_local0, { + models = { + tabName = "CPUI_ACCOLADES", + tabWidget = "CoD.MissionRecordVault_Challenges", + tabIcon = "" + }, + properties = { + tabId = "accolades" + } + }) + end + end + elseif Engine.IsZombiesGame() then + table.insert(f44_local0, { + models = { + tabName = SessionModeToUnlocalizedSessionModeCaps(Engine.CurrentSessionMode()), + tabWidget = "CoD.StartMenu_GameOptions_ZM", + tabIcon = "" + }, + properties = { + tabId = "gameOptions" + } + }) + else + table.insert(f44_local0, { + models = { + tabName = SessionModeToUnlocalizedSessionModeCaps(Engine.CurrentSessionMode()), + tabWidget = "CoD.StartMenu_GameOptions", + tabIcon = "" + }, + properties = { + tabId = "gameOptions" + } + }) + end + else + if not IsPlayerAGuest(f44_arg0) then + table.insert(f44_local0, { + models = { + tabName = "MENU_TAB_IDENTITY_CAPS", + tabWidget = "CoD.StartMenu_Identity", + tabIcon = "" + }, + properties = { + tabId = "identity", + disabled = Dvar.ui_execdemo_gamescom:get() + } + }) + end + if not IsLobbyNetworkModeLAN() and not Dvar.ui_execdemo:get() and not Engine.IsCampaignModeZombies() and not IsPlayerAGuest(f44_arg0) then + table.insert(f44_local0, { + models = { + tabName = "MENU_TAB_CHALLENGES_CAPS", + tabWidget = "CoD.StartMenu_Challenges", + tabIcon = "" + }, + properties = { + tabId = "challenges" + } + }) + local f44_local1 = CoD.isPC + if f44_local1 then + f44_local1 = false --Mods_IsUsingMods() + end + table.insert(f44_local0, { + models = { + tabName = "MENU_TAB_BARRACKS_CAPS", + tabWidget = "CoD.StartMenu_Barracks", + tabIcon = "", + disabled = f44_local1 + }, + properties = { + tabId = "barracks" + } + }) + if CommunityOptionsEnabled() then + local f44_local2 = CoD.perController[f44_arg0].openMediaTabAfterClosingGroups + CoD.perController[f44_arg0].openMediaTabAfterClosingGroups = false + table.insert(f44_local0, { + models = { + tabName = "MENU_TAB_MEDIA_CAPS", + tabWidget = "CoD.StartMenu_Media", + tabIcon = "" + }, + properties = { + tabId = "media", + selectIndex = f44_local2 + } + }) + end + end + end + if IsGameTypeDOA() and Engine.IsInGame() and not InSafehouse() then + local f44_local1 = table.insert + local f44_local2 = f44_local0 + local f44_local3 = { + models = { + tabName = "MENU_TAB_OPTIONS_CAPS", + tabWidget = "CoD.StartMenu_Options_DOA", + tabIcon = "" + } + } + local f44_local4 = { + tabId = "options" + } + local f44_local5 = Dvar.ui_execdemo:get() + if f44_local5 then + f44_local5 = not Engine.IsInGame() + end + f44_local4.selectIndex = f44_local5 + f44_local3.properties = f44_local4 + f44_local1(f44_local2, f44_local3) + else + local f44_local1 = table.insert + local f44_local2 = f44_local0 + local f44_local3 = { + models = { + tabName = "MENU_TAB_OPTIONS_CAPS", + tabWidget = "CoD.StartMenu_Options", + tabIcon = "" + } + } + local f44_local4 = { + tabId = "options" + } + local f44_local5 = Dvar.ui_execdemo_gamescom:get() + if f44_local5 then + f44_local5 = not Engine.IsInGame() + end + f44_local4.selectIndex = f44_local5 + f44_local3.properties = f44_local4 + f44_local1(f44_local2, f44_local3) + end + table.insert(f44_local0, { + models = { + tabIcon = CoD.buttonStrings.shoulderr + }, + properties = { + m_mouseDisabled = true + } + }) + return f44_local0 +end, true) diff --git a/data/ui_scripts/frontend_menus/utils.lua b/data/ui_scripts/frontend_menus/utils.lua new file mode 100644 index 0000000..f394e0a --- /dev/null +++ b/data/ui_scripts/frontend_menus/utils.lua @@ -0,0 +1,160 @@ +local IsGamescomDemo = function() + return Dvar.ui_execdemo_gamescom:get() +end + +local IsBetaDemo = function() + return Dvar.ui_execdemo_beta:get() +end + +local SetButtonState = function(button, state) + if state == nil then + return + elseif state == CoD.LobbyButtons.DISABLED then + button.disabled = true + elseif state == CoD.LobbyButtons.HIDDEN then + button.hidden = true + end +end + +local RemoveButton = function(buttonTable, button) + if not button then + return + end + for id, v in pairs(buttonTable) do + if buttonTable[id].optionDisplay == button.stringRef then + table.remove(buttonTable, id) + end + end +end + +local RemoveSpaces = function(buttonTable) + for id, v in pairs(buttonTable) do + buttonTable[id].isLastButtonInGroup = false + end +end + +local GetButtonIndex = function(buttonTable, button) + if not button then + return nil + end + for id, v in pairs(buttonTable) do + if buttonTable[id].optionDisplay == button.stringRef then + return id + end + end +end + +local AddButton = function(controller, options, button, isLargeButton, index) + if button == nil then + return + end + + button.disabled = false + button.hidden = false + button.selected = false + button.warning = false + if button.defaultState ~= nil then + if button.defaultState == CoD.LobbyButtons.DISABLED then + button.disabled = true + elseif button.defaultState == CoD.LobbyButtons.HIDDEN then + button.hidden = true + end + end + if button.disabledFunc ~= nil then + button.disabled = button.disabledFunc(controller) + end + if button.visibleFunc ~= nil then + button.hidden = not button.visibleFunc(controller) + end + if IsBetaDemo() then + SetButtonState(button, button.demo_beta) + elseif IsGamescomDemo() then + SetButtonState(button, button.demo_gamescom) + end + if button.hidden then + return + end + local lobbyNav = LobbyData.GetLobbyNav() + if button.selectedFunc ~= nil then + button.selected = button.selectedFunc(button.selectedParam) + elseif CoD.LobbyMenus.History[lobbyNav] ~= nil then + button.selected = CoD.LobbyMenus.History[lobbyNav] == button.customId + end + if button.newBreadcrumbFunc then + local f8_local1 = button.newBreadcrumbFunc + if type(f8_local1) == "string" then + f8_local1 = LUI.getTableFromPath(f8_local1) + end + if f8_local1 then + button.isBreadcrumbNew = f8_local1(controller) + end + end + if button.warningFunc ~= nil then + button.warning = button.warningFunc(controller) + end + if button.starterPack == CoD.LobbyButtons.STARTERPACK_UPGRADE then + button.starterPackUpgrade = true + if IsStarterPack() then + button.disabled = false + end + end + if index ~= nil then + table.insert(options, index, { + optionDisplay = button.stringRef, + action = button.action, + param = button.param, + customId = button.customId, + isLargeButton = isLargeButton, + isLastButtonInGroup = false, + disabled = button.disabled, + selected = button.selected, + isBreadcrumbNew = button.isBreadcrumbNew, + warning = button.warning, + requiredChunk = button.selectedParam, + starterPackUpgrade = button.starterPackUpgrade, + unloadMod = button.unloadMod + }) + else + table.insert(options, { + optionDisplay = button.stringRef, + action = button.action, + param = button.param, + customId = button.customId, + isLargeButton = isLargeButton, + isLastButtonInGroup = false, + disabled = button.disabled, + selected = button.selected, + isBreadcrumbNew = button.isBreadcrumbNew, + warning = button.warning, + requiredChunk = button.selectedParam, + starterPackUpgrade = button.starterPackUpgrade, + unloadMod = button.unloadMod + }) + end +end + +local AddLargeButton = function(controller, options, button, index) + AddButton(controller, options, button, true, index) +end + +local AddSmallButton = function(controller, options, button, index) + AddButton(controller, options, button, false, index) +end + +local AddSpacer = function(options, index) + if index ~= nil then + options[index].isLastButtonInGroup = true + elseif 0 < #options then + options[#options].isLastButtonInGroup = true + end +end + +return { + AddButton = AddButton, + AddLargeButton = AddLargeButton, + AddSmallButton = AddSmallButton, + AddSpacer = AddSpacer, + RemoveButton = RemoveButton, + RemoveSpaces = RemoveSpaces, + GetButtonIndex = GetButtonIndex +} diff --git a/data/ui_scripts/graphics_settings/__init__.lua b/data/ui_scripts/graphics_settings/__init__.lua new file mode 100644 index 0000000..1219bea --- /dev/null +++ b/data/ui_scripts/graphics_settings/__init__.lua @@ -0,0 +1,148 @@ +DataSources.OptionGraphicsVideo = DataSourceHelpers.ListSetup( "PC.OptionGraphicsVideo", function ( controller ) + local videoSettings = {} + table.insert( videoSettings, { + models = { + label = "PLATFORM_DISPLAY_MODE", + description = "PLATFORM_DISPLAY_MODE_DESC", + profileVarName = "r_fullscreen", + datasource = "OptionPCGraphicsDisplayMode", + widgetType = "dropdown" + }, + properties = CoD.PCUtil.DependantDropdownProperties + } ) + table.insert( videoSettings, { + models = { + label = "PLATFORM_MONITOR", + description = "PLATFORM_MONITOR_DESC", + profileVarName = "r_monitor", + datasource = "OptionPCGraphicsMonitor", + widgetType = "dropdown", + disabledFunction = function () + return Engine.GetHardwareProfileValueAsString( "r_fullscreen" ) == "0" + end + }, + properties = CoD.PCUtil.DependantDropdownProperties + } ) + table.insert( videoSettings, { + models = { + label = "PLATFORM_SCREEN_RESOLUTION", + description = "PLATFORM_SCREEN_RESOLUTION_DESC", + profileVarName = "r_mode", + datasource = "OptionPCGraphicsScreenResolution", + widgetType = "dropdown", + disabledFunction = function () + return Engine.GetHardwareProfileValueAsString( "r_fullscreen" ) == "2" + end + }, + properties = CoD.PCUtil.DependantDropdownProperties + } ) + table.insert( videoSettings, { + models = { + label = "PLATFORM_REFRESH_RATE", + description = "PLATFORM_REFRESH_RATE_DESC", + profileVarName = "r_refreshRate", + datasource = "OptionPCGraphicsRefreshRate", + widgetType = "dropdown", + disabledFunction = function () + return Engine.GetHardwareProfileValueAsString( "r_fullscreen" ) ~= "1" + end + }, + properties = CoD.PCUtil.OptionsGenericDropdownProperties + } ) + table.insert( videoSettings, { + models = { + label = "PLATFORM_SCENE_RESOLUTION_RATIO", + description = "PLATFORM_SCENE_RESOLUTION_RATIO_DESC", + profileVarName = "r_sceneResolutionMultiplier", + datasource = "OptionPCGraphicsSceneResolution", + widgetType = "dropdown" + }, + properties = CoD.PCUtil.DependantDropdownProperties + } ) + table.insert( videoSettings, { + models = { + label = "PLATFORM_DISPLAY_GAMMA", + description = "PLATFORM_DISPLAY_GAMMA_DESC", + profileVarName = "r_videoMode", + datasource = "OptionPCGraphicsDisplayGamma", + widgetType = "dropdown" + }, + properties = CoD.PCUtil.OptionsGenericDropdownProperties + } ) + table.insert( videoSettings, { + models = { + label = "PLATFORM_BRIGHTNESS", + description = "PLATFORM_BRIGHTNESS_DESC", + profileVarName = "r_sceneBrightness", + profileType = "user", + lowValue = -1, + highValue = 1, + widgetType = "slider" + }, + properties = CoD.PCUtil.OptionsGenericSliderProperties + } ) + table.insert( videoSettings, { + models = { + label = "PLATFORM_FOV", + description = "PLATFORM_FOV_DESC", + profileVarName = "cg_fov_default", + lowValue = 65, + highValue = 120, + useIntegerDisplay = 1, + widgetType = "slider" + }, + properties = CoD.PCUtil.OptionsGenericSliderProperties + } ) + table.insert( videoSettings, { + models = { + widgetType = "spacer", + height = 32 + } + } ) + table.insert( videoSettings, { + models = { + label = "PLATFORM_MAX_FPS", + description = "PLATFORM_MAX_FPS_DESC", + profileVarName = "com_maxfps", + lowValue = 24, + highValue = 500, + useIntegerDisplay = 1, + widgetType = "slider" + }, + properties = CoD.PCUtil.OptionsGenericSliderProperties + } ) + table.insert( videoSettings, { + models = { + label = "PLATFORM_SYNC_EVERY_FRAME", + description = "PLATFORM_VSYNC_DESC", + profileVarName = "r_vsync", + widgetType = "checkbox" + }, + properties = CoD.PCUtil.OptionsGenericCheckboxProperties + } ) + table.insert( videoSettings, { + models = { + label = "PLATFORM_DRAW_FPS", + description = "PLATFORM_DRAW_FPS_DESC", + profileVarName = "com_drawFPS_PC", + widgetType = "checkbox" + }, + properties = CoD.PCUtil.OptionsGenericCheckboxProperties + } ) + return videoSettings +end, true ) +DataSources.OptionGraphicsVideo.getWidgetTypeForItem = function ( list, dataItemModel, row ) + if dataItemModel then + local widgetType = Engine.GetModelValue( Engine.GetModel( dataItemModel, "widgetType" ) ) + if widgetType == "dropdown" then + return CoD.OptionDropdown + elseif widgetType == "checkbox" then + return CoD.StartMenu_Options_CheckBoxOption + elseif widgetType == "slider" then + return CoD.StartMenu_Options_SliderBar + elseif widgetType == "spacer" then + return CoD.VerticalListSpacer + end + end + return nil +end \ No newline at end of file diff --git a/data/ui_scripts/lua_fixes/__init__.lua b/data/ui_scripts/lua_fixes/__init__.lua new file mode 100644 index 0000000..e04639b --- /dev/null +++ b/data/ui_scripts/lua_fixes/__init__.lua @@ -0,0 +1,4 @@ + +-- Fix LUI_NULL_FUNCTION messages +function Engine.PIXBeginEvent() end +function Engine.PIXEndEvent() end \ No newline at end of file diff --git a/data/ui_scripts/party/__init__.lua b/data/ui_scripts/party/__init__.lua new file mode 100644 index 0000000..663b0e8 --- /dev/null +++ b/data/ui_scripts/party/__init__.lua @@ -0,0 +1,30 @@ +local modeInfo = LobbyData:UITargetFromId(Engine.GetLobbyUIScreen()) +local maxClients = modeInfo.maxClients + +-- Disable setting party privacy in menu. Auto set to open + max. +Engine.SetDvar("partyprivacyenabled", 0) +Engine.SetDvar("tu4_partyprivacyuseglobal", 0) +Engine.SetDvar("tu4_partyprivacyluacheck", 0) + +-- Fix for invisible bots in custom games +if maxClients >= 1 then + Engine.SetDvar("party_maxplayers", maxClients) +end + +if not Engine.IsInGame() then + return +end + +-- Removed check for public matches to allow team change in ranked matches +CoD.IsTeamChangeAllowed = function() + if Engine.GetGametypeSetting("allowInGameTeamChange") == 1 then + return true + else + return false + end +end + +-- Set com_maxclients InGame so players can join via direct connect (default from lobbydata) +Engine.SetDvar("com_maxclients", maxClients) + +require("datasources_start_menu_game_options") diff --git a/data/ui_scripts/party/datasources_start_menu_game_options.lua b/data/ui_scripts/party/datasources_start_menu_game_options.lua new file mode 100644 index 0000000..ae6eb3b --- /dev/null +++ b/data/ui_scripts/party/datasources_start_menu_game_options.lua @@ -0,0 +1,75 @@ +DataSources.StartMenuGameOptions = ListHelper_SetupDataSource("StartMenuGameOptions", function (controller) + local options = {} + if Engine.IsDemoPlaying() then + if not IsDemoRestrictedBasicMode() then + table.insert(options, {models = {displayText = Engine.ToUpper(Engine.Localize("MENU_UPLOAD_CLIP", Engine.GetDemoSegmentCount())), action = StartMenuUploadClip, disabledFunction = IsUploadClipButtonDisabled}, properties = {hideHelpItemLabel = true}}) + end + if Engine.IsDemoHighlightReelMode() then + table.insert(options, {models = {displayText = Engine.ToUpper(Engine.Localize("MENU_DEMO_CUSTOMIZE_HIGHLIGHT_REEL")), action = StartMenuOpenCustomizeHighlightReel, disabledFunction = IsCustomizeHighlightReelButtonDisabled}}) + end + table.insert(options, {models = {displayText = Engine.ToUpper(Engine.ToUpper(Engine.Localize("MENU_JUMP_TO_START"))), action = StartMenuJumpToStart, disabledFunction = IsJumpToStartButtonDisabled}, properties = {hideHelpItemLabel = true}}) + local endDemoButtonText = nil + if Engine.IsDemoClipPlaying() then + endDemoButtonText = Engine.ToUpper(Engine.Localize("MENU_END_CLIP")) + else + endDemoButtonText = Engine.ToUpper(Engine.Localize("MENU_END_FILM")) + end + table.insert(options, {models = {displayText = Engine.ToUpper(endDemoButtonText), action = StartMenuEndDemo}}) + elseif CoD.isCampaign then + table.insert(options, {models = {displayText = "MENU_RESUMEGAME_CAPS", action = StartMenuGoBack_ListElement}}) + local inTrainingSim = CoD.SafeGetModelValue(Engine.GetModelForController(controller), "safehouse.inTrainingSim") + if not inTrainingSim then + inTrainingSim = 0 + end + if Engine.IsLobbyHost(Enum.LobbyType.LOBBY_TYPE_GAME) then + if not CoD.isSafehouse and controller == Engine.GetPrimaryController() then + table.insert(options, {models = {displayText = "MENU_RESTART_MISSION_CAPS", action = RestartMission}}) + if LUI.DEV ~= nil then + table.insert(options, {models = {displayText = "MENU_RESTART_CHECKPOINT_CAPS", action = RestartFromCheckpoint}}) + end + end + if controller == Engine.GetPrimaryController() then + table.insert(options, {models = {displayText = "MENU_CHANGE_DIFFICULTY_CAPS", action = OpenDifficultySelect}}) + end + if CoD.isSafehouse and inTrainingSim == 1 then + table.insert(options, {models = {displayText = "MENU_END_TRAINING_SIM", action = EndTrainingSim}}) + elseif controller == Engine.GetPrimaryController() then + if Engine.DvarBool(0, "ui_blocksaves") then + table.insert(options, {models = {displayText = "MENU_EXIT_CAPS", action = SaveAndQuitGame}}) + else + table.insert(options, {models = {displayText = "MENU_SAVE_AND_QUIT_CAPS", action = SaveAndQuitGame}}) + end + end + elseif CoD.isSafehouse and inTrainingSim == 1 then + table.insert(options, {models = {displayText = "MENU_END_TRAINING_SIM", action = EndTrainingSim}}) + else + table.insert(options, {models = {displayText = "MENU_LEAVE_PARTY_AND_EXIT_CAPS", action = QuitGame}}) + end + elseif CoD.isMultiplayer then + if Engine.Team(controller, "name") ~= "TEAM_SPECTATOR" and Engine.GetGametypeSetting("disableClassSelection") ~= 1 then + table.insert(options, {models = {displayText = "MPUI_CHOOSE_CLASS_BUTTON_CAPS", action = ChooseClass}}) + end + if not Engine.IsVisibilityBitSet(controller, Enum.UIVisibilityBit.BIT_ROUND_END_KILLCAM) and not Engine.IsVisibilityBitSet(controller, Enum.UIVisibilityBit.BIT_FINAL_KILLCAM) and CoD.IsTeamChangeAllowed() then + table.insert(options, {models = {displayText = "MPUI_CHANGE_TEAM_BUTTON_CAPS", action = ChooseTeam}}) + end + if controller == 0 then + local endGameText = "MENU_QUIT_GAME_CAPS" + if Engine.IsLobbyHost(Enum.LobbyType.LOBBY_TYPE_GAME) and not CoD.isOnlineGame() then + endGameText = "MENU_END_GAME_CAPS" + end + table.insert(options, {models = {displayText = endGameText, action = QuitGame_MP}}) + end + elseif CoD.isZombie then + table.insert(options, {models = {displayText = "MENU_RESUMEGAME_CAPS", action = StartMenuGoBack_ListElement}}) + if Engine.IsLobbyHost(Enum.LobbyType.LOBBY_TYPE_GAME) and (not Engine.SessionModeIsMode(CoD.SESSIONMODE_SYSTEMLINK) or Engine.SessionModeIsMode(CoD.SESSIONMODE_OFFLINE)) then + table.insert(options, {models = {displayText = "MENU_RESTART_LEVEL_CAPS", action = RestartGame}}) + end + if Engine.IsLobbyHost(Enum.LobbyType.LOBBY_TYPE_GAME) == true then + table.insert(options, {models = {displayText = "MENU_END_GAME_CAPS", action = QuitGame_MP}}) + else + table.insert(options, {models = {displayText = "MENU_QUIT_GAME_CAPS", action = QuitGame_MP}}) + end + end + table.insert(options, {models = {displayText = "QUIT TO DESKTOP", action = OpenPCQuit}}) + return options +end, true) diff --git a/data/ui_scripts/playlist/__init__.lua b/data/ui_scripts/playlist/__init__.lua new file mode 100644 index 0000000..f808066 --- /dev/null +++ b/data/ui_scripts/playlist/__init__.lua @@ -0,0 +1,34 @@ +if Engine.GetCurrentMap() ~= "core_frontend" then + return +end + +if CoD.LobbyMember then + local oldLobbyMember = CoD.LobbyMember.new + function CoD.LobbyMember.new(menu, controller) + local self = oldLobbyMember(menu, controller) + + -- Hide the playlist count text + if self.SearchingForPlayer then + self.SearchingForPlayer:setAlpha(0) + end + if self.FEMemberBlurPanelContainer0 then + self.FEMemberBlurPanelContainer0:setAlpha(0) + end + + return self + end +end + +function IsLobbyStatusVisible() + return false +end + +Engine.SetDvar("lobbyMigrate_Enabled", 0) +Engine.SetDvar("lobbyTimerStatusVotingInterval", 11000) +Engine.SetDvar("lobbyTimerStatusBeginInterval", 10) +Engine.SetDvar("lobbyTimerStatusStartInterval", 10) +Engine.SetDvar("lobbyTimerStatusPostGameInterval", 10) +Engine.SetDvar("lobbyTimerStatusVotingInterval_Arena", 11000) + +require("widget_playlist_match_settings_info") +require("widget_playlist_category_match_settings_info") diff --git a/data/ui_scripts/playlist/widget_playlist_category_match_settings_info.lua b/data/ui_scripts/playlist/widget_playlist_category_match_settings_info.lua new file mode 100644 index 0000000..28c34d2 --- /dev/null +++ b/data/ui_scripts/playlist/widget_playlist_category_match_settings_info.lua @@ -0,0 +1,15 @@ +if not CoD.playlistCategoryMatchSettingsInfo then + return +end + +local oldPlaylistCategoryMatchSettingsInfo = CoD.playlistCategoryMatchSettingsInfo.new +function CoD.playlistCategoryMatchSettingsInfo.new(menu, controller) + local self = oldPlaylistCategoryMatchSettingsInfo(menu, controller) + + -- Hide the playlist count text + if self.playlistCount then + self.playlistCount:setAlpha(0) + end + + return self +end diff --git a/data/ui_scripts/playlist/widget_playlist_match_settings_info.lua b/data/ui_scripts/playlist/widget_playlist_match_settings_info.lua new file mode 100644 index 0000000..9b31390 --- /dev/null +++ b/data/ui_scripts/playlist/widget_playlist_match_settings_info.lua @@ -0,0 +1,15 @@ +if not CoD.playlistMatchSettingsInfo then + return +end + +local oldPlaylistMatchSettingsInfo = CoD.playlistMatchSettingsInfo.new +function CoD.playlistMatchSettingsInfo.new(menu, controller) + local self = oldPlaylistMatchSettingsInfo(menu, controller) + + -- Hide the playlist count text + if self.playlistCount then + self.playlistCount:setAlpha(0) + end + + return self +end diff --git a/data/ui_scripts/ranked/__init__.lua b/data/ui_scripts/ranked/__init__.lua new file mode 100644 index 0000000..685aa5c --- /dev/null +++ b/data/ui_scripts/ranked/__init__.lua @@ -0,0 +1 @@ +require("online_mods_loaded") diff --git a/data/ui_scripts/ranked/online_mods_loaded.lua b/data/ui_scripts/ranked/online_mods_loaded.lua new file mode 100644 index 0000000..2c388b9 --- /dev/null +++ b/data/ui_scripts/ranked/online_mods_loaded.lua @@ -0,0 +1,23 @@ +if Engine.GetCurrentMap() ~= "core_frontend" then + return +end + +function ShouldUnloadMod(arg0) + return false +end + +-- Load usermaps mod if custom map selected +local mustLoadUsermaps = function(element, controller) + if CoD.perController[controller].mapCategory == CoD.CONTENT_MODS_INDEX then + if not Engine.IsUsingMods() then + LuaUtils.Mods_LoadMod("usermaps") -- LuaUtils.Mods_LoadMod(element.loadModName) + + CoD.OverlayUtility.ShowToast("DefaultState", Engine.Localize("MENU_MODS_CAPS"), Engine.Localize("PLATFORM_MODS_LOADED") .. " " .. element.mapName) + end + end +end + +function MapSelected(element, controller) + SetMap(controller, element.mapName, false) + mustLoadUsermaps(element, controller) +end diff --git a/data/ui_scripts/server_browser/__init__.lua b/data/ui_scripts/server_browser/__init__.lua new file mode 100644 index 0000000..49cd0fc --- /dev/null +++ b/data/ui_scripts/server_browser/__init__.lua @@ -0,0 +1,378 @@ +if Engine.GetCurrentMap() ~= "core_frontend" then + return +end + +function IsServerBrowserEnabled() + return true +end + +DataSources.LobbyServer = { + prepare = function(controller, list, filter) + list.numElementsInList = list.vCount + list.controller = controller + list.serverBrowserRootModel = Engine.CreateModel(Engine.GetGlobalModel(), "serverBrowser") + local serverListCountModel = Engine.GetModel(list.serverBrowserRootModel, "serverListCount") + if serverListCountModel then + list.serverCount = Engine.GetModelValue(serverListCountModel) + else + list.serverCount = 0 + end + list.servers = {} + local serversModel = Engine.CreateModel(list.serverBrowserRootModel, "servers") + for i = 1, list.numElementsInList, 1 do + list.servers[i] = {} + list.servers[i].root = Engine.CreateModel(serversModel, "server_" .. i) + list.servers[i].model = Engine.CreateModel(list.servers[i].root, "model") + end + list.updateModels = function(controller, list, offset) + local serverInfo = Engine.SteamServerBrowser_GetServerInfo(offset) + if serverInfo then + local SetModelValue = function(model, key, value) + local model = Engine.CreateModel(model, key) + if model then + Engine.SetModelValue(model, value) + end + end + + local elementIndex = offset % list.numElementsInList + 1 + local serverModel = list.servers[elementIndex].model + SetModelValue(serverModel, "serverIndex", serverInfo.serverIndex) + SetModelValue(serverModel, "connectAddr", serverInfo.connectAddr) + SetModelValue(serverModel, "ping", serverInfo.ping) + SetModelValue(serverModel, "modName", serverInfo.modName) + SetModelValue(serverModel, "mapName", serverInfo.map) + SetModelValue(serverModel, "desc", serverInfo.desc) + -- Change the client count to be the actual player count + local clientCount = serverInfo.playerCount - serverInfo.botCount + SetModelValue(serverModel, "clientCount", clientCount) + SetModelValue(serverModel, "maxClients", serverInfo.maxPlayers) + SetModelValue(serverModel, "passwordProtected", serverInfo.password) + SetModelValue(serverModel, "secure", serverInfo.secure) + SetModelValue(serverModel, "name", serverInfo.name) + SetModelValue(serverModel, "gameType", serverInfo.gametype) + SetModelValue(serverModel, "dedicated", serverInfo.dedicated) + SetModelValue(serverModel, "ranked", serverInfo.ranked) + SetModelValue(serverModel, "hardcore", serverInfo.hardcore) + SetModelValue(serverModel, "zombies", serverInfo.zombies) + -- Add the bot count + SetModelValue(serverModel, "botCount", serverInfo.botCount) + return serverModel + else + return nil + end + end + + if list.serverListUpdateSubscription then + list:removeSubscription(list.serverListUpdateSubscription) + end + local serverListUpdateModel = Engine.CreateModel(list.serverBrowserRootModel, "serverListCount") + list.serverListUpdateSubscription = list:subscribeToModel(serverListUpdateModel, function(model) + list:updateDataSource(false, false) + end, false) + if list.serverListSortTypeSubscription then + list:removeSubscription(list.serverListSortTypeSubscription) + end + local serverListSortTypeModel = Engine.CreateModel(list.serverBrowserRootModel, "serverListSortType") + list.serverListSortTypeSubscription = list:subscribeToModel(serverListSortTypeModel, function(model) + list:updateDataSource(false, false) + end, false) + end, + getCount = function(list) + return list.serverCount + end, + getItem = function(controller, list, index) + local offset = index - 1 + return list.updateModels(controller, list, offset) + end, + cleanup = function(list) + if list.serverBrowserRootModel then + Engine.UnsubscribeAndFreeModel(list.serverBrowserRootModel) + list.serverBrowserRootModel = nil + end + end +} + +CoD.ServerBrowserRowInternal.new = function(menu, controller) + local self = LUI.UIHorizontalList.new({ + left = 0, + top = 0, + right = 0, + bottom = 0, + leftAnchor = true, + topAnchor = true, + rightAnchor = true, + bottomAnchor = true, + spacing = 2 + }) + self:setAlignment(LUI.Alignment.Left) + if PreLoadFunc then + PreLoadFunc(self, controller) + end + self:setUseStencil(false) + self:setClass(CoD.ServerBrowserRowInternal) + self.id = "ServerBrowserRowInternal" + self.soundSet = "default" + self:setLeftRight(true, false, 0, 700) + self:setTopBottom(true, false, 0, 22) + self:makeFocusable() + self.onlyChildrenFocusable = true + self.anyChildUsesUpdateState = true + + local passwordFlag = CoD.ServerBrowserFlag.new(menu, controller) + passwordFlag:setLeftRight(true, false, 0, 28) + passwordFlag:setTopBottom(true, true, 0, 0) + passwordFlag.icon:setImage(RegisterImage("uie_t7_icon_serverbrowser_protected")) + passwordFlag:linkToElementModel(self, nil, false, function(model) + passwordFlag:setModel(model, controller) + end) + passwordFlag:mergeStateConditions({ + { + stateName = "FlagOn", + condition = function(menu, element, event) + return IsSelfModelValueTrue(element, controller, "passwordProtected") + end + } + }) + passwordFlag:linkToElementModel(passwordFlag, "passwordProtected", true, function(model) + menu:updateElementState(passwordFlag, { + name = "model_validation", + menu = menu, + modelValue = Engine.GetModelValue(model), + modelName = "passwordProtected" + }) + end) + self:addElement(passwordFlag) + self.passwordFlag = passwordFlag + + local dedicatedFlag = CoD.ServerBrowserFlag.new(menu, controller) + dedicatedFlag:setLeftRight(true, false, 30, 58) + dedicatedFlag:setTopBottom(true, true, 0, 0) + dedicatedFlag.icon:setImage(RegisterImage("uie_t7_icon_serverbrowser_dedicated")) + dedicatedFlag:linkToElementModel(self, nil, false, function(model) + dedicatedFlag:setModel(model, controller) + end) + dedicatedFlag:mergeStateConditions({ + { + stateName = "FlagOn", + condition = function(menu, element, event) + return IsSelfModelValueTrue(element, controller, "dedicated") + end + } + }) + dedicatedFlag:linkToElementModel(dedicatedFlag, "dedicated", true, function(model) + menu:updateElementState(dedicatedFlag, { + name = "model_validation", + menu = menu, + modelValue = Engine.GetModelValue(model), + modelName = "dedicated" + }) + end) + self:addElement(dedicatedFlag) + self.dedicatedFlag = dedicatedFlag + + local rankedFlag = CoD.ServerBrowserFlag.new(menu, controller) + rankedFlag:setLeftRight(true, false, 60, 88) + rankedFlag:setTopBottom(true, true, 0, 0) + rankedFlag.icon:setImage(RegisterImage("uie_t7_icon_serverbrowser_ranked")) + rankedFlag:linkToElementModel(self, nil, false, function(model) + rankedFlag:setModel(model, controller) + end) + rankedFlag:mergeStateConditions({ + { + stateName = "FlagOn", + condition = function(menu, element, event) + return IsSelfModelValueTrue(element, controller, "ranked") + end + } + }) + rankedFlag:linkToElementModel(rankedFlag, "ranked", true, function(model) + menu:updateElementState(rankedFlag, { + name = "model_validation", + menu = menu, + modelValue = Engine.GetModelValue(model), + modelName = "ranked" + }) + end) + self:addElement(rankedFlag) + self.rankedFlag = rankedFlag + + local name = CoD.horizontalScrollingTextBox_18pt.new(menu, controller) + name:setLeftRight(true, false, 90, 330) + name:setTopBottom(true, false, 2, 20) + name.textBox:setTTF("fonts/default.ttf") + name.textBox:setAlignment(Enum.LUIAlignment.LUI_ALIGNMENT_LEFT) + name:linkToElementModel(self, "name", true, function(model) + local _name = Engine.GetModelValue(model) + if _name then + name.textBox:setText(Engine.Localize(_name)) + end + end) + self:addElement(name) + self.name = name + + local spacer = LUI.UIFrame.new(menu, controller, 0, 0, false) + spacer:setLeftRight(true, false, 332, 339) + spacer:setTopBottom(true, false, 0, 22) + spacer:setAlpha(0) + self:addElement(spacer) + self.spacer = spacer + + local map = CoD.horizontalScrollingTextBox_18pt.new(menu, controller) + map:setLeftRight(true, false, 341, 446) + map:setTopBottom(true, false, 2, 20) + map.textBox:setTTF("fonts/default.ttf") + map.textBox:setAlignment(Enum.LUIAlignment.LUI_ALIGNMENT_LEFT) + map:linkToElementModel(self, "mapName", true, function(model) + local mapName = Engine.GetModelValue(model) + if mapName then + map.textBox:setText(MapNameToLocalizedMapName(mapName)) + end + end) + self:addElement(map) + self.map = map + + local hardcoreFlag = CoD.ServerBrowserFlag.new(menu, controller) + hardcoreFlag:setLeftRight(true, false, 448, 470) + hardcoreFlag:setTopBottom(true, true, 0, 0) + hardcoreFlag.icon:setImage(RegisterImage("uie_t7_icon_serverbrowser_skull")) + hardcoreFlag:linkToElementModel(self, nil, false, function(model) + hardcoreFlag:setModel(model, controller) + end) + hardcoreFlag:mergeStateConditions({ + { + stateName = "FlagOn", + condition = function(menu, element, event) + return IsSelfModelValueTrue(element, controller, "hardcore") + end + } + }) + hardcoreFlag:linkToElementModel(hardcoreFlag, "hardcore", true, function(model) + menu:updateElementState(hardcoreFlag, { + name = "model_validation", + menu = menu, + modelValue = Engine.GetModelValue(model), + modelName = "hardcore" + }) + end) + self:addElement(hardcoreFlag) + self.hardcoreFlag = hardcoreFlag + + local gametype = LUI.UIText.new() + gametype:setLeftRight(true, false, 472, 576) + gametype:setTopBottom(true, false, 2, 20) + gametype:setTTF("fonts/RefrigeratorDeluxe-Regular.ttf") + gametype:setAlignment(Enum.LUIAlignment.LUI_ALIGNMENT_LEFT) + gametype:setAlignment(Enum.LUIAlignment.LUI_ALIGNMENT_TOP) + gametype:linkToElementModel(self, "gameType", true, function(model) + local gameType = Engine.GetModelValue(model) + if gameType then + gametype:setText(Engine.Localize(GetGameTypeDisplayString(gameType))) + end + end) + self:addElement(gametype) + self.gametype = gametype + + local playerCount = LUI.UIText.new() + playerCount:setLeftRight(true, false, 593, 613) + playerCount:setTopBottom(true, false, 2, 20) + playerCount:setTTF("fonts/RefrigeratorDeluxe-Regular.ttf") + playerCount:setAlignment(Enum.LUIAlignment.LUI_ALIGNMENT_RIGHT) + playerCount:setAlignment(Enum.LUIAlignment.LUI_ALIGNMENT_TOP) + playerCount:linkToElementModel(self, "clientCount", true, function(model) + local clientCount = Engine.GetModelValue(model) + if clientCount then + playerCount:setText(Engine.Localize(clientCount)) + end + end) + self:addElement(playerCount) + self.playerCount = playerCount + + local slash = LUI.UIText.new() + slash:setLeftRight(true, false, 615, 624) + slash:setTopBottom(true, false, 2, 20) + slash:setText(Engine.Localize("/")) + slash:setTTF("fonts/RefrigeratorDeluxe-Regular.ttf") + slash:setAlignment(Enum.LUIAlignment.LUI_ALIGNMENT_LEFT) + slash:setAlignment(Enum.LUIAlignment.LUI_ALIGNMENT_TOP) + self:addElement(slash) + self.slash = slash + + local maxPlayers = LUI.UIText.new() + maxPlayers:setLeftRight(true, false, 626, 645) + maxPlayers:setTopBottom(true, false, 2, 20) + maxPlayers:setTTF("fonts/RefrigeratorDeluxe-Regular.ttf") + maxPlayers:setAlignment(Enum.LUIAlignment.LUI_ALIGNMENT_LEFT) + maxPlayers:setAlignment(Enum.LUIAlignment.LUI_ALIGNMENT_TOP) + maxPlayers:linkToElementModel(self, "maxClients", true, function(model) + local maxClients = Engine.GetModelValue(model) + if maxClients then + maxPlayers:setText(Engine.Localize(maxClients)) + end + end) + self:addElement(maxPlayers) + self.maxPlayers = maxPlayers + + local botCount = LUI.UIText.new() + botCount:setLeftRight(true, false, 637, 659) + botCount:setTopBottom(true, false, 2, 20) + botCount:setTTF("fonts/RefrigeratorDeluxe-Regular.ttf") + botCount:setAlignment(Enum.LUIAlignment.LUI_ALIGNMENT_LEFT) + botCount:setAlignment(Enum.LUIAlignment.LUI_ALIGNMENT_TOP) + botCount:linkToElementModel(self, "botCount", true, function(model) + local _botCount = Engine.GetModelValue(model) + if _botCount then + botCount:setText("[" .. Engine.Localize(_botCount) .. "]") + end + end) + botCount:linkToElementModel(self, "zombies", true, function(model) + local zombies = Engine.GetModelValue(model) + if zombies ~= nil then + botCount:setAlpha(zombies and 0 or 1) + end + end) + self:addElement(botCount) + self.botCount = botCount + + local ping = LUI.UIText.new() + ping:setLeftRight(true, false, 661, 699.37) + ping:setTopBottom(true, false, 2, 20) + ping:setTTF("fonts/RefrigeratorDeluxe-Regular.ttf") + ping:setAlignment(Enum.LUIAlignment.LUI_ALIGNMENT_CENTER) + ping:setAlignment(Enum.LUIAlignment.LUI_ALIGNMENT_TOP) + ping:linkToElementModel(self, "ping", true, function(model) + local _ping = Engine.GetModelValue(model) + if _ping then + ping:setText(Engine.Localize(_ping)) + end + end) + self:addElement(ping) + self.ping = ping + + spacer.id = "spacer" + self:registerEventHandler("gain_focus", function(self, event) + if self.m_focusable and self.spacer:processEvent(event) then + return true + else + return LUI.UIElement.gainFocus(self, event) + end + end) + LUI.OverrideFunction_CallOriginalSecond(self, "close", function(element) + element.passwordFlag:close() + element.dedicatedFlag:close() + element.rankedFlag:close() + element.name:close() + element.map:close() + element.hardcoreFlag:close() + element.gametype:close() + element.playerCount:close() + element.maxPlayers:close() + element.botCount:close() + element.ping:close() + end) + + if PostLoadFunc then + PostLoadFunc(self, controller, menu) + end + + return self +end diff --git a/data/ui_scripts/stats/__init__.lua b/data/ui_scripts/stats/__init__.lua new file mode 100644 index 0000000..78f62b1 --- /dev/null +++ b/data/ui_scripts/stats/__init__.lua @@ -0,0 +1,421 @@ +if Engine.GetCurrentMap() ~= "core_frontend" then + return +end + +DataSources.MPStatsSettings = DataSourceHelpers.ListSetup("MPStatsSettings", function(controller) + local optionsTable = {} + + local updateDvar = function(f1_arg0, f1_arg1, f1_arg2, dvarName, f1_arg4) + local oldValue = Engine.DvarInt(nil, dvarName) + local newValue = f1_arg1.value + UpdateInfoModels(f1_arg1) + if oldValue == newValue then + return + end + Engine.SetDvar(dvarName, f1_arg1.value) + if dvarName == "cg_unlockall_loot" then + Engine.SetDvar("ui_enableAllHeroes", f1_arg1.value) + end + if dvarName == "all_ee_completed" then + Engine.ExecNow(f1_arg0, "statsetbyname darkops_zod_ee " .. f1_arg1.value) + Engine.ExecNow(f1_arg0, "statsetbyname darkops_zod_super_ee " .. f1_arg1.value) + Engine.ExecNow(f1_arg0, "statsetbyname darkops_factory_ee " .. f1_arg1.value) + Engine.ExecNow(f1_arg0, "statsetbyname darkops_factory_super_ee " .. f1_arg1.value) + Engine.ExecNow(f1_arg0, "statsetbyname darkops_castle_ee " .. f1_arg1.value) + Engine.ExecNow(f1_arg0, "statsetbyname darkops_castle_super_ee " .. f1_arg1.value) + Engine.ExecNow(f1_arg0, "statsetbyname darkops_island_ee " .. f1_arg1.value) + Engine.ExecNow(f1_arg0, "statsetbyname darkops_island_super_ee " .. f1_arg1.value) + Engine.ExecNow(f1_arg0, "statsetbyname darkops_stalingrad_ee " .. f1_arg1.value) + Engine.ExecNow(f1_arg0, "statsetbyname darkops_stalingrad_super_ee " .. f1_arg1.value) + Engine.ExecNow(f1_arg0, "statsetbyname darkops_genesis_ee " .. f1_arg1.value) + Engine.ExecNow(f1_arg0, "statsetbyname DARKOPS_GENESIS_SUPER_EE " .. f1_arg1.value) + end + end + + table.insert(optionsTable, + CoD.OptionsUtility.CreateDvarSettings(controller, "Unlock All Loot", + "Unlocks all Black Market loot.", "MPStatsSettings_unlock_loot", + "cg_unlockall_loot", { + { + option = "MENU_DISABLED", + value = 0, + default = true + }, + { + option = "MENU_ENABLED", + value = 1 + }, + }, nil, updateDvar)) + if Engine.CurrentSessionMode() == Enum.eModes.MODE_MULTIPLAYER then + table.insert(optionsTable, + CoD.OptionsUtility.CreateDvarSettings(controller, "Unlock All Purchases", + "All items that need to be purchased with unlock tokens are unlocked.", "MPStatsSettings_purchase_all", + "cg_unlockall_purchases", { + { + option = "MENU_DISABLED", + value = 0, + default = true + }, + { + option = "MENU_ENABLED", + value = 1 + }, + }, nil, updateDvar)) + table.insert(optionsTable, + CoD.OptionsUtility.CreateDvarSettings(controller, "Unlock All Class Slots", + "Unlocks all create-a-class slots and sets.", "MPStatsSettings_unlockall_cac_slots", + "cg_unlockall_cac_slots", { + { + option = "MENU_DISABLED", + value = 0, + default = true + }, + { + option = "MENU_ENABLED", + value = 1 + }, + }, nil, updateDvar)) + end + table.insert(optionsTable, + CoD.OptionsUtility.CreateDvarSettings(controller, "Unlock All Attachments", + "All attachments on weapons are unlocked.", + "MPStatsSettings_unlockall_attachments", "cg_unlockall_attachments", { + { + option = "MENU_DISABLED", + value = 0, + default = true + }, + { + option = "MENU_ENABLED", + value = 1 + }, + }, nil, updateDvar)) + table.insert(optionsTable, + CoD.OptionsUtility.CreateDvarSettings(controller, "Unlock all Camos and Reticles", + "All camos and reticles on weapons are unlocked.", "MPStatsSettings_unlockall_camos_and_reticles", + "cg_unlockall_camos_and_reticles", { + { + option = "MENU_DISABLED", + value = 0, + default = true + }, + { + option = "MENU_ENABLED", + value = 1 + }, + }, nil, updateDvar)) + table.insert(optionsTable, + CoD.OptionsUtility.CreateDvarSettings(controller, "Unlock all Calling Cards", "All calling cards are unlocked.", + "MPStatsSettings_unlockall_calling_cards", "cg_unlockall_calling_cards", { + { + option = "MENU_DISABLED", + value = 0, + default = true + }, + { + option = "MENU_ENABLED", + value = 1 + }, + }, nil, updateDvar)) + if Engine.CurrentSessionMode() == Enum.eModes.MODE_MULTIPLAYER then + table.insert(optionsTable, + CoD.OptionsUtility.CreateDvarSettings(controller, "Unlock all Specialists Outfits", + "All specialists outfits are unlocked.", "MPStatsSettings_unlockall_specialists_outfits", + "cg_unlockall_specialists_outfits", { + { + option = "MENU_DISABLED", + value = 0, + default = true + }, + { + option = "MENU_ENABLED", + value = 1 + }, + }, nil, updateDvar)) + end + if Engine.CurrentSessionMode() == Enum.eModes.MODE_ZOMBIES then + table.insert(optionsTable, + CoD.OptionsUtility.CreateDvarSettings(controller, "Unlock Easter Eggs", + "Complete all Easter Egg Achievements.", "MPStatsSettings_complete_ee", + "all_ee_completed", { + { + option = "MENU_DISABLED", + value = 0, + default = true + }, + { + option = "MENU_ENABLED", + value = 1 + }, + }, nil, updateDvar)) + end + + local rankLevels = {} + local rankObjs = {} + local hasDefault = true + local currentPrestige = CoD.PrestigeUtility.GetCurrentPLevel(controller, Engine.CurrentSessionMode()) + local currentRank = CoD.BlackMarketUtility.GetCurrentRank(controller) + 1 + + local isMasterPrestige = currentPrestige == 11 + + if Engine.CurrentSessionMode() == Enum.eModes.MODE_MULTIPLAYER then + if not isMasterPrestige then + rankLevels = { 1, 5, 10, 15, 20, 25, 30, 35, 40, 45, 50, 55 } + else + rankLevels = { 56, 100, 200, 300, 400, 500, 600, 700, 800, 900, 1000 } + end + elseif Engine.CurrentSessionMode() == Enum.eModes.MODE_ZOMBIES then + if not isMasterPrestige then + rankLevels = { 1, 5, 10, 15, 20, 25, 30, 35 } + else + rankLevels = { 36, 100, 200, 300, 400, 500, 600, 700, 800, 900, 1000 } + end + end + + local maxlevel = math.max(table.unpack(rankLevels)) + local minlevel = math.min(table.unpack(rankLevels)) + + for index, value in ipairs(rankLevels) do + table.insert(rankObjs, { + name = value <= minlevel and "Min" or value >= maxlevel and "Max" or value, + value = value - 1, + default = value == currentRank, + title = "Rank Level", + desc = value ~= currentRank and "" or "Current Rank" + }) + end + + if hasDefault and currentRank ~= minlevel and currentRank < maxlevel and not isMasterPrestige then + table.insert(rankObjs, { + name = "Current: " .. + tostring(currentRank <= minlevel and "Min" or currentRank >= maxlevel and "Max" or currentRank), + value = currentRank - 1, + default = true, + title = "Rank Level", + desc = "Do not adjust rank" + }) + end + + local prestigeTable = {} + for i = 0, 11 do + table.insert(prestigeTable, { + name = i == 0 and "None" or i == 11 and "Master" or i, + value = i, + default = i == currentPrestige, + title = "Prestige", + desc = "" + }) + end + + local createSettingsDatasource = function(controller, datasourceName, optionsTable, currentValue, loopEdges, action) + if currentValue == nil then + currentValue = 0 + end + DataSources[datasourceName] = DataSourceHelpers.ListSetup(datasourceName, function(f47_arg0) + local f47_local0 = {} + for f47_local4, f47_local5 in ipairs(optionsTable) do + table.insert(f47_local0, { + models = { + text = optionsTable[f47_local4].name + }, + properties = { + title = optionsTable[f47_local4].title, + desc = optionsTable[f47_local4].desc, + image = optionsTable[f47_local4].image, + value = optionsTable[f47_local4].value, + default = optionsTable[f47_local4].default, + action = action, + selectIndex = optionsTable[f47_local4].value == currentValue, + loopEdges = loopEdges, + showChangeIndicator = function(f48_arg0, f48_arg1, f48_arg2) + return f48_arg0.default ~= true + end + } + }) + end + f47_local0[1].properties.first = true + f47_local0[#optionsTable].properties.last = true + return f47_local0 + end, nil, nil, nil) + return datasourceName + end + + table.insert(optionsTable, { + models = { + name = "Prestige", + desc = "", + image = nil, + optionsDatasource = createSettingsDatasource(controller, "MPStatsSettings_rank_prestige", prestigeTable, + CoD.PrestigeUtility.GetCurrentPLevel(controller, Engine.CurrentSessionMode()), false, + function(f1_arg0, f1_arg1, f1_arg2, dvarName, f1_arg4) + UpdateInfoModels(f1_arg1) + local newPrestige = f1_arg1.value + if newPrestige == 11 then + Engine.Exec(f1_arg0, "PrestigeStatsMaster " .. tostring(Engine.CurrentSessionMode())) + end + Engine.ExecNow(f1_arg0, "statsetbyname plevel " .. newPrestige) + Engine.ExecNow(f1_arg0, "statsetbyname hasprestiged " .. (newPrestige > 0 and 1 or 0)) + Engine.Exec(f1_arg0, "uploadstats " .. tostring(Engine.CurrentSessionMode())) + end) + }, + properties = { + revert = function(f50_arg0) + end + } + }) + + table.insert(optionsTable, { + models = { + name = "Rank Level", + desc = "", + image = nil, + optionsDatasource = createSettingsDatasource(controller, "MPStatsSettings_rank_level", rankObjs, + CoD.BlackMarketUtility.GetCurrentRank(controller), false, + function(f1_arg0, f1_arg1, f1_arg2, dvarName, f1_arg4) + UpdateInfoModels(f1_arg1) + local rankTable = nil + local rank = f1_arg1.value + 1 + if currentPrestige <= 10 then + if Engine.CurrentSessionMode() == Enum.eModes.MODE_MULTIPLAYER then + rankTable = "gamedata/tables/mp/mp_ranktable.csv" + elseif Engine.CurrentSessionMode() == Enum.eModes.MODE_ZOMBIES then + rankTable = "gamedata/tables/zm/zm_ranktable.csv" + end + local skipLines = Engine.CurrentSessionMode() == Enum.eModes.MODE_MULTIPLAYER and 3 or 2 + local maxXp = tonumber(Engine.TableLookupGetColumnValueForRow(rankTable, rank - 2 + skipLines, 7)) + if Engine.CurrentSessionMode() == Enum.eModes.MODE_MULTIPLAYER then + if maxXp ~= nil and rank == maxlevel then + maxXp = maxXp + 55600 + end + end + if Engine.CurrentSessionMode() == Enum.eModes.MODE_ZOMBIES then + if maxXp ~= nil and rank == maxlevel then + maxXp = maxXp + 54244 + end + end + if maxXp == nil then + maxXp = 0 + end + Engine.ExecNow(f1_arg0, "statsetbyname rank " .. rank - 1) + Engine.ExecNow(f1_arg0, "statsetbyname rankxp " .. maxXp) + Engine.ExecNow(f1_arg0, "statsetbyname paragon_rankxp " .. 0) + else + if Engine.CurrentSessionMode() == Enum.eModes.MODE_MULTIPLAYER then + rankTable = "gamedata/tables/mp/mp_paragonranktable.csv" + elseif Engine.CurrentSessionMode() == Enum.eModes.MODE_ZOMBIES then + rankTable = "gamedata/tables/zm/zm_paragonranktable.csv" + end + local skipLines = 2 + local maxXp = 0 + if Engine.CurrentSessionMode() == Enum.eModes.MODE_MULTIPLAYER then + maxXp = tonumber(Engine.TableLookupGetColumnValueForRow(rankTable, rank - 57 + skipLines, 7)) + if maxXp ~= nil and rank == maxlevel then + maxXp = maxXp + 55600 + end + rank = rank - 55 + end + if Engine.CurrentSessionMode() == Enum.eModes.MODE_ZOMBIES then + maxXp = tonumber(Engine.TableLookupGetColumnValueForRow(rankTable, rank - 37 + skipLines, 7)) + if maxXp ~= nil and rank == maxlevel then + maxXp = maxXp + 54244 + end + rank = rank - 35 + end + if maxXp == nil then + maxXp = 0 + end + Engine.ExecNow(f1_arg0, "statsetbyname paragon_rank " .. rank - 1) + Engine.ExecNow(f1_arg0, "statsetbyname paragon_rankxp " .. maxXp) + end + Engine.Exec(f1_arg0, "uploadstats " .. tostring(Engine.CurrentSessionMode())) + + currentRank = rank + end) + }, + properties = { + revert = function(f50_arg0) + end + } + }) + + return optionsTable +end) + +if Dvar.cg_unlockall_loot:get() == true then + Engine.SetDvar("ui_enableAllHeroes", 1) +end + +LUI.createMenu.T7xStatsMenu = function(controller) + local self = CoD.Menu.NewForUIEditor("T7xStatsMenu") + if PreLoadFunc then + PreLoadFunc(self, controller) + end + self.soundSet = "ChooseDecal" + self:setOwner(controller) + self:setLeftRight(true, true, 0, 0) + self:setTopBottom(true, true, 0, 0) + self:playSound("menu_open", controller) + self.buttonModel = Engine.CreateModel(Engine.GetModelForController(controller), "T7xStatsMenu.buttonPrompts") + self.anyChildUsesUpdateState = true + + local GameSettingsBackground = CoD.GameSettings_Background.new(self, controller) + GameSettingsBackground:setLeftRight(true, true, 0, 0) + GameSettingsBackground:setTopBottom(true, true, 0, 0) + GameSettingsBackground.MenuFrame.titleLabel:setText(Engine.Localize("STATS SETTINGS")) + GameSettingsBackground.MenuFrame.cac3dTitleIntermediary0.FE3dTitleContainer0.MenuTitle.TextBox1.Label0:setText( + Engine.Localize("STATS SETTINGS")) + GameSettingsBackground.GameSettingsSelectedItemInfo.GameModeInfo:setAlpha(0) + GameSettingsBackground.GameSettingsSelectedItemInfo.GameModeName:setAlpha(0) + self:addElement(GameSettingsBackground) + self.GameSettingsBackground = GameSettingsBackground + + local Options = CoD.Competitive_SettingsList.new(self, controller) + Options:setLeftRight(true, false, 26, 741) + Options:setTopBottom(true, false, 135, 720) + Options.Title.DescTitle:setText(Engine.Localize("Stats")) + Options.ButtonList:setVerticalCount(15) + Options.ButtonList:setDataSource("MPStatsSettings") + self:addElement(Options) + self.Options = Options + + self:AddButtonCallbackFunction(self, controller, Enum.LUIButton.LUI_KEY_XBB_PSCIRCLE, nil, + function(element, menu, controller, model) + GoBack(self, controller) + SetPerControllerTableProperty(controller, "disableGameSettingsOptions", nil) + return true + end, function(element, menu, controller) + CoD.Menu.SetButtonLabel(menu, Enum.LUIButton.LUI_KEY_XBB_PSCIRCLE, "MENU_BACK") + return true + end, false) + + GameSettingsBackground.MenuFrame:setModel(self.buttonModel, controller) + Options.id = "Options" + + self:processEvent({ + name = "menu_loaded", + controller = controller + }) + self:processEvent({ + name = "update_state", + menu = self + }) + if not self:restoreState() then + self.Options:processEvent({ + name = "gain_focus", + controller = controller + }) + end + + LUI.OverrideFunction_CallOriginalSecond(self, "close", function(element) + element.GameSettingsBackground:close() + element.Options:close() + Engine.UnsubscribeAndFreeModel(Engine.GetModel(Engine.GetModelForController(controller), + "T7xStatsMenu.buttonPrompts")) + end) + + if PostLoadFunc then + PostLoadFunc(self, controller) + end + + return self +end