├── .gitignore ├── .gitmodules ├── CastingEssentials.sln ├── CastingEssentials ├── CastingEssentials.vcxproj ├── CastingEssentials.vcxproj.filters ├── Controls │ ├── ImageProgressBar.cpp │ ├── ImageProgressBar.h │ ├── StubPanel.cpp │ ├── StubPanel.h │ ├── VariableLabel.cpp │ └── VariableLabel.h ├── Hooking │ ├── BaseGroupHook.h │ ├── GroupClassHook.h │ ├── GroupGlobalHook.h │ ├── GroupGlobalVirtualHook.h │ ├── GroupManualClassHook.h │ ├── GroupVirtualHook.h │ ├── HookShim.h │ ├── IBaseHook.cpp │ ├── IBaseHook.h │ ├── IGroupHook.cpp │ ├── IGroupHook.h │ ├── ModuleSegments.cpp │ ├── ModuleSegments.h │ ├── TemplateFunctions.h │ └── TemplateTypedefs.h ├── Misc │ ├── CCvar.h │ ├── CRefPtrFix.h │ ├── CmdAlias.h │ ├── CommandCallbacks.h │ ├── CvarPusher.h │ ├── DebugOverlay.cpp │ ├── DebugOverlay.h │ ├── Extras │ │ ├── QAngle.h │ │ ├── Quaternion.h │ │ └── VPlane.h │ ├── HLTVCameraHack.h │ ├── Interpolators.h │ ├── MissingDefinitions.cpp │ ├── MissingDefinitions.h │ ├── NatVis │ │ ├── CBaseHandle.natvis │ │ ├── CUtlVector.natvis │ │ ├── ClientClass.natvis │ │ ├── RecvProp.natvis │ │ └── RecvTable.natvis │ ├── OffsetChecking.cpp │ ├── Padding.h │ ├── Polyhook.cpp │ └── SuggestionList.h ├── Modules │ ├── Antifreeze.cpp │ ├── Antifreeze.h │ ├── AutoCameras.cpp │ ├── AutoCameras.h │ ├── Camera │ │ ├── CameraStateCallbacks.cpp │ │ ├── CameraStateCallbacks.h │ │ ├── DeathCamera.cpp │ │ ├── DeathCamera.h │ │ ├── FirstPersonCamera.cpp │ │ ├── FirstPersonCamera.h │ │ ├── HybridPlayerCameraSmooth.cpp │ │ ├── HybridPlayerCameraSmooth.h │ │ ├── ICamera.cpp │ │ ├── ICamera.h │ │ ├── ICameraGroup.h │ │ ├── ICameraSmooth.h │ │ ├── LookatCamera.cpp │ │ ├── LookatCamera.h │ │ ├── OrbitCamera.cpp │ │ ├── OrbitCamera.h │ │ ├── PlayerCameraGroup.cpp │ │ ├── PlayerCameraGroup.h │ │ ├── RoamingCamera.cpp │ │ ├── RoamingCamera.h │ │ ├── SimpleCamera.h │ │ ├── SimpleCameraSmooth.cpp │ │ ├── SimpleCameraSmooth.h │ │ ├── SmoothSettings.h │ │ ├── TPLockCamera.cpp │ │ └── TPLockCamera.h │ ├── CameraAutoSwitch.cpp │ ├── CameraAutoSwitch.h │ ├── CameraSmooths.cpp │ ├── CameraSmooths.h │ ├── CameraState.cpp │ ├── CameraState.h │ ├── CameraTools.cpp │ ├── CameraTools.h │ ├── ClientTools.cpp │ ├── ClientTools.h │ ├── ConsoleTools.cpp │ ├── ConsoleTools.h │ ├── ExternalMinimap.cpp │ ├── ExternalMinimap.h │ ├── FreezeInfo.cpp │ ├── FreezeInfo.h │ ├── Graphics.cpp │ ├── Graphics.h │ ├── HUDHacking.cpp │ ├── HUDHacking.h │ ├── HitEvents.cpp │ ├── HitEvents.h │ ├── IngameTeamScores.cpp │ ├── IngameTeamScores.h │ ├── ItemSchema.cpp │ ├── ItemSchema.h │ ├── Killfeed.cpp │ ├── Killfeed.h │ ├── Killstreaks.cpp │ ├── Killstreaks.h │ ├── LoadoutIcons.cpp │ ├── LoadoutIcons.h │ ├── LocalPlayer.cpp │ ├── LocalPlayer.h │ ├── MapConfigs.cpp │ ├── MapConfigs.h │ ├── MedigunInfo.cpp │ ├── MedigunInfo.h │ ├── PlayerAliases.cpp │ ├── PlayerAliases.h │ ├── ProjectileOutlines.cpp │ ├── ProjectileOutlines.h │ ├── SniperLOS.cpp │ ├── SniperLOS.h │ ├── SrcTVPlus.cpp │ ├── SrcTVPlus.h │ ├── SteamTools.cpp │ ├── SteamTools.h │ ├── TeamNames.cpp │ ├── TeamNames.h │ ├── TextureTools.cpp │ ├── TextureTools.h │ ├── ViewAngles.cpp │ ├── ViewAngles.h │ ├── WeaponTools.cpp │ └── WeaponTools.h ├── PluginBase │ ├── CastingPlugin.cpp │ ├── Common.cpp │ ├── Common.h │ ├── Entities.cpp │ ├── Entities.h │ ├── EntityOffset.h │ ├── EntityOffsetIterator.h │ ├── Exceptions.cpp │ ├── Exceptions.h │ ├── Hook.h │ ├── HookDefinitions.h │ ├── HookManager.cpp │ ├── HookManager.h │ ├── Interfaces.cpp │ ├── Interfaces.h │ ├── Modules.cpp │ ├── Modules.h │ ├── Player.cpp │ ├── Player.h │ ├── PlayerStateBase.cpp │ ├── PlayerStateBase.h │ ├── Plugin.h │ ├── TFDefinitions.h │ ├── TFPlayerResource.cpp │ ├── TFPlayerResource.h │ ├── TFTeamResource.cpp │ ├── TFTeamResource.h │ └── VariablePusher.h └── Properties │ └── Shared.props ├── README.md ├── flythroughs_config.txt ├── license.md ├── plugin_folder ├── addons │ └── CastingEssentials.vdf ├── do not extract into your TF folder. PLEASE ├── materials │ ├── castingessentials │ │ ├── chargebars │ │ │ ├── baby_face_blue.vmt │ │ │ ├── baby_face_red.vmt │ │ │ ├── banana_blue.vmt │ │ │ ├── banana_red.vmt │ │ │ ├── banner_battalions_blue.vmt │ │ │ ├── banner_battalions_red.vmt │ │ │ ├── banner_buff_blue.vmt │ │ │ ├── banner_buff_red.vmt │ │ │ ├── banner_conch_blue.vmt │ │ │ ├── banner_conch_red.vmt │ │ │ ├── bonk_blue.vmt │ │ │ ├── bonk_red.vmt │ │ │ ├── cleaners_carbine_blue.vmt │ │ │ ├── cleaners_carbine_red.vmt │ │ │ ├── cleaver_blue.vmt │ │ │ ├── cleaver_red.vmt │ │ │ ├── cloak_and_dagger_blue.vmt │ │ │ ├── cloak_and_dagger_red.vmt │ │ │ ├── crit_cola_blue.vmt │ │ │ ├── crit_cola_red.vmt │ │ │ ├── dalokohs_blue.vmt │ │ │ ├── dalokohs_red.vmt │ │ │ ├── dead_ringer_blue.vmt │ │ │ ├── dead_ringer_red.vmt │ │ │ ├── gas_passer_blue.vmt │ │ │ ├── gas_passer_red.vmt │ │ │ ├── hitmans_heatmaker_blue.vmt │ │ │ ├── hitmans_heatmaker_red.vmt │ │ │ ├── invis_watch_blue.vmt │ │ │ ├── invis_watch_red.vmt │ │ │ ├── jarate_blue.vmt │ │ │ ├── jarate_red.vmt │ │ │ ├── jetpack_blue.vmt │ │ │ ├── jetpack_red.vmt │ │ │ ├── medigun_kritz_blue.vmt │ │ │ ├── medigun_kritz_red.vmt │ │ │ ├── medigun_quickfix_blue.vmt │ │ │ ├── medigun_quickfix_red.vmt │ │ │ ├── medigun_uber_blue.vmt │ │ │ ├── medigun_uber_red.vmt │ │ │ ├── medigun_vaccinator_blue_bullet.vmt │ │ │ ├── medigun_vaccinator_blue_explosive.vmt │ │ │ ├── medigun_vaccinator_blue_fire.vmt │ │ │ ├── medigun_vaccinator_red_bullet.vmt │ │ │ ├── medigun_vaccinator_red_explosive.vmt │ │ │ ├── medigun_vaccinator_red_fire.vmt │ │ │ ├── milk_blue.vmt │ │ │ ├── milk_red.vmt │ │ │ ├── phlog_blue.vmt │ │ │ ├── phlog_red.vmt │ │ │ ├── razorback_blue.vmt │ │ │ ├── razorback_red.vmt │ │ │ ├── sandman_blue.vmt │ │ │ ├── sandman_red.vmt │ │ │ ├── sandvich_blue.vmt │ │ │ ├── sandvich_red.vmt │ │ │ ├── shield_splendid_blue.vmt │ │ │ ├── shield_splendid_red.vmt │ │ │ ├── shield_targe_blue.vmt │ │ │ ├── shield_targe_red.vmt │ │ │ ├── shield_tide_blue.vmt │ │ │ ├── shield_tide_red.vmt │ │ │ ├── soda_popper_blue.vmt │ │ │ ├── soda_popper_red.vmt │ │ │ ├── spycicle_blue.vmt │ │ │ ├── spycicle_red.vmt │ │ │ ├── steak_sandvich_blue.vmt │ │ │ ├── steak_sandvich_red.vmt │ │ │ ├── wrap_assassin_blue.vmt │ │ │ └── wrap_assassin_red.vmt │ │ ├── fxaa │ │ │ ├── fxaa.vmt │ │ │ └── luma_to_alpha.vmt │ │ ├── outlines │ │ │ ├── backbuffer_reload_from_fb1.vmt │ │ │ ├── color_override_material.vmt │ │ │ ├── direct_copy.vmt │ │ │ ├── final_blend.vmt │ │ │ ├── l4d_ce_blur_x.vmt │ │ │ ├── l4d_ce_blur_y.vmt │ │ │ ├── l4d_ce_downsample4x.vmt │ │ │ └── poisson_outline.vmt │ │ ├── sniperlos │ │ │ └── beam.vmt │ │ └── statuseffects │ │ │ ├── battalions_backup_blue.vmt │ │ │ ├── battalions_backup_red.vmt │ │ │ ├── bleeding_blue.vmt │ │ │ ├── bleeding_red.vmt │ │ │ ├── buff_banner_blue.vmt │ │ │ ├── buff_banner_red.vmt │ │ │ ├── concheror_blue.vmt │ │ │ ├── concheror_red.vmt │ │ │ ├── kritzkrieged_blue.vmt │ │ │ ├── kritzkrieged_red.vmt │ │ │ ├── marked_for_death_blue.vmt │ │ │ ├── marked_for_death_red.vmt │ │ │ ├── quickfixed_blue.vmt │ │ │ ├── quickfixed_red.vmt │ │ │ ├── ubered_blue.vmt │ │ │ ├── ubered_red.vmt │ │ │ ├── vaccinated_blue_bullet.vmt │ │ │ ├── vaccinated_blue_explosive.vmt │ │ │ ├── vaccinated_blue_fire.vmt │ │ │ ├── vaccinated_red_bullet.vmt │ │ │ ├── vaccinated_red_explosive.vmt │ │ │ └── vaccinated_red_fire.vmt │ ├── debug │ │ ├── debugfbtexture0_transluscent.vmt │ │ ├── debugfbtexture1.vmt │ │ └── debugsmallfbtexture0_translucent.vmt │ └── vgui │ │ └── hud │ │ └── mediguninfo │ │ ├── dead_blue.vmt │ │ ├── dead_red.vmt │ │ ├── kritzkrieg_blue.vmt │ │ ├── kritzkrieg_red.vmt │ │ ├── medigun_blue.vmt │ │ ├── medigun_red.vmt │ │ ├── quickfix_blue.vmt │ │ ├── quickfix_red.vmt │ │ ├── vaccinator_blue_bullet.vmt │ │ ├── vaccinator_blue_explosive.vmt │ │ ├── vaccinator_blue_fire.vmt │ │ ├── vaccinator_red_bullet.vmt │ │ ├── vaccinator_red_explosive.vmt │ │ └── vaccinator_red_fire.vmt ├── put the whole CastingEssentials folder in custom instead ├── resource │ └── ui │ │ └── TeamScorePanel.res ├── scripts │ └── items │ │ └── itemschema_overrides.vdf └── shaders │ └── fxc │ ├── ce_fxaa_ps30.vcs │ ├── ce_luma_to_alpha_ps20.vcs │ ├── ce_luma_to_alpha_ps20b.vcs │ ├── ce_outline_downsample4x_ps20.vcs │ ├── ce_outline_downsample4x_ps20b.vcs │ ├── ce_outline_gaussian_ps20.vcs │ ├── ce_outline_gaussian_ps20b.vcs │ ├── ce_outline_poisson_ps20.vcs │ ├── ce_outline_poisson_ps20b.vcs │ ├── ce_texture_copy_ps20.vcs │ └── ce_texture_copy_ps20b.vcs └── sent_to_valve ├── better_glows.cpp └── spec_steamid.cpp /.gitignore: -------------------------------------------------------------------------------- 1 | # Compiled Object files 2 | *.slo 3 | *.lo 4 | *.o 5 | *.obj 6 | 7 | # Precompiled Headers 8 | *.gch 9 | *.pch 10 | 11 | # Compiled Dynamic libraries 12 | *.so 13 | *.dylib 14 | *.dll 15 | 16 | # Fortran module files 17 | *.mod 18 | *.smod 19 | 20 | # Compiled Static libraries 21 | *.lai 22 | *.la 23 | *.a 24 | *.lib 25 | 26 | # Executables 27 | *.exe 28 | *.out 29 | *.app 30 | *.tlog 31 | 32 | # Performance Profiling 33 | *.psess 34 | *.vspx 35 | 36 | # Other 37 | *.pdb 38 | /Release/ 39 | /Debug/ 40 | *.exp 41 | /CastingEssentials/*/Intermediate 42 | /CastingEssentials/Modules/Graphics_WORKING.zip 43 | /CastingEssentials/Modules/Graphics_borked.zip 44 | /CastingEssentials/Modules/Graphics_all_3_working.zip 45 | .vs/ 46 | plugin_folder/sound/sound.cache 47 | *.ilk 48 | *.vcxproj.user 49 | intermediate/ 50 | -------------------------------------------------------------------------------- /.gitmodules: -------------------------------------------------------------------------------- 1 | [submodule "sdk2013"] 2 | path = sdk2013 3 | url = https://github.com/PazerOP/source-sdk-2013.git 4 | branch = master 5 | [submodule "polyhook"] 6 | path = polyhook 7 | url=https://github.com/PazerOP/PolyHook 8 | branch = master -------------------------------------------------------------------------------- /CastingEssentials.sln: -------------------------------------------------------------------------------- 1 |  2 | Microsoft Visual Studio Solution File, Format Version 12.00 3 | # Visual Studio 15 4 | VisualStudioVersion = 15.0.27130.2026 5 | MinimumVisualStudioVersion = 10.0.40219.1 6 | Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "CastingEssentials", "CastingEssentials\CastingEssentials.vcxproj", "{32223B45-9C65-421A-A318-EB05D25ACA80}" 7 | EndProject 8 | Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "vgui_controls", "sdk2013\mp\src\vgui2\vgui_controls\vgui_controls.vcxproj", "{F69B3672-C5E8-CD1A-257F-253A25B5B939}" 9 | EndProject 10 | Global 11 | GlobalSection(SolutionConfigurationPlatforms) = preSolution 12 | Debug|x86 = Debug|x86 13 | Release|x86 = Release|x86 14 | EndGlobalSection 15 | GlobalSection(ProjectConfigurationPlatforms) = postSolution 16 | {32223B45-9C65-421A-A318-EB05D25ACA80}.Debug|x86.ActiveCfg = Debug|Win32 17 | {32223B45-9C65-421A-A318-EB05D25ACA80}.Debug|x86.Build.0 = Debug|Win32 18 | {32223B45-9C65-421A-A318-EB05D25ACA80}.Release|x86.ActiveCfg = Release|Win32 19 | {32223B45-9C65-421A-A318-EB05D25ACA80}.Release|x86.Build.0 = Release|Win32 20 | {F69B3672-C5E8-CD1A-257F-253A25B5B939}.Debug|x86.ActiveCfg = Debug|Win32 21 | {F69B3672-C5E8-CD1A-257F-253A25B5B939}.Debug|x86.Build.0 = Debug|Win32 22 | {F69B3672-C5E8-CD1A-257F-253A25B5B939}.Release|x86.ActiveCfg = Release|Win32 23 | {F69B3672-C5E8-CD1A-257F-253A25B5B939}.Release|x86.Build.0 = Release|Win32 24 | EndGlobalSection 25 | GlobalSection(SolutionProperties) = preSolution 26 | HideSolutionNode = FALSE 27 | EndGlobalSection 28 | GlobalSection(ExtensibilityGlobals) = postSolution 29 | SolutionGuid = {71446418-19A4-4E02-89F4-7D55BDAF8A3A} 30 | EndGlobalSection 31 | EndGlobal 32 | -------------------------------------------------------------------------------- /CastingEssentials/Controls/ImageProgressBar.h: -------------------------------------------------------------------------------- 1 | // Based on https://developer.valvesoftware.com/wiki/VGUI_Image_Progress_Bar 2 | #pragma once 3 | 4 | #include 5 | #include 6 | 7 | namespace vgui 8 | { 9 | class ImageProgressBar : public ContinuousProgressBar 10 | { 11 | DECLARE_CLASS_SIMPLE(ImageProgressBar, ContinuousProgressBar); 12 | 13 | public: 14 | ImageProgressBar(Panel *parent, const char *panelName); 15 | ImageProgressBar(Panel *parent, const char *panelName, const char *topTexturename, const char *bottomTextureName); 16 | virtual ~ImageProgressBar() { } 17 | 18 | virtual void Paint(void); 19 | virtual void ApplySettings(KeyValues *inResourceData); 20 | virtual void GetSettings(KeyValues *outResourceData); 21 | 22 | void SetTopTexture(const char *topTextureName); 23 | void SetBottomTexture(const char *bottomTextureName); 24 | 25 | private: 26 | int m_iTopTextureId; 27 | int m_iBottomTextureId; 28 | char m_szTopTextureName[64]; 29 | char m_szBottomTextureName[64]; 30 | }; 31 | } 32 | -------------------------------------------------------------------------------- /CastingEssentials/Controls/StubPanel.cpp: -------------------------------------------------------------------------------- 1 | #include "StubPanel.h" 2 | 3 | #include 4 | #include 5 | 6 | using namespace vgui; 7 | 8 | StubPanel::StubPanel() 9 | { 10 | m_VPanel = ivgui()->AllocPanel(); 11 | ipanel()->Init(GetVPanel(), this); 12 | 13 | ivgui()->AddTickSignal(GetVPanel()); 14 | } 15 | 16 | vgui::StubPanel::~StubPanel() 17 | { 18 | ivgui()->RemoveTickSignal(GetVPanel()); 19 | ivgui()->FreePanel(GetVPanel()); 20 | m_VPanel = 0; 21 | } -------------------------------------------------------------------------------- /CastingEssentials/Controls/StubPanel.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | #include 3 | 4 | namespace vgui 5 | { 6 | // A panel whose sole purporse is to hook into OnTick() (once-per-frame) events. 7 | class StubPanel : public IClientPanel 8 | { 9 | public: 10 | StubPanel(); 11 | virtual ~StubPanel(); 12 | 13 | private: 14 | virtual VPANEL GetVPanel() override final { return m_VPanel; } 15 | VPANEL m_VPanel; 16 | 17 | virtual void Think() override final { } 18 | virtual void PerformApplySchemeSettings() override final { } 19 | virtual void PaintTraverse(bool, bool) override final { } 20 | virtual void Repaint() override final { } 21 | virtual VPANEL IsWithinTraverse(int, int, bool) override final { return 0; } 22 | virtual void GetInset(int&, int&, int&, int&) override final { } 23 | virtual void GetClipRect(int&, int&, int&, int&) override final { } 24 | virtual void OnChildAdded(VPANEL) override final { } 25 | virtual void OnSizeChanged(int, int) override final { } 26 | 27 | virtual void InternalFocusChanged(bool) override final { } 28 | virtual bool RequestInfo(KeyValues*) override final { return false; } 29 | virtual void RequestFocus(int) override final { } 30 | virtual bool RequestFocusPrev(VPANEL) override final { return false; } 31 | virtual bool RequestFocusNext(VPANEL) override final { return false; } 32 | virtual void OnMessage(const KeyValues*, VPANEL) override final { } 33 | virtual VPANEL GetCurrentKeyFocus() override final { return 0; } 34 | virtual int GetTabPosition() override final { return 0; } 35 | 36 | virtual const char* GetName() override final { return "CastingEssentialsStubPanel"; } 37 | virtual const char* GetClassName() override final { return "vgui::CastingEssentialsStubPanel"; } 38 | 39 | virtual HScheme GetScheme() override final { return 0; } 40 | virtual bool IsProportional() override final { return false; } 41 | virtual bool IsAutoDeleteSet() override final { return false; } 42 | virtual void DeletePanel() override final { delete this; } 43 | 44 | virtual void* QueryInterface(EInterfaceID) override final { return nullptr; } 45 | 46 | virtual Panel* GetPanel() override final { return nullptr; } 47 | 48 | virtual const char* GetModuleName() override final { return "CastingEssentials"; } 49 | }; 50 | } -------------------------------------------------------------------------------- /CastingEssentials/Controls/VariableLabel.cpp: -------------------------------------------------------------------------------- 1 | #include "VariableLabel.h" 2 | 3 | #include 4 | #include 5 | 6 | inline void FindAndReplaceInString(std::string &str, const std::string &find, const std::string &replace) 7 | { 8 | if (find.empty()) 9 | return; 10 | 11 | const char* findstr = find.c_str(); 12 | const char* found = nullptr; 13 | const char* base = str.c_str(); 14 | 15 | while ((found = stristr(base, findstr)) != nullptr) 16 | { 17 | const auto offset = found - base; 18 | str.replace(offset, find.length(), replace); 19 | base = str.c_str() + offset + find.length(); // In case we get reallocated 20 | } 21 | } 22 | 23 | using namespace vgui; 24 | 25 | DECLARE_BUILD_FACTORY_DEFAULT_TEXT(VariableLabel, VariableLabel); 26 | 27 | VariableLabel::VariableLabel(Panel *parent, const char *panelName, const char *labelText) : BaseClass(parent, panelName, labelText) 28 | { 29 | m_sLabelText = labelText; 30 | } 31 | 32 | void VariableLabel::ApplySettings(KeyValues *inResourceData) 33 | { 34 | m_sLabelText = inResourceData->GetString("labelText"); 35 | 36 | BaseClass::ApplySettings(inResourceData); 37 | } 38 | 39 | void VariableLabel::GetSettings(KeyValues *outResourceData) 40 | { 41 | BaseClass::GetSettings(outResourceData); 42 | 43 | outResourceData->SetString("labelText", m_sLabelText.c_str()); 44 | } 45 | 46 | void VariableLabel::OnDialogVariablesChanged(KeyValues *dialogVariables) 47 | { 48 | std::string text = m_sLabelText; 49 | 50 | FOR_EACH_VALUE(dialogVariables, variable) 51 | { 52 | std::string find = "%"; 53 | find.append(variable->GetName()); 54 | find.append("%"); 55 | 56 | std::string replace = variable->GetString(); 57 | 58 | FindAndReplaceInString(text, find, replace); 59 | } 60 | 61 | SetText(text.c_str()); 62 | } -------------------------------------------------------------------------------- /CastingEssentials/Controls/VariableLabel.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include 4 | #include 5 | #include 6 | 7 | namespace vgui 8 | { 9 | class VariableLabel : public Label 10 | { 11 | DECLARE_CLASS_SIMPLE(VariableLabel, Label); 12 | 13 | public: 14 | VariableLabel(Panel *parent, const char *panelName, const char *labelText); 15 | virtual ~VariableLabel() { } 16 | 17 | virtual void ApplySettings(KeyValues *inResourceData); 18 | virtual void GetSettings(KeyValues *outResourceData); 19 | 20 | protected: 21 | MESSAGE_FUNC_PARAMS(OnDialogVariablesChanged, "DialogVariables", dialogVariables); 22 | 23 | private: 24 | std::string m_sLabelText; 25 | }; 26 | } -------------------------------------------------------------------------------- /CastingEssentials/Hooking/HookShim.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | #include "Hooking/BaseGroupHook.h" 3 | 4 | class HookManager; 5 | namespace Hooking 6 | { 7 | enum ShimType; 8 | template class HookShim final : 9 | public BaseGroupHook 10 | { 11 | friend class ::HookManager; 12 | 13 | public: 14 | using Functional = typename HookType::Functional; 15 | 16 | ~HookShim() 17 | { 18 | if (m_InnerHook) 19 | DetachHook(); 20 | 21 | m_HooksTable.clear(); 22 | } 23 | 24 | Functional GetOriginal() override { return m_InnerHook->GetOriginal(); } 25 | Hooking::HookType GetType() const override { return m_InnerHook->GetType(); } 26 | 27 | int AddHook(const Functional& newHook) override 28 | { 29 | const auto retVal = BaseGroupHookType::AddHook(newHook); 30 | AddInnerHook(retVal, newHook); 31 | return retVal; 32 | } 33 | bool RemoveHook(int hookID, const char* funcName) override 34 | { 35 | bool retVal = BaseGroupHookType::RemoveHook(hookID, funcName); 36 | RemoveInnerHook(hookID, funcName); 37 | return retVal; 38 | } 39 | 40 | void SetState(Hooking::HookAction action) override { Assert(m_InnerHook); m_InnerHook->SetState(action); } 41 | 42 | void InitHook() override {} 43 | int GetUniqueHookID() const { return (int)HOOK_ID; } 44 | 45 | typedef HookType Inner; 46 | void AttachHook(const std::shared_ptr& innerHook) 47 | { 48 | Assert(!m_InnerHook); 49 | 50 | std::lock_guard lock(m_Mutex); 51 | m_InnerHook = innerHook; 52 | 53 | std::lock_guard hooksTableLock(m_HooksTableMutex); 54 | for (auto hooks : m_HooksTable) 55 | AddInnerHook(hooks.first, hooks.second); 56 | } 57 | 58 | private: 59 | void DetachHook() 60 | { 61 | Assert(m_InnerHook); 62 | 63 | std::lock_guard lock(m_Mutex); 64 | for (auto hookID : m_ActiveHooks) 65 | m_InnerHook->RemoveHook(hookID.second, __FUNCSIG__); 66 | 67 | m_ActiveHooks.clear(); 68 | m_InnerHook.reset(); 69 | } 70 | 71 | void AddInnerHook(uint64 fakeHookID, const Functional& newHook) 72 | { 73 | std::lock_guard lock(m_Mutex); 74 | if (m_InnerHook) 75 | { 76 | const auto current = m_InnerHook->AddHook(newHook); 77 | m_ActiveHooks.insert(std::make_pair(fakeHookID, current)); 78 | } 79 | } 80 | void RemoveInnerHook(uint64 hookID, const char* funcName) 81 | { 82 | std::lock_guard lock(m_Mutex); 83 | if (m_InnerHook) 84 | { 85 | const auto& link = m_ActiveHooks.find(hookID); 86 | if (link != m_ActiveHooks.end()) 87 | { 88 | m_InnerHook->RemoveHook(link->second, funcName); 89 | m_ActiveHooks.erase(link); 90 | } 91 | } 92 | } 93 | 94 | std::recursive_mutex m_Mutex; 95 | 96 | std::shared_ptr m_InnerHook; 97 | std::map m_ActiveHooks; 98 | }; 99 | } -------------------------------------------------------------------------------- /CastingEssentials/Hooking/IBaseHook.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | #include 3 | 4 | namespace Hooking 5 | { 6 | class IBaseHook 7 | { 8 | public: 9 | virtual ~IBaseHook() = default; 10 | 11 | virtual bool Hook() = 0; 12 | virtual bool Unhook() = 0; 13 | 14 | virtual void* GetOriginalFunction() const = 0; 15 | }; 16 | 17 | extern std::shared_ptr CreateVTableSwapHook(void* instance, void* detourFunc, int vTableIndex); 18 | extern std::shared_ptr CreateVFuncSwapHook(void* instance, void* detourFunc, int vTableIndex); 19 | extern std::shared_ptr CreateDetour(void* func, void* detourFunc); 20 | 21 | namespace Internal 22 | { 23 | extern constexpr int MFI_GetVTblOffset(void* mfp); 24 | } 25 | template static int VTableOffset(F func) 26 | { 27 | static_assert(std::is_member_function_pointer_v); 28 | 29 | union 30 | { 31 | F p; 32 | intptr_t i; 33 | }; 34 | 35 | p = func; 36 | 37 | return Internal::MFI_GetVTblOffset((void*)i); 38 | } 39 | } 40 | -------------------------------------------------------------------------------- /CastingEssentials/Hooking/IGroupHook.cpp: -------------------------------------------------------------------------------- 1 | #include "IGroupHook.h" 2 | #include 3 | 4 | using namespace Hooking; 5 | 6 | std::atomic IGroupHook::s_LastHook; 7 | 8 | #if 0 9 | void* IGroupHook::GetOriginalRawFn(const std::shared_ptr& hook) 10 | { 11 | switch (hook->GetType()) 12 | { 13 | case PLH::HookType::VFuncSwap: 14 | return assert_cast(hook.get())->GetOriginal(); 15 | 16 | case PLH::HookType::X86Detour: 17 | return assert_cast(hook.get())->GetOriginal(); 18 | } 19 | 20 | Assert(!"Invalid hook type!"); 21 | return nullptr; 22 | } 23 | 24 | std::shared_ptr IGroupHook::SetupVFuncHook(void** instance, int vtableOffset, void* detourFunc) 25 | { 26 | if (vtableOffset < 0) 27 | return nullptr; 28 | 29 | PLH::VFuncSwap* newHook = new PLH::VFuncSwap(); 30 | newHook->SetupHook((BYTE**)instance, vtableOffset, (BYTE*)detourFunc); 31 | 32 | if (!newHook->Hook()) 33 | { 34 | Assert(0); 35 | delete newHook; 36 | return nullptr; 37 | } 38 | 39 | return std::shared_ptr(newHook); 40 | } 41 | 42 | std::shared_ptr IGroupHook::SetupDetour(BYTE* baseFunc, BYTE* detourFunc) 43 | { 44 | PLH::Detour* newHook = new PLH::Detour(); 45 | newHook->SetupHook(baseFunc, detourFunc); 46 | if (!newHook->Hook()) 47 | { 48 | Assert(0); 49 | delete newHook; 50 | return nullptr; 51 | } 52 | 53 | return std::shared_ptr(newHook); 54 | } 55 | #endif -------------------------------------------------------------------------------- /CastingEssentials/Hooking/IGroupHook.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | #include 3 | #include 4 | #include 5 | #include 6 | #include "IBaseHook.h" 7 | 8 | // Badly-named macros smh 9 | #undef IGNORE 10 | 11 | namespace Hooking 12 | { 13 | enum class HookAction 14 | { 15 | // Call the original function and use its return value. 16 | // Continue calling all the remaining hooks. 17 | IGNORE, 18 | 19 | // Use our return value instead of the original function. 20 | // Don't call the original function. 21 | // Continue calling all the remaining hooks. 22 | SUPERCEDE, 23 | }; 24 | 25 | enum class HookType 26 | { 27 | // Detours a global function. 28 | Global, 29 | 30 | // Detours a member function of a class. Applies to all instances, but passes the class 31 | // pointer through to the detour function. 32 | GlobalClass, 33 | 34 | // Detours a member function of a class. Applies to all instances. 35 | Class, 36 | 37 | // Detours a specific instance of a class (replaces a function pointer in a duplicated vtable). 38 | Virtual, 39 | 40 | // Detours all instances of a class (replaces a function pointer in the global vtable). 41 | VirtualGlobal, 42 | }; 43 | 44 | class IGroupHook 45 | { 46 | public: 47 | virtual ~IGroupHook() { } 48 | 49 | virtual void SetState(HookAction action) = 0; 50 | virtual bool IsInHook() const = 0; 51 | 52 | virtual bool RemoveHook(int hookID, const char* funcName) = 0; 53 | 54 | virtual void InitHook() = 0; 55 | 56 | virtual HookType GetType() const = 0; 57 | virtual int GetUniqueHookID() const = 0; 58 | 59 | protected: 60 | static std::atomic s_LastHook; 61 | 62 | std::recursive_mutex m_BaseHookMutex; 63 | std::shared_ptr m_BaseHook; 64 | }; 65 | } -------------------------------------------------------------------------------- /CastingEssentials/Hooking/ModuleSegments.cpp: -------------------------------------------------------------------------------- 1 | #include "ModuleSegments.h" 2 | 3 | #include 4 | #include 5 | 6 | void* Hooking::GetModuleSection(HMODULE module, const char* sectionName) 7 | { 8 | IMAGE_NT_HEADERS* ntHeader = ImageNtHeader(module); 9 | 10 | IMAGE_SECTION_HEADER* sectionHeaderBase = (IMAGE_SECTION_HEADER*)(ntHeader + 1); 11 | 12 | for (int i = 0; i < ntHeader->FileHeader.NumberOfSections; i++) 13 | { 14 | IMAGE_SECTION_HEADER& sectionHeader = sectionHeaderBase[i]; 15 | 16 | if (strncmp((const char*)sectionHeader.Name, sectionName, std::size(sectionHeader.Name))) 17 | continue; 18 | 19 | return (void*)((std::byte*)module + sectionHeader.VirtualAddress); 20 | } 21 | 22 | return nullptr; 23 | } 24 | -------------------------------------------------------------------------------- /CastingEssentials/Hooking/ModuleSegments.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include 4 | 5 | namespace Hooking 6 | { 7 | void* GetModuleSection(HMODULE module, const char* sectionName); 8 | } -------------------------------------------------------------------------------- /CastingEssentials/Hooking/TemplateFunctions.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | #include "TemplateTypedefs.h" 3 | 4 | #include 5 | #include 6 | #include 7 | 8 | namespace Hooking{ namespace Internal 9 | { 10 | template static OutType evil_cast(InType input) 11 | { 12 | static_assert(std::is_pointer::value, "InType must be a pointer type!"); 13 | static_assert(std::is_pointer::value, "OutType must be a pointer type!"); 14 | static_assert(sizeof(InType) == sizeof(OutType), "InType and OutType are not the same size!"); 15 | 16 | // >:( 17 | union 18 | { 19 | InType goodIn; 20 | OutType evilOut; 21 | }; 22 | 23 | goodIn = input; 24 | return evilOut; 25 | } 26 | 27 | template struct ArgType 28 | { 29 | static_assert(!std::is_reference::value); 30 | static_assert(!std::is_const::value); 31 | typedef T type; 32 | }; 33 | template struct ArgType 34 | { 35 | typedef typename std::remove_reference::type* type; 36 | }; 37 | 38 | template 39 | struct Skip2Types 40 | { 41 | typedef First First; 42 | typedef Second Second; 43 | typedef std::tuple Others; 44 | }; 45 | 46 | template 47 | struct Skip2Indices 48 | { 49 | private: 50 | static constexpr size_t Dumb1() { return _First; } 51 | static constexpr size_t Dumb2() { return _Second; } 52 | public: 53 | 54 | static constexpr size_t First = Dumb1(); 55 | static constexpr size_t Second = Dumb2(); 56 | typedef std::index_sequence<_Others...> Others; 57 | }; 58 | } } -------------------------------------------------------------------------------- /CastingEssentials/Hooking/TemplateTypedefs.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | namespace Hooking{ namespace Internal 4 | { 5 | template using MemberFnPtr_Const = RetVal(Type::*)(Args...) const; 6 | template using MemberFnPtr = RetVal(Type::*)(Args...); 7 | template using MemFnVaArgsPtr = RetVal(__cdecl Type::*)(Args..., ...); 8 | template using MemFnVaArgsPtr_Const = RetVal(__cdecl Type::*)(Args..., ...) const; 9 | 10 | // Hard cast from __thiscall to __fastcall, this pointer in ECX, garbage in EDX, arguments on stack 11 | template using LocalDetourFnPtr = RetVal(__fastcall*)(Type*, void*, Args...); 12 | template using GlobalDetourFnPtr = RetVal(*)(Args...); 13 | template using LocalFnPtr = RetVal(__thiscall*)(Type*, Args...); 14 | 15 | template using GlobalVaArgsFnPtr = RetVal(__cdecl*)(Args..., ...); 16 | template using LocalVaArgsFnPtr = RetVal(__cdecl*)(Type*, Args..., ...); 17 | 18 | template using GlobalFunctionalType = std::function; 19 | template using LocalFunctionalType = std::function; 20 | } } -------------------------------------------------------------------------------- /CastingEssentials/Misc/CCvar.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include 4 | 5 | #include 6 | 7 | class CCvar 8 | { 9 | public: 10 | static int GetFlags(const ConCommandBase* base) { return base->m_nFlags; } 11 | static void SetFlags(ConCommandBase* base, int flags) { base->m_nFlags = flags; } 12 | 13 | static void SetMin(ConVar* var, float min) 14 | { 15 | if ((var->m_bHasMin = !std::isnan(min)) == true) 16 | var->m_fMinVal = min; 17 | } 18 | static void SetMax(ConVar* var, float max) 19 | { 20 | if ((var->m_bHasMax = !std::isnan(max)) == true) 21 | var->m_fMaxVal = max; 22 | } 23 | 24 | static std::variant GetDispatchCallback(ConCommand* cmd) 25 | { 26 | if (cmd->m_bUsingNewCommandCallback) 27 | return &cmd->m_fnCommandCallback; 28 | else if (cmd->m_bUsingCommandCallbackInterface) 29 | return &cmd->m_pCommandCallback; 30 | else 31 | return &cmd->m_fnCommandCallbackV1; 32 | } 33 | static std::variant GetCompletionCallback(ConCommand* cmd) 34 | { 35 | if (cmd->m_bUsingCommandCallbackInterface) 36 | return &cmd->m_pCommandCompletionCallback; 37 | else 38 | return &cmd->m_fnCompletionCallback; 39 | } 40 | 41 | static FnChangeCallback_t* GetChangeCallback(ConVar* var) 42 | { 43 | return &var->m_fnChangeCallback; 44 | } 45 | static FnChangeCallback_t* GetChangeCallbackClient(ConVar* var) 46 | { 47 | return &var->m_fnChangeCallbackClient; 48 | } 49 | }; 50 | -------------------------------------------------------------------------------- /CastingEssentials/Misc/CRefPtrFix.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | #include 3 | 4 | // Who designed this reference counting system? 5 | template 6 | class CRefPtrFix : public CRefPtr 7 | { 8 | typedef CRefPtr BaseClass; 9 | 10 | public: 11 | CRefPtrFix() = default; 12 | CRefPtrFix(T* pInit) : BaseClass(InlineAddRef(pInit)) { } 13 | CRefPtrFix(const CRefPtr& from) : BaseClass(InlineAddRef(pInit)) { } 14 | 15 | T* operator=(T* p) { AssignAddRef(p); } 16 | 17 | private: 18 | int operator=(int i) { Assert(!"Terrible design"); return 0; } 19 | }; 20 | 21 | #define CRefPtr CRefPtrFix -------------------------------------------------------------------------------- /CastingEssentials/Misc/CmdAlias.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #define MAX_ALIAS_NAME 32 4 | #define MAX_COMMAND_LENGTH 1024 5 | 6 | struct cmdalias_t 7 | { 8 | cmdalias_t *next; 9 | char name[MAX_ALIAS_NAME]; 10 | char *value; 11 | }; -------------------------------------------------------------------------------- /CastingEssentials/Misc/CommandCallbacks.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | #include "PluginBase/Common.h" 3 | 4 | #include 5 | 6 | #include 7 | 8 | class CommandCallbacks : ICommandCallback, ICommandCompletionCallback 9 | { 10 | public: 11 | CommandCallbacks(std::function&& dispatch) : 12 | m_Dispatch(std::move(dispatch)) 13 | { 14 | } 15 | CommandCallbacks(std::function&& dispatch, 16 | std::function& suggestions)>&& autocomplete) : 17 | m_Dispatch(std::move(dispatch)), m_Autocomplete(std::move(autocomplete)) 18 | { 19 | } 20 | 21 | operator ICommandCallback*() { return this; } 22 | operator ICommandCompletionCallback*() { return m_Autocomplete ? this : nullptr; } 23 | 24 | private: 25 | void CommandCallback(const CCommand& cmd) override final 26 | { 27 | m_Dispatch(cmd); 28 | } 29 | int CommandCompletionCallback(const char* partial, CUtlVector& suggestions) override final 30 | { 31 | CCommand cmd; 32 | cmd.Tokenize(partial); 33 | m_Autocomplete(cmd, suggestions); 34 | Assert(suggestions.Count() <= COMMAND_COMPLETION_MAXITEMS); 35 | return suggestions.Count(); 36 | } 37 | 38 | std::function m_Dispatch; 39 | std::function& suggestions)> m_Autocomplete; 40 | }; -------------------------------------------------------------------------------- /CastingEssentials/Misc/CvarPusher.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include 4 | 5 | class CvarPusher 6 | { 7 | public: 8 | CvarPusher(const char* name, const char* newValue) : m_Var(name) { Push(newValue); } 9 | CvarPusher(const char* name, bool newValue) : m_Var(name) { Push(newValue ? "1" : "0"); } 10 | CvarPusher(const char* name, float newValue) : m_Var(name) 11 | { 12 | char buf[32]; 13 | sprintf_s(buf, "%f", newValue); 14 | Push(buf); 15 | } 16 | CvarPusher(const char* name, int newValue) : m_Var(name) 17 | { 18 | char buf[32]; 19 | sprintf_s(buf, "%i", newValue); 20 | Push(buf); 21 | } 22 | ~CvarPusher() 23 | { 24 | if (m_OldString) // If we don't have this, we are already clear 25 | m_Var.SetValue(m_OldString.get()); 26 | } 27 | 28 | CvarPusher(const CvarPusher&) = delete; 29 | CvarPusher& operator=(const CvarPusher&) = delete; 30 | 31 | void Clear() { m_OldString.reset(); } 32 | 33 | const char* GetName() const { Assert(m_OldString); return m_Var.GetName(); } 34 | 35 | const char* GetOldString() const { Assert(m_OldString); return m_OldString.get(); } 36 | float GetOldFloat() const { Assert(m_OldString); return atof(m_OldString.get()); } 37 | int GetOldInt() const { Assert(m_OldString); return atoi(m_OldString.get()); } 38 | bool GetOldBool() const { Assert(m_OldString); return !(m_OldString[0] == '0' && m_OldString[1] == '\0'); } 39 | 40 | private: 41 | void Push(const char* newValue) 42 | { 43 | auto oldLen = strlen(m_Var.GetString()); 44 | m_OldString = std::make_unique(oldLen); 45 | memcpy(m_OldString.get(), m_Var.GetString(), oldLen); 46 | m_OldString[oldLen] = '\0'; 47 | } 48 | 49 | ConVarRef m_Var; 50 | std::unique_ptr m_OldString; 51 | }; 52 | -------------------------------------------------------------------------------- /CastingEssentials/Misc/DebugOverlay.cpp: -------------------------------------------------------------------------------- 1 | #include "PluginBase/HookManager.h" 2 | 3 | #include 4 | #include 5 | 6 | void NDebugOverlay::Cross3D(const Vector &position, float size, int r, int g, int b, bool noDepthTest, float flDuration) 7 | { 8 | Line(position + Vector(size, 0, 0), position - Vector(size, 0, 0), r, g, b, noDepthTest, flDuration); 9 | Line(position + Vector(0, size, 0), position - Vector(0, size, 0), r, g, b, noDepthTest, flDuration); 10 | Line(position + Vector(0, 0, size), position - Vector(0, 0, size), r, g, b, noDepthTest, flDuration); 11 | } 12 | 13 | void NDebugOverlay::Line(const Vector &origin, const Vector &target, int r, int g, int b, bool noDepthTest, float duration) 14 | { 15 | #ifdef NDEBUG_PER_FRAME_SUPPORT 16 | if (duration == NDEBUG_PERSIST_TILL_NEXT_FRAME) 17 | { 18 | HookManager::GetRawFunc_RenderLine()(origin, target, Color(r, g, b), !noDepthTest); 19 | } 20 | else 21 | #endif 22 | { 23 | debugoverlay->AddLineOverlay(origin, target, r, g, b, noDepthTest, duration); 24 | } 25 | } 26 | 27 | void NDebugOverlay::Box(const Vector &origin, const Vector &mins, const Vector &maxs, int r, int g, int b, int a, float flDuration) 28 | { 29 | BoxAngles(origin, mins, maxs, vec3_angle, r, g, b, a, flDuration); 30 | } 31 | 32 | void NDebugOverlay::BoxAngles(const Vector &origin, const Vector &mins, const Vector &maxs, const QAngle &angles, int r, int g, int b, int a, float duration) 33 | { 34 | #ifdef NDEBUG_PER_FRAME_SUPPORT 35 | if (duration == NDEBUG_PERSIST_TILL_NEXT_FRAME) 36 | { 37 | if (a > 0) 38 | HookManager::GetRawFunc_RenderBox()(origin, angles, mins, maxs, Color(r, g, b, a), false, false); 39 | 40 | HookManager::GetRawFunc_RenderWireframeBox()(origin, angles, mins, maxs, Color(r, g, b, 255), true); 41 | } 42 | else 43 | #endif 44 | { 45 | debugoverlay->AddBoxOverlay(origin, mins, maxs, angles, r, g, b, a, duration); 46 | } 47 | } 48 | 49 | void NDebugOverlay::Text(const Vector& origin, const char* text, bool bViewCheck, float duration) 50 | { 51 | debugoverlay->AddTextOverlay(origin, duration, "%s", text); 52 | } 53 | 54 | void NDebugOverlay::Triangle(const Vector& p1, const Vector& p2, const Vector& p3, int r, int g, int b, int a, bool noDepthTest, float duration) 55 | { 56 | #ifdef NDEBUG_PER_FRAME_SUPPORT 57 | if (duration == NDEBUG_PERSIST_TILL_NEXT_FRAME) 58 | { 59 | HookManager::GetRawFunc_RenderTriangle()(p1, p2, p3, Color(r, g, b, a), !noDepthTest); 60 | } 61 | else 62 | #endif 63 | { 64 | debugoverlay->AddTriangleOverlay(p1, p2, p3, r, g, b, a, noDepthTest, duration); 65 | } 66 | } 67 | 68 | void NDebugOverlay::Cross3DOriented(const Vector& position, const QAngle& angles, float size, int r, int g, int b, bool noDepthTest, float flDuration) 69 | { 70 | Vector forward, right, up; 71 | AngleVectors(angles, &forward, &right, &up); 72 | 73 | forward *= size; 74 | right *= size; 75 | up *= size; 76 | 77 | Line(position + right, position - right, r, g, b, noDepthTest, flDuration); 78 | Line(position + forward, position - forward, r, g, b, noDepthTest, flDuration); 79 | Line(position + up, position - up, r, g, b, noDepthTest, flDuration); 80 | } 81 | 82 | void NDebugOverlay::EntityText(int entityID, int text_offset, const char *text, float duration, int r, int g, int b, int a) 83 | { 84 | debugoverlay->AddEntityTextOverlay(entityID, text_offset, duration, 85 | (int)clamp(r * 255.f, 0.f, 255.f), (int)clamp(g * 255.f, 0.f, 255.f), (int)clamp(b * 255.f, 0.f, 255.f), 86 | (int)clamp(a * 255.f, 0.f, 255.f), text); 87 | } -------------------------------------------------------------------------------- /CastingEssentials/Misc/DebugOverlay.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | #include 3 | 4 | namespace NDebugOverlay 5 | { 6 | inline void TriangleIgnoreZ(const Vector& p1, const Vector& p2, const Vector& p3, int r, int g, int b, int a, bool noDepthTest, float duration) 7 | { 8 | NDebugOverlay::Triangle(p1, p2, p3, r, g, b, a, noDepthTest, duration); 9 | NDebugOverlay::Triangle(p1, p3, p2, r, g, b, a, noDepthTest, duration); 10 | } 11 | } -------------------------------------------------------------------------------- /CastingEssentials/Misc/Extras/QAngle.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include 4 | 5 | inline QAngle AngleNormalize(const QAngle& q1) 6 | { 7 | return QAngle(AngleNormalize(q1.x), AngleNormalize(q1.y), AngleNormalize(q1.z)); 8 | } 9 | inline QAngle AngleNormalizePositive(const QAngle& q1) 10 | { 11 | return QAngle(AngleNormalizePositive(q1.x), AngleNormalizePositive(q1.y), AngleNormalizePositive(q1.z)); 12 | } 13 | -------------------------------------------------------------------------------- /CastingEssentials/Misc/Extras/Quaternion.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include 4 | 5 | inline Quaternion operator+(const Quaternion& p, const Quaternion& q) 6 | { 7 | Quaternion retVal; 8 | QuaternionAdd(p, q, retVal); 9 | return retVal; 10 | } 11 | inline Quaternion operator-(const Quaternion& p) 12 | { 13 | return Quaternion(-p.x, -p.y, -p.z, -p.w); 14 | } 15 | inline Quaternion& operator+=(Quaternion& p, const Quaternion& q) 16 | { 17 | QuaternionAdd(p, q, p); 18 | return p; 19 | } 20 | inline Quaternion operator*(const Quaternion& a, const Quaternion& b) 21 | { 22 | Quaternion temp; 23 | QuaternionMult(a, b, temp); 24 | return temp; 25 | } 26 | inline Quaternion operator*(const Quaternion& a, float scalar) 27 | { 28 | Quaternion temp; 29 | QuaternionScale(a, scalar, temp); 30 | return temp; 31 | } 32 | inline Quaternion& operator*=(Quaternion& a, const Quaternion& b) 33 | { 34 | QuaternionMult(Quaternion(a), b, a); 35 | return a; 36 | } 37 | inline Quaternion& operator*=(Quaternion& p, float scalar) 38 | { 39 | QuaternionScale(p, scalar, p); 40 | return p; 41 | } 42 | 43 | inline Quaternion QuaternionAdd(const Quaternion& a, const Quaternion& b) 44 | { 45 | Quaternion temp; 46 | QuaternionAdd(a, b, temp); 47 | return temp; 48 | } 49 | inline QAngle QuaternionAngles(const Quaternion& q) 50 | { 51 | QAngle temp; 52 | QuaternionAngles(q, temp); 53 | return temp; 54 | } 55 | inline Quaternion QuaternionInvert(const Quaternion& a) 56 | { 57 | Quaternion temp; 58 | QuaternionInvert(a, temp); 59 | return temp; 60 | } 61 | -------------------------------------------------------------------------------- /CastingEssentials/Misc/Extras/VPlane.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include 4 | 5 | inline void VPlaneInit(VPlane& plane, const Vector& vNormal, const Vector& vPoint) 6 | { 7 | plane.m_Normal = vNormal; 8 | plane.m_Dist = vNormal.Dot(vPoint); 9 | } 10 | inline VPlane VPlaneInit(const Vector& vNormal, const Vector& vPoint) 11 | { 12 | VPlane retVal; 13 | VPlaneInit(retVal, vNormal, vPoint); 14 | return retVal; 15 | } 16 | 17 | inline void VPlaneInit(VPlane& plane, const Vector& p0, const Vector& p1, const Vector& p2) 18 | { 19 | VPlaneInit(plane, (p1 - p0).Cross(p2 - p0).Normalized(), p0); 20 | } 21 | inline VPlane VPlaneInit(const Vector& p0, const Vector& p1, const Vector& p2) 22 | { 23 | VPlane retVal; 24 | VPlaneInit(p0, p1, p2); 25 | return retVal; 26 | } 27 | inline void VPlaneInit(VPlane& plane, const cplane_t& inPlane) 28 | { 29 | plane.Init(inPlane.normal, inPlane.dist); 30 | } 31 | inline VPlane VPlaneInit(const cplane_t& plane) 32 | { 33 | VPlane retVal; 34 | VPlaneInit(retVal, plane); 35 | return retVal; 36 | } 37 | 38 | // Returns true if the plane intersected with the line. 39 | inline bool VPlaneIntersectLine(const VPlane& plane, const Vector& p0, const Vector& p1, Vector* intersection = nullptr, bool lineSegment = true) 40 | { 41 | //if (plane.GetPointSideExact(p0) == plane.GetPointSideExact(p1)) 42 | // return false; // Both points of the line are on the same side of the plane, no intersection 43 | 44 | const Vector lineDir = p1 - p0; 45 | const float lineLength = lineDir.Length(); 46 | const Vector lineDirNorm = lineDir / lineLength; 47 | 48 | if (lineDirNorm.Dot(plane.m_Normal) == 0) 49 | return false; // Line and plane are parallel, no intersection 50 | 51 | // Make sure we have something here 52 | if (!intersection) 53 | intersection = (Vector*)stackalloc(sizeof(Vector)); 54 | 55 | const Vector& planePoint = plane.GetPointOnPlane(); 56 | 57 | // Substitute the parametric equation of the line into the normal equation of the plane 58 | const float upper = (planePoint - p0).Dot(plane.m_Normal); 59 | const float lower = lineDirNorm.Dot(plane.m_Normal); 60 | const float d = upper / lower; 61 | 62 | if (!lineSegment || d >= 0 && d <= lineLength) 63 | { 64 | if (intersection) 65 | *intersection = d * lineDirNorm + p0; 66 | 67 | return true; // Intersection 68 | } 69 | 70 | return false; // No intersection 71 | } -------------------------------------------------------------------------------- /CastingEssentials/Misc/HLTVCameraHack.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | #include 3 | 4 | enum ObserverMode; 5 | 6 | class HLTVCameraOverride : public C_HLTVCamera 7 | { 8 | public: 9 | ObserverMode GetMode() const { return (ObserverMode)m_nCameraMode; } 10 | using C_HLTVCamera::m_nCameraMode; 11 | using C_HLTVCamera::m_iCameraMan; 12 | using C_HLTVCamera::m_vCamOrigin; 13 | using C_HLTVCamera::m_aCamAngle; 14 | using C_HLTVCamera::m_iTraget1; 15 | using C_HLTVCamera::m_iTraget2; 16 | using C_HLTVCamera::m_flFOV; 17 | using C_HLTVCamera::m_flOffset; 18 | using C_HLTVCamera::m_flDistance; 19 | using C_HLTVCamera::m_flLastDistance; 20 | using C_HLTVCamera::m_flTheta; 21 | using C_HLTVCamera::m_flPhi; 22 | using C_HLTVCamera::m_flInertia; 23 | using C_HLTVCamera::m_flLastAngleUpdateTime; 24 | using C_HLTVCamera::m_bEntityPacketReceived; 25 | using C_HLTVCamera::m_nNumSpectators; 26 | using C_HLTVCamera::m_szTitleText; 27 | using C_HLTVCamera::m_LastCmd; 28 | using C_HLTVCamera::m_vecVelocity; 29 | 30 | using C_HLTVCamera::SetCameraAngle; 31 | }; 32 | 33 | #undef WALL_OFFSET 34 | static constexpr float WALL_OFFSET = 6; 35 | 36 | static constexpr Vector WALL_MIN(-WALL_OFFSET, -WALL_OFFSET, -WALL_OFFSET); 37 | static constexpr Vector WALL_MAX(WALL_OFFSET, WALL_OFFSET, WALL_OFFSET); 38 | -------------------------------------------------------------------------------- /CastingEssentials/Misc/Interpolators.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | namespace Interpolators 4 | { 5 | __forceinline constexpr float Linear(float x) 6 | { 7 | return x; 8 | } 9 | __forceinline constexpr float Smoothstep(float x) 10 | { 11 | return 3*(x*x) - 2*(x*x*x); 12 | }; 13 | __forceinline constexpr float Smootherstep(float x) 14 | { 15 | return 6*(x*x*x*x*x) - 15*(x*x*x*x) + 10*(x*x*x); 16 | } 17 | __forceinline float CircleEaseOut(float x, float bias = 0.5) 18 | { 19 | return 1 - std::pow(1 - std::pow(x, bias), 1 / bias); 20 | } 21 | __forceinline float CircleEaseIn(float x, float bias = 0.5) 22 | { 23 | return std::pow(1 - std::pow(1 - x, bias), 1 / bias); 24 | } 25 | __forceinline float EaseIn2(float x, float bias = 0.5) 26 | { 27 | return std::pow(x, 1 / bias); 28 | } 29 | __forceinline float EaseOut2(float x, float bias = 0.5) 30 | { 31 | return 1 - std::pow(-x + 1, 1 / bias); 32 | } 33 | }; -------------------------------------------------------------------------------- /CastingEssentials/Misc/MissingDefinitions.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | class SVC_FixAngle 4 | { 5 | public: 6 | PADDING(20); 7 | 8 | bool m_bRelative; 9 | QAngle m_Angle; 10 | }; 11 | -------------------------------------------------------------------------------- /CastingEssentials/Misc/NatVis/CBaseHandle.natvis: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | index {m_Index & 4095}, serial {m_Index >> 12} 5 | {{invalid}} 6 | 7 | -------------------------------------------------------------------------------- /CastingEssentials/Misc/NatVis/CUtlVector.natvis: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | [Count = {m_Size}] 5 | 6 | 7 | m_Size 8 | m_pElements 9 | 10 | 11 | 12 | -------------------------------------------------------------------------------- /CastingEssentials/Misc/NatVis/ClientClass.natvis: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | {m_pNetworkName,sb} 5 | 6 | -------------------------------------------------------------------------------- /CastingEssentials/Misc/NatVis/RecvProp.natvis: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | {m_pVarName,sb} 5 | 6 | 7 | m_pDataTable 8 | 9 | 10 | -------------------------------------------------------------------------------- /CastingEssentials/Misc/NatVis/RecvTable.natvis: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | {m_pNetTableName,sb}, {m_nProps} props 5 | 6 | 7 | m_nProps 8 | m_pProps 9 | 10 | 11 | 12 | -------------------------------------------------------------------------------- /CastingEssentials/Misc/Padding.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include 4 | 5 | template struct _PADDING_HELPER : _PADDING_HELPER 6 | { 7 | static_assert(i != 0, "0 size struct not supported in C++"); 8 | std::byte : 8; 9 | }; 10 | template<> struct _PADDING_HELPER<1> 11 | { 12 | std::byte : 8; 13 | }; 14 | template<> struct _PADDING_HELPER 15 | { 16 | // To catch infinite recursion 17 | }; 18 | 19 | #define PADDING(size) _PADDING_HELPER EXPAND_CONCAT(CE_PADDING, __COUNTER__) -------------------------------------------------------------------------------- /CastingEssentials/Misc/Polyhook.cpp: -------------------------------------------------------------------------------- 1 | #define POLYHOOK_ENABLE_IMPLEMENTATION 1 2 | #include -------------------------------------------------------------------------------- /CastingEssentials/Misc/SuggestionList.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include 4 | 5 | #include 6 | #include 7 | #include 8 | 9 | template 10 | class SuggestionList 11 | { 12 | public: 13 | auto begin() { return m_Array.begin(); } 14 | auto begin() const { return m_Array.begin(); } 15 | auto end() { return m_Array.begin() + m_Count; } 16 | auto end() const { return m_Array.begin() + m_Count; } 17 | 18 | auto size() const { return m_Count; } 19 | 20 | void insert(const T& val) { emplace(std::move(T(val))); } 21 | void emplace(T&& val) 22 | { 23 | if (m_Count < MaxCount) 24 | { 25 | // Just add to the end, we'll sort later 26 | m_Array[m_Count++] = std::move(val); 27 | } 28 | else 29 | { 30 | // Make sure we are initially sorted 31 | EnsureSorted(); 32 | 33 | // Insertion sort 34 | const auto& upperBound = std::upper_bound(m_Array.begin(), m_Array.end(), val, Sorter{}); 35 | if (upperBound != m_Array.end()) 36 | { 37 | std::move(upperBound, m_Array.end() - 1, upperBound + 1); 38 | *upperBound = std::move(val); 39 | } 40 | } 41 | } 42 | 43 | void EnsureSorted() 44 | { 45 | // If we're not sorted, sort 46 | if (!m_Sorted) 47 | { 48 | std::sort(begin(), end(), Sorter{}); 49 | m_Sorted = true; 50 | } 51 | } 52 | 53 | void clear() 54 | { 55 | m_Sorted = false; 56 | m_Count = 0; 57 | } 58 | 59 | private: 60 | struct CaseInsensitiveTraits : public std::char_traits 61 | { 62 | static constexpr bool eq(char a, char b) { return toupper(a) == toupper(b); } 63 | static constexpr bool lt(char a, char b) { return toupper(a) < toupper(b); } 64 | }; 65 | 66 | struct Sorter 67 | { 68 | bool operator()(const std::basic_string_view& a, 69 | const std::basic_string_view& b) const 70 | { 71 | return a < b; 72 | } 73 | }; 74 | 75 | bool m_Sorted = false; 76 | size_t m_Count = 0; 77 | std::array m_Array; 78 | }; -------------------------------------------------------------------------------- /CastingEssentials/Modules/Antifreeze.cpp: -------------------------------------------------------------------------------- 1 | 2 | #include "antifreeze.h" 3 | #include "PluginBase/Interfaces.h" 4 | 5 | #include 6 | #include 7 | #include 8 | #include 9 | #include 10 | #include 11 | #include 12 | 13 | MODULE_REGISTER(AntiFreeze); 14 | 15 | class AntiFreeze::Panel : public vgui::Panel 16 | { 17 | public: 18 | Panel(vgui::Panel *parent, const char *panelName) : vgui::Panel(parent, panelName) { } 19 | virtual ~Panel() { } 20 | 21 | virtual void OnTick(); 22 | }; 23 | 24 | AntiFreeze::AntiFreeze() : 25 | ce_antifreeze_enabled("ce_antifreeze_enabled", "0", FCVAR_NONE, "enable antifreeze (forces the spectator GUI to refresh)") 26 | { 27 | } 28 | 29 | bool AntiFreeze::CheckDependencies() 30 | { 31 | bool ready = true; 32 | 33 | if (!Interfaces::GetEngineTool()) 34 | { 35 | PluginWarning("Required interface IEngineTool for module %s not available!\n", GetModuleName()); 36 | ready = false; 37 | } 38 | 39 | if (!Interfaces::AreVguiLibrariesAvailable()) 40 | { 41 | PluginWarning("Required VGUI library for module %s not available!\n", GetModuleName()); 42 | ready = false; 43 | } 44 | 45 | if (!g_pVGui) 46 | { 47 | PluginWarning("Required interface vgui::IVGui for module %s not available!\n", GetModuleName()); 48 | ready = false; 49 | } 50 | 51 | if (!g_pVGuiPanel) 52 | { 53 | PluginWarning("Required interface vgui::IPanel for module %s not available!\n", GetModuleName()); 54 | ready = false; 55 | } 56 | 57 | try 58 | { 59 | Interfaces::GetClientMode(); 60 | } 61 | catch (bad_pointer) 62 | { 63 | PluginWarning("Module %s requires IClientMode, which cannot be verified at this time!\n", GetModuleName()); 64 | } 65 | 66 | return ready; 67 | } 68 | 69 | void AntiFreeze::OnTick(bool inGame) 70 | { 71 | VPROF_BUDGET(__FUNCTION__, VPROF_BUDGETGROUP_CE); 72 | 73 | if (inGame && ce_antifreeze_enabled.GetBool()) 74 | { 75 | if (!m_Panel) 76 | { 77 | try 78 | { 79 | vgui::Panel* const viewport = Interfaces::GetClientMode()->GetViewport(); 80 | if (viewport) 81 | { 82 | for (int i = 0; i < g_pVGuiPanel->GetChildCount(viewport->GetVPanel()); i++) 83 | { 84 | vgui::VPANEL childPanel = g_pVGuiPanel->GetChild(viewport->GetVPanel(), i); 85 | 86 | if (!strcmp(g_pVGuiPanel->GetName(childPanel), "specgui")) 87 | { 88 | m_Panel.reset(new Panel(viewport, "AntiFreeze")); 89 | m_Panel->SetParent(childPanel); 90 | return; 91 | } 92 | } 93 | 94 | Warning("Could not initialize the panel!\n"); 95 | } 96 | else 97 | Warning("Could not initialize the panel!\n"); 98 | } 99 | catch (bad_pointer) 100 | { 101 | Warning("Could not initialize the panel!\n"); 102 | } 103 | } 104 | 105 | if (m_Panel) 106 | { 107 | if (!m_Panel->IsEnabled()) 108 | m_Panel->SetEnabled(true); 109 | 110 | m_Panel->OnTick(); 111 | } 112 | 113 | Interfaces::GetEngineTool()->ForceSend(); 114 | Interfaces::GetEngineTool()->ForceUpdateDuringPause(); 115 | } 116 | else if (m_Panel) 117 | m_Panel.reset(); 118 | } 119 | 120 | void AntiFreeze::Panel::OnTick() 121 | { 122 | g_pVGuiPanel->GetPanel(GetVParent(), "ClientDLL")->OnCommand("performlayout"); 123 | } -------------------------------------------------------------------------------- /CastingEssentials/Modules/Antifreeze.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | #include "PluginBase/modules.h" 3 | 4 | #include 5 | 6 | class ConCommand; 7 | class IConVar; 8 | 9 | class AntiFreeze : public Module 10 | { 11 | public: 12 | AntiFreeze(); 13 | 14 | static bool CheckDependencies(); 15 | static constexpr __forceinline const char* GetModuleName() { return "HUD Antifreeze"; } 16 | 17 | private: 18 | class Panel; 19 | std::unique_ptr m_Panel; 20 | 21 | void OnTick(bool inGame) override; 22 | 23 | ConVar ce_antifreeze_enabled; 24 | void ToggleEnabled(IConVar *var, const char *pOldValue, float flOldValue); 25 | }; -------------------------------------------------------------------------------- /CastingEssentials/Modules/Camera/CameraStateCallbacks.cpp: -------------------------------------------------------------------------------- 1 | #include "Modules/Camera/CameraStateCallbacks.h" 2 | 3 | #include 4 | 5 | static std::vector s_CallbackInstances; 6 | class CameraStateCallbacksParent : public CameraStateCallbacks 7 | { 8 | public: 9 | CameraStateCallbacksParent() : CameraStateCallbacks(false) {} 10 | 11 | void SpecModeChanged(ObserverMode oldMode, ObserverMode& newMode) override 12 | { 13 | for (auto inst : s_CallbackInstances) 14 | inst->SpecModeChanged(oldMode, newMode); 15 | } 16 | void SpecTargetChanged(IClientEntity* oldEnt, IClientEntity*& newEnt) override 17 | { 18 | for (auto inst : s_CallbackInstances) 19 | inst->SpecTargetChanged(oldEnt, newEnt); 20 | } 21 | 22 | void SetupCameraTarget(ObserverMode mode, IClientEntity* target, CameraPtr& newCamera) override 23 | { 24 | for (auto inst : s_CallbackInstances) 25 | inst->SetupCameraTarget(mode, target, newCamera); 26 | } 27 | 28 | void SetupCameraSmooth(const CameraPtr& currentCamera, CameraPtr& targetCamera, const SmoothSettings& settings) override 29 | { 30 | for (auto inst : s_CallbackInstances) 31 | inst->SetupCameraSmooth(currentCamera, targetCamera, settings); 32 | } 33 | 34 | bool GetFOVOverride(const CameraConstPtr& camera, float& fov) override 35 | { 36 | bool overridden = false; 37 | 38 | for (auto inst : s_CallbackInstances) 39 | { 40 | if (inst->GetFOVOverride(camera, fov)) 41 | { 42 | #ifdef DEBUG 43 | AssertMsg(!overridden, "Attempted to override fov from two places at once!"); 44 | overridden = true; 45 | #else 46 | return true; 47 | #endif 48 | } 49 | } 50 | 51 | return overridden; 52 | } 53 | 54 | void CameraCollapsed(const CameraPtr& previousCam, CameraPtr& newCam) override 55 | { 56 | for (auto inst : s_CallbackInstances) 57 | inst->CameraCollapsed(previousCam, newCam); 58 | } 59 | }; 60 | 61 | CameraStateCallbacks::CameraStateCallbacks(bool nonParent) 62 | { 63 | if (nonParent) 64 | s_CallbackInstances.push_back(this); 65 | } 66 | CameraStateCallbacks::~CameraStateCallbacks() 67 | { 68 | if (auto found = std::find(s_CallbackInstances.begin(), s_CallbackInstances.end(), this); found != s_CallbackInstances.end()) 69 | s_CallbackInstances.erase(found); 70 | } 71 | 72 | CameraStateCallbacks& CameraStateCallbacks::GetCallbacksParent() 73 | { 74 | static CameraStateCallbacksParent s_Parent; 75 | return s_Parent; 76 | } 77 | -------------------------------------------------------------------------------- /CastingEssentials/Modules/Camera/CameraStateCallbacks.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include "Modules/Camera/ICamera.h" 4 | 5 | class IClientEntity; 6 | enum ObserverMode; 7 | struct SmoothSettings; 8 | 9 | class CameraStateCallbacks 10 | { 11 | public: 12 | CameraStateCallbacks(bool addToList = true); 13 | virtual ~CameraStateCallbacks(); 14 | 15 | // Lets modules prevent camera mode/target from being changed at all 16 | virtual void SpecModeChanged(ObserverMode oldMode, ObserverMode& newMode) {} 17 | virtual void SpecTargetChanged(IClientEntity* oldEnt, IClientEntity*& newEnt) {} 18 | 19 | // 1st function to be called, lets modules override the new target camera 20 | virtual void SetupCameraTarget(ObserverMode mode, IClientEntity* target, CameraPtr& newCamera) {} 21 | 22 | // 2nd function to be called, after all other modules have had a chance to mess 23 | // with the target camera via SetupCameraTarget. As the name implies, used by CameraSmooths 24 | // module to create a camera smooth once we know for sure what our target will be. 25 | virtual void SetupCameraSmooth(const CameraPtr& currentCamera, CameraPtr& targetCamera, const SmoothSettings& settings) {} 26 | 27 | virtual bool GetFOVOverride(const CameraConstPtr& camera, float& fov) { return false; } 28 | 29 | // Called whenever the top-level camera (the one returned by CameraState::GetActiveCamera()) 30 | // is collapsed. 31 | virtual void CameraCollapsed(const CameraPtr& previousCam, CameraPtr& newCam) {} 32 | 33 | private: 34 | friend class CameraState; 35 | static CameraStateCallbacks& GetCallbacksParent(); 36 | }; 37 | -------------------------------------------------------------------------------- /CastingEssentials/Modules/Camera/DeathCamera.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | #include "Modules/Camera/ICamera.h" 3 | 4 | #include 5 | 6 | #include 7 | 8 | class C_BaseEntity; 9 | class IClientEntity; 10 | enum class TFClassType; 11 | 12 | class DeathCamera : public ICamera 13 | { 14 | public: 15 | DeathCamera(); 16 | 17 | void Reset() override; 18 | int GetAttachedEntity() const override { return 0; } 19 | const char* GetDebugName() const override { return "DeathCamera"; } 20 | 21 | CHandle m_Victim; 22 | CHandle m_Killer; 23 | 24 | protected: 25 | bool IsCollapsible() const override { return false; } 26 | void Update(float dt, uint32_t frame) override; 27 | 28 | private: 29 | float m_ElapsedTime = 0; 30 | TFClassType m_VictimClass; 31 | 32 | void FindProjectiles(); 33 | std::vector>> m_Projectiles; 34 | 35 | bool m_ShouldUpdateKillerPosition = true; 36 | Vector m_KillerPosition; 37 | void UpdateKillerPosition(); 38 | 39 | QAngle SmoothCameraAngle(const QAngle& targetAngle, float rate) const; 40 | QAngle SmoothCameraAngle(const Vector& targetPos, float rate) const; 41 | }; 42 | -------------------------------------------------------------------------------- /CastingEssentials/Modules/Camera/FirstPersonCamera.cpp: -------------------------------------------------------------------------------- 1 | #include "Modules/Camera/FirstPersonCamera.h" 2 | 3 | #include 4 | #include 5 | 6 | FirstPersonCamera::FirstPersonCamera(CHandle entity) : 7 | m_Entity(entity) 8 | { 9 | m_Type = CameraType::FirstPerson; 10 | } 11 | 12 | void FirstPersonCamera::Update(float dt, uint32_t frame) 13 | { 14 | if (auto ent = m_Entity.Get()) 15 | { 16 | m_Origin = ent->EyePosition(); 17 | m_Angles = ent->EyeAngles(); 18 | 19 | if (ent->IsPlayer()) 20 | m_FOV = static_cast(ent)->GetFOV(); 21 | else 22 | m_FOV = 90; 23 | } 24 | else 25 | { 26 | m_Origin = vec3_origin; 27 | m_Angles = vec3_angle; 28 | m_FOV = 150; // So we know something is wrong 29 | } 30 | } 31 | -------------------------------------------------------------------------------- /CastingEssentials/Modules/Camera/FirstPersonCamera.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | #include "Modules/Camera/ICamera.h" 3 | 4 | #include 5 | 6 | class C_BaseEntity; 7 | 8 | class FirstPersonCamera final : public ICamera 9 | { 10 | public: 11 | FirstPersonCamera(CHandle entity); 12 | 13 | void Reset() override {} 14 | int GetAttachedEntity() const override { return m_Entity.GetEntryIndex(); } 15 | const char* GetDebugName() const override { return "FirstPersonCamera"; } 16 | 17 | protected: 18 | bool IsCollapsible() const override { return false; } 19 | void Update(float dt, uint32_t frame) override; 20 | 21 | private: 22 | CHandle m_Entity; 23 | }; 24 | -------------------------------------------------------------------------------- /CastingEssentials/Modules/Camera/HybridPlayerCameraSmooth.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | #include "Modules/Camera/ICamera.h" 3 | #include "Modules/Camera/ICameraSmooth.h" 4 | #include "Modules/Camera/SimpleCamera.h" 5 | 6 | class HybridPlayerCameraSmooth : public ICameraSmooth 7 | { 8 | public: 9 | HybridPlayerCameraSmooth(CameraPtr&& startCamera, CameraPtr&& endCamera); 10 | 11 | using ICameraSmooth::GetStartCamera; 12 | using ICameraSmooth::GetEndCamera; 13 | 14 | CameraConstPtr GetStartCamera() const override { return m_StartCamera; } 15 | CameraConstPtr GetEndCamera() const override { return m_EndCamera; } 16 | 17 | float GetProgress() const override { return m_Percent; } 18 | void Reset() override; 19 | const char* GetDebugName() const override { return "HybridPlayerCameraSmooth"; } 20 | 21 | float m_LinearSpeed = 875; 22 | float m_BezierDist = 1000; 23 | float m_BezierDuration = 0.65; 24 | float m_AngleBias = 0.85; 25 | 26 | enum class SmoothingMode 27 | { 28 | Approach, 29 | Lerp, 30 | } m_SmoothingMode = SmoothingMode::Approach; 31 | 32 | protected: 33 | bool IsCollapsible() const override { return true; } 34 | void Update(float dt, uint32_t frame) override; 35 | 36 | private: 37 | static float ComputeSmooth(float time, float startTime, float totalDist, float maxSpeed, float bezierDist, float bezierDuration, float& percent); 38 | 39 | CameraPtr m_StartCamera; 40 | CameraPtr m_EndCamera; 41 | 42 | float m_ElapsedTime = 0; 43 | float m_StartDist; 44 | float m_Percent = 0; 45 | float m_LastAngPercent = 0; 46 | }; -------------------------------------------------------------------------------- /CastingEssentials/Modules/Camera/ICamera.cpp: -------------------------------------------------------------------------------- 1 | #include "ICamera.h" 2 | 3 | bool ICamera::TryCollapse(CameraPtr& ptr) 4 | { 5 | if (ptr->IsCollapsible()) 6 | { 7 | if (auto collapsed = ptr->GetCollapsedCamera()) 8 | { 9 | ptr = collapsed; 10 | return true; 11 | } 12 | } 13 | 14 | return false; 15 | } 16 | -------------------------------------------------------------------------------- /CastingEssentials/Modules/Camera/ICamera.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | class Vector; 4 | class QAngle; 5 | 6 | class ICamera; 7 | using CameraPtr = std::shared_ptr; 8 | using CameraConstPtr = std::shared_ptr; 9 | 10 | enum class CameraType 11 | { 12 | Invalid = -1, 13 | 14 | FirstPerson, 15 | ThirdPerson, 16 | Roaming, 17 | 18 | // This doesn't mean that we're not moving, it just means the observer has no control 19 | Fixed, 20 | 21 | // Don't touch spec_mode upon changing to a camera with this type, other than making sure 22 | // we're not in spec_mode 4 (firstperson) which might cause some stuff not to draw 23 | Smooth, 24 | }; 25 | 26 | class ICamera 27 | { 28 | public: 29 | virtual ~ICamera() = default; 30 | 31 | virtual void Reset() = 0; 32 | void TryUpdate(float dt, uint32_t frame) 33 | { 34 | if (dt == 0 || frame != m_LastFrameUpdate) 35 | { 36 | m_LastFrameUpdate = frame; 37 | Update(dt, frame); 38 | } 39 | } 40 | 41 | // If we are attached to an entity (say, with TPLock), then return its entindex here (otherwise return 0). 42 | // This helps us keep our camera system more in sync with the game's. 43 | virtual int GetAttachedEntity() const = 0; 44 | 45 | virtual const char* GetDebugName() const = 0; 46 | 47 | // Code readability 48 | void ApplySettings() { Update(0, 0); } 49 | 50 | __forceinline const Vector& GetOrigin() const { return m_Origin; } 51 | __forceinline const QAngle& GetAngles() const { return m_Angles; } 52 | __forceinline float GetFOV() const { return m_FOV; } 53 | 54 | __forceinline CameraType GetCameraType() const { return m_Type; } 55 | 56 | static bool TryCollapse(CameraPtr& ptr); 57 | virtual bool IsCollapsible() const = 0; 58 | 59 | protected: 60 | virtual CameraPtr GetCollapsedCamera() { return nullptr; } 61 | virtual void Update(float dt, uint32_t frame) = 0; 62 | 63 | Vector m_Origin; 64 | QAngle m_Angles; 65 | float m_FOV; 66 | CameraType m_Type; 67 | 68 | private: 69 | uint32_t m_LastFrameUpdate = 0; 70 | }; 71 | -------------------------------------------------------------------------------- /CastingEssentials/Modules/Camera/ICameraGroup.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include "Modules/Camera/ICamera.h" 4 | 5 | enum class BestCameraResult 6 | { 7 | // Some general failure. 8 | Error, 9 | 10 | 11 | }; 12 | 13 | class ICameraGroup 14 | { 15 | public: 16 | virtual ~ICameraGroup() = default; 17 | 18 | virtual void GetBestCamera(CameraPtr& targetCamera) = 0; 19 | }; 20 | 21 | using CameraGroupPtr = std::shared_ptr; 22 | -------------------------------------------------------------------------------- /CastingEssentials/Modules/Camera/ICameraSmooth.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include "Modules/Camera/ICamera.h" 4 | 5 | #include 6 | 7 | class ICameraSmooth : public ICamera 8 | { 9 | public: 10 | virtual ~ICameraSmooth() = default; 11 | 12 | // ICamera 13 | int GetAttachedEntity() const override 14 | { 15 | if (GetProgress() < 0.5) 16 | { 17 | if (auto startCam = GetStartCamera()) 18 | return startCam->GetAttachedEntity(); 19 | } 20 | 21 | if (auto endCam = GetEndCamera()) 22 | return endCam->GetAttachedEntity(); 23 | 24 | return 0; 25 | } 26 | 27 | virtual CameraConstPtr GetStartCamera() const = 0; 28 | virtual CameraConstPtr GetEndCamera() const = 0; 29 | 30 | CameraPtr GetStartCamera() { return std::const_pointer_cast(std::as_const(*this).GetStartCamera()); } 31 | CameraPtr GetEndCamera() { return std::const_pointer_cast(std::as_const(*this).GetEndCamera()); } 32 | 33 | virtual float GetProgress() const = 0; 34 | 35 | // Helpers 36 | bool IsSmoothComplete() const { return GetProgress() >= 1; } 37 | 38 | // Gets/sets a camera to collapse to when this smooth is complete, INSTEAD OF the end camera. 39 | void SetQueuedCamera(const CameraPtr& camera) { m_QueuedCamera = camera; } 40 | const CameraPtr& GetQueuedCamera() const { return m_QueuedCamera; } 41 | 42 | protected: 43 | // ICamera 44 | CameraPtr GetCollapsedCamera() override 45 | { 46 | if (IsSmoothComplete()) 47 | { 48 | if (m_QueuedCamera) 49 | return m_QueuedCamera; 50 | else 51 | return GetEndCamera(); 52 | } 53 | 54 | return nullptr; 55 | } 56 | 57 | private: 58 | CameraPtr m_QueuedCamera; 59 | }; 60 | -------------------------------------------------------------------------------- /CastingEssentials/Modules/Camera/LookatCamera.cpp: -------------------------------------------------------------------------------- 1 | #include "LookatCamera.h" 2 | 3 | #include 4 | 5 | #include 6 | 7 | LookatCamera::LookatCamera() 8 | { 9 | m_Type = CameraType::Fixed; 10 | } 11 | 12 | void LookatCamera::Reset() 13 | { 14 | m_ElapsedTime = 0; 15 | m_Angles = GetTargetAngles(); 16 | } 17 | 18 | QAngle LookatCamera::SmoothCameraAngle(const QAngle& currentAngle, const QAngle& targetAngle, float dt, float inertia) 19 | { 20 | dt = std::clamp(dt * inertia, 0.01f, 1.0f); 21 | return Lerp(dt, currentAngle, targetAngle); 22 | } 23 | 24 | void LookatCamera::Update(float dt, uint32_t frame) 25 | { 26 | auto targetAngles = GetTargetAngles(); 27 | 28 | if (m_ElapsedTime == 0) 29 | m_Angles = targetAngles; 30 | else 31 | m_Angles = SmoothCameraAngle(m_Angles, targetAngles, dt, m_Inertia); 32 | 33 | m_ElapsedTime += dt; 34 | } 35 | 36 | QAngle LookatCamera::GetTargetAngles() const 37 | { 38 | auto targetPos = m_TargetOffset; 39 | if (auto ent = m_TargetEntity.Get()) 40 | targetPos += ent->GetAbsOrigin(); 41 | 42 | QAngle targetAngles; 43 | VectorAngles(targetPos - m_Origin, targetAngles); 44 | return targetAngles; 45 | } 46 | -------------------------------------------------------------------------------- /CastingEssentials/Modules/Camera/LookatCamera.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include "Modules/Camera/ICamera.h" 4 | 5 | #include 6 | 7 | class IClientEntity; 8 | 9 | class LookatCamera final : public ICamera 10 | { 11 | public: 12 | LookatCamera(); 13 | 14 | void Reset() override; 15 | int GetAttachedEntity() const override { return 0; } 16 | const char* GetDebugName() const override { return "LookatCamera"; } 17 | bool IsCollapsible() const { return false; } // Likely to continue moving, even after stopping 18 | 19 | using ICamera::m_Origin; 20 | using ICamera::m_FOV; 21 | 22 | float m_Inertia = 3; 23 | Vector m_TargetOffset = Vector(0, 0, 0); 24 | CHandle m_TargetEntity; 25 | 26 | static QAngle SmoothCameraAngle(const QAngle& currentAngle, const QAngle& targetAngle, float dt, float inertia); 27 | 28 | protected: 29 | void Update(float dt, uint32_t frame) override; 30 | 31 | private: 32 | QAngle GetTargetAngles() const; 33 | 34 | float m_ElapsedTime = 0; 35 | }; 36 | -------------------------------------------------------------------------------- /CastingEssentials/Modules/Camera/OrbitCamera.cpp: -------------------------------------------------------------------------------- 1 | #include "Modules/Camera/OrbitCamera.h" 2 | 3 | OrbitCamera::OrbitCamera() 4 | { 5 | m_Type = CameraType::Fixed; 6 | } 7 | 8 | void OrbitCamera::Reset() 9 | { 10 | m_ElapsedTime = 0; 11 | } 12 | 13 | void OrbitCamera::Update(float dt, uint32_t frame) 14 | { 15 | m_ElapsedTime += dt; 16 | 17 | m_Origin.z = m_OrbitPoint.z + m_ZOffset; 18 | 19 | const float angle = m_ElapsedTime * m_OrbitsPerSecond * (2 * M_PI_F); 20 | m_Origin.x = m_OrbitPoint.x + std::cosf(angle) * m_Radius; 21 | m_Origin.y = m_OrbitPoint.y + std::sinf(angle) * m_Radius; 22 | 23 | // Angles 24 | VectorAngles(m_OrbitPoint - m_Origin, m_Angles); 25 | 26 | m_FOV = 90; 27 | } 28 | -------------------------------------------------------------------------------- /CastingEssentials/Modules/Camera/OrbitCamera.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | #include "Modules/Camera/ICamera.h" 3 | 4 | class OrbitCamera : public ICamera 5 | { 6 | public: 7 | OrbitCamera(); 8 | 9 | void Reset() override; 10 | int GetAttachedEntity() const override { return 0; } 11 | 12 | const char* GetDebugName() const override { return "OrbitCamera"; } 13 | 14 | Vector m_OrbitPoint; 15 | float m_Radius; 16 | float m_ZOffset; 17 | 18 | float m_OrbitsPerSecond = 1.0f / 60; 19 | 20 | protected: 21 | bool IsCollapsible() const override { return false; } 22 | void Update(float dt, uint32_t frame) override; 23 | 24 | private: 25 | float m_ElapsedTime = 0; 26 | }; -------------------------------------------------------------------------------- /CastingEssentials/Modules/Camera/PlayerCameraGroup.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | #include "Modules/Camera/DeathCamera.h" 3 | #include "Modules/Camera/FirstPersonCamera.h" 4 | #include "Modules/Camera/ICameraGroup.h" 5 | #include "Modules/Camera/TPLockCamera.h" 6 | 7 | #include 8 | 9 | #include 10 | 11 | class PlayerCameraGroup final : public ICameraGroup, IGameEventListener2, public std::enable_shared_from_this 12 | { 13 | public: 14 | PlayerCameraGroup(Player& player); 15 | ~PlayerCameraGroup(); 16 | 17 | void GetBestCamera(CameraPtr& targetCamera) override; 18 | 19 | IClientEntity* GetPlayerEnt() const { return m_PlayerEnt.Get(); } 20 | 21 | protected: 22 | void FireGameEvent(IGameEvent* event) override; 23 | 24 | private: 25 | FirstPersonCamera m_FirstPersonCam; 26 | TPLockCamera m_TPLockCam; 27 | TPLockCamera m_TPLockTauntCam; 28 | DeathCamera m_DeathCam; 29 | 30 | float m_DeathCameraCreateTime; 31 | 32 | CHandle m_PlayerEnt; 33 | }; 34 | -------------------------------------------------------------------------------- /CastingEssentials/Modules/Camera/RoamingCamera.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include "Modules/Camera/ICamera.h" 4 | 5 | #include 6 | #include 7 | 8 | class IClientEntity; 9 | 10 | class RoamingCamera final : public ICamera 11 | { 12 | public: 13 | RoamingCamera(); 14 | 15 | void Reset() override; 16 | int GetAttachedEntity() const override { return 0; } 17 | const char* GetDebugName() const override { return "RoamingCamera"; } 18 | 19 | void SetPosition(const Vector& pos, const QAngle& angles); 20 | void SetFOV(float fov) { m_FOV = fov; } 21 | 22 | void CreateMove(const CUserCmd& cmd); 23 | 24 | void GotoEntity(IClientEntity* ent); 25 | 26 | void SetInputEnabled(bool enabled); 27 | 28 | protected: 29 | bool IsCollapsible() const override { return false; } 30 | void Update(float dt, uint32_t frame) override; 31 | 32 | private: 33 | void Accelerate(Vector& wishdir, float wishspeed, float accel, float dt); 34 | 35 | // Should we be processing the last usercmd, or should we just let velocity decay? 36 | bool m_InputEnabled = true; 37 | 38 | Vector m_Velocity; 39 | CUserCmd m_LastCmd; 40 | }; 41 | -------------------------------------------------------------------------------- /CastingEssentials/Modules/Camera/SimpleCamera.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | #include "Modules/Camera/ICamera.h" 3 | 4 | class SimpleCamera : public ICamera 5 | { 6 | public: 7 | SimpleCamera() 8 | { 9 | m_Type = CameraType::Fixed; 10 | } 11 | SimpleCamera(const Vector& origin, const QAngle& angles, float fov, CameraType camType = CameraType::Fixed) 12 | { 13 | m_Origin = origin; 14 | m_Angles = angles; 15 | m_FOV = fov; 16 | m_Type = camType; 17 | } 18 | 19 | void Reset() override {} 20 | int GetAttachedEntity() const override { return 0; } 21 | const char* GetDebugName() const override { return "SimpleCamera"; } 22 | 23 | using ICamera::m_Origin; 24 | using ICamera::m_Angles; 25 | using ICamera::m_FOV; 26 | using ICamera::m_Type; 27 | 28 | protected: 29 | bool IsCollapsible() const override { return false; } 30 | void Update(float dt, uint32_t frame) override {} 31 | }; 32 | -------------------------------------------------------------------------------- /CastingEssentials/Modules/Camera/SimpleCameraSmooth.cpp: -------------------------------------------------------------------------------- 1 | #include "Misc/Extras/QAngle.h" 2 | #include "Misc/Extras/Quaternion.h" 3 | #include "Modules/Camera/SimpleCameraSmooth.h" 4 | #include "PluginBase/Interfaces.h" 5 | 6 | #include 7 | #include 8 | #include 9 | 10 | #include 11 | 12 | #undef min 13 | 14 | SimpleCameraSmooth::SimpleCameraSmooth(CameraPtr&& startCamera, CameraPtr&& endCamera, float duration) : 15 | m_StartCamera(std::move(startCamera)), m_EndCamera(std::move(endCamera)), m_Duration(duration) 16 | { 17 | const auto startCam = GetStartCamera(); 18 | m_Origin = startCam->GetOrigin(); 19 | m_Angles = startCam->GetAngles(); 20 | m_FOV = startCam->GetFOV(); 21 | 22 | Assert(std::isfinite(m_Duration)); 23 | Assert(m_Duration > 0); 24 | } 25 | 26 | void SimpleCameraSmooth::Reset() 27 | { 28 | m_CurrentTime = 0; 29 | } 30 | 31 | void SimpleCameraSmooth::Update(float dt, uint32_t frame) 32 | { 33 | m_StartCamera->TryUpdate(dt, frame); 34 | TryCollapse(m_StartCamera); 35 | m_EndCamera->TryUpdate(dt, frame); 36 | TryCollapse(m_EndCamera); 37 | 38 | const float previousProgressLinear = GetProgress(); 39 | const float previousProgress = m_Interpolator(previousProgressLinear); 40 | 41 | if (!IsSmoothComplete()) 42 | { 43 | if (m_CurrentTime <= 0) 44 | { 45 | m_StartAngles = m_Angles = AngleNormalize(m_StartCamera->GetAngles()); 46 | m_StartOrigin = m_Origin = m_StartCamera->GetOrigin(); 47 | m_StartFOV = m_FOV = m_StartCamera->GetFOV(); 48 | 49 | const auto& endAngles = m_EndCamera->GetAngles(); 50 | for (int i = 0; i < 3; i++) 51 | m_EndAngles[i] = m_StartAngles[i] + AngleDistance(endAngles[i], m_StartAngles[i]); 52 | } 53 | 54 | m_CurrentTime = std::min(m_CurrentTime + dt, m_Duration); 55 | } 56 | 57 | const float progressLinear = GetProgress(); 58 | const float progress = m_Interpolator(progressLinear); 59 | float progressDelta = 1; 60 | if (previousProgress < 1) 61 | progressDelta = (progress - previousProgress) / (1 - previousProgress); 62 | 63 | if (m_UpdateStartOrigin) 64 | m_Origin = Lerp(progress, m_StartCamera->GetOrigin(), m_EndCamera->GetOrigin()); 65 | else 66 | m_Origin = Lerp(progress, m_StartOrigin, m_EndCamera->GetOrigin()); 67 | 68 | if (m_UpdateStartAngles) 69 | { 70 | const auto& newStartAngles = m_StartCamera->GetAngles(); 71 | const auto& newEndAngles = m_EndCamera->GetAngles(); 72 | 73 | // Just do linear interpolation between the start and end angles. We sum up the 74 | // euler angle differences so we can end up with start/end numbers greater/less 75 | // than 180. 76 | for (int i = 0; i < 3; i++) 77 | { 78 | m_StartAngles[i] += AngleDiff(newStartAngles[i], m_StartAngles[i]); 79 | m_EndAngles[i] += AngleDiff(newEndAngles[i], m_EndAngles[i]); 80 | m_Angles[i] = Lerp(progress, m_StartAngles[i], m_EndAngles[i]); 81 | } 82 | } 83 | else 84 | m_Angles = Lerp(progressDelta, m_Angles, m_EndCamera->GetAngles()); 85 | 86 | if (m_UpdateStartFOV) 87 | m_FOV = Lerp(progress, m_StartCamera->GetFOV(), m_EndCamera->GetFOV()); 88 | else 89 | m_FOV = Lerp(progress, m_StartFOV, m_EndCamera->GetFOV()); 90 | 91 | if (progress == 0) 92 | m_Type = m_StartCamera->GetCameraType(); 93 | else if (progress == 1) 94 | m_Type = m_EndCamera->GetCameraType(); 95 | else 96 | m_Type = CameraType::Smooth; 97 | 98 | Assert(m_Origin.IsValid()); 99 | Assert(m_Angles.IsValid()); 100 | Assert(std::isfinite(m_FOV)); 101 | } 102 | -------------------------------------------------------------------------------- /CastingEssentials/Modules/Camera/SimpleCameraSmooth.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include "Misc/Interpolators.h" 4 | #include "Modules/Camera/ICamera.h" 5 | #include "Modules/Camera/ICameraSmooth.h" 6 | 7 | #include 8 | 9 | class SimpleCameraSmooth final : public ICameraSmooth 10 | { 11 | public: 12 | SimpleCameraSmooth(CameraPtr&& startCamera, CameraPtr&& endCamera, float duration); 13 | 14 | using ICameraSmooth::GetStartCamera; 15 | using ICameraSmooth::GetEndCamera; 16 | 17 | CameraConstPtr GetStartCamera() const override { return m_StartCamera; } 18 | CameraConstPtr GetEndCamera() const override { return m_EndCamera; } 19 | 20 | void Reset() override; 21 | const char* GetDebugName() const override { return "SimpleCameraSmooth"; } 22 | 23 | float GetProgress() const override { return m_CurrentTime / m_Duration; } 24 | 25 | std::function m_Interpolator = Interpolators::Linear; 26 | 27 | bool m_UpdateStartAngles = true; 28 | bool m_UpdateStartOrigin = true; 29 | bool m_UpdateStartFOV = true; 30 | 31 | protected: 32 | bool IsCollapsible() const override { return true; } 33 | void Update(float dt, uint32_t frame) override; 34 | 35 | private: 36 | CameraPtr m_StartCamera; 37 | CameraPtr m_EndCamera; 38 | float m_Duration; 39 | float m_CurrentTime = 0; 40 | 41 | Vector m_StartOrigin; 42 | QAngle m_StartAngles; 43 | float m_StartFOV; 44 | 45 | QAngle m_EndAngles; 46 | }; 47 | -------------------------------------------------------------------------------- /CastingEssentials/Modules/Camera/SmoothSettings.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include 4 | 5 | struct SmoothSettings 6 | { 7 | bool m_TestFOV = true; 8 | bool m_TestDist = true; 9 | bool m_TestCooldown = true; 10 | bool m_TestLOS = true; 11 | 12 | float m_DurationOverride = -1; 13 | 14 | std::function m_InterpolatorOverride; 15 | }; 16 | -------------------------------------------------------------------------------- /CastingEssentials/Modules/Camera/TPLockCamera.cpp: -------------------------------------------------------------------------------- 1 | #include "Modules/Camera/TPLockCamera.h" 2 | 3 | #include "Misc/HLTVCameraHack.h" 4 | 5 | #include 6 | #include 7 | #include 8 | 9 | TPLockCamera::TPLockCamera(CHandle entity) : 10 | m_Entity(entity) 11 | { 12 | m_Type = CameraType::ThirdPerson; 13 | } 14 | 15 | void TPLockCamera::Update(float dt, uint32_t frame) 16 | { 17 | C_BaseEntity* const ent = m_Entity.Get(); 18 | Assert(ent); 19 | if (!ent) 20 | return; 21 | 22 | Vector targetPos; 23 | bool fallbackPos = true; 24 | C_BaseAnimating* const baseAnimating = ent->GetBaseAnimating(); 25 | if (baseAnimating) 26 | { 27 | const int targetBone = baseAnimating->LookupBone(m_Ruleset.m_Bone.c_str()); 28 | if (targetBone < 0) 29 | { 30 | DevWarning(2, "[Third person lock] Unable to find bone \"%s\"! Reverting to eye position.\n", m_Ruleset.m_Bone.c_str()); 31 | } 32 | else 33 | { 34 | QAngle dummy; 35 | baseAnimating->GetBonePosition(targetBone, targetPos, dummy); 36 | fallbackPos = false; 37 | } 38 | } 39 | 40 | if (fallbackPos) 41 | targetPos = ent->EyePosition(); 42 | 43 | QAngle idealAngles = ent->EyeAngles(); 44 | for (uint_fast8_t i = 0; i < 3; i++) 45 | { 46 | idealAngles[i] = AngleNormalize(m_Ruleset.m_Angle[i].GetValue(idealAngles[i])); 47 | 48 | if (m_Ruleset.m_DPS[i] >= 0) 49 | idealAngles[i] = ApproachAngle(idealAngles[i], m_Angles[i], m_Ruleset.m_DPS[i] * dt); 50 | } 51 | 52 | const Vector idealPos = CalcPosForAngle(targetPos, idealAngles); 53 | 54 | m_Angles = idealAngles; 55 | m_Origin = idealPos; 56 | } 57 | 58 | Vector TPLockCamera::CalcPosForAngle(const Vector& orbitCenter, const QAngle& angle) const 59 | { 60 | Vector forward, right, up; 61 | AngleVectors(angle, &forward, &right, &up); 62 | 63 | Vector idealPos = orbitCenter + forward * m_Ruleset.m_Pos[1]; 64 | idealPos += right * m_Ruleset.m_Pos[0]; 65 | idealPos += up * m_Ruleset.m_Pos[2]; 66 | 67 | const Vector camDir = (idealPos - orbitCenter).Normalized(); 68 | const float dist = orbitCenter.DistTo(idealPos); 69 | 70 | // clip against walls 71 | trace_t trace; 72 | 73 | CTraceFilterNoNPCsOrPlayer noPlayers(nullptr, COLLISION_GROUP_NONE); 74 | UTIL_TraceHull(orbitCenter, idealPos, WALL_MIN, WALL_MAX, MASK_OPAQUE | MASK_SOLID, &noPlayers, &trace); 75 | 76 | const float wallDist = (trace.endpos - orbitCenter).Length(); 77 | 78 | return orbitCenter + camDir * wallDist;; 79 | } 80 | 81 | float TPLockValue::GetValue(float input) const 82 | { 83 | switch (m_Mode) 84 | { 85 | case Mode::Set: 86 | return m_Value; 87 | case Mode::Add: 88 | return input + m_Value; 89 | case Mode::Scale: 90 | return input * m_Value; 91 | case Mode::ScaleAdd: 92 | return input * m_Value + m_Base; 93 | } 94 | 95 | Assert(!"Should never get here..."); 96 | return NAN; 97 | } 98 | -------------------------------------------------------------------------------- /CastingEssentials/Modules/Camera/TPLockCamera.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | #include "Modules/Camera/ICamera.h" 3 | 4 | #include 5 | 6 | #include 7 | 8 | class C_BaseEntity; 9 | 10 | struct TPLockValue 11 | { 12 | enum class Mode 13 | { 14 | Set, 15 | Add, 16 | Scale, 17 | ScaleAdd, 18 | }; 19 | 20 | Mode m_Mode; 21 | float m_Value; 22 | float m_Base; 23 | 24 | float GetValue(float input) const; 25 | }; 26 | 27 | struct TPLockRuleset 28 | { 29 | Vector m_Pos; 30 | std::array m_Angle; 31 | std::array m_DPS; 32 | std::string m_Bone; 33 | }; 34 | 35 | class TPLockCamera final : public ICamera 36 | { 37 | public: 38 | TPLockCamera(CHandle entity); 39 | 40 | void Reset() override {} 41 | int GetAttachedEntity() const override { return m_Entity.GetEntryIndex(); } 42 | 43 | const char* GetDebugName() const override { return "TPLockCamera"; } 44 | 45 | TPLockRuleset m_Ruleset; 46 | using ICamera::m_FOV; 47 | 48 | CHandle m_Entity; 49 | 50 | protected: 51 | // Based off of player position, never collapse 52 | bool IsCollapsible() const override { return false; } 53 | void Update(float dt, uint32_t frame) override; 54 | 55 | private: 56 | Vector CalcPosForAngle(const Vector& orbitCenter, const QAngle& angle) const; 57 | }; 58 | -------------------------------------------------------------------------------- /CastingEssentials/Modules/CameraAutoSwitch.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include "PluginBase/Modules.h" 4 | 5 | #include 6 | #include 7 | 8 | class CameraAutoSwitch final : public Module, IGameEventListener2 9 | { 10 | public: 11 | CameraAutoSwitch(); 12 | virtual ~CameraAutoSwitch(); 13 | 14 | static bool CheckDependencies(); 15 | static constexpr __forceinline const char* GetModuleName() { return "Camera Auto-Switch"; } 16 | 17 | private: 18 | ConVar ce_cameraautoswitch_enabled; 19 | ConVar ce_cameraautoswitch_killer; 20 | ConVar ce_cameraautoswitch_killer_delay; 21 | void ToggleKillerEnabled(IConVar *var, const char *pOldValue, float flOldValue); 22 | 23 | void QueueSwitchToPlayer(int player, int fromPlayer, float delay); 24 | bool m_AutoSwitchQueued; 25 | int m_AutoSwitchFromPlayer; 26 | int m_AutoSwitchToPlayer; 27 | float m_AutoSwitchTime; 28 | 29 | void FireGameEvent(IGameEvent *event) override; 30 | void OnPlayerDeath(IGameEvent* event); 31 | 32 | void OnTick(bool inGame) override; 33 | }; 34 | -------------------------------------------------------------------------------- /CastingEssentials/Modules/CameraSmooths.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include "Modules/Camera/CameraStateCallbacks.h" 4 | #include "Modules/Camera/ICameraSmooth.h" 5 | #include "PluginBase/Modules.h" 6 | 7 | #include 8 | #include 9 | #include 10 | 11 | #include 12 | 13 | class ConVar; 14 | class IConVar; 15 | class C_BaseEntity; 16 | 17 | class CameraSmooths final : public Module, CameraStateCallbacks 18 | { 19 | public: 20 | CameraSmooths(); 21 | 22 | static bool CheckDependencies(); 23 | static constexpr __forceinline const char* GetModuleName() { return "Camera Smooths"; } 24 | 25 | protected: 26 | void LevelInit() override; 27 | 28 | private: 29 | ConVar ce_smoothing_enabled; 30 | ConVar ce_smoothing_fov; 31 | ConVar ce_smoothing_force_distance; 32 | ConVar ce_smoothing_max_distance; 33 | 34 | ConVar ce_smoothing_rate; 35 | ConVar ce_smoothing_rate_dist_exp; 36 | 37 | ConVar ce_smoothing_debug; 38 | ConVar ce_smoothing_debug_los; 39 | 40 | ConVar ce_smoothing_los_buffer; 41 | ConVar ce_smoothing_los_min; 42 | 43 | ConVar ce_smoothing_cooldown; 44 | float m_LastSmoothEnd; 45 | 46 | void SetupCameraSmooth(const CameraPtr& currentCamera, CameraPtr& targetCamera, const SmoothSettings& settings) override; 47 | 48 | float TestVisibility(const Vector& eyePos, const Vector& targetPos) const; 49 | 50 | static constexpr Color DBGMSG_COLOR = Color(255, 205, 68, 255); 51 | }; 52 | -------------------------------------------------------------------------------- /CastingEssentials/Modules/CameraTools.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | #include "PluginBase/EntityOffset.h" 3 | #include "PluginBase/Hook.h" 4 | #include "PluginBase/Modules.h" 5 | 6 | #include "Modules/Camera/CameraStateCallbacks.h" 7 | 8 | #include 9 | #include 10 | #include 11 | 12 | #include 13 | #include 14 | 15 | enum class TFTeam; 16 | enum class TFClassType; 17 | 18 | class CCommand; 19 | class IHandleEntity; 20 | class KeyValues; 21 | class C_HLTVCamera; 22 | class C_BaseEntity; 23 | class Player; 24 | 25 | class CameraTools final : public Module, CameraStateCallbacks 26 | { 27 | public: 28 | CameraTools(); 29 | virtual ~CameraTools() = default; 30 | 31 | static bool CheckDependencies(); 32 | static constexpr __forceinline const char* GetModuleName() { return "Camera Tools"; } 33 | 34 | void SpecPosition(const Vector& pos, const QAngle& angle, ObserverMode mode = OBS_MODE_FIXED, float fov = INFINITY); 35 | 36 | static float CollisionTest3D(const Vector& startPos, const Vector& targetPos, float scale, 37 | const IHandleEntity* ignoreEnt = nullptr); 38 | 39 | static void GetSmoothTestSettings(const std::string_view& testsString, SmoothSettings& settings); 40 | 41 | protected: 42 | void SpecModeChanged(ObserverMode oldMode, ObserverMode& newMode) override; 43 | void SpecTargetChanged(IClientEntity* oldEnt, IClientEntity*& newEnt) override; 44 | 45 | private: 46 | ConVar ce_cameratools_autodirector_mode; 47 | ConVar ce_cameratools_force_target; 48 | ConVar ce_cameratools_disable_view_punches; 49 | 50 | ConCommand ce_cameratools_spec_pos; 51 | ConCommand ce_cameratools_spec_pos_delta; 52 | ConCommand ce_cameratools_spec_class; 53 | ConCommand ce_cameratools_spec_steamid; 54 | ConCommand ce_cameratools_spec_index; 55 | ConCommand ce_cameratools_spec_entindex; 56 | 57 | ConCommand ce_cameratools_show_users; 58 | void ShowUsers(const CCommand& command); 59 | 60 | bool ParseSpecPosCommand(const CCommand& command, Vector& pos, QAngle& angle, ObserverMode& mode, 61 | const Vector& defaultPos, const QAngle& defaultAng, ObserverMode defaultMode) const; 62 | void SpecPosition(const CCommand &command); 63 | void SpecPositionDelta(const CCommand& command); 64 | 65 | void SpecClass(const CCommand& command); 66 | void SpecClass(TFTeam team, TFClassType playerClass, int classIndex); 67 | void SpecSteamID(const CCommand& command); 68 | void SpecIndex(const CCommand& command); 69 | void SpecEntIndex(const CCommand& command); 70 | void SpecPlayer(int playerIndex); 71 | 72 | ConCommand ce_cameratools_smoothto; 73 | static void SmoothTo(const CCommand& cmd); 74 | 75 | void ToggleDisableViewPunches(const ConVar* var); 76 | VariablePusher m_vecPunchAngleProxy; 77 | VariablePusher m_vecPunchAngleVelProxy; 78 | }; 79 | -------------------------------------------------------------------------------- /CastingEssentials/Modules/ClientTools.cpp: -------------------------------------------------------------------------------- 1 | #include "Modules/ClientTools.h" 2 | #include "PluginBase/HookManager.h" 3 | 4 | #define WIN32_LEAN_AND_MEAN 5 | #include 6 | 7 | MODULE_REGISTER(ClientTools); 8 | 9 | ClientTools::ClientTools() : 10 | ce_clienttools_windowtitle("ce_clienttools_windowtitle", "", FCVAR_NONE, "Overrides the game window title", 11 | [](IConVar* var, const char* oldval, float foldval) { GetModule()->UpdateWindowTitle(oldval); }) 12 | { 13 | 14 | } 15 | 16 | HWND GetMainWindow() 17 | { 18 | class IGame 19 | { 20 | public: 21 | virtual ~IGame(void) { } 22 | virtual bool Init(void *pvInstance) = 0; 23 | virtual bool Shutdown(void) = 0; 24 | virtual bool CreateGameWindow(void) = 0; 25 | virtual void DestroyGameWindow(void) = 0; 26 | virtual void SetGameWindow(void* hWnd) = 0; 27 | virtual bool InputAttachToGameWindow() = 0; 28 | virtual void InputDetachFromGameWindow() = 0; 29 | virtual void PlayStartupVideos(void) = 0; 30 | virtual void* GetMainWindow(void) = 0; 31 | virtual void** GetMainWindowAddress(void) = 0; 32 | virtual void GetDesktopInfo(int &width, int &height, int &refreshrate) = 0; 33 | virtual void SetWindowXY(int x, int y) = 0; 34 | virtual void SetWindowSize(int w, int h) = 0; 35 | virtual void GetWindowRect(int *x, int *y, int *w, int *h) = 0; 36 | virtual bool IsActiveApp(void) = 0; 37 | virtual void DispatchAllStoredGameMessages() = 0; 38 | }; 39 | 40 | static IGame* g_pGame = nullptr; 41 | if (!g_pGame) 42 | { 43 | constexpr auto SIG = "\x55\x8B\xEC\x83\xEC\x14\x8B\x0D\x00\x00\x00\x00\xC7\x45\xEC\x14\x00\x00\x00\x8B\x01\xFF\x50\x24\x89\x45\xF0\x8D\x45\xEC\x50\xC7\x45\xF4\x03\x00\x00\x00\xC7\x45\xF8\x05\x00\x00\x00\xC7\x45\xFC\x00\x00\x00\x00\xFF\x15\x00\x00\x00\x00\x8B\xE5\x5D\xC3"; 44 | constexpr auto MASK = "xxxxxxxx????xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx????xxxx"; 45 | constexpr auto OFFSET = 8; 46 | 47 | auto target = (IGame***)((char*)SignatureScan("engine", SIG, MASK) + OFFSET); 48 | if (target == (IGame***)OFFSET) 49 | throw bad_pointer("CGame"); 50 | 51 | g_pGame = **target; 52 | } 53 | return (HWND)g_pGame->GetMainWindow(); 54 | } 55 | 56 | bool ClientTools::CheckDependencies() 57 | { 58 | bool ready = true; 59 | 60 | try 61 | { 62 | GetMainWindow(); 63 | } 64 | catch (const bad_pointer& ptrException) 65 | { 66 | PluginWarning("Required interface %s for module %s not available!\n", ptrException.what(), GetModuleName()); 67 | ready = false; 68 | } 69 | 70 | return ready; 71 | } 72 | 73 | void ClientTools::UpdateWindowTitle(const char* oldval) 74 | { 75 | auto newval = ce_clienttools_windowtitle.GetString(); 76 | if (!newval[0]) 77 | { 78 | if (oldval[0]) 79 | SetWindowText(GetMainWindow(), m_OriginalTitle.c_str()); 80 | } 81 | else 82 | { 83 | if (m_OriginalTitle.empty()) 84 | { 85 | const auto length = GetWindowTextLength(GetMainWindow()) + 1; 86 | m_OriginalTitle.resize(length); 87 | GetWindowText(GetMainWindow(), m_OriginalTitle.data(), length); 88 | } 89 | 90 | SetWindowText(GetMainWindow(), newval); 91 | } 92 | } -------------------------------------------------------------------------------- /CastingEssentials/Modules/ClientTools.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include "PluginBase/Modules.h" 4 | 5 | #include 6 | 7 | class ClientTools : public Module 8 | { 9 | public: 10 | ClientTools(); 11 | 12 | static bool CheckDependencies(); 13 | static constexpr __forceinline const char* GetModuleName() { return "Client Tools"; } 14 | 15 | private: 16 | void UpdateWindowTitle(const char* oldval); 17 | 18 | ConVar ce_clienttools_windowtitle; 19 | 20 | std::string m_OriginalTitle; 21 | }; 22 | -------------------------------------------------------------------------------- /CastingEssentials/Modules/ConsoleTools.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | #include "Misc/CommandCallbacks.h" 3 | #include "PluginBase/Hook.h" 4 | #include "PluginBase/Modules.h" 5 | 6 | #include 7 | 8 | #include 9 | #include 10 | 11 | class ConsoleTools final : public Module 12 | { 13 | public: 14 | ConsoleTools(); 15 | 16 | static bool CheckDependencies(); 17 | static constexpr __forceinline const char* GetModuleName() { return "Console Tools"; } 18 | 19 | private: 20 | void ConsoleColorPrintfHook(const Color& color, const char* msg); 21 | void ConsoleDPrintfHook(const char* msg); 22 | void ConsolePrintfHook(const char* msg); 23 | 24 | bool CheckFilters(const char* msg) const; 25 | 26 | Hook m_ConsoleColorPrintfHook; 27 | Hook m_ConsoleDPrintfHook; 28 | Hook m_ConsolePrintfHook; 29 | 30 | std::unordered_map m_Filters; 31 | 32 | ConVar ce_consoletools_filter_enabled; 33 | ConCommand ce_consoletools_filter_add; 34 | ConCommand ce_consoletools_filter_remove; 35 | ConCommand ce_consoletools_filter_list; 36 | 37 | ConCommand ce_consoletools_flags_add; 38 | ConCommand ce_consoletools_flags_remove; 39 | 40 | ConCommand ce_consoletools_limits_set; 41 | 42 | ConCommand ce_consoletools_alias_remove; 43 | 44 | ConCommand ce_consoletools_unhide_all_cvars; 45 | static void UnhideAllCvars(); 46 | 47 | void AddFilter(const CCommand& command); 48 | void RemoveFilter(const CCommand& command); 49 | void ListFilters(const CCommand& command); 50 | void ToggleFilterEnabled(const ConVar* var); 51 | 52 | CommandCallbacks m_SetLimitsCallbacks; 53 | static void SetLimits(const CCommand& command); 54 | static void SetLimitsAutocomplete(const CCommand& partial, CUtlVector& suggestions); 55 | 56 | CommandCallbacks m_AddFlagsCallbacks; 57 | CommandCallbacks m_RemoveFlagsCallbacks; 58 | static void AddFlags(const CCommand& command); 59 | static void RemoveFlags(const CCommand& command); 60 | static void FlagModifyAutocomplete(const CCommand& partial, CUtlVector& suggestions); 61 | 62 | CommandCallbacks m_RemoveAliasCallbacks; 63 | static void RemoveAlias(const CCommand& command); 64 | static void RemoveAliasAutocomplete(const CCommand& partial, CUtlVector& suggestions); 65 | 66 | class PauseFilter; 67 | int m_FilterPaused; 68 | 69 | static int ParseFlags(const CCommand& command); 70 | }; -------------------------------------------------------------------------------- /CastingEssentials/Modules/ExternalMinimap.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include "PluginBase/Modules.h" 4 | 5 | #include 6 | #include 7 | #include 8 | 9 | class ExternalMinimap final : public Module, CAutoGameSystemPerFrame 10 | { 11 | public: 12 | ExternalMinimap(); 13 | ~ExternalMinimap(); 14 | static constexpr __forceinline const char* GetModuleName() { return "External Minimap"; } 15 | 16 | static bool CheckDependencies(); 17 | 18 | protected: 19 | void LevelInit() override; 20 | void Update(float frametime) override; 21 | void PostRender() override; 22 | void LevelShutdown() override; 23 | 24 | private: 25 | ConVar ce_minimap_enabled; 26 | 27 | ConCommand ce_minimap_capture; 28 | bool m_CaptureQueued = false; 29 | void QueueCapture(const CCommand& cmd); 30 | void RunCapture(); 31 | 32 | #pragma pack(push, 1) 33 | struct MinimapData 34 | { 35 | struct Player 36 | { 37 | char m_Name[32]; 38 | 39 | Vector m_Position; 40 | QAngle m_Angles; 41 | 42 | uint8_t m_Class; 43 | uint8_t m_Team; 44 | 45 | uint16_t m_Health; 46 | uint16_t m_MaxHealth; 47 | uint16_t m_MaxOverheal; 48 | }; 49 | 50 | char m_MapName[260]; 51 | 52 | uint8_t m_PlayerCount; 53 | Player m_Players[MAX_PLAYERS]; 54 | }; 55 | #pragma pack(pop) 56 | 57 | static constexpr auto size = sizeof(MinimapData); 58 | static constexpr auto test = offsetof(MinimapData, m_Players); 59 | 60 | MinimapData* m_Data = nullptr; 61 | void* m_SharedMemHandle = nullptr; 62 | }; 63 | -------------------------------------------------------------------------------- /CastingEssentials/Modules/FreezeInfo.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include "PluginBase/Hook.h" 4 | #include "PluginBase/Modules.h" 5 | 6 | #include 7 | 8 | class FreezeInfo final : public Module 9 | { 10 | public: 11 | FreezeInfo(); 12 | 13 | static bool CheckDependencies(); 14 | static constexpr __forceinline const char* GetModuleName() { return "Freeze Info"; } 15 | 16 | private: 17 | void OnTick(bool inGame) override; 18 | 19 | class Panel; 20 | std::unique_ptr m_Panel; 21 | 22 | void PostEntityPacketReceivedHook(); 23 | Hook m_PostEntityPacketReceivedHook; 24 | 25 | ConVar ce_freezeinfo_enabled; 26 | ConVar ce_freezeinfo_threshold; 27 | ConCommand ce_freezeinfo_reload_settings; 28 | 29 | void ChangeThreshold(IConVar *var, const char *pOldValue, float flOldValue); 30 | void ReloadSettings(); 31 | void ToggleEnabled(const ConVar *var); 32 | }; -------------------------------------------------------------------------------- /CastingEssentials/Modules/HitEvents.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include "PluginBase/Hook.h" 4 | #include "PluginBase/Modules.h" 5 | 6 | #include 7 | #include 8 | #include 9 | 10 | #include 11 | 12 | class C_BaseCombatCharacter; 13 | class CAccountPanel; 14 | class CDamageAccountPanel; 15 | class C_TFPlayer; 16 | class IHandleEntity; 17 | using trace_t = class CGameTrace; 18 | 19 | class HitEvents final : public Module 20 | { 21 | public: 22 | HitEvents(); 23 | 24 | static bool CheckDependencies() { return true; } 25 | static constexpr __forceinline const char* GetModuleName() { return "Player Hit Events"; } 26 | 27 | protected: 28 | void LevelInit() override; 29 | void LevelShutdown() override; 30 | 31 | private: 32 | std::vector m_EventsToIgnore; 33 | 34 | void UpdateEnabledState(); 35 | 36 | void FireGameEventOverride(CDamageAccountPanel* pThis, IGameEvent* event); 37 | 38 | bool m_OverrideUTILTraceline; 39 | void UTILTracelineOverride(const Vector& vecAbsStart, const Vector& vecAbsEnd, unsigned int mask, const IHandleEntity* ignore, int collisionGroup, trace_t* ptr); 40 | 41 | bool DamageAccountPanelShouldDrawOverride(CDamageAccountPanel* pThis); 42 | 43 | Hook m_FireGameEventHook; 44 | Hook m_UTILTracelineHook; 45 | Hook m_DamageAccountPanelShouldDrawHook; 46 | 47 | CAccountPanel* m_LastDamageAccount; 48 | 49 | ConVar ce_hitevents_enabled; 50 | ConVar ce_hitevents_dmgnumbers_los; 51 | }; -------------------------------------------------------------------------------- /CastingEssentials/Modules/IngameTeamScores.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include "PluginBase/Modules.h" 4 | 5 | #include 6 | 7 | class IngameTeamScores final : public Module 8 | { 9 | public: 10 | IngameTeamScores(); 11 | static constexpr __forceinline const char* GetModuleName() { return "Ingame Team Scores"; } 12 | 13 | private: 14 | void ReloadSettings(); 15 | 16 | class ScorePanel; 17 | std::unique_ptr m_Panel; 18 | 19 | void OnTick(bool inGame) override; 20 | 21 | ConVar ce_teamscores_enabled; 22 | ConCommand ce_teamscores_reload; 23 | 24 | ConVar ce_teamscores_delta_blu; 25 | ConVar ce_teamscores_delta_red; 26 | 27 | static constexpr int CUSTOM_TEXT_COUNT = 4; 28 | 29 | std::unique_ptr ce_teamscores_text[CUSTOM_TEXT_COUNT]; 30 | char ce_teamscores_text_names[CUSTOM_TEXT_COUNT][32]; 31 | char ce_teamscores_text_helpstrings[CUSTOM_TEXT_COUNT][64]; 32 | }; -------------------------------------------------------------------------------- /CastingEssentials/Modules/ItemSchema.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include "PluginBase/Modules.h" 4 | 5 | #include 6 | 7 | #include 8 | #include 9 | #include 10 | #include 11 | 12 | class ConCommand; 13 | class ConVar; 14 | class IConVar; 15 | class KeyValues; 16 | 17 | class ItemSchema : public Module 18 | { 19 | public: 20 | ItemSchema(); 21 | 22 | static bool CheckDependencies(); 23 | static constexpr __forceinline const char* GetModuleName() { return "Item Schema"; } 24 | 25 | // Converts a "specialized" version of an item (a botkiller medigun, for example) into its 26 | // "base" item (a stock medigun) 27 | int GetBaseItemID(int specializedID) const; 28 | 29 | private: 30 | ConCommand ce_itemschema_print; 31 | ConCommand ce_itemschema_reload; 32 | 33 | void PrintAliases(); 34 | 35 | void LevelInit() override; 36 | void LoadItemSchema(); 37 | 38 | static void GetFirstPrefabType(const char* prefabsGroup, char* prefabOut, size_t maxOutSize); 39 | int GetFirstItemUsingPrefab(KeyValues* items, const char* prefabName); 40 | 41 | enum class ItemEquipSlot 42 | { 43 | Primary, 44 | Secondary, 45 | Melee, 46 | PDA, 47 | PDA2, 48 | Building, 49 | 50 | Action, 51 | Utility, 52 | Taunt, 53 | 54 | Head, 55 | Misc, 56 | 57 | Quest, 58 | 59 | Unspecified, 60 | }; 61 | 62 | struct ItemProperties 63 | { 64 | std::string m_Name; 65 | std::vector m_Prefabs; 66 | std::vector m_PrefabNames; 67 | std::string m_XifierClassRemap; 68 | std::string m_CraftClass; 69 | std::string m_PlayerModel; 70 | std::string m_IconName; 71 | ItemEquipSlot m_EquipSlot; 72 | 73 | const std::string& GetXifierClassRemap() const; 74 | const std::string& GetCraftClass() const; 75 | const std::string& GetPlayerModel() const; 76 | const std::string& GetIconName() const; 77 | bool HasPrefab(const char* prefabName) const; 78 | ItemEquipSlot GetEquipSlot() const; 79 | }; 80 | 81 | void LoadItemProperties(KeyValues* propsIn, ItemProperties& propsOut); 82 | 83 | struct ItemPrefab : public ItemProperties 84 | { 85 | }; 86 | 87 | struct ItemEntry : public ItemProperties 88 | { 89 | unsigned int m_ID; 90 | }; 91 | 92 | struct ItemRemap 93 | { 94 | std::string m_FromModel; 95 | unsigned int m_FromID; 96 | bool FromMatch(const ItemEntry& entry) const; 97 | 98 | unsigned int m_ToID; 99 | 100 | bool IsUnmap() const { return m_FromModel.empty() && m_FromID == m_ToID; } 101 | }; 102 | 103 | std::vector m_Remaps; 104 | void LoadOverrides(const std::forward_list& items); 105 | bool HasOverride() const; 106 | 107 | ItemPrefab* FindPrefab(const char* prefabName); 108 | void LoadPrefabs(KeyValues* prefabs); 109 | void LinkPrefabs(); 110 | 111 | bool m_PrefabsLinked = false; 112 | std::forward_list m_Prefabs; 113 | 114 | void LoadItems(KeyValues* inItems, std::forward_list& outItems); 115 | void LoadUniqueItems(std::forward_list& items); 116 | 117 | struct UniqueItemEntry 118 | { 119 | // If true, this weapon is not accurately represented by its default 120 | // ingame model. Don't automatically map children to this 121 | // UniqueItemEntry just because they match the model name. 122 | bool m_IsForceUnmapped = false; 123 | ItemEntry* m_MasterEntry = nullptr; 124 | std::vector m_Remaps; 125 | std::forward_list m_Entries; 126 | 127 | unsigned int GetLowestID() const; 128 | }; 129 | 130 | UniqueItemEntry* FindItemInUniqueItems(const std::string& partModelName); 131 | 132 | void ApplyUniqueItemOverrides(); 133 | std::forward_list m_UniqueItems; 134 | 135 | std::map m_Mappings; 136 | }; -------------------------------------------------------------------------------- /CastingEssentials/Modules/Killfeed.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | #include "PluginBase/Modules.h" 3 | 4 | #include 5 | 6 | class ConVarRef; 7 | 8 | class Killfeed final : public Module 9 | { 10 | public: 11 | Killfeed(); 12 | static constexpr __forceinline const char* GetModuleName() { return "Killfeed Fixes"; } 13 | 14 | private: 15 | ConVar ce_killfeed_continuous_update; 16 | 17 | class DeathNoticePanelOverride : public CHudBaseDeathNotice 18 | { 19 | public: 20 | ~DeathNoticePanelOverride() { } 21 | using CHudBaseDeathNotice::m_DeathNotices; 22 | }; 23 | 24 | enum EDeathNoticeIconFormat 25 | { 26 | kDeathNoticeIcon_Standard, 27 | kDeathNoticeIcon_Inverted, // used for display on lighter background when kill involved the local player 28 | }; 29 | 30 | static DeathNoticePanelOverride* FindDeathNoticePanel(); 31 | DeathNoticePanelOverride* m_DeathNoticePanel; 32 | 33 | static constexpr int DEATH_NOTICES_OFFSET = 448; 34 | CUtlVector* m_DeathNotices; 35 | 36 | void OnTick(bool inGame) override; 37 | }; -------------------------------------------------------------------------------- /CastingEssentials/Modules/Killstreaks.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include "PluginBase/Entities.h" 4 | #include "PluginBase/Hook.h" 5 | #include "PluginBase/Modules.h" 6 | 7 | #include 8 | #include 9 | 10 | #include 11 | #include 12 | 13 | class C_BaseEntity; 14 | 15 | class Killstreaks : public Module 16 | { 17 | public: 18 | Killstreaks(); 19 | 20 | static bool CheckDependencies(); 21 | static constexpr __forceinline const char* GetModuleName() { return "Killstreaks"; } 22 | 23 | protected: 24 | void OnTick(bool inGame) override; 25 | 26 | private: 27 | ConVar ce_killstreaks_enabled; 28 | ConVar ce_killstreaks_debug; 29 | void UpdateKillstreaks(bool inGame); 30 | 31 | ConVar ce_killstreaks_hide_firstperson_effects; 32 | void HideFirstPersonEffects() const; 33 | 34 | bool FireEventClientSideOverride(IGameEvent *event); 35 | 36 | int m_BluTopKillstreak; 37 | int m_BluTopKillstreakPlayer; 38 | int m_RedTopKillstreak; 39 | int m_RedTopKillstreakPlayer; 40 | 41 | std::map m_CurrentKillstreaks; 42 | Hook m_FireEventClientSideHook; 43 | 44 | static std::array, 4> s_PlayerStreaks; 45 | static EntityOffset s_MedigunHealing; 46 | static EntityOffset> s_MedigunHealingTarget; 47 | static EntityTypeChecker s_MedigunType; 48 | }; -------------------------------------------------------------------------------- /CastingEssentials/Modules/LoadoutIcons.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | #include "PluginBase/Modules.h" 3 | 4 | #include 5 | #include 6 | 7 | class IClientNetworkable; 8 | 9 | namespace vgui 10 | { 11 | class Panel; 12 | class ImagePanel; 13 | class EditablePanel; 14 | typedef unsigned int VPANEL; 15 | } 16 | 17 | class LoadoutIcons : public Module 18 | { 19 | public: 20 | LoadoutIcons(); 21 | 22 | static bool CheckDependencies(); 23 | static constexpr __forceinline const char* GetModuleName() { return "Loadout Icons"; } 24 | 25 | protected: 26 | void OnTick(bool ingame) override; 27 | 28 | private: 29 | void GatherWeapons(); 30 | void DrawIcons(); 31 | void PlayerPanelUpdateIcons(vgui::EditablePanel* playerPanel); 32 | 33 | static int GetPlayerIndex(vgui::EditablePanel* playerPanel); 34 | 35 | ConVar ce_loadout_enabled; 36 | ConVar ce_loadout_filter_active_red; 37 | ConVar ce_loadout_filter_active_blu; 38 | ConVar ce_loadout_filter_inactive_red; 39 | ConVar ce_loadout_filter_inactive_blu; 40 | 41 | enum ItemIndex 42 | { 43 | IDX_1, 44 | IDX_2, 45 | IDX_3, 46 | IDX_4, 47 | IDX_5, 48 | 49 | IDX_ACTIVE, 50 | 51 | ITEM_COUNT, 52 | }; 53 | 54 | static constexpr const char* LOADOUT_ICONS[ITEM_COUNT][2] = 55 | { 56 | { "LoadoutIconsItem1Red", "LoadoutIconsItem1Blue" }, 57 | { "LoadoutIconsItem2Red", "LoadoutIconsItem2Blue" }, 58 | { "LoadoutIconsItem3Red", "LoadoutIconsItem3Blue" }, 59 | { "LoadoutIconsItem4Red", "LoadoutIconsItem4Blue" }, 60 | { "LoadoutIconsItem5Red", "LoadoutIconsItem5Blue" }, 61 | { "LoadoutIconsActiveItemRed", "LoadoutIconsActiveItemBlue" }, 62 | }; 63 | 64 | byte m_ActiveWeaponIndices[MAX_PLAYERS]; // Index into m_Weapons 65 | int m_Weapons[MAX_PLAYERS][ITEM_COUNT]; 66 | }; -------------------------------------------------------------------------------- /CastingEssentials/Modules/LocalPlayer.cpp: -------------------------------------------------------------------------------- 1 | #include "LocalPlayer.h" 2 | #include "Modules/CameraState.h" 3 | #include "PluginBase/HookManager.h" 4 | #include "PluginBase/Interfaces.h" 5 | #include "PluginBase/Player.h" 6 | #include "Controls/StubPanel.h" 7 | 8 | #include 9 | #include 10 | #include 11 | #include 12 | #include 13 | #include 14 | #include 15 | #include 16 | 17 | #include 18 | 19 | MODULE_REGISTER(LocalPlayer); 20 | 21 | LocalPlayer::LocalPlayer() : 22 | ce_localplayer_enabled("ce_localplayer_enabled", "0", FCVAR_NONE, "enable local player override", 23 | [](IConVar *var, const char*, float) { GetModule()->ToggleEnabled(static_cast(var)); }), 24 | ce_localplayer_player("ce_localplayer_player", "0", FCVAR_NONE, "player index to set as the local player"), 25 | ce_localplayer_set_current_target("ce_localplayer_set_current_target", []() { GetModule()->SetToCurrentTarget(); }, 26 | "set the local player to the current spectator target"), 27 | ce_localplayer_track_spec_target("ce_localplayer_track_spec_target", "0", FCVAR_NONE, "have the local player value track the spectator target"), 28 | 29 | m_GetLocalPlayerIndexHook(std::bind(&LocalPlayer::GetLocalPlayerIndexOverride, this)) 30 | { 31 | } 32 | 33 | bool LocalPlayer::CheckDependencies() 34 | { 35 | bool ready = true; 36 | 37 | if (!Interfaces::GetClientDLL()) 38 | { 39 | PluginWarning("Required interface IBaseClientDLL for module %s not available!\n", GetModuleName()); 40 | ready = false; 41 | } 42 | 43 | if (!Interfaces::GetEngineClient()) 44 | { 45 | PluginWarning("Required interface IVEngineClient for module %s not available!\n", GetModuleName()); 46 | ready = false; 47 | } 48 | 49 | if (!Interfaces::GetHLTVCamera()) 50 | { 51 | PluginWarning("Required interface C_HLTVCamera for module %s not available!\n", GetModuleName()); 52 | ready = false; 53 | } 54 | 55 | try 56 | { 57 | HookManager::GetRawFunc(); 58 | } 59 | catch (bad_pointer) 60 | { 61 | PluginWarning("Required function GetLocalPlayerIndex for module %s not available!\n", GetModuleName()); 62 | ready = false; 63 | } 64 | 65 | return ready; 66 | } 67 | 68 | int LocalPlayer::GetLocalPlayerIndexOverride() 69 | { 70 | VPROF_BUDGET(__FUNCTION__, VPROF_BUDGETGROUP_CE); 71 | if (ce_localplayer_enabled.GetBool() && Player::IsValidIndex(ce_localplayer_player.GetInt())) 72 | { 73 | Player* localPlayer = Player::GetPlayer(ce_localplayer_player.GetInt(), __FUNCSIG__); 74 | if (localPlayer) 75 | { 76 | GetHooks()->GetHook()->SetState(Hooking::HookAction::SUPERCEDE); 77 | return ce_localplayer_player.GetInt(); 78 | } 79 | } 80 | 81 | return 0; 82 | } 83 | 84 | void LocalPlayer::ToggleEnabled(const ConVar *var) 85 | { 86 | m_GetLocalPlayerIndexHook.SetEnabled(var->GetBool()); 87 | } 88 | 89 | void LocalPlayer::SetToCurrentTarget() 90 | { 91 | auto localMode = CameraState::GetModule()->GetLocalObserverMode(); 92 | 93 | if (localMode == OBS_MODE_FIXED || 94 | localMode == OBS_MODE_IN_EYE || 95 | localMode == OBS_MODE_CHASE) 96 | { 97 | Player* targetPlayer = Player::AsPlayer(CameraState::GetModule()->GetLocalObserverTarget()); 98 | 99 | if (targetPlayer) 100 | { 101 | ce_localplayer_player.SetValue(targetPlayer->GetEntity()->entindex()); 102 | return; 103 | } 104 | } 105 | 106 | ce_localplayer_player.SetValue(Interfaces::GetEngineClient()->GetLocalPlayer()); 107 | } 108 | 109 | void LocalPlayer::OnTick(bool inGame) 110 | { 111 | VPROF_BUDGET(__FUNCTION__, VPROF_BUDGETGROUP_CE); 112 | 113 | if (!inGame) 114 | return; 115 | 116 | if (ce_localplayer_track_spec_target.GetBool()) 117 | SetToCurrentTarget(); 118 | } 119 | -------------------------------------------------------------------------------- /CastingEssentials/Modules/LocalPlayer.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | #include "PluginBase/Hook.h" 3 | #include "PluginBase/Modules.h" 4 | 5 | #include 6 | 7 | #include 8 | 9 | class LocalPlayer : public Module 10 | { 11 | public: 12 | LocalPlayer(); 13 | 14 | static bool CheckDependencies(); 15 | static constexpr __forceinline const char* GetModuleName() { return "Local Player"; } 16 | 17 | private: 18 | void OnTick(bool inGame) override; 19 | 20 | int GetLocalPlayerIndexOverride(); 21 | 22 | Hook m_GetLocalPlayerIndexHook; 23 | 24 | ConVar ce_localplayer_enabled; 25 | ConVar ce_localplayer_player; 26 | ConCommand ce_localplayer_set_current_target; 27 | ConVar ce_localplayer_track_spec_target; 28 | void SetToCurrentTarget(); 29 | void ToggleEnabled(const ConVar *var); 30 | }; -------------------------------------------------------------------------------- /CastingEssentials/Modules/MapConfigs.cpp: -------------------------------------------------------------------------------- 1 | #include "MapConfigs.h" 2 | #include "PluginBase/Interfaces.h" 3 | 4 | #include 5 | 6 | MODULE_REGISTER(MapConfigs); 7 | 8 | MapConfigs::MapConfigs() : 9 | ce_mapconfigs_enabled("ce_mapconfigs_enabled", "0", FCVAR_NONE, "If 1, execs cfg/.cfg on mapchange.") 10 | { 11 | } 12 | 13 | void MapConfigs::LevelInit() 14 | { 15 | if (!ce_mapconfigs_enabled.GetBool()) 16 | return; 17 | 18 | const char* const bspName = Interfaces::GetEngineClient()->GetLevelName(); 19 | std::string mapName(bspName); 20 | mapName.erase(mapName.size() - 4, 4); // remove .bsp 21 | mapName.erase(0, 5); // remove /maps/ 22 | 23 | if (Interfaces::GetEngineClient()->IsPlayingDemo() || Interfaces::GetEngineClient()->IsHLTV()) 24 | Interfaces::GetEngineClient()->ExecuteClientCmd(strprintf("exec %s", mapName.c_str()).c_str()); 25 | } 26 | -------------------------------------------------------------------------------- /CastingEssentials/Modules/MapConfigs.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include "PluginBase/Modules.h" 4 | 5 | #include 6 | 7 | class MapConfigs final : public Module 8 | { 9 | public: 10 | MapConfigs(); 11 | static constexpr __forceinline const char* GetModuleName() { return "Map Configs"; } 12 | 13 | private: 14 | ConVar ce_mapconfigs_enabled; 15 | 16 | void LevelInit() override; 17 | }; -------------------------------------------------------------------------------- /CastingEssentials/Modules/MedigunInfo.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include "PluginBase/EntityOffset.h" 4 | #include "PluginBase/Modules.h" 5 | 6 | #include 7 | #include 8 | 9 | enum class TFMedigun; 10 | enum class TFResistType; 11 | enum class TFTeam; 12 | 13 | namespace vgui 14 | { 15 | typedef unsigned int VPANEL; 16 | class EditablePanel; 17 | } 18 | 19 | class MedigunInfo : public Module 20 | { 21 | public: 22 | MedigunInfo(); 23 | 24 | static bool CheckDependencies(); 25 | static constexpr __forceinline const char* GetModuleName() { return "Medigun Info"; } 26 | 27 | protected: 28 | void LevelShutdown() override; 29 | 30 | private: 31 | struct Data 32 | { 33 | bool m_Alive; 34 | float m_Charge; 35 | TFMedigun m_Type; 36 | bool m_Popped; 37 | TFResistType m_ResistType; 38 | TFTeam m_Team; 39 | }; 40 | 41 | void CollectMedigunData(); 42 | std::map m_MedigunPanelData; 43 | 44 | class MainPanel; 45 | std::unique_ptr m_MainPanel; 46 | class MedigunPanel; 47 | 48 | void OnTick(bool inGame) override; 49 | 50 | ConVar ce_mediguninfo_separate_enabled; 51 | ConCommand ce_mediguninfo_separate_reload; 52 | 53 | static EntityOffset s_ChargeRelease; 54 | static EntityOffset s_ChargeResistType; 55 | static EntityOffset s_ChargeLevel; 56 | 57 | void ReloadSettings(); 58 | }; -------------------------------------------------------------------------------- /CastingEssentials/Modules/PlayerAliases.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | #include "PluginBase/Hook.h" 3 | #include "PluginBase/Modules.h" 4 | 5 | #include 6 | 7 | struct player_info_s; 8 | 9 | class PlayerAliases final : public Module 10 | { 11 | public: 12 | PlayerAliases(); 13 | virtual ~PlayerAliases() = default; 14 | 15 | static bool CheckDependencies(); 16 | static constexpr __forceinline const char* GetModuleName() { return "Player Aliases"; } 17 | 18 | private: 19 | bool GetPlayerInfoOverride(int ent_num, player_info_s* pInfo); 20 | 21 | std::map m_CustomAliases; 22 | Hook m_GetPlayerInfoHook; 23 | 24 | static void FindAndReplaceInString(std::string& str, const std::string_view& find, const std::string_view& replace); 25 | 26 | const char* GetAlias(const CSteamID& player) const; 27 | 28 | ConVar ce_playeraliases_enabled; 29 | ConVar ce_playeraliases_format_mode; 30 | ConVar ce_playeraliases_format_blu; 31 | ConVar ce_playeraliases_format_red; 32 | 33 | ConCommand ce_playeraliases_format_swap; 34 | void SwapTeamFormats(); 35 | 36 | ConCommand ce_playeraliases_list; 37 | void PrintPlayerAliases(); 38 | 39 | ConCommand ce_playeraliases_add; 40 | void AddPlayerAlias(const CCommand& command); 41 | ConCommand ce_playeraliases_remove; 42 | void RemovePlayerAlias(const CCommand& command); 43 | 44 | void ToggleEnabled(const ConVar* var); 45 | }; -------------------------------------------------------------------------------- /CastingEssentials/Modules/ProjectileOutlines.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | #include "PluginBase/EntityOffset.h" 3 | #include "PluginBase/Hook.h" 4 | #include "PluginBase/Modules.h" 5 | 6 | #include 7 | #include 8 | 9 | #include 10 | #include 11 | 12 | class C_BaseEntity; 13 | class IClientEntity; 14 | class IConVar; 15 | enum class TFGrenadePipebombType; 16 | 17 | class ProjectileOutlines final : public Module 18 | { 19 | public: 20 | ProjectileOutlines(); 21 | 22 | static bool CheckDependencies(); 23 | static constexpr __forceinline const char* GetModuleName() { return "Projectile Outlines"; } 24 | 25 | private: 26 | ConVar ce_projectileoutlines_rockets; 27 | ConVar ce_projectileoutlines_pills; 28 | ConVar ce_projectileoutlines_stickies; 29 | 30 | ConVar ce_projectileoutlines_mode; 31 | 32 | ConVar ce_projectileoutlines_color_blu; 33 | ConVar ce_projectileoutlines_color_red; 34 | 35 | ConVar ce_projectileoutlines_fade_start; 36 | ConVar ce_projectileoutlines_fade_end; 37 | 38 | void OnTick(bool inGame) override; 39 | 40 | void SoldierGlows(IClientEntity* entity); 41 | void DemoGlows(IClientEntity* entity); 42 | Color CalcProjectileColor(IClientEntity* baseEntity, IClientEntity* glowEntity); 43 | 44 | void CreateGlowForEntity(IClientEntity* ent); 45 | std::unordered_map> m_GlowEntities; 46 | 47 | // Some random numbers I generated 48 | static constexpr int MAGIC_ENTNUM = 0x141BCF9B; 49 | static constexpr int MAGIC_SERIALNUM = 0x0FCAD8B9; 50 | 51 | Hook m_BaseEntityInitHook; 52 | bool InitDetour(C_BaseEntity* pThis, int entnum, int iSerialNum); 53 | 54 | // List of entities that had C_BaseEntity::Init() called on them since our last 55 | // pass through OnTick() 56 | std::vector m_NewEntities; 57 | 58 | bool m_Init; 59 | void ColorChanged(ConVar* var, const char* oldValue); 60 | Color m_ColorRed; 61 | Color m_ColorBlu; 62 | 63 | void UpdateEnabled(); 64 | 65 | static EntityOffset s_GlowDisabledOffset; 66 | static EntityOffset s_GlowModeOffset; 67 | static EntityOffset> s_GlowTargetOffset; 68 | static EntityOffset s_GlowColorOffset; 69 | 70 | static EntityOffset s_PipeTypeOffset; 71 | static const ClientClass* s_RocketType; 72 | }; -------------------------------------------------------------------------------- /CastingEssentials/Modules/SniperLOS.cpp: -------------------------------------------------------------------------------- 1 | #include "Modules/CameraState.h" 2 | #include "Modules/SniperLOS.h" 3 | 4 | #include "PluginBase/Entities.h" 5 | #include "PluginBase/Interfaces.h" 6 | #include "PluginBase/Player.h" 7 | #include "PluginBase/TFDefinitions.h" 8 | 9 | #include 10 | #include 11 | #include 12 | #include 13 | #include 14 | 15 | MODULE_REGISTER(SniperLOS); 16 | 17 | EntityTypeChecker SniperLOS::s_SniperRifleType; 18 | 19 | SniperLOS::SniperLOS() : 20 | ce_sniperlos_enabled("ce_sniperlos_enabled", "0", FCVAR_NONE, "Enables drawing beams representing sniper line of sight.", 21 | [](IConVar* var, const char*, float) { GetModule()->ToggleEnabled(static_cast(var)); }), 22 | ce_sniperlos_width("ce_sniperlos_width", "5", FCVAR_NONE, "Width of the sniper line of sight beam."), 23 | 24 | ce_sniperlos_color_blu("ce_sniperlos_color_blu", "125 169 197 255", FCVAR_NONE, "RGBA color for the blue sniper line of sight beams.", 25 | [](IConVar* var, const char*, float) { ColorFromConVar(*static_cast(var), GetModule()->m_BeamColorBlue); }), 26 | ce_sniperlos_color_red("ce_sniperlos_color_red", "185 55 55 255", FCVAR_NONE, "RGBA color for the red sniper line of sight beams.", 27 | [](IConVar* var, const char*, float) { ColorFromConVar(*static_cast(var), GetModule()->m_BeamColorRed); }) 28 | { 29 | // Initialize with defaults 30 | ColorFromConVar(ce_sniperlos_color_blu, m_BeamColorBlue); 31 | ColorFromConVar(ce_sniperlos_color_red, m_BeamColorRed); 32 | } 33 | 34 | bool SniperLOS::CheckDependencies() 35 | { 36 | s_SniperRifleType = Entities::GetTypeChecker("CTFSniperRifle"); 37 | 38 | return true; 39 | } 40 | 41 | void SniperLOS::ToggleEnabled(const ConVar* var) 42 | { 43 | if (var->GetBool()) 44 | { 45 | if (!m_LOSRenderer) 46 | m_LOSRenderer.emplace(); 47 | } 48 | else 49 | m_LOSRenderer.reset(); 50 | } 51 | 52 | void SniperLOS::LOSRenderer::PostRender() 53 | { 54 | CMatRenderContextPtr pRenderContext(materials); 55 | IMaterial* beamMaterial = materials->FindMaterial("castingessentials/sniperlos/beam", TEXTURE_GROUP_OTHER, true); 56 | 57 | const auto curtime = Interfaces::GetEngineTool()->ClientTime(); 58 | const float beamWidth = GetModule()->ce_sniperlos_width.GetFloat(); 59 | const auto& beamColorBlue = GetModule()->m_BeamColorBlue; 60 | const auto& beamColorRed = GetModule()->m_BeamColorRed; 61 | const auto specTarget = CameraState::GetModule()->GetLocalObserverTarget(true); 62 | 63 | for (const auto& player : Player::Iterable()) 64 | { 65 | auto activeWep = player->GetActiveWeapon(); 66 | if (!activeWep || !s_SniperRifleType.Match(activeWep)) 67 | continue; 68 | 69 | if (!player->CheckCondition(TFCond::TFCond_Zoomed)) 70 | continue; 71 | 72 | if (player->GetEntity() == specTarget) 73 | continue; 74 | 75 | const auto team = player->GetTeam(); 76 | if (team != TFTeam::Blue && team != TFTeam::Red) 77 | continue; 78 | 79 | const auto eyeAngles = player->GetEyeAngles(); 80 | const auto eyePos = player->GetEyePosition(); 81 | 82 | Vector eyeForward; 83 | AngleVectors(eyeAngles, &eyeForward); 84 | 85 | trace_t tr; 86 | UTIL_TraceLine(eyePos, eyePos + eyeForward * 10000, MASK_SHOT, player->GetEntity(), COLLISION_GROUP_NONE, &tr); 87 | 88 | CBeamSegDraw beam; 89 | beam.Start(pRenderContext, 2, beamMaterial); 90 | 91 | BeamSeg_t seg; 92 | seg.m_flAlpha = 1; 93 | seg.m_flTexCoord = 0; 94 | seg.m_flWidth = beamWidth; 95 | seg.m_vColor = ColorToVector(team == TFTeam::Red ? beamColorRed : beamColorBlue); 96 | seg.m_vPos = tr.startpos; 97 | beam.NextSeg(&seg); 98 | 99 | seg.m_vPos = tr.endpos; 100 | beam.NextSeg(&seg); 101 | 102 | beam.End(); 103 | } 104 | } 105 | -------------------------------------------------------------------------------- /CastingEssentials/Modules/SniperLOS.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include "PluginBase/EntityOffset.h" 4 | #include "PluginBase/Modules.h" 5 | 6 | #include 7 | #include 8 | 9 | #include 10 | 11 | class SniperLOS : public Module 12 | { 13 | public: 14 | SniperLOS(); 15 | 16 | static bool CheckDependencies(); 17 | static constexpr __forceinline const char* GetModuleName() { return "Sniper LOS Beams"; } 18 | 19 | private: 20 | static EntityTypeChecker s_SniperRifleType; 21 | 22 | class LOSRenderer : public CAutoGameSystemPerFrame 23 | { 24 | public: 25 | const char* Name() override { return "SniperLOSRenderer"; } 26 | 27 | void PostRender() override; 28 | }; 29 | std::optional m_LOSRenderer; 30 | 31 | void ToggleEnabled(const ConVar* var); 32 | 33 | ConVar ce_sniperlos_enabled; 34 | ConVar ce_sniperlos_width; 35 | ConVar ce_sniperlos_color_blu; 36 | ConVar ce_sniperlos_color_red; 37 | 38 | Color m_BeamColorBlue; 39 | Color m_BeamColorRed; 40 | }; 41 | -------------------------------------------------------------------------------- /CastingEssentials/Modules/SrcTVPlus.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | #include 5 | #include 6 | #include 7 | #include 8 | 9 | MODULE_REGISTER(SrcTVPlus); 10 | 11 | bool SrcTVPlus::s_Detected = false; 12 | std::map> SrcTVPlus::s_Listeners; 13 | int SrcTVPlus::s_MaxListener = 0; 14 | 15 | void SrcTVPlus::NotifyListeners() { 16 | for (auto& listener : s_Listeners) 17 | listener.second(s_Detected); 18 | } 19 | void SrcTVPlus::SetDetected(bool value, bool force_broadcast) { 20 | if (!force_broadcast && value == s_Detected) return; // In general, don't re-send but we need it for initial load 21 | s_Detected = value; 22 | NotifyListeners(); 23 | } 24 | 25 | static RecvProp* g_Prop = nullptr; 26 | static VariablePusher g_ProxyPusher; 27 | static std::map g_SeenEntities; // Entity ID + serial -> number of times seen 28 | 29 | void SrcTVPlus::DetectorProxy(const CRecvProxyData *pData, void *pStruct, void *pOut) { 30 | auto ent = static_cast(pStruct); 31 | if(ent != C_BasePlayer::GetLocalPlayer()) { 32 | auto id = ent->GetRefEHandle().ToInt(); 33 | if (++g_SeenEntities[id] >= 10) { 34 | SrcTVPlus::DisableDetector(); 35 | PluginMsg("SrcTV+ detected\n"); 36 | SrcTVPlus::SetDetected(true); 37 | } 38 | } 39 | g_ProxyPusher.GetOldValue()(pData, pStruct, pOut); 40 | } 41 | 42 | bool SrcTVPlus::CheckDependencies() 43 | { 44 | auto tbl = const_cast(Entities::FindRecvTable("DT_LocalPlayerExclusive")); 45 | if (!tbl) { 46 | PluginWarning("Required data table DT_LocalPlayerExclusive for module %s not found!\n", GetModuleName()); 47 | return false; 48 | } 49 | g_Prop = Entities::FindRecvProp(tbl, "m_nTickBase"); 50 | if (!g_Prop) { 51 | PluginWarning("Required recv prop DT_LocalPlayerExclusive.m_nTickBase for module %s not found!\n", GetModuleName()); 52 | return false; 53 | } 54 | 55 | return true; 56 | } 57 | 58 | void SrcTVPlus::EnableDetector() 59 | { 60 | if (s_Detected) return; // Already detected, no need to enable 61 | if (!g_ProxyPusher.IsEmpty()) return; // Already enabled 62 | g_SeenEntities.clear(); 63 | g_ProxyPusher = CreateVariablePusher(g_Prop->m_ProxyFn, &DetectorProxy); 64 | } 65 | 66 | void SrcTVPlus::DisableDetector() 67 | { 68 | g_ProxyPusher.Clear(); 69 | g_SeenEntities.clear(); 70 | } -------------------------------------------------------------------------------- /CastingEssentials/Modules/SrcTVPlus.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | #pragma once 3 | 4 | #include "PluginBase/Modules.h" 5 | #include "PluginBase/Entities.h" 6 | #include 7 | 8 | class SrcTVPlusListener; 9 | class CRecvProxyData; 10 | 11 | // Detects the presence of SrcTV+(or equivalent) 12 | // 13 | // Other modules can use this to figure out if they should show extra information based 14 | // on the presence of SrcTV+ or an equivalent plugin. They should not declare a dependency 15 | // on this module, but rather use the `IsAvailable()` and `SrcTVPlusListener`. The former 16 | // allows checking if SrcTV+ is available, the latter allows listener for it becoming 17 | // (un)available. 18 | // 19 | // All of the members related to interfacing with other modules is static. This is for both 20 | // performance but also robustness. Should SrcTV+ detection fail for any reason, the static 21 | // members will continue to work and act as if SrcTV+ is disabled. 22 | 23 | class SrcTVPlus : public Module 24 | { 25 | public: 26 | __forceinline static bool IsAvailable() { return s_Detected; } 27 | using Callback = void(bool); 28 | 29 | protected: 30 | 31 | template static int register_listener(F&& cb) { 32 | auto id = s_MaxListener++; 33 | s_Listeners.emplace(id, std::forward(cb)); 34 | cb(s_Detected); // Call with current value 35 | return id; 36 | } 37 | static void unregister_listener(int id) { 38 | s_Listeners.erase(id); 39 | } 40 | friend class SrcTVPlusListener; 41 | 42 | // Module implementation 43 | public: 44 | static bool CheckDependencies(); 45 | static constexpr __forceinline const char* GetModuleName() { return "SrcTV+ detection"; } 46 | 47 | protected: 48 | // When entering/leaving a level we reset the detector 49 | virtual void LevelInit() { SetDetected(false, true); EnableDetector(); } 50 | virtual void LevelShutdown() { SetDetected(false); DisableDetector(); } 51 | 52 | static void EnableDetector(); 53 | static void DisableDetector(); 54 | static void DetectorProxy(const CRecvProxyData *pData, void *pStruct, void *pOut); 55 | 56 | private: 57 | static bool s_Detected; 58 | static std::map> s_Listeners; 59 | static int s_MaxListener; 60 | 61 | static void NotifyListeners(); 62 | static void SetDetected(bool value, bool force_broadcast = false); 63 | }; 64 | 65 | class SrcTVPlusListener 66 | { 67 | public: 68 | template SrcTVPlusListener(F&& cb) { 69 | m_ListenerID = SrcTVPlus::register_listener(std::forward(cb)); 70 | } 71 | SrcTVPlusListener() { 72 | SrcTVPlus::unregister_listener(m_ListenerID); 73 | } 74 | 75 | private: 76 | int m_ListenerID; 77 | }; -------------------------------------------------------------------------------- /CastingEssentials/Modules/SteamTools.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include "PluginBase/Modules.h" 4 | 5 | #include 6 | 7 | class SteamTools : public Module 8 | { 9 | public: 10 | SteamTools(); 11 | 12 | static bool CheckDependencies(); 13 | static constexpr __forceinline const char* GetModuleName() { return "Steam Tools"; } 14 | 15 | protected: 16 | void OnTick(bool inGame) override; 17 | 18 | private: 19 | ConVar ce_steamtools_rp_legacy; 20 | 21 | ConVar ce_steamtools_rp_state; 22 | ConVar ce_steamtools_rp_matchgroup; 23 | ConVar ce_steamtools_rp_currentmap; 24 | 25 | ConCommand ce_steamtools_rp_debug; 26 | 27 | enum class RichPresenceState 28 | { 29 | MainMenu, 30 | SearchingGeneric, 31 | SearchingMatchGroup, 32 | PlayingGeneric, 33 | LoadingGeneric, 34 | PlayingMatchGroup, 35 | LoadingMatchGroup, 36 | PlayingCommunity, 37 | LoadingCommunity, 38 | 39 | COUNT, 40 | }; 41 | static constexpr const char* RICH_PRESENCE_STATES[] = 42 | { 43 | "MainMenu", 44 | "SearchingGeneric", 45 | "SearchingMatchGroup", 46 | "PlayingGeneric", 47 | "LoadingGeneric", 48 | "PlayingMatchGroup", 49 | "LoadingMatchGroup", 50 | "PlayingCommunity", 51 | "LoadingCommunity", 52 | }; 53 | 54 | enum class MatchGroup 55 | { 56 | Competitive6v6, 57 | Casual, 58 | SpecialEvent, 59 | MannUp, 60 | BootCamp, 61 | 62 | COUNT, 63 | }; 64 | static constexpr const char* MATCH_GROUPS[] = 65 | { 66 | "Competitive6v6", 67 | "Casual", 68 | "SpecialEvent", 69 | "MannUp", 70 | "BootCamp", 71 | }; 72 | 73 | static constexpr float RP_UPDATE_INTERVAL = 10; 74 | 75 | void SetRichPresenceState(ConVar* var, const char* oldValue); 76 | void SetMatchGroup(ConVar* var, const char* oldValue); 77 | 78 | void UpdateRichPresence(); 79 | 80 | float m_LastRPUpdateTime; 81 | 82 | static void PrintRichPresence(); 83 | }; -------------------------------------------------------------------------------- /CastingEssentials/Modules/TeamNames.cpp: -------------------------------------------------------------------------------- 1 | #include "TeamNames.h" 2 | 3 | #include 4 | 5 | MODULE_REGISTER(TeamNames); 6 | 7 | // Hi we're TOTALLY not hijacking a friend class that's eventually only declared in a cpp file 8 | class CCvar 9 | { 10 | public: 11 | static FnChangeCallback_t GetChangeCallback(ConVar& cVar) { return cVar.m_pParent->m_fnChangeCallback; } 12 | static void SetChangeCallback(ConVar& cVar, FnChangeCallback_t callback) { cVar.m_pParent->m_fnChangeCallback = callback; } 13 | 14 | CCvar() = delete; 15 | CCvar(const CCvar&) = delete; 16 | }; 17 | 18 | TeamNames::TeamNames() : 19 | m_OverrideCvars { 20 | ConVar("ce_teamnames_blu", "", FCVAR_NONE, "Overrides mp_tournament_blueteamname."), 21 | ConVar("ce_teamnames_red", "", FCVAR_NONE, "Overrides mp_tournament_redteamname.") 22 | }, 23 | 24 | ce_teamnames_swap("ce_teamnames_swap", []() { GetModule()->SwapTeamNames(); }, "Swaps the values of ce_teamnames_blu and ce_teamnames_red.") 25 | { 26 | m_OriginalCvars[(int)TeamConvars::Blue] = g_pCVar->FindVar("mp_tournament_blueteamname"); 27 | m_OriginalCvars[(int)TeamConvars::Red] = g_pCVar->FindVar("mp_tournament_redteamname"); 28 | } 29 | 30 | void TeamNames::SwapTeamNames() 31 | { 32 | SwapConVars(m_OverrideCvars[(int)TeamConvars::Red], m_OverrideCvars[(int)TeamConvars::Blue]); 33 | } 34 | 35 | void TeamNames::OnTick(bool inGame) 36 | { 37 | VPROF_BUDGET(__FUNCTION__, VPROF_BUDGETGROUP_CE); 38 | for (TeamConvars::Enum t = (TeamConvars::Enum)0; t < TeamConvars::Count; (*((int*)&t))++) 39 | { 40 | const bool originalChanged = !!m_LastServerValues[t].compare(m_OriginalCvars[t]->GetString()) && !!m_LastOverrideValues[t].compare(m_OriginalCvars[t]->GetString()); 41 | if (originalChanged) 42 | m_LastServerValues[t] = m_OriginalCvars[t]->GetString(); 43 | 44 | const bool newOverride = !!m_LastOverrideValues[t].compare(m_OverrideCvars[t].GetString()); 45 | if (newOverride) 46 | m_LastOverrideValues[t] = m_OverrideCvars[t].GetString(); 47 | 48 | if (IsStringEmpty(m_OverrideCvars[t].GetString())) 49 | m_OriginalCvars[t]->SetValue(m_LastServerValues[t].c_str()); 50 | else 51 | m_OriginalCvars[t]->SetValue(m_OverrideCvars[t].GetString()); 52 | } 53 | } -------------------------------------------------------------------------------- /CastingEssentials/Modules/TeamNames.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | #include "PluginBase/Modules.h" 3 | 4 | #include 5 | 6 | class TeamNames final : public Module 7 | { 8 | public: 9 | TeamNames(); 10 | static constexpr __forceinline const char* GetModuleName() { return "Team Names"; } 11 | 12 | private: 13 | 14 | struct TeamConvars 15 | { 16 | enum Enum 17 | { 18 | Blue, 19 | Red, 20 | 21 | Count, 22 | }; 23 | }; 24 | 25 | ConVar* m_OriginalCvars[TeamConvars::Count]; 26 | ConVar m_OverrideCvars[TeamConvars::Count]; 27 | 28 | ConCommand ce_teamnames_swap; 29 | void SwapTeamNames(); 30 | 31 | std::string m_LastServerValues[(int)TeamConvars::Count]; 32 | std::string m_LastOverrideValues[TeamConvars::Count]; 33 | 34 | void OnTick(bool inGame) override; 35 | }; -------------------------------------------------------------------------------- /CastingEssentials/Modules/TextureTools.cpp: -------------------------------------------------------------------------------- 1 | #include "Modules/TextureTools.h" 2 | 3 | #include "PluginBase/Interfaces.h" 4 | 5 | #include 6 | #include 7 | 8 | MODULE_REGISTER(TextureTools); 9 | 10 | TextureTools::TextureTools() : 11 | ce_texturetools_full_res_rts("ce_texturetools_full_res_rts", "0", FCVAR_NONE, 12 | "Create the refraction and water reflection textures at framebuffer resolution (if possible). Must be set before the first map load. Changing after that requires a game restart.", 13 | [](IConVar*, const char*, float) { GetModule()->ToggleFullResRTs(); }), 14 | 15 | m_CreateRenderTargetsHook(std::bind(&TextureTools::InitClientRenderTargetsOverride, this, 16 | std::placeholders::_1, std::placeholders::_2, std::placeholders::_3, std::placeholders::_4, std::placeholders::_5), false) 17 | { 18 | } 19 | 20 | bool TextureTools::CheckDependencies() 21 | { 22 | return true; 23 | } 24 | 25 | static ITexture* CreateWaterReflectionTexture(IMaterialSystem* pMaterialSystem, int iSize) 26 | { 27 | return pMaterialSystem->CreateNamedRenderTargetTextureEx2( 28 | "_rt_WaterReflection", 29 | iSize, iSize, RT_SIZE_FULL_FRAME_BUFFER, 30 | pMaterialSystem->GetBackBufferFormat(), 31 | MATERIAL_RT_DEPTH_SHARED, 32 | TEXTUREFLAGS_CLAMPS | TEXTUREFLAGS_CLAMPT, 33 | CREATERENDERTARGETFLAGS_HDR); 34 | } 35 | 36 | static ITexture* CreateWaterRefractionTexture(IMaterialSystem* pMaterialSystem, int iSize) 37 | { 38 | return pMaterialSystem->CreateNamedRenderTargetTextureEx2( 39 | "_rt_WaterRefraction", 40 | iSize, iSize, RT_SIZE_FULL_FRAME_BUFFER, 41 | // This is different than reflection because it has to have alpha for fog factor. 42 | IMAGE_FORMAT_RGBA8888, 43 | MATERIAL_RT_DEPTH_SHARED, 44 | TEXTUREFLAGS_CLAMPS | TEXTUREFLAGS_CLAMPT, 45 | CREATERENDERTARGETFLAGS_HDR); 46 | } 47 | 48 | static ITexture* CreateCameraTexture(IMaterialSystem* pMaterialSystem, int iSize) 49 | { 50 | return pMaterialSystem->CreateNamedRenderTargetTextureEx2( 51 | "_rt_Camera", 52 | iSize, iSize, RT_SIZE_DEFAULT, 53 | pMaterialSystem->GetBackBufferFormat(), 54 | MATERIAL_RT_DEPTH_SHARED, 55 | 0, 56 | CREATERENDERTARGETFLAGS_HDR); 57 | } 58 | 59 | void TextureTools::ToggleFullResRTs() 60 | { 61 | m_CreateRenderTargetsHook.SetEnabled(ce_texturetools_full_res_rts.GetBool()); 62 | } 63 | 64 | void TextureTools::InitClientRenderTargetsOverride(CBaseClientRenderTargets* pThis, 65 | IMaterialSystem* matsys, IMaterialSystemHardwareConfig* config, int waterRes, int cameraRes) 66 | { 67 | auto pAbstract = Interfaces::GetClientRenderTargets(); 68 | auto pBase = static_cast(pAbstract); 69 | Assert(pBase == pThis); 70 | 71 | // Full frame depth texture 72 | { 73 | materials->RemoveTextureAlias("_rt_FullFrameDepth"); 74 | m_FullFrameDepth.Init(materials->CreateNamedRenderTargetTextureEx2("_rt_FullFrameDepth", 1, 1, 75 | RT_SIZE_FULL_FRAME_BUFFER, IMAGE_FORMAT_IA88, MATERIAL_RT_DEPTH_NONE, 76 | TEXTUREFLAGS_CLAMPS | TEXTUREFLAGS_CLAMPT)); 77 | } 78 | 79 | // Water effects 80 | pBase->m_WaterReflectionTexture.Init(CreateWaterReflectionTexture(matsys, 256)); 81 | pBase->m_WaterRefractionTexture.Init(CreateWaterRefractionTexture(matsys, 256)); 82 | 83 | // Just leave this at default because tf2 doesn't use the camera texture 84 | pBase->m_CameraTexture.Init(CreateCameraTexture(matsys, 256)); 85 | 86 | m_CreateRenderTargetsHook.SetState(Hooking::HookAction::SUPERCEDE); 87 | } -------------------------------------------------------------------------------- /CastingEssentials/Modules/TextureTools.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include "PluginBase/Modules.h" 4 | #include "PluginBase/Hook.h" 5 | 6 | #include 7 | #include 8 | 9 | #include 10 | 11 | class TextureTools : public Module 12 | { 13 | public: 14 | TextureTools(); 15 | 16 | static bool CheckDependencies(); 17 | static constexpr __forceinline const char* GetModuleName() { return "Texture Tools"; } 18 | 19 | private: 20 | Hook m_CreateRenderTargetsHook; 21 | 22 | void ToggleFullResRTs(); 23 | void InitClientRenderTargetsOverride(CBaseClientRenderTargets* pThis, IMaterialSystem* pMaterialSystem, IMaterialSystemHardwareConfig* config, int waterRes, int cameraRes); 24 | 25 | CTextureReference m_FullFrameDepth; 26 | 27 | ConVar ce_texturetools_full_res_rts; 28 | }; 29 | -------------------------------------------------------------------------------- /CastingEssentials/Modules/ViewAngles.cpp: -------------------------------------------------------------------------------- 1 | #include "Modules/ViewAngles.h" 2 | 3 | #include "PluginBase/Entities.h" 4 | #include "PluginBase/Player.h" 5 | 6 | #include 7 | #include 8 | 9 | MODULE_REGISTER(ViewAngles); 10 | 11 | EntityOffset ViewAngles::s_EyeAngles0Offset; 12 | EntityOffset ViewAngles::s_EyeAngles1Offset; 13 | EntityOffset ViewAngles::s_KartBoostOffset; 14 | EntityOffset ViewAngles::s_KartHealthOffset; 15 | 16 | RecvProp* ViewAngles::s_EyeAngles0Prop; 17 | RecvProp* ViewAngles::s_EyeAngles1Prop; 18 | RecvProp* ViewAngles::s_KartBoostProp; 19 | RecvProp* ViewAngles::s_KartHealthProp; 20 | 21 | ViewAngles::ViewAngles() : 22 | ce_viewangles_enabled("ce_viewangles_enabled", "0", FCVAR_NONE, "Enabled high-precision viewangle unpacking from servers running the TF32BitAngles plugin.", 23 | [](IConVar* var, const char*, float) { GetModule()->ToggleEnabled(static_cast(var)); }) 24 | { 25 | } 26 | 27 | bool ViewAngles::CheckDependencies() 28 | { 29 | { 30 | const auto ccPlayer = Entities::GetClientClass("CTFPlayer"); 31 | const auto playerTable = ccPlayer->m_pRecvTable; 32 | 33 | s_EyeAngles0Offset = Entities::GetEntityProp(ccPlayer, "m_angEyeAngles[0]"); 34 | s_EyeAngles0Prop = Entities::FindRecvProp(playerTable, "m_angEyeAngles[0]"); 35 | 36 | s_EyeAngles1Offset = Entities::GetEntityProp(ccPlayer, "m_angEyeAngles[1]"); 37 | s_EyeAngles1Prop = Entities::FindRecvProp(playerTable, "m_angEyeAngles[1]"); 38 | 39 | s_KartBoostOffset = Entities::GetEntityProp(ccPlayer, "m_flKartNextAvailableBoost"); 40 | s_KartBoostProp = Entities::FindRecvProp(playerTable, "m_flKartNextAvailableBoost"); 41 | 42 | s_KartHealthOffset = Entities::GetEntityProp(ccPlayer, "m_iKartHealth"); 43 | s_KartHealthProp = Entities::FindRecvProp(playerTable, "m_iKartHealth"); 44 | } 45 | 46 | return true; 47 | } 48 | 49 | void ViewAngles::OnTick(bool inGame) 50 | { 51 | if (!inGame || !ce_viewangles_enabled.GetBool()) 52 | return; 53 | 54 | for (auto* player : Player::Iterable()) 55 | { 56 | auto networkable = player->GetEntity()->GetClientNetworkable(); 57 | std::byte* base = (std::byte*)networkable->GetDataTableBasePtr(); 58 | 59 | const auto offsetBoost = s_KartBoostOffset.GetOffset(networkable); 60 | const auto offsetHealth = s_KartHealthOffset.GetOffset(networkable); 61 | 62 | m_KartBoostMap[base + offsetBoost] = networkable; 63 | m_KartHealthMap[base + offsetHealth] = networkable; 64 | } 65 | } 66 | 67 | void ViewAngles::LevelShutdown() 68 | { 69 | m_KartBoostMap.clear(); 70 | m_KartHealthMap.clear(); 71 | } 72 | 73 | void ViewAngles::ToggleEnabled(const ConVar* var) 74 | { 75 | if (var->GetBool()) 76 | { 77 | m_EyeAngles0Proxy.emplace(s_EyeAngles0Prop->m_ProxyFn, EyeAngles0Proxy); 78 | m_EyeAngles1Proxy.emplace(s_EyeAngles1Prop->m_ProxyFn, EyeAngles1Proxy); 79 | m_KartBoostProxy.emplace(s_KartBoostProp->m_ProxyFn, KartBoostProxy); 80 | m_KartHealthProxy.emplace(s_KartHealthProp->m_ProxyFn, KartHealthProxy); 81 | } 82 | else 83 | { 84 | m_EyeAngles0Proxy.reset(); 85 | m_EyeAngles1Proxy.reset(); 86 | m_KartBoostProxy.reset(); 87 | m_KartHealthProxy.reset(); 88 | } 89 | } 90 | 91 | void ViewAngles::EyeAngles0Proxy(const CRecvProxyData* pData, void* pStruct, void* pOut) 92 | { 93 | } 94 | 95 | void ViewAngles::EyeAngles1Proxy(const CRecvProxyData* pData, void* pStruct, void* pOut) 96 | { 97 | } 98 | 99 | void ViewAngles::KartBoostProxy(const CRecvProxyData* pData, void* pStruct, void* pOut) 100 | { 101 | const auto& module = GetModule(); 102 | const auto& map = module->m_KartBoostMap; 103 | if (auto found = map.find(pOut); found != map.end()) 104 | s_EyeAngles0Offset.GetValue(found->second) = pData->m_Value.m_Float; 105 | else 106 | module->m_KartBoostProxy->GetOldValue()(pData, pStruct, pOut); 107 | } 108 | 109 | void ViewAngles::KartHealthProxy(const CRecvProxyData* pData, void* pStruct, void* pOut) 110 | { 111 | const auto& module = GetModule(); 112 | const auto& map = module->m_KartHealthMap; 113 | if (auto found = map.find(pOut); found != map.end()) 114 | s_EyeAngles1Offset.GetValue(found->second) = pData->m_Value.m_Float; 115 | else 116 | module->m_KartHealthProxy->GetOldValue()(pData, pStruct, pOut); 117 | } 118 | -------------------------------------------------------------------------------- /CastingEssentials/Modules/ViewAngles.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | #include "PluginBase/EntityOffset.h" 3 | #include "PluginBase/Modules.h" 4 | 5 | #include 6 | #include 7 | 8 | #include 9 | #include 10 | 11 | class ConCommand; 12 | class IConVar; 13 | 14 | class ViewAngles final : public Module 15 | { 16 | public: 17 | ViewAngles(); 18 | 19 | static bool CheckDependencies(); 20 | static constexpr __forceinline const char* GetModuleName() { return "High-Precision View Angles"; } 21 | 22 | protected: 23 | void OnTick(bool inGame) override; 24 | void LevelShutdown() override; 25 | 26 | private: 27 | static EntityOffset s_EyeAngles0Offset; 28 | static EntityOffset s_EyeAngles1Offset; 29 | static EntityOffset s_KartBoostOffset; 30 | static EntityOffset s_KartHealthOffset; 31 | 32 | static RecvProp* s_EyeAngles0Prop; 33 | static RecvProp* s_EyeAngles1Prop; 34 | static RecvProp* s_KartBoostProp; 35 | static RecvProp* s_KartHealthProp; 36 | 37 | ConVar ce_viewangles_enabled; 38 | void ToggleEnabled(const ConVar *var); 39 | 40 | std::optional> m_EyeAngles0Proxy; 41 | std::optional> m_EyeAngles1Proxy; 42 | std::optional> m_KartBoostProxy; 43 | std::optional> m_KartHealthProxy; 44 | 45 | std::map m_KartBoostMap; 46 | std::map m_KartHealthMap; 47 | 48 | static void EyeAngles0Proxy(const CRecvProxyData* pData, void* pStruct, void* pOut); 49 | static void EyeAngles1Proxy(const CRecvProxyData* pData, void* pStruct, void* pOut); 50 | static void KartBoostProxy(const CRecvProxyData* pData, void* pStruct, void* pOut); 51 | static void KartHealthProxy(const CRecvProxyData* pData, void* pStruct, void* pOut); 52 | }; -------------------------------------------------------------------------------- /CastingEssentials/Modules/WeaponTools.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include "PluginBase/Modules.h" 4 | 5 | #include 6 | #include 7 | #include 8 | #include 9 | 10 | #include 11 | #include 12 | 13 | class C_BaseViewModel; 14 | 15 | namespace std 16 | { 17 | template<> struct hash 18 | { 19 | size_t operator()(const CBaseHandle& handle) const 20 | { 21 | return handle.GetEntryIndex() & (handle.GetSerialNumber() << NUM_ENT_ENTRY_BITS); 22 | } 23 | }; 24 | } 25 | 26 | class WeaponTools final : public Module 27 | { 28 | public: 29 | WeaponTools(); 30 | 31 | static bool CheckDependencies(); 32 | static constexpr __forceinline const char* GetModuleName() { return "Weapon Tools"; } 33 | 34 | protected: 35 | void OnTick(bool inGame) override; 36 | void LevelShutdown() override; 37 | 38 | private: 39 | static float& GetInspectInterp(); 40 | 41 | enum class InspectStage 42 | { 43 | None = -1, 44 | PullUp = 0, 45 | Hold = 1, 46 | PutDown = 2, 47 | }; 48 | 49 | ConVar ce_weapon_inspect_debug; 50 | ConVar ce_weapon_inspect_block; 51 | ConVar ce_weapon_skin_downsample; 52 | //ConCommand ce_weapon_inspect_force; 53 | 54 | std::optional> m_InspectStageProxyFnOverride; 55 | std::optional> m_ViewModelProxyFnOverride; 56 | void RecvProxy_SequenceNum_Override(const CRecvProxyData* data, void* pStruct, void* out); 57 | 58 | void SkinDownsampleChanged(const ConVar* var); 59 | 60 | void InspectBlockToggled(const ConVar* cv); 61 | 62 | struct ViewModel 63 | { 64 | CHandle m_VM; 65 | Activity m_LastVMIdleActivity = ACT_INVALID; 66 | }; 67 | 68 | void UpdateVMIdleActivity(const CHandle& vm, Activity newAct); 69 | std::unordered_map, Activity, std::hash> m_ViewModelCache; 70 | 71 | static std::pair GetSkinDownsampleVars(); 72 | }; -------------------------------------------------------------------------------- /CastingEssentials/PluginBase/EntityOffset.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include "PluginBase/Exceptions.h" 4 | 5 | #include 6 | #include 7 | #include 8 | 9 | #include 10 | #include 11 | #include 12 | 13 | class IClientNetworkable; 14 | 15 | #undef min 16 | 17 | class EntityTypeChecker final 18 | { 19 | public: 20 | EntityTypeChecker() = default; 21 | 22 | __forceinline bool IsInit() const { return !m_ValidRecvTables.empty(); } 23 | 24 | __forceinline bool Match(const IClientNetworkable* ent) const { Assert(ent); return Match(ent->GetClientClass()); } 25 | __forceinline bool Match(const ClientClass* cc) const { Assert(cc); return Match(cc->m_pRecvTable); } 26 | bool Match(const RecvTable* table) const 27 | { 28 | Assert(table); 29 | const auto& end = m_ValidRecvTables.data() + m_ValidRecvTables.size(); 30 | for (auto iter = m_ValidRecvTables.data(); iter < end; iter++) 31 | { 32 | if ((*iter) != table) 33 | continue; 34 | 35 | if (iter != m_ValidRecvTables.data()) 36 | std::swap(*(iter - 1), *iter); // Move up one 37 | 38 | return true; 39 | } 40 | 41 | return false; 42 | } 43 | 44 | private: 45 | inline EntityTypeChecker(const std::set& validRecvTables) : 46 | m_ValidRecvTables(validRecvTables.begin(), validRecvTables.end()) 47 | { 48 | } 49 | 50 | friend class Entities; 51 | mutable std::vector m_ValidRecvTables; 52 | }; 53 | 54 | template 55 | class EntityOffset final 56 | { 57 | public: 58 | inline constexpr EntityOffset() : m_Offset(std::numeric_limits::min()) 59 | { 60 | } 61 | 62 | inline constexpr EntityOffset(EntityTypeChecker&& validRecvTables, ptrdiff_t offset) : 63 | m_Offset(offset), m_ValidTypes(std::move(validRecvTables)) 64 | { 65 | } 66 | 67 | inline const TValue& GetValue(const IClientNetworkable* entity) const 68 | { 69 | if (!m_ValidTypes.Match(entity)) 70 | { 71 | const char* clientClass; 72 | if (!entity) 73 | clientClass = "(null entity)"; 74 | else if (auto cc = entity->GetClientClass(); !cc) 75 | clientClass = "(null ClientClass)"; 76 | else 77 | clientClass = cc->GetName(); 78 | 79 | throw mismatching_entity_offset("FIXME", clientClass); 80 | } 81 | 82 | return *(TValue*)(((std::byte*)entity->GetDataTableBasePtr()) + m_Offset); 83 | } 84 | __forceinline TValue& GetValue(IClientNetworkable* entity) const 85 | { 86 | return const_cast(GetValue((const IClientNetworkable*)entity)); 87 | } 88 | 89 | inline const TValue* TryGetValue(const IClientNetworkable* entity) const 90 | { 91 | if (!entity || !m_ValidTypes.Match(entity)) 92 | return nullptr; 93 | 94 | return (TValue*)(((std::byte*)entity->GetDataTableBasePtr()) + m_Offset); 95 | } 96 | __forceinline TValue* TryGetValue(IClientNetworkable* entity) const 97 | { 98 | return const_cast(TryGetValue((const IClientNetworkable*)entity)); 99 | } 100 | inline const TValue& TryGetValue(const IClientNetworkable* entity, const TValue& defaultVal) const 101 | { 102 | if (auto val = TryGetValue(entity)) 103 | return *val; 104 | else 105 | return defaultVal; 106 | } 107 | inline TValue& TryGetValue(IClientNetworkable* entity, TValue& defaultVal) const 108 | { 109 | if (auto val = TryGetValue(entity)) 110 | return *val; 111 | else 112 | return defaultVal; 113 | } 114 | 115 | __forceinline ptrdiff_t GetOffset(const IClientNetworkable* entity) const 116 | { 117 | if (!m_ValidTypes.Match(entity)) 118 | throw mismatching_entity_offset("FIXME", "FIXME2"); 119 | 120 | return m_Offset; 121 | } 122 | 123 | __forceinline bool IsInit() const { return m_ValidTypes.IsInit(); } 124 | 125 | private: 126 | ptrdiff_t m_Offset; 127 | EntityTypeChecker m_ValidTypes; 128 | }; -------------------------------------------------------------------------------- /CastingEssentials/PluginBase/Exceptions.cpp: -------------------------------------------------------------------------------- 1 | #include "PluginBase/Exceptions.h" 2 | 3 | #include 4 | 5 | invalid_class_prop::invalid_class_prop(const char *name) noexcept 6 | { 7 | className = name; 8 | } 9 | 10 | const char *invalid_class_prop::what() const noexcept 11 | { 12 | std::string s; 13 | std::stringstream ss; 14 | 15 | ss << "Attempted to access invalid property in entity class " << className << "!\n"; 16 | ss >> s; 17 | 18 | return s.c_str(); 19 | } 20 | 21 | mismatching_entity_offset::mismatching_entity_offset(const char* expected, const char* actual) noexcept 22 | : std::runtime_error(BuildMessage(expected, actual)) 23 | { 24 | } 25 | 26 | std::string mismatching_entity_offset::BuildMessage(const char* expected, const char* actual) 27 | { 28 | std::stringstream ss; 29 | ss << "Attempted to use an EntityOffset intended for " << expected << " on " << actual; 30 | return ss.str(); 31 | } 32 | 33 | module_not_loaded::module_not_loaded(const char *name) noexcept 34 | { 35 | moduleName = name; 36 | } 37 | 38 | const char *module_not_loaded::what() const noexcept 39 | { 40 | std::string s; 41 | std::stringstream ss; 42 | 43 | ss << "Module " << moduleName << " not loaded!\n"; 44 | ss >> s; 45 | 46 | return s.c_str(); 47 | } 48 | 49 | bad_pointer::bad_pointer(const char *type) noexcept 50 | { 51 | pointerType = type; 52 | } 53 | 54 | const char *bad_pointer::what() const noexcept 55 | { 56 | std::string s; 57 | std::stringstream ss; 58 | 59 | ss << "Invalid pointer to " << pointerType << "!\n"; 60 | ss >> s; 61 | 62 | return s.c_str(); 63 | } -------------------------------------------------------------------------------- /CastingEssentials/PluginBase/Exceptions.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include 4 | 5 | class invalid_class_prop : public std::exception 6 | { 7 | public: 8 | invalid_class_prop(const char *name) noexcept; 9 | virtual const char *what() const noexcept; 10 | private: 11 | const char *className; 12 | }; 13 | 14 | class mismatching_entity_offset final : public std::runtime_error 15 | { 16 | public: 17 | mismatching_entity_offset(const char* expected, const char* actual) noexcept; 18 | 19 | private: 20 | static std::string BuildMessage(const char* expected, const char* actual); 21 | }; 22 | 23 | class module_not_loaded : public std::exception 24 | { 25 | public: 26 | module_not_loaded(const char *name) noexcept; 27 | virtual const char *what() const noexcept; 28 | private: 29 | const char *moduleName; 30 | }; 31 | 32 | class module_load_failed : public std::exception 33 | { 34 | public: 35 | module_load_failed(const char *name) noexcept : moduleName(name) {} 36 | virtual const char *what() const noexcept { return moduleName.c_str(); } 37 | private: 38 | std::string moduleName; 39 | }; 40 | 41 | class module_circular_dependency : public std::exception 42 | { 43 | public: 44 | module_circular_dependency(const char *name) noexcept : moduleName(name) {} 45 | virtual const char *what() const noexcept { return moduleName.c_str(); } 46 | private: 47 | std::string moduleName; 48 | std::string message; 49 | }; 50 | 51 | class module_dependency_failed : public std::exception 52 | { 53 | public: 54 | module_dependency_failed(const char *name) noexcept : moduleName(name) {} 55 | virtual const char *what() const noexcept { return moduleName.c_str(); } 56 | private: 57 | std::string moduleName; 58 | std::string message; 59 | }; 60 | 61 | class bad_pointer : public std::exception 62 | { 63 | public: 64 | bad_pointer(const char *type) noexcept; 65 | virtual const char *what() const noexcept; 66 | private: 67 | const char *pointerType; 68 | }; 69 | 70 | class not_supported : public std::exception 71 | { 72 | public: 73 | not_supported(const char* funcname) noexcept { m_FuncName = funcname; } 74 | virtual const char* what() const noexcept override { return m_FuncName; } 75 | 76 | private: 77 | const char* m_FuncName; 78 | }; -------------------------------------------------------------------------------- /CastingEssentials/PluginBase/Hook.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | #include "PluginBase/HookManager.h" 3 | 4 | template 5 | class Hook final 6 | { 7 | using Functional = typename HookDefinitions::HookFuncType::Hook::Functional; 8 | 9 | public: 10 | Hook(Functional&& fn, bool enable = false) : 11 | m_Fn(std::move(fn)), m_HookID(-1) 12 | { 13 | if (enable) 14 | Enable(); 15 | } 16 | ~Hook() 17 | { 18 | if (IsEnabled()) 19 | Disable(); 20 | } 21 | 22 | // No copying allowed 23 | Hook(const Hook& other) = delete; 24 | Hook& operator=(const Hook& other) = delete; 25 | 26 | bool SetEnabled(bool enabled) 27 | { 28 | if (enabled) 29 | return Enable(); 30 | else 31 | return Disable(); 32 | } 33 | bool Enable() 34 | { 35 | if (IsEnabled()) 36 | return false; 37 | 38 | m_HookID = GetHooks()->AddHook(m_Fn); 39 | return true; 40 | } 41 | bool Disable() 42 | { 43 | if (!IsEnabled()) 44 | return true; 45 | 46 | if (GetHooks()->RemoveHook(m_HookID, __FUNCTION__)) 47 | { 48 | m_HookID = -1; 49 | return true; 50 | } 51 | else 52 | return false; 53 | } 54 | 55 | void SetState(Hooking::HookAction action) 56 | { 57 | Assert(IsEnabled()); 58 | if (!IsEnabled()) 59 | return; 60 | 61 | GetHooks()->SetState(action); 62 | } 63 | 64 | __forceinline auto GetOriginal() const { return GetHooks()->GetOriginal(); } 65 | __forceinline bool IsInHook() const { return GetHooks()->IsInHook(); } 66 | __forceinline bool IsEnabled() const { return m_HookID >= 0; } 67 | 68 | private: 69 | Functional m_Fn; 70 | int m_HookID; 71 | }; -------------------------------------------------------------------------------- /CastingEssentials/PluginBase/HookManager.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | #include "PluginBase/HookDefinitions.h" 3 | 4 | #include 5 | 6 | class HookManager final : HookDefinitions 7 | { 8 | template friend class Hook; 9 | 10 | public: 11 | HookManager(); 12 | 13 | static bool Load(); 14 | static bool Unload(); 15 | 16 | template __forceinline typename HookFuncType::Hook::OriginalFnType GetFunc() { return GetHook()->GetOriginal(); } 17 | template __forceinline typename HookFuncType::Hook* GetHook() { return static_cast::Hook*>(m_Hooks[(int)fn].get()); }; 18 | template static __forceinline typename HookFuncType::Raw GetRawFunc() { return (HookFuncType::Raw)s_RawFunctions[(int)fn]; } 19 | 20 | template inline int AddHook(const typename HookFuncType::Hook::Functional& hook) 21 | { 22 | auto hkPtr = GetHook(); 23 | if (!hkPtr) 24 | return 0; 25 | 26 | return hkPtr->AddHook(hook); 27 | } 28 | template inline bool RemoveHook(int hookID, const char* funcName) 29 | { 30 | auto hkPtr = GetHook(); 31 | if (!hkPtr) 32 | return false; 33 | 34 | return hkPtr->RemoveHook(hookID, funcName); 35 | } 36 | template inline typename HookFuncType::Hook::Functional GetOriginal() 37 | { 38 | auto hkPtr = GetHook(); 39 | if (!hkPtr) 40 | return nullptr; 41 | 42 | return hkPtr->GetOriginal(); 43 | } 44 | template inline void SetState(Hooking::HookAction state) 45 | { 46 | auto hkPtr = GetHook(); 47 | if (!hkPtr) 48 | return; 49 | 50 | hkPtr->SetState(state); 51 | } 52 | template inline bool IsInHook() 53 | { 54 | auto hkPtr = GetHook(); 55 | if (!hkPtr) 56 | return false; 57 | 58 | return hkPtr->IsInHook(); 59 | } 60 | 61 | private: 62 | std::unique_ptr m_Hooks[(int)HookFunc::Count]; 63 | 64 | template void InitHook(Args&&... args); 65 | template void InitGlobalHook(); 66 | 67 | static void* s_RawFunctions[(int)HookFunc::Count]; 68 | static void InitRawFunctionsList(); 69 | template static void FindFunc(const char* signature, const char* mask, int offset = 0, const char* module = "client"); 70 | static void FindFunc_C_BasePlayer_GetLocalPlayer(); 71 | 72 | void IngameStateChanged(bool inGame); 73 | class Panel; 74 | std::unique_ptr m_Panel; 75 | }; 76 | 77 | extern std::byte* SignatureScan(const char* moduleName, const char* signature, const char* mask, int offset = 0); 78 | extern std::byte* SignatureScanMultiple(const char* moduleName, const char* signature, const char* mask, 79 | const std::function& testFunc, int offset = 0); 80 | extern HookManager* GetHooks(); -------------------------------------------------------------------------------- /CastingEssentials/PluginBase/PlayerStateBase.cpp: -------------------------------------------------------------------------------- 1 | #include "PlayerStateBase.h" 2 | 3 | #include "PluginBase/Interfaces.h" 4 | 5 | #include 6 | 7 | void PlayerStateBase::Update() 8 | { 9 | auto tool = Interfaces::GetEngineTool(); 10 | if (!tool) 11 | return; 12 | 13 | const auto tick = tool->ClientTick(); 14 | const auto frame = tool->HostFrameCount(); 15 | 16 | UpdateInternal(tick != m_LastTickUpdate, frame != m_LastFrameUpdate); 17 | 18 | m_LastTickUpdate = tick; 19 | m_LastFrameUpdate = frame; 20 | } -------------------------------------------------------------------------------- /CastingEssentials/PluginBase/PlayerStateBase.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | class Player; 4 | 5 | class PlayerStateBase 6 | { 7 | public: 8 | constexpr PlayerStateBase(Player& player) : m_Player(player) {} 9 | PlayerStateBase(const PlayerStateBase& other) = delete; 10 | PlayerStateBase& operator=(const PlayerStateBase& other) = delete; 11 | 12 | virtual ~PlayerStateBase() = default; 13 | 14 | void Update(); 15 | 16 | protected: 17 | virtual void UpdateInternal(bool tickUpdate, bool frameUpdate) {} 18 | 19 | Player& GetPlayer() { return m_Player; } 20 | const Player& GetPlayer() const { return m_Player; } 21 | 22 | private: 23 | int m_LastTickUpdate = -1; 24 | int m_LastFrameUpdate = -1; 25 | 26 | Player& m_Player; 27 | }; -------------------------------------------------------------------------------- /CastingEssentials/PluginBase/Plugin.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include 4 | 5 | class Plugin : public IServerPluginCallbacks 6 | { 7 | public: 8 | virtual void Unload() override { } 9 | virtual void Pause() override { } 10 | virtual void UnPause() override { } 11 | virtual void LevelInit(const char* mapName) override { } 12 | virtual void ServerActivate(edict_t* edictList, int edictCount, int clientMax) override { } 13 | virtual void GameFrame(bool simulating) override { } 14 | virtual void LevelShutdown() override { } 15 | virtual void ClientActive(edict_t* entity) override { } 16 | virtual void ClientDisconnect(edict_t* entity) override { } 17 | virtual void ClientPutInServer(edict_t* entity, const char* playerName) override { } 18 | virtual void SetCommandClient(int index) override { } 19 | virtual void ClientSettingsChanged(edict_t* edict) override { } 20 | virtual PLUGIN_RESULT ClientConnect(bool* allowConnect, edict_t* entity, const char* name, const char* address, char* rejectMsg, int maxRejectMsgLength) override { return PLUGIN_CONTINUE; } 21 | virtual PLUGIN_RESULT ClientCommand(edict_t* entity, const CCommand& args) override { return PLUGIN_CONTINUE; } 22 | virtual PLUGIN_RESULT NetworkIDValidated(const char* userName, const char* networkID) override { return PLUGIN_CONTINUE; } 23 | virtual void OnQueryCvarValueFinished(QueryCvarCookie_t cookie, edict_t* playerEntity, EQueryCvarValueStatus status, const char* cvarName, const char* cvarValue) override { } 24 | virtual void OnEdictAllocated(edict_t* edict) override { } 25 | virtual void OnEdictFreed(const edict_t* edict) override { } 26 | }; -------------------------------------------------------------------------------- /CastingEssentials/PluginBase/TFPlayerResource.cpp: -------------------------------------------------------------------------------- 1 | #include "TFPlayerResource.h" 2 | 3 | #include "Interfaces.h" 4 | #include "Entities.h" 5 | 6 | #include 7 | #include 8 | #include 9 | #include 10 | #include 11 | 12 | std::shared_ptr TFPlayerResource::m_PlayerResource; 13 | 14 | std::shared_ptr TFPlayerResource::GetPlayerResource() 15 | { 16 | if (m_PlayerResource && m_PlayerResource->m_PlayerResourceEntity.Get()) 17 | return m_PlayerResource; 18 | 19 | const auto count = Interfaces::GetClientEntityList()->GetHighestEntityIndex(); 20 | for (int i = 0; i < count; i++) 21 | { 22 | IClientEntity* unknownEnt = Interfaces::GetClientEntityList()->GetClientEntity(i); 23 | if (!unknownEnt) 24 | continue; 25 | 26 | ClientClass* clClass = unknownEnt->GetClientClass(); 27 | if (!clClass) 28 | continue; 29 | 30 | const char* name = clClass->GetName(); 31 | if (strcmp(name, "CTFPlayerResource")) 32 | continue; 33 | 34 | m_PlayerResource = std::shared_ptr(new TFPlayerResource()); 35 | m_PlayerResource->m_PlayerResourceEntity = unknownEnt->GetBaseEntity(); 36 | return m_PlayerResource; 37 | } 38 | 39 | return nullptr; 40 | } 41 | 42 | TFPlayerResource::TFPlayerResource() 43 | { 44 | auto cc = Entities::GetClientClass("CTFPlayerResource"); 45 | 46 | char buf[32]; 47 | for (int i = 0; i < MAX_PLAYERS; i++) 48 | { 49 | m_AliveOffsets[i] = Entities::GetEntityProp(cc, Entities::PropIndex(buf, "m_bAlive", i + 1)); 50 | m_DamageOffsets[i] = Entities::GetEntityProp(cc, Entities::PropIndex(buf, "m_iDamage", i + 1)); 51 | m_MaxHealthOffsets[i] = Entities::GetEntityProp(cc, Entities::PropIndex(buf, "m_iMaxHealth", i + 1)); 52 | 53 | for (int w = 0; w < STREAK_WEAPONS; w++) 54 | m_StreakOffsets[i][w] = Entities::GetEntityProp(cc, Entities::PropIndex(buf, "m_iStreaks", (i + 1) * STREAK_WEAPONS + w)); 55 | } 56 | } 57 | 58 | bool TFPlayerResource::IsAlive(int playerEntIndex) 59 | { 60 | if (!CheckEntIndex(playerEntIndex, __FUNCTION__)) 61 | return false; 62 | 63 | return m_AliveOffsets[playerEntIndex - 1].GetValue(m_PlayerResourceEntity.Get()); 64 | } 65 | 66 | int* TFPlayerResource::GetKillstreak(int playerEntIndex, uint_fast8_t weapon) 67 | { 68 | if (!CheckEntIndex(playerEntIndex, __FUNCTION__)) 69 | return nullptr; 70 | 71 | if (weapon >= STREAK_WEAPONS) 72 | return nullptr; 73 | 74 | return &m_StreakOffsets[playerEntIndex - 1][weapon].GetValue(m_PlayerResourceEntity.Get()); 75 | } 76 | 77 | int TFPlayerResource::GetDamage(int playerEntIndex) 78 | { 79 | if (!CheckEntIndex(playerEntIndex, __FUNCTION__)) 80 | return std::numeric_limits::min(); 81 | 82 | return m_DamageOffsets[playerEntIndex - 1].GetValue(m_PlayerResourceEntity.Get()); 83 | } 84 | 85 | int TFPlayerResource::GetMaxHealth(int playerEntIndex) 86 | { 87 | if (!CheckEntIndex(playerEntIndex, __FUNCTION__)) 88 | return std::numeric_limits::min(); 89 | 90 | return m_MaxHealthOffsets[playerEntIndex - 1].GetValue(m_PlayerResourceEntity.Get()); 91 | } 92 | 93 | bool TFPlayerResource::CheckEntIndex(int playerEntIndex, const char* functionName) 94 | { 95 | if (playerEntIndex < 1 || playerEntIndex > Interfaces::GetEngineTool()->GetMaxClients()) 96 | { 97 | PluginWarning("Out of range playerEntIndex %i in %s()\n", playerEntIndex, functionName); 98 | return false; 99 | } 100 | 101 | return true; 102 | } -------------------------------------------------------------------------------- /CastingEssentials/PluginBase/TFPlayerResource.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include "PluginBase/EntityOffset.h" 4 | 5 | #include 6 | #include 7 | #include 8 | #include 9 | 10 | #include 11 | #include 12 | 13 | class C_BaseEntity; 14 | class Player; 15 | 16 | class TFPlayerResource final 17 | { 18 | TFPlayerResource(); 19 | 20 | public: 21 | ~TFPlayerResource() = default; 22 | static std::shared_ptr GetPlayerResource(); 23 | 24 | int GetMaxHealth(int playerEntIndex); 25 | bool IsAlive(int playerEntIndex); 26 | int* GetKillstreak(int playerEntIndex, uint_fast8_t weapon); 27 | int GetDamage(int playerEntIndex); 28 | 29 | static constexpr auto STREAK_WEAPONS = 4; 30 | 31 | private: 32 | bool CheckEntIndex(int playerEntIndex, const char* functionName); 33 | 34 | CHandle m_PlayerResourceEntity; 35 | static std::shared_ptr m_PlayerResource; 36 | 37 | std::array, MAX_PLAYERS> m_AliveOffsets; 38 | EntityOffset m_StreakOffsets[MAX_PLAYERS][STREAK_WEAPONS]; 39 | std::array, MAX_PLAYERS> m_DamageOffsets; 40 | std::array, MAX_PLAYERS> m_MaxHealthOffsets; 41 | }; -------------------------------------------------------------------------------- /CastingEssentials/PluginBase/TFTeamResource.cpp: -------------------------------------------------------------------------------- 1 | #include "TFTeamResource.h" 2 | #include "PluginBase/Entities.h" 3 | #include "PluginBase/Interfaces.h" 4 | #include "PluginBase/TFDefinitions.h" 5 | 6 | #include 7 | #include 8 | #include 9 | 10 | std::shared_ptr TFTeamResource::s_TeamResource; 11 | 12 | std::shared_ptr TFTeamResource::GetTeamResource() 13 | { 14 | static const auto s_TeamOffset = Entities::GetEntityProp("CTFTeam", "m_iTeamNum"); 15 | 16 | if (s_TeamResource && s_TeamResource->m_TeamResourceEntity[0].Get() && s_TeamResource->m_TeamResourceEntity[1].Get()) 17 | return s_TeamResource; 18 | 19 | s_TeamResource.reset(); 20 | 21 | const auto count = Interfaces::GetClientEntityList()->GetHighestEntityIndex(); 22 | for (int i = 0; i < count; i++) 23 | { 24 | IClientEntity* unknownEnt = Interfaces::GetClientEntityList()->GetClientEntity(i); 25 | if (!unknownEnt) 26 | continue; 27 | 28 | IClientNetworkable* networkable = unknownEnt->GetClientNetworkable(); 29 | if (!networkable) 30 | continue; 31 | 32 | const TFTeam* team = s_TeamOffset.TryGetValue(networkable); 33 | if (!team) 34 | continue; 35 | 36 | if (!s_TeamResource) 37 | s_TeamResource.reset(new TFTeamResource()); 38 | 39 | if (*team == TFTeam::Red) 40 | s_TeamResource->m_TeamResourceEntity[0] = unknownEnt->GetBaseEntity(); 41 | else if (*team == TFTeam::Blue) 42 | s_TeamResource->m_TeamResourceEntity[1] = unknownEnt->GetBaseEntity(); 43 | 44 | if (s_TeamResource->m_TeamResourceEntity[0] && s_TeamResource->m_TeamResourceEntity[1]) 45 | return s_TeamResource; 46 | } 47 | 48 | return nullptr; 49 | } 50 | 51 | int TFTeamResource::GetTeamScore(TFTeam team) 52 | { 53 | const auto teamIndex = ToTeamIndex(team); 54 | 55 | if (!m_TeamScores[teamIndex].IsInit()) 56 | m_TeamScores[teamIndex] = Entities::GetEntityProp(m_TeamResourceEntity[teamIndex].Get(), "m_iScore"); 57 | 58 | if (m_TeamScores[teamIndex].IsInit()) 59 | return m_TeamScores[teamIndex].GetValue(m_TeamResourceEntity[teamIndex]); 60 | else 61 | { 62 | Assert(!"Failed to get team score variable!"); 63 | return 0; 64 | } 65 | } 66 | 67 | uint_fast8_t TFTeamResource::ToTeamIndex(TFTeam team) 68 | { 69 | switch (team) 70 | { 71 | default: 72 | Assert(!"Invalid TFTeam for TFTeamResource!"); 73 | // Return team index 0 (team red) by default 74 | 75 | case TFTeam::Red: return 0; 76 | case TFTeam::Blue: return 1; 77 | } 78 | } 79 | -------------------------------------------------------------------------------- /CastingEssentials/PluginBase/TFTeamResource.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | #include "PluginBase/EntityOffset.h" 3 | 4 | #include 5 | 6 | #include 7 | 8 | class C_BaseEntity; 9 | enum class TFTeam; 10 | 11 | class TFTeamResource final 12 | { 13 | TFTeamResource() = default; 14 | 15 | public: 16 | ~TFTeamResource() = default; 17 | static std::shared_ptr GetTeamResource(); 18 | 19 | int GetTeamScore(TFTeam team); 20 | 21 | private: 22 | static uint_fast8_t ToTeamIndex(TFTeam team); 23 | 24 | // All arrays are [red, blue] 25 | EntityOffset m_TeamScores[2]; 26 | CHandle m_TeamResourceEntity[2]; 27 | static std::shared_ptr s_TeamResource; 28 | }; -------------------------------------------------------------------------------- /CastingEssentials/PluginBase/VariablePusher.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | template 4 | class VariablePusher final 5 | { 6 | public: 7 | constexpr VariablePusher() : m_Variable(nullptr) {} 8 | VariablePusher(const VariablePusher& other) = delete; 9 | VariablePusher(VariablePusher&& other) 10 | { 11 | m_Variable = std::move(other.m_Variable); 12 | other.m_Variable = nullptr; 13 | m_OldValue = std::move(other.m_OldValue); 14 | } 15 | VariablePusher& operator=(const VariablePusher& other) = delete; 16 | VariablePusher& operator=(VariablePusher&& other) 17 | { 18 | Clear(); 19 | m_Variable = std::move(other.m_Variable); 20 | other.m_Variable = nullptr; 21 | m_OldValue = std::move(other.m_OldValue); 22 | return *this; 23 | } 24 | VariablePusher(T& variable, const T& newValue) : m_Variable(&variable) 25 | { 26 | m_OldValue = std::move(*m_Variable); 27 | *m_Variable = newValue; 28 | } 29 | VariablePusher(T& variable, T&& newValue) : m_Variable(&variable) 30 | { 31 | m_OldValue = std::move(*m_Variable); 32 | *m_Variable = std::move(newValue); 33 | } 34 | ~VariablePusher() 35 | { 36 | if (m_Variable) 37 | *m_Variable = std::move(m_OldValue); 38 | } 39 | 40 | __forceinline constexpr T& GetOldValue() { return m_OldValue; } 41 | __forceinline constexpr const T& GetOldValue() const { return m_OldValue; } 42 | 43 | __forceinline constexpr bool IsEmpty() const { return !m_Variable; } 44 | void Clear() 45 | { 46 | if (m_Variable) 47 | { 48 | *m_Variable = std::move(m_OldValue); 49 | m_Variable = nullptr; 50 | } 51 | } 52 | 53 | void Emplace(T& variable, const T& newValue) 54 | { 55 | Clear(); 56 | m_Variable = &variable; 57 | m_OldValue = std::move(*m_Variable); 58 | *m_Variable = newValue; 59 | } 60 | void Emplace(T& variable, T&& newValue) 61 | { 62 | Clear(); 63 | m_Variable = &variable; 64 | m_OldValue = std::move(*m_Variable); 65 | *m_Variable = std::move(newValue); 66 | } 67 | 68 | private: 69 | T* m_Variable; 70 | T m_OldValue; 71 | }; 72 | 73 | template inline VariablePusher CreateVariablePusher(T& variable, T&& newValue) 74 | { 75 | return VariablePusher(variable, newValue); 76 | } 77 | template inline VariablePusher CreateVariablePusher(T& variable, const T& newValue) 78 | { 79 | return VariablePusher(variable, newValue); 80 | } -------------------------------------------------------------------------------- /CastingEssentials/Properties/Shared.props: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | 5 | 6 | $(SolutionDir)sdk2013\mp\src\public;$(SolutionDir)sdk2013\mp\src\public\tier0;$(SolutionDir)sdk2013\mp\src\public\tier1;$(SolutionDir)sdk2013\mp\src\common;$(SolutionDir)sdk2013\mp\src\game;$(SolutionDir)sdk2013\mp\src\game\shared;$(SolutionDir)polyhook\polyhook;$(IncludePath) 7 | $(SolutionDir)polyhook\capstone\msvc\x86\$(Configuration)\;$(LibraryPath) 8 | 9 | 10 | 11 | legacy_stdio_definitions.lib;$(SolutionDir)sdk2013\mp\src\lib\public\tier0.lib;$(SolutionDir)sdk2013\mp\src\lib\public\tier1.lib;$(SolutionDir)sdk2013\mp\src\lib\public\tier2.lib;$(SolutionDir)sdk2013\mp\src\lib\public\tier3.lib;$(SolutionDir)sdk2013\mp\src\lib\public\steam_api.lib;$(SolutionDir)sdk2013\mp\src\lib\public\vstdlib.lib;$(SolutionDir)sdk2013\mp\src\lib\public\mathlib.lib;$(SolutionDir)sdk2013\mp\src\lib\public\bitmap.lib;%(AdditionalDependencies) 12 | /ignore:4099 %(AdditionalOptions) 13 | 14 | 15 | 4172;4715;4717;%(TreatSpecificWarningsAsErrors) 16 | SUPPRESS_INVALID_PARAMETER_NO_INFO;VERSION_SAFE_STEAM_API_INTERFACES;CLIENT_DLL;WIN32;RAD_TELEMETRY_DISABLED;TF2_SDK;TF_CLIENT_DLL;GLOWS_ENABLE;NO_PCH;_X86_;MOVE_CONSTRUCTOR_SUPPORT;USES_ECON_ITEMS;CE_DLL;%(PreprocessorDefinitions) 17 | $(ProjectDir)PluginBase\Common.h;%(ForcedIncludeFiles) 18 | 4594;%(DisableSpecificWarnings) 19 | $(ProjectDir);%(AdditionalIncludeDirectories) 20 | true 21 | true 22 | Fast 23 | Level4 24 | true 25 | stdcpplatest 26 | ProgramDatabase 27 | true 28 | 29 | 30 | 31 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # CastingEssentials 2 | 3 | A Team Fortress 2 client plugin that enhances the experience of both casters and viewers. Reimplementation/fork of [StatusSpec](https://github.com/fwdcp/StatusSpec) by [tsc](https://github.com/thesupremecommander). 4 | -------------------------------------------------------------------------------- /flythroughs_config.txt: -------------------------------------------------------------------------------- 1 | Flythroughs 2 | { 3 | // Smooth out over 10 seconds 4 | smooth_period 10 5 | 6 | Idle 7 | { 8 | Target // blu last 9 | { 10 | pos "1234 5678 9012" 11 | ang "30 128 0" 12 | time 30 // Takes 30 seconds to get from red last to here 13 | } 14 | Target // blu second 15 | { 16 | pos "1234 5678 9012" 17 | ang "30 128 0" 18 | time 10 // Takes 10 seconds to get from blu last to here 19 | } 20 | Target // mid 21 | { 22 | pos "1234 5678 9012" 23 | ang "30 128 0" 24 | time 15 // Takes 15 seconds to get from blu second to here 25 | } 26 | Target // red second 27 | { 28 | pos "1234 5678 9012" 29 | ang "30 128 0" 30 | time 15 // Takes 15 seconds to get from mid to here 31 | } 32 | Target // red last 33 | { 34 | pos "1234 5678 9012" 35 | ang "30 128 0" 36 | time 10 // Takes 10 seconds to get from red second to here 37 | } 38 | } 39 | 40 | Blu_Rollout 41 | { 42 | // blu last to mid stuff 43 | } 44 | 45 | Red_Rollout 46 | { 47 | // red last to mid stuff 48 | } 49 | } -------------------------------------------------------------------------------- /license.md: -------------------------------------------------------------------------------- 1 | BSD 2-Clause License 2 | 3 | Copyright (c) 2018, PazerOP 4 | Portions copyright (c) fwdcp 5 | All rights reserved. 6 | 7 | Redistribution and use in source and binary forms, with or without 8 | modification, are permitted provided that the following conditions are met: 9 | 10 | * Redistributions of source code must retain the above copyright notice, this 11 | list of conditions and the following disclaimer. 12 | 13 | * Redistributions in binary form must reproduce the above copyright notice, 14 | this list of conditions and the following disclaimer in the documentation 15 | and/or other materials provided with the distribution. 16 | 17 | THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" 18 | AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 19 | IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE 20 | DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE 21 | FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 22 | DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR 23 | SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER 24 | CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, 25 | OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 26 | OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 27 | -------------------------------------------------------------------------------- /plugin_folder/addons/CastingEssentials.vdf: -------------------------------------------------------------------------------- 1 | Plugin 2 | { 3 | file "addons/CastingEssentials.dll" 4 | } -------------------------------------------------------------------------------- /plugin_folder/do not extract into your TF folder. PLEASE: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/PazerOP/CastingEssentials/d0bd4265233a6fa8d428cdcba326ac0574354a03/plugin_folder/do not extract into your TF folder. PLEASE -------------------------------------------------------------------------------- /plugin_folder/materials/castingessentials/chargebars/baby_face_blue.vmt: -------------------------------------------------------------------------------- 1 | UnlitGeneric 2 | { 3 | $alpha 0 4 | } -------------------------------------------------------------------------------- /plugin_folder/materials/castingessentials/chargebars/baby_face_red.vmt: -------------------------------------------------------------------------------- 1 | UnlitGeneric 2 | { 3 | $alpha 0 4 | } -------------------------------------------------------------------------------- /plugin_folder/materials/castingessentials/chargebars/banana_blue.vmt: -------------------------------------------------------------------------------- 1 | UnlitGeneric 2 | { 3 | $alpha 0 4 | } -------------------------------------------------------------------------------- /plugin_folder/materials/castingessentials/chargebars/banana_red.vmt: -------------------------------------------------------------------------------- 1 | UnlitGeneric 2 | { 3 | $alpha 0 4 | } -------------------------------------------------------------------------------- /plugin_folder/materials/castingessentials/chargebars/banner_battalions_blue.vmt: -------------------------------------------------------------------------------- 1 | UnlitGeneric 2 | { 3 | $alpha 0 4 | } -------------------------------------------------------------------------------- /plugin_folder/materials/castingessentials/chargebars/banner_battalions_red.vmt: -------------------------------------------------------------------------------- 1 | UnlitGeneric 2 | { 3 | $alpha 0 4 | } -------------------------------------------------------------------------------- /plugin_folder/materials/castingessentials/chargebars/banner_buff_blue.vmt: -------------------------------------------------------------------------------- 1 | UnlitGeneric 2 | { 3 | $alpha 0 4 | } -------------------------------------------------------------------------------- /plugin_folder/materials/castingessentials/chargebars/banner_buff_red.vmt: -------------------------------------------------------------------------------- 1 | UnlitGeneric 2 | { 3 | $alpha 0 4 | } -------------------------------------------------------------------------------- /plugin_folder/materials/castingessentials/chargebars/banner_conch_blue.vmt: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/PazerOP/CastingEssentials/d0bd4265233a6fa8d428cdcba326ac0574354a03/plugin_folder/materials/castingessentials/chargebars/banner_conch_blue.vmt -------------------------------------------------------------------------------- /plugin_folder/materials/castingessentials/chargebars/banner_conch_red.vmt: -------------------------------------------------------------------------------- 1 | UnlitGeneric 2 | { 3 | $alpha 0 4 | } -------------------------------------------------------------------------------- /plugin_folder/materials/castingessentials/chargebars/bonk_blue.vmt: -------------------------------------------------------------------------------- 1 | UnlitGeneric 2 | { 3 | $alpha 0 4 | } -------------------------------------------------------------------------------- /plugin_folder/materials/castingessentials/chargebars/bonk_red.vmt: -------------------------------------------------------------------------------- 1 | UnlitGeneric 2 | { 3 | $alpha 0 4 | } -------------------------------------------------------------------------------- /plugin_folder/materials/castingessentials/chargebars/cleaners_carbine_blue.vmt: -------------------------------------------------------------------------------- 1 | UnlitGeneric 2 | { 3 | $alpha 0 4 | } -------------------------------------------------------------------------------- /plugin_folder/materials/castingessentials/chargebars/cleaners_carbine_red.vmt: -------------------------------------------------------------------------------- 1 | UnlitGeneric 2 | { 3 | $alpha 0 4 | } -------------------------------------------------------------------------------- /plugin_folder/materials/castingessentials/chargebars/cleaver_blue.vmt: -------------------------------------------------------------------------------- 1 | UnlitGeneric 2 | { 3 | $alpha 0 4 | } -------------------------------------------------------------------------------- /plugin_folder/materials/castingessentials/chargebars/cleaver_red.vmt: -------------------------------------------------------------------------------- 1 | UnlitGeneric 2 | { 3 | $alpha 0 4 | } -------------------------------------------------------------------------------- /plugin_folder/materials/castingessentials/chargebars/cloak_and_dagger_blue.vmt: -------------------------------------------------------------------------------- 1 | UnlitGeneric 2 | { 3 | $alpha 0 4 | } -------------------------------------------------------------------------------- /plugin_folder/materials/castingessentials/chargebars/cloak_and_dagger_red.vmt: -------------------------------------------------------------------------------- 1 | UnlitGeneric 2 | { 3 | $alpha 0 4 | } -------------------------------------------------------------------------------- /plugin_folder/materials/castingessentials/chargebars/crit_cola_blue.vmt: -------------------------------------------------------------------------------- 1 | UnlitGeneric 2 | { 3 | $alpha 0 4 | } -------------------------------------------------------------------------------- /plugin_folder/materials/castingessentials/chargebars/crit_cola_red.vmt: -------------------------------------------------------------------------------- 1 | UnlitGeneric 2 | { 3 | $alpha 0 4 | } -------------------------------------------------------------------------------- /plugin_folder/materials/castingessentials/chargebars/dalokohs_blue.vmt: -------------------------------------------------------------------------------- 1 | UnlitGeneric 2 | { 3 | $alpha 0 4 | } -------------------------------------------------------------------------------- /plugin_folder/materials/castingessentials/chargebars/dalokohs_red.vmt: -------------------------------------------------------------------------------- 1 | UnlitGeneric 2 | { 3 | $alpha 0 4 | } -------------------------------------------------------------------------------- /plugin_folder/materials/castingessentials/chargebars/dead_ringer_blue.vmt: -------------------------------------------------------------------------------- 1 | UnlitGeneric 2 | { 3 | $alpha 0 4 | } -------------------------------------------------------------------------------- /plugin_folder/materials/castingessentials/chargebars/dead_ringer_red.vmt: -------------------------------------------------------------------------------- 1 | UnlitGeneric 2 | { 3 | $alpha 0 4 | } -------------------------------------------------------------------------------- /plugin_folder/materials/castingessentials/chargebars/gas_passer_blue.vmt: -------------------------------------------------------------------------------- 1 | UnlitGeneric 2 | { 3 | $alpha 0 4 | } -------------------------------------------------------------------------------- /plugin_folder/materials/castingessentials/chargebars/gas_passer_red.vmt: -------------------------------------------------------------------------------- 1 | UnlitGeneric 2 | { 3 | $alpha 0 4 | } -------------------------------------------------------------------------------- /plugin_folder/materials/castingessentials/chargebars/hitmans_heatmaker_blue.vmt: -------------------------------------------------------------------------------- 1 | UnlitGeneric 2 | { 3 | $alpha 0 4 | } -------------------------------------------------------------------------------- /plugin_folder/materials/castingessentials/chargebars/hitmans_heatmaker_red.vmt: -------------------------------------------------------------------------------- 1 | UnlitGeneric 2 | { 3 | $alpha 0 4 | } -------------------------------------------------------------------------------- /plugin_folder/materials/castingessentials/chargebars/invis_watch_blue.vmt: -------------------------------------------------------------------------------- 1 | UnlitGeneric 2 | { 3 | $alpha 0 4 | } -------------------------------------------------------------------------------- /plugin_folder/materials/castingessentials/chargebars/invis_watch_red.vmt: -------------------------------------------------------------------------------- 1 | UnlitGeneric 2 | { 3 | $alpha 0 4 | } -------------------------------------------------------------------------------- /plugin_folder/materials/castingessentials/chargebars/jarate_blue.vmt: -------------------------------------------------------------------------------- 1 | UnlitGeneric 2 | { 3 | $alpha 0 4 | } -------------------------------------------------------------------------------- /plugin_folder/materials/castingessentials/chargebars/jarate_red.vmt: -------------------------------------------------------------------------------- 1 | UnlitGeneric 2 | { 3 | $alpha 0 4 | } -------------------------------------------------------------------------------- /plugin_folder/materials/castingessentials/chargebars/jetpack_blue.vmt: -------------------------------------------------------------------------------- 1 | UnlitGeneric 2 | { 3 | $alpha 0 4 | } -------------------------------------------------------------------------------- /plugin_folder/materials/castingessentials/chargebars/jetpack_red.vmt: -------------------------------------------------------------------------------- 1 | UnlitGeneric 2 | { 3 | $alpha 0 4 | } -------------------------------------------------------------------------------- /plugin_folder/materials/castingessentials/chargebars/medigun_kritz_blue.vmt: -------------------------------------------------------------------------------- 1 | "UnlitGeneric" 2 | { 3 | "$basetexture" "vgui/replay/thumbnails/kritz" 4 | "$translucent" 1 5 | "$ignorez" 1 6 | 7 | $color "{79 117 144}" 8 | } 9 | -------------------------------------------------------------------------------- /plugin_folder/materials/castingessentials/chargebars/medigun_kritz_red.vmt: -------------------------------------------------------------------------------- 1 | "UnlitGeneric" 2 | { 3 | "$basetexture" "vgui/replay/thumbnails/kritz" 4 | "$translucent" 1 5 | "$ignorez" 1 6 | 7 | $color "{188 66 66}" 8 | } 9 | -------------------------------------------------------------------------------- /plugin_folder/materials/castingessentials/chargebars/medigun_quickfix_blue.vmt: -------------------------------------------------------------------------------- 1 | "UnlitGeneric" 2 | { 3 | "$basetexture" "vgui/replay/thumbnails/quickfix" 4 | "$translucent" 1 5 | "$ignorez" 1 6 | 7 | $color "{79 117 144}" 8 | } 9 | -------------------------------------------------------------------------------- /plugin_folder/materials/castingessentials/chargebars/medigun_quickfix_red.vmt: -------------------------------------------------------------------------------- 1 | "UnlitGeneric" 2 | { 3 | "$basetexture" "vgui/replay/thumbnails/quickfix" 4 | "$translucent" 1 5 | "$ignorez" 1 6 | 7 | $color "{188 66 66}" 8 | } 9 | -------------------------------------------------------------------------------- /plugin_folder/materials/castingessentials/chargebars/medigun_uber_blue.vmt: -------------------------------------------------------------------------------- 1 | "UnlitGeneric" 2 | { 3 | "$basetexture" "vgui/replay/thumbnails/uber" 4 | "$translucent" 1 5 | "$ignorez" 1 6 | 7 | $color "{79 117 144}" 8 | } 9 | -------------------------------------------------------------------------------- /plugin_folder/materials/castingessentials/chargebars/medigun_uber_red.vmt: -------------------------------------------------------------------------------- 1 | "UnlitGeneric" 2 | { 3 | "$basetexture" "vgui/replay/thumbnails/uber" 4 | "$translucent" 1 5 | "$ignorez" 1 6 | 7 | $color "{188 66 66}" 8 | } 9 | -------------------------------------------------------------------------------- /plugin_folder/materials/castingessentials/chargebars/medigun_vaccinator_blue_bullet.vmt: -------------------------------------------------------------------------------- 1 | "UnlitGeneric" 2 | { 3 | "$basetexture" "effects/defense_buff_bullet_blue" 4 | "$translucent" 1 5 | "$ignorez" 1 6 | } 7 | -------------------------------------------------------------------------------- /plugin_folder/materials/castingessentials/chargebars/medigun_vaccinator_blue_explosive.vmt: -------------------------------------------------------------------------------- 1 | "UnlitGeneric" 2 | { 3 | "$basetexture" "effects/defense_buff_explosion_blue" 4 | "$translucent" 1 5 | "$ignorez" 1 6 | } 7 | -------------------------------------------------------------------------------- /plugin_folder/materials/castingessentials/chargebars/medigun_vaccinator_blue_fire.vmt: -------------------------------------------------------------------------------- 1 | "UnlitGeneric" 2 | { 3 | "$basetexture" "effects/defense_buff_fire_blue" 4 | "$translucent" 1 5 | "$ignorez" 1 6 | } 7 | -------------------------------------------------------------------------------- /plugin_folder/materials/castingessentials/chargebars/medigun_vaccinator_red_bullet.vmt: -------------------------------------------------------------------------------- 1 | "UnlitGeneric" 2 | { 3 | "$basetexture" "effects/defense_buff_bullet_red" 4 | "$translucent" 1 5 | "$ignorez" 1 6 | } 7 | -------------------------------------------------------------------------------- /plugin_folder/materials/castingessentials/chargebars/medigun_vaccinator_red_explosive.vmt: -------------------------------------------------------------------------------- 1 | "UnlitGeneric" 2 | { 3 | "$basetexture" "effects/defense_buff_explosion_red" 4 | "$translucent" 1 5 | "$ignorez" 1 6 | } 7 | -------------------------------------------------------------------------------- /plugin_folder/materials/castingessentials/chargebars/medigun_vaccinator_red_fire.vmt: -------------------------------------------------------------------------------- 1 | "UnlitGeneric" 2 | { 3 | "$basetexture" "effects/defense_buff_fire_red" 4 | "$translucent" 1 5 | "$ignorez" 1 6 | } 7 | -------------------------------------------------------------------------------- /plugin_folder/materials/castingessentials/chargebars/milk_blue.vmt: -------------------------------------------------------------------------------- 1 | UnlitGeneric 2 | { 3 | $alpha 0 4 | } -------------------------------------------------------------------------------- /plugin_folder/materials/castingessentials/chargebars/milk_red.vmt: -------------------------------------------------------------------------------- 1 | UnlitGeneric 2 | { 3 | $alpha 0 4 | } -------------------------------------------------------------------------------- /plugin_folder/materials/castingessentials/chargebars/phlog_blue.vmt: -------------------------------------------------------------------------------- 1 | UnlitGeneric 2 | { 3 | $alpha 0 4 | } -------------------------------------------------------------------------------- /plugin_folder/materials/castingessentials/chargebars/phlog_red.vmt: -------------------------------------------------------------------------------- 1 | UnlitGeneric 2 | { 3 | $alpha 0 4 | } -------------------------------------------------------------------------------- /plugin_folder/materials/castingessentials/chargebars/razorback_blue.vmt: -------------------------------------------------------------------------------- 1 | UnlitGeneric 2 | { 3 | $alpha 0 4 | } -------------------------------------------------------------------------------- /plugin_folder/materials/castingessentials/chargebars/razorback_red.vmt: -------------------------------------------------------------------------------- 1 | UnlitGeneric 2 | { 3 | $alpha 0 4 | } -------------------------------------------------------------------------------- /plugin_folder/materials/castingessentials/chargebars/sandman_blue.vmt: -------------------------------------------------------------------------------- 1 | UnlitGeneric 2 | { 3 | $alpha 0 4 | } -------------------------------------------------------------------------------- /plugin_folder/materials/castingessentials/chargebars/sandman_red.vmt: -------------------------------------------------------------------------------- 1 | UnlitGeneric 2 | { 3 | $alpha 0 4 | } -------------------------------------------------------------------------------- /plugin_folder/materials/castingessentials/chargebars/sandvich_blue.vmt: -------------------------------------------------------------------------------- 1 | UnlitGeneric 2 | { 3 | $alpha 0 4 | } -------------------------------------------------------------------------------- /plugin_folder/materials/castingessentials/chargebars/sandvich_red.vmt: -------------------------------------------------------------------------------- 1 | UnlitGeneric 2 | { 3 | $alpha 0 4 | } -------------------------------------------------------------------------------- /plugin_folder/materials/castingessentials/chargebars/shield_splendid_blue.vmt: -------------------------------------------------------------------------------- 1 | UnlitGeneric 2 | { 3 | $alpha 0 4 | } -------------------------------------------------------------------------------- /plugin_folder/materials/castingessentials/chargebars/shield_splendid_red.vmt: -------------------------------------------------------------------------------- 1 | UnlitGeneric 2 | { 3 | $alpha 0 4 | } -------------------------------------------------------------------------------- /plugin_folder/materials/castingessentials/chargebars/shield_targe_blue.vmt: -------------------------------------------------------------------------------- 1 | UnlitGeneric 2 | { 3 | $alpha 0 4 | } -------------------------------------------------------------------------------- /plugin_folder/materials/castingessentials/chargebars/shield_targe_red.vmt: -------------------------------------------------------------------------------- 1 | UnlitGeneric 2 | { 3 | $alpha 0 4 | } -------------------------------------------------------------------------------- /plugin_folder/materials/castingessentials/chargebars/shield_tide_blue.vmt: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/PazerOP/CastingEssentials/d0bd4265233a6fa8d428cdcba326ac0574354a03/plugin_folder/materials/castingessentials/chargebars/shield_tide_blue.vmt -------------------------------------------------------------------------------- /plugin_folder/materials/castingessentials/chargebars/shield_tide_red.vmt: -------------------------------------------------------------------------------- 1 | UnlitGeneric 2 | { 3 | $alpha 0 4 | } -------------------------------------------------------------------------------- /plugin_folder/materials/castingessentials/chargebars/soda_popper_blue.vmt: -------------------------------------------------------------------------------- 1 | UnlitGeneric 2 | { 3 | $alpha 0 4 | } -------------------------------------------------------------------------------- /plugin_folder/materials/castingessentials/chargebars/soda_popper_red.vmt: -------------------------------------------------------------------------------- 1 | UnlitGeneric 2 | { 3 | $alpha 0 4 | } -------------------------------------------------------------------------------- /plugin_folder/materials/castingessentials/chargebars/spycicle_blue.vmt: -------------------------------------------------------------------------------- 1 | UnlitGeneric 2 | { 3 | $alpha 0 4 | } -------------------------------------------------------------------------------- /plugin_folder/materials/castingessentials/chargebars/spycicle_red.vmt: -------------------------------------------------------------------------------- 1 | UnlitGeneric 2 | { 3 | $alpha 0 4 | } -------------------------------------------------------------------------------- /plugin_folder/materials/castingessentials/chargebars/steak_sandvich_blue.vmt: -------------------------------------------------------------------------------- 1 | UnlitGeneric 2 | { 3 | $alpha 0 4 | } -------------------------------------------------------------------------------- /plugin_folder/materials/castingessentials/chargebars/steak_sandvich_red.vmt: -------------------------------------------------------------------------------- 1 | UnlitGeneric 2 | { 3 | $alpha 0 4 | } -------------------------------------------------------------------------------- /plugin_folder/materials/castingessentials/chargebars/wrap_assassin_blue.vmt: -------------------------------------------------------------------------------- 1 | UnlitGeneric 2 | { 3 | $alpha 0 4 | } -------------------------------------------------------------------------------- /plugin_folder/materials/castingessentials/chargebars/wrap_assassin_red.vmt: -------------------------------------------------------------------------------- 1 | UnlitGeneric 2 | { 3 | $alpha 0 4 | } -------------------------------------------------------------------------------- /plugin_folder/materials/castingessentials/fxaa/fxaa.vmt: -------------------------------------------------------------------------------- 1 | screenspace_general 2 | { 3 | $PIXSHADER ce_fxaa_ps30 4 | $basetexture _rt_FullFrameFB 5 | $ignorez 1 6 | $alpha_blend 0 7 | } -------------------------------------------------------------------------------- /plugin_folder/materials/castingessentials/fxaa/luma_to_alpha.vmt: -------------------------------------------------------------------------------- 1 | screenspace_general 2 | { 3 | $PIXSHADER ce_luma_to_alpha_ps20 4 | $basetexture _rt_FullFrameFB1 5 | $ignorez 1 6 | $alpha_blend 0 7 | 8 | $LINEARREAD_BASETEXTURE 1 9 | $LINEARWRITE 1 10 | } -------------------------------------------------------------------------------- /plugin_folder/materials/castingessentials/outlines/backbuffer_reload_from_fb1.vmt: -------------------------------------------------------------------------------- 1 | UnlitGeneric 2 | { 3 | $basetexture _rt_FullFrameFB1 4 | $ignorez 1 5 | } -------------------------------------------------------------------------------- /plugin_folder/materials/castingessentials/outlines/color_override_material.vmt: -------------------------------------------------------------------------------- 1 | UnlitGeneric 2 | { 3 | $basetexture white 4 | $ignorez 1 5 | $model 1 6 | $nodecal 1 7 | } 8 | -------------------------------------------------------------------------------- /plugin_folder/materials/castingessentials/outlines/direct_copy.vmt: -------------------------------------------------------------------------------- 1 | screenspace_general 2 | { 3 | $PIXSHADER ce_texture_copy_ps20 4 | $basetexture _rt_FullFrameFB 5 | $alpha_blend 1 6 | } -------------------------------------------------------------------------------- /plugin_folder/materials/castingessentials/outlines/final_blend.vmt: -------------------------------------------------------------------------------- 1 | //DebugTextureView 2 | UnlitGeneric 3 | { 4 | $basetexture _rt_FullFrameFB 5 | $ShowAlpha 1 6 | $translucent 1 7 | } 8 | -------------------------------------------------------------------------------- /plugin_folder/materials/castingessentials/outlines/l4d_ce_blur_x.vmt: -------------------------------------------------------------------------------- 1 | screenspace_general 2 | { 3 | $PIXSHADER ce_outline_gaussian_ps20 4 | $basetexture _rt_FullFrameFB 5 | $C0_Z 1 // direction X 6 | $C0_W 0 // direction Y 7 | } -------------------------------------------------------------------------------- /plugin_folder/materials/castingessentials/outlines/l4d_ce_blur_y.vmt: -------------------------------------------------------------------------------- 1 | screenspace_general 2 | { 3 | $PIXSHADER ce_outline_gaussian_ps20 4 | $basetexture _rt_FullFrameFB1 5 | $C0_Z 0 // direction X 6 | $C0_W 1 // direction Y 7 | } -------------------------------------------------------------------------------- /plugin_folder/materials/castingessentials/outlines/l4d_ce_downsample4x.vmt: -------------------------------------------------------------------------------- 1 | screenspace_general 2 | { 3 | $PIXSHADER ce_outline_downsample4x_ps20 4 | $basetexture _rt_FullFrameFB 5 | $ignorez 1 6 | } -------------------------------------------------------------------------------- /plugin_folder/materials/castingessentials/outlines/poisson_outline.vmt: -------------------------------------------------------------------------------- 1 | screenspace_general 2 | { 3 | $PIXSHADER ce_outline_poisson_ps20 4 | $alpha_blend 1 5 | $basetexture _rt_FullFrameFB 6 | $ignorez 1 7 | } -------------------------------------------------------------------------------- /plugin_folder/materials/castingessentials/sniperlos/beam.vmt: -------------------------------------------------------------------------------- 1 | UnlitGeneric 2 | { 3 | $basetexture "Effects/beam_generic_2" 4 | $translucent 1 5 | $vertexcolor 1 6 | $nocull 1 7 | $additive 1 8 | } -------------------------------------------------------------------------------- /plugin_folder/materials/castingessentials/statuseffects/battalions_backup_blue.vmt: -------------------------------------------------------------------------------- 1 | "UnlitGeneric" 2 | { 3 | "$basetexture" "effects/soldier_buff_defense_blue" 4 | "$translucent" 1 5 | "$ignorez" 1 6 | } 7 | -------------------------------------------------------------------------------- /plugin_folder/materials/castingessentials/statuseffects/battalions_backup_red.vmt: -------------------------------------------------------------------------------- 1 | "UnlitGeneric" 2 | { 3 | "$basetexture" "effects/soldier_buff_defense_red" 4 | "$translucent" 1 5 | "$ignorez" 1 6 | } 7 | -------------------------------------------------------------------------------- /plugin_folder/materials/castingessentials/statuseffects/bleeding_blue.vmt: -------------------------------------------------------------------------------- 1 | "UnlitGeneric" 2 | { 3 | "$basetexture" "vgui/bleed_drop" 4 | "$translucent" 1 5 | "$ignorez" 1 6 | 7 | //$color "{79 117 144}" 8 | $color "{191 0 0}" 9 | } 10 | -------------------------------------------------------------------------------- /plugin_folder/materials/castingessentials/statuseffects/bleeding_red.vmt: -------------------------------------------------------------------------------- 1 | "UnlitGeneric" 2 | { 3 | "$basetexture" "vgui/bleed_drop" 4 | "$translucent" 1 5 | "$ignorez" 1 6 | 7 | //$color "{188 66 66}" 8 | $color "{191 0 0}" 9 | } 10 | -------------------------------------------------------------------------------- /plugin_folder/materials/castingessentials/statuseffects/buff_banner_blue.vmt: -------------------------------------------------------------------------------- 1 | "UnlitGeneric" 2 | { 3 | "$basetexture" "effects/soldier_buff_offense_blue" 4 | "$translucent" 1 5 | "$ignorez" 1 6 | } 7 | -------------------------------------------------------------------------------- /plugin_folder/materials/castingessentials/statuseffects/buff_banner_red.vmt: -------------------------------------------------------------------------------- 1 | "UnlitGeneric" 2 | { 3 | "$basetexture" "effects/soldier_buff_offense_red" 4 | "$translucent" 1 5 | "$ignorez" 1 6 | } 7 | -------------------------------------------------------------------------------- /plugin_folder/materials/castingessentials/statuseffects/concheror_blue.vmt: -------------------------------------------------------------------------------- 1 | "UnlitGeneric" 2 | { 3 | "$basetexture" "effects/soldier_buff_healonhit_blue" 4 | "$translucent" 1 5 | "$ignorez" 1 6 | } 7 | -------------------------------------------------------------------------------- /plugin_folder/materials/castingessentials/statuseffects/concheror_red.vmt: -------------------------------------------------------------------------------- 1 | "UnlitGeneric" 2 | { 3 | "$basetexture" "effects/soldier_buff_healonhit_red" 4 | "$translucent" 1 5 | "$ignorez" 1 6 | } 7 | -------------------------------------------------------------------------------- /plugin_folder/materials/castingessentials/statuseffects/kritzkrieged_blue.vmt: -------------------------------------------------------------------------------- 1 | "UnlitGeneric" 2 | { 3 | "$basetexture" "vgui/replay/thumbnails/kritz" 4 | "$translucent" 1 5 | "$ignorez" 1 6 | 7 | $color "{79 117 144}" 8 | } 9 | -------------------------------------------------------------------------------- /plugin_folder/materials/castingessentials/statuseffects/kritzkrieged_red.vmt: -------------------------------------------------------------------------------- 1 | "UnlitGeneric" 2 | { 3 | "$basetexture" "vgui/replay/thumbnails/kritz" 4 | "$translucent" 1 5 | "$ignorez" 1 6 | 7 | $color "{188 66 66}" 8 | } 9 | -------------------------------------------------------------------------------- /plugin_folder/materials/castingessentials/statuseffects/marked_for_death_blue.vmt: -------------------------------------------------------------------------------- 1 | "UnlitGeneric" 2 | { 3 | "$basetexture" "vgui/marked_for_death" 4 | "$translucent" 1 5 | "$ignorez" 1 6 | 7 | //$color "{79 117 144}" 8 | } 9 | -------------------------------------------------------------------------------- /plugin_folder/materials/castingessentials/statuseffects/marked_for_death_red.vmt: -------------------------------------------------------------------------------- 1 | "UnlitGeneric" 2 | { 3 | "$basetexture" "vgui/marked_for_death" 4 | "$translucent" 1 5 | "$ignorez" 1 6 | 7 | //$color "{188 66 66}" 8 | } 9 | -------------------------------------------------------------------------------- /plugin_folder/materials/castingessentials/statuseffects/quickfixed_blue.vmt: -------------------------------------------------------------------------------- 1 | "UnlitGeneric" 2 | { 3 | "$basetexture" "vgui/replay/thumbnails/quickfix" 4 | "$translucent" 1 5 | "$ignorez" 1 6 | 7 | $color "{79 117 144}" 8 | } 9 | -------------------------------------------------------------------------------- /plugin_folder/materials/castingessentials/statuseffects/quickfixed_red.vmt: -------------------------------------------------------------------------------- 1 | "UnlitGeneric" 2 | { 3 | "$basetexture" "vgui/replay/thumbnails/quickfix" 4 | "$translucent" 1 5 | "$ignorez" 1 6 | 7 | $color "{188 66 66}" 8 | } 9 | -------------------------------------------------------------------------------- /plugin_folder/materials/castingessentials/statuseffects/ubered_blue.vmt: -------------------------------------------------------------------------------- 1 | "UnlitGeneric" 2 | { 3 | "$basetexture" "vgui/replay/thumbnails/uber" 4 | "$translucent" 1 5 | "$ignorez" 1 6 | 7 | $color "{79 117 144}" 8 | } 9 | -------------------------------------------------------------------------------- /plugin_folder/materials/castingessentials/statuseffects/ubered_red.vmt: -------------------------------------------------------------------------------- 1 | "UnlitGeneric" 2 | { 3 | "$basetexture" "vgui/replay/thumbnails/uber" 4 | "$translucent" 1 5 | "$ignorez" 1 6 | 7 | $color "{188 66 66}" 8 | } 9 | -------------------------------------------------------------------------------- /plugin_folder/materials/castingessentials/statuseffects/vaccinated_blue_bullet.vmt: -------------------------------------------------------------------------------- 1 | "UnlitGeneric" 2 | { 3 | "$basetexture" "effects/defense_buff_bullet_blue" 4 | "$translucent" 1 5 | "$ignorez" 1 6 | } 7 | -------------------------------------------------------------------------------- /plugin_folder/materials/castingessentials/statuseffects/vaccinated_blue_explosive.vmt: -------------------------------------------------------------------------------- 1 | "UnlitGeneric" 2 | { 3 | "$basetexture" "effects/defense_buff_explosion_blue" 4 | "$translucent" 1 5 | "$ignorez" 1 6 | } 7 | -------------------------------------------------------------------------------- /plugin_folder/materials/castingessentials/statuseffects/vaccinated_blue_fire.vmt: -------------------------------------------------------------------------------- 1 | "UnlitGeneric" 2 | { 3 | "$basetexture" "effects/defense_buff_fire_blue" 4 | "$translucent" 1 5 | "$ignorez" 1 6 | } 7 | -------------------------------------------------------------------------------- /plugin_folder/materials/castingessentials/statuseffects/vaccinated_red_bullet.vmt: -------------------------------------------------------------------------------- 1 | "UnlitGeneric" 2 | { 3 | "$basetexture" "effects/defense_buff_bullet_red" 4 | "$translucent" 1 5 | "$ignorez" 1 6 | } 7 | -------------------------------------------------------------------------------- /plugin_folder/materials/castingessentials/statuseffects/vaccinated_red_explosive.vmt: -------------------------------------------------------------------------------- 1 | "UnlitGeneric" 2 | { 3 | "$basetexture" "effects/defense_buff_explosion_red" 4 | "$translucent" 1 5 | "$ignorez" 1 6 | } 7 | -------------------------------------------------------------------------------- /plugin_folder/materials/castingessentials/statuseffects/vaccinated_red_fire.vmt: -------------------------------------------------------------------------------- 1 | "UnlitGeneric" 2 | { 3 | "$basetexture" "effects/defense_buff_fire_red" 4 | "$translucent" 1 5 | "$ignorez" 1 6 | } 7 | -------------------------------------------------------------------------------- /plugin_folder/materials/debug/debugfbtexture0_transluscent.vmt: -------------------------------------------------------------------------------- 1 | UnlitGeneric 2 | { 3 | $basetexture "_rt_FullFrameFB" 4 | //$translucent 1 5 | "%noToolTexture" 1 6 | $additive 1 7 | //$GAMMACOLORREAD 1 8 | //"$linearread_basetexture" 1 9 | //"$linearwrite" 1 10 | } -------------------------------------------------------------------------------- /plugin_folder/materials/debug/debugfbtexture1.vmt: -------------------------------------------------------------------------------- 1 | UnlitGeneric 2 | { 3 | $basetexture "_rt_FullFrameFB1" 4 | "%noToolTexture" 1 5 | 6 | //"$linearread_basetexture" 1 7 | //"$linearwrite" 1 8 | } -------------------------------------------------------------------------------- /plugin_folder/materials/debug/debugsmallfbtexture0_translucent.vmt: -------------------------------------------------------------------------------- 1 | UnlitGeneric 2 | { 3 | $basetexture "_rt_SmallFB0" 4 | //$translucent 1 5 | $additive 1 6 | "%noToolTexture" 1 7 | } -------------------------------------------------------------------------------- /plugin_folder/materials/vgui/hud/mediguninfo/dead_blue.vmt: -------------------------------------------------------------------------------- 1 | "UnlitGeneric" 2 | { 3 | "$basetexture" "vgui/replay/thumbnails/deadshield" 4 | "$translucent" 1 5 | "$ignorez" 1 6 | 7 | $color "{130 130 130}" 8 | $alpha 0.88 // 225 9 | } 10 | -------------------------------------------------------------------------------- /plugin_folder/materials/vgui/hud/mediguninfo/dead_red.vmt: -------------------------------------------------------------------------------- 1 | "UnlitGeneric" 2 | { 3 | "$basetexture" "vgui/replay/thumbnails/deadshield" 4 | "$translucent" 1 5 | "$ignorez" 1 6 | 7 | $color "{130 130 130}" 8 | $alpha 0.88 // 225 9 | } 10 | -------------------------------------------------------------------------------- /plugin_folder/materials/vgui/hud/mediguninfo/kritzkrieg_blue.vmt: -------------------------------------------------------------------------------- 1 | "UnlitGeneric" 2 | { 3 | "$basetexture" "vgui/replay/thumbnails/kritz" 4 | "$translucent" 1 5 | "$ignorez" 1 6 | 7 | $color "{79 117 144}" 8 | } 9 | -------------------------------------------------------------------------------- /plugin_folder/materials/vgui/hud/mediguninfo/kritzkrieg_red.vmt: -------------------------------------------------------------------------------- 1 | "UnlitGeneric" 2 | { 3 | "$basetexture" "vgui/replay/thumbnails/kritz" 4 | "$translucent" 1 5 | "$ignorez" 1 6 | 7 | $color "{188 66 66}" 8 | } 9 | -------------------------------------------------------------------------------- /plugin_folder/materials/vgui/hud/mediguninfo/medigun_blue.vmt: -------------------------------------------------------------------------------- 1 | "UnlitGeneric" 2 | { 3 | "$basetexture" "vgui/replay/thumbnails/uber" 4 | "$translucent" 1 5 | "$ignorez" 1 6 | 7 | $color "{79 117 144}" 8 | } 9 | -------------------------------------------------------------------------------- /plugin_folder/materials/vgui/hud/mediguninfo/medigun_red.vmt: -------------------------------------------------------------------------------- 1 | "UnlitGeneric" 2 | { 3 | "$basetexture" "vgui/replay/thumbnails/uber" 4 | "$translucent" 1 5 | "$ignorez" 1 6 | 7 | $color "{188 66 66}" 8 | } 9 | -------------------------------------------------------------------------------- /plugin_folder/materials/vgui/hud/mediguninfo/quickfix_blue.vmt: -------------------------------------------------------------------------------- 1 | "UnlitGeneric" 2 | { 3 | "$basetexture" "vgui/replay/thumbnails/quickfix" 4 | "$translucent" 1 5 | "$ignorez" 1 6 | 7 | $color "{79 117 144}" 8 | } 9 | -------------------------------------------------------------------------------- /plugin_folder/materials/vgui/hud/mediguninfo/quickfix_red.vmt: -------------------------------------------------------------------------------- 1 | "UnlitGeneric" 2 | { 3 | "$basetexture" "vgui/replay/thumbnails/quickfix" 4 | "$translucent" 1 5 | "$ignorez" 1 6 | 7 | $color "{188 66 66}" 8 | } 9 | -------------------------------------------------------------------------------- /plugin_folder/materials/vgui/hud/mediguninfo/vaccinator_blue_bullet.vmt: -------------------------------------------------------------------------------- 1 | "UnlitGeneric" 2 | { 3 | "$basetexture" "effects/defense_buff_bullet_blue" 4 | "$translucent" 1 5 | "$ignorez" 1 6 | } 7 | -------------------------------------------------------------------------------- /plugin_folder/materials/vgui/hud/mediguninfo/vaccinator_blue_explosive.vmt: -------------------------------------------------------------------------------- 1 | "UnlitGeneric" 2 | { 3 | "$basetexture" "effects/defense_buff_explosion_blue" 4 | "$translucent" 1 5 | "$ignorez" 1 6 | } 7 | -------------------------------------------------------------------------------- /plugin_folder/materials/vgui/hud/mediguninfo/vaccinator_blue_fire.vmt: -------------------------------------------------------------------------------- 1 | "UnlitGeneric" 2 | { 3 | "$basetexture" "effects/defense_buff_fire_blue" 4 | "$translucent" 1 5 | "$ignorez" 1 6 | } 7 | -------------------------------------------------------------------------------- /plugin_folder/materials/vgui/hud/mediguninfo/vaccinator_red_bullet.vmt: -------------------------------------------------------------------------------- 1 | "UnlitGeneric" 2 | { 3 | "$basetexture" "effects/defense_buff_bullet_red" 4 | "$translucent" 1 5 | "$ignorez" 1 6 | } 7 | -------------------------------------------------------------------------------- /plugin_folder/materials/vgui/hud/mediguninfo/vaccinator_red_explosive.vmt: -------------------------------------------------------------------------------- 1 | "UnlitGeneric" 2 | { 3 | "$basetexture" "effects/defense_buff_explosion_red" 4 | "$translucent" 1 5 | "$ignorez" 1 6 | } 7 | -------------------------------------------------------------------------------- /plugin_folder/materials/vgui/hud/mediguninfo/vaccinator_red_fire.vmt: -------------------------------------------------------------------------------- 1 | "UnlitGeneric" 2 | { 3 | "$basetexture" "effects/defense_buff_fire_red" 4 | "$translucent" 1 5 | "$ignorez" 1 6 | } 7 | -------------------------------------------------------------------------------- /plugin_folder/put the whole CastingEssentials folder in custom instead: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/PazerOP/CastingEssentials/d0bd4265233a6fa8d428cdcba326ac0574354a03/plugin_folder/put the whole CastingEssentials folder in custom instead -------------------------------------------------------------------------------- /plugin_folder/scripts/items/itemschema_overrides.vdf: -------------------------------------------------------------------------------- 1 | itemschema_overrides 2 | { 3 | // The remap section allows you to manually map children to specific parents. 4 | // If any item models contain the text on the left, they are matched to an 5 | // item with a model name containing the text on the right. 6 | 7 | // Festive weapons (with lights as part of the model) 8 | c_bonesaw_xmas c_bonesaw.mdl 9 | c_blackbox_xmas c_blackbox.mdl 10 | c_holymackerel_xmas c_holymackerel.mdl 11 | c_crusaders_crossbow_xmas c_crusaders_crossbow.mdl 12 | c_wrangler_xmas c_wrangler.mdl 13 | c_bow_xmas c_bow.mdl // Huntsman 14 | c_grenadelauncher_xmas c_grenadelauncher.mdl 15 | c_ambassador_xmas c_ambassador.mdl 16 | c_sandwich_xmas.mdl c_sandwich.mdl 17 | c_backburner_xmas c_backburner.mdl 18 | c_claymore_xmas c_claymore.mdl // Eyelander 19 | c_xms_urinejar "/urinejar.mdl" 20 | c_xms_flaregun c_flaregun_pyro.mdl 21 | c_sapper_xmas c_sapper.mdl 22 | c_xms_double_barrel c_double_barrel.mdl // Force-a-nature 23 | c_ubersaw_xmas c_ubersaw.mdl 24 | c_frontierjustice_xmas c_frontierjustice.mdl 25 | c_fireaxe_pyro_xmas c_axtinguisher_pyro.mdl 26 | c_revolver_xmas c_revolver.mdl 27 | c_xms_energy_drink c_energy_drink.mdl 28 | c_targe_xmas c_targe.mdl 29 | 30 | 35 35 // Separate Kritzkrieg from mediguns 31 | 163 163 // Separate Crit-a-Cola from Bonk 32 | 33 | 142 142 // Gunslinger doesn't have a model declared the normal way 34 | 35 | c_toolbox c_builder // Toolbox -> Build PDA 36 | 37 | 239 239 // Separate GRU from KGB 38 | c_boxing_gloves_xmas 239 // Festive GRU -> GRU 39 | 1184 239 // GRU MvM -> GRU 40 | 41 | 195 5 // UPGRADABLE Fists -> Fists (Fists don't have a model) 42 | } -------------------------------------------------------------------------------- /plugin_folder/shaders/fxc/ce_fxaa_ps30.vcs: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/PazerOP/CastingEssentials/d0bd4265233a6fa8d428cdcba326ac0574354a03/plugin_folder/shaders/fxc/ce_fxaa_ps30.vcs -------------------------------------------------------------------------------- /plugin_folder/shaders/fxc/ce_luma_to_alpha_ps20.vcs: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/PazerOP/CastingEssentials/d0bd4265233a6fa8d428cdcba326ac0574354a03/plugin_folder/shaders/fxc/ce_luma_to_alpha_ps20.vcs -------------------------------------------------------------------------------- /plugin_folder/shaders/fxc/ce_luma_to_alpha_ps20b.vcs: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/PazerOP/CastingEssentials/d0bd4265233a6fa8d428cdcba326ac0574354a03/plugin_folder/shaders/fxc/ce_luma_to_alpha_ps20b.vcs -------------------------------------------------------------------------------- /plugin_folder/shaders/fxc/ce_outline_downsample4x_ps20.vcs: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/PazerOP/CastingEssentials/d0bd4265233a6fa8d428cdcba326ac0574354a03/plugin_folder/shaders/fxc/ce_outline_downsample4x_ps20.vcs -------------------------------------------------------------------------------- /plugin_folder/shaders/fxc/ce_outline_downsample4x_ps20b.vcs: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/PazerOP/CastingEssentials/d0bd4265233a6fa8d428cdcba326ac0574354a03/plugin_folder/shaders/fxc/ce_outline_downsample4x_ps20b.vcs -------------------------------------------------------------------------------- /plugin_folder/shaders/fxc/ce_outline_gaussian_ps20.vcs: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/PazerOP/CastingEssentials/d0bd4265233a6fa8d428cdcba326ac0574354a03/plugin_folder/shaders/fxc/ce_outline_gaussian_ps20.vcs -------------------------------------------------------------------------------- /plugin_folder/shaders/fxc/ce_outline_gaussian_ps20b.vcs: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/PazerOP/CastingEssentials/d0bd4265233a6fa8d428cdcba326ac0574354a03/plugin_folder/shaders/fxc/ce_outline_gaussian_ps20b.vcs -------------------------------------------------------------------------------- /plugin_folder/shaders/fxc/ce_outline_poisson_ps20.vcs: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/PazerOP/CastingEssentials/d0bd4265233a6fa8d428cdcba326ac0574354a03/plugin_folder/shaders/fxc/ce_outline_poisson_ps20.vcs -------------------------------------------------------------------------------- /plugin_folder/shaders/fxc/ce_outline_poisson_ps20b.vcs: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/PazerOP/CastingEssentials/d0bd4265233a6fa8d428cdcba326ac0574354a03/plugin_folder/shaders/fxc/ce_outline_poisson_ps20b.vcs -------------------------------------------------------------------------------- /plugin_folder/shaders/fxc/ce_texture_copy_ps20.vcs: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/PazerOP/CastingEssentials/d0bd4265233a6fa8d428cdcba326ac0574354a03/plugin_folder/shaders/fxc/ce_texture_copy_ps20.vcs -------------------------------------------------------------------------------- /plugin_folder/shaders/fxc/ce_texture_copy_ps20b.vcs: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/PazerOP/CastingEssentials/d0bd4265233a6fa8d428cdcba326ac0574354a03/plugin_folder/shaders/fxc/ce_texture_copy_ps20b.vcs -------------------------------------------------------------------------------- /sent_to_valve/spec_steamid.cpp: -------------------------------------------------------------------------------- 1 | void CSteamID::SetFromString(const char* pchSteamID, EUniverse eDefaultUniverse) 2 | { 3 | uint64 steam1_ID; 4 | 5 | int steam2_ID1, steam2_ID2, steam2_ID3; 6 | 7 | char steam3AccType; 8 | int steam3_ID1, steam3_ID2; 9 | 10 | if (sscanf(pchSteamID, "[%c:%i:%i]", &steam3AccType, &steam3_ID1, &steam3_ID2) == 3 || 11 | sscanf(pchSteamID, "%c:%i:%i", &steam3AccType, &steam3_ID1, &steam3_ID2) == 3) 12 | { 13 | EAccountType accountType; 14 | if (steam3AccType == 'u' || steam3AccType == 'U') 15 | accountType = k_EAccountTypeIndividual; 16 | else if (steam3AccType == 'm' || steam3AccType == 'M') 17 | accountType = k_EAccountTypeMultiseat; 18 | else if (steam3AccType == 'G') 19 | accountType = k_EAccountTypeGameServer; 20 | else if (steam3AccType == 'A') 21 | accountType = k_EAccountTypeAnonGameServer; 22 | else if (steam3AccType == 'p' || steam3AccType == 'P') 23 | accountType = k_EAccountTypePending; 24 | else if (steam3AccType == 'C') 25 | accountType = k_EAccountTypeContentServer; 26 | else if (steam3AccType == 'g') 27 | accountType = k_EAccountTypeClan; 28 | else if (steam3AccType == 't' || steam3AccType == 'T' || steam3AccType == 'l' || steam3AccType == 'L' || steam3AccType == 'c') 29 | accountType = k_EAccountTypeChat; 30 | else if (steam3AccType == 'a') 31 | accountType = k_EAccountTypeAnonUser; 32 | else 33 | accountType = k_EAccountTypeInvalid; 34 | 35 | Set(steam3_ID2, (EUniverse)steam3_ID1, accountType); 36 | } 37 | else if (sscanf(pchSteamID, "STEAM_%i:%i:%i", &steam2_ID1, &steam2_ID2, &steam2_ID3) == 3) 38 | { 39 | Set(steam2_ID3 * 2 + steam2_ID2, (EUniverse)steam2_ID1, k_EAccountTypeIndividual); 40 | } 41 | else if (sscanf(pchSteamID, "%llu", &steam1_ID) == 1) 42 | { 43 | SetFromUint64(steam1_ID); 44 | } 45 | else 46 | { 47 | // Failed to parse 48 | *this = k_steamIDNil; 49 | } 50 | } 51 | 52 | // Required includes 53 | #include "convar.h" 54 | #include "cdll_int.h" 55 | #include "cdll_client_int.h" 56 | #include "hltvcamera.h" 57 | #include "util_shared.h" 58 | #include "c_baseplayer.h" 59 | #include "characterset.h" 60 | 61 | CON_COMMAND_F(spec_steamid, "Spectate player with the given SteamID", FCVAR_CLIENTCMD_CAN_EXECUTE) 62 | { 63 | // Default CCommand::Tokenize breaks up arguments at ':' characters 64 | CCommand reparsedArgs; 65 | { 66 | characterset_t newSet; 67 | CharacterSetBuild(&newSet, "{}()'"); // Everything the default set has, minus the ':' 68 | if (!reparsedArgs.Tokenize(args.GetCommandString(), &newSet)) 69 | { 70 | Warning("spec_steamid: Failed to reparse command string \"%s\"\n", args.GetCommandString()); 71 | return; 72 | } 73 | } 74 | 75 | if (reparsedArgs.ArgC() != 2) 76 | { 77 | Warning("Usage: spec_steamid \n"); 78 | return; 79 | } 80 | 81 | CSteamID parsedID; 82 | parsedID.SetFromString(reparsedArgs.Arg(1), k_EUniversePublic); 83 | if (parsedID == k_steamIDNil) 84 | { 85 | Warning("spec_steamid: Failed to parse steam ID \"%s\"\n", reparsedArgs.Arg(1)); 86 | return; 87 | } 88 | 89 | for (int i = 1; i <= MAX_PLAYERS; i++) 90 | { 91 | CSteamID currentID; 92 | { 93 | player_info_t info; 94 | if (!engine->GetPlayerInfo(i, &info)) 95 | continue; 96 | 97 | currentID.SetFromString(info.guid, k_EUniversePublic); 98 | } 99 | 100 | if (parsedID == currentID) 101 | { 102 | // Switch to this player 103 | if (engine->IsHLTV()) 104 | { 105 | if (!HLTVCamera()->IsPVSLocked()) 106 | HLTVCamera()->SetPrimaryTarget(i); 107 | else 108 | Warning("spec_steamid: HLTV PVS is currently locked.\n"); 109 | } 110 | else 111 | { 112 | // Re-use spec_player server command so valve only has to paste in 1 function :) 113 | char buffer[64]; 114 | snprintf(buffer, sizeof(buffer), "spec_player %i", i); 115 | 116 | CCommand specPlayerCmd; 117 | specPlayerCmd.Tokenize(buffer); 118 | ForwardSpecCmdToServer(specPlayerCmd); 119 | } 120 | 121 | return; 122 | } 123 | } 124 | 125 | Warning("spec_steamid: No player found on server with steam ID %s\n", reparsedArgs.Arg(1)); 126 | } --------------------------------------------------------------------------------