mirror of
https://github.com/alliedmodders/hl2sdk.git
synced 2024-12-23 01:59:43 +08:00
Added most recent version of unmodified HL2 SDK for Episode 1 engine
This commit is contained in:
commit
cb8fd25d1f
228
Everything_SDK-2003.sln
Normal file
228
Everything_SDK-2003.sln
Normal file
@ -0,0 +1,228 @@
|
|||||||
|
Microsoft Visual Studio Solution File, Format Version 8.00
|
||||||
|
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "glview", "utils\glview\glview-2003.vcproj", "{BD1604CA-F401-4C4B-821C-251F5AE157FE}"
|
||||||
|
ProjectSection(ProjectDependencies) = postProject
|
||||||
|
{E1DA8DB8-FB4C-4B14-91A6-98BCED6B9720} = {E1DA8DB8-FB4C-4B14-91A6-98BCED6B9720}
|
||||||
|
{E1DA9FB8-FB4C-4B14-91A6-98BCED6B9720} = {E1DA9FB8-FB4C-4B14-91A6-98BCED6B9720}
|
||||||
|
EndProjectSection
|
||||||
|
EndProject
|
||||||
|
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "height2normal", "utils\height2normal\height2normal-2003.vcproj", "{0FDD99E4-130F-493C-8202-4C0236CC47EA}"
|
||||||
|
ProjectSection(ProjectDependencies) = postProject
|
||||||
|
{E1DA8DB8-FB4C-4B14-91A6-98BCED6B9720} = {E1DA8DB8-FB4C-4B14-91A6-98BCED6B9720}
|
||||||
|
{E1DA9FB8-FB4C-4B14-91A6-98BCED6B9720} = {E1DA9FB8-FB4C-4B14-91A6-98BCED6B9720}
|
||||||
|
EndProjectSection
|
||||||
|
EndProject
|
||||||
|
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "serverplugin_empty", "utils\serverplugin_sample\serverplugin_empty-2003.vcproj", "{B6572CBE-7C7F-4FFF-94DE-AFBBBAB11C64}"
|
||||||
|
ProjectSection(ProjectDependencies) = postProject
|
||||||
|
{E1DA8DB8-FB4C-4B14-91A6-98BCED6B9720} = {E1DA8DB8-FB4C-4B14-91A6-98BCED6B9720}
|
||||||
|
{E1DA9FB8-FB4C-4B14-91A6-98BCED6B9720} = {E1DA9FB8-FB4C-4B14-91A6-98BCED6B9720}
|
||||||
|
EndProjectSection
|
||||||
|
EndProject
|
||||||
|
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "studiomdl", "utils\studiomdl\studiomdl-2003.vcproj", "{AE28536E-885A-41BF-99A4-41A7E424B869}"
|
||||||
|
ProjectSection(ProjectDependencies) = postProject
|
||||||
|
{E1DA8DB8-FB4C-4B14-91A6-98BCED6B9720} = {E1DA8DB8-FB4C-4B14-91A6-98BCED6B9720}
|
||||||
|
{E1DA9FB8-FB4C-4B14-91A6-98BCED6B9720} = {E1DA9FB8-FB4C-4B14-91A6-98BCED6B9720}
|
||||||
|
EndProjectSection
|
||||||
|
EndProject
|
||||||
|
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "tgadiff", "utils\tgadiff\tgadiff-2003.vcproj", "{0CE0AF8A-A977-4538-9D63-BCB76DE1BAC6}"
|
||||||
|
ProjectSection(ProjectDependencies) = postProject
|
||||||
|
{E1DA8DB8-FB4C-4B14-91A6-98BCED6B9720} = {E1DA8DB8-FB4C-4B14-91A6-98BCED6B9720}
|
||||||
|
{E1DA9FB8-FB4C-4B14-91A6-98BCED6B9720} = {E1DA9FB8-FB4C-4B14-91A6-98BCED6B9720}
|
||||||
|
EndProjectSection
|
||||||
|
EndProject
|
||||||
|
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "vbsp", "utils\vbsp\vbsp-2003.vcproj", "{B78B6271-B19A-4CF6-926E-40B643548E23}"
|
||||||
|
ProjectSection(ProjectDependencies) = postProject
|
||||||
|
{E1DA8DB8-FB4C-4B14-91A6-98BCED6B9720} = {E1DA8DB8-FB4C-4B14-91A6-98BCED6B9720}
|
||||||
|
{E1DA9FB8-FB4C-4B14-91A6-98BCED6B9720} = {E1DA9FB8-FB4C-4B14-91A6-98BCED6B9720}
|
||||||
|
EndProjectSection
|
||||||
|
EndProject
|
||||||
|
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "vice", "utils\vice\vice-2003.vcproj", "{3CE6E7A9-89EC-4304-8D72-5B602B4DBD09}"
|
||||||
|
ProjectSection(ProjectDependencies) = postProject
|
||||||
|
{E1DA8DB8-FB4C-4B14-91A6-98BCED6B9720} = {E1DA8DB8-FB4C-4B14-91A6-98BCED6B9720}
|
||||||
|
EndProjectSection
|
||||||
|
EndProject
|
||||||
|
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "vprojtomake", "utils\vprojtomake\vprojtomake-2003.vcproj", "{EA55446E-BC04-491C-A9F0-605DFCBB213A}"
|
||||||
|
ProjectSection(ProjectDependencies) = postProject
|
||||||
|
{E1DA8DB8-FB4C-4B14-91A6-98BCED6B9720} = {E1DA8DB8-FB4C-4B14-91A6-98BCED6B9720}
|
||||||
|
EndProjectSection
|
||||||
|
EndProject
|
||||||
|
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "vrad", "utils\vrad\vrad-2003.vcproj", "{FC0F5DE3-F09F-4EF6-98F9-BA762FFF268D}"
|
||||||
|
ProjectSection(ProjectDependencies) = postProject
|
||||||
|
{E1DA8DB8-FB4C-4B14-91A6-98BCED6B9720} = {E1DA8DB8-FB4C-4B14-91A6-98BCED6B9720}
|
||||||
|
{E1DA9FB8-FB4C-4B14-91A6-98BCED6B9720} = {E1DA9FB8-FB4C-4B14-91A6-98BCED6B9720}
|
||||||
|
EndProjectSection
|
||||||
|
EndProject
|
||||||
|
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "vrad_launcher", "utils\vrad_launcher\vrad_launcher-2003.vcproj", "{914F19DF-64EC-4E7D-8B01-76477BF06479}"
|
||||||
|
ProjectSection(ProjectDependencies) = postProject
|
||||||
|
{E1DA8DB8-FB4C-4B14-91A6-98BCED6B9720} = {E1DA8DB8-FB4C-4B14-91A6-98BCED6B9720}
|
||||||
|
EndProjectSection
|
||||||
|
EndProject
|
||||||
|
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "vtf2tga", "utils\vtf2tga\vtf2tga-2003.vcproj", "{2A1F656C-053C-46A4-AE33-304C1D865E0C}"
|
||||||
|
ProjectSection(ProjectDependencies) = postProject
|
||||||
|
{E1DA8DB8-FB4C-4B14-91A6-98BCED6B9720} = {E1DA8DB8-FB4C-4B14-91A6-98BCED6B9720}
|
||||||
|
{E1DA9FB8-FB4C-4B14-91A6-98BCED6B9720} = {E1DA9FB8-FB4C-4B14-91A6-98BCED6B9720}
|
||||||
|
EndProjectSection
|
||||||
|
EndProject
|
||||||
|
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "vtfdiff", "utils\vtfdiff\vtfdiff-2003.vcproj", "{0A368DE7-D34A-48D3-B517-996BFF2D0D5D}"
|
||||||
|
ProjectSection(ProjectDependencies) = postProject
|
||||||
|
{E1DA8DB8-FB4C-4B14-91A6-98BCED6B9720} = {E1DA8DB8-FB4C-4B14-91A6-98BCED6B9720}
|
||||||
|
{E1DA9FB8-FB4C-4B14-91A6-98BCED6B9720} = {E1DA9FB8-FB4C-4B14-91A6-98BCED6B9720}
|
||||||
|
EndProjectSection
|
||||||
|
EndProject
|
||||||
|
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "vvis", "utils\vvis\vvis-2003.vcproj", "{5B065E70-6EE0-4B47-BA64-113D2F81220D}"
|
||||||
|
ProjectSection(ProjectDependencies) = postProject
|
||||||
|
{E1DA8DB8-FB4C-4B14-91A6-98BCED6B9720} = {E1DA8DB8-FB4C-4B14-91A6-98BCED6B9720}
|
||||||
|
{E1DA9FB8-FB4C-4B14-91A6-98BCED6B9720} = {E1DA9FB8-FB4C-4B14-91A6-98BCED6B9720}
|
||||||
|
EndProjectSection
|
||||||
|
EndProject
|
||||||
|
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "vvis_launcher", "utils\vvis_launcher\vvis_launcher-2003.vcproj", "{4C0B9915-E8FF-4089-8927-FC934BFC1E4A}"
|
||||||
|
ProjectSection(ProjectDependencies) = postProject
|
||||||
|
{E1DA8DB8-FB4C-4B14-91A6-98BCED6B9720} = {E1DA8DB8-FB4C-4B14-91A6-98BCED6B9720}
|
||||||
|
EndProjectSection
|
||||||
|
EndProject
|
||||||
|
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "xwad", "utils\xwad\xwad-2003.vcproj", "{B850012C-98A2-42F7-B023-9F65C448D938}"
|
||||||
|
ProjectSection(ProjectDependencies) = postProject
|
||||||
|
EndProjectSection
|
||||||
|
EndProject
|
||||||
|
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "vgui_controls", "vgui2\controls\vgui_controls-2003.vcproj", "{C3CEFD6F-5CDC-41DE-8D43-D932F508F51B}"
|
||||||
|
ProjectSection(ProjectDependencies) = postProject
|
||||||
|
EndProjectSection
|
||||||
|
EndProject
|
||||||
|
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "demoinfo", "utils\demoinfo\demoinfo-2003.vcproj", "{4FE3FDCA-9571-44B3-A521-C81448434490}"
|
||||||
|
ProjectSection(ProjectDependencies) = postProject
|
||||||
|
{E1DA8DB8-FB4C-4B14-91A6-98BCED6B9720} = {E1DA8DB8-FB4C-4B14-91A6-98BCED6B9720}
|
||||||
|
EndProjectSection
|
||||||
|
EndProject
|
||||||
|
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "motionmapper", "utils\motionmapper\motionmapper-2003.vcproj", "{A882FC08-8B92-4D4F-89BF-75BCEC2BAE11}"
|
||||||
|
ProjectSection(ProjectDependencies) = postProject
|
||||||
|
{E1DA8DB8-FB4C-4B14-91A6-98BCED6B9720} = {E1DA8DB8-FB4C-4B14-91A6-98BCED6B9720}
|
||||||
|
{E1DA9FB8-FB4C-4B14-91A6-98BCED6B9720} = {E1DA9FB8-FB4C-4B14-91A6-98BCED6B9720}
|
||||||
|
EndProjectSection
|
||||||
|
EndProject
|
||||||
|
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "QC_Eyes", "utils\qc_eyes\QC_Eyes-2003.vcproj", "{D373436F-7DBF-468B-A3E4-601FB8556544}"
|
||||||
|
ProjectSection(ProjectDependencies) = postProject
|
||||||
|
EndProjectSection
|
||||||
|
EndProject
|
||||||
|
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "mathlib", "mathlib\mathlib-2003.vcproj", "{E1DA9FB8-FB4C-4B14-91A6-98BCED6B9720}"
|
||||||
|
ProjectSection(ProjectDependencies) = postProject
|
||||||
|
EndProjectSection
|
||||||
|
EndProject
|
||||||
|
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "tier1", "tier1\tier1-2003.vcproj", "{E1DA8DB8-FB4C-4B14-91A6-98BCED6B9720}"
|
||||||
|
ProjectSection(ProjectDependencies) = postProject
|
||||||
|
EndProjectSection
|
||||||
|
EndProject
|
||||||
|
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "phonemeextractor", "utils\phonemeextractor\phonemeextractor-2003.vcproj", "{8A35F55B-B5C2-47A0-8C4A-5857A8E20385}"
|
||||||
|
ProjectSection(ProjectDependencies) = postProject
|
||||||
|
{E1DA8DB8-FB4C-4B14-91A6-98BCED6B9720} = {E1DA8DB8-FB4C-4B14-91A6-98BCED6B9720}
|
||||||
|
{E1DA9FB8-FB4C-4B14-91A6-98BCED6B9720} = {E1DA9FB8-FB4C-4B14-91A6-98BCED6B9720}
|
||||||
|
EndProjectSection
|
||||||
|
EndProject
|
||||||
|
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "hlmv", "utils\hlmv\hlmv-2003.vcproj", "{F3704DBF-8055-413C-B027-399E5DBCA4DD}"
|
||||||
|
ProjectSection(ProjectDependencies) = postProject
|
||||||
|
EndProjectSection
|
||||||
|
EndProject
|
||||||
|
Global
|
||||||
|
GlobalSection(SolutionConfiguration) = preSolution
|
||||||
|
Debug = Debug
|
||||||
|
Release = Release
|
||||||
|
EndGlobalSection
|
||||||
|
GlobalSection(ProjectDependencies) = postSolution
|
||||||
|
EndGlobalSection
|
||||||
|
GlobalSection(ProjectConfiguration) = postSolution
|
||||||
|
{BD1604CA-F401-4C4B-821C-251F5AE157FE}.Debug.ActiveCfg = Debug|Win32
|
||||||
|
{BD1604CA-F401-4C4B-821C-251F5AE157FE}.Debug.Build.0 = Debug|Win32
|
||||||
|
{BD1604CA-F401-4C4B-821C-251F5AE157FE}.Release.ActiveCfg = Release|Win32
|
||||||
|
{BD1604CA-F401-4C4B-821C-251F5AE157FE}.Release.Build.0 = Release|Win32
|
||||||
|
{0FDD99E4-130F-493C-8202-4C0236CC47EA}.Debug.ActiveCfg = Debug|Win32
|
||||||
|
{0FDD99E4-130F-493C-8202-4C0236CC47EA}.Debug.Build.0 = Debug|Win32
|
||||||
|
{0FDD99E4-130F-493C-8202-4C0236CC47EA}.Release.ActiveCfg = Release|Win32
|
||||||
|
{0FDD99E4-130F-493C-8202-4C0236CC47EA}.Release.Build.0 = Release|Win32
|
||||||
|
{B6572CBE-7C7F-4FFF-94DE-AFBBBAB11C64}.Debug.ActiveCfg = Debug|Win32
|
||||||
|
{B6572CBE-7C7F-4FFF-94DE-AFBBBAB11C64}.Debug.Build.0 = Debug|Win32
|
||||||
|
{B6572CBE-7C7F-4FFF-94DE-AFBBBAB11C64}.Release.ActiveCfg = Release|Win32
|
||||||
|
{B6572CBE-7C7F-4FFF-94DE-AFBBBAB11C64}.Release.Build.0 = Release|Win32
|
||||||
|
{AE28536E-885A-41BF-99A4-41A7E424B869}.Debug.ActiveCfg = Debug|Win32
|
||||||
|
{AE28536E-885A-41BF-99A4-41A7E424B869}.Debug.Build.0 = Debug|Win32
|
||||||
|
{AE28536E-885A-41BF-99A4-41A7E424B869}.Release.ActiveCfg = Release|Win32
|
||||||
|
{AE28536E-885A-41BF-99A4-41A7E424B869}.Release.Build.0 = Release|Win32
|
||||||
|
{0CE0AF8A-A977-4538-9D63-BCB76DE1BAC6}.Debug.ActiveCfg = Debug|Win32
|
||||||
|
{0CE0AF8A-A977-4538-9D63-BCB76DE1BAC6}.Debug.Build.0 = Debug|Win32
|
||||||
|
{0CE0AF8A-A977-4538-9D63-BCB76DE1BAC6}.Release.ActiveCfg = Release|Win32
|
||||||
|
{0CE0AF8A-A977-4538-9D63-BCB76DE1BAC6}.Release.Build.0 = Release|Win32
|
||||||
|
{B78B6271-B19A-4CF6-926E-40B643548E23}.Debug.ActiveCfg = Debug|Win32
|
||||||
|
{B78B6271-B19A-4CF6-926E-40B643548E23}.Debug.Build.0 = Debug|Win32
|
||||||
|
{B78B6271-B19A-4CF6-926E-40B643548E23}.Release.ActiveCfg = Release|Win32
|
||||||
|
{B78B6271-B19A-4CF6-926E-40B643548E23}.Release.Build.0 = Release|Win32
|
||||||
|
{3CE6E7A9-89EC-4304-8D72-5B602B4DBD09}.Debug.ActiveCfg = Debug|Win32
|
||||||
|
{3CE6E7A9-89EC-4304-8D72-5B602B4DBD09}.Debug.Build.0 = Debug|Win32
|
||||||
|
{3CE6E7A9-89EC-4304-8D72-5B602B4DBD09}.Release.ActiveCfg = Release|Win32
|
||||||
|
{3CE6E7A9-89EC-4304-8D72-5B602B4DBD09}.Release.Build.0 = Release|Win32
|
||||||
|
{EA55446E-BC04-491C-A9F0-605DFCBB213A}.Debug.ActiveCfg = Debug|Win32
|
||||||
|
{EA55446E-BC04-491C-A9F0-605DFCBB213A}.Debug.Build.0 = Debug|Win32
|
||||||
|
{EA55446E-BC04-491C-A9F0-605DFCBB213A}.Release.ActiveCfg = Release|Win32
|
||||||
|
{EA55446E-BC04-491C-A9F0-605DFCBB213A}.Release.Build.0 = Release|Win32
|
||||||
|
{FC0F5DE3-F09F-4EF6-98F9-BA762FFF268D}.Debug.ActiveCfg = Debug|Win32
|
||||||
|
{FC0F5DE3-F09F-4EF6-98F9-BA762FFF268D}.Debug.Build.0 = Debug|Win32
|
||||||
|
{FC0F5DE3-F09F-4EF6-98F9-BA762FFF268D}.Release.ActiveCfg = Release|Win32
|
||||||
|
{FC0F5DE3-F09F-4EF6-98F9-BA762FFF268D}.Release.Build.0 = Release|Win32
|
||||||
|
{914F19DF-64EC-4E7D-8B01-76477BF06479}.Debug.ActiveCfg = Debug|Win32
|
||||||
|
{914F19DF-64EC-4E7D-8B01-76477BF06479}.Debug.Build.0 = Debug|Win32
|
||||||
|
{914F19DF-64EC-4E7D-8B01-76477BF06479}.Release.ActiveCfg = Release|Win32
|
||||||
|
{914F19DF-64EC-4E7D-8B01-76477BF06479}.Release.Build.0 = Release|Win32
|
||||||
|
{2A1F656C-053C-46A4-AE33-304C1D865E0C}.Debug.ActiveCfg = Debug|Win32
|
||||||
|
{2A1F656C-053C-46A4-AE33-304C1D865E0C}.Debug.Build.0 = Debug|Win32
|
||||||
|
{2A1F656C-053C-46A4-AE33-304C1D865E0C}.Release.ActiveCfg = Release|Win32
|
||||||
|
{2A1F656C-053C-46A4-AE33-304C1D865E0C}.Release.Build.0 = Release|Win32
|
||||||
|
{0A368DE7-D34A-48D3-B517-996BFF2D0D5D}.Debug.ActiveCfg = Debug|Win32
|
||||||
|
{0A368DE7-D34A-48D3-B517-996BFF2D0D5D}.Debug.Build.0 = Debug|Win32
|
||||||
|
{0A368DE7-D34A-48D3-B517-996BFF2D0D5D}.Release.ActiveCfg = Release|Win32
|
||||||
|
{0A368DE7-D34A-48D3-B517-996BFF2D0D5D}.Release.Build.0 = Release|Win32
|
||||||
|
{5B065E70-6EE0-4B47-BA64-113D2F81220D}.Debug.ActiveCfg = Debug|Win32
|
||||||
|
{5B065E70-6EE0-4B47-BA64-113D2F81220D}.Debug.Build.0 = Debug|Win32
|
||||||
|
{5B065E70-6EE0-4B47-BA64-113D2F81220D}.Release.ActiveCfg = Release|Win32
|
||||||
|
{5B065E70-6EE0-4B47-BA64-113D2F81220D}.Release.Build.0 = Release|Win32
|
||||||
|
{4C0B9915-E8FF-4089-8927-FC934BFC1E4A}.Debug.ActiveCfg = Debug|Win32
|
||||||
|
{4C0B9915-E8FF-4089-8927-FC934BFC1E4A}.Debug.Build.0 = Debug|Win32
|
||||||
|
{4C0B9915-E8FF-4089-8927-FC934BFC1E4A}.Release.ActiveCfg = Release|Win32
|
||||||
|
{4C0B9915-E8FF-4089-8927-FC934BFC1E4A}.Release.Build.0 = Release|Win32
|
||||||
|
{B850012C-98A2-42F7-B023-9F65C448D938}.Debug.ActiveCfg = Debug|Win32
|
||||||
|
{B850012C-98A2-42F7-B023-9F65C448D938}.Debug.Build.0 = Debug|Win32
|
||||||
|
{B850012C-98A2-42F7-B023-9F65C448D938}.Release.ActiveCfg = Release|Win32
|
||||||
|
{B850012C-98A2-42F7-B023-9F65C448D938}.Release.Build.0 = Release|Win32
|
||||||
|
{C3CEFD6F-5CDC-41DE-8D43-D932F508F51B}.Debug.ActiveCfg = Debug|Win32
|
||||||
|
{C3CEFD6F-5CDC-41DE-8D43-D932F508F51B}.Debug.Build.0 = Debug|Win32
|
||||||
|
{C3CEFD6F-5CDC-41DE-8D43-D932F508F51B}.Release.ActiveCfg = Release|Win32
|
||||||
|
{C3CEFD6F-5CDC-41DE-8D43-D932F508F51B}.Release.Build.0 = Release|Win32
|
||||||
|
{4FE3FDCA-9571-44B3-A521-C81448434490}.Debug.ActiveCfg = Debug|Win32
|
||||||
|
{4FE3FDCA-9571-44B3-A521-C81448434490}.Debug.Build.0 = Debug|Win32
|
||||||
|
{4FE3FDCA-9571-44B3-A521-C81448434490}.Release.ActiveCfg = Release|Win32
|
||||||
|
{4FE3FDCA-9571-44B3-A521-C81448434490}.Release.Build.0 = Release|Win32
|
||||||
|
{A882FC08-8B92-4D4F-89BF-75BCEC2BAE11}.Debug.ActiveCfg = Debug|Win32
|
||||||
|
{A882FC08-8B92-4D4F-89BF-75BCEC2BAE11}.Debug.Build.0 = Debug|Win32
|
||||||
|
{A882FC08-8B92-4D4F-89BF-75BCEC2BAE11}.Release.ActiveCfg = Release|Win32
|
||||||
|
{A882FC08-8B92-4D4F-89BF-75BCEC2BAE11}.Release.Build.0 = Release|Win32
|
||||||
|
{D373436F-7DBF-468B-A3E4-601FB8556544}.Debug.ActiveCfg = Debug|Win32
|
||||||
|
{D373436F-7DBF-468B-A3E4-601FB8556544}.Debug.Build.0 = Debug|Win32
|
||||||
|
{D373436F-7DBF-468B-A3E4-601FB8556544}.Release.ActiveCfg = Release|Win32
|
||||||
|
{D373436F-7DBF-468B-A3E4-601FB8556544}.Release.Build.0 = Release|Win32
|
||||||
|
{E1DA9FB8-FB4C-4B14-91A6-98BCED6B9720}.Debug.ActiveCfg = Debug|Win32
|
||||||
|
{E1DA9FB8-FB4C-4B14-91A6-98BCED6B9720}.Debug.Build.0 = Debug|Win32
|
||||||
|
{E1DA9FB8-FB4C-4B14-91A6-98BCED6B9720}.Release.ActiveCfg = Release|Win32
|
||||||
|
{E1DA9FB8-FB4C-4B14-91A6-98BCED6B9720}.Release.Build.0 = Release|Win32
|
||||||
|
{E1DA8DB8-FB4C-4B14-91A6-98BCED6B9720}.Debug.ActiveCfg = Debug|Win32
|
||||||
|
{E1DA8DB8-FB4C-4B14-91A6-98BCED6B9720}.Debug.Build.0 = Debug|Win32
|
||||||
|
{E1DA8DB8-FB4C-4B14-91A6-98BCED6B9720}.Release.ActiveCfg = Release|Win32
|
||||||
|
{E1DA8DB8-FB4C-4B14-91A6-98BCED6B9720}.Release.Build.0 = Release|Win32
|
||||||
|
{8A35F55B-B5C2-47A0-8C4A-5857A8E20385}.Debug.ActiveCfg = Debug|Win32
|
||||||
|
{8A35F55B-B5C2-47A0-8C4A-5857A8E20385}.Debug.Build.0 = Debug|Win32
|
||||||
|
{8A35F55B-B5C2-47A0-8C4A-5857A8E20385}.Release.ActiveCfg = Release|Win32
|
||||||
|
{8A35F55B-B5C2-47A0-8C4A-5857A8E20385}.Release.Build.0 = Release|Win32
|
||||||
|
{F3704DBF-8055-413C-B027-399E5DBCA4DD}.Debug.ActiveCfg = Debug|Win32
|
||||||
|
{F3704DBF-8055-413C-B027-399E5DBCA4DD}.Debug.Build.0 = Debug|Win32
|
||||||
|
{F3704DBF-8055-413C-B027-399E5DBCA4DD}.Release.ActiveCfg = Release|Win32
|
||||||
|
{F3704DBF-8055-413C-B027-399E5DBCA4DD}.Release.Build.0 = Release|Win32
|
||||||
|
EndGlobalSection
|
||||||
|
GlobalSection(ExtensibilityGlobals) = postSolution
|
||||||
|
EndGlobalSection
|
||||||
|
GlobalSection(ExtensibilityAddIns) = postSolution
|
||||||
|
EndGlobalSection
|
||||||
|
EndGlobal
|
214
Everything_SDK-2005.sln
Normal file
214
Everything_SDK-2005.sln
Normal file
@ -0,0 +1,214 @@
|
|||||||
|
Microsoft Visual Studio Solution File, Format Version 9.00
|
||||||
|
# Visual Studio 2005
|
||||||
|
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "glview", "utils\glview\glview-2005.vcproj", "{BD1604CA-F401-4C4B-821C-251F5AE157FE}"
|
||||||
|
ProjectSection(ProjectDependencies) = postProject
|
||||||
|
{E1DA9FB8-FB4C-4B14-91A6-98BCED6B9720} = {E1DA9FB8-FB4C-4B14-91A6-98BCED6B9720}
|
||||||
|
{E1DA8DB8-FB4C-4B14-91A6-98BCED6B9720} = {E1DA8DB8-FB4C-4B14-91A6-98BCED6B9720}
|
||||||
|
EndProjectSection
|
||||||
|
EndProject
|
||||||
|
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "height2normal", "utils\height2normal\height2normal-2005.vcproj", "{0FDD99E4-130F-493C-8202-4C0236CC47EA}"
|
||||||
|
ProjectSection(ProjectDependencies) = postProject
|
||||||
|
{E1DA8DB8-FB4C-4B14-91A6-98BCED6B9720} = {E1DA8DB8-FB4C-4B14-91A6-98BCED6B9720}
|
||||||
|
{E1DA9FB8-FB4C-4B14-91A6-98BCED6B9720} = {E1DA9FB8-FB4C-4B14-91A6-98BCED6B9720}
|
||||||
|
EndProjectSection
|
||||||
|
EndProject
|
||||||
|
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "serverplugin_empty", "utils\serverplugin_sample\serverplugin_empty-2005.vcproj", "{B6572CBE-7C7F-4FFF-94DE-AFBBBAB11C64}"
|
||||||
|
ProjectSection(ProjectDependencies) = postProject
|
||||||
|
{E1DA8DB8-FB4C-4B14-91A6-98BCED6B9720} = {E1DA8DB8-FB4C-4B14-91A6-98BCED6B9720}
|
||||||
|
{E1DA9FB8-FB4C-4B14-91A6-98BCED6B9720} = {E1DA9FB8-FB4C-4B14-91A6-98BCED6B9720}
|
||||||
|
EndProjectSection
|
||||||
|
EndProject
|
||||||
|
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "studiomdl", "utils\studiomdl\studiomdl-2005.vcproj", "{AE28536E-885A-41BF-99A4-41A7E424B869}"
|
||||||
|
ProjectSection(ProjectDependencies) = postProject
|
||||||
|
{E1DA9FB8-FB4C-4B14-91A6-98BCED6B9720} = {E1DA9FB8-FB4C-4B14-91A6-98BCED6B9720}
|
||||||
|
{E1DA8DB8-FB4C-4B14-91A6-98BCED6B9720} = {E1DA8DB8-FB4C-4B14-91A6-98BCED6B9720}
|
||||||
|
EndProjectSection
|
||||||
|
EndProject
|
||||||
|
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "tgadiff", "utils\tgadiff\tgadiff-2005.vcproj", "{0CE0AF8A-A977-4538-9D63-BCB76DE1BAC6}"
|
||||||
|
ProjectSection(ProjectDependencies) = postProject
|
||||||
|
{E1DA8DB8-FB4C-4B14-91A6-98BCED6B9720} = {E1DA8DB8-FB4C-4B14-91A6-98BCED6B9720}
|
||||||
|
{E1DA9FB8-FB4C-4B14-91A6-98BCED6B9720} = {E1DA9FB8-FB4C-4B14-91A6-98BCED6B9720}
|
||||||
|
EndProjectSection
|
||||||
|
EndProject
|
||||||
|
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "vbsp", "utils\vbsp\vbsp-2005.vcproj", "{B78B6271-B19A-4CF6-926E-40B643548E23}"
|
||||||
|
ProjectSection(ProjectDependencies) = postProject
|
||||||
|
{E1DA9FB8-FB4C-4B14-91A6-98BCED6B9720} = {E1DA9FB8-FB4C-4B14-91A6-98BCED6B9720}
|
||||||
|
{E1DA8DB8-FB4C-4B14-91A6-98BCED6B9720} = {E1DA8DB8-FB4C-4B14-91A6-98BCED6B9720}
|
||||||
|
EndProjectSection
|
||||||
|
EndProject
|
||||||
|
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "vice", "utils\vice\vice-2005.vcproj", "{3CE6E7A9-89EC-4304-8D72-5B602B4DBD09}"
|
||||||
|
ProjectSection(ProjectDependencies) = postProject
|
||||||
|
{E1DA8DB8-FB4C-4B14-91A6-98BCED6B9720} = {E1DA8DB8-FB4C-4B14-91A6-98BCED6B9720}
|
||||||
|
EndProjectSection
|
||||||
|
EndProject
|
||||||
|
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "vprojtomake", "utils\vprojtomake\vprojtomake-2005.vcproj", "{EA55446E-BC04-491C-A9F0-605DFCBB213A}"
|
||||||
|
ProjectSection(ProjectDependencies) = postProject
|
||||||
|
{E1DA8DB8-FB4C-4B14-91A6-98BCED6B9720} = {E1DA8DB8-FB4C-4B14-91A6-98BCED6B9720}
|
||||||
|
EndProjectSection
|
||||||
|
EndProject
|
||||||
|
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "vrad", "utils\vrad\vrad-2005.vcproj", "{FC0F5DE3-F09F-4EF6-98F9-BA762FFF268D}"
|
||||||
|
ProjectSection(ProjectDependencies) = postProject
|
||||||
|
{E1DA8DB8-FB4C-4B14-91A6-98BCED6B9720} = {E1DA8DB8-FB4C-4B14-91A6-98BCED6B9720}
|
||||||
|
{E1DA9FB8-FB4C-4B14-91A6-98BCED6B9720} = {E1DA9FB8-FB4C-4B14-91A6-98BCED6B9720}
|
||||||
|
EndProjectSection
|
||||||
|
EndProject
|
||||||
|
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "vrad_launcher", "utils\vrad_launcher\vrad_launcher-2005.vcproj", "{914F19DF-64EC-4E7D-8B01-76477BF06479}"
|
||||||
|
ProjectSection(ProjectDependencies) = postProject
|
||||||
|
{E1DA8DB8-FB4C-4B14-91A6-98BCED6B9720} = {E1DA8DB8-FB4C-4B14-91A6-98BCED6B9720}
|
||||||
|
EndProjectSection
|
||||||
|
EndProject
|
||||||
|
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "vtf2tga", "utils\vtf2tga\vtf2tga-2005.vcproj", "{2A1F656C-053C-46A4-AE33-304C1D865E0C}"
|
||||||
|
ProjectSection(ProjectDependencies) = postProject
|
||||||
|
{E1DA8DB8-FB4C-4B14-91A6-98BCED6B9720} = {E1DA8DB8-FB4C-4B14-91A6-98BCED6B9720}
|
||||||
|
{E1DA9FB8-FB4C-4B14-91A6-98BCED6B9720} = {E1DA9FB8-FB4C-4B14-91A6-98BCED6B9720}
|
||||||
|
EndProjectSection
|
||||||
|
EndProject
|
||||||
|
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "vtfdiff", "utils\vtfdiff\vtfdiff-2005.vcproj", "{0A368DE7-D34A-48D3-B517-996BFF2D0D5D}"
|
||||||
|
ProjectSection(ProjectDependencies) = postProject
|
||||||
|
{E1DA9FB8-FB4C-4B14-91A6-98BCED6B9720} = {E1DA9FB8-FB4C-4B14-91A6-98BCED6B9720}
|
||||||
|
{E1DA8DB8-FB4C-4B14-91A6-98BCED6B9720} = {E1DA8DB8-FB4C-4B14-91A6-98BCED6B9720}
|
||||||
|
EndProjectSection
|
||||||
|
EndProject
|
||||||
|
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "vvis", "utils\vvis\vvis-2005.vcproj", "{5B065E70-6EE0-4B47-BA64-113D2F81220D}"
|
||||||
|
ProjectSection(ProjectDependencies) = postProject
|
||||||
|
{E1DA8DB8-FB4C-4B14-91A6-98BCED6B9720} = {E1DA8DB8-FB4C-4B14-91A6-98BCED6B9720}
|
||||||
|
{E1DA9FB8-FB4C-4B14-91A6-98BCED6B9720} = {E1DA9FB8-FB4C-4B14-91A6-98BCED6B9720}
|
||||||
|
EndProjectSection
|
||||||
|
EndProject
|
||||||
|
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "vvis_launcher", "utils\vvis_launcher\vvis_launcher-2005.vcproj", "{4C0B9915-E8FF-4089-8927-FC934BFC1E4A}"
|
||||||
|
ProjectSection(ProjectDependencies) = postProject
|
||||||
|
{E1DA8DB8-FB4C-4B14-91A6-98BCED6B9720} = {E1DA8DB8-FB4C-4B14-91A6-98BCED6B9720}
|
||||||
|
EndProjectSection
|
||||||
|
EndProject
|
||||||
|
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "xwad", "utils\xwad\xwad-2005.vcproj", "{B850012C-98A2-42F7-B023-9F65C448D938}"
|
||||||
|
EndProject
|
||||||
|
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "vgui_controls", "vgui2\controls\vgui_controls-2005.vcproj", "{C3CEFD6F-5CDC-41DE-8D43-D932F508F51B}"
|
||||||
|
EndProject
|
||||||
|
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "demoinfo", "utils\demoinfo\demoinfo-2005.vcproj", "{4FE3FDCA-9571-44B3-A521-C81448434490}"
|
||||||
|
ProjectSection(ProjectDependencies) = postProject
|
||||||
|
{E1DA8DB8-FB4C-4B14-91A6-98BCED6B9720} = {E1DA8DB8-FB4C-4B14-91A6-98BCED6B9720}
|
||||||
|
EndProjectSection
|
||||||
|
EndProject
|
||||||
|
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "motionmapper", "utils\motionmapper\motionmapper-2005.vcproj", "{A882FC08-8B92-4D4F-89BF-75BCEC2BAE11}"
|
||||||
|
ProjectSection(ProjectDependencies) = postProject
|
||||||
|
{E1DA9FB8-FB4C-4B14-91A6-98BCED6B9720} = {E1DA9FB8-FB4C-4B14-91A6-98BCED6B9720}
|
||||||
|
{E1DA8DB8-FB4C-4B14-91A6-98BCED6B9720} = {E1DA8DB8-FB4C-4B14-91A6-98BCED6B9720}
|
||||||
|
EndProjectSection
|
||||||
|
EndProject
|
||||||
|
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "QC_Eyes", "utils\qc_eyes\QC_Eyes-2005.vcproj", "{D373436F-7DBF-468B-A3E4-601FB8556544}"
|
||||||
|
EndProject
|
||||||
|
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "mathlib", "mathlib\mathlib-2005.vcproj", "{E1DA9FB8-FB4C-4B14-91A6-98BCED6B9720}"
|
||||||
|
EndProject
|
||||||
|
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "tier1", "tier1\tier1-2005.vcproj", "{E1DA8DB8-FB4C-4B14-91A6-98BCED6B9720}"
|
||||||
|
EndProject
|
||||||
|
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "phonemeextractor", "utils\phonemeextractor\phonemeextractor-2005.vcproj", "{8A35F55B-B5C2-47A0-8C4A-5857A8E20385}"
|
||||||
|
ProjectSection(ProjectDependencies) = postProject
|
||||||
|
{E1DA8DB8-FB4C-4B14-91A6-98BCED6B9720} = {E1DA8DB8-FB4C-4B14-91A6-98BCED6B9720}
|
||||||
|
{E1DA9FB8-FB4C-4B14-91A6-98BCED6B9720} = {E1DA9FB8-FB4C-4B14-91A6-98BCED6B9720}
|
||||||
|
EndProjectSection
|
||||||
|
EndProject
|
||||||
|
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "hlmv", "utils\hlmv\hlmv-2005.vcproj", "{F3704DBF-8055-413C-B027-399E5DBCA4DD}"
|
||||||
|
EndProject
|
||||||
|
Global
|
||||||
|
GlobalSection(SolutionConfigurationPlatforms) = preSolution
|
||||||
|
Debug|Win32 = Debug|Win32
|
||||||
|
Release|Win32 = Release|Win32
|
||||||
|
EndGlobalSection
|
||||||
|
GlobalSection(ProjectConfigurationPlatforms) = postSolution
|
||||||
|
{BD1604CA-F401-4C4B-821C-251F5AE157FE}.Debug|Win32.ActiveCfg = Debug|Win32
|
||||||
|
{BD1604CA-F401-4C4B-821C-251F5AE157FE}.Debug|Win32.Build.0 = Debug|Win32
|
||||||
|
{BD1604CA-F401-4C4B-821C-251F5AE157FE}.Release|Win32.ActiveCfg = Release|Win32
|
||||||
|
{BD1604CA-F401-4C4B-821C-251F5AE157FE}.Release|Win32.Build.0 = Release|Win32
|
||||||
|
{0FDD99E4-130F-493C-8202-4C0236CC47EA}.Debug|Win32.ActiveCfg = Debug|Win32
|
||||||
|
{0FDD99E4-130F-493C-8202-4C0236CC47EA}.Debug|Win32.Build.0 = Debug|Win32
|
||||||
|
{0FDD99E4-130F-493C-8202-4C0236CC47EA}.Release|Win32.ActiveCfg = Release|Win32
|
||||||
|
{0FDD99E4-130F-493C-8202-4C0236CC47EA}.Release|Win32.Build.0 = Release|Win32
|
||||||
|
{B6572CBE-7C7F-4FFF-94DE-AFBBBAB11C64}.Debug|Win32.ActiveCfg = Debug|Win32
|
||||||
|
{B6572CBE-7C7F-4FFF-94DE-AFBBBAB11C64}.Debug|Win32.Build.0 = Debug|Win32
|
||||||
|
{B6572CBE-7C7F-4FFF-94DE-AFBBBAB11C64}.Release|Win32.ActiveCfg = Release|Win32
|
||||||
|
{B6572CBE-7C7F-4FFF-94DE-AFBBBAB11C64}.Release|Win32.Build.0 = Release|Win32
|
||||||
|
{AE28536E-885A-41BF-99A4-41A7E424B869}.Debug|Win32.ActiveCfg = Debug|Win32
|
||||||
|
{AE28536E-885A-41BF-99A4-41A7E424B869}.Debug|Win32.Build.0 = Debug|Win32
|
||||||
|
{AE28536E-885A-41BF-99A4-41A7E424B869}.Release|Win32.ActiveCfg = Release|Win32
|
||||||
|
{AE28536E-885A-41BF-99A4-41A7E424B869}.Release|Win32.Build.0 = Release|Win32
|
||||||
|
{0CE0AF8A-A977-4538-9D63-BCB76DE1BAC6}.Debug|Win32.ActiveCfg = Debug|Win32
|
||||||
|
{0CE0AF8A-A977-4538-9D63-BCB76DE1BAC6}.Debug|Win32.Build.0 = Debug|Win32
|
||||||
|
{0CE0AF8A-A977-4538-9D63-BCB76DE1BAC6}.Release|Win32.ActiveCfg = Release|Win32
|
||||||
|
{0CE0AF8A-A977-4538-9D63-BCB76DE1BAC6}.Release|Win32.Build.0 = Release|Win32
|
||||||
|
{B78B6271-B19A-4CF6-926E-40B643548E23}.Debug|Win32.ActiveCfg = Debug|Win32
|
||||||
|
{B78B6271-B19A-4CF6-926E-40B643548E23}.Debug|Win32.Build.0 = Debug|Win32
|
||||||
|
{B78B6271-B19A-4CF6-926E-40B643548E23}.Release|Win32.ActiveCfg = Release|Win32
|
||||||
|
{B78B6271-B19A-4CF6-926E-40B643548E23}.Release|Win32.Build.0 = Release|Win32
|
||||||
|
{3CE6E7A9-89EC-4304-8D72-5B602B4DBD09}.Debug|Win32.ActiveCfg = Debug|Win32
|
||||||
|
{3CE6E7A9-89EC-4304-8D72-5B602B4DBD09}.Debug|Win32.Build.0 = Debug|Win32
|
||||||
|
{3CE6E7A9-89EC-4304-8D72-5B602B4DBD09}.Release|Win32.ActiveCfg = Release|Win32
|
||||||
|
{3CE6E7A9-89EC-4304-8D72-5B602B4DBD09}.Release|Win32.Build.0 = Release|Win32
|
||||||
|
{EA55446E-BC04-491C-A9F0-605DFCBB213A}.Debug|Win32.ActiveCfg = Debug|Win32
|
||||||
|
{EA55446E-BC04-491C-A9F0-605DFCBB213A}.Debug|Win32.Build.0 = Debug|Win32
|
||||||
|
{EA55446E-BC04-491C-A9F0-605DFCBB213A}.Release|Win32.ActiveCfg = Release|Win32
|
||||||
|
{EA55446E-BC04-491C-A9F0-605DFCBB213A}.Release|Win32.Build.0 = Release|Win32
|
||||||
|
{FC0F5DE3-F09F-4EF6-98F9-BA762FFF268D}.Debug|Win32.ActiveCfg = Debug|Win32
|
||||||
|
{FC0F5DE3-F09F-4EF6-98F9-BA762FFF268D}.Debug|Win32.Build.0 = Debug|Win32
|
||||||
|
{FC0F5DE3-F09F-4EF6-98F9-BA762FFF268D}.Release|Win32.ActiveCfg = Release|Win32
|
||||||
|
{FC0F5DE3-F09F-4EF6-98F9-BA762FFF268D}.Release|Win32.Build.0 = Release|Win32
|
||||||
|
{914F19DF-64EC-4E7D-8B01-76477BF06479}.Debug|Win32.ActiveCfg = Debug|Win32
|
||||||
|
{914F19DF-64EC-4E7D-8B01-76477BF06479}.Debug|Win32.Build.0 = Debug|Win32
|
||||||
|
{914F19DF-64EC-4E7D-8B01-76477BF06479}.Release|Win32.ActiveCfg = Release|Win32
|
||||||
|
{914F19DF-64EC-4E7D-8B01-76477BF06479}.Release|Win32.Build.0 = Release|Win32
|
||||||
|
{2A1F656C-053C-46A4-AE33-304C1D865E0C}.Debug|Win32.ActiveCfg = Debug|Win32
|
||||||
|
{2A1F656C-053C-46A4-AE33-304C1D865E0C}.Debug|Win32.Build.0 = Debug|Win32
|
||||||
|
{2A1F656C-053C-46A4-AE33-304C1D865E0C}.Release|Win32.ActiveCfg = Release|Win32
|
||||||
|
{2A1F656C-053C-46A4-AE33-304C1D865E0C}.Release|Win32.Build.0 = Release|Win32
|
||||||
|
{0A368DE7-D34A-48D3-B517-996BFF2D0D5D}.Debug|Win32.ActiveCfg = Debug|Win32
|
||||||
|
{0A368DE7-D34A-48D3-B517-996BFF2D0D5D}.Debug|Win32.Build.0 = Debug|Win32
|
||||||
|
{0A368DE7-D34A-48D3-B517-996BFF2D0D5D}.Release|Win32.ActiveCfg = Release|Win32
|
||||||
|
{0A368DE7-D34A-48D3-B517-996BFF2D0D5D}.Release|Win32.Build.0 = Release|Win32
|
||||||
|
{5B065E70-6EE0-4B47-BA64-113D2F81220D}.Debug|Win32.ActiveCfg = Debug|Win32
|
||||||
|
{5B065E70-6EE0-4B47-BA64-113D2F81220D}.Debug|Win32.Build.0 = Debug|Win32
|
||||||
|
{5B065E70-6EE0-4B47-BA64-113D2F81220D}.Release|Win32.ActiveCfg = Release|Win32
|
||||||
|
{5B065E70-6EE0-4B47-BA64-113D2F81220D}.Release|Win32.Build.0 = Release|Win32
|
||||||
|
{4C0B9915-E8FF-4089-8927-FC934BFC1E4A}.Debug|Win32.ActiveCfg = Debug|Win32
|
||||||
|
{4C0B9915-E8FF-4089-8927-FC934BFC1E4A}.Debug|Win32.Build.0 = Debug|Win32
|
||||||
|
{4C0B9915-E8FF-4089-8927-FC934BFC1E4A}.Release|Win32.ActiveCfg = Release|Win32
|
||||||
|
{4C0B9915-E8FF-4089-8927-FC934BFC1E4A}.Release|Win32.Build.0 = Release|Win32
|
||||||
|
{B850012C-98A2-42F7-B023-9F65C448D938}.Debug|Win32.ActiveCfg = Debug|Win32
|
||||||
|
{B850012C-98A2-42F7-B023-9F65C448D938}.Debug|Win32.Build.0 = Debug|Win32
|
||||||
|
{B850012C-98A2-42F7-B023-9F65C448D938}.Release|Win32.ActiveCfg = Release|Win32
|
||||||
|
{B850012C-98A2-42F7-B023-9F65C448D938}.Release|Win32.Build.0 = Release|Win32
|
||||||
|
{C3CEFD6F-5CDC-41DE-8D43-D932F508F51B}.Debug|Win32.ActiveCfg = Debug|Win32
|
||||||
|
{C3CEFD6F-5CDC-41DE-8D43-D932F508F51B}.Debug|Win32.Build.0 = Debug|Win32
|
||||||
|
{C3CEFD6F-5CDC-41DE-8D43-D932F508F51B}.Release|Win32.ActiveCfg = Release|Win32
|
||||||
|
{C3CEFD6F-5CDC-41DE-8D43-D932F508F51B}.Release|Win32.Build.0 = Release|Win32
|
||||||
|
{4FE3FDCA-9571-44B3-A521-C81448434490}.Debug|Win32.ActiveCfg = Debug|Win32
|
||||||
|
{4FE3FDCA-9571-44B3-A521-C81448434490}.Debug|Win32.Build.0 = Debug|Win32
|
||||||
|
{4FE3FDCA-9571-44B3-A521-C81448434490}.Release|Win32.ActiveCfg = Release|Win32
|
||||||
|
{4FE3FDCA-9571-44B3-A521-C81448434490}.Release|Win32.Build.0 = Release|Win32
|
||||||
|
{A882FC08-8B92-4D4F-89BF-75BCEC2BAE11}.Debug|Win32.ActiveCfg = Debug|Win32
|
||||||
|
{A882FC08-8B92-4D4F-89BF-75BCEC2BAE11}.Debug|Win32.Build.0 = Debug|Win32
|
||||||
|
{A882FC08-8B92-4D4F-89BF-75BCEC2BAE11}.Release|Win32.ActiveCfg = Release|Win32
|
||||||
|
{A882FC08-8B92-4D4F-89BF-75BCEC2BAE11}.Release|Win32.Build.0 = Release|Win32
|
||||||
|
{D373436F-7DBF-468B-A3E4-601FB8556544}.Debug|Win32.ActiveCfg = Debug|Win32
|
||||||
|
{D373436F-7DBF-468B-A3E4-601FB8556544}.Debug|Win32.Build.0 = Debug|Win32
|
||||||
|
{D373436F-7DBF-468B-A3E4-601FB8556544}.Release|Win32.ActiveCfg = Release|Win32
|
||||||
|
{D373436F-7DBF-468B-A3E4-601FB8556544}.Release|Win32.Build.0 = Release|Win32
|
||||||
|
{E1DA9FB8-FB4C-4B14-91A6-98BCED6B9720}.Debug|Win32.ActiveCfg = Debug|Win32
|
||||||
|
{E1DA9FB8-FB4C-4B14-91A6-98BCED6B9720}.Debug|Win32.Build.0 = Debug|Win32
|
||||||
|
{E1DA9FB8-FB4C-4B14-91A6-98BCED6B9720}.Release|Win32.ActiveCfg = Release|Win32
|
||||||
|
{E1DA9FB8-FB4C-4B14-91A6-98BCED6B9720}.Release|Win32.Build.0 = Release|Win32
|
||||||
|
{E1DA8DB8-FB4C-4B14-91A6-98BCED6B9720}.Debug|Win32.ActiveCfg = Debug|Win32
|
||||||
|
{E1DA8DB8-FB4C-4B14-91A6-98BCED6B9720}.Debug|Win32.Build.0 = Debug|Win32
|
||||||
|
{E1DA8DB8-FB4C-4B14-91A6-98BCED6B9720}.Release|Win32.ActiveCfg = Release|Win32
|
||||||
|
{E1DA8DB8-FB4C-4B14-91A6-98BCED6B9720}.Release|Win32.Build.0 = Release|Win32
|
||||||
|
{8A35F55B-B5C2-47A0-8C4A-5857A8E20385}.Debug|Win32.ActiveCfg = Debug|Win32
|
||||||
|
{8A35F55B-B5C2-47A0-8C4A-5857A8E20385}.Debug|Win32.Build.0 = Debug|Win32
|
||||||
|
{8A35F55B-B5C2-47A0-8C4A-5857A8E20385}.Release|Win32.ActiveCfg = Release|Win32
|
||||||
|
{8A35F55B-B5C2-47A0-8C4A-5857A8E20385}.Release|Win32.Build.0 = Release|Win32
|
||||||
|
{F3704DBF-8055-413C-B027-399E5DBCA4DD}.Debug|Win32.ActiveCfg = Debug|Win32
|
||||||
|
{F3704DBF-8055-413C-B027-399E5DBCA4DD}.Debug|Win32.Build.0 = Debug|Win32
|
||||||
|
{F3704DBF-8055-413C-B027-399E5DBCA4DD}.Release|Win32.ActiveCfg = Release|Win32
|
||||||
|
{F3704DBF-8055-413C-B027-399E5DBCA4DD}.Release|Win32.Build.0 = Release|Win32
|
||||||
|
EndGlobalSection
|
||||||
|
GlobalSection(SolutionProperties) = preSolution
|
||||||
|
HideSolutionNode = FALSE
|
||||||
|
EndGlobalSection
|
||||||
|
EndGlobal
|
29
Game_HL2-2003.sln
Normal file
29
Game_HL2-2003.sln
Normal file
@ -0,0 +1,29 @@
|
|||||||
|
Microsoft Visual Studio Solution File, Format Version 8.00
|
||||||
|
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "client", "cl_dll\client_hl2-2003.vcproj", "{E44D6502-2BB4-47F8-85CF-ACDD4FC18329}"
|
||||||
|
ProjectSection(ProjectDependencies) = postProject
|
||||||
|
EndProjectSection
|
||||||
|
EndProject
|
||||||
|
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "server", "dlls\server_hl2-2003.vcproj", "{1AA0213B-2B68-40CD-90F8-CFDFD37C1550}"
|
||||||
|
ProjectSection(ProjectDependencies) = postProject
|
||||||
|
EndProjectSection
|
||||||
|
EndProject
|
||||||
|
Global
|
||||||
|
GlobalSection(SolutionConfiguration) = preSolution
|
||||||
|
Debug HL2 = Debug HL2
|
||||||
|
Release HL2 = Release HL2
|
||||||
|
EndGlobalSection
|
||||||
|
GlobalSection(ProjectConfiguration) = postSolution
|
||||||
|
{E44D6502-2BB4-47F8-85CF-ACDD4FC18329}.Debug HL2.ActiveCfg = Debug HL2|Win32
|
||||||
|
{E44D6502-2BB4-47F8-85CF-ACDD4FC18329}.Debug HL2.Build.0 = Debug HL2|Win32
|
||||||
|
{E44D6502-2BB4-47F8-85CF-ACDD4FC18329}.Release HL2.ActiveCfg = Release HL2|Win32
|
||||||
|
{E44D6502-2BB4-47F8-85CF-ACDD4FC18329}.Release HL2.Build.0 = Release HL2|Win32
|
||||||
|
{1AA0213B-2B68-40CD-90F8-CFDFD37C1550}.Debug HL2.ActiveCfg = Debug HL2|Win32
|
||||||
|
{1AA0213B-2B68-40CD-90F8-CFDFD37C1550}.Debug HL2.Build.0 = Debug HL2|Win32
|
||||||
|
{1AA0213B-2B68-40CD-90F8-CFDFD37C1550}.Release HL2.ActiveCfg = Release HL2|Win32
|
||||||
|
{1AA0213B-2B68-40CD-90F8-CFDFD37C1550}.Release HL2.Build.0 = Release HL2|Win32
|
||||||
|
EndGlobalSection
|
||||||
|
GlobalSection(ExtensibilityGlobals) = postSolution
|
||||||
|
EndGlobalSection
|
||||||
|
GlobalSection(ExtensibilityAddIns) = postSolution
|
||||||
|
EndGlobalSection
|
||||||
|
EndGlobal
|
25
Game_HL2-2005.sln
Normal file
25
Game_HL2-2005.sln
Normal file
@ -0,0 +1,25 @@
|
|||||||
|
Microsoft Visual Studio Solution File, Format Version 9.00
|
||||||
|
# Visual Studio 2005
|
||||||
|
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "client_hl2", "cl_dll\client_hl2-2005.vcproj", "{E44D6502-2BB4-47F8-85CF-ACDD4FC18329}"
|
||||||
|
EndProject
|
||||||
|
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "server_hl2", "dlls\server_hl2-2005.vcproj", "{1AA0213B-2B68-40CD-90F8-CFDFD37C1550}"
|
||||||
|
EndProject
|
||||||
|
Global
|
||||||
|
GlobalSection(SolutionConfigurationPlatforms) = preSolution
|
||||||
|
Debug HL2|Win32 = Debug HL2|Win32
|
||||||
|
Release HL2|Win32 = Release HL2|Win32
|
||||||
|
EndGlobalSection
|
||||||
|
GlobalSection(ProjectConfigurationPlatforms) = postSolution
|
||||||
|
{E44D6502-2BB4-47F8-85CF-ACDD4FC18329}.Debug HL2|Win32.ActiveCfg = Debug HL2|Win32
|
||||||
|
{E44D6502-2BB4-47F8-85CF-ACDD4FC18329}.Debug HL2|Win32.Build.0 = Debug HL2|Win32
|
||||||
|
{E44D6502-2BB4-47F8-85CF-ACDD4FC18329}.Release HL2|Win32.ActiveCfg = Release HL2|Win32
|
||||||
|
{E44D6502-2BB4-47F8-85CF-ACDD4FC18329}.Release HL2|Win32.Build.0 = Release HL2|Win32
|
||||||
|
{1AA0213B-2B68-40CD-90F8-CFDFD37C1550}.Debug HL2|Win32.ActiveCfg = Debug HL2|Win32
|
||||||
|
{1AA0213B-2B68-40CD-90F8-CFDFD37C1550}.Debug HL2|Win32.Build.0 = Debug HL2|Win32
|
||||||
|
{1AA0213B-2B68-40CD-90F8-CFDFD37C1550}.Release HL2|Win32.ActiveCfg = Release HL2|Win32
|
||||||
|
{1AA0213B-2B68-40CD-90F8-CFDFD37C1550}.Release HL2|Win32.Build.0 = Release HL2|Win32
|
||||||
|
EndGlobalSection
|
||||||
|
GlobalSection(SolutionProperties) = preSolution
|
||||||
|
HideSolutionNode = FALSE
|
||||||
|
EndGlobalSection
|
||||||
|
EndGlobal
|
29
Game_HL2MP-2003.sln
Normal file
29
Game_HL2MP-2003.sln
Normal file
@ -0,0 +1,29 @@
|
|||||||
|
Microsoft Visual Studio Solution File, Format Version 8.00
|
||||||
|
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "client", "cl_dll\client_hl2mp-2003.vcproj", "{E44D6502-2BB4-47F8-85CF-ACDD4FC18329}"
|
||||||
|
ProjectSection(ProjectDependencies) = postProject
|
||||||
|
EndProjectSection
|
||||||
|
EndProject
|
||||||
|
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "server", "dlls\server_hl2mp-2003.vcproj", "{1AA0213B-2B68-40CD-90F8-CFDFD37C1550}"
|
||||||
|
ProjectSection(ProjectDependencies) = postProject
|
||||||
|
EndProjectSection
|
||||||
|
EndProject
|
||||||
|
Global
|
||||||
|
GlobalSection(SolutionConfiguration) = preSolution
|
||||||
|
Debug HL2MP = Debug HL2MP
|
||||||
|
Release HL2MP = Release HL2MP
|
||||||
|
EndGlobalSection
|
||||||
|
GlobalSection(ProjectConfiguration) = postSolution
|
||||||
|
{E44D6502-2BB4-47F8-85CF-ACDD4FC18329}.Debug HL2MP.ActiveCfg = Debug HL2MP|Win32
|
||||||
|
{E44D6502-2BB4-47F8-85CF-ACDD4FC18329}.Debug HL2MP.Build.0 = Debug HL2MP|Win32
|
||||||
|
{E44D6502-2BB4-47F8-85CF-ACDD4FC18329}.Release HL2MP.ActiveCfg = Release HL2MP|Win32
|
||||||
|
{E44D6502-2BB4-47F8-85CF-ACDD4FC18329}.Release HL2MP.Build.0 = Release HL2MP|Win32
|
||||||
|
{1AA0213B-2B68-40CD-90F8-CFDFD37C1550}.Debug HL2MP.ActiveCfg = Debug HL2MP|Win32
|
||||||
|
{1AA0213B-2B68-40CD-90F8-CFDFD37C1550}.Debug HL2MP.Build.0 = Debug HL2MP|Win32
|
||||||
|
{1AA0213B-2B68-40CD-90F8-CFDFD37C1550}.Release HL2MP.ActiveCfg = Release HL2MP|Win32
|
||||||
|
{1AA0213B-2B68-40CD-90F8-CFDFD37C1550}.Release HL2MP.Build.0 = Release HL2MP|Win32
|
||||||
|
EndGlobalSection
|
||||||
|
GlobalSection(ExtensibilityGlobals) = postSolution
|
||||||
|
EndGlobalSection
|
||||||
|
GlobalSection(ExtensibilityAddIns) = postSolution
|
||||||
|
EndGlobalSection
|
||||||
|
EndGlobal
|
25
Game_HL2MP-2005.sln
Normal file
25
Game_HL2MP-2005.sln
Normal file
@ -0,0 +1,25 @@
|
|||||||
|
Microsoft Visual Studio Solution File, Format Version 9.00
|
||||||
|
# Visual Studio 2005
|
||||||
|
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "client_hl2mp", "cl_dll\client_hl2mp-2005.vcproj", "{E44D6502-2BB4-47F8-85CF-ACDD4FC18329}"
|
||||||
|
EndProject
|
||||||
|
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "server_hl2mp", "dlls\server_hl2mp-2005.vcproj", "{1AA0213B-2B68-40CD-90F8-CFDFD37C1550}"
|
||||||
|
EndProject
|
||||||
|
Global
|
||||||
|
GlobalSection(SolutionConfigurationPlatforms) = preSolution
|
||||||
|
Debug HL2MP|Win32 = Debug HL2MP|Win32
|
||||||
|
Release HL2MP|Win32 = Release HL2MP|Win32
|
||||||
|
EndGlobalSection
|
||||||
|
GlobalSection(ProjectConfigurationPlatforms) = postSolution
|
||||||
|
{E44D6502-2BB4-47F8-85CF-ACDD4FC18329}.Debug HL2MP|Win32.ActiveCfg = Debug HL2MP|Win32
|
||||||
|
{E44D6502-2BB4-47F8-85CF-ACDD4FC18329}.Debug HL2MP|Win32.Build.0 = Debug HL2MP|Win32
|
||||||
|
{E44D6502-2BB4-47F8-85CF-ACDD4FC18329}.Release HL2MP|Win32.ActiveCfg = Release HL2MP|Win32
|
||||||
|
{E44D6502-2BB4-47F8-85CF-ACDD4FC18329}.Release HL2MP|Win32.Build.0 = Release HL2MP|Win32
|
||||||
|
{1AA0213B-2B68-40CD-90F8-CFDFD37C1550}.Debug HL2MP|Win32.ActiveCfg = Debug HL2MP|Win32
|
||||||
|
{1AA0213B-2B68-40CD-90F8-CFDFD37C1550}.Debug HL2MP|Win32.Build.0 = Debug HL2MP|Win32
|
||||||
|
{1AA0213B-2B68-40CD-90F8-CFDFD37C1550}.Release HL2MP|Win32.ActiveCfg = Release HL2MP|Win32
|
||||||
|
{1AA0213B-2B68-40CD-90F8-CFDFD37C1550}.Release HL2MP|Win32.Build.0 = Release HL2MP|Win32
|
||||||
|
EndGlobalSection
|
||||||
|
GlobalSection(SolutionProperties) = preSolution
|
||||||
|
HideSolutionNode = FALSE
|
||||||
|
EndGlobalSection
|
||||||
|
EndGlobal
|
29
Game_Scratch-2003.sln
Normal file
29
Game_Scratch-2003.sln
Normal file
@ -0,0 +1,29 @@
|
|||||||
|
Microsoft Visual Studio Solution File, Format Version 8.00
|
||||||
|
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "client", "cl_dll\client_scratch-2003.vcproj", "{E44D6502-2BB4-47F8-85CF-ACDD4FC18329}"
|
||||||
|
ProjectSection(ProjectDependencies) = postProject
|
||||||
|
EndProjectSection
|
||||||
|
EndProject
|
||||||
|
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "server", "dlls\server_scratch-2003.vcproj", "{1AA0213B-2B68-40CD-90F8-CFDFD37C1550}"
|
||||||
|
ProjectSection(ProjectDependencies) = postProject
|
||||||
|
EndProjectSection
|
||||||
|
EndProject
|
||||||
|
Global
|
||||||
|
GlobalSection(SolutionConfiguration) = preSolution
|
||||||
|
Debug SDK = Debug SDK
|
||||||
|
Release SDK = Release SDK
|
||||||
|
EndGlobalSection
|
||||||
|
GlobalSection(ProjectConfiguration) = postSolution
|
||||||
|
{E44D6502-2BB4-47F8-85CF-ACDD4FC18329}.Debug SDK.ActiveCfg = Debug SDK|Win32
|
||||||
|
{E44D6502-2BB4-47F8-85CF-ACDD4FC18329}.Debug SDK.Build.0 = Debug SDK|Win32
|
||||||
|
{E44D6502-2BB4-47F8-85CF-ACDD4FC18329}.Release SDK.ActiveCfg = Release SDK|Win32
|
||||||
|
{E44D6502-2BB4-47F8-85CF-ACDD4FC18329}.Release SDK.Build.0 = Release SDK|Win32
|
||||||
|
{1AA0213B-2B68-40CD-90F8-CFDFD37C1550}.Debug SDK.ActiveCfg = Debug SDK|Win32
|
||||||
|
{1AA0213B-2B68-40CD-90F8-CFDFD37C1550}.Debug SDK.Build.0 = Debug SDK|Win32
|
||||||
|
{1AA0213B-2B68-40CD-90F8-CFDFD37C1550}.Release SDK.ActiveCfg = Release SDK|Win32
|
||||||
|
{1AA0213B-2B68-40CD-90F8-CFDFD37C1550}.Release SDK.Build.0 = Release SDK|Win32
|
||||||
|
EndGlobalSection
|
||||||
|
GlobalSection(ExtensibilityGlobals) = postSolution
|
||||||
|
EndGlobalSection
|
||||||
|
GlobalSection(ExtensibilityAddIns) = postSolution
|
||||||
|
EndGlobalSection
|
||||||
|
EndGlobal
|
25
Game_Scratch-2005.sln
Normal file
25
Game_Scratch-2005.sln
Normal file
@ -0,0 +1,25 @@
|
|||||||
|
Microsoft Visual Studio Solution File, Format Version 9.00
|
||||||
|
# Visual Studio 2005
|
||||||
|
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "client_sdk", "cl_dll\client_scratch-2005.vcproj", "{E44D6502-2BB4-47F8-85CF-ACDD4FC18329}"
|
||||||
|
EndProject
|
||||||
|
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "server_sdk", "dlls\server_scratch-2005.vcproj", "{1AA0213B-2B68-40CD-90F8-CFDFD37C1550}"
|
||||||
|
EndProject
|
||||||
|
Global
|
||||||
|
GlobalSection(SolutionConfigurationPlatforms) = preSolution
|
||||||
|
Debug SDK|Win32 = Debug SDK|Win32
|
||||||
|
Release SDK|Win32 = Release SDK|Win32
|
||||||
|
EndGlobalSection
|
||||||
|
GlobalSection(ProjectConfigurationPlatforms) = postSolution
|
||||||
|
{E44D6502-2BB4-47F8-85CF-ACDD4FC18329}.Debug SDK|Win32.ActiveCfg = Debug SDK|Win32
|
||||||
|
{E44D6502-2BB4-47F8-85CF-ACDD4FC18329}.Debug SDK|Win32.Build.0 = Debug SDK|Win32
|
||||||
|
{E44D6502-2BB4-47F8-85CF-ACDD4FC18329}.Release SDK|Win32.ActiveCfg = Release SDK|Win32
|
||||||
|
{E44D6502-2BB4-47F8-85CF-ACDD4FC18329}.Release SDK|Win32.Build.0 = Release SDK|Win32
|
||||||
|
{1AA0213B-2B68-40CD-90F8-CFDFD37C1550}.Debug SDK|Win32.ActiveCfg = Debug SDK|Win32
|
||||||
|
{1AA0213B-2B68-40CD-90F8-CFDFD37C1550}.Debug SDK|Win32.Build.0 = Debug SDK|Win32
|
||||||
|
{1AA0213B-2B68-40CD-90F8-CFDFD37C1550}.Release SDK|Win32.ActiveCfg = Release SDK|Win32
|
||||||
|
{1AA0213B-2B68-40CD-90F8-CFDFD37C1550}.Release SDK|Win32.Build.0 = Release SDK|Win32
|
||||||
|
EndGlobalSection
|
||||||
|
GlobalSection(SolutionProperties) = preSolution
|
||||||
|
HideSolutionNode = FALSE
|
||||||
|
EndGlobalSection
|
||||||
|
EndGlobal
|
53
cl_dll/AnimateSpecificTextureProxy.cpp
Normal file
53
cl_dll/AnimateSpecificTextureProxy.cpp
Normal file
@ -0,0 +1,53 @@
|
|||||||
|
//========= Copyright © 1996-2005, Valve Corporation, All rights reserved. ============//
|
||||||
|
//
|
||||||
|
// Purpose: Acts exactly like "AnimatedTexture", but ONLY if the texture
|
||||||
|
// it's working on matches the desired texture to work on.
|
||||||
|
//
|
||||||
|
// This assumes that some other proxy will be switching out the textures.
|
||||||
|
//
|
||||||
|
// $NoKeywords: $
|
||||||
|
//=============================================================================//
|
||||||
|
#include "cbase.h"
|
||||||
|
#include "materialsystem/IMaterialProxy.h"
|
||||||
|
#include "materialsystem/IMaterialVar.h"
|
||||||
|
#include "materialsystem/IMaterial.h"
|
||||||
|
#include "materialsystem/ITexture.h"
|
||||||
|
#include "BaseAnimatedTextureProxy.h"
|
||||||
|
#include "utlstring.h"
|
||||||
|
#include <KeyValues.h>
|
||||||
|
|
||||||
|
// memdbgon must be the last include file in a .cpp file!!!
|
||||||
|
#include "tier0/memdbgon.h"
|
||||||
|
|
||||||
|
class CAnimateSpecificTexture : public CBaseAnimatedTextureProxy
|
||||||
|
{
|
||||||
|
private:
|
||||||
|
CUtlString m_OnlyAnimateOnTexture;
|
||||||
|
public:
|
||||||
|
virtual float GetAnimationStartTime( void* pBaseEntity ) { return 0; }
|
||||||
|
virtual bool Init( IMaterial *pMaterial, KeyValues *pKeyValues );
|
||||||
|
virtual void OnBind( void *pC_BaseEntity );
|
||||||
|
virtual void Release( void ) { delete this; }
|
||||||
|
};
|
||||||
|
|
||||||
|
bool CAnimateSpecificTexture::Init( IMaterial *pMaterial, KeyValues *pKeyValues )
|
||||||
|
{
|
||||||
|
char const* pszAnimateOnTexture = pKeyValues->GetString( "onlyAnimateOnTexture" );
|
||||||
|
if( !pszAnimateOnTexture )
|
||||||
|
return false;
|
||||||
|
|
||||||
|
m_OnlyAnimateOnTexture.Set( pszAnimateOnTexture );
|
||||||
|
|
||||||
|
return CBaseAnimatedTextureProxy::Init( pMaterial, pKeyValues );
|
||||||
|
}
|
||||||
|
|
||||||
|
void CAnimateSpecificTexture::OnBind( void *pC_BaseEntity )
|
||||||
|
{
|
||||||
|
if( FStrEq( m_AnimatedTextureVar->GetTextureValue()->GetName(), m_OnlyAnimateOnTexture ) )
|
||||||
|
{
|
||||||
|
CBaseAnimatedTextureProxy::OnBind( pC_BaseEntity );
|
||||||
|
}
|
||||||
|
//else do nothing
|
||||||
|
}
|
||||||
|
|
||||||
|
EXPOSE_INTERFACE( CAnimateSpecificTexture, IMaterialProxy, "AnimateSpecificTexture" IMATERIAL_PROXY_INTERFACE_VERSION );
|
778
cl_dll/C_MaterialModifyControl.cpp
Normal file
778
cl_dll/C_MaterialModifyControl.cpp
Normal file
@ -0,0 +1,778 @@
|
|||||||
|
//========= Copyright © 1996-2005, Valve Corporation, All rights reserved. ============//
|
||||||
|
//
|
||||||
|
// Purpose: Material Modify control entity.
|
||||||
|
//
|
||||||
|
//=============================================================================//
|
||||||
|
|
||||||
|
#include "cbase.h"
|
||||||
|
#include "ProxyEntity.h"
|
||||||
|
#include "materialsystem/IMaterial.h"
|
||||||
|
#include "materialsystem/IMaterialVar.h"
|
||||||
|
#include "materialsystem/ITexture.h"
|
||||||
|
#include "iviewrender.h"
|
||||||
|
#include "texture_group_names.h"
|
||||||
|
#include "BaseAnimatedTextureProxy.h"
|
||||||
|
|
||||||
|
// memdbgon must be the last include file in a .cpp file!!!
|
||||||
|
#include "tier0/memdbgon.h"
|
||||||
|
|
||||||
|
#define MATERIAL_MODIFY_STRING_SIZE 255
|
||||||
|
#define MATERIAL_MODIFY_ANIMATION_UNSET -1
|
||||||
|
|
||||||
|
// Must match MaterialModifyControl.cpp
|
||||||
|
enum MaterialModifyMode_t
|
||||||
|
{
|
||||||
|
MATERIAL_MODIFY_MODE_NONE = 0,
|
||||||
|
MATERIAL_MODIFY_MODE_SETVAR = 1,
|
||||||
|
MATERIAL_MODIFY_MODE_ANIM_SEQUENCE = 2,
|
||||||
|
MATERIAL_MODIFY_MODE_FLOAT_LERP = 3,
|
||||||
|
};
|
||||||
|
|
||||||
|
ConVar debug_materialmodifycontrol_client( "debug_materialmodifycontrol_client", "0" );
|
||||||
|
|
||||||
|
struct materialanimcommands_t
|
||||||
|
{
|
||||||
|
int iFrameStart;
|
||||||
|
int iFrameEnd;
|
||||||
|
bool bWrap;
|
||||||
|
float flFrameRate;
|
||||||
|
};
|
||||||
|
|
||||||
|
struct materialfloatlerpcommands_t
|
||||||
|
{
|
||||||
|
int flStartValue;
|
||||||
|
int flEndValue;
|
||||||
|
float flTransitionTime;
|
||||||
|
};
|
||||||
|
|
||||||
|
//------------------------------------------------------------------------------
|
||||||
|
// FIXME: This really should inherit from something more lightweight
|
||||||
|
//------------------------------------------------------------------------------
|
||||||
|
|
||||||
|
class C_MaterialModifyControl : public C_BaseEntity
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
|
||||||
|
DECLARE_CLASS( C_MaterialModifyControl, C_BaseEntity );
|
||||||
|
|
||||||
|
C_MaterialModifyControl();
|
||||||
|
|
||||||
|
void OnPreDataChanged( DataUpdateType_t updateType );
|
||||||
|
void OnDataChanged( DataUpdateType_t updateType );
|
||||||
|
bool ShouldDraw();
|
||||||
|
|
||||||
|
IMaterial *GetMaterial( void ) { return m_pMaterial; }
|
||||||
|
const char *GetMaterialVariableName( void ) { return m_szMaterialVar; }
|
||||||
|
const char *GetMaterialVariableValue( void ) { return m_szMaterialVarValue; }
|
||||||
|
|
||||||
|
DECLARE_CLIENTCLASS();
|
||||||
|
|
||||||
|
// Animated texture and Float Lerp usage
|
||||||
|
bool HasNewAnimationCommands( void ) { return m_bHasNewAnimationCommands; }
|
||||||
|
void ClearAnimationCommands( void ) { m_bHasNewAnimationCommands = false; }
|
||||||
|
|
||||||
|
// Animated texture usage
|
||||||
|
void GetAnimationCommands( materialanimcommands_t *pCommands );
|
||||||
|
|
||||||
|
// FloatLerp usage
|
||||||
|
void GetFloatLerpCommands( materialfloatlerpcommands_t *pCommands );
|
||||||
|
|
||||||
|
void SetAnimationStartTime( float flTime )
|
||||||
|
{
|
||||||
|
m_flAnimationStartTime = flTime;
|
||||||
|
}
|
||||||
|
float GetAnimationStartTime( void ) const
|
||||||
|
{
|
||||||
|
return m_flAnimationStartTime;
|
||||||
|
}
|
||||||
|
|
||||||
|
MaterialModifyMode_t GetModifyMode( void ) const
|
||||||
|
{
|
||||||
|
return ( MaterialModifyMode_t)m_nModifyMode;
|
||||||
|
}
|
||||||
|
private:
|
||||||
|
|
||||||
|
char m_szMaterialName[MATERIAL_MODIFY_STRING_SIZE];
|
||||||
|
char m_szMaterialVar[MATERIAL_MODIFY_STRING_SIZE];
|
||||||
|
char m_szMaterialVarValue[MATERIAL_MODIFY_STRING_SIZE];
|
||||||
|
IMaterial *m_pMaterial;
|
||||||
|
|
||||||
|
bool m_bHasNewAnimationCommands;
|
||||||
|
|
||||||
|
// Animation commands from the server
|
||||||
|
int m_iFrameStart;
|
||||||
|
int m_iFrameEnd;
|
||||||
|
bool m_bWrap;
|
||||||
|
float m_flFramerate;
|
||||||
|
bool m_bNewAnimCommandsSemaphore;
|
||||||
|
bool m_bOldAnimCommandsSemaphore;
|
||||||
|
|
||||||
|
// Float lerp commands from the server
|
||||||
|
float m_flFloatLerpStartValue;
|
||||||
|
float m_flFloatLerpEndValue;
|
||||||
|
float m_flFloatLerpTransitionTime;
|
||||||
|
bool m_bFloatLerpWrap;
|
||||||
|
float m_flAnimationStartTime;
|
||||||
|
|
||||||
|
int m_nModifyMode;
|
||||||
|
};
|
||||||
|
|
||||||
|
IMPLEMENT_CLIENTCLASS_DT(C_MaterialModifyControl, DT_MaterialModifyControl, CMaterialModifyControl)
|
||||||
|
RecvPropString( RECVINFO( m_szMaterialName ) ),
|
||||||
|
RecvPropString( RECVINFO( m_szMaterialVar ) ),
|
||||||
|
RecvPropString( RECVINFO( m_szMaterialVarValue ) ),
|
||||||
|
RecvPropInt( RECVINFO(m_iFrameStart) ),
|
||||||
|
RecvPropInt( RECVINFO(m_iFrameEnd) ),
|
||||||
|
RecvPropInt( RECVINFO(m_bWrap) ),
|
||||||
|
RecvPropFloat( RECVINFO(m_flFramerate) ),
|
||||||
|
RecvPropInt( RECVINFO(m_bNewAnimCommandsSemaphore) ),
|
||||||
|
RecvPropFloat( RECVINFO(m_flFloatLerpStartValue) ),
|
||||||
|
RecvPropFloat( RECVINFO(m_flFloatLerpEndValue) ),
|
||||||
|
RecvPropFloat( RECVINFO(m_flFloatLerpTransitionTime) ),
|
||||||
|
RecvPropInt( RECVINFO(m_bFloatLerpWrap) ),
|
||||||
|
RecvPropInt( RECVINFO(m_nModifyMode) ),
|
||||||
|
END_RECV_TABLE()
|
||||||
|
|
||||||
|
//------------------------------------------------------------------------------
|
||||||
|
// Purpose:
|
||||||
|
//------------------------------------------------------------------------------
|
||||||
|
C_MaterialModifyControl::C_MaterialModifyControl()
|
||||||
|
{
|
||||||
|
m_pMaterial = NULL;
|
||||||
|
m_bOldAnimCommandsSemaphore = false;
|
||||||
|
}
|
||||||
|
|
||||||
|
//-----------------------------------------------------------------------------
|
||||||
|
// Purpose:
|
||||||
|
//-----------------------------------------------------------------------------
|
||||||
|
void C_MaterialModifyControl::OnPreDataChanged( DataUpdateType_t updateType )
|
||||||
|
{
|
||||||
|
BaseClass::OnPreDataChanged( updateType );
|
||||||
|
|
||||||
|
m_bOldAnimCommandsSemaphore = m_bNewAnimCommandsSemaphore;
|
||||||
|
}
|
||||||
|
|
||||||
|
//------------------------------------------------------------------------------
|
||||||
|
// Purpose:
|
||||||
|
//------------------------------------------------------------------------------
|
||||||
|
void C_MaterialModifyControl::OnDataChanged( DataUpdateType_t updateType )
|
||||||
|
{
|
||||||
|
if( updateType == DATA_UPDATE_CREATED )
|
||||||
|
{
|
||||||
|
m_pMaterial = materials->FindMaterial( m_szMaterialName, TEXTURE_GROUP_OTHER );
|
||||||
|
|
||||||
|
// Clear out our variables
|
||||||
|
m_bHasNewAnimationCommands = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Detect changes in the anim commands
|
||||||
|
if ( m_bNewAnimCommandsSemaphore != m_bOldAnimCommandsSemaphore )
|
||||||
|
{
|
||||||
|
m_bHasNewAnimationCommands = true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
//-----------------------------------------------------------------------------
|
||||||
|
// Purpose:
|
||||||
|
//-----------------------------------------------------------------------------
|
||||||
|
void C_MaterialModifyControl::GetAnimationCommands( materialanimcommands_t *pCommands )
|
||||||
|
{
|
||||||
|
pCommands->iFrameStart = m_iFrameStart;
|
||||||
|
pCommands->iFrameEnd = m_iFrameEnd;
|
||||||
|
pCommands->bWrap = m_bWrap;
|
||||||
|
pCommands->flFrameRate = m_flFramerate;
|
||||||
|
}
|
||||||
|
|
||||||
|
//-----------------------------------------------------------------------------
|
||||||
|
// Purpose:
|
||||||
|
//-----------------------------------------------------------------------------
|
||||||
|
void C_MaterialModifyControl::GetFloatLerpCommands( materialfloatlerpcommands_t *pCommands )
|
||||||
|
{
|
||||||
|
pCommands->flStartValue = m_flFloatLerpStartValue;
|
||||||
|
pCommands->flEndValue = m_flFloatLerpEndValue;
|
||||||
|
pCommands->flTransitionTime = m_flFloatLerpTransitionTime;
|
||||||
|
}
|
||||||
|
|
||||||
|
//------------------------------------------------------------------------------
|
||||||
|
// Purpose: We don't draw.
|
||||||
|
//------------------------------------------------------------------------------
|
||||||
|
bool C_MaterialModifyControl::ShouldDraw()
|
||||||
|
{
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
//=============================================================================
|
||||||
|
//
|
||||||
|
// THE MATERIALMODIFYPROXY ITSELF
|
||||||
|
//
|
||||||
|
class CMaterialModifyProxy : public CBaseAnimatedTextureProxy
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
CMaterialModifyProxy();
|
||||||
|
virtual ~CMaterialModifyProxy();
|
||||||
|
virtual bool Init( IMaterial *pMaterial, KeyValues *pKeyValues );
|
||||||
|
virtual void OnBind( void *pEntity );
|
||||||
|
|
||||||
|
private:
|
||||||
|
void OnBindSetVar( C_MaterialModifyControl *pControl );
|
||||||
|
void OnBindAnimatedTexture( C_MaterialModifyControl *pControl );
|
||||||
|
void OnBindFloatLerp( C_MaterialModifyControl *pControl );
|
||||||
|
float GetAnimationStartTime( void* pArg );
|
||||||
|
void AnimationWrapped( void* pArg );
|
||||||
|
|
||||||
|
IMaterial *m_pMaterial;
|
||||||
|
|
||||||
|
// texture animation stuff
|
||||||
|
int m_iFrameStart;
|
||||||
|
int m_iFrameEnd;
|
||||||
|
bool m_bReachedEnd;
|
||||||
|
bool m_bCustomWrap;
|
||||||
|
float m_flCustomFramerate;
|
||||||
|
|
||||||
|
// float lerp stuff
|
||||||
|
IMaterialVar *m_pMaterialVar;
|
||||||
|
int m_flStartValue;
|
||||||
|
int m_flEndValue;
|
||||||
|
float m_flStartTime;
|
||||||
|
float m_flTransitionTime;
|
||||||
|
};
|
||||||
|
|
||||||
|
//-----------------------------------------------------------------------------
|
||||||
|
// Purpose:
|
||||||
|
//-----------------------------------------------------------------------------
|
||||||
|
CMaterialModifyProxy::CMaterialModifyProxy()
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
//-----------------------------------------------------------------------------
|
||||||
|
// Purpose:
|
||||||
|
//-----------------------------------------------------------------------------
|
||||||
|
CMaterialModifyProxy::~CMaterialModifyProxy()
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
bool CMaterialModifyProxy::Init( IMaterial *pMaterial, KeyValues *pKeyValues )
|
||||||
|
{
|
||||||
|
// set var stuff
|
||||||
|
m_pMaterial = pMaterial;
|
||||||
|
|
||||||
|
// float lerp stuff
|
||||||
|
m_flStartValue = MATERIAL_MODIFY_ANIMATION_UNSET;
|
||||||
|
m_flEndValue = MATERIAL_MODIFY_ANIMATION_UNSET;
|
||||||
|
|
||||||
|
// animated stuff
|
||||||
|
// m_pMaterial = pMaterial;
|
||||||
|
// m_iFrameStart = MATERIAL_MODIFY_ANIMATION_UNSET;
|
||||||
|
// m_iFrameEnd = MATERIAL_MODIFY_ANIMATION_UNSET;
|
||||||
|
// m_bReachedEnd = false;
|
||||||
|
// return CBaseAnimatedTextureProxy::Init( pMaterial, pKeyValues );
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
void CMaterialModifyProxy::OnBind( void *pEntity )
|
||||||
|
{
|
||||||
|
// Get the modified material vars from the entity input
|
||||||
|
IClientRenderable *pRend = (IClientRenderable *)pEntity;
|
||||||
|
if ( pRend )
|
||||||
|
{
|
||||||
|
C_BaseEntity *pBaseEntity = pRend->GetIClientUnknown()->GetBaseEntity();
|
||||||
|
|
||||||
|
if ( pBaseEntity )
|
||||||
|
{
|
||||||
|
if( debug_materialmodifycontrol_client.GetBool() )
|
||||||
|
{
|
||||||
|
// DevMsg( 1, "%s\n", pBaseEntity->GetDebugName() );
|
||||||
|
}
|
||||||
|
int numChildren = 0;
|
||||||
|
bool gotOne = false;
|
||||||
|
for ( C_BaseEntity *pChild = pBaseEntity->FirstMoveChild(); pChild; pChild = pChild->NextMovePeer() )
|
||||||
|
{
|
||||||
|
numChildren++;
|
||||||
|
C_MaterialModifyControl *pControl = dynamic_cast<C_MaterialModifyControl*>( pChild );
|
||||||
|
if ( !pControl )
|
||||||
|
continue;
|
||||||
|
|
||||||
|
if( debug_materialmodifycontrol_client.GetBool() )
|
||||||
|
{
|
||||||
|
// DevMsg( 1, "pControl: 0x%p\n", pControl );
|
||||||
|
}
|
||||||
|
|
||||||
|
switch( pControl->GetModifyMode() )
|
||||||
|
{
|
||||||
|
case MATERIAL_MODIFY_MODE_NONE:
|
||||||
|
break;
|
||||||
|
case MATERIAL_MODIFY_MODE_SETVAR:
|
||||||
|
gotOne = true;
|
||||||
|
OnBindSetVar( pControl );
|
||||||
|
break;
|
||||||
|
case MATERIAL_MODIFY_MODE_ANIM_SEQUENCE:
|
||||||
|
OnBindAnimatedTexture( pControl );
|
||||||
|
break;
|
||||||
|
case MATERIAL_MODIFY_MODE_FLOAT_LERP:
|
||||||
|
OnBindFloatLerp( pControl );
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
Assert( 0 );
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if( gotOne )
|
||||||
|
{
|
||||||
|
// DevMsg( 1, "numChildren: %d\n", numChildren );
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
//-----------------------------------------------------------------------------
|
||||||
|
// Purpose:
|
||||||
|
//-----------------------------------------------------------------------------
|
||||||
|
void CMaterialModifyProxy::OnBindSetVar( C_MaterialModifyControl *pControl )
|
||||||
|
{
|
||||||
|
IMaterial *pMaterial = pControl->GetMaterial();
|
||||||
|
if( !pMaterial )
|
||||||
|
{
|
||||||
|
Assert( 0 );
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if ( pMaterial != m_pMaterial )
|
||||||
|
{
|
||||||
|
// Warning( "\t%s!=%s\n", pMaterial->GetName(), m_pMaterial->GetName() );
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool bFound;
|
||||||
|
IMaterialVar *pMaterialVar = pMaterial->FindVar( pControl->GetMaterialVariableName(), &bFound, false );
|
||||||
|
if ( !bFound )
|
||||||
|
return;
|
||||||
|
|
||||||
|
if( Q_strcmp( pControl->GetMaterialVariableValue(), "" ) )
|
||||||
|
{
|
||||||
|
// const char *pMaterialName = m_pMaterial->GetName();
|
||||||
|
// const char *pMaterialVarName = pMaterialVar->GetName();
|
||||||
|
// const char *pMaterialVarValue = pControl->GetMaterialVariableValue();
|
||||||
|
// if( debug_materialmodifycontrol_client.GetBool()
|
||||||
|
// && Q_stristr( m_pMaterial->GetName(), "faceandhair" )
|
||||||
|
// && Q_stristr( pMaterialVar->GetName(), "self" )
|
||||||
|
// )
|
||||||
|
// {
|
||||||
|
// static int count = 0;
|
||||||
|
// DevMsg( 1, "CMaterialModifyProxy::OnBindSetVar \"%s\" %s=%s %d pControl=0x%p\n",
|
||||||
|
// m_pMaterial->GetName(), pMaterialVar->GetName(), pControl->GetMaterialVariableValue(), count++, pControl );
|
||||||
|
// }
|
||||||
|
pMaterialVar->SetValueAutodetectType( pControl->GetMaterialVariableValue() );
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
//-----------------------------------------------------------------------------
|
||||||
|
// Does the dirty deed
|
||||||
|
//-----------------------------------------------------------------------------
|
||||||
|
void CMaterialModifyProxy::OnBindAnimatedTexture( C_MaterialModifyControl *pControl )
|
||||||
|
{
|
||||||
|
assert ( m_AnimatedTextureVar );
|
||||||
|
if( m_AnimatedTextureVar->GetType() != MATERIAL_VAR_TYPE_TEXTURE )
|
||||||
|
return;
|
||||||
|
|
||||||
|
ITexture *pTexture;
|
||||||
|
pTexture = m_AnimatedTextureVar->GetTextureValue();
|
||||||
|
|
||||||
|
if ( !pControl )
|
||||||
|
return;
|
||||||
|
|
||||||
|
if ( pControl->HasNewAnimationCommands() )
|
||||||
|
{
|
||||||
|
// Read the data from the modify entity
|
||||||
|
materialanimcommands_t sCommands;
|
||||||
|
pControl->GetAnimationCommands( &sCommands );
|
||||||
|
|
||||||
|
m_iFrameStart = sCommands.iFrameStart;
|
||||||
|
m_iFrameEnd = sCommands.iFrameEnd;
|
||||||
|
m_bCustomWrap = sCommands.bWrap;
|
||||||
|
m_flCustomFramerate = sCommands.flFrameRate;
|
||||||
|
m_bReachedEnd = false;
|
||||||
|
|
||||||
|
m_flStartTime = gpGlobals->curtime;
|
||||||
|
|
||||||
|
pControl->ClearAnimationCommands();
|
||||||
|
}
|
||||||
|
|
||||||
|
// Init all the vars based on whether we're using the base material settings,
|
||||||
|
// or the custom ones from the entity input.
|
||||||
|
int numFrames;
|
||||||
|
bool bWrapAnimation;
|
||||||
|
float flFrameRate;
|
||||||
|
int iLastFrame;
|
||||||
|
|
||||||
|
// Do we have a custom frame section from the server?
|
||||||
|
if ( m_iFrameStart != MATERIAL_MODIFY_ANIMATION_UNSET )
|
||||||
|
{
|
||||||
|
if ( m_iFrameEnd == MATERIAL_MODIFY_ANIMATION_UNSET )
|
||||||
|
{
|
||||||
|
m_iFrameEnd = pTexture->GetNumAnimationFrames();
|
||||||
|
}
|
||||||
|
|
||||||
|
numFrames = (m_iFrameEnd - m_iFrameStart) + 1;
|
||||||
|
bWrapAnimation = m_bCustomWrap;
|
||||||
|
flFrameRate = m_flCustomFramerate;
|
||||||
|
iLastFrame = (m_iFrameEnd - 1);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
numFrames = pTexture->GetNumAnimationFrames();
|
||||||
|
bWrapAnimation = m_WrapAnimation;
|
||||||
|
flFrameRate = m_FrameRate;
|
||||||
|
iLastFrame = (numFrames - 1);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Have we already reached the end? If so, stay there.
|
||||||
|
if ( m_bReachedEnd && !bWrapAnimation )
|
||||||
|
{
|
||||||
|
m_AnimatedTextureFrameNumVar->SetIntValue( iLastFrame );
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
// NOTE: Must not use relative time based methods here
|
||||||
|
// because the bind proxy can be called many times per frame.
|
||||||
|
// Prevent multiple Wrap callbacks to be sent for no wrap mode
|
||||||
|
float startTime;
|
||||||
|
if ( m_iFrameStart != MATERIAL_MODIFY_ANIMATION_UNSET )
|
||||||
|
{
|
||||||
|
startTime = m_flStartTime;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
startTime = GetAnimationStartTime(pControl);
|
||||||
|
}
|
||||||
|
float deltaTime = gpGlobals->curtime - startTime;
|
||||||
|
float prevTime = deltaTime - gpGlobals->frametime;
|
||||||
|
|
||||||
|
// Clamp..
|
||||||
|
if (deltaTime < 0.0f)
|
||||||
|
deltaTime = 0.0f;
|
||||||
|
if (prevTime < 0.0f)
|
||||||
|
prevTime = 0.0f;
|
||||||
|
|
||||||
|
float frame = flFrameRate * deltaTime;
|
||||||
|
float prevFrame = flFrameRate * prevTime;
|
||||||
|
|
||||||
|
int intFrame = ((int)frame) % numFrames;
|
||||||
|
int intPrevFrame = ((int)prevFrame) % numFrames;
|
||||||
|
|
||||||
|
if ( m_iFrameStart != MATERIAL_MODIFY_ANIMATION_UNSET )
|
||||||
|
{
|
||||||
|
intFrame += m_iFrameStart;
|
||||||
|
intPrevFrame += m_iFrameStart;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Report wrap situation...
|
||||||
|
if (intPrevFrame > intFrame)
|
||||||
|
{
|
||||||
|
m_bReachedEnd = true;
|
||||||
|
|
||||||
|
if (bWrapAnimation)
|
||||||
|
{
|
||||||
|
AnimationWrapped( pControl );
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
// Only sent the wrapped message once.
|
||||||
|
// when we're in non-wrapping mode
|
||||||
|
if (prevFrame < numFrames)
|
||||||
|
AnimationWrapped( pControl );
|
||||||
|
intFrame = numFrames - 1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
m_AnimatedTextureFrameNumVar->SetIntValue( intFrame );
|
||||||
|
}
|
||||||
|
|
||||||
|
//-----------------------------------------------------------------------------
|
||||||
|
// Purpose:
|
||||||
|
//-----------------------------------------------------------------------------
|
||||||
|
float CMaterialModifyProxy::GetAnimationStartTime( void* pArg )
|
||||||
|
{
|
||||||
|
IClientRenderable *pRend = (IClientRenderable *)pArg;
|
||||||
|
if (!pRend)
|
||||||
|
return 0.0f;
|
||||||
|
|
||||||
|
C_BaseEntity* pEntity = pRend->GetIClientUnknown()->GetBaseEntity();
|
||||||
|
if (pEntity)
|
||||||
|
{
|
||||||
|
return pEntity->GetTextureAnimationStartTime();
|
||||||
|
}
|
||||||
|
return 0.0f;
|
||||||
|
}
|
||||||
|
|
||||||
|
//-----------------------------------------------------------------------------
|
||||||
|
// Purpose:
|
||||||
|
//-----------------------------------------------------------------------------
|
||||||
|
void CMaterialModifyProxy::AnimationWrapped( void* pArg )
|
||||||
|
{
|
||||||
|
IClientRenderable *pRend = (IClientRenderable *)pArg;
|
||||||
|
if (!pRend)
|
||||||
|
return;
|
||||||
|
|
||||||
|
C_BaseEntity* pEntity = pRend->GetIClientUnknown()->GetBaseEntity();
|
||||||
|
if (pEntity)
|
||||||
|
{
|
||||||
|
pEntity->TextureAnimationWrapped();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
//-----------------------------------------------------------------------------
|
||||||
|
// Does the dirty deed
|
||||||
|
//-----------------------------------------------------------------------------
|
||||||
|
void CMaterialModifyProxy::OnBindFloatLerp( C_MaterialModifyControl *pControl )
|
||||||
|
{
|
||||||
|
if ( !pControl )
|
||||||
|
return;
|
||||||
|
|
||||||
|
if ( pControl->HasNewAnimationCommands() )
|
||||||
|
{
|
||||||
|
pControl->SetAnimationStartTime( gpGlobals->curtime );
|
||||||
|
pControl->ClearAnimationCommands();
|
||||||
|
}
|
||||||
|
|
||||||
|
// Read the data from the modify entity
|
||||||
|
materialfloatlerpcommands_t sCommands;
|
||||||
|
pControl->GetFloatLerpCommands( &sCommands );
|
||||||
|
|
||||||
|
m_flStartValue = sCommands.flStartValue;
|
||||||
|
m_flEndValue = sCommands.flEndValue;
|
||||||
|
m_flTransitionTime = sCommands.flTransitionTime;
|
||||||
|
m_flStartTime = pControl->GetAnimationStartTime();
|
||||||
|
bool bFound;
|
||||||
|
m_pMaterialVar = m_pMaterial->FindVar( pControl->GetMaterialVariableName(), &bFound, false );
|
||||||
|
|
||||||
|
if( bFound )
|
||||||
|
{
|
||||||
|
float currentValue;
|
||||||
|
if( m_flTransitionTime > 0.0f )
|
||||||
|
{
|
||||||
|
currentValue = m_flStartValue + ( m_flEndValue - m_flStartValue ) * clamp( ( ( gpGlobals->curtime - m_flStartTime ) / m_flTransitionTime ), 0.0f, 1.0f );
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
currentValue = m_flEndValue;
|
||||||
|
}
|
||||||
|
|
||||||
|
if( debug_materialmodifycontrol_client.GetBool() && Q_stristr( m_pMaterial->GetName(), "faceandhair" ) && Q_stristr( m_pMaterialVar->GetName(), "warp" ) )
|
||||||
|
{
|
||||||
|
static int count = 0;
|
||||||
|
DevMsg( 1, "CMaterialFloatLerpProxy::OnBind \"%s\" %s=%f %d\n", m_pMaterial->GetName(), m_pMaterialVar->GetName(), currentValue, count++ );
|
||||||
|
}
|
||||||
|
m_pMaterialVar->SetFloatValue( currentValue );
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
//=============================================================================
|
||||||
|
//
|
||||||
|
// MATERIALMODIFYANIMATED PROXY
|
||||||
|
//
|
||||||
|
class CMaterialModifyAnimatedProxy : public CBaseAnimatedTextureProxy
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
CMaterialModifyAnimatedProxy() {};
|
||||||
|
virtual ~CMaterialModifyAnimatedProxy() {};
|
||||||
|
virtual bool Init( IMaterial *pMaterial, KeyValues *pKeyValues );
|
||||||
|
virtual void OnBind( void *pEntity );
|
||||||
|
|
||||||
|
virtual float GetAnimationStartTime( void* pBaseEntity );
|
||||||
|
virtual void AnimationWrapped( void* pC_BaseEntity );
|
||||||
|
|
||||||
|
private:
|
||||||
|
IMaterial *m_pMaterial;
|
||||||
|
int m_iFrameStart;
|
||||||
|
int m_iFrameEnd;
|
||||||
|
bool m_bReachedEnd;
|
||||||
|
float m_flStartTime;
|
||||||
|
bool m_bCustomWrap;
|
||||||
|
float m_flCustomFramerate;
|
||||||
|
};
|
||||||
|
|
||||||
|
//-----------------------------------------------------------------------------
|
||||||
|
// Purpose:
|
||||||
|
//-----------------------------------------------------------------------------
|
||||||
|
bool CMaterialModifyAnimatedProxy::Init( IMaterial *pMaterial, KeyValues *pKeyValues )
|
||||||
|
{
|
||||||
|
m_pMaterial = pMaterial;
|
||||||
|
m_iFrameStart = MATERIAL_MODIFY_ANIMATION_UNSET;
|
||||||
|
m_iFrameEnd = MATERIAL_MODIFY_ANIMATION_UNSET;
|
||||||
|
m_bReachedEnd = false;
|
||||||
|
return CBaseAnimatedTextureProxy::Init( pMaterial, pKeyValues );
|
||||||
|
}
|
||||||
|
|
||||||
|
//-----------------------------------------------------------------------------
|
||||||
|
// Does the dirty deed
|
||||||
|
//-----------------------------------------------------------------------------
|
||||||
|
void CMaterialModifyAnimatedProxy::OnBind( void *pEntity )
|
||||||
|
{
|
||||||
|
assert ( m_AnimatedTextureVar );
|
||||||
|
if( m_AnimatedTextureVar->GetType() != MATERIAL_VAR_TYPE_TEXTURE )
|
||||||
|
return;
|
||||||
|
|
||||||
|
ITexture *pTexture;
|
||||||
|
pTexture = m_AnimatedTextureVar->GetTextureValue();
|
||||||
|
|
||||||
|
// Get the modified material vars from the entity input
|
||||||
|
IClientRenderable *pRend = (IClientRenderable *)pEntity;
|
||||||
|
if ( pRend )
|
||||||
|
{
|
||||||
|
C_BaseEntity *pBaseEntity = pRend->GetIClientUnknown()->GetBaseEntity();
|
||||||
|
if ( pBaseEntity )
|
||||||
|
{
|
||||||
|
for ( C_BaseEntity *pChild = pBaseEntity->FirstMoveChild(); pChild; pChild = pChild->NextMovePeer() )
|
||||||
|
{
|
||||||
|
C_MaterialModifyControl *pControl = dynamic_cast<C_MaterialModifyControl*>( pChild );
|
||||||
|
if ( !pControl )
|
||||||
|
continue;
|
||||||
|
|
||||||
|
if ( !pControl->HasNewAnimationCommands() )
|
||||||
|
continue;
|
||||||
|
|
||||||
|
// Read the data from the modify entity
|
||||||
|
materialanimcommands_t sCommands;
|
||||||
|
pControl->GetAnimationCommands( &sCommands );
|
||||||
|
|
||||||
|
m_iFrameStart = sCommands.iFrameStart;
|
||||||
|
m_iFrameEnd = sCommands.iFrameEnd;
|
||||||
|
m_bCustomWrap = sCommands.bWrap;
|
||||||
|
m_flCustomFramerate = sCommands.flFrameRate;
|
||||||
|
m_bReachedEnd = false;
|
||||||
|
|
||||||
|
m_flStartTime = gpGlobals->curtime;
|
||||||
|
|
||||||
|
pControl->ClearAnimationCommands();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Init all the vars based on whether we're using the base material settings,
|
||||||
|
// or the custom ones from the entity input.
|
||||||
|
int numFrames;
|
||||||
|
bool bWrapAnimation;
|
||||||
|
float flFrameRate;
|
||||||
|
int iLastFrame;
|
||||||
|
|
||||||
|
// Do we have a custom frame section from the server?
|
||||||
|
if ( m_iFrameStart != MATERIAL_MODIFY_ANIMATION_UNSET )
|
||||||
|
{
|
||||||
|
if ( m_iFrameEnd == MATERIAL_MODIFY_ANIMATION_UNSET )
|
||||||
|
{
|
||||||
|
m_iFrameEnd = pTexture->GetNumAnimationFrames();
|
||||||
|
}
|
||||||
|
|
||||||
|
numFrames = (m_iFrameEnd - m_iFrameStart) + 1;
|
||||||
|
bWrapAnimation = m_bCustomWrap;
|
||||||
|
flFrameRate = m_flCustomFramerate;
|
||||||
|
iLastFrame = (m_iFrameEnd - 1);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
numFrames = pTexture->GetNumAnimationFrames();
|
||||||
|
bWrapAnimation = m_WrapAnimation;
|
||||||
|
flFrameRate = m_FrameRate;
|
||||||
|
iLastFrame = (numFrames - 1);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Have we already reached the end? If so, stay there.
|
||||||
|
if ( m_bReachedEnd && !bWrapAnimation )
|
||||||
|
{
|
||||||
|
m_AnimatedTextureFrameNumVar->SetIntValue( iLastFrame );
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
// NOTE: Must not use relative time based methods here
|
||||||
|
// because the bind proxy can be called many times per frame.
|
||||||
|
// Prevent multiple Wrap callbacks to be sent for no wrap mode
|
||||||
|
float startTime;
|
||||||
|
if ( m_iFrameStart != MATERIAL_MODIFY_ANIMATION_UNSET )
|
||||||
|
{
|
||||||
|
startTime = m_flStartTime;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
startTime = GetAnimationStartTime(pEntity);
|
||||||
|
}
|
||||||
|
float deltaTime = gpGlobals->curtime - startTime;
|
||||||
|
float prevTime = deltaTime - gpGlobals->frametime;
|
||||||
|
|
||||||
|
// Clamp..
|
||||||
|
if (deltaTime < 0.0f)
|
||||||
|
deltaTime = 0.0f;
|
||||||
|
if (prevTime < 0.0f)
|
||||||
|
prevTime = 0.0f;
|
||||||
|
|
||||||
|
float frame = flFrameRate * deltaTime;
|
||||||
|
float prevFrame = flFrameRate * prevTime;
|
||||||
|
|
||||||
|
int intFrame = ((int)frame) % numFrames;
|
||||||
|
int intPrevFrame = ((int)prevFrame) % numFrames;
|
||||||
|
|
||||||
|
if ( m_iFrameStart != MATERIAL_MODIFY_ANIMATION_UNSET )
|
||||||
|
{
|
||||||
|
intFrame += m_iFrameStart;
|
||||||
|
intPrevFrame += m_iFrameStart;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Report wrap situation...
|
||||||
|
if (intPrevFrame > intFrame)
|
||||||
|
{
|
||||||
|
m_bReachedEnd = true;
|
||||||
|
|
||||||
|
if (bWrapAnimation)
|
||||||
|
{
|
||||||
|
AnimationWrapped( pEntity );
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
// Only sent the wrapped message once.
|
||||||
|
// when we're in non-wrapping mode
|
||||||
|
if (prevFrame < numFrames)
|
||||||
|
AnimationWrapped( pEntity );
|
||||||
|
intFrame = numFrames - 1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
m_AnimatedTextureFrameNumVar->SetIntValue( intFrame );
|
||||||
|
}
|
||||||
|
|
||||||
|
//-----------------------------------------------------------------------------
|
||||||
|
// Purpose:
|
||||||
|
//-----------------------------------------------------------------------------
|
||||||
|
float CMaterialModifyAnimatedProxy::GetAnimationStartTime( void* pArg )
|
||||||
|
{
|
||||||
|
IClientRenderable *pRend = (IClientRenderable *)pArg;
|
||||||
|
if (!pRend)
|
||||||
|
return 0.0f;
|
||||||
|
|
||||||
|
C_BaseEntity* pEntity = pRend->GetIClientUnknown()->GetBaseEntity();
|
||||||
|
if (pEntity)
|
||||||
|
{
|
||||||
|
return pEntity->GetTextureAnimationStartTime();
|
||||||
|
}
|
||||||
|
return 0.0f;
|
||||||
|
}
|
||||||
|
|
||||||
|
//-----------------------------------------------------------------------------
|
||||||
|
// Purpose:
|
||||||
|
//-----------------------------------------------------------------------------
|
||||||
|
void CMaterialModifyAnimatedProxy::AnimationWrapped( void* pArg )
|
||||||
|
{
|
||||||
|
IClientRenderable *pRend = (IClientRenderable *)pArg;
|
||||||
|
if (!pRend)
|
||||||
|
return;
|
||||||
|
|
||||||
|
C_BaseEntity* pEntity = pRend->GetIClientUnknown()->GetBaseEntity();
|
||||||
|
if (pEntity)
|
||||||
|
{
|
||||||
|
pEntity->TextureAnimationWrapped();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
EXPOSE_INTERFACE( CMaterialModifyProxy, IMaterialProxy, "MaterialModify" IMATERIAL_PROXY_INTERFACE_VERSION );
|
||||||
|
EXPOSE_INTERFACE( CMaterialModifyAnimatedProxy, IMaterialProxy, "MaterialModifyAnimated" IMATERIAL_PROXY_INTERFACE_VERSION );
|
231
cl_dll/EffectsClient.cpp
Normal file
231
cl_dll/EffectsClient.cpp
Normal file
@ -0,0 +1,231 @@
|
|||||||
|
//========= Copyright © 1996-2005, Valve Corporation, All rights reserved. ============//
|
||||||
|
//
|
||||||
|
// Purpose: Utility code.
|
||||||
|
//
|
||||||
|
// $NoKeywords: $
|
||||||
|
//=============================================================================//
|
||||||
|
#include "cbase.h"
|
||||||
|
#include "IEffects.h"
|
||||||
|
#include "fx.h"
|
||||||
|
#include "c_te_legacytempents.h"
|
||||||
|
|
||||||
|
// memdbgon must be the last include file in a .cpp file!!!
|
||||||
|
#include "tier0/memdbgon.h"
|
||||||
|
|
||||||
|
//-----------------------------------------------------------------------------
|
||||||
|
// Client-server neutral effects interface
|
||||||
|
//-----------------------------------------------------------------------------
|
||||||
|
class CEffectsClient : public IEffects
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
CEffectsClient();
|
||||||
|
virtual ~CEffectsClient();
|
||||||
|
|
||||||
|
// Members of the IEffect interface
|
||||||
|
virtual void Beam( const Vector &Start, const Vector &End, int nModelIndex,
|
||||||
|
int nHaloIndex, unsigned char frameStart, unsigned char frameRate,
|
||||||
|
float flLife, unsigned char width, unsigned char endWidth, unsigned char fadeLength,
|
||||||
|
unsigned char noise, unsigned char red, unsigned char green,
|
||||||
|
unsigned char blue, unsigned char brightness, unsigned char speed);
|
||||||
|
virtual void Smoke( const Vector &origin, int modelIndex, float scale, float framerate );
|
||||||
|
virtual void Sparks( const Vector &position, int nMagnitude = 1, int nTrailLength = 1, const Vector *pvecDir = NULL );
|
||||||
|
virtual void Dust( const Vector &pos, const Vector &dir, float size, float speed );
|
||||||
|
virtual void MuzzleFlash( const Vector &origin, const QAngle &angles, float fScale, int type );
|
||||||
|
virtual void MetalSparks( const Vector &position, const Vector &direction );
|
||||||
|
virtual void EnergySplash( const Vector &position, const Vector &direction, bool bExplosive = false );
|
||||||
|
virtual void Ricochet( const Vector &position, const Vector &direction );
|
||||||
|
|
||||||
|
// FIXME: Should these methods remain in this interface? Or go in some
|
||||||
|
// other client-server neutral interface?
|
||||||
|
virtual float Time();
|
||||||
|
virtual bool IsServer();
|
||||||
|
virtual void SuppressEffectsSounds( bool bSuppress );
|
||||||
|
|
||||||
|
private:
|
||||||
|
//-----------------------------------------------------------------------------
|
||||||
|
// Purpose: Returning true means don't even call TE func
|
||||||
|
// Input : filter -
|
||||||
|
// *suppress_host -
|
||||||
|
// Output : static bool
|
||||||
|
//-----------------------------------------------------------------------------
|
||||||
|
bool SuppressTE( C_RecipientFilter& filter )
|
||||||
|
{
|
||||||
|
if ( !CanPredict() )
|
||||||
|
return true;
|
||||||
|
|
||||||
|
if ( !filter.GetRecipientCount() )
|
||||||
|
{
|
||||||
|
// Suppress it
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
// There's at least one recipient
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool m_bSuppressSound;
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
//-----------------------------------------------------------------------------
|
||||||
|
// Client-server neutral effects interface accessor
|
||||||
|
//-----------------------------------------------------------------------------
|
||||||
|
static CEffectsClient s_EffectClient;
|
||||||
|
EXPOSE_SINGLE_INTERFACE_GLOBALVAR(CEffectsClient, IEffects, IEFFECTS_INTERFACE_VERSION, s_EffectClient);
|
||||||
|
IEffects *g_pEffects = &s_EffectClient;
|
||||||
|
|
||||||
|
ConVar r_decals("r_decals","0");
|
||||||
|
|
||||||
|
//-----------------------------------------------------------------------------
|
||||||
|
// constructor, destructor
|
||||||
|
//-----------------------------------------------------------------------------
|
||||||
|
CEffectsClient::CEffectsClient()
|
||||||
|
{
|
||||||
|
m_bSuppressSound = false;
|
||||||
|
}
|
||||||
|
|
||||||
|
CEffectsClient::~CEffectsClient()
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
//-----------------------------------------------------------------------------
|
||||||
|
// Suppress sound on effects
|
||||||
|
//-----------------------------------------------------------------------------
|
||||||
|
void CEffectsClient::SuppressEffectsSounds( bool bSuppress )
|
||||||
|
{
|
||||||
|
m_bSuppressSound = bSuppress;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
//-----------------------------------------------------------------------------
|
||||||
|
// Generates a beam
|
||||||
|
//-----------------------------------------------------------------------------
|
||||||
|
void CEffectsClient::Beam( const Vector &vecStartPoint, const Vector &vecEndPoint,
|
||||||
|
int nModelIndex, int nHaloIndex, unsigned char frameStart, unsigned char nFrameRate,
|
||||||
|
float flLife, unsigned char nWidth, unsigned char nEndWidth, unsigned char nFadeLength,
|
||||||
|
unsigned char noise, unsigned char r, unsigned char g,
|
||||||
|
unsigned char b, unsigned char brightness, unsigned char nSpeed)
|
||||||
|
{
|
||||||
|
Assert(0);
|
||||||
|
// CBroadcastRecipientFilter filter;
|
||||||
|
// if ( !SuppressTE( filter ) )
|
||||||
|
// {
|
||||||
|
// beams->CreateBeamPoints( vecStartPoint, vecEndPoint, nModelIndex, nHaloIndex,
|
||||||
|
// m_fHaloScale,
|
||||||
|
// flLife, 0.1 * nWidth, 0.1 * nEndWidth, nFadeLength, 0.01 * nAmplitude, a, 0.1 * nSpeed,
|
||||||
|
// m_nStartFrame, 0.1 * nFrameRate, r, g, b );
|
||||||
|
// }
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
//-----------------------------------------------------------------------------
|
||||||
|
// Generates various tempent effects
|
||||||
|
//-----------------------------------------------------------------------------
|
||||||
|
void CEffectsClient::Smoke( const Vector &vecOrigin, int modelIndex, float scale, float framerate )
|
||||||
|
{
|
||||||
|
CPVSFilter filter( vecOrigin );
|
||||||
|
if ( !SuppressTE( filter ) )
|
||||||
|
{
|
||||||
|
int iColor = random->RandomInt(20,35);
|
||||||
|
color32 color;
|
||||||
|
color.r = iColor;
|
||||||
|
color.g = iColor;
|
||||||
|
color.b = iColor;
|
||||||
|
color.a = iColor;
|
||||||
|
QAngle angles;
|
||||||
|
VectorAngles( Vector(0,0,1), angles );
|
||||||
|
FX_Smoke( vecOrigin, angles, scale * 0.1f, 4, (unsigned char *)&color, 255 );
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void CEffectsClient::Sparks( const Vector &position, int nMagnitude, int nTrailLength, const Vector *pVecDir )
|
||||||
|
{
|
||||||
|
CPVSFilter filter( position );
|
||||||
|
if ( !SuppressTE( filter ) )
|
||||||
|
{
|
||||||
|
FX_ElectricSpark( position, nMagnitude, nTrailLength, pVecDir );
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void CEffectsClient::Dust( const Vector &pos, const Vector &dir, float size, float speed )
|
||||||
|
{
|
||||||
|
CPVSFilter filter( pos );
|
||||||
|
if ( !SuppressTE( filter ) )
|
||||||
|
{
|
||||||
|
FX_Dust( pos, dir, size, speed );
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void CEffectsClient::MuzzleFlash( const Vector &vecOrigin, const QAngle &vecAngles, float flScale, int iType )
|
||||||
|
{
|
||||||
|
CPVSFilter filter( vecOrigin );
|
||||||
|
if ( !SuppressTE( filter ) )
|
||||||
|
{
|
||||||
|
switch( iType )
|
||||||
|
{
|
||||||
|
case MUZZLEFLASH_TYPE_DEFAULT:
|
||||||
|
FX_MuzzleEffect( vecOrigin, vecAngles, flScale, INVALID_EHANDLE_INDEX );
|
||||||
|
break;
|
||||||
|
|
||||||
|
case MUZZLEFLASH_TYPE_GUNSHIP:
|
||||||
|
FX_GunshipMuzzleEffect( vecOrigin, vecAngles, flScale, INVALID_EHANDLE_INDEX );
|
||||||
|
break;
|
||||||
|
|
||||||
|
case MUZZLEFLASH_TYPE_STRIDER:
|
||||||
|
FX_StriderMuzzleEffect( vecOrigin, vecAngles, flScale, INVALID_EHANDLE_INDEX );
|
||||||
|
break;
|
||||||
|
|
||||||
|
default:
|
||||||
|
Msg("No case for Muzzleflash type: %d\n", iType );
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void CEffectsClient::MetalSparks( const Vector &position, const Vector &direction )
|
||||||
|
{
|
||||||
|
CPVSFilter filter( position );
|
||||||
|
if ( !SuppressTE( filter ) )
|
||||||
|
{
|
||||||
|
FX_MetalSpark( position, direction, direction );
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void CEffectsClient::EnergySplash( const Vector &position, const Vector &direction, bool bExplosive )
|
||||||
|
{
|
||||||
|
CPVSFilter filter( position );
|
||||||
|
if ( !SuppressTE( filter ) )
|
||||||
|
{
|
||||||
|
FX_EnergySplash( position, direction, bExplosive );
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void CEffectsClient::Ricochet( const Vector &position, const Vector &direction )
|
||||||
|
{
|
||||||
|
CPVSFilter filter( position );
|
||||||
|
if ( !SuppressTE( filter ) )
|
||||||
|
{
|
||||||
|
FX_MetalSpark( position, direction, direction );
|
||||||
|
|
||||||
|
if ( !m_bSuppressSound )
|
||||||
|
{
|
||||||
|
FX_RicochetSound( position );
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// FIXME: Should these methods remain in this interface? Or go in some
|
||||||
|
// other client-server neutral interface?
|
||||||
|
float CEffectsClient::Time()
|
||||||
|
{
|
||||||
|
return gpGlobals->curtime;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
bool CEffectsClient::IsServer()
|
||||||
|
{
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
60
cl_dll/MonitorMaterialProxy.cpp
Normal file
60
cl_dll/MonitorMaterialProxy.cpp
Normal file
@ -0,0 +1,60 @@
|
|||||||
|
//========= Copyright © 1996-2005, Valve Corporation, All rights reserved. ============//
|
||||||
|
//
|
||||||
|
// Purpose:
|
||||||
|
//
|
||||||
|
// $NoKeywords: $
|
||||||
|
//=============================================================================//
|
||||||
|
#include "cbase.h"
|
||||||
|
#include "materialsystem/IMaterialProxy.h"
|
||||||
|
#include "materialsystem/IMaterial.h"
|
||||||
|
#include "materialsystem/IMaterialVar.h"
|
||||||
|
|
||||||
|
// $monitorTextureVar
|
||||||
|
class CMonitorMaterialProxy : public IMaterialProxy
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
CMonitorMaterialProxy();
|
||||||
|
virtual ~CMonitorMaterialProxy();
|
||||||
|
virtual bool Init( IMaterial *pMaterial, KeyValues *pKeyValues );
|
||||||
|
virtual void OnBind( void *pC_BaseEntity );
|
||||||
|
virtual void Release( void ) { delete this; }
|
||||||
|
private:
|
||||||
|
IMaterialVar *m_pMonitorTextureVar;
|
||||||
|
};
|
||||||
|
|
||||||
|
CMonitorMaterialProxy::CMonitorMaterialProxy()
|
||||||
|
{
|
||||||
|
m_pMonitorTextureVar = NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
CMonitorMaterialProxy::~CMonitorMaterialProxy()
|
||||||
|
{
|
||||||
|
m_pMonitorTextureVar = NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
bool CMonitorMaterialProxy::Init( IMaterial *pMaterial, KeyValues *pKeyValues )
|
||||||
|
{
|
||||||
|
char const* pMonitorTextureVarName = pKeyValues->getString( "$monitorTextureVar" );
|
||||||
|
if( !pMonitorTextureVarName )
|
||||||
|
return false;
|
||||||
|
|
||||||
|
bool foundVar;
|
||||||
|
m_pMonitorTextureVar = pMaterial->FindVar( pMonitorTextureVarName, &foundVar, false );
|
||||||
|
if( !foundVar )
|
||||||
|
{
|
||||||
|
m_pMonitorTextureVar = NULL;
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
void CMonitorMaterialProxy::OnBind( void *pC_BaseEntity )
|
||||||
|
{
|
||||||
|
if( !m_pMonitorTextureVar )
|
||||||
|
{
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
EXPOSE_INTERFACE( CMonitorMaterialProxy, IMaterialProxy, "Monitor" IMATERIAL_PROXY_INTERFACE_VERSION );
|
50
cl_dll/ProxyHealth.cpp
Normal file
50
cl_dll/ProxyHealth.cpp
Normal file
@ -0,0 +1,50 @@
|
|||||||
|
//========= Copyright © 1996-2005, Valve Corporation, All rights reserved. ============//
|
||||||
|
//
|
||||||
|
// Purpose:
|
||||||
|
//
|
||||||
|
// $NoKeywords: $
|
||||||
|
//=============================================================================//
|
||||||
|
#include "cbase.h"
|
||||||
|
#include "FunctionProxy.h"
|
||||||
|
|
||||||
|
// memdbgon must be the last include file in a .cpp file!!!
|
||||||
|
#include "tier0/memdbgon.h"
|
||||||
|
|
||||||
|
//-----------------------------------------------------------------------------
|
||||||
|
// Returns the player health (from 0 to 1)
|
||||||
|
//-----------------------------------------------------------------------------
|
||||||
|
class CProxyHealth : public CResultProxy
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
bool Init( IMaterial *pMaterial, KeyValues *pKeyValues );
|
||||||
|
void OnBind( void *pC_BaseEntity );
|
||||||
|
|
||||||
|
private:
|
||||||
|
CFloatInput m_Factor;
|
||||||
|
};
|
||||||
|
|
||||||
|
bool CProxyHealth::Init( IMaterial *pMaterial, KeyValues *pKeyValues )
|
||||||
|
{
|
||||||
|
if (!CResultProxy::Init( pMaterial, pKeyValues ))
|
||||||
|
return false;
|
||||||
|
|
||||||
|
if (!m_Factor.Init( pMaterial, pKeyValues, "scale", 1 ))
|
||||||
|
return false;
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
void CProxyHealth::OnBind( void *pC_BaseEntity )
|
||||||
|
{
|
||||||
|
if (!pC_BaseEntity)
|
||||||
|
return;
|
||||||
|
|
||||||
|
C_BaseEntity *pEntity = BindArgToEntity( pC_BaseEntity );
|
||||||
|
|
||||||
|
Assert( m_pResult );
|
||||||
|
SetFloatResult( pEntity->HealthFraction() * m_Factor.GetFloat() );
|
||||||
|
}
|
||||||
|
|
||||||
|
EXPOSE_INTERFACE( CProxyHealth, IMaterialProxy, "Health" IMATERIAL_PROXY_INTERFACE_VERSION );
|
||||||
|
|
||||||
|
|
454
cl_dll/ScreenSpaceEffects.cpp
Normal file
454
cl_dll/ScreenSpaceEffects.cpp
Normal file
@ -0,0 +1,454 @@
|
|||||||
|
#include "cbase.h"
|
||||||
|
|
||||||
|
#include "keyvalues.h"
|
||||||
|
#include "cdll_client_int.h"
|
||||||
|
#include "view_scene.h"
|
||||||
|
#include "viewrender.h"
|
||||||
|
#include "vstdlib/icommandline.h"
|
||||||
|
#include "materialsystem/IMesh.h"
|
||||||
|
#include "materialsystem/IMaterial.h"
|
||||||
|
#include "materialsystem/IMaterialSystemHardwareConfig.h"
|
||||||
|
#include "materialsystem/IMaterialVar.h"
|
||||||
|
#include "materialsystem/IColorCorrection.h"
|
||||||
|
|
||||||
|
#include "ScreenSpaceEffects.h"
|
||||||
|
|
||||||
|
// memdbgon must be the last include file in a .cpp file!!!
|
||||||
|
#include "tier0/memdbgon.h"
|
||||||
|
|
||||||
|
static ConVar mat_colorcorrection( "mat_colorcorrection", "1" );
|
||||||
|
|
||||||
|
//------------------------------------------------------------------------------
|
||||||
|
// CScreenSpaceEffectRegistration code
|
||||||
|
// Used to register and effect with the IScreenSpaceEffectManager
|
||||||
|
//------------------------------------------------------------------------------
|
||||||
|
CScreenSpaceEffectRegistration *CScreenSpaceEffectRegistration::s_pHead = NULL;
|
||||||
|
|
||||||
|
CScreenSpaceEffectRegistration::CScreenSpaceEffectRegistration( const char *pName, IScreenSpaceEffect *pEffect )
|
||||||
|
{
|
||||||
|
m_pEffectName = pName;
|
||||||
|
m_pEffect = pEffect;
|
||||||
|
m_pNext = s_pHead;
|
||||||
|
s_pHead = this;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
//------------------------------------------------------------------------------
|
||||||
|
// CScreenSpaceEffectManager - Implementation of IScreenSpaceEffectManager
|
||||||
|
//------------------------------------------------------------------------------
|
||||||
|
class CScreenSpaceEffectManager : public IScreenSpaceEffectManager
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
|
||||||
|
virtual void InitScreenSpaceEffects( );
|
||||||
|
virtual void ShutdownScreenSpaceEffects( );
|
||||||
|
|
||||||
|
virtual IScreenSpaceEffect *GetScreenSpaceEffect( const char *pEffectName );
|
||||||
|
|
||||||
|
virtual void SetScreenSpaceEffectParams( const char *pEffectName, KeyValues *params );
|
||||||
|
virtual void SetScreenSpaceEffectParams( IScreenSpaceEffect *pEffect, KeyValues *params );
|
||||||
|
|
||||||
|
virtual void EnableScreenSpaceEffect( const char *pEffectName );
|
||||||
|
virtual void EnableScreenSpaceEffect( IScreenSpaceEffect *pEffect );
|
||||||
|
|
||||||
|
virtual void DisableScreenSpaceEffect( const char *pEffectName );
|
||||||
|
virtual void DisableScreenSpaceEffect( IScreenSpaceEffect *pEffect );
|
||||||
|
|
||||||
|
virtual void DisableAllScreenSpaceEffects( );
|
||||||
|
|
||||||
|
virtual void RenderEffects( int x, int y, int w, int h );
|
||||||
|
};
|
||||||
|
|
||||||
|
CScreenSpaceEffectManager g_ScreenSpaceEffectManager;
|
||||||
|
IScreenSpaceEffectManager *g_pScreenSpaceEffects = &g_ScreenSpaceEffectManager;
|
||||||
|
|
||||||
|
//---------------------------------------------------------------------------------------
|
||||||
|
// CScreenSpaceEffectManager::InitScreenSpaceEffects - Initialise all registered effects
|
||||||
|
//---------------------------------------------------------------------------------------
|
||||||
|
void CScreenSpaceEffectManager::InitScreenSpaceEffects( )
|
||||||
|
{
|
||||||
|
if ( CommandLine()->FindParm( "-colorcorrection" ) || CommandLine()->FindParm( "-tools" ) )
|
||||||
|
{
|
||||||
|
GetScreenSpaceEffect( "colorcorrection" )->Enable( true );
|
||||||
|
}
|
||||||
|
|
||||||
|
if ( CommandLine()->FindParm( "-filmgrain" ) )
|
||||||
|
{
|
||||||
|
GetScreenSpaceEffect( "filmgrain" )->Enable( true );
|
||||||
|
}
|
||||||
|
|
||||||
|
for( CScreenSpaceEffectRegistration *pReg=CScreenSpaceEffectRegistration::s_pHead; pReg!=NULL; pReg=pReg->m_pNext )
|
||||||
|
{
|
||||||
|
IScreenSpaceEffect *pEffect = pReg->m_pEffect;
|
||||||
|
if( pEffect )
|
||||||
|
{
|
||||||
|
bool bIsEnabled = pEffect->IsEnabled( );
|
||||||
|
pEffect->Init( );
|
||||||
|
pEffect->Enable( bIsEnabled );
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
//----------------------------------------------------------------------------------------
|
||||||
|
// CScreenSpaceEffectManager::ShutdownScreenSpaceEffects - Shutdown all registered effects
|
||||||
|
//----------------------------------------------------------------------------------------
|
||||||
|
void CScreenSpaceEffectManager::ShutdownScreenSpaceEffects( )
|
||||||
|
{
|
||||||
|
for( CScreenSpaceEffectRegistration *pReg=CScreenSpaceEffectRegistration::s_pHead; pReg!=NULL; pReg=pReg->m_pNext )
|
||||||
|
{
|
||||||
|
IScreenSpaceEffect *pEffect = pReg->m_pEffect;
|
||||||
|
if( pEffect )
|
||||||
|
{
|
||||||
|
pEffect->Shutdown( );
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
//---------------------------------------------------------------------------------------
|
||||||
|
// CScreenSpaceEffectManager::GetScreenSpaceEffect - Returns a point to the named effect
|
||||||
|
//---------------------------------------------------------------------------------------
|
||||||
|
IScreenSpaceEffect *CScreenSpaceEffectManager::GetScreenSpaceEffect( const char *pEffectName )
|
||||||
|
{
|
||||||
|
for( CScreenSpaceEffectRegistration *pReg=CScreenSpaceEffectRegistration::s_pHead; pReg!=NULL; pReg=pReg->m_pNext )
|
||||||
|
{
|
||||||
|
if( !Q_stricmp( pReg->m_pEffectName, pEffectName ) )
|
||||||
|
{
|
||||||
|
IScreenSpaceEffect *pEffect = pReg->m_pEffect;
|
||||||
|
return pEffect;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
Warning( "Could not find screen space effect %s\n", pEffectName );
|
||||||
|
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
//---------------------------------------------------------------------------------------
|
||||||
|
// CScreenSpaceEffectManager::SetScreenSpaceEffectParams
|
||||||
|
// - Assign parameters to the specified effect
|
||||||
|
//---------------------------------------------------------------------------------------
|
||||||
|
void CScreenSpaceEffectManager::SetScreenSpaceEffectParams( const char *pEffectName, KeyValues *params )
|
||||||
|
{
|
||||||
|
IScreenSpaceEffect *pEffect = GetScreenSpaceEffect( pEffectName );
|
||||||
|
if( pEffect )
|
||||||
|
SetScreenSpaceEffectParams( pEffect, params );
|
||||||
|
}
|
||||||
|
|
||||||
|
void CScreenSpaceEffectManager::SetScreenSpaceEffectParams( IScreenSpaceEffect *pEffect, KeyValues *params )
|
||||||
|
{
|
||||||
|
if( pEffect )
|
||||||
|
pEffect->SetParameters( params );
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
//---------------------------------------------------------------------------------------
|
||||||
|
// CScreenSpaceEffectManager::EnableScreenSpaceEffect
|
||||||
|
// - Enables the specified effect
|
||||||
|
//---------------------------------------------------------------------------------------
|
||||||
|
void CScreenSpaceEffectManager::EnableScreenSpaceEffect( const char *pEffectName )
|
||||||
|
{
|
||||||
|
IScreenSpaceEffect *pEffect = GetScreenSpaceEffect( pEffectName );
|
||||||
|
if( pEffect )
|
||||||
|
EnableScreenSpaceEffect( pEffect );
|
||||||
|
}
|
||||||
|
|
||||||
|
void CScreenSpaceEffectManager::EnableScreenSpaceEffect( IScreenSpaceEffect *pEffect )
|
||||||
|
{
|
||||||
|
if( pEffect )
|
||||||
|
pEffect->Enable( true );
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
//---------------------------------------------------------------------------------------
|
||||||
|
// CScreenSpaceEffectManager::DisableScreenSpaceEffect
|
||||||
|
// - Disables the specified effect
|
||||||
|
//---------------------------------------------------------------------------------------
|
||||||
|
void CScreenSpaceEffectManager::DisableScreenSpaceEffect( const char *pEffectName )
|
||||||
|
{
|
||||||
|
IScreenSpaceEffect *pEffect = GetScreenSpaceEffect( pEffectName );
|
||||||
|
if( pEffect )
|
||||||
|
DisableScreenSpaceEffect( pEffect );
|
||||||
|
}
|
||||||
|
|
||||||
|
void CScreenSpaceEffectManager::DisableScreenSpaceEffect( IScreenSpaceEffect *pEffect )
|
||||||
|
{
|
||||||
|
if( pEffect )
|
||||||
|
pEffect->Enable( false );
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
//---------------------------------------------------------------------------------------
|
||||||
|
// CScreenSpaceEffectManager::DisableAllScreenSpaceEffects
|
||||||
|
// - Disables all registered screen space effects
|
||||||
|
//---------------------------------------------------------------------------------------
|
||||||
|
void CScreenSpaceEffectManager::DisableAllScreenSpaceEffects( )
|
||||||
|
{
|
||||||
|
for( CScreenSpaceEffectRegistration *pReg=CScreenSpaceEffectRegistration::s_pHead; pReg!=NULL; pReg=pReg->m_pNext )
|
||||||
|
{
|
||||||
|
IScreenSpaceEffect *pEffect = pReg->m_pEffect;
|
||||||
|
if( pEffect )
|
||||||
|
{
|
||||||
|
pEffect->Enable( false );
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
//---------------------------------------------------------------------------------------
|
||||||
|
// CScreenSpaceEffectManager::RenderEffects
|
||||||
|
// - Renders all registered screen space effects
|
||||||
|
//---------------------------------------------------------------------------------------
|
||||||
|
void CScreenSpaceEffectManager::RenderEffects( int x, int y, int w, int h )
|
||||||
|
{
|
||||||
|
for( CScreenSpaceEffectRegistration *pReg=CScreenSpaceEffectRegistration::s_pHead; pReg!=NULL; pReg=pReg->m_pNext )
|
||||||
|
{
|
||||||
|
IScreenSpaceEffect *pEffect = pReg->m_pEffect;
|
||||||
|
if( pEffect )
|
||||||
|
{
|
||||||
|
pEffect->Render( x, y, w, h );
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
//------------------------------------------------------------------------------
|
||||||
|
// Color correction post-processing effect
|
||||||
|
//------------------------------------------------------------------------------
|
||||||
|
class CColorCorrectionEffect : public IScreenSpaceEffect
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
CColorCorrectionEffect( );
|
||||||
|
~CColorCorrectionEffect( );
|
||||||
|
|
||||||
|
void Init( );
|
||||||
|
void Shutdown( );
|
||||||
|
|
||||||
|
void SetParameters( KeyValues *params );
|
||||||
|
|
||||||
|
void Render( int x, int y, int w, int h );
|
||||||
|
|
||||||
|
void Enable( bool bEnable );
|
||||||
|
bool IsEnabled( );
|
||||||
|
|
||||||
|
private:
|
||||||
|
|
||||||
|
bool m_bEnable;
|
||||||
|
|
||||||
|
CMaterialReference m_Material;
|
||||||
|
|
||||||
|
bool m_bSplitScreen;
|
||||||
|
|
||||||
|
};
|
||||||
|
|
||||||
|
ADD_SCREENSPACE_EFFECT( CColorCorrectionEffect, colorcorrection );
|
||||||
|
|
||||||
|
//------------------------------------------------------------------------------
|
||||||
|
// CColorCorrectionEffect constructor
|
||||||
|
//------------------------------------------------------------------------------
|
||||||
|
CColorCorrectionEffect::CColorCorrectionEffect( )
|
||||||
|
{
|
||||||
|
m_bSplitScreen = false;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
//------------------------------------------------------------------------------
|
||||||
|
// CColorCorrectionEffect destructor
|
||||||
|
//------------------------------------------------------------------------------
|
||||||
|
CColorCorrectionEffect::~CColorCorrectionEffect( )
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
//------------------------------------------------------------------------------
|
||||||
|
// CColorCorrectionEffect init
|
||||||
|
//------------------------------------------------------------------------------
|
||||||
|
void CColorCorrectionEffect::Init( )
|
||||||
|
{
|
||||||
|
m_Material.Init( "engine/colorcorrection", TEXTURE_GROUP_OTHER );
|
||||||
|
|
||||||
|
m_bEnable = false;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
//------------------------------------------------------------------------------
|
||||||
|
// CColorCorrectionEffect shutdown
|
||||||
|
//------------------------------------------------------------------------------
|
||||||
|
void CColorCorrectionEffect::Shutdown( )
|
||||||
|
{
|
||||||
|
m_Material.Shutdown();
|
||||||
|
}
|
||||||
|
|
||||||
|
//------------------------------------------------------------------------------
|
||||||
|
// CColorCorrectionEffect enable
|
||||||
|
//------------------------------------------------------------------------------
|
||||||
|
void CColorCorrectionEffect::Enable( bool bEnable )
|
||||||
|
{
|
||||||
|
if( g_pMaterialSystemHardwareConfig->GetDXSupportLevel()<90 && bEnable )
|
||||||
|
{
|
||||||
|
Msg( "Color correction can not be enabled when not in DX9 mode.\n" );
|
||||||
|
bEnable = false;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
m_bEnable = bEnable;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
bool CColorCorrectionEffect::IsEnabled( )
|
||||||
|
{
|
||||||
|
return m_bEnable;
|
||||||
|
}
|
||||||
|
|
||||||
|
//------------------------------------------------------------------------------
|
||||||
|
// CColorCorrectionEffect SetParameters
|
||||||
|
//------------------------------------------------------------------------------
|
||||||
|
void CColorCorrectionEffect::SetParameters( KeyValues *params )
|
||||||
|
{
|
||||||
|
if( params->GetDataType( "split_screen" ) == KeyValues::TYPE_STRING )
|
||||||
|
{
|
||||||
|
int ival = params->GetInt( "split_screen" );
|
||||||
|
m_bSplitScreen = ival?true:false;
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
//------------------------------------------------------------------------------
|
||||||
|
// CColorCorrectionEffect render
|
||||||
|
//------------------------------------------------------------------------------
|
||||||
|
void CColorCorrectionEffect::Render( int x, int y, int w, int h )
|
||||||
|
{
|
||||||
|
// We're releasing the CS:S client before the engine with this interface, so we need to fail gracefully
|
||||||
|
if( mat_colorcorrection.GetInt()==0 || !colorcorrection )
|
||||||
|
{
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if( g_pMaterialSystemHardwareConfig->GetDXSupportLevel()<90 )
|
||||||
|
{
|
||||||
|
mat_colorcorrection.SetValue( 0 );
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
colorcorrection->NormalizeWeights();
|
||||||
|
|
||||||
|
if( colorcorrection->GetNumLookups()==0 )
|
||||||
|
{
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Set up shader inputs (there has to be a better way to do this)
|
||||||
|
|
||||||
|
int paramCount = m_Material->ShaderParamCount();
|
||||||
|
IMaterialVar **pParams = m_Material->GetShaderParams();
|
||||||
|
for( int i=0;i<paramCount;i++ )
|
||||||
|
{
|
||||||
|
IMaterialVar *pVar = pParams[i];
|
||||||
|
|
||||||
|
if( !Q_stricmp( pVar->GetName(), "$weight_default" ) )
|
||||||
|
{
|
||||||
|
pVar->SetFloatValue( colorcorrection->GetLookupWeight(-1) );
|
||||||
|
}
|
||||||
|
else if( !Q_stricmp( pVar->GetName(), "$weight0" ) )
|
||||||
|
{
|
||||||
|
pVar->SetFloatValue( colorcorrection->GetLookupWeight(0) );
|
||||||
|
}
|
||||||
|
else if( !Q_stricmp( pVar->GetName(), "$weight1" ) )
|
||||||
|
{
|
||||||
|
pVar->SetFloatValue( colorcorrection->GetLookupWeight(1) );
|
||||||
|
}
|
||||||
|
else if( !Q_stricmp( pVar->GetName(), "$weight2" ) )
|
||||||
|
{
|
||||||
|
pVar->SetFloatValue( colorcorrection->GetLookupWeight(2) );
|
||||||
|
}
|
||||||
|
else if( !Q_stricmp( pVar->GetName(), "$weight3" ) )
|
||||||
|
{
|
||||||
|
pVar->SetFloatValue( colorcorrection->GetLookupWeight(3) );
|
||||||
|
}
|
||||||
|
else if( !Q_stricmp( pVar->GetName(), "$num_lookups" ) )
|
||||||
|
{
|
||||||
|
pVar->SetIntValue( colorcorrection->GetNumLookups() );
|
||||||
|
}
|
||||||
|
else if( !Q_stricmp( pVar->GetName(), "$use_fb_texture" ) )
|
||||||
|
{
|
||||||
|
pVar->SetIntValue( 1 );
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
colorcorrection->ResetLookupWeights();
|
||||||
|
|
||||||
|
// Render Effect
|
||||||
|
Rect_t actualRect;
|
||||||
|
UpdateScreenEffectTexture( 0, x, y, w, h, false, &actualRect );
|
||||||
|
ITexture *pTexture = GetFullFrameFrameBufferTexture( 0 );
|
||||||
|
|
||||||
|
if( m_bSplitScreen )
|
||||||
|
{
|
||||||
|
w /= 2;
|
||||||
|
x += w;
|
||||||
|
actualRect.x = actualRect.x + actualRect.width/2;
|
||||||
|
actualRect.width = actualRect.width/2;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Tempororary hack... Color correction was crashing on the first frame
|
||||||
|
// when run outside the debugger for some mods (DoD). This forces it to skip
|
||||||
|
// a frame, ensuring we don't get the weird texture crash we otherwise would.
|
||||||
|
// This will be removed when the true cause is found
|
||||||
|
static bool bFirstFrame = true;
|
||||||
|
if( !bFirstFrame )
|
||||||
|
{
|
||||||
|
materials->DrawScreenSpaceRectangle( m_Material, x, y, w, h,
|
||||||
|
actualRect.x, actualRect.y, actualRect.x+actualRect.width-1, actualRect.y+actualRect.height-1,
|
||||||
|
pTexture->GetActualWidth(), pTexture->GetActualHeight() );
|
||||||
|
}
|
||||||
|
bFirstFrame = false;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
//------------------------------------------------------------------------------
|
||||||
|
// Console Interface
|
||||||
|
//------------------------------------------------------------------------------
|
||||||
|
static void EnableColorCorrection( ConVar *var, char const *pOldString )
|
||||||
|
{
|
||||||
|
if( var->GetBool() )
|
||||||
|
{
|
||||||
|
g_pScreenSpaceEffects->EnableScreenSpaceEffect( "colorcorrection" );
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
g_pScreenSpaceEffects->DisableScreenSpaceEffect( "colorcorrection" );
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
static void SetScreenEffectParam()
|
||||||
|
{
|
||||||
|
if( engine->Cmd_Argc() >= 4 )
|
||||||
|
{
|
||||||
|
const char *effect_type = engine->Cmd_Argv(1);
|
||||||
|
|
||||||
|
int num_params = (engine->Cmd_Argc()-2)/2;
|
||||||
|
if( engine->Cmd_Argc() != num_params*2+2 )
|
||||||
|
{
|
||||||
|
Msg( "Missing hald of key/value pair.\n" );
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
KeyValues *params = new KeyValues( "params" );
|
||||||
|
for( int i=0;i<num_params;i++ )
|
||||||
|
{
|
||||||
|
params->SetString( engine->Cmd_Argv( i*2 + 2 ), engine->Cmd_Argv( i*2 + 3 ) );
|
||||||
|
}
|
||||||
|
|
||||||
|
g_pScreenSpaceEffects->SetScreenSpaceEffectParams( effect_type, params );
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Console interface for setting screen space effect parameters
|
||||||
|
// Format:
|
||||||
|
// set_effect_param effect_type param_name param_value
|
||||||
|
// eg set_effect_param 1 $noise_scale "255 255 255 0"
|
||||||
|
static ConCommand set_screen_effect_param( "set_screen_effect_param", SetScreenEffectParam, "Set a parameter for one of the screen space effects.", FCVAR_CHEAT );
|
88
cl_dll/ScreenSpaceEffects.h
Normal file
88
cl_dll/ScreenSpaceEffects.h
Normal file
@ -0,0 +1,88 @@
|
|||||||
|
//========= Copyright © 1996-2005, Valve Corporation, All rights reserved. ============//
|
||||||
|
//
|
||||||
|
// Purpose:
|
||||||
|
//
|
||||||
|
// $NoKeywords: $
|
||||||
|
//
|
||||||
|
//=====================================================================================//
|
||||||
|
|
||||||
|
#ifndef SCREENSPACEEFFECTS_H
|
||||||
|
#define SCREENSPACEEFFECTS_H
|
||||||
|
|
||||||
|
#ifdef _WIN32
|
||||||
|
#pragma once
|
||||||
|
#endif
|
||||||
|
|
||||||
|
class KeyValues;
|
||||||
|
|
||||||
|
|
||||||
|
//------------------------------------------------------------------------------
|
||||||
|
// Simple base class for screen space post-processing effects
|
||||||
|
//------------------------------------------------------------------------------
|
||||||
|
abstract_class IScreenSpaceEffect
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
|
||||||
|
virtual void Init( ) = 0;
|
||||||
|
virtual void Shutdown( ) = 0;
|
||||||
|
|
||||||
|
virtual void SetParameters( KeyValues *params ) = 0;
|
||||||
|
|
||||||
|
virtual void Render( int x, int y, int w, int h ) = 0;
|
||||||
|
|
||||||
|
virtual void Enable( bool bEnable ) = 0;
|
||||||
|
virtual bool IsEnabled( ) = 0;
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
//------------------------------------------------------------------------------
|
||||||
|
// Interface class for managing screen space post-processing effects
|
||||||
|
//------------------------------------------------------------------------------
|
||||||
|
abstract_class IScreenSpaceEffectManager
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
|
||||||
|
virtual void InitScreenSpaceEffects( ) = 0;
|
||||||
|
virtual void ShutdownScreenSpaceEffects( ) = 0;
|
||||||
|
|
||||||
|
virtual IScreenSpaceEffect *GetScreenSpaceEffect( const char *pEffectName ) = 0;
|
||||||
|
|
||||||
|
virtual void SetScreenSpaceEffectParams( const char *pEffectName, KeyValues *params ) = 0;
|
||||||
|
virtual void SetScreenSpaceEffectParams( IScreenSpaceEffect *pEffect, KeyValues *params ) = 0;
|
||||||
|
|
||||||
|
virtual void EnableScreenSpaceEffect( const char *pEffectName ) = 0;
|
||||||
|
virtual void EnableScreenSpaceEffect( IScreenSpaceEffect *pEffect ) = 0;
|
||||||
|
|
||||||
|
virtual void DisableScreenSpaceEffect( const char *pEffectName ) = 0;
|
||||||
|
virtual void DisableScreenSpaceEffect( IScreenSpaceEffect *pEffect ) = 0;
|
||||||
|
|
||||||
|
virtual void DisableAllScreenSpaceEffects( ) = 0;
|
||||||
|
|
||||||
|
virtual void RenderEffects( int x, int y, int w, int h ) = 0;
|
||||||
|
};
|
||||||
|
|
||||||
|
extern IScreenSpaceEffectManager *g_pScreenSpaceEffects;
|
||||||
|
|
||||||
|
|
||||||
|
//-------------------------------------------------------------------------------------
|
||||||
|
// Registration class for adding screen space effects to the IScreenSpaceEffectManager
|
||||||
|
//-------------------------------------------------------------------------------------
|
||||||
|
class CScreenSpaceEffectRegistration
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
CScreenSpaceEffectRegistration( const char *pName, IScreenSpaceEffect *pEffect );
|
||||||
|
|
||||||
|
const char *m_pEffectName;
|
||||||
|
IScreenSpaceEffect *m_pEffect;
|
||||||
|
|
||||||
|
CScreenSpaceEffectRegistration *m_pNext;
|
||||||
|
|
||||||
|
static CScreenSpaceEffectRegistration *s_pHead;
|
||||||
|
};
|
||||||
|
|
||||||
|
#define ADD_SCREENSPACE_EFFECT( CEffect, pEffectName ) CEffect pEffectName##_effect; \
|
||||||
|
CScreenSpaceEffectRegistration pEffectName##_reg( #pEffectName, &pEffectName##_effect );
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
#endif
|
172
cl_dll/TeamBitmapImage.cpp
Normal file
172
cl_dll/TeamBitmapImage.cpp
Normal file
@ -0,0 +1,172 @@
|
|||||||
|
//========= Copyright © 1996-2005, Valve Corporation, All rights reserved. ============//
|
||||||
|
//
|
||||||
|
// Purpose: This is a panel which is rendered image on top of an entity
|
||||||
|
//
|
||||||
|
// $Revision: $
|
||||||
|
// $NoKeywords: $
|
||||||
|
//=============================================================================//
|
||||||
|
#include "cbase.h"
|
||||||
|
#include "teambitmapimage.h"
|
||||||
|
#include <KeyValues.h>
|
||||||
|
#include "vgui_BitmapImage.h"
|
||||||
|
#include "PanelMetaClassMgr.h"
|
||||||
|
#include "vguimatsurface/IMatSystemSurface.h"
|
||||||
|
#include <vgui_controls/Panel.h>
|
||||||
|
|
||||||
|
// memdbgon must be the last include file in a .cpp file!!!
|
||||||
|
#include "tier0/memdbgon.h"
|
||||||
|
|
||||||
|
//-----------------------------------------------------------------------------
|
||||||
|
// A multiplexer bitmap that chooses a bitmap based on team
|
||||||
|
//-----------------------------------------------------------------------------
|
||||||
|
CTeamBitmapImage::CTeamBitmapImage() : m_Alpha(1.0f)
|
||||||
|
{
|
||||||
|
memset( m_ppImage, 0, BITMAP_COUNT * sizeof(BitmapImage*) );
|
||||||
|
m_pEntity = NULL;
|
||||||
|
m_bRelativeTeams = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
CTeamBitmapImage::~CTeamBitmapImage()
|
||||||
|
{
|
||||||
|
int i;
|
||||||
|
for ( i = 0; i < BITMAP_COUNT; ++i )
|
||||||
|
{
|
||||||
|
if (m_ppImage[i])
|
||||||
|
delete m_ppImage[i];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
//-----------------------------------------------------------------------------
|
||||||
|
// initialization
|
||||||
|
//-----------------------------------------------------------------------------
|
||||||
|
bool CTeamBitmapImage::Init( vgui::Panel *pParent, KeyValues* pInitData, C_BaseEntity* pEntity )
|
||||||
|
{
|
||||||
|
static char *pRelativeTeamNames[BITMAP_COUNT] =
|
||||||
|
{
|
||||||
|
"NoTeam",
|
||||||
|
"MyTeam",
|
||||||
|
"EnemyTeam",
|
||||||
|
};
|
||||||
|
|
||||||
|
static char *pAbsoluteTeamNames[BITMAP_COUNT] =
|
||||||
|
{
|
||||||
|
"Team0",
|
||||||
|
"Team1",
|
||||||
|
"Team2",
|
||||||
|
};
|
||||||
|
|
||||||
|
m_pEntity = pEntity;
|
||||||
|
m_bRelativeTeams = (pInitData->GetInt( "relativeteam" ) != 0);
|
||||||
|
|
||||||
|
char **ppTeamNames = m_bRelativeTeams ? pRelativeTeamNames : pAbsoluteTeamNames;
|
||||||
|
|
||||||
|
int i;
|
||||||
|
for ( i = 0 ; i < BITMAP_COUNT; ++i )
|
||||||
|
{
|
||||||
|
// Default to null
|
||||||
|
m_ppImage[i] = NULL;
|
||||||
|
|
||||||
|
// Look for team section
|
||||||
|
KeyValues *pTeamKV = pInitData->FindKey( ppTeamNames[i] );
|
||||||
|
if ( !pTeamKV )
|
||||||
|
continue;
|
||||||
|
|
||||||
|
char const* pClassImage = pTeamKV->GetString( "material" );
|
||||||
|
if ( !pClassImage || !pClassImage[ 0 ] )
|
||||||
|
return false;
|
||||||
|
|
||||||
|
// modulation color
|
||||||
|
Color color;
|
||||||
|
if (!ParseRGBA( pTeamKV, "color", color ))
|
||||||
|
color.SetColor( 255, 255, 255, 255 );
|
||||||
|
|
||||||
|
// hook in the bitmap
|
||||||
|
m_ppImage[i] = new BitmapImage( pParent->GetVPanel(), pClassImage );
|
||||||
|
m_ppImage[i]->SetColor( color );
|
||||||
|
}
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
//-----------------------------------------------------------------------------
|
||||||
|
// Alpha modulate...
|
||||||
|
//-----------------------------------------------------------------------------
|
||||||
|
void CTeamBitmapImage::SetAlpha( float alpha )
|
||||||
|
{
|
||||||
|
m_Alpha = clamp( alpha, 0.0f, 1.0f );
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
//-----------------------------------------------------------------------------
|
||||||
|
// draw
|
||||||
|
//-----------------------------------------------------------------------------
|
||||||
|
void CTeamBitmapImage::Paint( float yaw /*= 0.0f*/ )
|
||||||
|
{
|
||||||
|
if (m_Alpha == 0.0f)
|
||||||
|
return;
|
||||||
|
|
||||||
|
int team = 0;
|
||||||
|
if (m_bRelativeTeams)
|
||||||
|
{
|
||||||
|
if (GetEntity())
|
||||||
|
{
|
||||||
|
if (GetEntity()->GetTeamNumber() != 0)
|
||||||
|
{
|
||||||
|
team = GetEntity()->InLocalTeam() ? 1 : 2;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
if (GetEntity())
|
||||||
|
team = GetEntity()->GetTeamNumber();
|
||||||
|
}
|
||||||
|
|
||||||
|
// Paint the image for the current team
|
||||||
|
if (m_ppImage[team])
|
||||||
|
{
|
||||||
|
// Modulate the color based on the alpha....
|
||||||
|
Color color = m_ppImage[team]->GetColor();
|
||||||
|
int alpha = color[3];
|
||||||
|
color[3] = (alpha * m_Alpha);
|
||||||
|
m_ppImage[team]->SetColor( color );
|
||||||
|
|
||||||
|
if ( yaw != 0.0f )
|
||||||
|
{
|
||||||
|
g_pMatSystemSurface->DisableClipping( true );
|
||||||
|
|
||||||
|
m_ppImage[team]->DoPaint( m_ppImage[team]->GetRenderSizePanel(), yaw );
|
||||||
|
|
||||||
|
g_pMatSystemSurface->DisableClipping( false );
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
// Paint
|
||||||
|
m_ppImage[team]->Paint();
|
||||||
|
}
|
||||||
|
|
||||||
|
// restore previous color
|
||||||
|
color[3] = alpha;
|
||||||
|
m_ppImage[team]->SetColor( color );
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
//-----------------------------------------------------------------------------
|
||||||
|
// Helper method to initialize a team image from KeyValues data..
|
||||||
|
//-----------------------------------------------------------------------------
|
||||||
|
bool InitializeTeamImage( KeyValues *pInitData, const char* pSectionName, vgui::Panel *pParent, C_BaseEntity *pEntity, CTeamBitmapImage* pTeamImage )
|
||||||
|
{
|
||||||
|
KeyValues *pTeamImageSection = pInitData;
|
||||||
|
if (pSectionName)
|
||||||
|
{
|
||||||
|
pTeamImageSection = pInitData->FindKey( pSectionName );
|
||||||
|
if ( !pTeamImageSection )
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
return pTeamImage->Init( pParent, pTeamImageSection, pEntity );
|
||||||
|
}
|
||||||
|
|
80
cl_dll/TeamBitmapImage.h
Normal file
80
cl_dll/TeamBitmapImage.h
Normal file
@ -0,0 +1,80 @@
|
|||||||
|
//========= Copyright © 1996-2005, Valve Corporation, All rights reserved. ============//
|
||||||
|
//
|
||||||
|
// Purpose: This is a panel which is rendered image on top of an entity
|
||||||
|
//
|
||||||
|
// $Revision: $
|
||||||
|
// $NoKeywords: $
|
||||||
|
//=============================================================================//
|
||||||
|
|
||||||
|
#ifndef TEAMBITMAPIMAGE_H
|
||||||
|
#define TEAMBITMAPIMAGE_H
|
||||||
|
|
||||||
|
#ifdef _WIN32
|
||||||
|
#pragma once
|
||||||
|
#endif
|
||||||
|
|
||||||
|
//#include "tf_shareddefs.h"
|
||||||
|
|
||||||
|
#include <vgui/VGUI.h>
|
||||||
|
|
||||||
|
namespace vgui
|
||||||
|
{
|
||||||
|
class Panel;
|
||||||
|
}
|
||||||
|
|
||||||
|
class BitmapImage;
|
||||||
|
class C_BaseEntity;
|
||||||
|
class KeyValues;
|
||||||
|
|
||||||
|
//-----------------------------------------------------------------------------
|
||||||
|
// A multiplexer bitmap that chooses a bitmap based on team
|
||||||
|
//-----------------------------------------------------------------------------
|
||||||
|
class CTeamBitmapImage
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
// construction, destruction
|
||||||
|
CTeamBitmapImage();
|
||||||
|
~CTeamBitmapImage();
|
||||||
|
|
||||||
|
// initialization
|
||||||
|
bool Init( vgui::Panel *pParent, KeyValues* pInitData, C_BaseEntity* pEntity );
|
||||||
|
|
||||||
|
// Alpha override...
|
||||||
|
void SetAlpha( float alpha );
|
||||||
|
|
||||||
|
// Paint the sucka. Paint it the size of the parent panel
|
||||||
|
void Paint( float yaw = 0.0f );
|
||||||
|
|
||||||
|
protected:
|
||||||
|
// Wrapper so we can implement this with EHANDLES some day
|
||||||
|
C_BaseEntity *GetEntity() { return m_pEntity; }
|
||||||
|
|
||||||
|
private:
|
||||||
|
enum
|
||||||
|
{
|
||||||
|
// NOTE: Was MAX_TF_TEAMS not 4, but I don't like the dependency here.
|
||||||
|
BITMAP_COUNT = 4 + 1
|
||||||
|
};
|
||||||
|
|
||||||
|
BitmapImage *m_ppImage[ BITMAP_COUNT ];
|
||||||
|
C_BaseEntity *m_pEntity;
|
||||||
|
float m_Alpha;
|
||||||
|
bool m_bRelativeTeams;
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
//-----------------------------------------------------------------------------
|
||||||
|
// Helper method to initialize a team image from KeyValues data..
|
||||||
|
// KeyValues contains the bitmap data. pSectionName, if it exists,
|
||||||
|
// indicates which subsection of pInitData should be looked at to get at the
|
||||||
|
// image data. The final argument is the bitmap image to initialize.
|
||||||
|
// The function returns true if it succeeded.
|
||||||
|
//
|
||||||
|
// NOTE: This function looks for the key values 'material' and 'color'
|
||||||
|
// and uses them to set up the material + modulation color of the image
|
||||||
|
//-----------------------------------------------------------------------------
|
||||||
|
bool InitializeTeamImage( KeyValues *pInitData, const char* pSectionName,
|
||||||
|
vgui::Panel *pParent, C_BaseEntity *pEntity, CTeamBitmapImage* pBitmapImage );
|
||||||
|
|
||||||
|
|
||||||
|
#endif // TEAMBITMAPIMAGE_H
|
83
cl_dll/ViewConeImage.cpp
Normal file
83
cl_dll/ViewConeImage.cpp
Normal file
@ -0,0 +1,83 @@
|
|||||||
|
//========= Copyright © 1996-2005, Valve Corporation, All rights reserved. ============//
|
||||||
|
//
|
||||||
|
// Purpose: This is a panel which is rendered image on top of an entity
|
||||||
|
//
|
||||||
|
// $Revision: $
|
||||||
|
// $NoKeywords: $
|
||||||
|
//=============================================================================//
|
||||||
|
#include "cbase.h"
|
||||||
|
#include "ViewConeImage.h"
|
||||||
|
#include <KeyValues.h>
|
||||||
|
#include <vgui_controls/Panel.h>
|
||||||
|
#include "vguimatsurface/IMatSystemSurface.h"
|
||||||
|
|
||||||
|
// memdbgon must be the last include file in a .cpp file!!!
|
||||||
|
#include "tier0/memdbgon.h"
|
||||||
|
|
||||||
|
//-----------------------------------------------------------------------------
|
||||||
|
// initialization
|
||||||
|
//-----------------------------------------------------------------------------
|
||||||
|
bool CViewConeImage::Init( vgui::Panel *pParent, KeyValues* pInitData )
|
||||||
|
{
|
||||||
|
Assert( pParent );
|
||||||
|
|
||||||
|
// Load viewcone material
|
||||||
|
if (!m_Image.Init( pParent->GetVPanel(), pInitData ))
|
||||||
|
return false;
|
||||||
|
|
||||||
|
// Position the view cone...
|
||||||
|
int viewconesize = pInitData->GetInt( "size", 32 );
|
||||||
|
m_Image.SetRenderSize( viewconesize, viewconesize );
|
||||||
|
|
||||||
|
int cx, cy;
|
||||||
|
pParent->GetSize( cx, cy );
|
||||||
|
m_Image.SetPos( (cx - viewconesize) / 2, (cy - viewconesize) / 2 );
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
//-----------------------------------------------------------------------------
|
||||||
|
// Paint the sucka
|
||||||
|
//-----------------------------------------------------------------------------
|
||||||
|
void CViewConeImage::Paint( float yaw )
|
||||||
|
{
|
||||||
|
g_pMatSystemSurface->DisableClipping( true );
|
||||||
|
|
||||||
|
m_Image.DoPaint( NULL, yaw );
|
||||||
|
|
||||||
|
g_pMatSystemSurface->DisableClipping( false );
|
||||||
|
}
|
||||||
|
|
||||||
|
void CViewConeImage::SetColor( int r, int g, int b )
|
||||||
|
{
|
||||||
|
m_Image.SetColor( Color( r, g, b, 255 ) );
|
||||||
|
}
|
||||||
|
|
||||||
|
//-----------------------------------------------------------------------------
|
||||||
|
// Helper method to initialize a view cone image from KeyValues data..
|
||||||
|
// KeyValues contains the bitmap data, pSectionName, if it exists,
|
||||||
|
// indicates which subsection of pInitData should be looked at to get at the
|
||||||
|
// image data. The final argument is the bitmap image to initialize.
|
||||||
|
// The function returns true if it succeeded.
|
||||||
|
//
|
||||||
|
// NOTE: This function looks for the key values 'material' and 'color'
|
||||||
|
// and uses them to set up the material + modulation color of the image
|
||||||
|
//-----------------------------------------------------------------------------
|
||||||
|
bool InitializeViewConeImage( KeyValues *pInitData, const char* pSectionName,
|
||||||
|
vgui::Panel *pParent, CViewConeImage* pViewConeImage )
|
||||||
|
{
|
||||||
|
KeyValues *pViewConeImageSection;
|
||||||
|
if (pSectionName)
|
||||||
|
{
|
||||||
|
pViewConeImageSection = pInitData->FindKey( pSectionName );
|
||||||
|
if ( !pViewConeImageSection )
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
pViewConeImageSection = pInitData;
|
||||||
|
}
|
||||||
|
|
||||||
|
return pViewConeImage->Init( pParent, pViewConeImageSection );
|
||||||
|
}
|
||||||
|
|
56
cl_dll/ViewConeImage.h
Normal file
56
cl_dll/ViewConeImage.h
Normal file
@ -0,0 +1,56 @@
|
|||||||
|
//========= Copyright © 1996-2005, Valve Corporation, All rights reserved. ============//
|
||||||
|
//
|
||||||
|
// Purpose: This is a panel which draws a viewcone
|
||||||
|
//
|
||||||
|
// $Revision: $
|
||||||
|
// $NoKeywords: $
|
||||||
|
//=============================================================================//
|
||||||
|
|
||||||
|
#ifndef VIEWCONEIMAGE_H
|
||||||
|
#define VIEWCONEIMAGE_H
|
||||||
|
|
||||||
|
#include "shareddefs.h"
|
||||||
|
#include "VGUI_BitmapImage.h"
|
||||||
|
|
||||||
|
namespace vgui
|
||||||
|
{
|
||||||
|
class Panel;
|
||||||
|
}
|
||||||
|
|
||||||
|
class C_BaseEntity;
|
||||||
|
class KeyValues;
|
||||||
|
|
||||||
|
//-----------------------------------------------------------------------------
|
||||||
|
// A bitmap that renders a view cone based on angles
|
||||||
|
//-----------------------------------------------------------------------------
|
||||||
|
class CViewConeImage
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
// initialization
|
||||||
|
bool Init( vgui::Panel *pParent, KeyValues* pInitData );
|
||||||
|
|
||||||
|
// Paint the sucka
|
||||||
|
void Paint( float yaw );
|
||||||
|
|
||||||
|
void SetColor( int r, int g, int b );
|
||||||
|
|
||||||
|
private:
|
||||||
|
BitmapImage m_Image;
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
//-----------------------------------------------------------------------------
|
||||||
|
// Helper method to initialize a view cone image from KeyValues data..
|
||||||
|
// KeyValues contains the bitmap data, pSectionName, if it exists,
|
||||||
|
// indicates which subsection of pInitData should be looked at to get at the
|
||||||
|
// image data. The final argument is the bitmap image to initialize.
|
||||||
|
// The function returns true if it succeeded.
|
||||||
|
//
|
||||||
|
// NOTE: This function looks for the key values 'material' and 'color'
|
||||||
|
// and uses them to set up the material + modulation color of the image
|
||||||
|
//-----------------------------------------------------------------------------
|
||||||
|
bool InitializeViewConeImage( KeyValues *pInitData, const char* pSectionName,
|
||||||
|
vgui::Panel *pParent, CViewConeImage* pViewConeImage );
|
||||||
|
|
||||||
|
|
||||||
|
#endif // VIEWCONEIMAGE_H
|
68
cl_dll/WaterLODMaterialProxy.cpp
Normal file
68
cl_dll/WaterLODMaterialProxy.cpp
Normal file
@ -0,0 +1,68 @@
|
|||||||
|
//========= Copyright © 1996-2005, Valve Corporation, All rights reserved. ============//
|
||||||
|
//
|
||||||
|
// Purpose:
|
||||||
|
//
|
||||||
|
// $NoKeywords: $
|
||||||
|
//=============================================================================//
|
||||||
|
#include "cbase.h"
|
||||||
|
#include "materialsystem/IMaterialProxy.h"
|
||||||
|
#include "materialsystem/IMaterial.h"
|
||||||
|
#include "materialsystem/IMaterialVar.h"
|
||||||
|
#include "iviewrender.h"
|
||||||
|
//#include "VMatrix.h"
|
||||||
|
|
||||||
|
// memdbgon must be the last include file in a .cpp file!!!
|
||||||
|
#include "tier0/memdbgon.h"
|
||||||
|
|
||||||
|
// no inputs, assumes that the results go into $CHEAPWATERSTARTDISTANCE and $CHEAPWATERENDDISTANCE
|
||||||
|
class CWaterLODMaterialProxy : public IMaterialProxy
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
CWaterLODMaterialProxy();
|
||||||
|
virtual ~CWaterLODMaterialProxy();
|
||||||
|
virtual bool Init( IMaterial *pMaterial, KeyValues *pKeyValues );
|
||||||
|
virtual void OnBind( void *pC_BaseEntity );
|
||||||
|
virtual void Release( void ) { delete this; }
|
||||||
|
private:
|
||||||
|
IMaterialVar *m_pCheapWaterStartDistanceVar;
|
||||||
|
IMaterialVar *m_pCheapWaterEndDistanceVar;
|
||||||
|
};
|
||||||
|
|
||||||
|
CWaterLODMaterialProxy::CWaterLODMaterialProxy()
|
||||||
|
{
|
||||||
|
m_pCheapWaterStartDistanceVar = NULL;
|
||||||
|
m_pCheapWaterEndDistanceVar = NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
CWaterLODMaterialProxy::~CWaterLODMaterialProxy()
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
bool CWaterLODMaterialProxy::Init( IMaterial *pMaterial, KeyValues *pKeyValues )
|
||||||
|
{
|
||||||
|
bool foundVar;
|
||||||
|
m_pCheapWaterStartDistanceVar = pMaterial->FindVar( "$CHEAPWATERSTARTDISTANCE", &foundVar, false );
|
||||||
|
if( !foundVar )
|
||||||
|
return false;
|
||||||
|
|
||||||
|
m_pCheapWaterEndDistanceVar = pMaterial->FindVar( "$CHEAPWATERENDDISTANCE", &foundVar, false );
|
||||||
|
if( !foundVar )
|
||||||
|
return false;
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
void CWaterLODMaterialProxy::OnBind( void *pC_BaseEntity )
|
||||||
|
{
|
||||||
|
if( !m_pCheapWaterStartDistanceVar || !m_pCheapWaterEndDistanceVar )
|
||||||
|
{
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
float start, end;
|
||||||
|
view->GetWaterLODParams( start, end );
|
||||||
|
m_pCheapWaterStartDistanceVar->SetFloatValue( start );
|
||||||
|
m_pCheapWaterEndDistanceVar->SetFloatValue( end );
|
||||||
|
}
|
||||||
|
|
||||||
|
EXPOSE_INTERFACE( CWaterLODMaterialProxy, IMaterialProxy, "WaterLOD" IMATERIAL_PROXY_INTERFACE_VERSION );
|
63
cl_dll/WorldDimsProxy.cpp
Normal file
63
cl_dll/WorldDimsProxy.cpp
Normal file
@ -0,0 +1,63 @@
|
|||||||
|
//========= Copyright © 1996-2005, Valve Corporation, All rights reserved. ============//
|
||||||
|
//
|
||||||
|
// Purpose:
|
||||||
|
//
|
||||||
|
//=============================================================================//
|
||||||
|
|
||||||
|
#include "cbase.h"
|
||||||
|
#include "materialsystem/IMaterialProxy.h"
|
||||||
|
#include "materialsystem/IMaterial.h"
|
||||||
|
#include "materialsystem/IMaterialVar.h"
|
||||||
|
#include "c_world.h"
|
||||||
|
|
||||||
|
// memdbgon must be the last include file in a .cpp file!!!
|
||||||
|
#include "tier0/memdbgon.h"
|
||||||
|
|
||||||
|
class CWorldDimsProxy : public IMaterialProxy
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
CWorldDimsProxy();
|
||||||
|
virtual ~CWorldDimsProxy();
|
||||||
|
virtual bool Init( IMaterial *pMaterial, KeyValues *pKeyValues );
|
||||||
|
virtual void OnBind( void *pC_BaseEntity );
|
||||||
|
virtual void Release( void ) { delete this; }
|
||||||
|
|
||||||
|
|
||||||
|
public:
|
||||||
|
IMaterialVar *m_pMinsVar;
|
||||||
|
IMaterialVar *m_pMaxsVar;
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
CWorldDimsProxy::CWorldDimsProxy()
|
||||||
|
{
|
||||||
|
m_pMinsVar = m_pMaxsVar = NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
CWorldDimsProxy::~CWorldDimsProxy()
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
bool CWorldDimsProxy::Init( IMaterial *pMaterial, KeyValues *pKeyValues )
|
||||||
|
{
|
||||||
|
m_pMinsVar = pMaterial->FindVar( "$world_mins", NULL, false );
|
||||||
|
m_pMaxsVar = pMaterial->FindVar( "$world_maxs", NULL, false );
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
void CWorldDimsProxy::OnBind( void *pC_BaseEntity )
|
||||||
|
{
|
||||||
|
if ( m_pMinsVar && m_pMaxsVar )
|
||||||
|
{
|
||||||
|
C_World *pWorld = GetClientWorldEntity();
|
||||||
|
if ( pWorld )
|
||||||
|
{
|
||||||
|
m_pMinsVar->SetVecValue( (const float*)&pWorld->m_WorldMins, 3 );
|
||||||
|
m_pMaxsVar->SetVecValue( (const float*)&pWorld->m_WorldMaxs, 3 );
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
EXPOSE_INTERFACE( CWorldDimsProxy, IMaterialProxy, "WorldDims" IMATERIAL_PROXY_INTERFACE_VERSION );
|
||||||
|
|
||||||
|
|
53
cl_dll/alphamaterialproxy.cpp
Normal file
53
cl_dll/alphamaterialproxy.cpp
Normal file
@ -0,0 +1,53 @@
|
|||||||
|
//========= Copyright © 1996-2005, Valve Corporation, All rights reserved. ============//
|
||||||
|
//
|
||||||
|
// Purpose:
|
||||||
|
//
|
||||||
|
// $NoKeywords: $
|
||||||
|
//=============================================================================//
|
||||||
|
#include "cbase.h"
|
||||||
|
#include "ProxyEntity.h"
|
||||||
|
#include "materialsystem/IMaterial.h"
|
||||||
|
#include "materialsystem/IMaterialVar.h"
|
||||||
|
|
||||||
|
// memdbgon must be the last include file in a .cpp file!!!
|
||||||
|
#include "tier0/memdbgon.h"
|
||||||
|
|
||||||
|
// $sineVar : name of variable that controls the alpha level (float)
|
||||||
|
class CAlphaMaterialProxy : public CEntityMaterialProxy
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
CAlphaMaterialProxy();
|
||||||
|
virtual ~CAlphaMaterialProxy();
|
||||||
|
virtual bool Init( IMaterial *pMaterial, KeyValues *pKeyValues );
|
||||||
|
virtual void OnBind( C_BaseEntity *pEntity );
|
||||||
|
|
||||||
|
private:
|
||||||
|
IMaterialVar *m_AlphaVar;
|
||||||
|
};
|
||||||
|
|
||||||
|
CAlphaMaterialProxy::CAlphaMaterialProxy()
|
||||||
|
{
|
||||||
|
m_AlphaVar = NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
CAlphaMaterialProxy::~CAlphaMaterialProxy()
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
bool CAlphaMaterialProxy::Init( IMaterial *pMaterial, KeyValues *pKeyValues )
|
||||||
|
{
|
||||||
|
bool foundVar;
|
||||||
|
m_AlphaVar = pMaterial->FindVar( "$alpha", &foundVar, false );
|
||||||
|
return foundVar;
|
||||||
|
}
|
||||||
|
|
||||||
|
void CAlphaMaterialProxy::OnBind( C_BaseEntity *pEnt )
|
||||||
|
{
|
||||||
|
if (m_AlphaVar)
|
||||||
|
{
|
||||||
|
m_AlphaVar->SetFloatValue( pEnt->m_clrRender->a );
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
EXPOSE_INTERFACE( CAlphaMaterialProxy, IMaterialProxy, "Alpha" IMATERIAL_PROXY_INTERFACE_VERSION );
|
51
cl_dll/animatedentitytextureproxy.cpp
Normal file
51
cl_dll/animatedentitytextureproxy.cpp
Normal file
@ -0,0 +1,51 @@
|
|||||||
|
//========= Copyright © 1996-2005, Valve Corporation, All rights reserved. ============//
|
||||||
|
//
|
||||||
|
// Purpose:
|
||||||
|
//
|
||||||
|
// $NoKeywords: $
|
||||||
|
//=============================================================================//
|
||||||
|
#include "cbase.h"
|
||||||
|
#include "BaseAnimatedTextureProxy.h"
|
||||||
|
|
||||||
|
// memdbgon must be the last include file in a .cpp file!!!
|
||||||
|
#include "tier0/memdbgon.h"
|
||||||
|
|
||||||
|
class CAnimatedEntityTextureProxy : public CBaseAnimatedTextureProxy
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
CAnimatedEntityTextureProxy() {}
|
||||||
|
virtual ~CAnimatedEntityTextureProxy() {}
|
||||||
|
|
||||||
|
virtual float GetAnimationStartTime( void* pBaseEntity );
|
||||||
|
virtual void AnimationWrapped( void* pC_BaseEntity );
|
||||||
|
|
||||||
|
};
|
||||||
|
|
||||||
|
EXPOSE_INTERFACE( CAnimatedEntityTextureProxy, IMaterialProxy, "AnimatedEntityTexture" IMATERIAL_PROXY_INTERFACE_VERSION );
|
||||||
|
|
||||||
|
float CAnimatedEntityTextureProxy::GetAnimationStartTime( void* pArg )
|
||||||
|
{
|
||||||
|
IClientRenderable *pRend = (IClientRenderable *)pArg;
|
||||||
|
if (!pRend)
|
||||||
|
return 0.0f;
|
||||||
|
|
||||||
|
C_BaseEntity* pEntity = pRend->GetIClientUnknown()->GetBaseEntity();
|
||||||
|
if (pEntity)
|
||||||
|
{
|
||||||
|
return pEntity->GetTextureAnimationStartTime();
|
||||||
|
}
|
||||||
|
return 0.0f;
|
||||||
|
}
|
||||||
|
|
||||||
|
void CAnimatedEntityTextureProxy::AnimationWrapped( void* pArg )
|
||||||
|
{
|
||||||
|
IClientRenderable *pRend = (IClientRenderable *)pArg;
|
||||||
|
if (!pRend)
|
||||||
|
return;
|
||||||
|
|
||||||
|
C_BaseEntity* pEntity = pRend->GetIClientUnknown()->GetBaseEntity();
|
||||||
|
if (pEntity)
|
||||||
|
{
|
||||||
|
pEntity->TextureAnimationWrapped();
|
||||||
|
}
|
||||||
|
}
|
56
cl_dll/animatedoffsettextureproxy.cpp
Normal file
56
cl_dll/animatedoffsettextureproxy.cpp
Normal file
@ -0,0 +1,56 @@
|
|||||||
|
//========= Copyright © 1996-2005, Valve Corporation, All rights reserved. ============//
|
||||||
|
//
|
||||||
|
// Purpose:
|
||||||
|
//
|
||||||
|
//=============================================================================//
|
||||||
|
|
||||||
|
#include "cbase.h"
|
||||||
|
#include "BaseAnimatedTextureProxy.h"
|
||||||
|
|
||||||
|
// memdbgon must be the last include file in a .cpp file!!!
|
||||||
|
#include "tier0/memdbgon.h"
|
||||||
|
|
||||||
|
class CAnimatedOffsetTextureProxy : public CBaseAnimatedTextureProxy
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
CAnimatedOffsetTextureProxy() : m_flFrameOffset( 0.0f ) {}
|
||||||
|
|
||||||
|
virtual ~CAnimatedOffsetTextureProxy() {}
|
||||||
|
|
||||||
|
virtual float GetAnimationStartTime( void* pBaseEntity );
|
||||||
|
virtual void OnBind( void *pBaseEntity );
|
||||||
|
|
||||||
|
protected:
|
||||||
|
|
||||||
|
float m_flFrameOffset;
|
||||||
|
};
|
||||||
|
|
||||||
|
EXPOSE_INTERFACE( CAnimatedOffsetTextureProxy, IMaterialProxy, "AnimatedOffsetTexture" IMATERIAL_PROXY_INTERFACE_VERSION );
|
||||||
|
|
||||||
|
//-----------------------------------------------------------------------------
|
||||||
|
// Purpose:
|
||||||
|
// Input : pArg -
|
||||||
|
// Output : float
|
||||||
|
//-----------------------------------------------------------------------------
|
||||||
|
float CAnimatedOffsetTextureProxy::GetAnimationStartTime( void* pArg )
|
||||||
|
{
|
||||||
|
return m_flFrameOffset;
|
||||||
|
}
|
||||||
|
|
||||||
|
//-----------------------------------------------------------------------------
|
||||||
|
// Purpose:
|
||||||
|
// Input : *pBaseEntity -
|
||||||
|
//-----------------------------------------------------------------------------
|
||||||
|
void CAnimatedOffsetTextureProxy::OnBind( void *pBaseEntity )
|
||||||
|
{
|
||||||
|
C_BaseEntity* pEntity = (C_BaseEntity*)pBaseEntity;
|
||||||
|
|
||||||
|
if ( pEntity )
|
||||||
|
{
|
||||||
|
m_flFrameOffset = pEntity->GetTextureAnimationStartTime();
|
||||||
|
}
|
||||||
|
|
||||||
|
// Call into the base class
|
||||||
|
CBaseAnimatedTextureProxy::OnBind( pBaseEntity );
|
||||||
|
}
|
||||||
|
|
29
cl_dll/animatedtextureproxy.cpp
Normal file
29
cl_dll/animatedtextureproxy.cpp
Normal file
@ -0,0 +1,29 @@
|
|||||||
|
//========= Copyright © 1996-2005, Valve Corporation, All rights reserved. ============//
|
||||||
|
//
|
||||||
|
// Purpose:
|
||||||
|
//
|
||||||
|
// $NoKeywords: $
|
||||||
|
//=============================================================================//
|
||||||
|
#include "cbase.h"
|
||||||
|
#include "BaseAnimatedTextureProxy.h"
|
||||||
|
|
||||||
|
// memdbgon must be the last include file in a .cpp file!!!
|
||||||
|
#include "tier0/memdbgon.h"
|
||||||
|
|
||||||
|
class CAnimatedTextureProxy : public CBaseAnimatedTextureProxy
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
CAnimatedTextureProxy() {}
|
||||||
|
virtual ~CAnimatedTextureProxy() {}
|
||||||
|
virtual float GetAnimationStartTime( void* pBaseEntity );
|
||||||
|
};
|
||||||
|
|
||||||
|
EXPOSE_INTERFACE( CAnimatedTextureProxy, IMaterialProxy, "AnimatedTexture" IMATERIAL_PROXY_INTERFACE_VERSION );
|
||||||
|
|
||||||
|
#pragma warning (disable : 4100)
|
||||||
|
|
||||||
|
float CAnimatedTextureProxy::GetAnimationStartTime( void* pBaseEntity )
|
||||||
|
{
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
167
cl_dll/animationlayer.h
Normal file
167
cl_dll/animationlayer.h
Normal file
@ -0,0 +1,167 @@
|
|||||||
|
//========= Copyright © 1996-2005, Valve Corporation, All rights reserved. ============//
|
||||||
|
//
|
||||||
|
// Purpose:
|
||||||
|
//
|
||||||
|
//=============================================================================//
|
||||||
|
|
||||||
|
#ifndef ANIMATIONLAYER_H
|
||||||
|
#define ANIMATIONLAYER_H
|
||||||
|
#ifdef _WIN32
|
||||||
|
#pragma once
|
||||||
|
#endif
|
||||||
|
|
||||||
|
|
||||||
|
#include "rangecheckedvar.h"
|
||||||
|
#include "lerp_functions.h"
|
||||||
|
|
||||||
|
class C_AnimationLayer
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
|
||||||
|
// This allows the datatables to access private members.
|
||||||
|
ALLOW_DATATABLES_PRIVATE_ACCESS();
|
||||||
|
|
||||||
|
C_AnimationLayer();
|
||||||
|
|
||||||
|
void SetOrder( int order );
|
||||||
|
|
||||||
|
public:
|
||||||
|
|
||||||
|
bool IsActive( void );
|
||||||
|
|
||||||
|
CRangeCheckedVar<int, -1, 2048, 0> m_nSequence;
|
||||||
|
CRangeCheckedVar<float, -2, 2, 0> m_flPrevCycle;
|
||||||
|
CRangeCheckedVar<float, -5, 5, 0> m_flWeight;
|
||||||
|
int m_nOrder;
|
||||||
|
|
||||||
|
// used for automatic crossfades between sequence changes
|
||||||
|
CRangeCheckedVar<float, -50, 50, 1> m_flPlaybackRate;
|
||||||
|
CRangeCheckedVar<float, -2, 2, 0> m_flCycle;
|
||||||
|
|
||||||
|
float GetFadeout( float flCurTime );
|
||||||
|
|
||||||
|
float m_flLayerAnimtime;
|
||||||
|
float m_flLayerFadeOuttime;
|
||||||
|
};
|
||||||
|
#ifdef CLIENT_DLL
|
||||||
|
#define CAnimationLayer C_AnimationLayer
|
||||||
|
#endif
|
||||||
|
|
||||||
|
|
||||||
|
inline C_AnimationLayer::C_AnimationLayer()
|
||||||
|
{
|
||||||
|
m_nSequence = 0;
|
||||||
|
m_flPrevCycle = 0;
|
||||||
|
m_flWeight = 0;
|
||||||
|
m_flPlaybackRate = 0;
|
||||||
|
m_flCycle = 0;
|
||||||
|
m_flLayerAnimtime = 0;
|
||||||
|
m_flLayerFadeOuttime = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
inline void C_AnimationLayer::SetOrder( int order )
|
||||||
|
{
|
||||||
|
m_nOrder = order;
|
||||||
|
}
|
||||||
|
|
||||||
|
inline float C_AnimationLayer::GetFadeout( float flCurTime )
|
||||||
|
{
|
||||||
|
float s;
|
||||||
|
|
||||||
|
if (m_flLayerFadeOuttime <= 0.0f)
|
||||||
|
{
|
||||||
|
s = 0;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
// blend in over 0.2 seconds
|
||||||
|
s = 1.0 - (flCurTime - m_flLayerAnimtime) / m_flLayerFadeOuttime;
|
||||||
|
if (s > 0 && s <= 1.0)
|
||||||
|
{
|
||||||
|
// do a nice spline curve
|
||||||
|
s = 3 * s * s - 2 * s * s * s;
|
||||||
|
}
|
||||||
|
else if ( s > 1.0f )
|
||||||
|
{
|
||||||
|
// Shouldn't happen, but maybe curtime is behind animtime?
|
||||||
|
s = 1.0f;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return s;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
inline C_AnimationLayer LoopingLerp( float flPercent, C_AnimationLayer from, C_AnimationLayer to )
|
||||||
|
{
|
||||||
|
C_AnimationLayer output;
|
||||||
|
|
||||||
|
output.m_nSequence = to.m_nSequence;
|
||||||
|
output.m_flCycle = LoopingLerp( flPercent, (float)from.m_flCycle, (float)to.m_flCycle );
|
||||||
|
output.m_flPrevCycle = to.m_flPrevCycle;
|
||||||
|
output.m_flWeight = Lerp( flPercent, from.m_flWeight, to.m_flWeight );
|
||||||
|
output.m_nOrder = to.m_nOrder;
|
||||||
|
|
||||||
|
output.m_flLayerAnimtime = to.m_flLayerAnimtime;
|
||||||
|
output.m_flLayerFadeOuttime = to.m_flLayerFadeOuttime;
|
||||||
|
return output;
|
||||||
|
}
|
||||||
|
|
||||||
|
inline C_AnimationLayer Lerp( float flPercent, const C_AnimationLayer& from, const C_AnimationLayer& to )
|
||||||
|
{
|
||||||
|
C_AnimationLayer output;
|
||||||
|
|
||||||
|
output.m_nSequence = to.m_nSequence;
|
||||||
|
output.m_flCycle = Lerp( flPercent, from.m_flCycle, to.m_flCycle );
|
||||||
|
output.m_flPrevCycle = to.m_flPrevCycle;
|
||||||
|
output.m_flWeight = Lerp( flPercent, from.m_flWeight, to.m_flWeight );
|
||||||
|
output.m_nOrder = to.m_nOrder;
|
||||||
|
|
||||||
|
output.m_flLayerAnimtime = to.m_flLayerAnimtime;
|
||||||
|
output.m_flLayerFadeOuttime = to.m_flLayerFadeOuttime;
|
||||||
|
return output;
|
||||||
|
}
|
||||||
|
|
||||||
|
inline C_AnimationLayer LoopingLerp_Hermite( float flPercent, C_AnimationLayer prev, C_AnimationLayer from, C_AnimationLayer to )
|
||||||
|
{
|
||||||
|
C_AnimationLayer output;
|
||||||
|
|
||||||
|
output.m_nSequence = to.m_nSequence;
|
||||||
|
output.m_flCycle = LoopingLerp_Hermite( flPercent, (float)prev.m_flCycle, (float)from.m_flCycle, (float)to.m_flCycle );
|
||||||
|
output.m_flPrevCycle = to.m_flPrevCycle;
|
||||||
|
output.m_flWeight = Lerp( flPercent, from.m_flWeight, to.m_flWeight );
|
||||||
|
output.m_nOrder = to.m_nOrder;
|
||||||
|
|
||||||
|
output.m_flLayerAnimtime = to.m_flLayerAnimtime;
|
||||||
|
output.m_flLayerFadeOuttime = to.m_flLayerFadeOuttime;
|
||||||
|
return output;
|
||||||
|
}
|
||||||
|
|
||||||
|
// YWB: Specialization for interpolating euler angles via quaternions...
|
||||||
|
inline C_AnimationLayer Lerp_Hermite( float flPercent, const C_AnimationLayer& prev, const C_AnimationLayer& from, const C_AnimationLayer& to )
|
||||||
|
{
|
||||||
|
C_AnimationLayer output;
|
||||||
|
|
||||||
|
output.m_nSequence = to.m_nSequence;
|
||||||
|
output.m_flCycle = Lerp_Hermite( flPercent, prev.m_flCycle, from.m_flCycle, to.m_flCycle );
|
||||||
|
output.m_flPrevCycle = to.m_flPrevCycle;
|
||||||
|
output.m_flWeight = Lerp( flPercent, from.m_flWeight, to.m_flWeight );
|
||||||
|
output.m_nOrder = to.m_nOrder;
|
||||||
|
|
||||||
|
output.m_flLayerAnimtime = to.m_flLayerAnimtime;
|
||||||
|
output.m_flLayerFadeOuttime = to.m_flLayerFadeOuttime;
|
||||||
|
return output;
|
||||||
|
}
|
||||||
|
|
||||||
|
inline void Lerp_Clamp( C_AnimationLayer &val )
|
||||||
|
{
|
||||||
|
Lerp_Clamp( val.m_nSequence );
|
||||||
|
Lerp_Clamp( val.m_flCycle );
|
||||||
|
Lerp_Clamp( val.m_flPrevCycle );
|
||||||
|
Lerp_Clamp( val.m_flWeight );
|
||||||
|
Lerp_Clamp( val.m_nOrder );
|
||||||
|
Lerp_Clamp( val.m_flLayerAnimtime );
|
||||||
|
Lerp_Clamp( val.m_flLayerFadeOuttime );
|
||||||
|
}
|
||||||
|
|
||||||
|
#endif // ANIMATIONLAYER_H
|
124
cl_dll/baseanimatedtextureproxy.cpp
Normal file
124
cl_dll/baseanimatedtextureproxy.cpp
Normal file
@ -0,0 +1,124 @@
|
|||||||
|
//========= Copyright © 1996-2005, Valve Corporation, All rights reserved. ============//
|
||||||
|
//
|
||||||
|
// Purpose:
|
||||||
|
//
|
||||||
|
// $NoKeywords: $
|
||||||
|
//=============================================================================//
|
||||||
|
#include "cbase.h"
|
||||||
|
#include "BaseAnimatedTextureProxy.h"
|
||||||
|
#include "materialsystem/IMaterial.h"
|
||||||
|
#include "materialsystem/IMaterialVar.h"
|
||||||
|
#include "materialsystem/ITexture.h"
|
||||||
|
#include <KeyValues.h>
|
||||||
|
|
||||||
|
// memdbgon must be the last include file in a .cpp file!!!
|
||||||
|
#include "tier0/memdbgon.h"
|
||||||
|
|
||||||
|
//-----------------------------------------------------------------------------
|
||||||
|
// Constructor, destructor:
|
||||||
|
//-----------------------------------------------------------------------------
|
||||||
|
|
||||||
|
CBaseAnimatedTextureProxy::CBaseAnimatedTextureProxy()
|
||||||
|
{
|
||||||
|
Cleanup();
|
||||||
|
}
|
||||||
|
|
||||||
|
CBaseAnimatedTextureProxy::~CBaseAnimatedTextureProxy()
|
||||||
|
{
|
||||||
|
Cleanup();
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
//-----------------------------------------------------------------------------
|
||||||
|
// Initialization, shutdown
|
||||||
|
//-----------------------------------------------------------------------------
|
||||||
|
bool CBaseAnimatedTextureProxy::Init( IMaterial *pMaterial, KeyValues *pKeyValues )
|
||||||
|
{
|
||||||
|
char const* pAnimatedTextureVarName = pKeyValues->GetString( "animatedTextureVar" );
|
||||||
|
if( !pAnimatedTextureVarName )
|
||||||
|
return false;
|
||||||
|
|
||||||
|
bool foundVar;
|
||||||
|
m_AnimatedTextureVar = pMaterial->FindVar( pAnimatedTextureVarName, &foundVar, false );
|
||||||
|
if( !foundVar )
|
||||||
|
return false;
|
||||||
|
|
||||||
|
char const* pAnimatedTextureFrameNumVarName = pKeyValues->GetString( "animatedTextureFrameNumVar" );
|
||||||
|
if( !pAnimatedTextureFrameNumVarName )
|
||||||
|
return false;
|
||||||
|
|
||||||
|
m_AnimatedTextureFrameNumVar = pMaterial->FindVar( pAnimatedTextureFrameNumVarName, &foundVar, false );
|
||||||
|
if( !foundVar )
|
||||||
|
return false;
|
||||||
|
|
||||||
|
m_FrameRate = pKeyValues->GetFloat( "animatedTextureFrameRate", 15 );
|
||||||
|
m_WrapAnimation = !pKeyValues->GetInt( "animationNoWrap", 0 );
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
void CBaseAnimatedTextureProxy::Cleanup()
|
||||||
|
{
|
||||||
|
m_AnimatedTextureVar = NULL;
|
||||||
|
m_AnimatedTextureFrameNumVar = NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
//-----------------------------------------------------------------------------
|
||||||
|
// Does the dirty deed
|
||||||
|
//-----------------------------------------------------------------------------
|
||||||
|
void CBaseAnimatedTextureProxy::OnBind( void *pEntity )
|
||||||
|
{
|
||||||
|
Assert ( m_AnimatedTextureVar );
|
||||||
|
|
||||||
|
if( m_AnimatedTextureVar->GetType() != MATERIAL_VAR_TYPE_TEXTURE )
|
||||||
|
{
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
ITexture *pTexture;
|
||||||
|
pTexture = m_AnimatedTextureVar->GetTextureValue();
|
||||||
|
int numFrames = pTexture->GetNumAnimationFrames();
|
||||||
|
|
||||||
|
if ( numFrames <= 0 )
|
||||||
|
{
|
||||||
|
Assert( !"0 frames in material calling animated texture proxy" );
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
// NOTE: Must not use relative time based methods here
|
||||||
|
// because the bind proxy can be called many times per frame.
|
||||||
|
// Prevent multiple Wrap callbacks to be sent for no wrap mode
|
||||||
|
float startTime = GetAnimationStartTime(pEntity);
|
||||||
|
float deltaTime = gpGlobals->curtime - startTime;
|
||||||
|
float prevTime = deltaTime - gpGlobals->frametime;
|
||||||
|
|
||||||
|
// Clamp..
|
||||||
|
if (deltaTime < 0.0f)
|
||||||
|
deltaTime = 0.0f;
|
||||||
|
if (prevTime < 0.0f)
|
||||||
|
prevTime = 0.0f;
|
||||||
|
|
||||||
|
float frame = m_FrameRate * deltaTime;
|
||||||
|
float prevFrame = m_FrameRate * prevTime;
|
||||||
|
|
||||||
|
int intFrame = ((int)frame) % numFrames;
|
||||||
|
int intPrevFrame = ((int)prevFrame) % numFrames;
|
||||||
|
|
||||||
|
// Report wrap situation...
|
||||||
|
if (intPrevFrame > intFrame)
|
||||||
|
{
|
||||||
|
if (m_WrapAnimation)
|
||||||
|
{
|
||||||
|
AnimationWrapped( pEntity );
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
// Only sent the wrapped message once.
|
||||||
|
// when we're in non-wrapping mode
|
||||||
|
if (prevFrame < numFrames)
|
||||||
|
AnimationWrapped( pEntity );
|
||||||
|
intFrame = numFrames - 1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
m_AnimatedTextureFrameNumVar->SetIntValue( intFrame );
|
||||||
|
}
|
46
cl_dll/baseanimatedtextureproxy.h
Normal file
46
cl_dll/baseanimatedtextureproxy.h
Normal file
@ -0,0 +1,46 @@
|
|||||||
|
//========= Copyright © 1996-2005, Valve Corporation, All rights reserved. ============//
|
||||||
|
//
|
||||||
|
// Purpose:
|
||||||
|
//
|
||||||
|
// $NoKeywords: $
|
||||||
|
//=============================================================================//
|
||||||
|
|
||||||
|
#ifndef BASEANIMATEDTEXTUREPROXY
|
||||||
|
#define BASEANIMATEDTEXTUREPROXY
|
||||||
|
|
||||||
|
#include "materialsystem/IMaterialProxy.h"
|
||||||
|
|
||||||
|
class IMaterial;
|
||||||
|
class IMaterialVar;
|
||||||
|
|
||||||
|
#pragma warning (disable : 4100)
|
||||||
|
|
||||||
|
class CBaseAnimatedTextureProxy : public IMaterialProxy
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
CBaseAnimatedTextureProxy();
|
||||||
|
virtual ~CBaseAnimatedTextureProxy();
|
||||||
|
|
||||||
|
virtual bool Init( IMaterial *pMaterial, KeyValues *pKeyValues );
|
||||||
|
virtual void OnBind( void *pC_BaseEntity );
|
||||||
|
virtual void Release( void ) { delete this; }
|
||||||
|
|
||||||
|
protected:
|
||||||
|
// derived classes must implement this; it returns the time
|
||||||
|
// that the animation began
|
||||||
|
virtual float GetAnimationStartTime( void* pBaseEntity ) = 0;
|
||||||
|
|
||||||
|
// Derived classes may implement this if they choose;
|
||||||
|
// this method is called whenever the animation wraps...
|
||||||
|
virtual void AnimationWrapped( void* pBaseEntity ) {}
|
||||||
|
|
||||||
|
protected:
|
||||||
|
void Cleanup();
|
||||||
|
|
||||||
|
IMaterialVar *m_AnimatedTextureVar;
|
||||||
|
IMaterialVar *m_AnimatedTextureFrameNumVar;
|
||||||
|
float m_FrameRate;
|
||||||
|
bool m_WrapAnimation;
|
||||||
|
};
|
||||||
|
|
||||||
|
#endif // BASEANIMATEDTEXTUREPROXY
|
81
cl_dll/baseclientrendertargets.cpp
Normal file
81
cl_dll/baseclientrendertargets.cpp
Normal file
@ -0,0 +1,81 @@
|
|||||||
|
//========= Copyright © 1996-2005, Valve Corporation, All rights reserved. ============//
|
||||||
|
//
|
||||||
|
// Purpose: Implementation for CBaseClientRenderTargets class.
|
||||||
|
// Provides Init functions for common render textures used by the engine.
|
||||||
|
// Mod makers can inherit from this class, and call the Create functions for
|
||||||
|
// only the render textures the want for their mod.
|
||||||
|
//
|
||||||
|
// $NoKeywords: $
|
||||||
|
//=============================================================================//
|
||||||
|
#include "cbase.h"
|
||||||
|
#include "baseclientrendertargets.h" // header
|
||||||
|
#include "materialsystem/imaterialsystemhardwareconfig.h" // Hardware config checks
|
||||||
|
|
||||||
|
|
||||||
|
ITexture* CBaseClientRenderTargets::CreateWaterReflectionTexture( IMaterialSystem* pMaterialSystem )
|
||||||
|
{
|
||||||
|
return pMaterialSystem->CreateNamedRenderTargetTextureEx2(
|
||||||
|
"_rt_WaterReflection",
|
||||||
|
1024, 1024, RT_SIZE_PICMIP,
|
||||||
|
pMaterialSystem->GetBackBufferFormat(),
|
||||||
|
MATERIAL_RT_DEPTH_SHARED,
|
||||||
|
TEXTUREFLAGS_CLAMPS | TEXTUREFLAGS_CLAMPT,
|
||||||
|
CREATERENDERTARGETFLAGS_HDR );
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
ITexture* CBaseClientRenderTargets::CreateWaterRefractionTexture( IMaterialSystem* pMaterialSystem )
|
||||||
|
{
|
||||||
|
return pMaterialSystem->CreateNamedRenderTargetTextureEx2(
|
||||||
|
"_rt_WaterRefraction",
|
||||||
|
1024, 1024, RT_SIZE_PICMIP,
|
||||||
|
// This is different than reflection because it has to have alpha for fog factor.
|
||||||
|
IMAGE_FORMAT_RGBA8888,
|
||||||
|
MATERIAL_RT_DEPTH_SHARED,
|
||||||
|
TEXTUREFLAGS_CLAMPS | TEXTUREFLAGS_CLAMPT,
|
||||||
|
CREATERENDERTARGETFLAGS_HDR );
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
ITexture* CBaseClientRenderTargets::CreateCameraTexture( IMaterialSystem* pMaterialSystem )
|
||||||
|
{
|
||||||
|
return pMaterialSystem->CreateNamedRenderTargetTextureEx2(
|
||||||
|
"_rt_Camera",
|
||||||
|
256, 256, RT_SIZE_DEFAULT,
|
||||||
|
pMaterialSystem->GetBackBufferFormat(),
|
||||||
|
MATERIAL_RT_DEPTH_SHARED,
|
||||||
|
0,
|
||||||
|
CREATERENDERTARGETFLAGS_HDR );
|
||||||
|
}
|
||||||
|
|
||||||
|
//-----------------------------------------------------------------------------
|
||||||
|
// Purpose: Called by the engine in material system init and shutdown.
|
||||||
|
// Clients should override this in their inherited version, but the base
|
||||||
|
// is to init all standard render targets for use.
|
||||||
|
// Input : pMaterialSystem - the engine's material system (our singleton is not yet inited at the time this is called)
|
||||||
|
// pHardwareConfig - the user hardware config, useful for conditional render target setup
|
||||||
|
//-----------------------------------------------------------------------------
|
||||||
|
void CBaseClientRenderTargets::InitClientRenderTargets( IMaterialSystem* pMaterialSystem, IMaterialSystemHardwareConfig* pHardwareConfig )
|
||||||
|
{
|
||||||
|
// Water effects
|
||||||
|
m_WaterReflectionTexture.Init( CreateWaterReflectionTexture( pMaterialSystem ) );
|
||||||
|
m_WaterRefractionTexture.Init ( CreateWaterRefractionTexture( pMaterialSystem ) );
|
||||||
|
|
||||||
|
// Monitors
|
||||||
|
m_CameraTexture.Init ( CreateCameraTexture( pMaterialSystem ) );
|
||||||
|
}
|
||||||
|
|
||||||
|
//-----------------------------------------------------------------------------
|
||||||
|
// Purpose: Shut down each CTextureReference we created in InitClientRenderTargets.
|
||||||
|
// Called by the engine in material system shutdown.
|
||||||
|
// Input : -
|
||||||
|
//-----------------------------------------------------------------------------
|
||||||
|
void CBaseClientRenderTargets::ShutdownClientRenderTargets()
|
||||||
|
{
|
||||||
|
// Water effects
|
||||||
|
m_WaterReflectionTexture.Shutdown();
|
||||||
|
m_WaterRefractionTexture.Shutdown();
|
||||||
|
|
||||||
|
// Monitors
|
||||||
|
m_CameraTexture.Shutdown();
|
||||||
|
}
|
61
cl_dll/baseclientrendertargets.h
Normal file
61
cl_dll/baseclientrendertargets.h
Normal file
@ -0,0 +1,61 @@
|
|||||||
|
//========= Copyright © 1996-2005, Valve Corporation, All rights reserved. ============//
|
||||||
|
//
|
||||||
|
// Purpose: Has init functions for all the standard render targets used by most games.
|
||||||
|
// Mods who wish to make their own render targets can inherit from this class
|
||||||
|
// and in the 'InitClientRenderTargets' interface called by the engine, set up
|
||||||
|
// their own render targets as well as calling the init functions for various
|
||||||
|
// common render targets provided by this class.
|
||||||
|
//
|
||||||
|
// Note: Unless the client defines a singleton interface by inheriting from
|
||||||
|
// this class and exposing the singleton instance, these init and shutdown
|
||||||
|
// functions WILL NOT be called by the engine.
|
||||||
|
//
|
||||||
|
//
|
||||||
|
// $Workfile: $
|
||||||
|
// $Date: $
|
||||||
|
// $NoKeywords: $
|
||||||
|
//=============================================================================//
|
||||||
|
#ifndef CLIENTRENDERTARTETS_H_
|
||||||
|
#define CLIENTRENDERTARTETS_H_
|
||||||
|
#ifdef _WIN32
|
||||||
|
#pragma once
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#include "cl_dll\iclientrendertargets.h" // base class with interfaces called by the engine
|
||||||
|
#include "materialsystem\imaterialsystem.h" // for material system classes and interfaces
|
||||||
|
|
||||||
|
|
||||||
|
// Externs
|
||||||
|
class IMaterialSystem;
|
||||||
|
class IMaterialSystemHardwareConfig;
|
||||||
|
|
||||||
|
class CBaseClientRenderTargets : public IClientRenderTargets
|
||||||
|
{
|
||||||
|
// no networked vars
|
||||||
|
DECLARE_CLASS_GAMEROOT( CBaseClientRenderTargets, IClientRenderTargets );
|
||||||
|
public:
|
||||||
|
// Interface called by engine during material system startup.
|
||||||
|
virtual void InitClientRenderTargets ( IMaterialSystem* pMaterialSystem, IMaterialSystemHardwareConfig* pHardwareConfig );
|
||||||
|
// Shutdown all custom render targets here.
|
||||||
|
virtual void ShutdownClientRenderTargets ( void );
|
||||||
|
|
||||||
|
protected:
|
||||||
|
|
||||||
|
// Standard render textures used by most mods-- Classes inheriting from
|
||||||
|
// this can choose to init these or not depending on their needs.
|
||||||
|
|
||||||
|
// For reflective and refracting water
|
||||||
|
CTextureReference m_WaterReflectionTexture;
|
||||||
|
CTextureReference m_WaterRefractionTexture;
|
||||||
|
|
||||||
|
// Used for monitors
|
||||||
|
CTextureReference m_CameraTexture;
|
||||||
|
|
||||||
|
// Init functions for the common render targets
|
||||||
|
ITexture* CreateWaterReflectionTexture( IMaterialSystem* pMaterialSystem );
|
||||||
|
ITexture* CreateWaterRefractionTexture( IMaterialSystem* pMaterialSystem );
|
||||||
|
ITexture* CreateCameraTexture( IMaterialSystem* pMaterialSystem );
|
||||||
|
|
||||||
|
};
|
||||||
|
|
||||||
|
#endif // CLIENTRENDERTARTETS_H_
|
1733
cl_dll/beamdraw.cpp
Normal file
1733
cl_dll/beamdraw.cpp
Normal file
File diff suppressed because it is too large
Load Diff
219
cl_dll/beamdraw.h
Normal file
219
cl_dll/beamdraw.h
Normal file
@ -0,0 +1,219 @@
|
|||||||
|
//========= Copyright © 1996-2005, Valve Corporation, All rights reserved. ============//
|
||||||
|
//
|
||||||
|
// Purpose:
|
||||||
|
//
|
||||||
|
// $NoKeywords: $
|
||||||
|
//=============================================================================//
|
||||||
|
#if !defined( BEAMDRAW_H )
|
||||||
|
#define BEAMDRAW_H
|
||||||
|
#ifdef _WIN32
|
||||||
|
#pragma once
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#include "materialsystem/imaterial.h"
|
||||||
|
#include "materialsystem/imesh.h"
|
||||||
|
#include "vector.h"
|
||||||
|
#include "c_pixel_visibility.h"
|
||||||
|
|
||||||
|
#define NOISE_DIVISIONS 128
|
||||||
|
|
||||||
|
//-----------------------------------------------------------------------------
|
||||||
|
// Forward declarations
|
||||||
|
//-----------------------------------------------------------------------------
|
||||||
|
|
||||||
|
struct model_t;
|
||||||
|
struct BeamTrail_t;
|
||||||
|
|
||||||
|
//-----------------------------------------------------------------------------
|
||||||
|
// Purpose: Beams fill out this data structure
|
||||||
|
// This is also used for rendering
|
||||||
|
//-----------------------------------------------------------------------------
|
||||||
|
|
||||||
|
class Beam_t : public CDefaultClientRenderable
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
Beam_t();
|
||||||
|
|
||||||
|
// Methods of IClientRenderable
|
||||||
|
virtual const Vector& GetRenderOrigin( void );
|
||||||
|
virtual const QAngle& GetRenderAngles( void );
|
||||||
|
virtual const matrix3x4_t &RenderableToWorldTransform();
|
||||||
|
virtual void GetRenderBounds( Vector& mins, Vector& maxs );
|
||||||
|
virtual bool ShouldDraw( void );
|
||||||
|
virtual bool IsTransparent( void );
|
||||||
|
virtual int DrawModel( int flags );
|
||||||
|
virtual void ComputeFxBlend( );
|
||||||
|
virtual int GetFxBlend( );
|
||||||
|
|
||||||
|
// Resets the beam state
|
||||||
|
void Reset();
|
||||||
|
|
||||||
|
// Method to computing the bounding box
|
||||||
|
void ComputeBounds();
|
||||||
|
|
||||||
|
// Bounding box...
|
||||||
|
Vector m_Mins;
|
||||||
|
Vector m_Maxs;
|
||||||
|
pixelvis_handle_t *m_queryHandleHalo;
|
||||||
|
float m_haloProxySize;
|
||||||
|
|
||||||
|
// Data is below..
|
||||||
|
|
||||||
|
// Next beam in list
|
||||||
|
Beam_t* next;
|
||||||
|
|
||||||
|
// Type of beam
|
||||||
|
int type;
|
||||||
|
int flags;
|
||||||
|
|
||||||
|
// Control points for the beam
|
||||||
|
int numAttachments;
|
||||||
|
Vector attachment[MAX_BEAM_ENTS];
|
||||||
|
Vector delta;
|
||||||
|
|
||||||
|
// 0 .. 1 over lifetime of beam
|
||||||
|
float t;
|
||||||
|
float freq;
|
||||||
|
|
||||||
|
// Time when beam should die
|
||||||
|
float die;
|
||||||
|
float width;
|
||||||
|
float endWidth;
|
||||||
|
float fadeLength;
|
||||||
|
float amplitude;
|
||||||
|
float life;
|
||||||
|
|
||||||
|
// Color
|
||||||
|
float r, g, b;
|
||||||
|
float brightness;
|
||||||
|
|
||||||
|
// Speed
|
||||||
|
float speed;
|
||||||
|
|
||||||
|
// Animation
|
||||||
|
float frameRate;
|
||||||
|
float frame;
|
||||||
|
int segments;
|
||||||
|
|
||||||
|
// Attachment entities for the beam
|
||||||
|
EHANDLE entity[MAX_BEAM_ENTS];
|
||||||
|
int attachmentIndex[MAX_BEAM_ENTS];
|
||||||
|
|
||||||
|
// Model info
|
||||||
|
int modelIndex;
|
||||||
|
int haloIndex;
|
||||||
|
|
||||||
|
float haloScale;
|
||||||
|
int frameCount;
|
||||||
|
|
||||||
|
float rgNoise[NOISE_DIVISIONS+1];
|
||||||
|
|
||||||
|
// Popcorn trail for beam follows to use
|
||||||
|
BeamTrail_t* trail;
|
||||||
|
|
||||||
|
// for TE_BEAMRINGPOINT
|
||||||
|
float start_radius;
|
||||||
|
float end_radius;
|
||||||
|
|
||||||
|
// for FBEAM_ONLYNOISEONCE
|
||||||
|
bool m_bCalculatedNoise;
|
||||||
|
|
||||||
|
float m_flHDRColorScale;
|
||||||
|
};
|
||||||
|
|
||||||
|
// ---------------------------------------------------------------- //
|
||||||
|
// CBeamSegDraw is a simple interface to beam rendering.
|
||||||
|
// ---------------------------------------------------------------- //
|
||||||
|
class CBeamSeg
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
Vector m_vPos;
|
||||||
|
Vector m_vColor;
|
||||||
|
float m_flTexCoord; // Y texture coordinate
|
||||||
|
float m_flWidth;
|
||||||
|
float m_flAlpha;
|
||||||
|
};
|
||||||
|
|
||||||
|
class CBeamSegDraw
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
// Pass null for pMaterial if you have already set the material you want.
|
||||||
|
void Start( int nSegs, IMaterial *pMaterial=0, CMeshBuilder *pMeshBuilder = NULL, int nMeshVertCount = 0 );
|
||||||
|
virtual void NextSeg( CBeamSeg *pSeg );
|
||||||
|
void End();
|
||||||
|
|
||||||
|
protected:
|
||||||
|
|
||||||
|
void SpecifySeg( const Vector &vNextPos );
|
||||||
|
void ComputeNormal( const Vector &vStartPos, const Vector &vNextPos, Vector *pNormal );
|
||||||
|
|
||||||
|
CMeshBuilder *m_pMeshBuilder;
|
||||||
|
int m_nMeshVertCount;
|
||||||
|
|
||||||
|
CMeshBuilder m_Mesh;
|
||||||
|
CBeamSeg m_Seg;
|
||||||
|
|
||||||
|
int m_nTotalSegs;
|
||||||
|
int m_nSegsDrawn;
|
||||||
|
|
||||||
|
Vector m_vNormalLast;
|
||||||
|
};
|
||||||
|
|
||||||
|
class CBeamSegDrawArbitrary : public CBeamSegDraw
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
|
||||||
|
void SetNormal( const Vector &normal );
|
||||||
|
|
||||||
|
void NextSeg( CBeamSeg *pSeg );
|
||||||
|
|
||||||
|
protected:
|
||||||
|
|
||||||
|
CBeamSeg m_PrevSeg;
|
||||||
|
|
||||||
|
void SpecifySeg( const Vector &vNextPos );
|
||||||
|
};
|
||||||
|
|
||||||
|
int ScreenTransform( const Vector& point, Vector& screen );
|
||||||
|
|
||||||
|
void DrawSegs( int noise_divisions, float *prgNoise, const model_t* spritemodel,
|
||||||
|
float frame, int rendermode, const Vector& source, const Vector& delta,
|
||||||
|
float startWidth, float endWidth, float scale, float freq, float speed, int segments,
|
||||||
|
int flags, float* color, float fadeLength, float flHDRColorScale = 1.0f );
|
||||||
|
void DrawTeslaSegs( int noise_divisions, float *prgNoise, const model_t* spritemodel,
|
||||||
|
float frame, int rendermode, const Vector& source, const Vector& delta,
|
||||||
|
float startWidth, float endWidth, float scale, float freq, float speed, int segments,
|
||||||
|
int flags, float* color, float fadeLength, float flHDRColorScale = 1.0f );
|
||||||
|
void DrawSplineSegs( int noise_divisions, float *prgNoise,
|
||||||
|
const model_t* beammodel, const model_t* halomodel, float flHaloScale,
|
||||||
|
float frame, int rendermode, int numAttachments, Vector* attachment,
|
||||||
|
float startWidth, float endWidth, float scale, float freq, float speed, int segments,
|
||||||
|
int flags, float* color, float fadeLength, float flHDRColorScale = 1.0f );
|
||||||
|
void DrawHalo(IMaterial* pMaterial, const Vector& source, float scale, float const* color, float flHDRColorScale = 1.0f );
|
||||||
|
void BeamDrawHalo( const model_t* spritemodel, float frame, int rendermode, const Vector& source,
|
||||||
|
float scale, float* color, float flHDRColorScale = 1.0f );
|
||||||
|
void DrawDisk( int noise_divisions, float *prgNoise, const model_t* spritemodel,
|
||||||
|
float frame, int rendermode, const Vector& source, const Vector& delta,
|
||||||
|
float width, float scale, float freq, float speed,
|
||||||
|
int segments, float* color, float flHDRColorScale = 1.0f );
|
||||||
|
void DrawCylinder( int noise_divisions, float *prgNoise, const model_t* spritemodel,
|
||||||
|
float frame, int rendermode, const Vector& source,
|
||||||
|
const Vector& delta, float width, float scale, float freq,
|
||||||
|
float speed, int segments, float* color, float flHDRColorScale = 1.0f );
|
||||||
|
void DrawRing( int noise_divisions, float *prgNoise, void (*pfnNoise)( float *noise, int divs, float scale ),
|
||||||
|
const model_t* spritemodel, float frame, int rendermode,
|
||||||
|
const Vector& source, const Vector& delta, float width, float amplitude,
|
||||||
|
float freq, float speed, int segments, float* color, float flHDRColorScale = 1.0f );
|
||||||
|
void DrawBeamFollow( const model_t* spritemodel, BeamTrail_t* pHead, int frame, int rendermode, Vector& delta,
|
||||||
|
Vector& screen, Vector& screenLast, float die, const Vector& source,
|
||||||
|
int flags, float width, float amplitude, float freq, float* color, float flHDRColorScale = 1.0f );
|
||||||
|
|
||||||
|
void DrawBeamQuadratic( const Vector &start, const Vector &control, const Vector &end, float width, const Vector &color, float scrollOffset, float flHDRColorScale = 1.0f );
|
||||||
|
class CEngineSprite *Draw_SetSpriteTexture( const model_t *pSpriteModel, int frame, int rendermode );
|
||||||
|
|
||||||
|
//-----------------------------------------------------------------------------
|
||||||
|
// Assumes the material has already been bound
|
||||||
|
//-----------------------------------------------------------------------------
|
||||||
|
void DrawSprite( const Vector &vecOrigin, float flWidth, float flHeight, color32 color );
|
||||||
|
|
||||||
|
#endif // BEAMDRAW_H
|
164
cl_dll/bone_merge_cache.cpp
Normal file
164
cl_dll/bone_merge_cache.cpp
Normal file
@ -0,0 +1,164 @@
|
|||||||
|
//========= Copyright © 1996-2005, Valve Corporation, All rights reserved. ============//
|
||||||
|
//
|
||||||
|
// Purpose:
|
||||||
|
//
|
||||||
|
// $NoKeywords: $
|
||||||
|
//
|
||||||
|
//=============================================================================//
|
||||||
|
|
||||||
|
#include "cbase.h"
|
||||||
|
#include "bone_merge_cache.h"
|
||||||
|
#include "bone_setup.h"
|
||||||
|
|
||||||
|
// memdbgon must be the last include file in a .cpp file!!!
|
||||||
|
#include "tier0/memdbgon.h"
|
||||||
|
|
||||||
|
//-----------------------------------------------------------------------------
|
||||||
|
// CBoneMergeCache
|
||||||
|
//-----------------------------------------------------------------------------
|
||||||
|
|
||||||
|
CBoneMergeCache::CBoneMergeCache()
|
||||||
|
{
|
||||||
|
m_pOwner = NULL;
|
||||||
|
m_pFollow = NULL;
|
||||||
|
m_pFollowHdr = NULL;
|
||||||
|
m_pOwnerHdr = NULL;
|
||||||
|
m_nFollowBoneSetupMask = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
void CBoneMergeCache::Init( C_BaseAnimating *pOwner )
|
||||||
|
{
|
||||||
|
m_pOwner = pOwner;
|
||||||
|
m_pFollow = NULL;
|
||||||
|
m_pFollowHdr = NULL;
|
||||||
|
m_pOwnerHdr = NULL;
|
||||||
|
m_nFollowBoneSetupMask = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
void CBoneMergeCache::UpdateCache()
|
||||||
|
{
|
||||||
|
if ( !m_pOwner )
|
||||||
|
return;
|
||||||
|
|
||||||
|
CStudioHdr *pOwnerHdr = m_pOwner->GetModelPtr();
|
||||||
|
if ( !pOwnerHdr )
|
||||||
|
return;
|
||||||
|
|
||||||
|
C_BaseAnimating *pTestFollow = m_pOwner->FindFollowedEntity();
|
||||||
|
CStudioHdr *pTestHdr = (pTestFollow ? pTestFollow->GetModelPtr() : NULL);
|
||||||
|
if ( pTestFollow != m_pFollow || pTestHdr != m_pFollowHdr || pOwnerHdr != m_pOwnerHdr )
|
||||||
|
{
|
||||||
|
m_MergedBones.Purge();
|
||||||
|
m_BoneMergeBits.Purge();
|
||||||
|
|
||||||
|
// Update the cache.
|
||||||
|
if ( pTestFollow && pTestHdr && pOwnerHdr )
|
||||||
|
{
|
||||||
|
m_pFollow = pTestFollow;
|
||||||
|
m_pFollowHdr = pTestHdr;
|
||||||
|
m_pOwnerHdr = pOwnerHdr;
|
||||||
|
|
||||||
|
m_BoneMergeBits.SetSize( pOwnerHdr->numbones() / 8 + 1 );
|
||||||
|
memset( m_BoneMergeBits.Base(), 0, m_BoneMergeBits.Count() );
|
||||||
|
|
||||||
|
mstudiobone_t *pOwnerBones = m_pOwnerHdr->pBone( 0 );
|
||||||
|
|
||||||
|
m_nFollowBoneSetupMask = BONE_USED_BY_BONE_MERGE;
|
||||||
|
for ( int i = 0; i < m_pOwnerHdr->numbones(); i++ )
|
||||||
|
{
|
||||||
|
int parentBoneIndex = Studio_BoneIndexByName( m_pFollowHdr, pOwnerBones[i].pszName() );
|
||||||
|
if ( parentBoneIndex < 0 )
|
||||||
|
continue;
|
||||||
|
|
||||||
|
// Add a merged bone here.
|
||||||
|
CMergedBone mergedBone;
|
||||||
|
mergedBone.m_iMyBone = i;
|
||||||
|
mergedBone.m_iParentBone = parentBoneIndex;
|
||||||
|
m_MergedBones.AddToTail( mergedBone );
|
||||||
|
|
||||||
|
m_BoneMergeBits[i>>3] |= ( 1 << ( i & 7 ) );
|
||||||
|
|
||||||
|
if ( ( m_pFollowHdr->pBone( parentBoneIndex )->flags & BONE_USED_BY_BONE_MERGE ) == 0 )
|
||||||
|
{
|
||||||
|
m_nFollowBoneSetupMask = BONE_USED_BY_ANYTHING;
|
||||||
|
Warning("Performance warning: Mark bone '%s' in model '%s' as being used by bone merge in the .qc!\n",
|
||||||
|
m_pFollowHdr->pBone( parentBoneIndex )->pszName(), m_pFollowHdr->pszName() );
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// No merged bones found? Slam the mask to 0
|
||||||
|
if ( !m_MergedBones.Count() )
|
||||||
|
{
|
||||||
|
m_nFollowBoneSetupMask = 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
m_pFollow = NULL;
|
||||||
|
m_pFollowHdr = NULL;
|
||||||
|
m_pOwnerHdr = NULL;
|
||||||
|
m_nFollowBoneSetupMask = 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void CBoneMergeCache::MergeMatchingBones( int boneMask )
|
||||||
|
{
|
||||||
|
UpdateCache();
|
||||||
|
|
||||||
|
// If this is set, then all the other cache data is set.
|
||||||
|
if ( !m_pOwnerHdr || m_MergedBones.Count() == 0 )
|
||||||
|
return;
|
||||||
|
|
||||||
|
// Have the entity we're following setup its bones.
|
||||||
|
m_pFollow->SetupBones( NULL, -1, m_nFollowBoneSetupMask, gpGlobals->curtime );
|
||||||
|
|
||||||
|
// Now copy the bone matrices.
|
||||||
|
for ( int i=0; i < m_MergedBones.Count(); i++ )
|
||||||
|
{
|
||||||
|
int iOwnerBone = m_MergedBones[i].m_iMyBone;
|
||||||
|
int iParentBone = m_MergedBones[i].m_iParentBone;
|
||||||
|
|
||||||
|
// Only update bones reference by the bone mask.
|
||||||
|
if ( !( m_pOwnerHdr->pBone( iOwnerBone )->flags & boneMask ) )
|
||||||
|
continue;
|
||||||
|
|
||||||
|
MatrixCopy( m_pFollow->GetBone( iParentBone ), m_pOwner->GetBoneForWrite( iOwnerBone ) );
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
bool CBoneMergeCache::GetAimEntOrigin( Vector *pAbsOrigin, QAngle *pAbsAngles )
|
||||||
|
{
|
||||||
|
UpdateCache();
|
||||||
|
|
||||||
|
// If this is set, then all the other cache data is set.
|
||||||
|
if ( !m_pOwnerHdr || m_MergedBones.Count() == 0 )
|
||||||
|
return false;
|
||||||
|
|
||||||
|
// We want the abs origin such that if we put the entity there, the first merged bone
|
||||||
|
// will be aligned. This way the entity will be culled in the correct position.
|
||||||
|
//
|
||||||
|
// ie: mEntity * mBoneLocal = mFollowBone
|
||||||
|
// so: mEntity = mFollowBone * Inverse( mBoneLocal )
|
||||||
|
//
|
||||||
|
// Note: the code below doesn't take animation into account. If the attached entity animates
|
||||||
|
// all over the place, then this won't get the right results.
|
||||||
|
|
||||||
|
// Get mFollowBone.
|
||||||
|
m_pFollow->SetupBones( NULL, -1, m_nFollowBoneSetupMask, gpGlobals->curtime );
|
||||||
|
const matrix3x4_t &mFollowBone = m_pFollow->GetBone( m_MergedBones[0].m_iParentBone );
|
||||||
|
|
||||||
|
// Get Inverse( mBoneLocal )
|
||||||
|
matrix3x4_t mBoneLocal, mBoneLocalInv;
|
||||||
|
SetupSingleBoneMatrix( m_pOwnerHdr, m_pOwner->GetSequence(), 0, m_MergedBones[0].m_iMyBone, mBoneLocal );
|
||||||
|
MatrixInvert( mBoneLocal, mBoneLocalInv );
|
||||||
|
|
||||||
|
// Now calculate mEntity = mFollowBone * Inverse( mBoneLocal )
|
||||||
|
matrix3x4_t mEntity;
|
||||||
|
ConcatTransforms( mFollowBone, mBoneLocalInv, mEntity );
|
||||||
|
MatrixAngles( mEntity, *pAbsAngles, *pAbsOrigin );
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
79
cl_dll/bone_merge_cache.h
Normal file
79
cl_dll/bone_merge_cache.h
Normal file
@ -0,0 +1,79 @@
|
|||||||
|
//========= Copyright © 1996-2005, Valve Corporation, All rights reserved. ============//
|
||||||
|
//
|
||||||
|
// Purpose:
|
||||||
|
//
|
||||||
|
//=============================================================================//
|
||||||
|
|
||||||
|
#ifndef BONE_MERGE_CACHE_H
|
||||||
|
#define BONE_MERGE_CACHE_H
|
||||||
|
#ifdef _WIN32
|
||||||
|
#pragma once
|
||||||
|
#endif
|
||||||
|
|
||||||
|
|
||||||
|
class C_BaseAnimating;
|
||||||
|
class CStudioHdr;
|
||||||
|
|
||||||
|
|
||||||
|
#include "vector.h"
|
||||||
|
|
||||||
|
|
||||||
|
class CBoneMergeCache
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
|
||||||
|
CBoneMergeCache();
|
||||||
|
|
||||||
|
void Init( C_BaseAnimating *pOwner );
|
||||||
|
|
||||||
|
// Updates the lookups that let it merge bones quickly.
|
||||||
|
void UpdateCache();
|
||||||
|
|
||||||
|
// This copies the transform from all bones in the followed entity that have
|
||||||
|
// names that match our bones.
|
||||||
|
void MergeMatchingBones( int boneMask );
|
||||||
|
|
||||||
|
// Returns true if the specified bone is one that gets merged in MergeMatchingBones.
|
||||||
|
int CBoneMergeCache::IsBoneMerged( int iBone ) const;
|
||||||
|
|
||||||
|
// Gets the origin for the first merge bone on the parent.
|
||||||
|
bool GetAimEntOrigin( Vector *pAbsOrigin, QAngle *pAbsAngles );
|
||||||
|
|
||||||
|
|
||||||
|
private:
|
||||||
|
|
||||||
|
// This is the entity that we're keeping the cache updated for.
|
||||||
|
C_BaseAnimating *m_pOwner;
|
||||||
|
|
||||||
|
// All the cache data is based off these. When they change, the cache data is regenerated.
|
||||||
|
// These are either all valid pointers or all NULL.
|
||||||
|
C_BaseAnimating *m_pFollow;
|
||||||
|
CStudioHdr *m_pFollowHdr;
|
||||||
|
CStudioHdr *m_pOwnerHdr;
|
||||||
|
|
||||||
|
// This is the mask we need to use to set up bones on the followed entity to do the bone merge
|
||||||
|
int m_nFollowBoneSetupMask;
|
||||||
|
|
||||||
|
// Cache data.
|
||||||
|
class CMergedBone
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
unsigned short m_iMyBone;
|
||||||
|
unsigned short m_iParentBone;
|
||||||
|
};
|
||||||
|
|
||||||
|
CUtlVector<CMergedBone> m_MergedBones;
|
||||||
|
CUtlVector<unsigned char> m_BoneMergeBits; // One bit for each bone. The bit is set if the bone gets merged.
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
inline int CBoneMergeCache::IsBoneMerged( int iBone ) const
|
||||||
|
{
|
||||||
|
if ( m_pOwnerHdr )
|
||||||
|
return m_BoneMergeBits[iBone >> 3] & ( 1 << ( iBone & 7 ) );
|
||||||
|
else
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
#endif // BONE_MERGE_CACHE_H
|
169
cl_dll/c_ai_basehumanoid.cpp
Normal file
169
cl_dll/c_ai_basehumanoid.cpp
Normal file
@ -0,0 +1,169 @@
|
|||||||
|
//========= Copyright © 1996-2005, Valve Corporation, All rights reserved. ============//
|
||||||
|
//
|
||||||
|
// Purpose:
|
||||||
|
//
|
||||||
|
// $NoKeywords: $
|
||||||
|
//=============================================================================//
|
||||||
|
|
||||||
|
#include "cbase.h"
|
||||||
|
|
||||||
|
// memdbgon must be the last include file in a .cpp file!!!
|
||||||
|
#include "tier0/memdbgon.h"
|
||||||
|
|
||||||
|
#if 0
|
||||||
|
|
||||||
|
class C_AI_BaseHumanoid : public C_AI_BaseNPC
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
DECLARE_CLASS( C_AI_BaseHumanoid, C_AI_BaseNPC );
|
||||||
|
DECLARE_CLIENTCLASS();
|
||||||
|
|
||||||
|
C_AI_BaseHumanoid();
|
||||||
|
|
||||||
|
// model specific
|
||||||
|
virtual bool Interpolate( float currentTime );
|
||||||
|
virtual void StandardBlendingRules( CStudioHdr *pStudioHdr, Vector pos[], Quaternion q[], float currentTime, int boneMask );
|
||||||
|
|
||||||
|
float m_recanimtime[3];
|
||||||
|
AnimationLayer_t m_Layer[4][3];
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
C_AI_BaseHumanoid::C_AI_BaseHumanoid()
|
||||||
|
{
|
||||||
|
memset(m_recanimtime, 0, sizeof(m_recanimtime));
|
||||||
|
memset(m_Layer, 0, sizeof(m_Layer));
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
BEGIN_RECV_TABLE_NOBASE(AnimationLayer_t, DT_Animationlayer)
|
||||||
|
RecvPropInt(RECVINFO_NAME(nSequence,sequence)),
|
||||||
|
RecvPropFloat(RECVINFO_NAME(flCycle,cycle)),
|
||||||
|
RecvPropFloat(RECVINFO_NAME(flPlaybackrate,playbackrate)),
|
||||||
|
RecvPropFloat(RECVINFO_NAME(flWeight,weight))
|
||||||
|
END_RECV_TABLE()
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
IMPLEMENT_CLIENTCLASS_DT(C_AI_BaseHumanoid, DT_BaseHumanoid, CAI_BaseHumanoid)
|
||||||
|
/*
|
||||||
|
RecvPropDataTable(RECVINFO_DTNAME(m_Layer[0][2],m_Layer0),0, &REFERENCE_RECV_TABLE(DT_Animationlayer)),
|
||||||
|
RecvPropDataTable(RECVINFO_DTNAME(m_Layer[1][2],m_Layer1),0, &REFERENCE_RECV_TABLE(DT_Animationlayer)),
|
||||||
|
RecvPropDataTable(RECVINFO_DTNAME(m_Layer[2][2],m_Layer2),0, &REFERENCE_RECV_TABLE(DT_Animationlayer)),
|
||||||
|
RecvPropDataTable(RECVINFO_DTNAME(m_Layer[3][2],m_Layer3),0, &REFERENCE_RECV_TABLE(DT_Animationlayer)),
|
||||||
|
*/
|
||||||
|
RecvPropInt(RECVINFO_NAME(m_Layer[0][2].nSequence,sequence0)),
|
||||||
|
RecvPropFloat(RECVINFO_NAME(m_Layer[0][2].flCycle,cycle0)),
|
||||||
|
RecvPropFloat(RECVINFO_NAME(m_Layer[0][2].flPlaybackrate,playbackrate0)),
|
||||||
|
RecvPropFloat(RECVINFO_NAME(m_Layer[0][2].flWeight,weight0)),
|
||||||
|
RecvPropInt(RECVINFO_NAME(m_Layer[1][2].nSequence,sequence1)),
|
||||||
|
RecvPropFloat(RECVINFO_NAME(m_Layer[1][2].flCycle,cycle1)),
|
||||||
|
RecvPropFloat(RECVINFO_NAME(m_Layer[1][2].flPlaybackrate,playbackrate1)),
|
||||||
|
RecvPropFloat(RECVINFO_NAME(m_Layer[1][2].flWeight,weight1)),
|
||||||
|
RecvPropInt(RECVINFO_NAME(m_Layer[2][2].nSequence,sequence2)),
|
||||||
|
RecvPropFloat(RECVINFO_NAME(m_Layer[2][2].flCycle,cycle2)),
|
||||||
|
RecvPropFloat(RECVINFO_NAME(m_Layer[2][2].flPlaybackrate,playbackrate2)),
|
||||||
|
RecvPropFloat(RECVINFO_NAME(m_Layer[2][2].flWeight,weight2)),
|
||||||
|
RecvPropInt(RECVINFO_NAME(m_Layer[3][2].nSequence,sequence3)),
|
||||||
|
RecvPropFloat(RECVINFO_NAME(m_Layer[3][2].flCycle,cycle3)),
|
||||||
|
RecvPropFloat(RECVINFO_NAME(m_Layer[3][2].flPlaybackrate,playbackrate3)),
|
||||||
|
RecvPropFloat(RECVINFO_NAME(m_Layer[3][2].flWeight,weight3))
|
||||||
|
END_RECV_TABLE()
|
||||||
|
|
||||||
|
//-----------------------------------------------------------------------------
|
||||||
|
// Purpose:
|
||||||
|
//-----------------------------------------------------------------------------
|
||||||
|
void C_AI_BaseHumanoid::StandardBlendingRules( CStudioHdr *pStudioHdr, Vector pos[], Quaternion q[], float currentTime, int boneMask )
|
||||||
|
{
|
||||||
|
VPROF( "C_AI_BaseHumanoid::StandardBlendingRules" );
|
||||||
|
|
||||||
|
BaseClass::StandardBlendingRules( pStudioHdr, pos, q, currentTime, boneMask );
|
||||||
|
|
||||||
|
if ( !hdr )
|
||||||
|
{
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
#if 0
|
||||||
|
float poseparam[MAXSTUDIOPOSEPARAM];
|
||||||
|
|
||||||
|
if ( GetSequence() >= hdr->numseq )
|
||||||
|
{
|
||||||
|
SetSequence( 0 );
|
||||||
|
}
|
||||||
|
|
||||||
|
// interpolate pose parameters
|
||||||
|
for (int i = 0; i < hdr->numposeparameters; i++)
|
||||||
|
{
|
||||||
|
poseparam[ i ] = m_flPoseParameter[i];
|
||||||
|
}
|
||||||
|
|
||||||
|
// build root animation
|
||||||
|
float fCycle = GetCycle();
|
||||||
|
CalcPose( hdr, NULL, pos, q, GetSequence(), fCycle, poseparam );
|
||||||
|
|
||||||
|
// debugoverlay->AddTextOverlay( GetAbsOrigin() + Vector( 0, 0, 64 ), 0, 0, "%30s %6.2f : %6.2f", hdr->pSeqdesc( GetSequence() )->pszLabel( ), fCycle, 1.0 );
|
||||||
|
|
||||||
|
MaintainSequenceTransitions( hdr, fCycle, poseparam, pos, q, boneMask );
|
||||||
|
|
||||||
|
#if 1
|
||||||
|
for (i = 0; i < 4; i++)
|
||||||
|
{
|
||||||
|
if (m_Layer[i][2].nSequence != m_Layer[i][1].nSequence)
|
||||||
|
{
|
||||||
|
if (m_Layer[i][2].flWeight > 0.5) m_Layer[i][1].flWeight = 1.0; else m_Layer[i][1].flWeight = 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#if 1
|
||||||
|
for (i = 0; i < 4; i++)
|
||||||
|
{
|
||||||
|
Vector pos2[MAXSTUDIOBONES];
|
||||||
|
Quaternion q2[MAXSTUDIOBONES];
|
||||||
|
float fWeight = m_Layer[i][1].flWeight * (1 - dadt) + m_Layer[i][2].flWeight * dadt;
|
||||||
|
|
||||||
|
/*
|
||||||
|
debugoverlay->AddTextOverlay( GetAbsOrigin() + Vector( 0, 0, 64 ), -i - 1, 0,
|
||||||
|
"%2d %6.2f %6.2f : %2d %6.2f %6.2f : %2d %6.2f %6.2f",
|
||||||
|
m_Layer[i][0].nSequence, m_Layer[i][0].flCycle, m_Layer[i][0].flWeight,
|
||||||
|
m_Layer[i][1].nSequence, m_Layer[i][1].flCycle, m_Layer[i][1].flWeight,
|
||||||
|
m_Layer[i][2].nSequence, m_Layer[i][2].flCycle, m_Layer[i][2].flWeight );
|
||||||
|
*/
|
||||||
|
|
||||||
|
if (fWeight > 0)
|
||||||
|
{
|
||||||
|
mstudioseqdesc_t *pseqdesc = hdr->pSeqdesc( m_Layer[i][2].nSequence );
|
||||||
|
|
||||||
|
float fCycle = m_Layer[i][2].flCycle;
|
||||||
|
|
||||||
|
// UNDONE: Do IK here.
|
||||||
|
CalcPose( hdr, NULL, pos2, q2, m_Layer[i][2].nSequence, fCycle, poseparam );
|
||||||
|
|
||||||
|
if (fWeight > 1)
|
||||||
|
fWeight = 1;
|
||||||
|
SlerpBones( hdr, q, pos, pseqdesc, q2, pos2, fWeight );
|
||||||
|
|
||||||
|
engine->Con_NPrintf( 10 + i, "%30s %6.2f : %6.2f", pseqdesc->pszLabel(), fCycle, fWeight );
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
engine->Con_NPrintf( 10 + i, "%30s %6.2f : %6.2f", " ", 0, 0 );
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
CIKContext auto_ik;
|
||||||
|
auto_ik.Init( hdr, GetRenderAngles(), GetRenderOrigin(), gpGlobals->curtime );
|
||||||
|
CalcAutoplaySequences( hdr, &auto_ik, pos, q, poseparam, boneMask, currentTime );
|
||||||
|
|
||||||
|
float controllers[MAXSTUDIOBONECTRLS];
|
||||||
|
GetBoneControllers(controllers);
|
||||||
|
CalcBoneAdj( hdr, pos, q, controllers );
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
#endif
|
116
cl_dll/c_ai_basenpc.cpp
Normal file
116
cl_dll/c_ai_basenpc.cpp
Normal file
@ -0,0 +1,116 @@
|
|||||||
|
//========= Copyright © 1996-2005, Valve Corporation, All rights reserved. ============//
|
||||||
|
//
|
||||||
|
// Purpose:
|
||||||
|
//
|
||||||
|
// $NoKeywords: $
|
||||||
|
//=============================================================================//
|
||||||
|
#include "cbase.h"
|
||||||
|
#include "c_AI_BaseNPC.h"
|
||||||
|
#include "engine/IVDebugOverlay.h"
|
||||||
|
|
||||||
|
#ifdef HL2_DLL
|
||||||
|
#include "c_basehlplayer.h"
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#include "death_pose.h"
|
||||||
|
|
||||||
|
// memdbgon must be the last include file in a .cpp file!!!
|
||||||
|
#include "tier0/memdbgon.h"
|
||||||
|
|
||||||
|
IMPLEMENT_CLIENTCLASS_DT( C_AI_BaseNPC, DT_AI_BaseNPC, CAI_BaseNPC )
|
||||||
|
RecvPropInt( RECVINFO( m_lifeState ) ),
|
||||||
|
RecvPropBool( RECVINFO( m_bPerformAvoidance ) ),
|
||||||
|
RecvPropBool( RECVINFO( m_bIsMoving ) ),
|
||||||
|
RecvPropBool( RECVINFO( m_bFadeCorpse ) ),
|
||||||
|
RecvPropInt( RECVINFO ( m_iDeathPose) ),
|
||||||
|
RecvPropInt( RECVINFO( m_iDeathFrame) ),
|
||||||
|
RecvPropInt( RECVINFO( m_iSpeedModRadius ) ),
|
||||||
|
RecvPropInt( RECVINFO( m_iSpeedModSpeed ) ),
|
||||||
|
RecvPropInt( RECVINFO( m_bSpeedModActive ) ),
|
||||||
|
RecvPropBool( RECVINFO( m_bImportanRagdoll ) ),
|
||||||
|
END_RECV_TABLE()
|
||||||
|
|
||||||
|
extern ConVar cl_npc_speedmod_intime;
|
||||||
|
|
||||||
|
bool NPC_IsImportantNPC( C_BaseAnimating *pAnimating )
|
||||||
|
{
|
||||||
|
C_AI_BaseNPC *pBaseNPC = dynamic_cast < C_AI_BaseNPC* > ( pAnimating );
|
||||||
|
|
||||||
|
if ( pBaseNPC == NULL )
|
||||||
|
return false;
|
||||||
|
|
||||||
|
return pBaseNPC->ImportantRagdoll();
|
||||||
|
}
|
||||||
|
|
||||||
|
C_AI_BaseNPC::C_AI_BaseNPC()
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
//-----------------------------------------------------------------------------
|
||||||
|
// Makes ragdolls ignore npcclip brushes
|
||||||
|
//-----------------------------------------------------------------------------
|
||||||
|
unsigned int C_AI_BaseNPC::PhysicsSolidMaskForEntity( void ) const
|
||||||
|
{
|
||||||
|
// This allows ragdolls to move through npcclip brushes
|
||||||
|
if ( !IsRagdoll() )
|
||||||
|
{
|
||||||
|
return MASK_NPCSOLID;
|
||||||
|
}
|
||||||
|
return MASK_SOLID;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void C_AI_BaseNPC::ClientThink( void )
|
||||||
|
{
|
||||||
|
BaseClass::ClientThink();
|
||||||
|
|
||||||
|
#ifdef HL2_DLL
|
||||||
|
C_BaseHLPlayer *pPlayer = dynamic_cast<C_BaseHLPlayer*>( C_BasePlayer::GetLocalPlayer() );
|
||||||
|
|
||||||
|
if ( ShouldModifyPlayerSpeed() == true )
|
||||||
|
{
|
||||||
|
if ( pPlayer )
|
||||||
|
{
|
||||||
|
float flDist = (GetAbsOrigin() - pPlayer->GetAbsOrigin()).LengthSqr();
|
||||||
|
|
||||||
|
if ( flDist <= GetSpeedModifyRadius() )
|
||||||
|
{
|
||||||
|
if ( pPlayer->m_hClosestNPC )
|
||||||
|
{
|
||||||
|
if ( pPlayer->m_hClosestNPC != this )
|
||||||
|
{
|
||||||
|
float flDistOther = (pPlayer->m_hClosestNPC->GetAbsOrigin() - pPlayer->GetAbsOrigin()).Length();
|
||||||
|
|
||||||
|
//If I'm closer than the other NPC then replace it with myself.
|
||||||
|
if ( flDist < flDistOther )
|
||||||
|
{
|
||||||
|
pPlayer->m_hClosestNPC = this;
|
||||||
|
pPlayer->m_flSpeedModTime = gpGlobals->curtime + cl_npc_speedmod_intime.GetFloat();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
pPlayer->m_hClosestNPC = this;
|
||||||
|
pPlayer->m_flSpeedModTime = gpGlobals->curtime + cl_npc_speedmod_intime.GetFloat();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
#endif // HL2_DLL
|
||||||
|
}
|
||||||
|
|
||||||
|
void C_AI_BaseNPC::OnDataChanged( DataUpdateType_t type )
|
||||||
|
{
|
||||||
|
BaseClass::OnDataChanged( type );
|
||||||
|
|
||||||
|
if ( ShouldModifyPlayerSpeed() == true )
|
||||||
|
{
|
||||||
|
SetNextClientThink( CLIENT_THINK_ALWAYS );
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void C_AI_BaseNPC::GetRagdollCurSequence( matrix3x4_t *curBones, float flTime )
|
||||||
|
{
|
||||||
|
GetRagdollCurSequenceWithDeathPose( this, curBones, flTime, m_iDeathPose, m_iDeathFrame );
|
||||||
|
}
|
60
cl_dll/c_ai_basenpc.h
Normal file
60
cl_dll/c_ai_basenpc.h
Normal file
@ -0,0 +1,60 @@
|
|||||||
|
//========= Copyright © 1996-2005, Valve Corporation, All rights reserved. ============//
|
||||||
|
//
|
||||||
|
// Purpose:
|
||||||
|
//
|
||||||
|
// $NoKeywords: $
|
||||||
|
//=============================================================================//
|
||||||
|
|
||||||
|
#ifndef C_AI_BASENPC_H
|
||||||
|
#define C_AI_BASENPC_H
|
||||||
|
#ifdef _WIN32
|
||||||
|
#pragma once
|
||||||
|
#endif
|
||||||
|
|
||||||
|
|
||||||
|
#include "c_basecombatcharacter.h"
|
||||||
|
|
||||||
|
// NOTE: MOved all controller code into c_basestudiomodel
|
||||||
|
class C_AI_BaseNPC : public C_BaseCombatCharacter
|
||||||
|
{
|
||||||
|
DECLARE_CLASS( C_AI_BaseNPC, C_BaseCombatCharacter );
|
||||||
|
|
||||||
|
public:
|
||||||
|
DECLARE_CLIENTCLASS();
|
||||||
|
|
||||||
|
C_AI_BaseNPC();
|
||||||
|
virtual unsigned int PhysicsSolidMaskForEntity( void ) const;
|
||||||
|
virtual bool IsNPC( void ) { return true; }
|
||||||
|
bool IsMoving( void ){ return m_bIsMoving; }
|
||||||
|
bool ShouldAvoidObstacle( void ){ return m_bPerformAvoidance; }
|
||||||
|
virtual bool AddRagdollToFadeQueue( void ) { return m_bFadeCorpse; }
|
||||||
|
|
||||||
|
virtual void GetRagdollCurSequence( matrix3x4_t *curBones, float flTime );
|
||||||
|
|
||||||
|
int GetDeathPose( void ) { return m_iDeathPose; }
|
||||||
|
|
||||||
|
bool ShouldModifyPlayerSpeed( void ) { return m_bSpeedModActive; }
|
||||||
|
int GetSpeedModifyRadius( void ) { return m_iSpeedModRadius; }
|
||||||
|
int GetSpeedModifySpeed( void ) { return m_iSpeedModSpeed; }
|
||||||
|
|
||||||
|
void ClientThink( void );
|
||||||
|
void OnDataChanged( DataUpdateType_t type );
|
||||||
|
bool ImportantRagdoll( void ) { return m_bImportanRagdoll; }
|
||||||
|
|
||||||
|
private:
|
||||||
|
C_AI_BaseNPC( const C_AI_BaseNPC & ); // not defined, not accessible
|
||||||
|
bool m_bPerformAvoidance;
|
||||||
|
bool m_bIsMoving;
|
||||||
|
bool m_bFadeCorpse;
|
||||||
|
int m_iDeathPose;
|
||||||
|
int m_iDeathFrame;
|
||||||
|
|
||||||
|
int m_iSpeedModRadius;
|
||||||
|
int m_iSpeedModSpeed;
|
||||||
|
bool m_bSpeedModActive;
|
||||||
|
|
||||||
|
bool m_bImportanRagdoll;
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
#endif // C_AI_BASENPC_H
|
5071
cl_dll/c_baseanimating.cpp
Normal file
5071
cl_dll/c_baseanimating.cpp
Normal file
File diff suppressed because it is too large
Load Diff
647
cl_dll/c_baseanimating.h
Normal file
647
cl_dll/c_baseanimating.h
Normal file
@ -0,0 +1,647 @@
|
|||||||
|
//========= Copyright © 1996-2005, Valve Corporation, All rights reserved. ============//
|
||||||
|
//
|
||||||
|
// Purpose:
|
||||||
|
//
|
||||||
|
// $Workfile: $
|
||||||
|
// $NoKeywords: $
|
||||||
|
//=============================================================================//
|
||||||
|
#ifndef C_BASEANIMATING_H
|
||||||
|
#define C_BASEANIMATING_H
|
||||||
|
|
||||||
|
#ifdef _WIN32
|
||||||
|
#pragma once
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#include "c_baseentity.h"
|
||||||
|
#include "studio.h"
|
||||||
|
#include "UtlVector.h"
|
||||||
|
#include "ragdoll.h"
|
||||||
|
#include "mouthinfo.h"
|
||||||
|
// Shared activities
|
||||||
|
#include "ai_activity.h"
|
||||||
|
#include "animationlayer.h"
|
||||||
|
#include "sequence_transitioner.h"
|
||||||
|
#include "bone_accessor.h"
|
||||||
|
#include "bone_merge_cache.h"
|
||||||
|
#include "ragdoll_shared.h"
|
||||||
|
|
||||||
|
#define LIPSYNC_POSEPARAM_NAME "mouth"
|
||||||
|
#define NUM_HITBOX_FIRES 10
|
||||||
|
|
||||||
|
/*
|
||||||
|
class C_BaseClientShader
|
||||||
|
{
|
||||||
|
virtual void RenderMaterial( C_BaseEntity *pEntity, int count, const vec4_t *verts, const vec4_t *normals, const vec2_t *texcoords, vec4_t *lightvalues );
|
||||||
|
};
|
||||||
|
*/
|
||||||
|
|
||||||
|
class IRagdoll;
|
||||||
|
class CIKContext;
|
||||||
|
class CIKState;
|
||||||
|
class ConVar;
|
||||||
|
class C_RopeKeyframe;
|
||||||
|
class CBoneBitList;
|
||||||
|
class CBoneList;
|
||||||
|
class KeyValues;
|
||||||
|
FORWARD_DECLARE_HANDLE( memhandle_t );
|
||||||
|
|
||||||
|
extern ConVar vcollide_wireframe;
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
struct RagdollInfo_t
|
||||||
|
{
|
||||||
|
bool m_bActive;
|
||||||
|
float m_flSaveTime;
|
||||||
|
int m_nNumBones;
|
||||||
|
Vector m_rgBonePos[MAXSTUDIOBONES];
|
||||||
|
Quaternion m_rgBoneQuaternion[MAXSTUDIOBONES];
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
class CAttachmentData
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
Vector m_vOrigin;
|
||||||
|
QAngle m_angRotation;
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
typedef unsigned int ClientSideAnimationListHandle_t;
|
||||||
|
|
||||||
|
#define INVALID_CLIENTSIDEANIMATION_LIST_HANDLE (ClientSideAnimationListHandle_t)~0
|
||||||
|
|
||||||
|
|
||||||
|
class C_BaseAnimating : public C_BaseEntity
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
DECLARE_CLASS( C_BaseAnimating, C_BaseEntity );
|
||||||
|
DECLARE_CLIENTCLASS();
|
||||||
|
DECLARE_PREDICTABLE();
|
||||||
|
DECLARE_INTERPOLATION();
|
||||||
|
|
||||||
|
enum
|
||||||
|
{
|
||||||
|
NUM_POSEPAREMETERS = 24,
|
||||||
|
NUM_BONECTRLS = 4
|
||||||
|
};
|
||||||
|
|
||||||
|
C_BaseAnimating();
|
||||||
|
~C_BaseAnimating();
|
||||||
|
|
||||||
|
virtual C_BaseAnimating* GetBaseAnimating() { return this; }
|
||||||
|
|
||||||
|
bool UsesFrameBufferTexture( void );
|
||||||
|
|
||||||
|
virtual bool Interpolate( float currentTime );
|
||||||
|
virtual void Simulate();
|
||||||
|
virtual void Release();
|
||||||
|
|
||||||
|
float GetAnimTimeInterval( void ) const;
|
||||||
|
|
||||||
|
virtual unsigned char GetClientSideFade( void );
|
||||||
|
|
||||||
|
// Get bone controller values.
|
||||||
|
virtual void GetBoneControllers(float controllers[MAXSTUDIOBONECTRLS]);
|
||||||
|
virtual float SetBoneController ( int iController, float flValue );
|
||||||
|
|
||||||
|
int GetNumFlexControllers( void );
|
||||||
|
const char *GetFlexDescFacs( int iFlexDesc );
|
||||||
|
const char *GetFlexControllerName( int iFlexController );
|
||||||
|
const char *GetFlexControllerType( int iFlexController );
|
||||||
|
|
||||||
|
virtual void GetAimEntOrigin( IClientEntity *pAttachedTo, Vector *pAbsOrigin, QAngle *pAbsAngles );
|
||||||
|
|
||||||
|
// Computes a box that surrounds all hitboxes
|
||||||
|
bool ComputeHitboxSurroundingBox( Vector *pVecWorldMins, Vector *pVecWorldMaxs );
|
||||||
|
bool ComputeEntitySpaceHitboxSurroundingBox( Vector *pVecWorldMins, Vector *pVecWorldMaxs );
|
||||||
|
|
||||||
|
// Gets the hitbox-to-world transforms, returns false if there was a problem
|
||||||
|
bool HitboxToWorldTransforms( matrix3x4_t *pHitboxToWorld[MAXSTUDIOBONES] );
|
||||||
|
|
||||||
|
// base model functionality
|
||||||
|
float ClampCycle( float cycle, bool isLooping );
|
||||||
|
virtual void GetPoseParameters( CStudioHdr *pStudioHdr, float poseParameter[MAXSTUDIOPOSEPARAM] );
|
||||||
|
virtual void BuildTransformations( CStudioHdr *pStudioHdr, Vector *pos, Quaternion q[], const matrix3x4_t& cameraTransform, int boneMask, CBoneBitList &boneComputed );
|
||||||
|
virtual void ApplyBoneMatrixTransform( matrix3x4_t& transform );
|
||||||
|
virtual int VPhysicsGetObjectList( IPhysicsObject **pList, int listMax );
|
||||||
|
|
||||||
|
// model specific
|
||||||
|
virtual bool SetupBones( matrix3x4_t *pBoneToWorldOut, int nMaxBones, int boneMask, float currentTime );
|
||||||
|
virtual void UpdateIKLocks( float currentTime );
|
||||||
|
virtual void CalculateIKLocks( float currentTime );
|
||||||
|
virtual int DrawModel( int flags );
|
||||||
|
virtual int InternalDrawModel( int flags );
|
||||||
|
|
||||||
|
//
|
||||||
|
virtual CMouthInfo *GetMouth();
|
||||||
|
virtual void ControlMouth( CStudioHdr *pStudioHdr );
|
||||||
|
|
||||||
|
// override in sub-classes
|
||||||
|
virtual void DoAnimationEvents( CStudioHdr *pStudio );
|
||||||
|
virtual void FireEvent( const Vector& origin, const QAngle& angles, int event, const char *options );
|
||||||
|
|
||||||
|
// Parses and distributes muzzle flash events
|
||||||
|
virtual bool DispatchMuzzleEffect( const char *options, bool isFirstPerson );
|
||||||
|
|
||||||
|
// virtual void AllocateMaterials( void );
|
||||||
|
// virtual void FreeMaterials( void );
|
||||||
|
|
||||||
|
virtual CStudioHdr *OnNewModel( void );
|
||||||
|
CStudioHdr *GetModelPtr() const;
|
||||||
|
|
||||||
|
virtual void SetPredictable( bool state );
|
||||||
|
|
||||||
|
// C_BaseClientShader **p_ClientShaders;
|
||||||
|
|
||||||
|
virtual void StandardBlendingRules( CStudioHdr *pStudioHdr, Vector pos[], Quaternion q[], float currentTime, int boneMask );
|
||||||
|
void UnragdollBlend( CStudioHdr *hdr, Vector pos[], Quaternion q[], float currentTime );
|
||||||
|
|
||||||
|
void MaintainSequenceTransitions( CStudioHdr *hdr, float flCycle, float flPoseParameter[], Vector pos[], Quaternion q[], int boneMask );
|
||||||
|
|
||||||
|
virtual void AccumulateLayers( CStudioHdr *hdr, Vector pos[], Quaternion q[], float poseparam[], float currentTime, int boneMask );
|
||||||
|
|
||||||
|
// Attachments
|
||||||
|
int LookupAttachment( const char *pAttachmentName );
|
||||||
|
int LookupRandomAttachment( const char *pAttachmentNameSubstring );
|
||||||
|
|
||||||
|
int LookupPoseParameter( CStudioHdr *pStudioHdr, const char *szName );
|
||||||
|
inline int LookupPoseParameter( const char *szName ) { return LookupPoseParameter(GetModelPtr(), szName); }
|
||||||
|
|
||||||
|
float SetPoseParameter( CStudioHdr *pStudioHdr, const char *szName, float flValue );
|
||||||
|
inline float SetPoseParameter( const char *szName, float flValue ) { return SetPoseParameter( GetModelPtr(), szName, flValue ); }
|
||||||
|
float SetPoseParameter( CStudioHdr *pStudioHdr, int iParameter, float flValue );
|
||||||
|
inline float SetPoseParameter( int iParameter, float flValue ) { return SetPoseParameter( GetModelPtr(), iParameter, flValue ); }
|
||||||
|
|
||||||
|
float GetPoseParameter( int iPoseParameter );
|
||||||
|
|
||||||
|
bool GetPoseParameterRange( int iPoseParameter, float &minValue, float &maxValue );
|
||||||
|
|
||||||
|
int LookupBone( const char *szName );
|
||||||
|
void GetBonePosition( int iBone, Vector &origin, QAngle &angles );
|
||||||
|
void GetBoneTransform( int iBone, matrix3x4_t &pBoneToWorld );
|
||||||
|
|
||||||
|
|
||||||
|
//bool solveIK(float a, float b, const Vector &Foot, const Vector &Knee1, Vector &Knee2);
|
||||||
|
//void DebugIK( mstudioikchain_t *pikchain );
|
||||||
|
|
||||||
|
virtual void PreDataUpdate( DataUpdateType_t updateType );
|
||||||
|
virtual void PostDataUpdate( DataUpdateType_t updateType );
|
||||||
|
|
||||||
|
virtual void NotifyShouldTransmit( ShouldTransmitState_t state );
|
||||||
|
virtual void OnPreDataChanged( DataUpdateType_t updateType );
|
||||||
|
virtual void OnDataChanged( DataUpdateType_t updateType );
|
||||||
|
virtual void AddEntity( void );
|
||||||
|
|
||||||
|
// This can be used to force client side animation to be on. Only use if you know what you're doing!
|
||||||
|
// Normally, the server entity should set this.
|
||||||
|
void ForceClientSideAnimationOn();
|
||||||
|
|
||||||
|
void AddToClientSideAnimationList();
|
||||||
|
void RemoveFromClientSideAnimationList();
|
||||||
|
|
||||||
|
virtual bool IsSelfAnimating();
|
||||||
|
virtual void ResetLatched();
|
||||||
|
|
||||||
|
// implements these so ragdolls can handle frustum culling & leaf visibility
|
||||||
|
virtual void GetRenderBounds( Vector& theMins, Vector& theMaxs );
|
||||||
|
virtual const Vector& GetRenderOrigin( void );
|
||||||
|
virtual const QAngle& GetRenderAngles( void );
|
||||||
|
|
||||||
|
virtual bool GetSoundSpatialization( SpatializationInfo_t& info );
|
||||||
|
|
||||||
|
// Attachments.
|
||||||
|
bool GetAttachment( int number, Vector &origin, QAngle &angles );
|
||||||
|
virtual bool GetAttachment( int number, matrix3x4_t &matrix );
|
||||||
|
|
||||||
|
// Returns the attachment in local space
|
||||||
|
bool GetAttachmentLocal( int iAttachment, matrix3x4_t &attachmentToLocal );
|
||||||
|
bool GetAttachmentLocal( int iAttachment, Vector &origin, QAngle &angles );
|
||||||
|
|
||||||
|
// Should this object cast render-to-texture shadows?
|
||||||
|
virtual ShadowType_t ShadowCastType();
|
||||||
|
|
||||||
|
// Should we collide?
|
||||||
|
virtual CollideType_t ShouldCollide( );
|
||||||
|
|
||||||
|
virtual bool TestCollision( const Ray_t &ray, unsigned int fContentsMask, trace_t& tr );
|
||||||
|
virtual bool TestHitboxes( const Ray_t &ray, unsigned int fContentsMask, trace_t& tr );
|
||||||
|
|
||||||
|
// returns true if we're currently being ragdolled
|
||||||
|
bool IsRagdoll() const;
|
||||||
|
virtual C_BaseAnimating * BecomeRagdollOnClient( bool bCopyEntity = true ); // returns ragdoll-owning entity
|
||||||
|
void IgniteRagdoll( C_BaseAnimating *pSource );
|
||||||
|
void TransferDissolveFrom( C_BaseAnimating *pSource );
|
||||||
|
virtual void SaveRagdollInfo( int numbones, const matrix3x4_t &cameraTransform, CBoneAccessor &pBoneToWorld );
|
||||||
|
virtual bool RetrieveRagdollInfo( Vector *pos, Quaternion *q );
|
||||||
|
virtual void Clear( void );
|
||||||
|
void ClearRagdoll();
|
||||||
|
void CreateUnragdollInfo( C_BaseAnimating *pRagdoll );
|
||||||
|
|
||||||
|
// For shadows rendering the correct body + sequence...
|
||||||
|
virtual int GetBody() { return m_nBody; }
|
||||||
|
virtual int GetSkin() { return m_nSkin; }
|
||||||
|
|
||||||
|
bool IsOnFire() { return ( (GetFlags() & FL_ONFIRE) != 0 ); }
|
||||||
|
|
||||||
|
inline float GetPlaybackRate();
|
||||||
|
inline void SetPlaybackRate( float rate );
|
||||||
|
|
||||||
|
void SetModelWidthScale( float scale );
|
||||||
|
float GetModelWidthScale() const;
|
||||||
|
|
||||||
|
int GetSequence();
|
||||||
|
void SetSequence(int nSequence);
|
||||||
|
inline void ResetSequence(int nSequence);
|
||||||
|
float GetSequenceGroundSpeed( CStudioHdr *pStudioHdr, int iSequence );
|
||||||
|
inline float GetSequenceGroundSpeed( int iSequence ) { return GetSequenceGroundSpeed(GetModelPtr(), iSequence); }
|
||||||
|
bool IsSequenceLooping( CStudioHdr *pStudioHdr, int iSequence );
|
||||||
|
inline bool IsSequenceLooping( int iSequence ) { return IsSequenceLooping(GetModelPtr(),iSequence); }
|
||||||
|
float GetSequenceMoveDist( CStudioHdr *pStudioHdr, int iSequence );
|
||||||
|
void GetSequenceLinearMotion( int iSequence, Vector *pVec );
|
||||||
|
void GetBlendedLinearVelocity( Vector *pVec );
|
||||||
|
int LookupSequence ( const char *label );
|
||||||
|
int LookupActivity( const char *label );
|
||||||
|
char const *GetSequenceName( int iSequence );
|
||||||
|
char const *GetSequenceActivityName( int iSequence );
|
||||||
|
Activity GetSequenceActivity( int iSequence );
|
||||||
|
virtual void StudioFrameAdvance(); // advance animation frame to some time in the future
|
||||||
|
|
||||||
|
// Clientside animation
|
||||||
|
virtual float FrameAdvance( float flInterval = 0.0f );
|
||||||
|
virtual float GetSequenceCycleRate( CStudioHdr *pStudioHdr, int iSequence );
|
||||||
|
virtual void UpdateClientSideAnimation();
|
||||||
|
void ClientSideAnimationChanged();
|
||||||
|
virtual unsigned int ComputeClientSideAnimationFlags();
|
||||||
|
|
||||||
|
void SetCycle( float flCycle );
|
||||||
|
float GetCycle() const;
|
||||||
|
|
||||||
|
void SetBodygroup( int iGroup, int iValue );
|
||||||
|
int GetBodygroup( int iGroup );
|
||||||
|
|
||||||
|
const char *GetBodygroupName( int iGroup );
|
||||||
|
int FindBodygroupByName( const char *name );
|
||||||
|
int GetBodygroupCount( int iGroup );
|
||||||
|
int GetNumBodyGroups( void );
|
||||||
|
|
||||||
|
class CBoneCache *GetBoneCache( CStudioHdr *pStudioHdr );
|
||||||
|
void SetHitboxSet( int setnum );
|
||||||
|
void SetHitboxSetByName( const char *setname );
|
||||||
|
int GetHitboxSet( void );
|
||||||
|
char const *GetHitboxSetName( void );
|
||||||
|
int GetHitboxSetCount( void );
|
||||||
|
void DrawClientHitboxes( float duration = 0.0f, bool monocolor = false );
|
||||||
|
|
||||||
|
C_BaseAnimating* FindFollowedEntity();
|
||||||
|
|
||||||
|
virtual bool IsActivityFinished( void ) { return m_bSequenceFinished; }
|
||||||
|
inline bool IsSequenceFinished( void );
|
||||||
|
|
||||||
|
// All view model attachments origins are stretched so you can place entities at them and
|
||||||
|
// they will match up with where the attachment winds up being drawn on the view model, since
|
||||||
|
// the view models are drawn with a different FOV.
|
||||||
|
//
|
||||||
|
// If you're drawing something inside of a view model's DrawModel() function, then you want the
|
||||||
|
// original attachment origin instead of the adjusted one. To get that, call this on the
|
||||||
|
// adjusted attachment origin.
|
||||||
|
virtual void UncorrectViewModelAttachment( Vector &vOrigin ) {}
|
||||||
|
|
||||||
|
// Call this if SetupBones() has already been called this frame but you need to move the
|
||||||
|
// entity and rerender.
|
||||||
|
void InvalidateBoneCache();
|
||||||
|
bool IsBoneCacheValid() const; // Returns true if the bone cache is considered good for this frame.
|
||||||
|
void GetCachedBoneMatrix( int boneIndex, matrix3x4_t &out );
|
||||||
|
|
||||||
|
// Wrappers for CBoneAccessor.
|
||||||
|
const matrix3x4_t& GetBone( int iBone ) const;
|
||||||
|
matrix3x4_t& GetBoneForWrite( int iBone );
|
||||||
|
|
||||||
|
// Used for debugging. Will produce asserts if someone tries to setup bones or
|
||||||
|
// attachments before it's allowed.
|
||||||
|
static void AllowBoneAccess( bool bAllowForNormalModels, bool bAllowForViewModels );
|
||||||
|
static void PushAllowBoneAccess( bool bAllowForNormalModels, bool bAllowForViewModels );
|
||||||
|
static void PopBoneAccess( void );
|
||||||
|
|
||||||
|
// Invalidate bone caches so all SetupBones() calls force bone transforms to be regenerated.
|
||||||
|
static void InvalidateBoneCaches();
|
||||||
|
|
||||||
|
// Purpose: My physics object has been updated, react or extract data
|
||||||
|
virtual void VPhysicsUpdate( IPhysicsObject *pPhysics );
|
||||||
|
|
||||||
|
void DisableMuzzleFlash(); // Turn off the muzzle flash (ie: signal that we handled the server's event).
|
||||||
|
virtual void DoMuzzleFlash(); // Force a muzzle flash event. Note: this only QUEUES an event, so
|
||||||
|
// ProcessMuzzleFlashEvent will get called later.
|
||||||
|
bool ShouldMuzzleFlash() const; // Is the muzzle flash event on?
|
||||||
|
|
||||||
|
// This is called to do the actual muzzle flash effect.
|
||||||
|
virtual void ProcessMuzzleFlashEvent();
|
||||||
|
|
||||||
|
// Update client side animations
|
||||||
|
static void UpdateClientSideAnimations();
|
||||||
|
|
||||||
|
void InitRopes();
|
||||||
|
|
||||||
|
// Sometimes the server wants to update the client's cycle to get the two to run in sync (for proper hit detection)
|
||||||
|
virtual void SetServerIntendedCycle( float intended ) { intended; }
|
||||||
|
virtual float GetServerIntendedCycle( void ) { return -1.0f; }
|
||||||
|
|
||||||
|
// For prediction
|
||||||
|
int SelectWeightedSequence ( int activity );
|
||||||
|
void ResetSequenceInfo( void );
|
||||||
|
float SequenceDuration( void );
|
||||||
|
float SequenceDuration( CStudioHdr *pStudioHdr, int iSequence );
|
||||||
|
inline float SequenceDuration( int iSequence ) { return SequenceDuration(GetModelPtr(), iSequence); }
|
||||||
|
int FindTransitionSequence( int iCurrentSequence, int iGoalSequence, int *piDir );
|
||||||
|
|
||||||
|
virtual void GetRagdollPreSequence( matrix3x4_t *preBones, float flTime );
|
||||||
|
virtual void GetRagdollCurSequence( matrix3x4_t *curBones, float flTime );
|
||||||
|
|
||||||
|
void RagdollMoved( void );
|
||||||
|
|
||||||
|
virtual void GetToolRecordingState( KeyValues *msg );
|
||||||
|
virtual void CleanupToolRecordingState( KeyValues *msg );
|
||||||
|
|
||||||
|
void RecordBones( CStudioHdr *hdr, KeyValues *kvBones );
|
||||||
|
|
||||||
|
protected:
|
||||||
|
// View models scale their attachment positions to account for FOV. To get the unmodified
|
||||||
|
// attachment position (like if you're rendering something else during the view model's DrawModel call),
|
||||||
|
// use TransformViewModelAttachmentToWorld.
|
||||||
|
virtual void FormatViewModelAttachment( int nAttachment, Vector &vecOrigin, QAngle &angle ) {}
|
||||||
|
|
||||||
|
// View models say yes to this.
|
||||||
|
virtual bool IsViewModel() const;
|
||||||
|
bool IsBoneAccessAllowed() const;
|
||||||
|
CMouthInfo& MouthInfo();
|
||||||
|
|
||||||
|
// Allow studio models to tell C_BaseEntity what their m_nBody value is
|
||||||
|
virtual int GetStudioBody( void ) { return m_nBody; }
|
||||||
|
|
||||||
|
private:
|
||||||
|
CBoneList* RecordBones( CStudioHdr *hdr );
|
||||||
|
|
||||||
|
virtual bool CalcAttachments();
|
||||||
|
bool PutAttachment( int number, const Vector &origin, const QAngle &angles );
|
||||||
|
void TermRopes();
|
||||||
|
|
||||||
|
void UpdateRelevantInterpolatedVars();
|
||||||
|
void AddBaseAnimatingInterpolatedVars();
|
||||||
|
void RemoveBaseAnimatingInterpolatedVars();
|
||||||
|
|
||||||
|
public:
|
||||||
|
CRagdoll *m_pRagdoll;
|
||||||
|
|
||||||
|
// Texture group to use
|
||||||
|
int m_nSkin;
|
||||||
|
|
||||||
|
// Object bodygroup
|
||||||
|
int m_nBody;
|
||||||
|
|
||||||
|
// Hitbox set to use (default 0)
|
||||||
|
int m_nHitboxSet;
|
||||||
|
|
||||||
|
CSequenceTransitioner m_SequenceTransitioner;
|
||||||
|
|
||||||
|
protected:
|
||||||
|
CIKContext *m_pIk;
|
||||||
|
|
||||||
|
int m_iEyeAttachment;
|
||||||
|
|
||||||
|
// Animation playback framerate
|
||||||
|
float m_flPlaybackRate;
|
||||||
|
|
||||||
|
// Decomposed ragdoll info
|
||||||
|
bool m_bStoreRagdollInfo;
|
||||||
|
RagdollInfo_t *m_pRagdollInfo;
|
||||||
|
|
||||||
|
// Is bone cache valid
|
||||||
|
// bone transformation matrix
|
||||||
|
unsigned long m_iMostRecentModelBoneCounter;
|
||||||
|
int m_iPrevBoneMask;
|
||||||
|
int m_iAccumulatedBoneMask;
|
||||||
|
|
||||||
|
CBoneAccessor m_BoneAccessor;
|
||||||
|
|
||||||
|
ClientSideAnimationListHandle_t m_ClientSideAnimationListHandle;
|
||||||
|
|
||||||
|
// Client-side animation
|
||||||
|
bool m_bClientSideFrameReset;
|
||||||
|
|
||||||
|
protected:
|
||||||
|
|
||||||
|
float m_fadeMinDist;
|
||||||
|
float m_fadeMaxDist;
|
||||||
|
float m_flFadeScale;
|
||||||
|
|
||||||
|
private:
|
||||||
|
|
||||||
|
float m_flGroundSpeed; // computed linear movement rate for current sequence
|
||||||
|
float m_flLastEventCheck; // cycle index of when events were last checked
|
||||||
|
bool m_bSequenceFinished;// flag set when StudioAdvanceFrame moves across a frame boundry
|
||||||
|
|
||||||
|
Vector m_vecForce;
|
||||||
|
int m_nForceBone;
|
||||||
|
|
||||||
|
// Mouth lipsync/envelope following values
|
||||||
|
CMouthInfo m_mouth;
|
||||||
|
|
||||||
|
CNetworkVar( float, m_flModelWidthScale );
|
||||||
|
|
||||||
|
// Animation blending factors
|
||||||
|
float m_flPoseParameter[MAXSTUDIOPOSEPARAM];
|
||||||
|
CInterpolatedVarArray< float, MAXSTUDIOPOSEPARAM > m_iv_flPoseParameter;
|
||||||
|
|
||||||
|
int m_nPrevSequence;
|
||||||
|
int m_nRestoreSequence;
|
||||||
|
|
||||||
|
// Ropes that got spawned when the model was created.
|
||||||
|
CUtlLinkedList<C_RopeKeyframe*,unsigned short> m_Ropes;
|
||||||
|
|
||||||
|
// event processing info
|
||||||
|
float m_flPrevEventCycle;
|
||||||
|
int m_nEventSequence;
|
||||||
|
|
||||||
|
float m_flEncodedController[MAXSTUDIOBONECTRLS];
|
||||||
|
CInterpolatedVarArray< float, MAXSTUDIOBONECTRLS > m_iv_flEncodedController;
|
||||||
|
|
||||||
|
// Clientside animation
|
||||||
|
bool m_bClientSideAnimation;
|
||||||
|
bool m_bLastClientSideFrameReset;
|
||||||
|
|
||||||
|
int m_nNewSequenceParity;
|
||||||
|
int m_nResetEventsParity;
|
||||||
|
|
||||||
|
int m_nPrevNewSequenceParity;
|
||||||
|
int m_nPrevResetEventsParity;
|
||||||
|
|
||||||
|
bool m_builtRagdoll;
|
||||||
|
Vector m_vecPreRagdollMins;
|
||||||
|
Vector m_vecPreRagdollMaxs;
|
||||||
|
|
||||||
|
// Current animation sequence
|
||||||
|
int m_nSequence;
|
||||||
|
|
||||||
|
// Current cycle location from server
|
||||||
|
float m_flCycle;
|
||||||
|
CInterpolatedVar< float > m_iv_flCycle;
|
||||||
|
float m_flOldCycle;
|
||||||
|
int m_nOldSequence;
|
||||||
|
CBoneMergeCache *m_pBoneMergeCache; // This caches the strcmp lookups that it has to do
|
||||||
|
// when merg
|
||||||
|
|
||||||
|
CUtlVector< matrix3x4_t > m_CachedBoneData; // never access this directly. Use m_BoneAccessor.
|
||||||
|
memhandle_t m_hitboxBoneCacheHandle;
|
||||||
|
|
||||||
|
// Calculated attachment points
|
||||||
|
CUtlVector<CAttachmentData> m_Attachments;
|
||||||
|
|
||||||
|
void SetupBones_AttachmentHelper( CStudioHdr *pStudioHdr );
|
||||||
|
|
||||||
|
EHANDLE m_hLightingOrigin;
|
||||||
|
EHANDLE m_hLightingOriginRelative;
|
||||||
|
|
||||||
|
// These are compared against each other to determine if the entity should muzzle flash.
|
||||||
|
CNetworkVar( unsigned char, m_nMuzzleFlashParity );
|
||||||
|
unsigned char m_nOldMuzzleFlashParity;
|
||||||
|
|
||||||
|
private:
|
||||||
|
mutable CStudioHdr *m_pStudioHdr;
|
||||||
|
};
|
||||||
|
|
||||||
|
enum
|
||||||
|
{
|
||||||
|
RAGDOLL_FRICTION_OFF = -2,
|
||||||
|
RAGDOLL_FRICTION_NONE,
|
||||||
|
RAGDOLL_FRICTION_IN,
|
||||||
|
RAGDOLL_FRICTION_HOLD,
|
||||||
|
RAGDOLL_FRICTION_OUT,
|
||||||
|
};
|
||||||
|
|
||||||
|
class C_ClientRagdoll : public C_BaseAnimating, public IPVSNotify
|
||||||
|
{
|
||||||
|
|
||||||
|
public:
|
||||||
|
C_ClientRagdoll( bool bRestoring = true );
|
||||||
|
DECLARE_CLASS( C_ClientRagdoll, C_BaseAnimating );
|
||||||
|
DECLARE_DATADESC();
|
||||||
|
|
||||||
|
// inherited from IPVSNotify
|
||||||
|
virtual void OnPVSStatusChanged( bool bInPVS );
|
||||||
|
|
||||||
|
virtual void Release( void );
|
||||||
|
virtual void SetupWeights( void );
|
||||||
|
virtual void ImpactTrace( trace_t *pTrace, int iDamageType, char *pCustomImpactName );
|
||||||
|
void ClientThink( void );
|
||||||
|
void ReleaseRagdoll( void ) { m_bReleaseRagdoll = true; }
|
||||||
|
bool ShouldSavePhysics( void ) { return true; }
|
||||||
|
virtual void OnSave();
|
||||||
|
virtual void OnRestore();
|
||||||
|
virtual int ObjectCaps( void ) { return BaseClass::ObjectCaps() | FCAP_SAVE_NON_NETWORKABLE; }
|
||||||
|
virtual IPVSNotify* GetPVSNotifyInterface() { return this; }
|
||||||
|
|
||||||
|
void HandleAnimatedFriction( void );
|
||||||
|
virtual void SUB_Remove( void );
|
||||||
|
|
||||||
|
void FadeOut( void );
|
||||||
|
|
||||||
|
bool m_bFadeOut;
|
||||||
|
bool m_bImportant;
|
||||||
|
float m_flEffectTime;
|
||||||
|
|
||||||
|
private:
|
||||||
|
int m_iCurrentFriction;
|
||||||
|
int m_iMinFriction;
|
||||||
|
int m_iMaxFriction;
|
||||||
|
float m_flFrictionModTime;
|
||||||
|
float m_flFrictionTime;
|
||||||
|
|
||||||
|
int m_iFrictionAnimState;
|
||||||
|
bool m_bReleaseRagdoll;
|
||||||
|
|
||||||
|
bool m_bFadingOut;
|
||||||
|
|
||||||
|
float m_flScaleEnd[NUM_HITBOX_FIRES];
|
||||||
|
float m_flScaleTimeStart[NUM_HITBOX_FIRES];
|
||||||
|
float m_flScaleTimeEnd[NUM_HITBOX_FIRES];
|
||||||
|
};
|
||||||
|
|
||||||
|
//-----------------------------------------------------------------------------
|
||||||
|
// Purpose: Serves the 90% case of calling SetSequence / ResetSequenceInfo.
|
||||||
|
//-----------------------------------------------------------------------------
|
||||||
|
inline void C_BaseAnimating::ResetSequence(int nSequence)
|
||||||
|
{
|
||||||
|
SetSequence( nSequence );
|
||||||
|
ResetSequenceInfo();
|
||||||
|
}
|
||||||
|
|
||||||
|
inline float C_BaseAnimating::GetPlaybackRate()
|
||||||
|
{
|
||||||
|
return m_flPlaybackRate;
|
||||||
|
}
|
||||||
|
|
||||||
|
inline void C_BaseAnimating::SetPlaybackRate( float rate )
|
||||||
|
{
|
||||||
|
m_flPlaybackRate = rate;
|
||||||
|
}
|
||||||
|
|
||||||
|
inline const matrix3x4_t& C_BaseAnimating::GetBone( int iBone ) const
|
||||||
|
{
|
||||||
|
return m_BoneAccessor.GetBone( iBone );
|
||||||
|
}
|
||||||
|
|
||||||
|
inline matrix3x4_t& C_BaseAnimating::GetBoneForWrite( int iBone )
|
||||||
|
{
|
||||||
|
return m_BoneAccessor.GetBoneForWrite( iBone );
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
inline bool C_BaseAnimating::ShouldMuzzleFlash() const
|
||||||
|
{
|
||||||
|
return m_nOldMuzzleFlashParity != m_nMuzzleFlashParity;
|
||||||
|
}
|
||||||
|
|
||||||
|
inline float C_BaseAnimating::GetCycle() const
|
||||||
|
{
|
||||||
|
return m_flCycle;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
//-----------------------------------------------------------------------------
|
||||||
|
// Sequence access
|
||||||
|
//-----------------------------------------------------------------------------
|
||||||
|
inline int C_BaseAnimating::GetSequence()
|
||||||
|
{
|
||||||
|
return m_nSequence;
|
||||||
|
}
|
||||||
|
|
||||||
|
inline bool C_BaseAnimating::IsSequenceFinished( void )
|
||||||
|
{
|
||||||
|
return m_bSequenceFinished;
|
||||||
|
}
|
||||||
|
|
||||||
|
inline float C_BaseAnimating::SequenceDuration( void )
|
||||||
|
{
|
||||||
|
return SequenceDuration( GetSequence() );
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
//-----------------------------------------------------------------------------
|
||||||
|
// Mouth
|
||||||
|
//-----------------------------------------------------------------------------
|
||||||
|
inline CMouthInfo& C_BaseAnimating::MouthInfo()
|
||||||
|
{
|
||||||
|
return m_mouth;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
// FIXME: move these to somewhere that makes sense
|
||||||
|
void GetColumn( matrix3x4_t& src, int column, Vector &dest );
|
||||||
|
void SetColumn( Vector &src, int column, matrix3x4_t& dest );
|
||||||
|
|
||||||
|
EXTERN_RECV_TABLE(DT_BaseAnimating);
|
||||||
|
|
||||||
|
|
||||||
|
extern void DevMsgRT( char const* pMsg, ... );
|
||||||
|
|
||||||
|
#endif // C_BASEANIMATING_H
|
521
cl_dll/c_baseanimatingoverlay.cpp
Normal file
521
cl_dll/c_baseanimatingoverlay.cpp
Normal file
@ -0,0 +1,521 @@
|
|||||||
|
//========= Copyright © 1996-2005, Valve Corporation, All rights reserved. ============//
|
||||||
|
//
|
||||||
|
// Purpose:
|
||||||
|
//
|
||||||
|
// $NoKeywords: $
|
||||||
|
//=============================================================================//
|
||||||
|
|
||||||
|
#include "cbase.h"
|
||||||
|
#include "c_baseanimatingoverlay.h"
|
||||||
|
#include "bone_setup.h"
|
||||||
|
#include "tier0/vprof.h"
|
||||||
|
#include "engine/IVDebugOverlay.h"
|
||||||
|
#include "datacache/imdlcache.h"
|
||||||
|
#include "eventlist.h"
|
||||||
|
|
||||||
|
#include "dt_utlvector_recv.h"
|
||||||
|
|
||||||
|
// memdbgon must be the last include file in a .cpp file!!!
|
||||||
|
#include "tier0/memdbgon.h"
|
||||||
|
|
||||||
|
extern ConVar r_sequence_debug;
|
||||||
|
|
||||||
|
C_BaseAnimatingOverlay::C_BaseAnimatingOverlay()
|
||||||
|
{
|
||||||
|
// FIXME: where does this initialization go now?
|
||||||
|
//for ( int i=0; i < MAX_OVERLAYS; i++ )
|
||||||
|
//{
|
||||||
|
// memset( &m_Layer[i], 0, sizeof(m_Layer[0]) );
|
||||||
|
// m_Layer[i].m_nOrder = MAX_OVERLAYS;
|
||||||
|
//}
|
||||||
|
|
||||||
|
// FIXME: where does this initialization go now?
|
||||||
|
// AddVar( m_Layer, &m_iv_AnimOverlay, LATCH_ANIMATION_VAR );
|
||||||
|
}
|
||||||
|
|
||||||
|
#undef CBaseAnimatingOverlay
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
BEGIN_RECV_TABLE_NOBASE(CAnimationLayer, DT_Animationlayer)
|
||||||
|
RecvPropInt( RECVINFO_NAME(m_nSequence, m_nSequence)),
|
||||||
|
RecvPropFloat( RECVINFO_NAME(m_flCycle, m_flCycle)),
|
||||||
|
RecvPropFloat( RECVINFO_NAME(m_flPrevCycle, m_flPrevCycle)),
|
||||||
|
RecvPropFloat( RECVINFO_NAME(m_flWeight, m_flWeight)),
|
||||||
|
RecvPropInt( RECVINFO_NAME(m_nOrder, m_nOrder))
|
||||||
|
END_RECV_TABLE()
|
||||||
|
|
||||||
|
const char *s_m_iv_AnimOverlayNames[C_BaseAnimatingOverlay::MAX_OVERLAYS] =
|
||||||
|
{
|
||||||
|
"C_BaseAnimatingOverlay::m_iv_AnimOverlay00",
|
||||||
|
"C_BaseAnimatingOverlay::m_iv_AnimOverlay01",
|
||||||
|
"C_BaseAnimatingOverlay::m_iv_AnimOverlay02",
|
||||||
|
"C_BaseAnimatingOverlay::m_iv_AnimOverlay03",
|
||||||
|
"C_BaseAnimatingOverlay::m_iv_AnimOverlay04",
|
||||||
|
"C_BaseAnimatingOverlay::m_iv_AnimOverlay05",
|
||||||
|
"C_BaseAnimatingOverlay::m_iv_AnimOverlay06",
|
||||||
|
"C_BaseAnimatingOverlay::m_iv_AnimOverlay07",
|
||||||
|
"C_BaseAnimatingOverlay::m_iv_AnimOverlay08",
|
||||||
|
"C_BaseAnimatingOverlay::m_iv_AnimOverlay09",
|
||||||
|
"C_BaseAnimatingOverlay::m_iv_AnimOverlay10",
|
||||||
|
"C_BaseAnimatingOverlay::m_iv_AnimOverlay11",
|
||||||
|
"C_BaseAnimatingOverlay::m_iv_AnimOverlay12",
|
||||||
|
"C_BaseAnimatingOverlay::m_iv_AnimOverlay13",
|
||||||
|
"C_BaseAnimatingOverlay::m_iv_AnimOverlay14"
|
||||||
|
};
|
||||||
|
|
||||||
|
void ResizeAnimationLayerCallback( void *pStruct, int offsetToUtlVector, int len )
|
||||||
|
{
|
||||||
|
C_BaseAnimatingOverlay *pEnt = (C_BaseAnimatingOverlay*)pStruct;
|
||||||
|
CUtlVector < C_AnimationLayer > *pVec = &pEnt->m_AnimOverlay;
|
||||||
|
CUtlVector< CInterpolatedVar< C_AnimationLayer > > *pVecIV = &pEnt->m_iv_AnimOverlay;
|
||||||
|
|
||||||
|
Assert( (char*)pVec - (char*)pEnt == offsetToUtlVector );
|
||||||
|
Assert( pVec->Count() == pVecIV->Count() );
|
||||||
|
Assert( pVec->Count() <= C_BaseAnimatingOverlay::MAX_OVERLAYS );
|
||||||
|
|
||||||
|
int diff = len - pVec->Count();
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
if ( diff == 0 )
|
||||||
|
return;
|
||||||
|
|
||||||
|
// remove all entries
|
||||||
|
for ( int i=0; i < pVec->Count(); i++ )
|
||||||
|
{
|
||||||
|
pEnt->RemoveVar( &pVec->Element( i ) );
|
||||||
|
}
|
||||||
|
|
||||||
|
// adjust vector sizes
|
||||||
|
if ( diff > 0 )
|
||||||
|
{
|
||||||
|
pVec->AddMultipleToTail( diff );
|
||||||
|
pVecIV->AddMultipleToTail( diff );
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
pVec->RemoveMultiple( len, -diff );
|
||||||
|
pVecIV->RemoveMultiple( len, -diff );
|
||||||
|
}
|
||||||
|
|
||||||
|
// Rebind all the variables in the ent's list.
|
||||||
|
for ( int i=0; i < len; i++ )
|
||||||
|
{
|
||||||
|
IInterpolatedVar *pWatcher = &pVecIV->Element( i );
|
||||||
|
pWatcher->SetDebugName( s_m_iv_AnimOverlayNames[i] );
|
||||||
|
pEnt->AddVar( &pVec->Element( i ), pWatcher, LATCH_ANIMATION_VAR, true );
|
||||||
|
}
|
||||||
|
// FIXME: need to set historical values of nOrder in pVecIV to MAX_OVERLAY
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
BEGIN_RECV_TABLE_NOBASE( C_BaseAnimatingOverlay, DT_OverlayVars )
|
||||||
|
RecvPropUtlVector(
|
||||||
|
RECVINFO_UTLVECTOR_SIZEFN( m_AnimOverlay, ResizeAnimationLayerCallback ),
|
||||||
|
C_BaseAnimatingOverlay::MAX_OVERLAYS,
|
||||||
|
RecvPropDataTable(NULL, 0, 0, &REFERENCE_RECV_TABLE( DT_Animationlayer ) ) )
|
||||||
|
END_RECV_TABLE()
|
||||||
|
|
||||||
|
|
||||||
|
IMPLEMENT_CLIENTCLASS_DT( C_BaseAnimatingOverlay, DT_BaseAnimatingOverlay, CBaseAnimatingOverlay )
|
||||||
|
RecvPropDataTable( "overlay_vars", 0, 0, &REFERENCE_RECV_TABLE( DT_OverlayVars ) )
|
||||||
|
END_RECV_TABLE()
|
||||||
|
|
||||||
|
BEGIN_PREDICTION_DATA( C_BaseAnimatingOverlay )
|
||||||
|
|
||||||
|
/*
|
||||||
|
DEFINE_FIELD( C_BaseAnimatingOverlay, m_Layer[0][2].m_nSequence, FIELD_INTEGER ),
|
||||||
|
DEFINE_FIELD( C_BaseAnimatingOverlay, m_Layer[0][2].m_flCycle, FIELD_FLOAT ),
|
||||||
|
DEFINE_FIELD( C_BaseAnimatingOverlay, m_Layer[0][2].m_flPlaybackRate, FIELD_FLOAT),
|
||||||
|
DEFINE_FIELD( C_BaseAnimatingOverlay, m_Layer[0][2].m_flWeight, FIELD_FLOAT),
|
||||||
|
DEFINE_FIELD( C_BaseAnimatingOverlay, m_Layer[1][2].m_nSequence, FIELD_INTEGER ),
|
||||||
|
DEFINE_FIELD( C_BaseAnimatingOverlay, m_Layer[1][2].m_flCycle, FIELD_FLOAT ),
|
||||||
|
DEFINE_FIELD( C_BaseAnimatingOverlay, m_Layer[1][2].m_flPlaybackRate, FIELD_FLOAT),
|
||||||
|
DEFINE_FIELD( C_BaseAnimatingOverlay, m_Layer[1][2].m_flWeight, FIELD_FLOAT),
|
||||||
|
DEFINE_FIELD( C_BaseAnimatingOverlay, m_Layer[2][2].m_nSequence, FIELD_INTEGER ),
|
||||||
|
DEFINE_FIELD( C_BaseAnimatingOverlay, m_Layer[2][2].m_flCycle, FIELD_FLOAT ),
|
||||||
|
DEFINE_FIELD( C_BaseAnimatingOverlay, m_Layer[2][2].m_flPlaybackRate, FIELD_FLOAT),
|
||||||
|
DEFINE_FIELD( C_BaseAnimatingOverlay, m_Layer[2][2].m_flWeight, FIELD_FLOAT),
|
||||||
|
DEFINE_FIELD( C_BaseAnimatingOverlay, m_Layer[3][2].m_nSequence, FIELD_INTEGER ),
|
||||||
|
DEFINE_FIELD( C_BaseAnimatingOverlay, m_Layer[3][2].m_flCycle, FIELD_FLOAT ),
|
||||||
|
DEFINE_FIELD( C_BaseAnimatingOverlay, m_Layer[3][2].m_flPlaybackRate, FIELD_FLOAT),
|
||||||
|
DEFINE_FIELD( C_BaseAnimatingOverlay, m_Layer[3][2].m_flWeight, FIELD_FLOAT),
|
||||||
|
*/
|
||||||
|
|
||||||
|
END_PREDICTION_DATA()
|
||||||
|
|
||||||
|
C_AnimationLayer* C_BaseAnimatingOverlay::GetAnimOverlay( int i )
|
||||||
|
{
|
||||||
|
Assert( i >= 0 && i < MAX_OVERLAYS );
|
||||||
|
return &m_AnimOverlay[i];
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void C_BaseAnimatingOverlay::SetNumAnimOverlays( int num )
|
||||||
|
{
|
||||||
|
if ( m_AnimOverlay.Count() < num )
|
||||||
|
{
|
||||||
|
m_AnimOverlay.AddMultipleToTail( num - m_AnimOverlay.Count() );
|
||||||
|
}
|
||||||
|
else if ( m_AnimOverlay.Count() > num )
|
||||||
|
{
|
||||||
|
m_AnimOverlay.RemoveMultiple( num, m_AnimOverlay.Count() - num );
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
int C_BaseAnimatingOverlay::GetNumAnimOverlays() const
|
||||||
|
{
|
||||||
|
return m_AnimOverlay.Count();
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void C_BaseAnimatingOverlay::GetRenderBounds( Vector& theMins, Vector& theMaxs )
|
||||||
|
{
|
||||||
|
BaseClass::GetRenderBounds( theMins, theMaxs );
|
||||||
|
|
||||||
|
if ( !IsRagdoll() )
|
||||||
|
{
|
||||||
|
CStudioHdr *pStudioHdr = GetModelPtr();
|
||||||
|
if ( !pStudioHdr || !pStudioHdr->SequencesAvailable() )
|
||||||
|
return;
|
||||||
|
|
||||||
|
int nSequences = pStudioHdr->GetNumSeq();
|
||||||
|
|
||||||
|
int i;
|
||||||
|
for (i = 0; i < m_AnimOverlay.Count(); i++)
|
||||||
|
{
|
||||||
|
if (m_AnimOverlay[i].m_flWeight > 0.0)
|
||||||
|
{
|
||||||
|
if ( m_AnimOverlay[i].m_nSequence >= nSequences )
|
||||||
|
{
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
mstudioseqdesc_t &seqdesc = pStudioHdr->pSeqdesc( m_AnimOverlay[i].m_nSequence );
|
||||||
|
VectorMin( seqdesc.bbmin, theMins, theMins );
|
||||||
|
VectorMax( seqdesc.bbmax, theMaxs, theMaxs );
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
void C_BaseAnimatingOverlay::CheckForLayerChanges( CStudioHdr *hdr, float currentTime )
|
||||||
|
{
|
||||||
|
CDisableRangeChecks disableRangeChecks;
|
||||||
|
|
||||||
|
// FIXME: damn, there has to be a better way than this.
|
||||||
|
int i;
|
||||||
|
for (i = 0; i < m_iv_AnimOverlay.Count(); i++)
|
||||||
|
{
|
||||||
|
CDisableRangeChecks disableRangeChecks;
|
||||||
|
|
||||||
|
int iHead, iPrev1, iPrev2;
|
||||||
|
m_iv_AnimOverlay[i].GetInterpolationInfo( currentTime, &iHead, &iPrev1, &iPrev2 );
|
||||||
|
|
||||||
|
// fake up previous cycle values.
|
||||||
|
float t0;
|
||||||
|
C_AnimationLayer *pHead = m_iv_AnimOverlay[i].GetHistoryValue( iHead, t0 );
|
||||||
|
// reset previous
|
||||||
|
float t1;
|
||||||
|
C_AnimationLayer *pPrev1 = m_iv_AnimOverlay[i].GetHistoryValue( iPrev1, t1 );
|
||||||
|
// reset previous previous
|
||||||
|
float t2;
|
||||||
|
C_AnimationLayer *pPrev2 = m_iv_AnimOverlay[i].GetHistoryValue( iPrev2, t2 );
|
||||||
|
|
||||||
|
if ( pHead && pPrev1 && pHead->m_nSequence != pPrev1->m_nSequence )
|
||||||
|
{
|
||||||
|
#if _DEBUG
|
||||||
|
if (Q_stristr( hdr->pszName(), r_sequence_debug.GetString()) != NULL)
|
||||||
|
{
|
||||||
|
DevMsgRT( "(%5.2f : %30s : %5.3f : %4.2f : %1d)\n", t0, hdr->pSeqdesc( pHead->m_nSequence ).pszLabel(), (float)pHead->m_flCycle, (float)pHead->m_flWeight, i );
|
||||||
|
DevMsgRT( "(%5.2f : %30s : %5.3f : %4.2f : %1d)\n", t1, hdr->pSeqdesc( pPrev1->m_nSequence ).pszLabel(), (float)pPrev1->m_flCycle, (float)pPrev1->m_flWeight, i );
|
||||||
|
if (pPrev2)
|
||||||
|
DevMsgRT( "(%5.2f : %30s : %5.3f : %4.2f : %1d)\n", t2, hdr->pSeqdesc( pPrev2->m_nSequence ).pszLabel(), (float)pPrev2->m_flCycle, (float)pPrev2->m_flWeight, i );
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
if (pPrev1)
|
||||||
|
{
|
||||||
|
pPrev1->m_nSequence = pHead->m_nSequence;
|
||||||
|
pPrev1->m_flCycle = pHead->m_flPrevCycle;
|
||||||
|
pPrev1->m_flWeight = pHead->m_flWeight;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (pPrev2)
|
||||||
|
{
|
||||||
|
float num = 0;
|
||||||
|
if ( fabs( t0 - t1 ) > 0.001f )
|
||||||
|
num = (t2 - t1) / (t0 - t1);
|
||||||
|
|
||||||
|
pPrev2->m_nSequence = pHead->m_nSequence;
|
||||||
|
float flTemp;
|
||||||
|
if (IsSequenceLooping( hdr, pHead->m_nSequence ))
|
||||||
|
{
|
||||||
|
flTemp = LoopingLerp( num, (float)pHead->m_flPrevCycle, (float)pHead->m_flCycle );
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
flTemp = Lerp( num, (float)pHead->m_flPrevCycle, (float)pHead->m_flCycle );
|
||||||
|
}
|
||||||
|
pPrev2->m_flCycle = flTemp;
|
||||||
|
pPrev2->m_flWeight = pHead->m_flWeight;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
if (stricmp( r_seq_overlay_debug.GetString(), hdr->name ) == 0)
|
||||||
|
{
|
||||||
|
DevMsgRT( "(%30s %6.2f : %6.2f : %6.2f)\n", hdr->pSeqdesc( pHead->nSequence ).pszLabel(), (float)pPrev2->m_flCycle, (float)pPrev1->m_flCycle, (float)pHead->m_flCycle );
|
||||||
|
}
|
||||||
|
*/
|
||||||
|
|
||||||
|
m_iv_AnimOverlay[i].SetLooping( IsSequenceLooping( hdr, pHead->m_nSequence ) );
|
||||||
|
m_iv_AnimOverlay[i].Interpolate( currentTime );
|
||||||
|
|
||||||
|
// reset event indexes
|
||||||
|
m_flOverlayPrevEventCycle[i] = pHead->m_flPrevCycle - 0.01;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
void C_BaseAnimatingOverlay::AccumulateLayers( CStudioHdr *hdr, Vector pos[], Quaternion q[], float poseparam[], float currentTime, int boneMask )
|
||||||
|
{
|
||||||
|
BaseClass::AccumulateLayers( hdr, pos, q, poseparam, currentTime, boneMask );
|
||||||
|
int i;
|
||||||
|
|
||||||
|
// resort the layers
|
||||||
|
int layer[MAX_OVERLAYS];
|
||||||
|
for (i = 0; i < MAX_OVERLAYS; i++)
|
||||||
|
{
|
||||||
|
layer[i] = MAX_OVERLAYS;
|
||||||
|
}
|
||||||
|
for (i = 0; i < m_AnimOverlay.Count(); i++)
|
||||||
|
{
|
||||||
|
if (m_AnimOverlay[i].m_nOrder < MAX_OVERLAYS)
|
||||||
|
{
|
||||||
|
/*
|
||||||
|
Assert( layer[m_AnimOverlay[i].m_nOrder] == MAX_OVERLAYS );
|
||||||
|
layer[m_AnimOverlay[i].m_nOrder] = i;
|
||||||
|
*/
|
||||||
|
// hacky code until initialization of new layers is finished
|
||||||
|
if (layer[m_AnimOverlay[i].m_nOrder] != MAX_OVERLAYS)
|
||||||
|
{
|
||||||
|
m_AnimOverlay[i].m_nOrder = MAX_OVERLAYS;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
layer[m_AnimOverlay[i].m_nOrder] = i;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
CheckForLayerChanges( hdr, currentTime );
|
||||||
|
|
||||||
|
int nSequences = hdr->GetNumSeq();
|
||||||
|
|
||||||
|
// add in the overlay layers
|
||||||
|
int j;
|
||||||
|
for (j = 0; j < MAX_OVERLAYS; j++)
|
||||||
|
{
|
||||||
|
i = layer[ j ];
|
||||||
|
if (i < m_AnimOverlay.Count())
|
||||||
|
{
|
||||||
|
if ( m_AnimOverlay[i].m_nSequence >= nSequences )
|
||||||
|
{
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
DevMsgRT( 1 , "%.3f %.3f %.3f\n", currentTime, fWeight, dadt );
|
||||||
|
debugoverlay->AddTextOverlay( GetAbsOrigin() + Vector( 0, 0, 64 ), -j - 1, 0,
|
||||||
|
"%2d(%s) : %6.2f : %6.2f",
|
||||||
|
m_AnimOverlay[i].m_nSequence,
|
||||||
|
hdr->pSeqdesc( m_AnimOverlay[i].m_nSequence )->pszLabel(),
|
||||||
|
m_AnimOverlay[i].m_flCycle,
|
||||||
|
m_AnimOverlay[i].m_flWeight
|
||||||
|
);
|
||||||
|
*/
|
||||||
|
|
||||||
|
float fWeight = m_AnimOverlay[i].m_flWeight;
|
||||||
|
|
||||||
|
if (fWeight > 0)
|
||||||
|
{
|
||||||
|
// check to see if the sequence changed
|
||||||
|
// FIXME: move this to somewhere more reasonable
|
||||||
|
// do a nice spline interpolation of the values
|
||||||
|
// if ( m_AnimOverlay[i].m_nSequence != m_iv_AnimOverlay.GetPrev( i )->nSequence )
|
||||||
|
float fCycle = m_AnimOverlay[ i ].m_flCycle;
|
||||||
|
|
||||||
|
fCycle = ClampCycle( fCycle, IsSequenceLooping( m_AnimOverlay[i].m_nSequence ) );
|
||||||
|
|
||||||
|
if (fWeight > 1)
|
||||||
|
fWeight = 1;
|
||||||
|
|
||||||
|
AccumulatePose( hdr, m_pIk, pos, q, m_AnimOverlay[i].m_nSequence, fCycle, poseparam, boneMask, fWeight, currentTime );
|
||||||
|
|
||||||
|
#if _DEBUG
|
||||||
|
if (Q_stristr( hdr->pszName(), r_sequence_debug.GetString()) != NULL)
|
||||||
|
{
|
||||||
|
if (1)
|
||||||
|
{
|
||||||
|
DevMsgRT( "%6.2f : %30s : %5.3f : %4.2f : %1d\n", currentTime, hdr->pSeqdesc( m_AnimOverlay[i].m_nSequence ).pszLabel(), fCycle, fWeight, i );
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
int iHead, iPrev1, iPrev2;
|
||||||
|
m_iv_AnimOverlay[i].GetInterpolationInfo( currentTime, &iHead, &iPrev1, &iPrev2 );
|
||||||
|
|
||||||
|
// fake up previous cycle values.
|
||||||
|
float t0;
|
||||||
|
C_AnimationLayer *pHead = m_iv_AnimOverlay[i].GetHistoryValue( iHead, t0 );
|
||||||
|
// reset previous
|
||||||
|
float t1;
|
||||||
|
C_AnimationLayer *pPrev1 = m_iv_AnimOverlay[i].GetHistoryValue( iPrev1, t1 );
|
||||||
|
// reset previous previous
|
||||||
|
float t2;
|
||||||
|
C_AnimationLayer *pPrev2 = m_iv_AnimOverlay[i].GetHistoryValue( iPrev2, t2 );
|
||||||
|
|
||||||
|
if ( pHead && pPrev1 && pPrev2 )
|
||||||
|
{
|
||||||
|
DevMsgRT( "%6.2f : %30s %6.2f (%6.2f:%6.2f:%6.2f) : %6.2f (%6.2f:%6.2f:%6.2f) : %1d\n", currentTime, hdr->pSeqdesc( m_AnimOverlay[i].m_nSequence ).pszLabel(),
|
||||||
|
fCycle, (float)pPrev2->m_flCycle, (float)pPrev1->m_flCycle, (float)pHead->m_flCycle,
|
||||||
|
fWeight, (float)pPrev2->m_flWeight, (float)pPrev1->m_flWeight, (float)pHead->m_flWeight,
|
||||||
|
i );
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
DevMsgRT( "%6.2f : %30s %6.2f : %6.2f : %1d\n", currentTime, hdr->pSeqdesc( m_AnimOverlay[i].m_nSequence ).pszLabel(), fCycle, fWeight, i );
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void C_BaseAnimatingOverlay::DoAnimationEvents( CStudioHdr *pStudioHdr )
|
||||||
|
{
|
||||||
|
if ( !pStudioHdr || !pStudioHdr->SequencesAvailable() )
|
||||||
|
return;
|
||||||
|
|
||||||
|
MDLCACHE_CRITICAL_SECTION();
|
||||||
|
|
||||||
|
int nSequences = pStudioHdr->GetNumSeq();
|
||||||
|
|
||||||
|
BaseClass::DoAnimationEvents( pStudioHdr );
|
||||||
|
|
||||||
|
bool watch = false; // Q_strstr( hdr->name, "rifle" ) ? true : false;
|
||||||
|
|
||||||
|
CheckForLayerChanges( pStudioHdr, gpGlobals->curtime ); // !!!
|
||||||
|
|
||||||
|
int j;
|
||||||
|
for (j = 0; j < m_AnimOverlay.Count(); j++)
|
||||||
|
{
|
||||||
|
if ( m_AnimOverlay[j].m_nSequence >= nSequences )
|
||||||
|
{
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
mstudioseqdesc_t &seqdesc = pStudioHdr->pSeqdesc( m_AnimOverlay[j].m_nSequence );
|
||||||
|
if ( seqdesc.numevents == 0 )
|
||||||
|
continue;
|
||||||
|
|
||||||
|
// stalled?
|
||||||
|
if (m_AnimOverlay[j].m_flCycle == m_flOverlayPrevEventCycle[j])
|
||||||
|
continue;
|
||||||
|
|
||||||
|
// check for looping
|
||||||
|
BOOL bLooped = false;
|
||||||
|
if (m_AnimOverlay[j].m_flCycle <= m_flOverlayPrevEventCycle[j])
|
||||||
|
{
|
||||||
|
if (m_flOverlayPrevEventCycle[j] - m_AnimOverlay[j].m_flCycle > 0.5)
|
||||||
|
{
|
||||||
|
bLooped = true;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
// things have backed up, which is bad since it'll probably result in a hitch in the animation playback
|
||||||
|
// but, don't play events again for the same time slice
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
mstudioevent_t *pevent = seqdesc.pEvent( 0 );
|
||||||
|
|
||||||
|
// This makes sure events that occur at the end of a sequence occur are
|
||||||
|
// sent before events that occur at the beginning of a sequence.
|
||||||
|
if (bLooped)
|
||||||
|
{
|
||||||
|
for (int i = 0; i < (int)seqdesc.numevents; i++)
|
||||||
|
{
|
||||||
|
// ignore all non-client-side events
|
||||||
|
if ( pevent[i].type & AE_TYPE_NEWEVENTSYSTEM )
|
||||||
|
{
|
||||||
|
if ( !( pevent[i].type & AE_TYPE_CLIENT ) )
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
else if ( pevent[i].event < 5000 ) //Adrian - Support the old event system
|
||||||
|
continue;
|
||||||
|
|
||||||
|
if ( pevent[i].cycle <= m_flOverlayPrevEventCycle[j] )
|
||||||
|
continue;
|
||||||
|
|
||||||
|
if ( watch )
|
||||||
|
{
|
||||||
|
Msg( "%i FE %i Looped cycle %f, prev %f ev %f (time %.3f)\n",
|
||||||
|
gpGlobals->tickcount,
|
||||||
|
pevent[i].event,
|
||||||
|
pevent[i].cycle,
|
||||||
|
m_flOverlayPrevEventCycle[j],
|
||||||
|
m_AnimOverlay[j].m_flCycle,
|
||||||
|
gpGlobals->curtime );
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
FireEvent( GetAbsOrigin(), GetAbsAngles(), pevent[ i ].event, pevent[ i ].pszOptions() );
|
||||||
|
}
|
||||||
|
|
||||||
|
// Necessary to get the next loop working
|
||||||
|
m_flOverlayPrevEventCycle[j] = -0.01;
|
||||||
|
}
|
||||||
|
|
||||||
|
for (int i = 0; i < (int)seqdesc.numevents; i++)
|
||||||
|
{
|
||||||
|
if ( pevent[i].type & AE_TYPE_NEWEVENTSYSTEM )
|
||||||
|
{
|
||||||
|
if ( !( pevent[i].type & AE_TYPE_CLIENT ) )
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
else if ( pevent[i].event < 5000 ) //Adrian - Support the old event system
|
||||||
|
continue;
|
||||||
|
|
||||||
|
if ( (pevent[i].cycle > m_flOverlayPrevEventCycle[j] && pevent[i].cycle <= m_AnimOverlay[j].m_flCycle) )
|
||||||
|
{
|
||||||
|
if ( watch )
|
||||||
|
{
|
||||||
|
Msg( "%i (seq: %d) FE %i Normal cycle %f, prev %f ev %f (time %.3f)\n",
|
||||||
|
gpGlobals->tickcount,
|
||||||
|
m_AnimOverlay[j].m_nSequence,
|
||||||
|
pevent[i].event,
|
||||||
|
pevent[i].cycle,
|
||||||
|
m_flOverlayPrevEventCycle[j],
|
||||||
|
m_AnimOverlay[j].m_flCycle,
|
||||||
|
gpGlobals->curtime );
|
||||||
|
}
|
||||||
|
|
||||||
|
FireEvent( GetAbsOrigin(), GetAbsAngles(), pevent[ i ].event, pevent[ i ].pszOptions() );
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
m_flOverlayPrevEventCycle[j] = m_AnimOverlay[j].m_flCycle;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
66
cl_dll/c_baseanimatingoverlay.h
Normal file
66
cl_dll/c_baseanimatingoverlay.h
Normal file
@ -0,0 +1,66 @@
|
|||||||
|
//========= Copyright © 1996-2005, Valve Corporation, All rights reserved. ============//
|
||||||
|
//
|
||||||
|
// Purpose:
|
||||||
|
//
|
||||||
|
// $NoKeywords: $
|
||||||
|
//
|
||||||
|
//=============================================================================//
|
||||||
|
|
||||||
|
#ifndef C_BASEANIMATINGOVERLAY_H
|
||||||
|
#define C_BASEANIMATINGOVERLAY_H
|
||||||
|
#pragma once
|
||||||
|
|
||||||
|
#include "c_baseanimating.h"
|
||||||
|
|
||||||
|
// For shared code.
|
||||||
|
#define CBaseAnimatingOverlay C_BaseAnimatingOverlay
|
||||||
|
|
||||||
|
|
||||||
|
class C_BaseAnimatingOverlay : public C_BaseAnimating
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
DECLARE_CLASS( C_BaseAnimatingOverlay, C_BaseAnimating );
|
||||||
|
DECLARE_CLIENTCLASS();
|
||||||
|
DECLARE_PREDICTABLE();
|
||||||
|
DECLARE_INTERPOLATION();
|
||||||
|
|
||||||
|
|
||||||
|
C_BaseAnimatingOverlay();
|
||||||
|
|
||||||
|
C_AnimationLayer* GetAnimOverlay( int i );
|
||||||
|
void SetNumAnimOverlays( int num ); // This makes sure there is space for this # of layers.
|
||||||
|
int GetNumAnimOverlays() const;
|
||||||
|
|
||||||
|
virtual void GetRenderBounds( Vector& theMins, Vector& theMaxs );
|
||||||
|
|
||||||
|
void CheckForLayerChanges( CStudioHdr *hdr, float currentTime );
|
||||||
|
|
||||||
|
// model specific
|
||||||
|
virtual void AccumulateLayers( CStudioHdr *hdr, Vector pos[], Quaternion q[], float poseparam[], float currentTime, int boneMask );
|
||||||
|
|
||||||
|
virtual void DoAnimationEvents( CStudioHdr *pStudioHdr );
|
||||||
|
|
||||||
|
enum
|
||||||
|
{
|
||||||
|
MAX_OVERLAYS = 15,
|
||||||
|
};
|
||||||
|
|
||||||
|
CUtlVector < C_AnimationLayer > m_AnimOverlay;
|
||||||
|
|
||||||
|
CUtlVector < CInterpolatedVar< C_AnimationLayer > > m_iv_AnimOverlay;
|
||||||
|
|
||||||
|
float m_flOverlayPrevEventCycle[ MAX_OVERLAYS ];
|
||||||
|
|
||||||
|
private:
|
||||||
|
C_BaseAnimatingOverlay( const C_BaseAnimatingOverlay & ); // not defined, not accessible
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
EXTERN_RECV_TABLE(DT_BaseAnimatingOverlay);
|
||||||
|
|
||||||
|
|
||||||
|
#endif // C_BASEANIMATINGOVERLAY_H
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
72
cl_dll/c_basecombatcharacter.cpp
Normal file
72
cl_dll/c_basecombatcharacter.cpp
Normal file
@ -0,0 +1,72 @@
|
|||||||
|
//========= Copyright © 1996-2005, Valve Corporation, All rights reserved. ============//
|
||||||
|
//
|
||||||
|
// Purpose: Client's C_BaseCombatCharacter entity
|
||||||
|
//
|
||||||
|
// $Workfile: $
|
||||||
|
// $Date: $
|
||||||
|
//
|
||||||
|
//-----------------------------------------------------------------------------
|
||||||
|
// $Log: $
|
||||||
|
//
|
||||||
|
// $NoKeywords: $
|
||||||
|
//=============================================================================//
|
||||||
|
#include "cbase.h"
|
||||||
|
#include "c_basecombatcharacter.h"
|
||||||
|
|
||||||
|
// memdbgon must be the last include file in a .cpp file!!!
|
||||||
|
#include "tier0/memdbgon.h"
|
||||||
|
|
||||||
|
#if defined( CBaseCombatCharacter )
|
||||||
|
#undef CBaseCombatCharacter
|
||||||
|
#endif
|
||||||
|
|
||||||
|
//-----------------------------------------------------------------------------
|
||||||
|
// Purpose:
|
||||||
|
//-----------------------------------------------------------------------------
|
||||||
|
C_BaseCombatCharacter::C_BaseCombatCharacter()
|
||||||
|
{
|
||||||
|
for ( int i=0; i < m_iAmmo.Count(); i++ )
|
||||||
|
m_iAmmo.Set( i, 0 );
|
||||||
|
}
|
||||||
|
|
||||||
|
//-----------------------------------------------------------------------------
|
||||||
|
// Purpose:
|
||||||
|
//-----------------------------------------------------------------------------
|
||||||
|
C_BaseCombatCharacter::~C_BaseCombatCharacter()
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
//-----------------------------------------------------------------------------
|
||||||
|
// Purpose: Returns the amount of ammunition of the specified type the character's carrying
|
||||||
|
//-----------------------------------------------------------------------------
|
||||||
|
int C_BaseCombatCharacter::GetAmmoCount( char *szName ) const
|
||||||
|
{
|
||||||
|
return GetAmmoCount( g_pGameRules->GetAmmoDef()->Index(szName) );
|
||||||
|
}
|
||||||
|
*/
|
||||||
|
|
||||||
|
IMPLEMENT_CLIENTCLASS(C_BaseCombatCharacter, DT_BaseCombatCharacter, CBaseCombatCharacter);
|
||||||
|
|
||||||
|
// Only send active weapon index to local player
|
||||||
|
BEGIN_RECV_TABLE_NOBASE( C_BaseCombatCharacter, DT_BCCLocalPlayerExclusive )
|
||||||
|
RecvPropTime( RECVINFO( m_flNextAttack ) ),
|
||||||
|
RecvPropArray3( RECVINFO_ARRAY(m_hMyWeapons), RecvPropEHandle( RECVINFO( m_hMyWeapons[0] ) ) ),
|
||||||
|
END_RECV_TABLE();
|
||||||
|
|
||||||
|
|
||||||
|
BEGIN_RECV_TABLE(C_BaseCombatCharacter, DT_BaseCombatCharacter)
|
||||||
|
RecvPropDataTable( "bcc_localdata", 0, 0, &REFERENCE_RECV_TABLE(DT_BCCLocalPlayerExclusive) ),
|
||||||
|
RecvPropEHandle( RECVINFO( m_hActiveWeapon ) ),
|
||||||
|
|
||||||
|
END_RECV_TABLE()
|
||||||
|
|
||||||
|
|
||||||
|
BEGIN_PREDICTION_DATA( C_BaseCombatCharacter )
|
||||||
|
|
||||||
|
DEFINE_PRED_ARRAY( m_iAmmo, FIELD_INTEGER, MAX_AMMO_TYPES, FTYPEDESC_INSENDTABLE ),
|
||||||
|
DEFINE_PRED_FIELD( m_flNextAttack, FIELD_FLOAT, FTYPEDESC_INSENDTABLE ),
|
||||||
|
DEFINE_PRED_FIELD( m_hActiveWeapon, FIELD_EHANDLE, FTYPEDESC_INSENDTABLE ),
|
||||||
|
DEFINE_PRED_ARRAY( m_hMyWeapons, FIELD_EHANDLE, MAX_WEAPONS, FTYPEDESC_INSENDTABLE ),
|
||||||
|
|
||||||
|
END_PREDICTION_DATA()
|
101
cl_dll/c_basecombatcharacter.h
Normal file
101
cl_dll/c_basecombatcharacter.h
Normal file
@ -0,0 +1,101 @@
|
|||||||
|
//========= Copyright © 1996-2005, Valve Corporation, All rights reserved. ============//
|
||||||
|
//
|
||||||
|
// Purpose: Defines the client-side representation of CBaseCombatCharacter.
|
||||||
|
//
|
||||||
|
// $NoKeywords: $
|
||||||
|
//=============================================================================//
|
||||||
|
|
||||||
|
#ifndef C_BASECOMBATCHARACTER_H
|
||||||
|
#define C_BASECOMBATCHARACTER_H
|
||||||
|
|
||||||
|
#ifdef _WIN32
|
||||||
|
#pragma once
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#include "shareddefs.h"
|
||||||
|
#include "c_baseflex.h"
|
||||||
|
|
||||||
|
class C_BaseCombatWeapon;
|
||||||
|
class C_WeaponCombatShield;
|
||||||
|
|
||||||
|
class C_BaseCombatCharacter : public C_BaseFlex
|
||||||
|
{
|
||||||
|
DECLARE_CLASS( C_BaseCombatCharacter, C_BaseFlex );
|
||||||
|
public:
|
||||||
|
DECLARE_CLIENTCLASS();
|
||||||
|
DECLARE_PREDICTABLE();
|
||||||
|
|
||||||
|
C_BaseCombatCharacter( void );
|
||||||
|
virtual ~C_BaseCombatCharacter( void );
|
||||||
|
|
||||||
|
virtual bool IsBaseCombatCharacter( void ) { return true; };
|
||||||
|
virtual C_BaseCombatCharacter *MyCombatCharacterPointer( void ) { return this; }
|
||||||
|
|
||||||
|
// -----------------------
|
||||||
|
// Ammo
|
||||||
|
// -----------------------
|
||||||
|
void RemoveAmmo( int iCount, int iAmmoIndex );
|
||||||
|
void RemoveAmmo( int iCount, const char *szName );
|
||||||
|
void RemoveAllAmmo( );
|
||||||
|
int GetAmmoCount( int iAmmoIndex ) const;
|
||||||
|
int GetAmmoCount( char *szName ) const;
|
||||||
|
|
||||||
|
C_BaseCombatWeapon* Weapon_OwnsThisType( const char *pszWeapon, int iSubType = 0 ) const; // True if already owns a weapon of this class
|
||||||
|
virtual bool Weapon_Switch( C_BaseCombatWeapon *pWeapon, int viewmodelindex = 0 );
|
||||||
|
virtual bool Weapon_CanSwitchTo(C_BaseCombatWeapon *pWeapon);
|
||||||
|
|
||||||
|
// I can't use my current weapon anymore. Switch me to the next best weapon.
|
||||||
|
bool SwitchToNextBestWeapon(C_BaseCombatWeapon *pCurrent);
|
||||||
|
|
||||||
|
virtual C_BaseCombatWeapon *GetActiveWeapon( void ) const;
|
||||||
|
int WeaponCount() const;
|
||||||
|
C_BaseCombatWeapon *GetWeapon( int i ) const;
|
||||||
|
|
||||||
|
// This is a sort of hack back-door only used by physgun!
|
||||||
|
void SetAmmoCount( int iCount, int iAmmoIndex );
|
||||||
|
|
||||||
|
float GetNextAttack() const { return m_flNextAttack; }
|
||||||
|
void SetNextAttack( float flWait ) { m_flNextAttack = flWait; }
|
||||||
|
|
||||||
|
virtual int BloodColor();
|
||||||
|
|
||||||
|
// Blood color (see BLOOD_COLOR_* macros in baseentity.h)
|
||||||
|
void SetBloodColor( int nBloodColor );
|
||||||
|
|
||||||
|
public:
|
||||||
|
|
||||||
|
float m_flNextAttack;
|
||||||
|
|
||||||
|
|
||||||
|
protected:
|
||||||
|
|
||||||
|
int m_bloodColor; // color of blood particless
|
||||||
|
|
||||||
|
|
||||||
|
private:
|
||||||
|
CNetworkArray( int, m_iAmmo, MAX_AMMO_TYPES );
|
||||||
|
|
||||||
|
CHandle<C_BaseCombatWeapon> m_hMyWeapons[MAX_WEAPONS];
|
||||||
|
CHandle< C_BaseCombatWeapon > m_hActiveWeapon;
|
||||||
|
private:
|
||||||
|
C_BaseCombatCharacter( const C_BaseCombatCharacter & ); // not defined, not accessible
|
||||||
|
|
||||||
|
|
||||||
|
//-----------------------
|
||||||
|
};
|
||||||
|
|
||||||
|
inline C_BaseCombatCharacter *ToBaseCombatCharacter( C_BaseEntity *pEntity )
|
||||||
|
{
|
||||||
|
if ( !pEntity || !pEntity->IsBaseCombatCharacter() )
|
||||||
|
return NULL;
|
||||||
|
|
||||||
|
#if _DEBUG
|
||||||
|
return dynamic_cast<C_BaseCombatCharacter *>( pEntity );
|
||||||
|
#else
|
||||||
|
return static_cast<C_BaseCombatCharacter *>( pEntity );
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
|
EXTERN_RECV_TABLE(DT_BaseCombatCharacter);
|
||||||
|
|
||||||
|
#endif // C_BASECOMBATCHARACTER_H
|
496
cl_dll/c_basecombatweapon.cpp
Normal file
496
cl_dll/c_basecombatweapon.cpp
Normal file
@ -0,0 +1,496 @@
|
|||||||
|
//========= Copyright © 1996-2005, Valve Corporation, All rights reserved. ============//
|
||||||
|
//
|
||||||
|
// Purpose: Client side implementation of CBaseCombatWeapon.
|
||||||
|
//
|
||||||
|
// $NoKeywords: $
|
||||||
|
//=============================================================================//
|
||||||
|
#include "cbase.h"
|
||||||
|
#include "history_resource.h"
|
||||||
|
#include "iclientmode.h"
|
||||||
|
#include "iinput.h"
|
||||||
|
#include "weapon_selection.h"
|
||||||
|
#include "hud_crosshair.h"
|
||||||
|
#include "engine/ivmodelinfo.h"
|
||||||
|
#include "tier0/vprof.h"
|
||||||
|
#include "hltvcamera.h"
|
||||||
|
#include "tier1/KeyValues.h"
|
||||||
|
#include "toolframework/itoolframework.h"
|
||||||
|
|
||||||
|
// memdbgon must be the last include file in a .cpp file!!!
|
||||||
|
#include "tier0/memdbgon.h"
|
||||||
|
|
||||||
|
//-----------------------------------------------------------------------------
|
||||||
|
// Purpose: Gets the local client's active weapon, if any.
|
||||||
|
//-----------------------------------------------------------------------------
|
||||||
|
C_BaseCombatWeapon *GetActiveWeapon( void )
|
||||||
|
{
|
||||||
|
C_BasePlayer *player = C_BasePlayer::GetLocalPlayer();
|
||||||
|
|
||||||
|
if ( !player )
|
||||||
|
return NULL;
|
||||||
|
|
||||||
|
return player->GetActiveWeapon();
|
||||||
|
}
|
||||||
|
|
||||||
|
//-----------------------------------------------------------------------------
|
||||||
|
// Purpose:
|
||||||
|
//-----------------------------------------------------------------------------
|
||||||
|
void C_BaseCombatWeapon::SetDormant( bool bDormant )
|
||||||
|
{
|
||||||
|
// If I'm going from active to dormant and I'm carried by another player, holster me.
|
||||||
|
if ( !IsDormant() && bDormant && !IsCarriedByLocalPlayer() )
|
||||||
|
{
|
||||||
|
Holster( NULL );
|
||||||
|
}
|
||||||
|
|
||||||
|
BaseClass::SetDormant( bDormant );
|
||||||
|
}
|
||||||
|
|
||||||
|
//-----------------------------------------------------------------------------
|
||||||
|
// Purpose:
|
||||||
|
//-----------------------------------------------------------------------------
|
||||||
|
void C_BaseCombatWeapon::NotifyShouldTransmit( ShouldTransmitState_t state )
|
||||||
|
{
|
||||||
|
BaseClass::NotifyShouldTransmit(state);
|
||||||
|
|
||||||
|
if (state == SHOULDTRANSMIT_END)
|
||||||
|
{
|
||||||
|
if (m_iState == WEAPON_IS_ACTIVE)
|
||||||
|
{
|
||||||
|
m_iState = WEAPON_IS_CARRIED_BY_PLAYER;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else if( state == SHOULDTRANSMIT_START )
|
||||||
|
{
|
||||||
|
if( m_iState == WEAPON_IS_CARRIED_BY_PLAYER )
|
||||||
|
{
|
||||||
|
if( GetOwner() && GetOwner()->GetActiveWeapon() == this )
|
||||||
|
{
|
||||||
|
// Restore the Activeness of the weapon if we client-twiddled it off in the first case above.
|
||||||
|
m_iState = WEAPON_IS_ACTIVE;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
//-----------------------------------------------------------------------------
|
||||||
|
// Purpose:
|
||||||
|
//-----------------------------------------------------------------------------
|
||||||
|
static inline bool ShouldDrawLocalPlayer( void )
|
||||||
|
{
|
||||||
|
return C_BasePlayer::ShouldDrawLocalPlayer();
|
||||||
|
}
|
||||||
|
|
||||||
|
//-----------------------------------------------------------------------------
|
||||||
|
// Purpose:
|
||||||
|
//-----------------------------------------------------------------------------
|
||||||
|
void C_BaseCombatWeapon::OnRestore()
|
||||||
|
{
|
||||||
|
BaseClass::OnRestore();
|
||||||
|
|
||||||
|
// if the player is holding this weapon,
|
||||||
|
// mark it as just restored so it won't show as a new pickup
|
||||||
|
if (GetOwner() == C_BasePlayer::GetLocalPlayer())
|
||||||
|
{
|
||||||
|
m_bJustRestored = true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
int C_BaseCombatWeapon::GetWorldModelIndex( void )
|
||||||
|
{
|
||||||
|
return m_iWorldModelIndex;
|
||||||
|
}
|
||||||
|
|
||||||
|
//-----------------------------------------------------------------------------
|
||||||
|
// Purpose:
|
||||||
|
// Input : bnewentity -
|
||||||
|
//-----------------------------------------------------------------------------
|
||||||
|
void C_BaseCombatWeapon::OnDataChanged( DataUpdateType_t updateType )
|
||||||
|
{
|
||||||
|
BaseClass::OnDataChanged(updateType);
|
||||||
|
|
||||||
|
CHandle< C_BaseCombatWeapon > handle = this;
|
||||||
|
|
||||||
|
// If it's being carried by the *local* player, on the first update,
|
||||||
|
// find the registered weapon for this ID
|
||||||
|
|
||||||
|
C_BasePlayer *pPlayer = C_BasePlayer::GetLocalPlayer();
|
||||||
|
C_BaseCombatCharacter *pOwner = GetOwner();
|
||||||
|
|
||||||
|
// check if weapon is carried by local player
|
||||||
|
bool bIsLocalPlayer = pPlayer && pPlayer == pOwner;
|
||||||
|
if ( bIsLocalPlayer && !ShouldDrawLocalPlayer() )
|
||||||
|
{
|
||||||
|
// If I was just picked up, or created & immediately carried, add myself to this client's list of weapons
|
||||||
|
if ( (m_iState != WEAPON_NOT_CARRIED ) && (m_iOldState == WEAPON_NOT_CARRIED) )
|
||||||
|
{
|
||||||
|
// Tell the HUD this weapon's been picked up
|
||||||
|
if ( ShouldDrawPickup() )
|
||||||
|
{
|
||||||
|
CBaseHudWeaponSelection *pHudSelection = GetHudWeaponSelection();
|
||||||
|
if ( pHudSelection )
|
||||||
|
{
|
||||||
|
pHudSelection->OnWeaponPickup( this );
|
||||||
|
}
|
||||||
|
|
||||||
|
pPlayer->EmitSound( "Player.PickupWeapon" );
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else // weapon carried by other player or not at all
|
||||||
|
{
|
||||||
|
// BRJ 10/14/02
|
||||||
|
// FIXME: Remove when Yahn's client-side prediction is done
|
||||||
|
// It's a hacky workaround for the model indices fighting
|
||||||
|
// (GetRenderBounds uses the model index, which is for the view model)
|
||||||
|
SetModelIndex( GetWorldModelIndex() );
|
||||||
|
}
|
||||||
|
|
||||||
|
UpdateVisibility();
|
||||||
|
|
||||||
|
m_iOldState = m_iState;
|
||||||
|
|
||||||
|
m_bJustRestored = false;
|
||||||
|
}
|
||||||
|
|
||||||
|
//-----------------------------------------------------------------------------
|
||||||
|
// Is anyone carrying it?
|
||||||
|
//-----------------------------------------------------------------------------
|
||||||
|
bool C_BaseCombatWeapon::IsBeingCarried() const
|
||||||
|
{
|
||||||
|
return ( m_hOwner.Get() != NULL );
|
||||||
|
}
|
||||||
|
|
||||||
|
//-----------------------------------------------------------------------------
|
||||||
|
// Is the carrier alive?
|
||||||
|
//-----------------------------------------------------------------------------
|
||||||
|
bool C_BaseCombatWeapon::IsCarrierAlive() const
|
||||||
|
{
|
||||||
|
if ( !m_hOwner.Get() )
|
||||||
|
return false;
|
||||||
|
|
||||||
|
return m_hOwner.Get()->GetHealth() > 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
//-----------------------------------------------------------------------------
|
||||||
|
// Should this object cast shadows?
|
||||||
|
//-----------------------------------------------------------------------------
|
||||||
|
ShadowType_t C_BaseCombatWeapon::ShadowCastType()
|
||||||
|
{
|
||||||
|
if (!IsBeingCarried())
|
||||||
|
return SHADOWS_RENDER_TO_TEXTURE;
|
||||||
|
|
||||||
|
if (IsCarriedByLocalPlayer())
|
||||||
|
return SHADOWS_NONE;
|
||||||
|
|
||||||
|
return (m_iState != WEAPON_IS_CARRIED_BY_PLAYER) ? SHADOWS_RENDER_TO_TEXTURE : SHADOWS_NONE;
|
||||||
|
}
|
||||||
|
|
||||||
|
//-----------------------------------------------------------------------------
|
||||||
|
// Purpose: This weapon is the active weapon, and it should now draw anything
|
||||||
|
// it wants to. This gets called every frame.
|
||||||
|
//-----------------------------------------------------------------------------
|
||||||
|
void C_BaseCombatWeapon::Redraw()
|
||||||
|
{
|
||||||
|
if ( g_pClientMode->ShouldDrawCrosshair() )
|
||||||
|
{
|
||||||
|
DrawCrosshair();
|
||||||
|
}
|
||||||
|
|
||||||
|
// ammo drawing has been moved into hud_ammo.cpp
|
||||||
|
}
|
||||||
|
|
||||||
|
//-----------------------------------------------------------------------------
|
||||||
|
// Purpose: Draw the weapon's crosshair
|
||||||
|
//-----------------------------------------------------------------------------
|
||||||
|
void C_BaseCombatWeapon::DrawCrosshair()
|
||||||
|
{
|
||||||
|
C_BasePlayer *player = C_BasePlayer::GetLocalPlayer();
|
||||||
|
if ( !player )
|
||||||
|
return;
|
||||||
|
|
||||||
|
Color clr = gHUD.m_clrNormal;
|
||||||
|
/*
|
||||||
|
|
||||||
|
// TEST: if the thing under your crosshair is on a different team, light the crosshair with a different color.
|
||||||
|
Vector vShootPos, vShootAngles;
|
||||||
|
GetShootPosition( vShootPos, vShootAngles );
|
||||||
|
|
||||||
|
Vector vForward;
|
||||||
|
AngleVectors( vShootAngles, &vForward );
|
||||||
|
|
||||||
|
|
||||||
|
// Change the color depending on if we're looking at a friend or an enemy.
|
||||||
|
CPartitionFilterListMask filter( PARTITION_ALL_CLIENT_EDICTS );
|
||||||
|
trace_t tr;
|
||||||
|
traceline->TraceLine( vShootPos, vShootPos + vForward * 10000, COLLISION_GROUP_NONE, MASK_SHOT, &tr, true, ~0, &filter );
|
||||||
|
|
||||||
|
if ( tr.index != 0 && tr.index != INVALID_CLIENTENTITY_HANDLE )
|
||||||
|
{
|
||||||
|
C_BaseEntity *pEnt = ClientEntityList().GetBaseEntityFromHandle( tr.index );
|
||||||
|
if ( pEnt )
|
||||||
|
{
|
||||||
|
if ( pEnt->GetTeamNumber() != player->GetTeamNumber() )
|
||||||
|
{
|
||||||
|
g = b = 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
*/
|
||||||
|
|
||||||
|
CHudCrosshair *crosshair = GET_HUDELEMENT( CHudCrosshair );
|
||||||
|
if ( !crosshair )
|
||||||
|
return;
|
||||||
|
|
||||||
|
// Check to see if the player is in VGUI mode...
|
||||||
|
if (player->IsInVGuiInputMode())
|
||||||
|
{
|
||||||
|
CHudTexture *pArrow = gHUD.GetIcon( "arrow" );
|
||||||
|
|
||||||
|
crosshair->SetCrosshair( pArrow, gHUD.m_clrNormal );
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Find out if this weapon's auto-aimed onto a target
|
||||||
|
bool bOnTarget = ( m_iState == WEAPON_IS_ONTARGET );
|
||||||
|
|
||||||
|
if ( player->GetFOV() >= 90 )
|
||||||
|
{
|
||||||
|
// normal crosshairs
|
||||||
|
if ( bOnTarget && GetWpnData().iconAutoaim )
|
||||||
|
{
|
||||||
|
clr[3] = 255;
|
||||||
|
|
||||||
|
crosshair->SetCrosshair( GetWpnData().iconAutoaim, clr );
|
||||||
|
}
|
||||||
|
else if ( GetWpnData().iconCrosshair )
|
||||||
|
{
|
||||||
|
clr[3] = 255;
|
||||||
|
crosshair->SetCrosshair( GetWpnData().iconCrosshair, clr );
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
crosshair->ResetCrosshair();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
Color white( 255, 255, 255, 255 );
|
||||||
|
|
||||||
|
// zoomed crosshairs
|
||||||
|
if (bOnTarget && GetWpnData().iconZoomedAutoaim)
|
||||||
|
crosshair->SetCrosshair(GetWpnData().iconZoomedAutoaim, white);
|
||||||
|
else if ( GetWpnData().iconZoomedCrosshair )
|
||||||
|
crosshair->SetCrosshair( GetWpnData().iconZoomedCrosshair, white );
|
||||||
|
else
|
||||||
|
crosshair->ResetCrosshair();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
//-----------------------------------------------------------------------------
|
||||||
|
// Purpose: This weapon is the active weapon, and the viewmodel for it was just drawn.
|
||||||
|
//-----------------------------------------------------------------------------
|
||||||
|
void C_BaseCombatWeapon::ViewModelDrawn( C_BaseViewModel *pViewModel )
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
//-----------------------------------------------------------------------------
|
||||||
|
// Purpose: Returns true if this client's carrying this weapon
|
||||||
|
//-----------------------------------------------------------------------------
|
||||||
|
bool C_BaseCombatWeapon::IsCarriedByLocalPlayer( void )
|
||||||
|
{
|
||||||
|
if ( !GetOwner() )
|
||||||
|
return false;
|
||||||
|
|
||||||
|
return ( GetOwner() == C_BasePlayer::GetLocalPlayer() );
|
||||||
|
}
|
||||||
|
|
||||||
|
//-----------------------------------------------------------------------------
|
||||||
|
// Purpose: Returns true if this weapon is the local client's currently wielded weapon
|
||||||
|
//-----------------------------------------------------------------------------
|
||||||
|
bool C_BaseCombatWeapon::IsActiveByLocalPlayer( void )
|
||||||
|
{
|
||||||
|
if ( IsCarriedByLocalPlayer() )
|
||||||
|
{
|
||||||
|
return (m_iState == WEAPON_IS_ACTIVE);
|
||||||
|
}
|
||||||
|
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool C_BaseCombatWeapon::GetShootPosition( Vector &vOrigin, QAngle &vAngles )
|
||||||
|
{
|
||||||
|
// Get the entity because the weapon doesn't have the right angles.
|
||||||
|
C_BaseCombatCharacter *pEnt = ToBaseCombatCharacter( GetOwner() );
|
||||||
|
if ( pEnt )
|
||||||
|
{
|
||||||
|
if ( pEnt == C_BasePlayer::GetLocalPlayer() )
|
||||||
|
{
|
||||||
|
vAngles = pEnt->EyeAngles();
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
vAngles = pEnt->GetRenderAngles();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
vAngles.Init();
|
||||||
|
}
|
||||||
|
|
||||||
|
QAngle vDummy;
|
||||||
|
if ( IsActiveByLocalPlayer() && !ShouldDrawLocalPlayer() )
|
||||||
|
{
|
||||||
|
C_BasePlayer *player = ToBasePlayer( pEnt );
|
||||||
|
C_BaseViewModel *vm = player ? player->GetViewModel( 0 ) : NULL;
|
||||||
|
if ( vm )
|
||||||
|
{
|
||||||
|
int iAttachment = vm->LookupAttachment( "muzzle" );
|
||||||
|
if ( vm->GetAttachment( iAttachment, vOrigin, vDummy ) )
|
||||||
|
{
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
// Thirdperson
|
||||||
|
int iAttachment = LookupAttachment( "muzzle" );
|
||||||
|
if ( GetAttachment( iAttachment, vOrigin, vDummy ) )
|
||||||
|
{
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
vOrigin = GetRenderOrigin();
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
//-----------------------------------------------------------------------------
|
||||||
|
// Purpose:
|
||||||
|
// Output : Returns true on success, false on failure.
|
||||||
|
//-----------------------------------------------------------------------------
|
||||||
|
bool C_BaseCombatWeapon::ShouldDraw( void )
|
||||||
|
{
|
||||||
|
if ( m_iWorldModelIndex == 0 )
|
||||||
|
return false;
|
||||||
|
|
||||||
|
// FIXME: All weapons with owners are set to transmit in CBaseCombatWeapon::UpdateTransmitState,
|
||||||
|
// even if they have EF_NODRAW set, so we have to check this here. Ideally they would never
|
||||||
|
// transmit except for the weapons owned by the local player.
|
||||||
|
if ( IsEffectActive( EF_NODRAW ) )
|
||||||
|
return false;
|
||||||
|
|
||||||
|
C_BaseCombatCharacter *pOwner = GetOwner();
|
||||||
|
|
||||||
|
// weapon has no owner, always draw it
|
||||||
|
if ( !pOwner )
|
||||||
|
return true;
|
||||||
|
|
||||||
|
bool bIsActive = ( m_iState == WEAPON_IS_ACTIVE );
|
||||||
|
|
||||||
|
C_BasePlayer *pLocalPlayer = C_BasePlayer::GetLocalPlayer();
|
||||||
|
|
||||||
|
// carried by local player?
|
||||||
|
if ( pOwner == pLocalPlayer )
|
||||||
|
{
|
||||||
|
// Only ever show the active weapon
|
||||||
|
if ( !bIsActive )
|
||||||
|
return false;
|
||||||
|
|
||||||
|
// 3rd person mode
|
||||||
|
if ( ShouldDrawLocalPlayer() )
|
||||||
|
return true;
|
||||||
|
|
||||||
|
// don't draw active weapon if not in some kind of 3rd person mode, the viewmodel will do that
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
// If it's a player, then only show active weapons
|
||||||
|
if ( pOwner->IsPlayer() )
|
||||||
|
{
|
||||||
|
// Show it if it's active...
|
||||||
|
return bIsActive;
|
||||||
|
}
|
||||||
|
|
||||||
|
// FIXME: We may want to only show active weapons on NPCs
|
||||||
|
// These are carried by AIs; always show them
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
//-----------------------------------------------------------------------------
|
||||||
|
// Purpose: Return true if a weapon-pickup icon should be displayed when this weapon is received
|
||||||
|
//-----------------------------------------------------------------------------
|
||||||
|
bool C_BaseCombatWeapon::ShouldDrawPickup( void )
|
||||||
|
{
|
||||||
|
if ( m_bJustRestored )
|
||||||
|
return false;
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
//-----------------------------------------------------------------------------
|
||||||
|
// Purpose: Render the weapon. Draw the Viewmodel if the weapon's being carried
|
||||||
|
// by this player, otherwise draw the worldmodel.
|
||||||
|
//-----------------------------------------------------------------------------
|
||||||
|
int C_BaseCombatWeapon::DrawModel( int flags )
|
||||||
|
{
|
||||||
|
VPROF_BUDGET( "C_BaseCombatWeapon::DrawModel", VPROF_BUDGETGROUP_MODEL_RENDERING );
|
||||||
|
if ( !m_bReadyToDraw )
|
||||||
|
return 0;
|
||||||
|
|
||||||
|
if ( !IsVisible() )
|
||||||
|
return 0;
|
||||||
|
|
||||||
|
// check if local player chases owner of this weapon in first person
|
||||||
|
C_BasePlayer *localplayer = C_BasePlayer::GetLocalPlayer();
|
||||||
|
|
||||||
|
if ( localplayer && localplayer->IsObserver() && GetOwner() )
|
||||||
|
{
|
||||||
|
// don't draw weapon if chasing this guy as spectator
|
||||||
|
// we don't check that in ShouldDraw() since this may change
|
||||||
|
// without notification
|
||||||
|
|
||||||
|
if ( localplayer->GetObserverMode() == OBS_MODE_IN_EYE &&
|
||||||
|
localplayer->GetObserverTarget() == GetOwner() )
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
return BaseClass::DrawModel( flags );
|
||||||
|
}
|
||||||
|
|
||||||
|
//-----------------------------------------------------------------------------
|
||||||
|
// tool recording
|
||||||
|
//-----------------------------------------------------------------------------
|
||||||
|
void C_BaseCombatWeapon::GetToolRecordingState( KeyValues *msg )
|
||||||
|
{
|
||||||
|
if ( !ToolsEnabled() )
|
||||||
|
return;
|
||||||
|
|
||||||
|
int nModelIndex = GetModelIndex();
|
||||||
|
int nWorldModelIndex = GetWorldModelIndex();
|
||||||
|
if ( nModelIndex != nWorldModelIndex )
|
||||||
|
{
|
||||||
|
SetModelIndex( nWorldModelIndex );
|
||||||
|
}
|
||||||
|
|
||||||
|
BaseClass::GetToolRecordingState( msg );
|
||||||
|
|
||||||
|
if ( m_iState == WEAPON_IS_ACTIVE )
|
||||||
|
{
|
||||||
|
BaseEntityRecordingState_t *pBaseEntity = (BaseEntityRecordingState_t*)msg->GetPtr( "baseentity" );
|
||||||
|
pBaseEntity->m_bVisible = true;
|
||||||
|
}
|
||||||
|
else if ( m_iState == WEAPON_NOT_CARRIED )
|
||||||
|
{
|
||||||
|
BaseEntityRecordingState_t *pBaseEntity = (BaseEntityRecordingState_t*)msg->GetPtr( "baseentity" );
|
||||||
|
pBaseEntity->m_nOwner = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
if ( nModelIndex != nWorldModelIndex )
|
||||||
|
{
|
||||||
|
SetModelIndex( nModelIndex );
|
||||||
|
}
|
||||||
|
}
|
26
cl_dll/c_basecombatweapon.h
Normal file
26
cl_dll/c_basecombatweapon.h
Normal file
@ -0,0 +1,26 @@
|
|||||||
|
//========= Copyright © 1996-2005, Valve Corporation, All rights reserved. ============//
|
||||||
|
//
|
||||||
|
// Purpose: Client's CBaseCombatWeapon entity
|
||||||
|
//
|
||||||
|
// $Workfile: $
|
||||||
|
// $Date: $
|
||||||
|
// $NoKeywords: $
|
||||||
|
//=============================================================================//
|
||||||
|
#ifndef C_BASECOMBATWEAPON_H
|
||||||
|
#define C_BASECOMBATWEAPON_H
|
||||||
|
|
||||||
|
#ifdef _WIN32
|
||||||
|
#pragma once
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#include "basecombatweapon_shared.h"
|
||||||
|
#include "weapons_resource.h"
|
||||||
|
|
||||||
|
class CViewSetup;
|
||||||
|
class C_BaseViewModel;
|
||||||
|
|
||||||
|
// Accessors for local weapons
|
||||||
|
C_BaseCombatWeapon *GetActiveWeapon( void );
|
||||||
|
|
||||||
|
|
||||||
|
#endif // C_BASECOMBATWEAPON
|
28
cl_dll/c_basedoor.cpp
Normal file
28
cl_dll/c_basedoor.cpp
Normal file
@ -0,0 +1,28 @@
|
|||||||
|
//========= Copyright © 1996-2005, Valve Corporation, All rights reserved. ============//
|
||||||
|
//
|
||||||
|
// Purpose:
|
||||||
|
//
|
||||||
|
// $NoKeywords: $
|
||||||
|
//=============================================================================//
|
||||||
|
#include "cbase.h"
|
||||||
|
#include "c_basedoor.h"
|
||||||
|
|
||||||
|
// memdbgon must be the last include file in a .cpp file!!!
|
||||||
|
#include "tier0/memdbgon.h"
|
||||||
|
|
||||||
|
#ifdef CBaseDoor
|
||||||
|
#undef CBaseDoor
|
||||||
|
#endif
|
||||||
|
|
||||||
|
IMPLEMENT_CLIENTCLASS_DT(C_BaseDoor, DT_BaseDoor, CBaseDoor)
|
||||||
|
RecvPropFloat(RECVINFO(m_flWaveHeight)),
|
||||||
|
END_RECV_TABLE()
|
||||||
|
|
||||||
|
C_BaseDoor::C_BaseDoor( void )
|
||||||
|
{
|
||||||
|
m_flWaveHeight = 0.0f;
|
||||||
|
}
|
||||||
|
|
||||||
|
C_BaseDoor::~C_BaseDoor( void )
|
||||||
|
{
|
||||||
|
}
|
32
cl_dll/c_basedoor.h
Normal file
32
cl_dll/c_basedoor.h
Normal file
@ -0,0 +1,32 @@
|
|||||||
|
//========= Copyright © 1996-2005, Valve Corporation, All rights reserved. ============//
|
||||||
|
//
|
||||||
|
// Purpose:
|
||||||
|
//
|
||||||
|
// $NoKeywords: $
|
||||||
|
//=============================================================================//
|
||||||
|
#if !defined( C_BASEDOOR_H )
|
||||||
|
#define C_BASEDOOR_H
|
||||||
|
#ifdef _WIN32
|
||||||
|
#pragma once
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#include "c_baseentity.h"
|
||||||
|
|
||||||
|
#if defined( CLIENT_DLL )
|
||||||
|
#define CBaseDoor C_BaseDoor
|
||||||
|
#endif
|
||||||
|
|
||||||
|
class C_BaseDoor : public C_BaseEntity
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
DECLARE_CLASS( C_BaseDoor, C_BaseEntity );
|
||||||
|
DECLARE_CLIENTCLASS();
|
||||||
|
|
||||||
|
C_BaseDoor( void );
|
||||||
|
~C_BaseDoor( void );
|
||||||
|
|
||||||
|
public:
|
||||||
|
float m_flWaveHeight;
|
||||||
|
};
|
||||||
|
|
||||||
|
#endif // C_BASEDOOR_H
|
5736
cl_dll/c_baseentity.cpp
Normal file
5736
cl_dll/c_baseentity.cpp
Normal file
File diff suppressed because it is too large
Load Diff
2027
cl_dll/c_baseentity.h
Normal file
2027
cl_dll/c_baseentity.h
Normal file
File diff suppressed because it is too large
Load Diff
1730
cl_dll/c_baseflex.cpp
Normal file
1730
cl_dll/c_baseflex.cpp
Normal file
File diff suppressed because it is too large
Load Diff
276
cl_dll/c_baseflex.h
Normal file
276
cl_dll/c_baseflex.h
Normal file
@ -0,0 +1,276 @@
|
|||||||
|
//========= Copyright © 1996-2005, Valve Corporation, All rights reserved. ============//
|
||||||
|
//
|
||||||
|
// Purpose:
|
||||||
|
//
|
||||||
|
// $NoKeywords: $
|
||||||
|
//
|
||||||
|
//=============================================================================//
|
||||||
|
// Client-side CBasePlayer
|
||||||
|
|
||||||
|
#ifndef C_STUDIOFLEX_H
|
||||||
|
#define C_STUDIOFLEX_H
|
||||||
|
#pragma once
|
||||||
|
|
||||||
|
|
||||||
|
#include "c_baseanimating.h"
|
||||||
|
#include "c_baseanimatingoverlay.h"
|
||||||
|
#include "sceneentity_shared.h"
|
||||||
|
|
||||||
|
#include "UtlVector.h"
|
||||||
|
|
||||||
|
//-----------------------------------------------------------------------------
|
||||||
|
// Purpose: Item in list of loaded scene files
|
||||||
|
//-----------------------------------------------------------------------------
|
||||||
|
class CFlexSceneFile
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
enum
|
||||||
|
{
|
||||||
|
MAX_FLEX_FILENAME = 128,
|
||||||
|
};
|
||||||
|
|
||||||
|
char filename[ MAX_FLEX_FILENAME ];
|
||||||
|
void *buffer;
|
||||||
|
};
|
||||||
|
|
||||||
|
// For phoneme emphasis track
|
||||||
|
struct Emphasized_Phoneme;
|
||||||
|
class CSentence;
|
||||||
|
|
||||||
|
//-----------------------------------------------------------------------------
|
||||||
|
// Purpose:
|
||||||
|
//-----------------------------------------------------------------------------
|
||||||
|
class C_BaseFlex : public C_BaseAnimatingOverlay
|
||||||
|
{
|
||||||
|
DECLARE_CLASS( C_BaseFlex, C_BaseAnimatingOverlay );
|
||||||
|
public:
|
||||||
|
DECLARE_CLIENTCLASS();
|
||||||
|
DECLARE_PREDICTABLE();
|
||||||
|
DECLARE_INTERPOLATION();
|
||||||
|
|
||||||
|
C_BaseFlex();
|
||||||
|
virtual ~C_BaseFlex();
|
||||||
|
|
||||||
|
virtual CStudioHdr *OnNewModel( void );
|
||||||
|
|
||||||
|
// model specific
|
||||||
|
virtual void SetupWeights( );
|
||||||
|
|
||||||
|
virtual void RunFlexRules( CStudioHdr *pStudioHdr, float *dest );
|
||||||
|
|
||||||
|
virtual Vector SetViewTarget( CStudioHdr *pStudioHdr );
|
||||||
|
|
||||||
|
virtual bool GetSoundSpatialization( SpatializationInfo_t& info );
|
||||||
|
|
||||||
|
virtual void GetToolRecordingState( KeyValues *msg );
|
||||||
|
|
||||||
|
// Called at the lowest level to actually apply a flex animation
|
||||||
|
void AddFlexAnimation( CSceneEventInfo *info );
|
||||||
|
|
||||||
|
void SetFlexWeight( int index, float value );
|
||||||
|
float GetFlexWeight( int index );
|
||||||
|
|
||||||
|
// Look up flex controller index by global name
|
||||||
|
int FindFlexController( const char *szName );
|
||||||
|
|
||||||
|
public:
|
||||||
|
Vector m_viewtarget;
|
||||||
|
CInterpolatedVar< Vector > m_iv_viewtarget;
|
||||||
|
float m_flexWeight[64];
|
||||||
|
CInterpolatedVarArray< float, 64 > m_iv_flexWeight;
|
||||||
|
|
||||||
|
int m_blinktoggle;
|
||||||
|
|
||||||
|
static int AddGlobalFlexController( char *szName );
|
||||||
|
static char const *GetGlobalFlexControllerName( int idx );
|
||||||
|
|
||||||
|
// bah, this should be unified with all prev/current stuff.
|
||||||
|
|
||||||
|
public:
|
||||||
|
|
||||||
|
// Keep track of what scenes are being played
|
||||||
|
void StartChoreoScene( CChoreoScene *scene );
|
||||||
|
void RemoveChoreoScene( CChoreoScene *scene );
|
||||||
|
|
||||||
|
// Start the specifics of an scene event
|
||||||
|
virtual bool StartSceneEvent( CSceneEventInfo *info, CChoreoScene *scene, CChoreoEvent *event, CChoreoActor *actor, C_BaseEntity *pTarget );
|
||||||
|
|
||||||
|
// Manipulation of events for the object
|
||||||
|
// Should be called by think function to process all scene events
|
||||||
|
// The default implementation resets m_flexWeight array and calls
|
||||||
|
// AddSceneEvents
|
||||||
|
virtual void ProcessSceneEvents( bool bFlexEvents );
|
||||||
|
|
||||||
|
// Assumes m_flexWeight array has been set up, this adds the actual currently playing
|
||||||
|
// expressions to the flex weights and adds other scene events as needed
|
||||||
|
virtual bool ProcessSceneEvent( bool bFlexEvents, CSceneEventInfo *info, CChoreoScene *scene, CChoreoEvent *event );
|
||||||
|
|
||||||
|
// Remove all playing events
|
||||||
|
void ClearSceneEvents( CChoreoScene *scene, bool canceled );
|
||||||
|
|
||||||
|
// Stop specifics of event
|
||||||
|
virtual bool ClearSceneEvent( CSceneEventInfo *info, bool fastKill, bool canceled );
|
||||||
|
|
||||||
|
// Add the event to the queue for this actor
|
||||||
|
void AddSceneEvent( CChoreoScene *scene, CChoreoEvent *event, C_BaseEntity *pTarget = NULL );
|
||||||
|
|
||||||
|
// Remove the event from the queue for this actor
|
||||||
|
void RemoveSceneEvent( CChoreoScene *scene, CChoreoEvent *event, bool fastKill );
|
||||||
|
|
||||||
|
// Checks to see if the event should be considered "completed"
|
||||||
|
bool CheckSceneEvent( float currenttime, CChoreoScene *scene, CChoreoEvent *event );
|
||||||
|
|
||||||
|
// Checks to see if a event should be considered "completed"
|
||||||
|
virtual bool CheckSceneEventCompletion( CSceneEventInfo *info, float currenttime, CChoreoScene *scene, CChoreoEvent *event );
|
||||||
|
|
||||||
|
int FlexControllerLocalToGlobal( const flexsettinghdr_t *pSettinghdr, int key );
|
||||||
|
void EnsureTranslations( const flexsettinghdr_t *pSettinghdr );
|
||||||
|
|
||||||
|
private:
|
||||||
|
|
||||||
|
bool ProcessFlexAnimationSceneEvent( CSceneEventInfo *info, CChoreoScene *scene, CChoreoEvent *event );
|
||||||
|
bool ProcessFlexSettingSceneEvent( CSceneEventInfo *info, CChoreoScene *scene, CChoreoEvent *event );
|
||||||
|
void AddFlexSetting( const char *expr, float scale,
|
||||||
|
const flexsettinghdr_t *pSettinghdr, const flexsettinghdr_t *pOverrideHdr, bool newexpression );
|
||||||
|
|
||||||
|
// Array of active SceneEvents, in order oldest to newest
|
||||||
|
CUtlVector < CSceneEventInfo > m_SceneEvents;
|
||||||
|
CUtlVector < CChoreoScene * > m_ActiveChoreoScenes;
|
||||||
|
|
||||||
|
bool HasSceneEvents() const;
|
||||||
|
|
||||||
|
private:
|
||||||
|
// Mapping for each loaded scene file used by this actor
|
||||||
|
struct FS_LocalToGlobal_t
|
||||||
|
{
|
||||||
|
explicit FS_LocalToGlobal_t() :
|
||||||
|
m_Key( 0 ),
|
||||||
|
m_nCount( 0 ),
|
||||||
|
m_Mapping( 0 )
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
explicit FS_LocalToGlobal_t( const flexsettinghdr_t *key ) :
|
||||||
|
m_Key( key ),
|
||||||
|
m_nCount( 0 ),
|
||||||
|
m_Mapping( 0 )
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
void SetCount( int count )
|
||||||
|
{
|
||||||
|
Assert( !m_Mapping );
|
||||||
|
Assert( count > 0 );
|
||||||
|
m_nCount = count;
|
||||||
|
m_Mapping = new int[ m_nCount ];
|
||||||
|
Q_memset( m_Mapping, 0, m_nCount * sizeof( int ) );
|
||||||
|
}
|
||||||
|
|
||||||
|
FS_LocalToGlobal_t( const FS_LocalToGlobal_t& src )
|
||||||
|
{
|
||||||
|
m_Key = src.m_Key;
|
||||||
|
delete m_Mapping;
|
||||||
|
m_Mapping = new int[ src.m_nCount ];
|
||||||
|
Q_memcpy( m_Mapping, src.m_Mapping, src.m_nCount * sizeof( int ) );
|
||||||
|
|
||||||
|
m_nCount = src.m_nCount;
|
||||||
|
}
|
||||||
|
|
||||||
|
~FS_LocalToGlobal_t()
|
||||||
|
{
|
||||||
|
delete m_Mapping;
|
||||||
|
m_nCount = 0;
|
||||||
|
m_Mapping = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
const flexsettinghdr_t *m_Key;
|
||||||
|
int m_nCount;
|
||||||
|
int *m_Mapping;
|
||||||
|
};
|
||||||
|
|
||||||
|
static bool FlexSettingLessFunc( const FS_LocalToGlobal_t& lhs, const FS_LocalToGlobal_t& rhs );
|
||||||
|
|
||||||
|
CUtlRBTree< FS_LocalToGlobal_t, unsigned short > m_LocalToGlobal;
|
||||||
|
|
||||||
|
float m_blinktime;
|
||||||
|
int m_prevblinktoggle;
|
||||||
|
|
||||||
|
int m_iBlink;
|
||||||
|
int m_iEyeUpdown;
|
||||||
|
int m_iEyeRightleft;
|
||||||
|
int m_iMouthAttachment;
|
||||||
|
|
||||||
|
float *m_flFlexDelayedWeight;
|
||||||
|
|
||||||
|
// shared flex controllers
|
||||||
|
static int g_numflexcontrollers;
|
||||||
|
static char *g_flexcontroller[MAXSTUDIOFLEXCTRL*4]; // room for global set of flexcontrollers
|
||||||
|
static float g_flexweight[MAXSTUDIOFLEXDESC];
|
||||||
|
|
||||||
|
private:
|
||||||
|
C_BaseFlex( const C_BaseFlex & ); // not defined, not accessible
|
||||||
|
|
||||||
|
enum
|
||||||
|
{
|
||||||
|
PHONEME_CLASS_WEAK = 0,
|
||||||
|
PHONEME_CLASS_NORMAL,
|
||||||
|
PHONEME_CLASS_STRONG,
|
||||||
|
|
||||||
|
NUM_PHONEME_CLASSES
|
||||||
|
};
|
||||||
|
|
||||||
|
//-----------------------------------------------------------------------------
|
||||||
|
// Purpose:
|
||||||
|
//-----------------------------------------------------------------------------
|
||||||
|
struct Emphasized_Phoneme
|
||||||
|
{
|
||||||
|
// Global fields, setup at start
|
||||||
|
char classname[ 64 ];
|
||||||
|
bool required;
|
||||||
|
// Global fields setup first time tracks played
|
||||||
|
bool basechecked;
|
||||||
|
const flexsettinghdr_t *base;
|
||||||
|
#if !defined( NO_ENTITY_PREDICTION )
|
||||||
|
bool overridechecked;
|
||||||
|
const flexsettinghdr_t *override;
|
||||||
|
#endif
|
||||||
|
const flexsetting_t *exp;
|
||||||
|
|
||||||
|
// Local fields, processed for each sentence
|
||||||
|
bool valid;
|
||||||
|
float amount;
|
||||||
|
};
|
||||||
|
|
||||||
|
// For handling scene files
|
||||||
|
void *FindSceneFile( const char *filename );
|
||||||
|
|
||||||
|
const flexsetting_t *FindNamedSetting( const flexsettinghdr_t *pSettinghdr, const char *expr );
|
||||||
|
|
||||||
|
void ProcessVisemes( Emphasized_Phoneme *classes );
|
||||||
|
void AddVisemesForSentence( Emphasized_Phoneme *classes, float emphasis_intensity, CSentence *sentence, float t, float dt, bool juststarted );
|
||||||
|
void AddViseme( Emphasized_Phoneme *classes, float emphasis_intensity, int phoneme, float scale, bool newexpression );
|
||||||
|
bool SetupEmphasisBlend( Emphasized_Phoneme *classes, int phoneme );
|
||||||
|
void ComputeBlendedSetting( Emphasized_Phoneme *classes, float emphasis_intensity );
|
||||||
|
|
||||||
|
Emphasized_Phoneme m_PhonemeClasses[ NUM_PHONEME_CLASSES ];
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
//-----------------------------------------------------------------------------
|
||||||
|
// Do we have active expressions?
|
||||||
|
//-----------------------------------------------------------------------------
|
||||||
|
inline bool C_BaseFlex::HasSceneEvents() const
|
||||||
|
{
|
||||||
|
return m_SceneEvents.Count() != 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
EXTERN_RECV_TABLE(DT_BaseFlex);
|
||||||
|
|
||||||
|
float *GetVisemeWeights( int phoneme );
|
||||||
|
|
||||||
|
#endif // C_STUDIOFLEX_H
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
2011
cl_dll/c_baseplayer.cpp
Normal file
2011
cl_dll/c_baseplayer.cpp
Normal file
File diff suppressed because it is too large
Load Diff
533
cl_dll/c_baseplayer.h
Normal file
533
cl_dll/c_baseplayer.h
Normal file
@ -0,0 +1,533 @@
|
|||||||
|
//========= Copyright © 1996-2005, Valve Corporation, All rights reserved. ============//
|
||||||
|
//
|
||||||
|
// Purpose: Client-side CBasePlayer.
|
||||||
|
//
|
||||||
|
// - Manages the player's flashlight effect.
|
||||||
|
//
|
||||||
|
//=============================================================================//
|
||||||
|
|
||||||
|
#ifndef C_BASEPLAYER_H
|
||||||
|
#define C_BASEPLAYER_H
|
||||||
|
#ifdef _WIN32
|
||||||
|
#pragma once
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#include "c_playerlocaldata.h"
|
||||||
|
#include "c_basecombatcharacter.h"
|
||||||
|
#include "playerstate.h"
|
||||||
|
#include "usercmd.h"
|
||||||
|
#include "shareddefs.h"
|
||||||
|
#include "timedevent.h"
|
||||||
|
#include "smartptr.h"
|
||||||
|
#include "fx_water.h"
|
||||||
|
|
||||||
|
class C_BaseCombatWeapon;
|
||||||
|
class C_BaseViewModel;
|
||||||
|
class C_FuncLadder;
|
||||||
|
class CFlashlightEffect;
|
||||||
|
|
||||||
|
extern int g_nKillCamMode;
|
||||||
|
extern int g_nKillCamTarget1;
|
||||||
|
extern int g_nKillCamTarget2;
|
||||||
|
extern int g_nUsedPrediction;
|
||||||
|
|
||||||
|
class C_CommandContext
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
bool needsprocessing;
|
||||||
|
|
||||||
|
CUserCmd cmd;
|
||||||
|
int command_number;
|
||||||
|
};
|
||||||
|
|
||||||
|
class C_PredictionError
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
float time;
|
||||||
|
Vector error;
|
||||||
|
};
|
||||||
|
|
||||||
|
#define CHASE_CAM_DISTANCE 96.0f
|
||||||
|
#define WALL_OFFSET 6.0f
|
||||||
|
|
||||||
|
//-----------------------------------------------------------------------------
|
||||||
|
// Purpose: Base Player class
|
||||||
|
//-----------------------------------------------------------------------------
|
||||||
|
class C_BasePlayer : public C_BaseCombatCharacter
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
DECLARE_CLASS( C_BasePlayer, C_BaseCombatCharacter );
|
||||||
|
DECLARE_CLIENTCLASS();
|
||||||
|
DECLARE_PREDICTABLE();
|
||||||
|
DECLARE_INTERPOLATION();
|
||||||
|
|
||||||
|
C_BasePlayer();
|
||||||
|
virtual ~C_BasePlayer();
|
||||||
|
|
||||||
|
virtual void Spawn( void );
|
||||||
|
virtual void SharedSpawn(); // Shared between client and server.
|
||||||
|
|
||||||
|
// IClientEntity overrides.
|
||||||
|
virtual void OnPreDataChanged( DataUpdateType_t updateType );
|
||||||
|
virtual void OnDataChanged( DataUpdateType_t updateType );
|
||||||
|
|
||||||
|
virtual void PostDataUpdate( DataUpdateType_t updateType );
|
||||||
|
|
||||||
|
virtual void ReceiveMessage( int classID, bf_read &msg );
|
||||||
|
|
||||||
|
virtual void OnRestore();
|
||||||
|
|
||||||
|
virtual void AddEntity( void );
|
||||||
|
|
||||||
|
virtual void MakeTracer( const Vector &vecTracerSrc, const trace_t &tr, int iTracerType );
|
||||||
|
|
||||||
|
virtual void GetToolRecordingState( KeyValues *msg );
|
||||||
|
|
||||||
|
void SetAnimationExtension( const char *pExtension );
|
||||||
|
|
||||||
|
C_BaseViewModel *GetViewModel( int viewmodelindex = 0 );
|
||||||
|
C_BaseCombatWeapon *GetActiveWeapon( void ) const;
|
||||||
|
|
||||||
|
// View model prediction setup
|
||||||
|
virtual void CalcView( Vector &eyeOrigin, QAngle &eyeAngles, float &zNear, float &zFar, float &fov );
|
||||||
|
virtual void CalcViewModelView( const Vector& eyeOrigin, const QAngle& eyeAngles);
|
||||||
|
|
||||||
|
|
||||||
|
// Handle view smoothing when going up stairs
|
||||||
|
void SmoothViewOnStairs( Vector& eyeOrigin );
|
||||||
|
virtual float CalcRoll (const QAngle& angles, const Vector& velocity, float rollangle, float rollspeed);
|
||||||
|
void CalcViewRoll( QAngle& eyeAngles );
|
||||||
|
void CreateWaterEffects( void );
|
||||||
|
|
||||||
|
virtual Vector Weapon_ShootPosition();
|
||||||
|
virtual void Weapon_DropPrimary( void ) {}
|
||||||
|
|
||||||
|
virtual Vector GetAutoaimVector( float flScale );
|
||||||
|
void SetSuitUpdate(char *name, int fgroup, int iNoRepeat);
|
||||||
|
|
||||||
|
// Input handling
|
||||||
|
virtual void CreateMove( float flInputSampleTime, CUserCmd *pCmd );
|
||||||
|
virtual void AvoidPhysicsProps( CUserCmd *pCmd );
|
||||||
|
|
||||||
|
virtual void PlayerUse( void );
|
||||||
|
CBaseEntity *FindUseEntity( void );
|
||||||
|
virtual bool IsUseableEntity( CBaseEntity *pEntity, unsigned int requiredCaps );
|
||||||
|
|
||||||
|
// Data handlers
|
||||||
|
virtual bool IsPlayer( void ) const { return true; };
|
||||||
|
virtual int GetHealth() const { return m_iHealth; };
|
||||||
|
|
||||||
|
// observer mode
|
||||||
|
virtual int GetObserverMode() const;
|
||||||
|
virtual CBaseEntity *GetObserverTarget() const;
|
||||||
|
void SetObserverTarget( EHANDLE hObserverTarget );
|
||||||
|
|
||||||
|
|
||||||
|
bool IsObserver() const;
|
||||||
|
bool IsHLTV() const;
|
||||||
|
void ResetObserverMode();
|
||||||
|
bool IsBot( void ) const { return false; }
|
||||||
|
|
||||||
|
// Eye position..
|
||||||
|
virtual Vector EyePosition();
|
||||||
|
virtual const QAngle &EyeAngles(); // Direction of eyes
|
||||||
|
void EyePositionAndVectors( Vector *pPosition, Vector *pForward, Vector *pRight, Vector *pUp );
|
||||||
|
virtual const QAngle &LocalEyeAngles(); // Direction of eyes
|
||||||
|
|
||||||
|
// This can be overridden to return something other than m_pRagdoll if the mod uses separate
|
||||||
|
// entities for ragdolls.
|
||||||
|
virtual IRagdoll* GetRepresentativeRagdoll() const;
|
||||||
|
|
||||||
|
// Returns eye vectors
|
||||||
|
void EyeVectors( Vector *pForward, Vector *pRight = NULL, Vector *pUp = NULL );
|
||||||
|
|
||||||
|
bool IsSuitEquipped( void ) { return m_Local.m_bWearingSuit; };
|
||||||
|
|
||||||
|
// Team handlers
|
||||||
|
virtual void TeamChange( int iNewTeam );
|
||||||
|
|
||||||
|
// Flashlight
|
||||||
|
void Flashlight( void );
|
||||||
|
void UpdateFlashlight( void );
|
||||||
|
|
||||||
|
// Weapon selection code
|
||||||
|
virtual bool IsAllowedToSwitchWeapons( void ) { return !IsObserver(); }
|
||||||
|
virtual C_BaseCombatWeapon *GetActiveWeaponForSelection( void );
|
||||||
|
|
||||||
|
// Returns the view model if this is the local player. If you're in third person or
|
||||||
|
// this is a remote player, it returns the active weapon
|
||||||
|
//
|
||||||
|
virtual C_BaseAnimating* GetRenderedWeaponModel();
|
||||||
|
|
||||||
|
virtual bool IsOverridingViewmodel( void ) { return false; };
|
||||||
|
virtual int DrawOverriddenViewmodel( C_BaseViewModel *pViewmodel, int flags ) { return 0; };
|
||||||
|
|
||||||
|
virtual float GetDefaultAnimSpeed( void ) { return 1.0; }
|
||||||
|
|
||||||
|
void SetMaxSpeed( float flMaxSpeed ) { m_flMaxspeed = flMaxSpeed; }
|
||||||
|
float MaxSpeed() const { return m_flMaxspeed; }
|
||||||
|
|
||||||
|
// Should this object cast shadows?
|
||||||
|
virtual ShadowType_t ShadowCastType() { return SHADOWS_NONE; }
|
||||||
|
|
||||||
|
bool ShouldReceiveProjectedTextures( int flags )
|
||||||
|
{
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
bool IsLocalPlayer( void ) const;
|
||||||
|
|
||||||
|
// Global/static methods
|
||||||
|
static bool ShouldDrawLocalPlayer();
|
||||||
|
static C_BasePlayer *GetLocalPlayer( void );
|
||||||
|
int GetUserID( void );
|
||||||
|
|
||||||
|
// Called by the view model if its rendering is being overridden.
|
||||||
|
virtual bool ViewModel_IsTransparent( void );
|
||||||
|
|
||||||
|
#if !defined( NO_ENTITY_PREDICTION )
|
||||||
|
void AddToPlayerSimulationList( C_BaseEntity *other );
|
||||||
|
void SimulatePlayerSimulatedEntities( void );
|
||||||
|
void RemoveFromPlayerSimulationList( C_BaseEntity *ent );
|
||||||
|
void ClearPlayerSimulationList( void );
|
||||||
|
#endif
|
||||||
|
|
||||||
|
virtual void PhysicsSimulate( void );
|
||||||
|
virtual unsigned int PhysicsSolidMaskForEntity( void ) const { return MASK_PLAYERSOLID; }
|
||||||
|
|
||||||
|
// Prediction stuff
|
||||||
|
virtual bool ShouldPredict( void );
|
||||||
|
|
||||||
|
virtual void PreThink( void );
|
||||||
|
virtual void PostThink( void );
|
||||||
|
|
||||||
|
virtual void ItemPreFrame( void );
|
||||||
|
virtual void ItemPostFrame( void );
|
||||||
|
virtual void AbortReload( void );
|
||||||
|
|
||||||
|
virtual void SelectLastItem(void);
|
||||||
|
virtual void Weapon_SetLast( C_BaseCombatWeapon *pWeapon );
|
||||||
|
virtual bool Weapon_ShouldSetLast( C_BaseCombatWeapon *pOldWeapon, C_BaseCombatWeapon *pNewWeapon ) { return true; }
|
||||||
|
virtual bool Weapon_ShouldSelectItem( C_BaseCombatWeapon *pWeapon );
|
||||||
|
virtual bool Weapon_Switch( C_BaseCombatWeapon *pWeapon, int viewmodelindex = 0 ); // Switch to given weapon if has ammo (false if failed)
|
||||||
|
virtual C_BaseCombatWeapon *GetLastWeapon( void ) { return m_hLastWeapon.Get(); }
|
||||||
|
void ResetAutoaim( void );
|
||||||
|
virtual void SelectItem( const char *pstr, int iSubType = 0 );
|
||||||
|
|
||||||
|
virtual void UpdateClientData( void );
|
||||||
|
|
||||||
|
virtual float GetFOV( void );
|
||||||
|
int GetDefaultFOV( void ) const;
|
||||||
|
virtual bool IsZoomed( void ) { return false; }
|
||||||
|
|
||||||
|
float GetFOVDistanceAdjustFactor();
|
||||||
|
|
||||||
|
virtual void ViewPunch( const QAngle &angleOffset );
|
||||||
|
void ViewPunchReset( float tolerance = 0 );
|
||||||
|
|
||||||
|
void UpdateButtonState( int nUserCmdButtonMask );
|
||||||
|
int GetImpulse( void ) const;
|
||||||
|
|
||||||
|
virtual void Simulate();
|
||||||
|
|
||||||
|
virtual bool ShouldInterpolate();
|
||||||
|
|
||||||
|
virtual bool ShouldDraw();
|
||||||
|
virtual int DrawModel( int flags );
|
||||||
|
|
||||||
|
// Called when not in tactical mode. Allows view to be overriden for things like driving a tank.
|
||||||
|
virtual void OverrideView( CViewSetup *pSetup );
|
||||||
|
|
||||||
|
// returns the player name
|
||||||
|
const char * GetPlayerName();
|
||||||
|
virtual const Vector GetPlayerMins( void ) const; // uses local player
|
||||||
|
virtual const Vector GetPlayerMaxs( void ) const; // uses local player
|
||||||
|
|
||||||
|
// Is the player dead?
|
||||||
|
bool IsPlayerDead();
|
||||||
|
bool IsPoisoned( void ) { return m_Local.m_bPoisoned; }
|
||||||
|
|
||||||
|
// Vehicles...
|
||||||
|
IClientVehicle *GetVehicle();
|
||||||
|
|
||||||
|
bool IsInAVehicle() const { return ( NULL != m_hVehicle.Get() ) ? true : false; }
|
||||||
|
virtual void SetVehicleRole( int nRole );
|
||||||
|
void LeaveVehicle( void );
|
||||||
|
|
||||||
|
bool UsingStandardWeaponsInVehicle( void );
|
||||||
|
|
||||||
|
virtual void SetAnimation( PLAYER_ANIM playerAnim );
|
||||||
|
|
||||||
|
float GetTimeBase( void ) const;
|
||||||
|
float GetFinalPredictedTime() const;
|
||||||
|
|
||||||
|
bool IsInVGuiInputMode() const;
|
||||||
|
|
||||||
|
C_CommandContext *GetCommandContext();
|
||||||
|
|
||||||
|
// Get the command number associated with the current usercmd we're running (if in predicted code).
|
||||||
|
int CurrentCommandNumber() const;
|
||||||
|
const CUserCmd *GetCurrentUserCommand() const;
|
||||||
|
|
||||||
|
const QAngle& GetPunchAngle();
|
||||||
|
void SetPunchAngle( const QAngle &angle );
|
||||||
|
|
||||||
|
float GetWaterJumpTime() const;
|
||||||
|
void SetWaterJumpTime( float flWaterJumpTime );
|
||||||
|
float GetSwimSoundTime( void ) const;
|
||||||
|
void SetSwimSoundTime( float flSwimSoundTime );
|
||||||
|
|
||||||
|
// CS wants to allow small FOVs for zoomed-in AWPs.
|
||||||
|
virtual float GetMinFOV() const;
|
||||||
|
|
||||||
|
virtual void DoMuzzleFlash();
|
||||||
|
virtual void PlayPlayerJingle();
|
||||||
|
|
||||||
|
virtual void UpdateStepSound( surfacedata_t *psurface, const Vector &vecOrigin, const Vector &vecVelocity );
|
||||||
|
virtual void PlayStepSound( Vector &vecOrigin, surfacedata_t *psurface, float fvol, bool force );
|
||||||
|
virtual surfacedata_t * GetFootstepSurface( const Vector &origin, const char *surfaceName );
|
||||||
|
|
||||||
|
// Called by prediction when it detects a prediction correction.
|
||||||
|
// vDelta is the line from where the client had predicted the player to at the usercmd in question,
|
||||||
|
// to where the server says the client should be at said usercmd.
|
||||||
|
void NotePredictionError( const Vector &vDelta );
|
||||||
|
|
||||||
|
// Called by the renderer to apply the prediction error smoothing.
|
||||||
|
void GetPredictionErrorSmoothingVector( Vector &vOffset );
|
||||||
|
|
||||||
|
virtual void ExitLadder() {}
|
||||||
|
|
||||||
|
surfacedata_t *GetSurfaceData( void ) { return m_pSurfaceData; }
|
||||||
|
|
||||||
|
void SetLadderNormal( Vector vecLadderNormal ) { m_vecLadderNormal = vecLadderNormal; }
|
||||||
|
|
||||||
|
public:
|
||||||
|
int m_StuckLast;
|
||||||
|
|
||||||
|
// Data for only the local player
|
||||||
|
CNetworkVarEmbedded( CPlayerLocalData, m_Local );
|
||||||
|
|
||||||
|
// Data common to all other players, too
|
||||||
|
CPlayerState pl;
|
||||||
|
|
||||||
|
// Player FOV values
|
||||||
|
int m_iFOV; // field of view
|
||||||
|
int m_iFOVStart; // starting value of the FOV changing over time (client only)
|
||||||
|
float m_flFOVTime; // starting time of the FOV zoom
|
||||||
|
int m_iDefaultFOV; // default FOV if no other zooms are occurring
|
||||||
|
|
||||||
|
// For weapon prediction
|
||||||
|
bool m_fOnTarget; //Is the crosshair on a target?
|
||||||
|
|
||||||
|
char m_szAnimExtension[32];
|
||||||
|
|
||||||
|
int m_afButtonLast;
|
||||||
|
int m_afButtonPressed;
|
||||||
|
int m_afButtonReleased;
|
||||||
|
|
||||||
|
int m_nButtons;
|
||||||
|
|
||||||
|
CUserCmd *m_pCurrentCommand;
|
||||||
|
|
||||||
|
// Movement constraints
|
||||||
|
EHANDLE m_hConstraintEntity;
|
||||||
|
Vector m_vecConstraintCenter;
|
||||||
|
float m_flConstraintRadius;
|
||||||
|
float m_flConstraintWidth;
|
||||||
|
float m_flConstraintSpeedFactor;
|
||||||
|
|
||||||
|
protected:
|
||||||
|
|
||||||
|
void CalcPlayerView( Vector& eyeOrigin, QAngle& eyeAngles, float& fov );
|
||||||
|
void CalcVehicleView(IClientVehicle *pVehicle, Vector& eyeOrigin, QAngle& eyeAngles,
|
||||||
|
float& zNear, float& zFar, float& fov );
|
||||||
|
virtual void CalcObserverView( Vector& eyeOrigin, QAngle& eyeAngles, float& fov );
|
||||||
|
void CalcChaseCamView( Vector& eyeOrigin, QAngle& eyeAngles, float& fov );
|
||||||
|
void CalcInEyeCamView( Vector& eyeOrigin, QAngle& eyeAngles, float& fov );
|
||||||
|
void CalcDeathCamView( Vector& eyeOrigin, QAngle& eyeAngles, float& fov );
|
||||||
|
void CalcRoamingView(Vector& eyeOrigin, QAngle& eyeAngles, float& fov);
|
||||||
|
|
||||||
|
// Check to see if we're in vgui input mode...
|
||||||
|
void DetermineVguiInputMode( CUserCmd *pCmd );
|
||||||
|
|
||||||
|
// Used by prediction, sets the view angles for the player
|
||||||
|
void SetLocalViewAngles( const QAngle &viewAngles );
|
||||||
|
|
||||||
|
// used by client side player footsteps
|
||||||
|
surfacedata_t* GetGroundSurface();
|
||||||
|
|
||||||
|
protected:
|
||||||
|
// Did we just enter a vehicle this frame?
|
||||||
|
bool JustEnteredVehicle();
|
||||||
|
|
||||||
|
// DATA
|
||||||
|
int m_iObserverMode; // if in spectator mode != 0
|
||||||
|
EHANDLE m_hObserverTarget; // current observer target
|
||||||
|
float m_flObserverChaseDistance; // last distance to observer traget
|
||||||
|
float m_flDeathTime; // last time player died
|
||||||
|
|
||||||
|
float m_flStepSoundTime;
|
||||||
|
|
||||||
|
private:
|
||||||
|
// Make sure no one calls this...
|
||||||
|
C_BasePlayer& operator=( const C_BasePlayer& src );
|
||||||
|
C_BasePlayer( const C_BasePlayer & ); // not defined, not accessible
|
||||||
|
|
||||||
|
// Vehicle stuff.
|
||||||
|
EHANDLE m_hVehicle;
|
||||||
|
EHANDLE m_hOldVehicle;
|
||||||
|
EHANDLE m_hUseEntity;
|
||||||
|
|
||||||
|
float m_flMaxspeed;
|
||||||
|
int m_iHealth;
|
||||||
|
|
||||||
|
CInterpolatedVar< Vector > m_iv_vecViewOffset;
|
||||||
|
|
||||||
|
// Not replicated
|
||||||
|
Vector m_vecWaterJumpVel;
|
||||||
|
float m_flWaterJumpTime; // used to be called teleport_time
|
||||||
|
int m_nImpulse;
|
||||||
|
|
||||||
|
float m_flSwimSoundTime;
|
||||||
|
Vector m_vecLadderNormal;
|
||||||
|
|
||||||
|
QAngle m_vecOldViewAngles;
|
||||||
|
|
||||||
|
bool m_bWasFrozen;
|
||||||
|
int m_flPhysics;
|
||||||
|
|
||||||
|
int m_nTickBase;
|
||||||
|
int m_nFinalPredictedTick;
|
||||||
|
|
||||||
|
EHANDLE m_pCurrentVguiScreen;
|
||||||
|
|
||||||
|
// Player flashlight dynamic light pointers
|
||||||
|
CFlashlightEffect *m_pFlashlight;
|
||||||
|
|
||||||
|
typedef CHandle<C_BaseCombatWeapon> CBaseCombatWeaponHandle;
|
||||||
|
CNetworkVar( CBaseCombatWeaponHandle, m_hLastWeapon );
|
||||||
|
|
||||||
|
#if !defined( NO_ENTITY_PREDICTION )
|
||||||
|
CUtlVector< CHandle< C_BaseEntity > > m_SimulatedByThisPlayer;
|
||||||
|
#endif
|
||||||
|
|
||||||
|
// players own view models, left & right hand
|
||||||
|
CHandle< C_BaseViewModel > m_hViewModel[ MAX_VIEWMODELS ];
|
||||||
|
|
||||||
|
float m_flOldPlayerZ;
|
||||||
|
float m_flOldPlayerViewOffsetZ;
|
||||||
|
|
||||||
|
// For UI purposes...
|
||||||
|
int m_iOldAmmo[ MAX_AMMO_TYPES ];
|
||||||
|
|
||||||
|
C_CommandContext m_CommandContext;
|
||||||
|
|
||||||
|
// For underwater effects
|
||||||
|
float m_flWaterSurfaceZ;
|
||||||
|
bool m_bResampleWaterSurface;
|
||||||
|
TimedEvent m_tWaterParticleTimer;
|
||||||
|
CSmartPtr<WaterDebrisEffect> m_pWaterEmitter;
|
||||||
|
|
||||||
|
friend class CPrediction;
|
||||||
|
|
||||||
|
friend class CTFGameMovementRecon;
|
||||||
|
friend class CGameMovement;
|
||||||
|
friend class CTFGameMovement;
|
||||||
|
friend class CHL1GameMovement;
|
||||||
|
friend class CCSGameMovement;
|
||||||
|
friend class CHL2GameMovement;
|
||||||
|
friend class CDODGameMovement;
|
||||||
|
|
||||||
|
// Accessors for gamemovement
|
||||||
|
float GetStepSize( void ) const { return m_Local.m_flStepSize; }
|
||||||
|
|
||||||
|
float m_flNextAvoidanceTime;
|
||||||
|
float m_flAvoidanceRight;
|
||||||
|
float m_flAvoidanceForward;
|
||||||
|
float m_flAvoidanceDotForward;
|
||||||
|
float m_flAvoidanceDotRight;
|
||||||
|
|
||||||
|
protected:
|
||||||
|
virtual bool IsDucked( void ) const { return m_Local.m_bDucked; }
|
||||||
|
virtual bool IsDucking( void ) const { return m_Local.m_bDucking; }
|
||||||
|
virtual float GetFallVelocity( void ) { return m_Local.m_flFallVelocity; }
|
||||||
|
|
||||||
|
float m_flLaggedMovementValue;
|
||||||
|
|
||||||
|
// These are used to smooth out prediction corrections. They're most useful when colliding with
|
||||||
|
// vphysics objects. The server will be sending constant prediction corrections, and these can help
|
||||||
|
// the errors not be so jerky.
|
||||||
|
Vector m_vecPredictionError;
|
||||||
|
float m_flPredictionErrorTime;
|
||||||
|
|
||||||
|
char m_szLastPlaceName[MAX_PLACE_NAME_LENGTH]; // received from the server
|
||||||
|
|
||||||
|
// Texture names and surface data, used by CGameMovement
|
||||||
|
int m_surfaceProps;
|
||||||
|
surfacedata_t* m_pSurfaceData;
|
||||||
|
float m_surfaceFriction;
|
||||||
|
char m_chTextureType;
|
||||||
|
|
||||||
|
public:
|
||||||
|
|
||||||
|
const char *GetLastKnownPlaceName( void ) const { return m_szLastPlaceName; } // return the last nav place name the player occupied
|
||||||
|
|
||||||
|
float GetLaggedMovementValue( void ){ return m_flLaggedMovementValue; }
|
||||||
|
bool ShouldGoSouth( Vector vNPCForward, Vector vNPCRight ); //Such a bad name.
|
||||||
|
|
||||||
|
void SetOldPlayerZ( float flOld ) { m_flOldPlayerZ = flOld; }
|
||||||
|
};
|
||||||
|
|
||||||
|
EXTERN_RECV_TABLE(DT_BasePlayer);
|
||||||
|
|
||||||
|
//-----------------------------------------------------------------------------
|
||||||
|
// Inline methods
|
||||||
|
//-----------------------------------------------------------------------------
|
||||||
|
inline C_BasePlayer *ToBasePlayer( C_BaseEntity *pEntity )
|
||||||
|
{
|
||||||
|
if ( !pEntity || !pEntity->IsPlayer() )
|
||||||
|
return NULL;
|
||||||
|
|
||||||
|
#if _DEBUG
|
||||||
|
Assert( dynamic_cast<C_BasePlayer *>( pEntity ) != NULL );
|
||||||
|
#endif
|
||||||
|
|
||||||
|
return static_cast<C_BasePlayer *>( pEntity );
|
||||||
|
}
|
||||||
|
|
||||||
|
inline IClientVehicle *C_BasePlayer::GetVehicle()
|
||||||
|
{
|
||||||
|
C_BaseEntity *pVehicleEnt = m_hVehicle.Get();
|
||||||
|
return pVehicleEnt ? pVehicleEnt->GetClientVehicle() : NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
inline bool C_BasePlayer::IsObserver() const
|
||||||
|
{
|
||||||
|
return (GetObserverMode() != OBS_MODE_NONE);
|
||||||
|
}
|
||||||
|
|
||||||
|
inline int C_BasePlayer::GetImpulse( void ) const
|
||||||
|
{
|
||||||
|
return m_nImpulse;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
inline C_CommandContext* C_BasePlayer::GetCommandContext()
|
||||||
|
{
|
||||||
|
return &m_CommandContext;
|
||||||
|
}
|
||||||
|
|
||||||
|
inline int CBasePlayer::CurrentCommandNumber() const
|
||||||
|
{
|
||||||
|
Assert( m_pCurrentCommand );
|
||||||
|
return m_pCurrentCommand->command_number;
|
||||||
|
}
|
||||||
|
|
||||||
|
inline const CUserCmd *CBasePlayer::GetCurrentUserCommand() const
|
||||||
|
{
|
||||||
|
Assert( m_pCurrentCommand );
|
||||||
|
return m_pCurrentCommand;
|
||||||
|
}
|
||||||
|
|
||||||
|
#endif // C_BASEPLAYER_H
|
200
cl_dll/c_basetempentity.cpp
Normal file
200
cl_dll/c_basetempentity.cpp
Normal file
@ -0,0 +1,200 @@
|
|||||||
|
//========= Copyright © 1996-2005, Valve Corporation, All rights reserved. ============//
|
||||||
|
//
|
||||||
|
// Purpose: Core Temp Entity client implementation.
|
||||||
|
//
|
||||||
|
// $NoKeywords: $
|
||||||
|
//=============================================================================//
|
||||||
|
#include "cbase.h"
|
||||||
|
#include "c_basetempentity.h"
|
||||||
|
|
||||||
|
// memdbgon must be the last include file in a .cpp file!!!
|
||||||
|
#include "tier0/memdbgon.h"
|
||||||
|
|
||||||
|
IMPLEMENT_CLIENTCLASS(C_BaseTempEntity, DT_BaseTempEntity, CBaseTempEntity);
|
||||||
|
|
||||||
|
BEGIN_RECV_TABLE_NOBASE(C_BaseTempEntity, DT_BaseTempEntity)
|
||||||
|
END_RECV_TABLE()
|
||||||
|
|
||||||
|
|
||||||
|
// Global list of temp entity classes
|
||||||
|
C_BaseTempEntity *C_BaseTempEntity::s_pTempEntities = NULL;
|
||||||
|
|
||||||
|
// Global list of dynamic temp entities
|
||||||
|
C_BaseTempEntity *C_BaseTempEntity::s_pDynamicEntities = NULL;
|
||||||
|
|
||||||
|
//-----------------------------------------------------------------------------
|
||||||
|
// Purpose: Returns head of list
|
||||||
|
// Output : CBaseTempEntity * -- head of list
|
||||||
|
//-----------------------------------------------------------------------------
|
||||||
|
C_BaseTempEntity *C_BaseTempEntity::GetDynamicList( void )
|
||||||
|
{
|
||||||
|
return s_pDynamicEntities;
|
||||||
|
}
|
||||||
|
|
||||||
|
//-----------------------------------------------------------------------------
|
||||||
|
// Purpose: Returns head of list
|
||||||
|
// Output : CBaseTempEntity * -- head of list
|
||||||
|
//-----------------------------------------------------------------------------
|
||||||
|
C_BaseTempEntity *C_BaseTempEntity::GetList( void )
|
||||||
|
{
|
||||||
|
return s_pTempEntities;
|
||||||
|
}
|
||||||
|
|
||||||
|
//-----------------------------------------------------------------------------
|
||||||
|
// Purpose:
|
||||||
|
// Output :
|
||||||
|
//-----------------------------------------------------------------------------
|
||||||
|
C_BaseTempEntity::C_BaseTempEntity( void )
|
||||||
|
{
|
||||||
|
// Add to list
|
||||||
|
m_pNext = s_pTempEntities;
|
||||||
|
s_pTempEntities = this;
|
||||||
|
|
||||||
|
m_pNextDynamic = NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
//-----------------------------------------------------------------------------
|
||||||
|
// Purpose:
|
||||||
|
// Output :
|
||||||
|
//-----------------------------------------------------------------------------
|
||||||
|
C_BaseTempEntity::~C_BaseTempEntity( void )
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
//-----------------------------------------------------------------------------
|
||||||
|
// Purpose: Get next temp ent in chain
|
||||||
|
// Output : CBaseTempEntity *
|
||||||
|
//-----------------------------------------------------------------------------
|
||||||
|
C_BaseTempEntity *C_BaseTempEntity::GetNext( void )
|
||||||
|
{
|
||||||
|
return m_pNext;
|
||||||
|
}
|
||||||
|
|
||||||
|
//-----------------------------------------------------------------------------
|
||||||
|
// Purpose: Get next temp ent in chain
|
||||||
|
// Output : CBaseTempEntity *
|
||||||
|
//-----------------------------------------------------------------------------
|
||||||
|
C_BaseTempEntity *C_BaseTempEntity::GetNextDynamic( void )
|
||||||
|
{
|
||||||
|
return m_pNextDynamic;
|
||||||
|
}
|
||||||
|
|
||||||
|
//-----------------------------------------------------------------------------
|
||||||
|
// Purpose:
|
||||||
|
//-----------------------------------------------------------------------------
|
||||||
|
void C_BaseTempEntity::Precache( void )
|
||||||
|
{
|
||||||
|
// Nothing...
|
||||||
|
}
|
||||||
|
|
||||||
|
//-----------------------------------------------------------------------------
|
||||||
|
// Purpose: Called at startup to allow temp entities to precache any models/sounds that they need
|
||||||
|
//-----------------------------------------------------------------------------
|
||||||
|
void C_BaseTempEntity::PrecacheTempEnts( void )
|
||||||
|
{
|
||||||
|
C_BaseTempEntity *te = GetList();
|
||||||
|
while ( te )
|
||||||
|
{
|
||||||
|
te->Precache();
|
||||||
|
te = te->GetNext();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
//-----------------------------------------------------------------------------
|
||||||
|
// Purpose: Called at startup and level load to clear out leftover temp entities
|
||||||
|
//-----------------------------------------------------------------------------
|
||||||
|
void C_BaseTempEntity::ClearDynamicTempEnts( void )
|
||||||
|
{
|
||||||
|
C_BaseTempEntity *next;
|
||||||
|
C_BaseTempEntity *te = s_pDynamicEntities;
|
||||||
|
while ( te )
|
||||||
|
{
|
||||||
|
next = te->GetNextDynamic();
|
||||||
|
delete te;
|
||||||
|
te = next;
|
||||||
|
}
|
||||||
|
|
||||||
|
s_pDynamicEntities = NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
//-----------------------------------------------------------------------------
|
||||||
|
// Purpose: Called at startup and level load to clear out leftover temp entities
|
||||||
|
//-----------------------------------------------------------------------------
|
||||||
|
void C_BaseTempEntity::CheckDynamicTempEnts( void )
|
||||||
|
{
|
||||||
|
C_BaseTempEntity *next, *newlist = NULL;
|
||||||
|
C_BaseTempEntity *te = s_pDynamicEntities;
|
||||||
|
while ( te )
|
||||||
|
{
|
||||||
|
next = te->GetNextDynamic();
|
||||||
|
if ( te->ShouldDestroy() )
|
||||||
|
{
|
||||||
|
delete te;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
te->m_pNextDynamic = newlist;
|
||||||
|
newlist = te;
|
||||||
|
}
|
||||||
|
te = next;
|
||||||
|
}
|
||||||
|
|
||||||
|
s_pDynamicEntities = newlist;
|
||||||
|
}
|
||||||
|
|
||||||
|
//-----------------------------------------------------------------------------
|
||||||
|
// Purpose: Dynamic/non-singleton temp entities are initialized by
|
||||||
|
// calling into here. They should be added to a list of C_BaseTempEntities so
|
||||||
|
// that their memory can be deallocated appropriately.
|
||||||
|
// Input : *pEnt -
|
||||||
|
// Output : Returns true on success, false on failure.
|
||||||
|
//-----------------------------------------------------------------------------
|
||||||
|
bool C_BaseTempEntity::Init( int entnum, int iSerialNum )
|
||||||
|
{
|
||||||
|
if ( entnum != -1 )
|
||||||
|
{
|
||||||
|
Assert( 0 );
|
||||||
|
}
|
||||||
|
|
||||||
|
// Link into dynamic entity list
|
||||||
|
m_pNextDynamic = s_pDynamicEntities;
|
||||||
|
s_pDynamicEntities = this;
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void C_BaseTempEntity::Release()
|
||||||
|
{
|
||||||
|
Assert( !"C_BaseTempEntity::Release should never be called" );
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void C_BaseTempEntity::NotifyShouldTransmit( ShouldTransmitState_t state )
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
//-----------------------------------------------------------------------------
|
||||||
|
// Purpose:
|
||||||
|
// Input : bool -
|
||||||
|
//-----------------------------------------------------------------------------
|
||||||
|
void C_BaseTempEntity::PreDataUpdate( DataUpdateType_t updateType )
|
||||||
|
{
|
||||||
|
// TE's may or may not implement this
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
int C_BaseTempEntity::entindex( void ) const { Assert( 0 ); return 0; }
|
||||||
|
void C_BaseTempEntity::PostDataUpdate( DataUpdateType_t updateType ) { Assert( 0 ); }
|
||||||
|
void C_BaseTempEntity::OnPreDataChanged( DataUpdateType_t updateType ) { Assert( 0 ); }
|
||||||
|
void C_BaseTempEntity::OnDataChanged( DataUpdateType_t updateType ) { Assert( 0 ); }
|
||||||
|
void C_BaseTempEntity::SetDormant( bool bDormant ) { Assert( 0 ); }
|
||||||
|
bool C_BaseTempEntity::IsDormant( void ) { Assert( 0 ); return false; };
|
||||||
|
void C_BaseTempEntity::ReceiveMessage( int classID, bf_read &msg ) { Assert( 0 ); }
|
||||||
|
|
||||||
|
void* C_BaseTempEntity::GetDataTableBasePtr()
|
||||||
|
{
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
121
cl_dll/c_basetempentity.h
Normal file
121
cl_dll/c_basetempentity.h
Normal file
@ -0,0 +1,121 @@
|
|||||||
|
//========= Copyright © 1996-2005, Valve Corporation, All rights reserved. ============//
|
||||||
|
//
|
||||||
|
// Purpose:
|
||||||
|
//
|
||||||
|
// $NoKeywords: $
|
||||||
|
//=============================================================================//
|
||||||
|
|
||||||
|
#ifndef C_BASETEMPENTITY_H
|
||||||
|
#define C_BASETEMPENTITY_H
|
||||||
|
#ifdef _WIN32
|
||||||
|
#pragma once
|
||||||
|
#endif
|
||||||
|
|
||||||
|
|
||||||
|
#include "client_class.h"
|
||||||
|
#include "iclientnetworkable.h"
|
||||||
|
#include "c_recipientfilter.h"
|
||||||
|
|
||||||
|
|
||||||
|
//-----------------------------------------------------------------------------
|
||||||
|
// Purpose: Base class for TEs. All TEs should derive from this and at
|
||||||
|
// least implement OnDataChanged to be notified when the TE has been received
|
||||||
|
// from the server
|
||||||
|
//-----------------------------------------------------------------------------
|
||||||
|
class C_BaseTempEntity : public IClientUnknown, public IClientNetworkable
|
||||||
|
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
DECLARE_CLASS_NOBASE( C_BaseTempEntity );
|
||||||
|
DECLARE_CLIENTCLASS();
|
||||||
|
|
||||||
|
C_BaseTempEntity( void );
|
||||||
|
virtual ~C_BaseTempEntity( void );
|
||||||
|
|
||||||
|
|
||||||
|
// IClientUnknown implementation.
|
||||||
|
public:
|
||||||
|
|
||||||
|
virtual void SetRefEHandle( const CBaseHandle &handle ) { Assert( false ); }
|
||||||
|
virtual const CBaseHandle& GetRefEHandle() const { return *((CBaseHandle*)0); }
|
||||||
|
|
||||||
|
virtual IClientUnknown* GetIClientUnknown() { return this; }
|
||||||
|
virtual ICollideable* GetCollideable() { return 0; }
|
||||||
|
virtual IClientNetworkable* GetClientNetworkable() { return this; }
|
||||||
|
virtual IClientRenderable* GetClientRenderable() { return 0; }
|
||||||
|
virtual IClientEntity* GetIClientEntity() { return 0; }
|
||||||
|
virtual C_BaseEntity* GetBaseEntity() { return 0; }
|
||||||
|
virtual IClientThinkable* GetClientThinkable() { return 0; }
|
||||||
|
|
||||||
|
|
||||||
|
// IClientNetworkable overrides.
|
||||||
|
public:
|
||||||
|
|
||||||
|
virtual void Release();
|
||||||
|
virtual void NotifyShouldTransmit( ShouldTransmitState_t state );
|
||||||
|
virtual void PreDataUpdate( DataUpdateType_t updateType );
|
||||||
|
virtual void PostDataUpdate( DataUpdateType_t updateType );
|
||||||
|
virtual void OnPreDataChanged( DataUpdateType_t updateType );
|
||||||
|
virtual void OnDataChanged( DataUpdateType_t updateType );
|
||||||
|
virtual void SetDormant( bool bDormant );
|
||||||
|
virtual bool IsDormant( void );
|
||||||
|
virtual int entindex( void ) const;
|
||||||
|
virtual void ReceiveMessage( int classID, bf_read &msg );
|
||||||
|
virtual void* GetDataTableBasePtr();
|
||||||
|
|
||||||
|
|
||||||
|
public:
|
||||||
|
|
||||||
|
// Dummy for CNetworkVars.
|
||||||
|
void NetworkStateChanged() {}
|
||||||
|
void NetworkStateChanged( void *pVar ) {}
|
||||||
|
|
||||||
|
virtual bool Init(int entnum, int iSerialNum);
|
||||||
|
|
||||||
|
virtual void Precache( void );
|
||||||
|
|
||||||
|
// For dynamic entities, return true to allow destruction
|
||||||
|
virtual bool ShouldDestroy( void ) { return false; };
|
||||||
|
|
||||||
|
C_BaseTempEntity *GetNext( void );
|
||||||
|
|
||||||
|
// Get list of tempentities
|
||||||
|
static C_BaseTempEntity *GetList( void );
|
||||||
|
|
||||||
|
C_BaseTempEntity *GetNextDynamic( void );
|
||||||
|
|
||||||
|
// Determine the color modulation amount
|
||||||
|
void GetColorModulation( float* color )
|
||||||
|
{
|
||||||
|
assert(color);
|
||||||
|
color[0] = color[1] = color[2] = 1.0f;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Should this object be able to have shadows cast onto it?
|
||||||
|
virtual bool ShouldReceiveProjectedTextures( int flags ) { return false; }
|
||||||
|
|
||||||
|
// Static members
|
||||||
|
public:
|
||||||
|
// List of dynamically allocated temp entis
|
||||||
|
static C_BaseTempEntity *GetDynamicList();
|
||||||
|
|
||||||
|
// Called at startup to allow temp entities to precache any models/sounds that they need
|
||||||
|
static void PrecacheTempEnts( void );
|
||||||
|
|
||||||
|
static void ClearDynamicTempEnts( void );
|
||||||
|
|
||||||
|
static void CheckDynamicTempEnts( void );
|
||||||
|
|
||||||
|
private:
|
||||||
|
|
||||||
|
// Next in chain
|
||||||
|
C_BaseTempEntity *m_pNext;
|
||||||
|
C_BaseTempEntity *m_pNextDynamic;
|
||||||
|
|
||||||
|
// TEs add themselves to this list for the executable.
|
||||||
|
static C_BaseTempEntity *s_pTempEntities;
|
||||||
|
static C_BaseTempEntity *s_pDynamicEntities;
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
#endif // C_BASETEMPENTITY_H
|
411
cl_dll/c_baseviewmodel.cpp
Normal file
411
cl_dll/c_baseviewmodel.cpp
Normal file
@ -0,0 +1,411 @@
|
|||||||
|
//========= Copyright © 1996-2005, Valve Corporation, All rights reserved. ============//
|
||||||
|
//
|
||||||
|
// Purpose: Client side view model implementation. Responsible for drawing
|
||||||
|
// the view model.
|
||||||
|
//
|
||||||
|
// $NoKeywords: $
|
||||||
|
//=============================================================================//
|
||||||
|
#include "cbase.h"
|
||||||
|
#include "c_baseviewmodel.h"
|
||||||
|
#include "model_types.h"
|
||||||
|
#include "hud.h"
|
||||||
|
#include "view_shared.h"
|
||||||
|
#include "iviewrender.h"
|
||||||
|
#include "view.h"
|
||||||
|
#include "vmatrix.h"
|
||||||
|
#include "cl_animevent.h"
|
||||||
|
#include "eventlist.h"
|
||||||
|
#include "tools/bonelist.h"
|
||||||
|
#include <KeyValues.h>
|
||||||
|
#include "hltvcamera.h"
|
||||||
|
|
||||||
|
// memdbgon must be the last include file in a .cpp file!!!
|
||||||
|
#include "tier0/memdbgon.h"
|
||||||
|
|
||||||
|
#ifdef CSTRIKE_DLL
|
||||||
|
ConVar cl_righthand( "cl_righthand", "1", FCVAR_ARCHIVE, "Use right-handed view models." );
|
||||||
|
#endif
|
||||||
|
|
||||||
|
void PostToolMessage( HTOOLHANDLE hEntity, KeyValues *msg );
|
||||||
|
|
||||||
|
void FormatViewModelAttachment( Vector &vOrigin, bool bInverse )
|
||||||
|
{
|
||||||
|
// Presumably, SetUpView has been called so we know our FOV and render origin.
|
||||||
|
const CViewSetup *pViewSetup = view->GetPlayerViewSetup();
|
||||||
|
|
||||||
|
float worldx = tan( pViewSetup->fov * M_PI/360.0 );
|
||||||
|
float viewx = tan( pViewSetup->fovViewmodel * M_PI/360.0 );
|
||||||
|
|
||||||
|
// aspect ratio cancels out, so only need one factor
|
||||||
|
// the difference between the screen coordinates of the 2 systems is the ratio
|
||||||
|
// of the coefficients of the projection matrices (tan (fov/2) is that coefficient)
|
||||||
|
float factorX = worldx / viewx;
|
||||||
|
|
||||||
|
float factorY = factorX;
|
||||||
|
|
||||||
|
// Get the coordinates in the viewer's space.
|
||||||
|
Vector tmp = vOrigin - pViewSetup->origin;
|
||||||
|
Vector vTransformed( MainViewRight().Dot( tmp ), MainViewUp().Dot( tmp ), MainViewForward().Dot( tmp ) );
|
||||||
|
|
||||||
|
// Now squash X and Y.
|
||||||
|
if ( bInverse )
|
||||||
|
{
|
||||||
|
if ( factorX != 0 && factorY != 0 )
|
||||||
|
{
|
||||||
|
vTransformed.x /= factorX;
|
||||||
|
vTransformed.y /= factorY;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
vTransformed.x = 0.0f;
|
||||||
|
vTransformed.y = 0.0f;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
vTransformed.x *= factorX;
|
||||||
|
vTransformed.y *= factorY;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
// Transform back to world space.
|
||||||
|
Vector vOut = (MainViewRight() * vTransformed.x) + (MainViewUp() * vTransformed.y) + (MainViewForward() * vTransformed.z);
|
||||||
|
vOrigin = pViewSetup->origin + vOut;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void C_BaseViewModel::FormatViewModelAttachment( int nAttachment, Vector &vecOrigin, QAngle &angle )
|
||||||
|
{
|
||||||
|
::FormatViewModelAttachment( vecOrigin, false );
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
bool C_BaseViewModel::IsViewModel() const
|
||||||
|
{
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
void C_BaseViewModel::UncorrectViewModelAttachment( Vector &vOrigin )
|
||||||
|
{
|
||||||
|
// Unformat the attachment.
|
||||||
|
::FormatViewModelAttachment( vOrigin, true );
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
//-----------------------------------------------------------------------------
|
||||||
|
// Purpose
|
||||||
|
//-----------------------------------------------------------------------------
|
||||||
|
void C_BaseViewModel::FireEvent( const Vector& origin, const QAngle& angles, int event, const char *options )
|
||||||
|
{
|
||||||
|
// We override sound requests so that we can play them locally on the owning player
|
||||||
|
if ( ( event == AE_CL_PLAYSOUND ) || ( event == CL_EVENT_SOUND ) )
|
||||||
|
{
|
||||||
|
// Only do this if we're owned by someone
|
||||||
|
if ( GetOwner() != NULL )
|
||||||
|
{
|
||||||
|
CLocalPlayerFilter filter;
|
||||||
|
EmitSound( filter, GetOwner()->GetSoundSourceIndex(), options, &GetAbsOrigin() );
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Otherwise pass the event to our associated weapon
|
||||||
|
C_BaseCombatWeapon *pWeapon = GetActiveWeapon();
|
||||||
|
if ( pWeapon )
|
||||||
|
{
|
||||||
|
bool bResult = pWeapon->OnFireEvent( this, origin, angles, event, options );
|
||||||
|
if ( !bResult )
|
||||||
|
{
|
||||||
|
BaseClass::FireEvent( origin, angles, event, options );
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
bool C_BaseViewModel::Interpolate( float currentTime )
|
||||||
|
{
|
||||||
|
CStudioHdr *pStudioHdr = GetModelPtr();
|
||||||
|
// Make sure we reset our animation information if we've switch sequences
|
||||||
|
UpdateAnimationParity();
|
||||||
|
|
||||||
|
bool bret = BaseClass::Interpolate( currentTime );
|
||||||
|
|
||||||
|
// Hack to extrapolate cycle counter for view model
|
||||||
|
float elapsed_time = currentTime - m_flAnimTime;
|
||||||
|
C_BasePlayer *pPlayer = C_BasePlayer::GetLocalPlayer();
|
||||||
|
|
||||||
|
// Predicted viewmodels have fixed up interval
|
||||||
|
if ( GetPredictable() || IsClientCreated() )
|
||||||
|
{
|
||||||
|
Assert( pPlayer );
|
||||||
|
float curtime = pPlayer ? pPlayer->GetFinalPredictedTime() : gpGlobals->curtime;
|
||||||
|
elapsed_time = curtime - m_flAnimTime;
|
||||||
|
// Adjust for interpolated partial frame
|
||||||
|
elapsed_time += ( gpGlobals->interpolation_amount * TICK_INTERVAL );
|
||||||
|
}
|
||||||
|
|
||||||
|
// Prediction errors?
|
||||||
|
if ( elapsed_time < 0 )
|
||||||
|
{
|
||||||
|
elapsed_time = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
float dt = elapsed_time * GetSequenceCycleRate( pStudioHdr, GetSequence() );
|
||||||
|
if ( dt >= 1.0f )
|
||||||
|
{
|
||||||
|
if ( !IsSequenceLooping( GetSequence() ) )
|
||||||
|
{
|
||||||
|
dt = 0.999f;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
dt = fmod( dt, 1.0f );
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
SetCycle( dt );
|
||||||
|
return bret;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
inline bool C_BaseViewModel::ShouldFlipViewModel()
|
||||||
|
{
|
||||||
|
#ifdef CSTRIKE_DLL
|
||||||
|
// If cl_righthand is set, then we want them all right-handed.
|
||||||
|
CBaseCombatWeapon *pWeapon = m_hWeapon.Get();
|
||||||
|
if ( pWeapon )
|
||||||
|
{
|
||||||
|
const FileWeaponInfo_t *pInfo = &pWeapon->GetWpnData();
|
||||||
|
return pInfo->m_bAllowFlipping && pInfo->m_bBuiltRightHanded != cl_righthand.GetBool();
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void C_BaseViewModel::ApplyBoneMatrixTransform( matrix3x4_t& transform )
|
||||||
|
{
|
||||||
|
if ( ShouldFlipViewModel() )
|
||||||
|
{
|
||||||
|
matrix3x4_t viewMatrix, viewMatrixInverse;
|
||||||
|
|
||||||
|
// We could get MATERIAL_VIEW here, but this is called sometimes before the renderer
|
||||||
|
// has set that matrix. Luckily, this is called AFTER the CViewSetup has been initialized.
|
||||||
|
const CViewSetup *pSetup = view->GetPlayerViewSetup();
|
||||||
|
AngleMatrix( pSetup->angles, pSetup->origin, viewMatrixInverse );
|
||||||
|
MatrixInvert( viewMatrixInverse, viewMatrix );
|
||||||
|
|
||||||
|
// Transform into view space.
|
||||||
|
matrix3x4_t temp, temp2;
|
||||||
|
ConcatTransforms( viewMatrix, transform, temp );
|
||||||
|
|
||||||
|
// Flip it along X.
|
||||||
|
|
||||||
|
// (This is the slower way to do it, and it equates to negating the top row).
|
||||||
|
//matrix3x4_t mScale;
|
||||||
|
//SetIdentityMatrix( mScale );
|
||||||
|
//mScale[0][0] = 1;
|
||||||
|
//mScale[1][1] = -1;
|
||||||
|
//mScale[2][2] = 1;
|
||||||
|
//ConcatTransforms( mScale, temp, temp2 );
|
||||||
|
temp[1][0] = -temp[1][0];
|
||||||
|
temp[1][1] = -temp[1][1];
|
||||||
|
temp[1][2] = -temp[1][2];
|
||||||
|
temp[1][3] = -temp[1][3];
|
||||||
|
|
||||||
|
// Transform back out of view space.
|
||||||
|
ConcatTransforms( viewMatrixInverse, temp, transform );
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
//-----------------------------------------------------------------------------
|
||||||
|
// Purpose: check if weapon viewmodel should be drawn
|
||||||
|
//-----------------------------------------------------------------------------
|
||||||
|
bool C_BaseViewModel::ShouldDraw()
|
||||||
|
{
|
||||||
|
if ( engine->IsHLTV() )
|
||||||
|
{
|
||||||
|
return ( HLTVCamera()->GetMode() == OBS_MODE_IN_EYE &&
|
||||||
|
HLTVCamera()->GetPrimaryTarget() == GetOwner() );
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
return BaseClass::ShouldDraw();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
//-----------------------------------------------------------------------------
|
||||||
|
// Purpose: Render the weapon. Draw the Viewmodel if the weapon's being carried
|
||||||
|
// by this player, otherwise draw the worldmodel.
|
||||||
|
//-----------------------------------------------------------------------------
|
||||||
|
int C_BaseViewModel::DrawModel( int flags )
|
||||||
|
{
|
||||||
|
if ( !m_bReadyToDraw )
|
||||||
|
return 0;
|
||||||
|
|
||||||
|
if ( flags & STUDIO_RENDER )
|
||||||
|
{
|
||||||
|
// Determine blending amount and tell engine
|
||||||
|
float blend = (float)( GetFxBlend() / 255.0f );
|
||||||
|
|
||||||
|
// Totally gone
|
||||||
|
if ( blend <= 0.0f )
|
||||||
|
return 0;
|
||||||
|
|
||||||
|
// Tell engine
|
||||||
|
render->SetBlend( blend );
|
||||||
|
|
||||||
|
float color[3];
|
||||||
|
GetColorModulation( color );
|
||||||
|
render->SetColorModulation( color );
|
||||||
|
}
|
||||||
|
|
||||||
|
if ( ShouldFlipViewModel() )
|
||||||
|
materials->CullMode( MATERIAL_CULLMODE_CW );
|
||||||
|
|
||||||
|
C_BasePlayer *pPlayer = C_BasePlayer::GetLocalPlayer();
|
||||||
|
int ret;
|
||||||
|
// If the local player's overriding the viewmodel rendering, let him do it
|
||||||
|
if ( pPlayer && pPlayer->IsOverridingViewmodel() )
|
||||||
|
{
|
||||||
|
ret = pPlayer->DrawOverriddenViewmodel( this, flags );
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
ret = BaseClass::DrawModel( flags );
|
||||||
|
}
|
||||||
|
|
||||||
|
materials->CullMode( MATERIAL_CULLMODE_CCW );
|
||||||
|
|
||||||
|
// Now that we've rendered, reset the animation restart flag
|
||||||
|
if ( flags & STUDIO_RENDER )
|
||||||
|
{
|
||||||
|
if ( m_nOldAnimationParity != m_nAnimationParity )
|
||||||
|
{
|
||||||
|
m_nOldAnimationParity = m_nAnimationParity;
|
||||||
|
}
|
||||||
|
// Tell the weapon itself that we've rendered, in case it wants to do something
|
||||||
|
C_BaseCombatWeapon *pWeapon = GetActiveWeapon();
|
||||||
|
if ( pWeapon )
|
||||||
|
{
|
||||||
|
pWeapon->ViewModelDrawn( this );
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
//-----------------------------------------------------------------------------
|
||||||
|
// Purpose: Called by the player when the player's overriding the viewmodel drawing. Avoids infinite recursion.
|
||||||
|
//-----------------------------------------------------------------------------
|
||||||
|
int C_BaseViewModel::DrawOverriddenViewmodel( int flags )
|
||||||
|
{
|
||||||
|
return BaseClass::DrawModel( flags );
|
||||||
|
}
|
||||||
|
|
||||||
|
//-----------------------------------------------------------------------------
|
||||||
|
// Purpose:
|
||||||
|
// Output : int
|
||||||
|
//-----------------------------------------------------------------------------
|
||||||
|
int C_BaseViewModel::GetFxBlend( void )
|
||||||
|
{
|
||||||
|
// See if the local player wants to override the viewmodel's rendering
|
||||||
|
C_BasePlayer *pPlayer = C_BasePlayer::GetLocalPlayer();
|
||||||
|
if ( pPlayer && pPlayer->IsOverridingViewmodel() )
|
||||||
|
{
|
||||||
|
return pPlayer->GetFxBlend();
|
||||||
|
}
|
||||||
|
|
||||||
|
return BaseClass::GetFxBlend();
|
||||||
|
}
|
||||||
|
|
||||||
|
//-----------------------------------------------------------------------------
|
||||||
|
// Purpose:
|
||||||
|
// Output : Returns true on success, false on failure.
|
||||||
|
//-----------------------------------------------------------------------------
|
||||||
|
bool C_BaseViewModel::IsTransparent( void )
|
||||||
|
{
|
||||||
|
// See if the local player wants to override the viewmodel's rendering
|
||||||
|
C_BasePlayer *pPlayer = C_BasePlayer::GetLocalPlayer();
|
||||||
|
if ( pPlayer && pPlayer->IsOverridingViewmodel() )
|
||||||
|
{
|
||||||
|
return pPlayer->ViewModel_IsTransparent();
|
||||||
|
}
|
||||||
|
|
||||||
|
return BaseClass::IsTransparent();
|
||||||
|
}
|
||||||
|
|
||||||
|
//-----------------------------------------------------------------------------
|
||||||
|
// Purpose: If the animation parity of the weapon has changed, we reset cycle to avoid popping
|
||||||
|
//-----------------------------------------------------------------------------
|
||||||
|
void C_BaseViewModel::UpdateAnimationParity( void )
|
||||||
|
{
|
||||||
|
C_BasePlayer *pPlayer = C_BasePlayer::GetLocalPlayer();
|
||||||
|
|
||||||
|
// If we're predicting, then we don't use animation parity because we change the animations on the clientside
|
||||||
|
// while predicting. When not predicting, only the server changes the animations, so a parity mismatch
|
||||||
|
// tells us if we need to reset the animation.
|
||||||
|
if ( m_nOldAnimationParity != m_nAnimationParity && !GetPredictable() )
|
||||||
|
{
|
||||||
|
float curtime = (pPlayer && IsIntermediateDataAllocated()) ? pPlayer->GetFinalPredictedTime() : gpGlobals->curtime;
|
||||||
|
// FIXME: this is bad
|
||||||
|
// Simulate a networked m_flAnimTime and m_flCycle
|
||||||
|
// FIXME: Do we need the magic 0.1?
|
||||||
|
SetCycle( 0.0f ); // GetSequenceCycleRate( GetSequence() ) * 0.1;
|
||||||
|
m_flAnimTime = curtime;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
//-----------------------------------------------------------------------------
|
||||||
|
// Purpose: Update global map state based on data received
|
||||||
|
// Input : bnewentity -
|
||||||
|
//-----------------------------------------------------------------------------
|
||||||
|
void C_BaseViewModel::OnDataChanged( DataUpdateType_t updateType )
|
||||||
|
{
|
||||||
|
SetPredictionEligible( true );
|
||||||
|
BaseClass::OnDataChanged(updateType);
|
||||||
|
}
|
||||||
|
|
||||||
|
void C_BaseViewModel::PostDataUpdate( DataUpdateType_t updateType )
|
||||||
|
{
|
||||||
|
BaseClass::PostDataUpdate(updateType);
|
||||||
|
OnLatchInterpolatedVariables( LATCH_ANIMATION_VAR );
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
//-----------------------------------------------------------------------------
|
||||||
|
// Purpose: Add entity to visible view models list
|
||||||
|
//-----------------------------------------------------------------------------
|
||||||
|
void C_BaseViewModel::AddEntity( void )
|
||||||
|
{
|
||||||
|
// Server says don't interpolate this frame, so set previous info to new info.
|
||||||
|
if ( IsEffectActive(EF_NOINTERP) )
|
||||||
|
{
|
||||||
|
ResetLatched();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
//-----------------------------------------------------------------------------
|
||||||
|
// Purpose:
|
||||||
|
//-----------------------------------------------------------------------------
|
||||||
|
void C_BaseViewModel::GetBoneControllers(float controllers[MAXSTUDIOBONECTRLS])
|
||||||
|
{
|
||||||
|
BaseClass::GetBoneControllers( controllers );
|
||||||
|
|
||||||
|
// Tell the weapon itself that we've rendered, in case it wants to do something
|
||||||
|
C_BaseCombatWeapon *pWeapon = GetActiveWeapon();
|
||||||
|
if ( pWeapon )
|
||||||
|
{
|
||||||
|
pWeapon->GetViewmodelBoneControllers( this, controllers );
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
//-----------------------------------------------------------------------------
|
||||||
|
// Purpose:
|
||||||
|
// Output : RenderGroup_t
|
||||||
|
//-----------------------------------------------------------------------------
|
||||||
|
RenderGroup_t C_BaseViewModel::GetRenderGroup()
|
||||||
|
{
|
||||||
|
return RENDER_GROUP_VIEW_MODEL_OPAQUE;
|
||||||
|
}
|
19
cl_dll/c_baseviewmodel.h
Normal file
19
cl_dll/c_baseviewmodel.h
Normal file
@ -0,0 +1,19 @@
|
|||||||
|
//========= Copyright © 1996-2005, Valve Corporation, All rights reserved. ============//
|
||||||
|
//
|
||||||
|
// Purpose: Client side view model implementation. Responsible for drawing
|
||||||
|
// the view model.
|
||||||
|
//
|
||||||
|
// $NoKeywords: $
|
||||||
|
//=============================================================================//
|
||||||
|
|
||||||
|
#ifndef C_BASEVIEWMODEL_H
|
||||||
|
#define C_BASEVIEWMODEL_H
|
||||||
|
#ifdef _WIN32
|
||||||
|
#pragma once
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#include "c_baseanimating.h"
|
||||||
|
#include "UtlVector.h"
|
||||||
|
#include "baseviewmodel_shared.h"
|
||||||
|
|
||||||
|
#endif // C_BASEVIEWMODEL_H
|
46
cl_dll/c_breakableprop.cpp
Normal file
46
cl_dll/c_breakableprop.cpp
Normal file
@ -0,0 +1,46 @@
|
|||||||
|
//========= Copyright © 1996-2005, Valve Corporation, All rights reserved. ============//
|
||||||
|
//
|
||||||
|
// Purpose:
|
||||||
|
//
|
||||||
|
//=============================================================================//
|
||||||
|
#include "cbase.h"
|
||||||
|
#include "model_types.h"
|
||||||
|
#include "vcollide.h"
|
||||||
|
#include "vcollide_parse.h"
|
||||||
|
#include "solidsetdefaults.h"
|
||||||
|
#include "bone_setup.h"
|
||||||
|
#include "engine/ivmodelinfo.h"
|
||||||
|
#include "physics.h"
|
||||||
|
#include "c_breakableprop.h"
|
||||||
|
#include "view.h"
|
||||||
|
|
||||||
|
// memdbgon must be the last include file in a .cpp file!!!
|
||||||
|
#include "tier0/memdbgon.h"
|
||||||
|
|
||||||
|
IMPLEMENT_CLIENTCLASS_DT(C_BreakableProp, DT_BreakableProp, CBreakableProp)
|
||||||
|
END_RECV_TABLE()
|
||||||
|
|
||||||
|
//-----------------------------------------------------------------------------
|
||||||
|
// Purpose:
|
||||||
|
//-----------------------------------------------------------------------------
|
||||||
|
C_BreakableProp::C_BreakableProp( void )
|
||||||
|
{
|
||||||
|
m_takedamage = DAMAGE_YES;
|
||||||
|
}
|
||||||
|
|
||||||
|
//-----------------------------------------------------------------------------
|
||||||
|
// Purpose:
|
||||||
|
//-----------------------------------------------------------------------------
|
||||||
|
void C_BreakableProp::SetFadeMinMax( float fademin, float fademax )
|
||||||
|
{
|
||||||
|
m_fadeMinDist = fademin;
|
||||||
|
m_fadeMaxDist = fademax;
|
||||||
|
}
|
||||||
|
|
||||||
|
//-----------------------------------------------------------------------------
|
||||||
|
// Copy fade from another breakable prop
|
||||||
|
//-----------------------------------------------------------------------------
|
||||||
|
void C_BreakableProp::CopyFadeFrom( C_BreakableProp *pSource )
|
||||||
|
{
|
||||||
|
m_flFadeScale = pSource->m_flFadeScale;
|
||||||
|
}
|
30
cl_dll/c_breakableprop.h
Normal file
30
cl_dll/c_breakableprop.h
Normal file
@ -0,0 +1,30 @@
|
|||||||
|
//========= Copyright © 1996-2005, Valve Corporation, All rights reserved. ============//
|
||||||
|
//
|
||||||
|
// Purpose:
|
||||||
|
//
|
||||||
|
//=============================================================================//
|
||||||
|
|
||||||
|
#ifndef C_BREAKABLEPROP_H
|
||||||
|
#define C_BREAKABLEPROP_H
|
||||||
|
#ifdef _WIN32
|
||||||
|
#pragma once
|
||||||
|
#endif
|
||||||
|
|
||||||
|
//-----------------------------------------------------------------------------
|
||||||
|
// Purpose:
|
||||||
|
//-----------------------------------------------------------------------------
|
||||||
|
class C_BreakableProp : public C_BaseAnimating
|
||||||
|
{
|
||||||
|
typedef C_BaseAnimating BaseClass;
|
||||||
|
public:
|
||||||
|
DECLARE_CLIENTCLASS();
|
||||||
|
|
||||||
|
C_BreakableProp();
|
||||||
|
|
||||||
|
virtual void SetFadeMinMax( float fademin, float fademax );
|
||||||
|
|
||||||
|
// Copy fade from another breakable prop
|
||||||
|
void CopyFadeFrom( C_BreakableProp *pSource );
|
||||||
|
};
|
||||||
|
|
||||||
|
#endif // C_BREAKABLEPROP_H
|
143
cl_dll/c_colorcorrection.cpp
Normal file
143
cl_dll/c_colorcorrection.cpp
Normal file
@ -0,0 +1,143 @@
|
|||||||
|
//========= Copyright © 1996-2005, Valve Corporation, All rights reserved. ============//
|
||||||
|
//
|
||||||
|
// Purpose: Color correction entity with simple radial falloff
|
||||||
|
//
|
||||||
|
// $NoKeywords: $
|
||||||
|
//=============================================================================//
|
||||||
|
#include "cbase.h"
|
||||||
|
|
||||||
|
#include "cbase.h"
|
||||||
|
#include "filesystem.h"
|
||||||
|
#include "cdll_client_int.h"
|
||||||
|
|
||||||
|
#include "materialsystem/materialsystemutil.h"
|
||||||
|
#include "materialsystem/icolorcorrection.h"
|
||||||
|
|
||||||
|
#include "utlvector.h"
|
||||||
|
|
||||||
|
#include "generichash.h"
|
||||||
|
|
||||||
|
// memdbgon must be the last include file in a .cpp file!!!
|
||||||
|
#include "tier0/memdbgon.h"
|
||||||
|
|
||||||
|
|
||||||
|
//------------------------------------------------------------------------------
|
||||||
|
// Purpose : Color correction entity with radial falloff
|
||||||
|
//------------------------------------------------------------------------------
|
||||||
|
class C_ColorCorrection : public C_BaseEntity
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
DECLARE_CLASS( C_ColorCorrection, C_BaseEntity );
|
||||||
|
|
||||||
|
DECLARE_CLIENTCLASS();
|
||||||
|
|
||||||
|
void OnDataChanged(DataUpdateType_t updateType);
|
||||||
|
bool ShouldDraw();
|
||||||
|
|
||||||
|
void ClientThink();
|
||||||
|
|
||||||
|
private:
|
||||||
|
Vector m_vecOrigin;
|
||||||
|
|
||||||
|
float m_minFalloff;
|
||||||
|
float m_maxFalloff;
|
||||||
|
float m_maxWeight;
|
||||||
|
char m_netLookupFilename[MAX_PATH];
|
||||||
|
|
||||||
|
bool m_bEnabled;
|
||||||
|
|
||||||
|
ColorCorrectionHandle_t m_CCHandle;
|
||||||
|
};
|
||||||
|
|
||||||
|
IMPLEMENT_CLIENTCLASS_DT(C_ColorCorrection, DT_ColorCorrection, CColorCorrection)
|
||||||
|
RecvPropVector( RECVINFO(m_vecOrigin) ),
|
||||||
|
RecvPropFloat( RECVINFO(m_minFalloff) ),
|
||||||
|
RecvPropFloat( RECVINFO(m_maxFalloff) ),
|
||||||
|
RecvPropFloat( RECVINFO(m_maxWeight) ),
|
||||||
|
RecvPropString( RECVINFO(m_netLookupFilename) ),
|
||||||
|
RecvPropBool( RECVINFO(m_bEnabled) ),
|
||||||
|
|
||||||
|
END_RECV_TABLE()
|
||||||
|
|
||||||
|
//------------------------------------------------------------------------------
|
||||||
|
// Purpose :
|
||||||
|
// Input :
|
||||||
|
// Output :
|
||||||
|
//------------------------------------------------------------------------------
|
||||||
|
void C_ColorCorrection::OnDataChanged(DataUpdateType_t updateType)
|
||||||
|
{
|
||||||
|
BaseClass::OnDataChanged( updateType );
|
||||||
|
|
||||||
|
// We're releasing the CS:S client before the engine with this interface, so we need to fail gracefully
|
||||||
|
if ( !colorcorrection )
|
||||||
|
{
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if ( updateType == DATA_UPDATE_CREATED )
|
||||||
|
{
|
||||||
|
SetNextClientThink( CLIENT_THINK_ALWAYS );
|
||||||
|
|
||||||
|
char filename[MAX_PATH];
|
||||||
|
Q_strncpy( filename, m_netLookupFilename, MAX_PATH );
|
||||||
|
|
||||||
|
m_CCHandle = colorcorrection->AddLookup( filename );
|
||||||
|
|
||||||
|
colorcorrection->LockLookup( m_CCHandle );
|
||||||
|
colorcorrection->LoadLookup( m_CCHandle, filename );
|
||||||
|
colorcorrection->UnlockLookup( m_CCHandle );
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
//------------------------------------------------------------------------------
|
||||||
|
// We don't draw...
|
||||||
|
//------------------------------------------------------------------------------
|
||||||
|
bool C_ColorCorrection::ShouldDraw()
|
||||||
|
{
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
void C_ColorCorrection::ClientThink()
|
||||||
|
{
|
||||||
|
// We're releasing the CS:S client before the engine with this interface, so we need to fail gracefully
|
||||||
|
if ( !colorcorrection )
|
||||||
|
{
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if( !m_bEnabled )
|
||||||
|
{
|
||||||
|
colorcorrection->SetLookupWeight( m_CCHandle, 0.0f );
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
CBaseEntity *pPlayer = UTIL_PlayerByIndex(1);
|
||||||
|
if( !pPlayer )
|
||||||
|
{
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
Vector playerOrigin = pPlayer->GetAbsOrigin();
|
||||||
|
|
||||||
|
float dist = (playerOrigin - m_vecOrigin).Length();
|
||||||
|
float weight = (dist-m_minFalloff) / (m_maxFalloff-m_minFalloff);
|
||||||
|
if( weight<0.0f ) weight = 0.0f;
|
||||||
|
if( weight>1.0f ) weight = 1.0f;
|
||||||
|
|
||||||
|
colorcorrection->SetLookupWeight( m_CCHandle, m_maxWeight * (1.0f - weight) );
|
||||||
|
|
||||||
|
BaseClass::ClientThink();
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
126
cl_dll/c_colorcorrectionvolume.cpp
Normal file
126
cl_dll/c_colorcorrectionvolume.cpp
Normal file
@ -0,0 +1,126 @@
|
|||||||
|
//========= Copyright © 1996-2005, Valve Corporation, All rights reserved. ============//
|
||||||
|
//
|
||||||
|
// Purpose: Color correction entity.
|
||||||
|
//
|
||||||
|
// $NoKeywords: $
|
||||||
|
//=============================================================================//
|
||||||
|
#include "cbase.h"
|
||||||
|
|
||||||
|
#include "cbase.h"
|
||||||
|
#include "filesystem.h"
|
||||||
|
//#include "triggers.h"
|
||||||
|
#include "cdll_client_int.h"
|
||||||
|
|
||||||
|
#include "materialsystem/materialsystemutil.h"
|
||||||
|
#include "materialsystem/icolorcorrection.h"
|
||||||
|
|
||||||
|
#include "utlvector.h"
|
||||||
|
|
||||||
|
#include "generichash.h"
|
||||||
|
|
||||||
|
//#include "engine/conprint.h"
|
||||||
|
|
||||||
|
// memdbgon must be the last include file in a .cpp file!!!
|
||||||
|
#include "tier0/memdbgon.h"
|
||||||
|
|
||||||
|
//------------------------------------------------------------------------------
|
||||||
|
// FIXME: This really should inherit from something more lightweight
|
||||||
|
//------------------------------------------------------------------------------
|
||||||
|
|
||||||
|
|
||||||
|
//------------------------------------------------------------------------------
|
||||||
|
// Purpose : Shadow control entity
|
||||||
|
//------------------------------------------------------------------------------
|
||||||
|
class C_ColorCorrectionVolume : public C_BaseEntity
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
DECLARE_CLASS( C_ColorCorrectionVolume, C_BaseEntity );
|
||||||
|
|
||||||
|
DECLARE_CLIENTCLASS();
|
||||||
|
DECLARE_PREDICTABLE();
|
||||||
|
|
||||||
|
void OnDataChanged(DataUpdateType_t updateType);
|
||||||
|
bool ShouldDraw();
|
||||||
|
|
||||||
|
void ClientThink();
|
||||||
|
|
||||||
|
private:
|
||||||
|
|
||||||
|
float m_Weight;
|
||||||
|
char m_lookupFilename[MAX_PATH];
|
||||||
|
|
||||||
|
ColorCorrectionHandle_t m_CCHandle;
|
||||||
|
};
|
||||||
|
|
||||||
|
IMPLEMENT_CLIENTCLASS_DT(C_ColorCorrectionVolume, DT_ColorCorrectionVolume, CColorCorrectionVolume)
|
||||||
|
RecvPropFloat( RECVINFO(m_Weight) ),
|
||||||
|
RecvPropString( RECVINFO(m_lookupFilename) ),
|
||||||
|
END_RECV_TABLE()
|
||||||
|
|
||||||
|
BEGIN_PREDICTION_DATA( C_ColorCorrectionVolume )
|
||||||
|
DEFINE_PRED_FIELD( m_Weight, FIELD_FLOAT, FTYPEDESC_INSENDTABLE ),
|
||||||
|
END_PREDICTION_DATA()
|
||||||
|
|
||||||
|
//------------------------------------------------------------------------------
|
||||||
|
// Purpose :
|
||||||
|
// Input :
|
||||||
|
// Output :
|
||||||
|
//------------------------------------------------------------------------------
|
||||||
|
void C_ColorCorrectionVolume::OnDataChanged(DataUpdateType_t updateType)
|
||||||
|
{
|
||||||
|
BaseClass::OnDataChanged( updateType );
|
||||||
|
|
||||||
|
// We're releasing the CS:S client before the engine with this interface, so we need to fail gracefully
|
||||||
|
if ( !colorcorrection )
|
||||||
|
{
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if ( updateType == DATA_UPDATE_CREATED )
|
||||||
|
{
|
||||||
|
SetNextClientThink( CLIENT_THINK_ALWAYS );
|
||||||
|
|
||||||
|
char filename[MAX_PATH];
|
||||||
|
Q_strncpy( filename, m_lookupFilename, MAX_PATH );
|
||||||
|
|
||||||
|
m_CCHandle = colorcorrection->AddLookup( filename );
|
||||||
|
|
||||||
|
colorcorrection->LockLookup( m_CCHandle );
|
||||||
|
colorcorrection->LoadLookup( m_CCHandle, filename );
|
||||||
|
colorcorrection->UnlockLookup( m_CCHandle );
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
//------------------------------------------------------------------------------
|
||||||
|
// We don't draw...
|
||||||
|
//------------------------------------------------------------------------------
|
||||||
|
bool C_ColorCorrectionVolume::ShouldDraw()
|
||||||
|
{
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
void C_ColorCorrectionVolume::ClientThink()
|
||||||
|
{
|
||||||
|
// We're releasing the CS:S client before the engine with this interface, so we need to fail gracefully
|
||||||
|
if ( !colorcorrection )
|
||||||
|
{
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
Vector entityPosition = GetAbsOrigin();
|
||||||
|
|
||||||
|
colorcorrection->SetLookupWeight( m_CCHandle, m_Weight );
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
189
cl_dll/c_dynamiclight.cpp
Normal file
189
cl_dll/c_dynamiclight.cpp
Normal file
@ -0,0 +1,189 @@
|
|||||||
|
//========= Copyright © 1996-2005, Valve Corporation, All rights reserved. ============//
|
||||||
|
//
|
||||||
|
// Purpose: Dynamic light
|
||||||
|
//
|
||||||
|
// $Workfile: $
|
||||||
|
// $Date: $
|
||||||
|
// $NoKeywords: $
|
||||||
|
//=============================================================================//
|
||||||
|
#include "cbase.h"
|
||||||
|
#include "dlight.h"
|
||||||
|
#include "iefx.h"
|
||||||
|
#include "IViewRender.h"
|
||||||
|
|
||||||
|
// memdbgon must be the last include file in a .cpp file!!!
|
||||||
|
#include "tier0/memdbgon.h"
|
||||||
|
|
||||||
|
//-----------------------------------------------------------------------------
|
||||||
|
// A dynamic light, with the goofy hack needed for spotlights
|
||||||
|
//-----------------------------------------------------------------------------
|
||||||
|
class C_DynamicLight : public C_BaseEntity
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
DECLARE_CLASS( C_DynamicLight, C_BaseEntity );
|
||||||
|
DECLARE_CLIENTCLASS();
|
||||||
|
|
||||||
|
C_DynamicLight();
|
||||||
|
|
||||||
|
public:
|
||||||
|
void OnDataChanged(DataUpdateType_t updateType);
|
||||||
|
bool ShouldDraw();
|
||||||
|
void ClientThink( void );
|
||||||
|
|
||||||
|
unsigned char m_Flags;
|
||||||
|
unsigned char m_LightStyle;
|
||||||
|
|
||||||
|
float m_Radius;
|
||||||
|
int m_Exponent;
|
||||||
|
float m_InnerAngle;
|
||||||
|
float m_OuterAngle;
|
||||||
|
float m_SpotRadius;
|
||||||
|
|
||||||
|
private:
|
||||||
|
dlight_t* m_pDynamicLight;
|
||||||
|
dlight_t* m_pSpotlightEnd;
|
||||||
|
};
|
||||||
|
|
||||||
|
IMPLEMENT_CLIENTCLASS_DT(C_DynamicLight, DT_DynamicLight, CDynamicLight)
|
||||||
|
RecvPropInt (RECVINFO(m_Flags)),
|
||||||
|
RecvPropInt (RECVINFO(m_LightStyle)),
|
||||||
|
RecvPropFloat (RECVINFO(m_Radius)),
|
||||||
|
RecvPropInt (RECVINFO(m_Exponent)),
|
||||||
|
RecvPropFloat (RECVINFO(m_InnerAngle)),
|
||||||
|
RecvPropFloat (RECVINFO(m_OuterAngle)),
|
||||||
|
RecvPropFloat (RECVINFO(m_SpotRadius)),
|
||||||
|
END_RECV_TABLE()
|
||||||
|
|
||||||
|
|
||||||
|
//------------------------------------------------------------------------------
|
||||||
|
// Purpose :
|
||||||
|
//------------------------------------------------------------------------------
|
||||||
|
C_DynamicLight::C_DynamicLight(void) : m_pSpotlightEnd(0), m_pDynamicLight(0)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
//------------------------------------------------------------------------------
|
||||||
|
// Purpose :
|
||||||
|
//------------------------------------------------------------------------------
|
||||||
|
void C_DynamicLight::OnDataChanged(DataUpdateType_t updateType)
|
||||||
|
{
|
||||||
|
if ( updateType == DATA_UPDATE_CREATED )
|
||||||
|
{
|
||||||
|
SetNextClientThink(gpGlobals->curtime + 0.05);
|
||||||
|
}
|
||||||
|
|
||||||
|
BaseClass::OnDataChanged( updateType );
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
//------------------------------------------------------------------------------
|
||||||
|
// Purpose :
|
||||||
|
//------------------------------------------------------------------------------
|
||||||
|
bool C_DynamicLight::ShouldDraw()
|
||||||
|
{
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
//------------------------------------------------------------------------------
|
||||||
|
// Purpose :
|
||||||
|
//------------------------------------------------------------------------------
|
||||||
|
void C_DynamicLight::ClientThink(void)
|
||||||
|
{
|
||||||
|
Vector forward;
|
||||||
|
AngleVectors( GetAbsAngles(), &forward );
|
||||||
|
|
||||||
|
if ( (m_Flags & DLIGHT_NO_MODEL_ILLUMINATION) == 0 )
|
||||||
|
{
|
||||||
|
// Deal with the model light
|
||||||
|
if ( !m_pDynamicLight || (m_pDynamicLight->key != index) )
|
||||||
|
{
|
||||||
|
m_pDynamicLight = effects->CL_AllocDlight( index );
|
||||||
|
Assert (m_pDynamicLight);
|
||||||
|
}
|
||||||
|
|
||||||
|
m_pDynamicLight->style = m_LightStyle;
|
||||||
|
m_pDynamicLight->radius = m_Radius;
|
||||||
|
m_pDynamicLight->flags = m_Flags;
|
||||||
|
if ( m_OuterAngle > 0 )
|
||||||
|
m_pDynamicLight->flags |= DLIGHT_NO_WORLD_ILLUMINATION;
|
||||||
|
m_pDynamicLight->color.r = m_clrRender->r;
|
||||||
|
m_pDynamicLight->color.g = m_clrRender->g;
|
||||||
|
m_pDynamicLight->color.b = m_clrRender->b;
|
||||||
|
m_pDynamicLight->color.exponent = m_Exponent; // this makes it match the world
|
||||||
|
m_pDynamicLight->origin = GetAbsOrigin();
|
||||||
|
m_pDynamicLight->m_InnerAngle = m_InnerAngle;
|
||||||
|
m_pDynamicLight->m_OuterAngle = m_OuterAngle;
|
||||||
|
m_pDynamicLight->die = gpGlobals->curtime + 1e6;
|
||||||
|
m_pDynamicLight->m_Direction = forward;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
// In this case, the m_Flags could have changed; which is how we turn the light off
|
||||||
|
if (m_pDynamicLight)
|
||||||
|
{
|
||||||
|
m_pDynamicLight->die = gpGlobals->curtime;
|
||||||
|
m_pDynamicLight = 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (( m_OuterAngle > 0 ) && ((m_Flags & DLIGHT_NO_WORLD_ILLUMINATION) == 0) )
|
||||||
|
{
|
||||||
|
// Raycast to where the endpoint goes
|
||||||
|
// Deal with the environment light
|
||||||
|
if ( !m_pSpotlightEnd || (m_pSpotlightEnd->key != -index) )
|
||||||
|
{
|
||||||
|
m_pSpotlightEnd = effects->CL_AllocDlight( -index );
|
||||||
|
Assert (m_pSpotlightEnd);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Trace a line outward, don't use hitboxes (too slow)
|
||||||
|
Vector end;
|
||||||
|
VectorMA( GetAbsOrigin(), m_Radius, forward, end );
|
||||||
|
|
||||||
|
trace_t pm;
|
||||||
|
C_BaseEntity::PushEnableAbsRecomputations( false ); // HACK don't recompute positions while doing RayTrace
|
||||||
|
UTIL_TraceLine( GetAbsOrigin(), end, MASK_NPCWORLDSTATIC, NULL, COLLISION_GROUP_NONE, &pm );
|
||||||
|
C_BaseEntity::PopEnableAbsRecomputations();
|
||||||
|
VectorCopy( pm.endpos, m_pSpotlightEnd->origin );
|
||||||
|
|
||||||
|
if (pm.fraction == 1.0f)
|
||||||
|
{
|
||||||
|
m_pSpotlightEnd->die = gpGlobals->curtime;
|
||||||
|
m_pSpotlightEnd = 0;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
float falloff = 1.0 - pm.fraction;
|
||||||
|
falloff *= falloff;
|
||||||
|
|
||||||
|
m_pSpotlightEnd->style = m_LightStyle;
|
||||||
|
m_pSpotlightEnd->flags = DLIGHT_NO_MODEL_ILLUMINATION | (m_Flags & DLIGHT_DISPLACEMENT_MASK);
|
||||||
|
m_pSpotlightEnd->radius = m_SpotRadius; // * falloff;
|
||||||
|
m_pSpotlightEnd->die = gpGlobals->curtime + 1e6;
|
||||||
|
m_pSpotlightEnd->color.r = m_clrRender->r * falloff;
|
||||||
|
m_pSpotlightEnd->color.g = m_clrRender->g * falloff;
|
||||||
|
m_pSpotlightEnd->color.b = m_clrRender->b * falloff;
|
||||||
|
m_pSpotlightEnd->color.exponent = m_Exponent;
|
||||||
|
|
||||||
|
// For bumped lighting
|
||||||
|
m_pSpotlightEnd->m_Direction = forward;
|
||||||
|
|
||||||
|
// Update list of surfaces we influence
|
||||||
|
render->TouchLight( m_pSpotlightEnd );
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
// In this case, the m_Flags could have changed; which is how we turn the light off
|
||||||
|
if (m_pSpotlightEnd)
|
||||||
|
{
|
||||||
|
m_pSpotlightEnd->die = gpGlobals->curtime;
|
||||||
|
m_pSpotlightEnd = 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
SetNextClientThink(gpGlobals->curtime + 0.001);
|
||||||
|
}
|
||||||
|
|
2220
cl_dll/c_effects.cpp
Normal file
2220
cl_dll/c_effects.cpp
Normal file
File diff suppressed because it is too large
Load Diff
18
cl_dll/c_effects.h
Normal file
18
cl_dll/c_effects.h
Normal file
@ -0,0 +1,18 @@
|
|||||||
|
//========= Copyright © 1996-2005, Valve Corporation, All rights reserved. ============//
|
||||||
|
//
|
||||||
|
// Purpose:
|
||||||
|
//
|
||||||
|
//=============================================================================//
|
||||||
|
|
||||||
|
#ifndef C_EFFECTS_H
|
||||||
|
#define C_EFFECTS_H
|
||||||
|
#ifdef _WIN32
|
||||||
|
#pragma once
|
||||||
|
#endif
|
||||||
|
|
||||||
|
|
||||||
|
// Draw rain effects.
|
||||||
|
void DrawPrecipitation();
|
||||||
|
|
||||||
|
|
||||||
|
#endif // C_EFFECTS_H
|
773
cl_dll/c_entitydissolve.cpp
Normal file
773
cl_dll/c_entitydissolve.cpp
Normal file
@ -0,0 +1,773 @@
|
|||||||
|
//========= Copyright © 1996-2005, Valve Corporation, All rights reserved. ============//
|
||||||
|
//
|
||||||
|
// Purpose:
|
||||||
|
//
|
||||||
|
// $NoKeywords: $
|
||||||
|
//=============================================================================//
|
||||||
|
|
||||||
|
#include "cbase.h"
|
||||||
|
|
||||||
|
#include "IViewRender.h"
|
||||||
|
#include "view.h"
|
||||||
|
#include "studio.h"
|
||||||
|
#include "bone_setup.h"
|
||||||
|
#include "model_types.h"
|
||||||
|
#include "beamdraw.h"
|
||||||
|
#include "engine/ivdebugoverlay.h"
|
||||||
|
#include "iviewrender_beams.h"
|
||||||
|
#include "fx.h"
|
||||||
|
#include "IEffects.h"
|
||||||
|
#include "c_entitydissolve.h"
|
||||||
|
#include "movevars_shared.h"
|
||||||
|
#include "ClientEffectPrecacheSystem.h"
|
||||||
|
|
||||||
|
// memdbgon must be the last include file in a .cpp file!!!
|
||||||
|
#include "tier0/memdbgon.h"
|
||||||
|
|
||||||
|
CLIENTEFFECT_REGISTER_BEGIN( PrecacheEffectBuild )
|
||||||
|
CLIENTEFFECT_MATERIAL( "effects/tesla_glow_noz" )
|
||||||
|
CLIENTEFFECT_MATERIAL( "effects/spark" )
|
||||||
|
CLIENTEFFECT_MATERIAL( "effects/combinemuzzle2" )
|
||||||
|
CLIENTEFFECT_REGISTER_END()
|
||||||
|
|
||||||
|
//-----------------------------------------------------------------------------
|
||||||
|
// Networking
|
||||||
|
//-----------------------------------------------------------------------------
|
||||||
|
IMPLEMENT_CLIENTCLASS_DT( C_EntityDissolve, DT_EntityDissolve, CEntityDissolve )
|
||||||
|
RecvPropTime(RECVINFO(m_flStartTime)),
|
||||||
|
RecvPropFloat(RECVINFO(m_flFadeOutStart)),
|
||||||
|
RecvPropFloat(RECVINFO(m_flFadeOutLength)),
|
||||||
|
RecvPropFloat(RECVINFO(m_flFadeOutModelStart)),
|
||||||
|
RecvPropFloat(RECVINFO(m_flFadeOutModelLength)),
|
||||||
|
RecvPropFloat(RECVINFO(m_flFadeInStart)),
|
||||||
|
RecvPropFloat(RECVINFO(m_flFadeInLength)),
|
||||||
|
RecvPropInt(RECVINFO(m_nDissolveType)),
|
||||||
|
RecvPropVector( RECVINFO( m_vDissolverOrigin) ),
|
||||||
|
RecvPropInt( RECVINFO( m_nMagnitude ) ),
|
||||||
|
END_RECV_TABLE()
|
||||||
|
|
||||||
|
extern PMaterialHandle g_Material_Spark;
|
||||||
|
PMaterialHandle g_Material_AR2Glow = NULL;
|
||||||
|
|
||||||
|
//-----------------------------------------------------------------------------
|
||||||
|
// Purpose:
|
||||||
|
//-----------------------------------------------------------------------------
|
||||||
|
C_EntityDissolve::C_EntityDissolve( void )
|
||||||
|
{
|
||||||
|
m_bLinkedToServerEnt = true;
|
||||||
|
m_pController = false;
|
||||||
|
m_bCoreExplode = false;
|
||||||
|
}
|
||||||
|
|
||||||
|
//-----------------------------------------------------------------------------
|
||||||
|
// Purpose:
|
||||||
|
//-----------------------------------------------------------------------------
|
||||||
|
void C_EntityDissolve::GetRenderBounds( Vector& theMins, Vector& theMaxs )
|
||||||
|
{
|
||||||
|
if ( GetMoveParent() )
|
||||||
|
{
|
||||||
|
GetMoveParent()->GetRenderBounds( theMins, theMaxs );
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
theMins = GetAbsOrigin();
|
||||||
|
theMaxs = theMaxs;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
//-----------------------------------------------------------------------------
|
||||||
|
// On data changed
|
||||||
|
//-----------------------------------------------------------------------------
|
||||||
|
void C_EntityDissolve::OnDataChanged( DataUpdateType_t updateType )
|
||||||
|
{
|
||||||
|
BaseClass::OnDataChanged( updateType );
|
||||||
|
if ( updateType == DATA_UPDATE_CREATED )
|
||||||
|
{
|
||||||
|
m_flNextSparkTime = m_flStartTime;
|
||||||
|
SetNextClientThink( CLIENT_THINK_ALWAYS );
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
//-----------------------------------------------------------------------------
|
||||||
|
// Cleanup
|
||||||
|
//-----------------------------------------------------------------------------
|
||||||
|
void C_EntityDissolve::UpdateOnRemove( void )
|
||||||
|
{
|
||||||
|
if ( m_pController )
|
||||||
|
{
|
||||||
|
physenv->DestroyMotionController( m_pController );
|
||||||
|
m_pController = NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
BaseClass::UpdateOnRemove();
|
||||||
|
}
|
||||||
|
|
||||||
|
//------------------------------------------------------------------------------
|
||||||
|
// Apply the forces to the entity
|
||||||
|
//------------------------------------------------------------------------------
|
||||||
|
IMotionEvent::simresult_e C_EntityDissolve::Simulate( IPhysicsMotionController *pController, IPhysicsObject *pObject, float deltaTime, Vector &linear, AngularImpulse &angular )
|
||||||
|
{
|
||||||
|
linear.Init();
|
||||||
|
angular.Init();
|
||||||
|
|
||||||
|
// Make it zero g
|
||||||
|
linear.z -= -1.02 * sv_gravity.GetFloat();
|
||||||
|
|
||||||
|
Vector vel;
|
||||||
|
AngularImpulse angVel;
|
||||||
|
pObject->GetVelocity( &vel, &angVel );
|
||||||
|
vel += linear * deltaTime; // account for gravity scale
|
||||||
|
|
||||||
|
Vector unitVel = vel;
|
||||||
|
Vector unitAngVel = angVel;
|
||||||
|
|
||||||
|
float speed = VectorNormalize( unitVel );
|
||||||
|
// float angSpeed = VectorNormalize( unitAngVel );
|
||||||
|
|
||||||
|
// float speedScale = 0.0;
|
||||||
|
// float angSpeedScale = 0.0;
|
||||||
|
|
||||||
|
float flLinearLimit = 50;
|
||||||
|
float flLinearLimitDelta = 40;
|
||||||
|
if ( speed > flLinearLimit )
|
||||||
|
{
|
||||||
|
float flDeltaVel = (flLinearLimit - speed) / deltaTime;
|
||||||
|
if ( flLinearLimitDelta != 0.0f )
|
||||||
|
{
|
||||||
|
float flMaxDeltaVel = -flLinearLimitDelta / deltaTime;
|
||||||
|
if ( flDeltaVel < flMaxDeltaVel )
|
||||||
|
{
|
||||||
|
flDeltaVel = flMaxDeltaVel;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
VectorMA( linear, flDeltaVel, unitVel, linear );
|
||||||
|
}
|
||||||
|
|
||||||
|
return SIM_GLOBAL_ACCELERATION;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
//-----------------------------------------------------------------------------
|
||||||
|
// Tesla effect
|
||||||
|
//-----------------------------------------------------------------------------
|
||||||
|
static void FX_BuildTesla( C_BaseEntity *pEntity, Vector &vecOrigin, Vector &vecEnd )
|
||||||
|
{
|
||||||
|
BeamInfo_t beamInfo;
|
||||||
|
beamInfo.m_pStartEnt = pEntity;
|
||||||
|
beamInfo.m_nStartAttachment = 0;
|
||||||
|
beamInfo.m_pEndEnt = NULL;
|
||||||
|
beamInfo.m_nEndAttachment = 0;
|
||||||
|
beamInfo.m_nType = TE_BEAMTESLA;
|
||||||
|
beamInfo.m_vecStart = vecOrigin;
|
||||||
|
beamInfo.m_vecEnd = vecEnd;
|
||||||
|
beamInfo.m_pszModelName = "sprites/lgtning.vmt";
|
||||||
|
beamInfo.m_flHaloScale = 0.0;
|
||||||
|
beamInfo.m_flLife = random->RandomFloat( 0.25f, 1.0f );
|
||||||
|
beamInfo.m_flWidth = random->RandomFloat( 8.0f, 14.0f );
|
||||||
|
beamInfo.m_flEndWidth = 1.0f;
|
||||||
|
beamInfo.m_flFadeLength = 0.5f;
|
||||||
|
beamInfo.m_flAmplitude = 24;
|
||||||
|
beamInfo.m_flBrightness = 255.0;
|
||||||
|
beamInfo.m_flSpeed = 150.0f;
|
||||||
|
beamInfo.m_nStartFrame = 0.0;
|
||||||
|
beamInfo.m_flFrameRate = 30.0;
|
||||||
|
beamInfo.m_flRed = 255.0;
|
||||||
|
beamInfo.m_flGreen = 255.0;
|
||||||
|
beamInfo.m_flBlue = 255.0;
|
||||||
|
beamInfo.m_nSegments = 18;
|
||||||
|
beamInfo.m_bRenderable = true;
|
||||||
|
beamInfo.m_nFlags = 0; //FBEAM_ONLYNOISEONCE;
|
||||||
|
|
||||||
|
beams->CreateBeamEntPoint( beamInfo );
|
||||||
|
}
|
||||||
|
|
||||||
|
//-----------------------------------------------------------------------------
|
||||||
|
// Purpose: Tesla effect
|
||||||
|
//-----------------------------------------------------------------------------
|
||||||
|
void C_EntityDissolve::BuildTeslaEffect( mstudiobbox_t *pHitBox, const matrix3x4_t &hitboxToWorld, bool bRandom, float flYawOffset )
|
||||||
|
{
|
||||||
|
Vector vecOrigin;
|
||||||
|
QAngle vecAngles;
|
||||||
|
MatrixGetColumn( hitboxToWorld, 3, vecOrigin );
|
||||||
|
MatrixAngles( hitboxToWorld, vecAngles.Base() );
|
||||||
|
C_BaseEntity *pEntity = GetMoveParent();
|
||||||
|
|
||||||
|
// Make a couple of tries at it
|
||||||
|
int iTries = -1;
|
||||||
|
Vector vecForward;
|
||||||
|
trace_t tr;
|
||||||
|
do
|
||||||
|
{
|
||||||
|
iTries++;
|
||||||
|
|
||||||
|
// Some beams are deliberatly aimed around the point, the rest are random.
|
||||||
|
if ( !bRandom )
|
||||||
|
{
|
||||||
|
QAngle vecTemp = vecAngles;
|
||||||
|
vecTemp[YAW] += flYawOffset;
|
||||||
|
AngleVectors( vecTemp, &vecForward );
|
||||||
|
|
||||||
|
// Randomly angle it up or down
|
||||||
|
vecForward.z = RandomFloat( -1, 1 );
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
vecForward = RandomVector( -1, 1 );
|
||||||
|
}
|
||||||
|
|
||||||
|
UTIL_TraceLine( vecOrigin, vecOrigin + (vecForward * 192), MASK_SHOT, pEntity, COLLISION_GROUP_NONE, &tr );
|
||||||
|
} while ( tr.fraction >= 1.0 && iTries < 3 );
|
||||||
|
|
||||||
|
Vector vecEnd = tr.endpos - (vecForward * 8);
|
||||||
|
|
||||||
|
// Only spark & glow if we hit something
|
||||||
|
if ( tr.fraction < 1.0 )
|
||||||
|
{
|
||||||
|
if ( !EffectOccluded( tr.endpos ) )
|
||||||
|
{
|
||||||
|
// Move it towards the camera
|
||||||
|
Vector vecFlash = tr.endpos;
|
||||||
|
Vector vecForward;
|
||||||
|
AngleVectors( MainViewAngles(), &vecForward );
|
||||||
|
vecFlash -= (vecForward * 8);
|
||||||
|
|
||||||
|
g_pEffects->EnergySplash( vecFlash, -vecForward, false );
|
||||||
|
|
||||||
|
// End glow
|
||||||
|
CSmartPtr<CSimpleEmitter> pSimple = CSimpleEmitter::Create( "dust" );
|
||||||
|
pSimple->SetSortOrigin( vecFlash );
|
||||||
|
SimpleParticle *pParticle;
|
||||||
|
pParticle = (SimpleParticle *) pSimple->AddParticle( sizeof( SimpleParticle ), pSimple->GetPMaterial( "effects/tesla_glow_noz" ), vecFlash );
|
||||||
|
if ( pParticle != NULL )
|
||||||
|
{
|
||||||
|
pParticle->m_flLifetime = 0.0f;
|
||||||
|
pParticle->m_flDieTime = RandomFloat( 0.5, 1 );
|
||||||
|
pParticle->m_vecVelocity = vec3_origin;
|
||||||
|
Vector color( 1,1,1 );
|
||||||
|
float colorRamp = RandomFloat( 0.75f, 1.25f );
|
||||||
|
pParticle->m_uchColor[0] = min( 1.0f, color[0] * colorRamp ) * 255.0f;
|
||||||
|
pParticle->m_uchColor[1] = min( 1.0f, color[1] * colorRamp ) * 255.0f;
|
||||||
|
pParticle->m_uchColor[2] = min( 1.0f, color[2] * colorRamp ) * 255.0f;
|
||||||
|
pParticle->m_uchStartSize = RandomFloat( 6,13 );
|
||||||
|
pParticle->m_uchEndSize = pParticle->m_uchStartSize - 2;
|
||||||
|
pParticle->m_uchStartAlpha = 255;
|
||||||
|
pParticle->m_uchEndAlpha = 10;
|
||||||
|
pParticle->m_flRoll = RandomFloat( 0,360 );
|
||||||
|
pParticle->m_flRollDelta = 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Build the tesla
|
||||||
|
FX_BuildTesla( pEntity, vecOrigin, tr.endpos );
|
||||||
|
}
|
||||||
|
|
||||||
|
//-----------------------------------------------------------------------------
|
||||||
|
// Sorts the components of a vector
|
||||||
|
//-----------------------------------------------------------------------------
|
||||||
|
static inline void SortAbsVectorComponents( const Vector& src, int* pVecIdx )
|
||||||
|
{
|
||||||
|
Vector absVec( fabs(src[0]), fabs(src[1]), fabs(src[2]) );
|
||||||
|
|
||||||
|
int maxIdx = (absVec[0] > absVec[1]) ? 0 : 1;
|
||||||
|
if (absVec[2] > absVec[maxIdx])
|
||||||
|
{
|
||||||
|
maxIdx = 2;
|
||||||
|
}
|
||||||
|
|
||||||
|
// always choose something right-handed....
|
||||||
|
switch( maxIdx )
|
||||||
|
{
|
||||||
|
case 0:
|
||||||
|
pVecIdx[0] = 1;
|
||||||
|
pVecIdx[1] = 2;
|
||||||
|
pVecIdx[2] = 0;
|
||||||
|
break;
|
||||||
|
case 1:
|
||||||
|
pVecIdx[0] = 2;
|
||||||
|
pVecIdx[1] = 0;
|
||||||
|
pVecIdx[2] = 1;
|
||||||
|
break;
|
||||||
|
case 2:
|
||||||
|
pVecIdx[0] = 0;
|
||||||
|
pVecIdx[1] = 1;
|
||||||
|
pVecIdx[2] = 2;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
//-----------------------------------------------------------------------------
|
||||||
|
// Compute the bounding box's center, size, and basis
|
||||||
|
//-----------------------------------------------------------------------------
|
||||||
|
void C_EntityDissolve::ComputeRenderInfo( mstudiobbox_t *pHitBox, const matrix3x4_t &hitboxToWorld,
|
||||||
|
Vector *pVecAbsOrigin, Vector *pXVec, Vector *pYVec )
|
||||||
|
{
|
||||||
|
// Compute the center of the hitbox in worldspace
|
||||||
|
Vector vecHitboxCenter;
|
||||||
|
VectorAdd( pHitBox->bbmin, pHitBox->bbmax, vecHitboxCenter );
|
||||||
|
vecHitboxCenter *= 0.5f;
|
||||||
|
VectorTransform( vecHitboxCenter, hitboxToWorld, *pVecAbsOrigin );
|
||||||
|
|
||||||
|
// Get the object's basis
|
||||||
|
Vector vec[3];
|
||||||
|
MatrixGetColumn( hitboxToWorld, 0, vec[0] );
|
||||||
|
MatrixGetColumn( hitboxToWorld, 1, vec[1] );
|
||||||
|
MatrixGetColumn( hitboxToWorld, 2, vec[2] );
|
||||||
|
// vec[1] *= -1.0f;
|
||||||
|
|
||||||
|
Vector vecViewDir;
|
||||||
|
VectorSubtract( CurrentViewOrigin(), *pVecAbsOrigin, vecViewDir );
|
||||||
|
VectorNormalize( vecViewDir );
|
||||||
|
|
||||||
|
// Project the shadow casting direction into the space of the hitbox
|
||||||
|
Vector localViewDir;
|
||||||
|
localViewDir[0] = DotProduct( vec[0], vecViewDir );
|
||||||
|
localViewDir[1] = DotProduct( vec[1], vecViewDir );
|
||||||
|
localViewDir[2] = DotProduct( vec[2], vecViewDir );
|
||||||
|
|
||||||
|
// Figure out which vector has the largest component perpendicular
|
||||||
|
// to the view direction...
|
||||||
|
// Sort by how perpendicular it is
|
||||||
|
int vecIdx[3];
|
||||||
|
SortAbsVectorComponents( localViewDir, vecIdx );
|
||||||
|
|
||||||
|
// Here's our hitbox basis vectors; namely the ones that are
|
||||||
|
// most perpendicular to the view direction
|
||||||
|
*pXVec = vec[vecIdx[0]];
|
||||||
|
*pYVec = vec[vecIdx[1]];
|
||||||
|
|
||||||
|
// Project them into a plane perpendicular to the view direction
|
||||||
|
*pXVec -= vecViewDir * DotProduct( vecViewDir, *pXVec );
|
||||||
|
*pYVec -= vecViewDir * DotProduct( vecViewDir, *pYVec );
|
||||||
|
VectorNormalize( *pXVec );
|
||||||
|
VectorNormalize( *pYVec );
|
||||||
|
|
||||||
|
// Compute the hitbox size
|
||||||
|
Vector boxSize;
|
||||||
|
VectorSubtract( pHitBox->bbmax, pHitBox->bbmin, boxSize );
|
||||||
|
|
||||||
|
// We project the two longest sides into the vectors perpendicular
|
||||||
|
// to the projection direction, then add in the projection of the perp direction
|
||||||
|
Vector2D size( boxSize[vecIdx[0]], boxSize[vecIdx[1]] );
|
||||||
|
size.x *= fabs( DotProduct( vec[vecIdx[0]], *pXVec ) );
|
||||||
|
size.y *= fabs( DotProduct( vec[vecIdx[1]], *pYVec ) );
|
||||||
|
|
||||||
|
// Add the third component into x and y
|
||||||
|
size.x += boxSize[vecIdx[2]] * fabs( DotProduct( vec[vecIdx[2]], *pXVec ) );
|
||||||
|
size.y += boxSize[vecIdx[2]] * fabs( DotProduct( vec[vecIdx[2]], *pYVec ) );
|
||||||
|
|
||||||
|
// Bloat a bit, since the shadow wants to extend outside the model a bit
|
||||||
|
size *= 2.0f;
|
||||||
|
|
||||||
|
// Clamp the minimum size
|
||||||
|
Vector2DMax( size, Vector2D(10.0f, 10.0f), size );
|
||||||
|
|
||||||
|
// Factor the size into the xvec + yvec
|
||||||
|
(*pXVec) *= size.x * 0.5f;
|
||||||
|
(*pYVec) *= size.y * 0.5f;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
//-----------------------------------------------------------------------------
|
||||||
|
// Sparks!
|
||||||
|
//-----------------------------------------------------------------------------
|
||||||
|
void C_EntityDissolve::DoSparks( mstudiohitboxset_t *set, matrix3x4_t *hitboxbones[MAXSTUDIOBONES] )
|
||||||
|
{
|
||||||
|
if ( m_flNextSparkTime > gpGlobals->curtime )
|
||||||
|
return;
|
||||||
|
|
||||||
|
float dt = m_flStartTime + m_flFadeOutStart - gpGlobals->curtime;
|
||||||
|
dt = clamp( dt, 0.0f, m_flFadeOutStart );
|
||||||
|
|
||||||
|
float flNextTime;
|
||||||
|
if (m_nDissolveType == ENTITY_DISSOLVE_ELECTRICAL)
|
||||||
|
{
|
||||||
|
flNextTime = SimpleSplineRemapVal( dt, 0.0f, m_flFadeOutStart, 2.0f * TICK_INTERVAL, 0.4f );
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
// m_nDissolveType == ENTITY_DISSOLVE_ELECTRICAL_LIGHT);
|
||||||
|
flNextTime = SimpleSplineRemapVal( dt, 0.0f, m_flFadeOutStart, 0.3f, 1.0f );
|
||||||
|
}
|
||||||
|
|
||||||
|
m_flNextSparkTime = gpGlobals->curtime + flNextTime;
|
||||||
|
|
||||||
|
// Send out beams around us
|
||||||
|
int iNumBeamsAround = 2;
|
||||||
|
int iNumRandomBeams = 1;
|
||||||
|
int iTotalBeams = iNumBeamsAround + iNumRandomBeams;
|
||||||
|
float flYawOffset = RandomFloat(0,360);
|
||||||
|
for ( int i = 0; i < iTotalBeams; i++ )
|
||||||
|
{
|
||||||
|
int nHitbox = random->RandomInt( 0, set->numhitboxes - 1 );
|
||||||
|
mstudiobbox_t *pBox = set->pHitbox(nHitbox);
|
||||||
|
|
||||||
|
float flActualYawOffset = 0;
|
||||||
|
bool bRandom = ( i >= iNumBeamsAround );
|
||||||
|
if ( !bRandom )
|
||||||
|
{
|
||||||
|
flActualYawOffset = anglemod( flYawOffset + ((360 / iTotalBeams) * i) );
|
||||||
|
}
|
||||||
|
|
||||||
|
BuildTeslaEffect( pBox, *hitboxbones[pBox->bone], bRandom, flActualYawOffset );
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
//-----------------------------------------------------------------------------
|
||||||
|
// Purpose:
|
||||||
|
//-----------------------------------------------------------------------------
|
||||||
|
void C_EntityDissolve::SetupEmitter( void )
|
||||||
|
{
|
||||||
|
if ( !m_pEmitter )
|
||||||
|
{
|
||||||
|
m_pEmitter = CSimpleEmitter::Create( "C_EntityDissolve" );
|
||||||
|
m_pEmitter->SetSortOrigin( GetAbsOrigin() );
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
//-----------------------------------------------------------------------------
|
||||||
|
// Purpose:
|
||||||
|
// Output : float
|
||||||
|
//-----------------------------------------------------------------------------
|
||||||
|
float C_EntityDissolve::GetFadeInPercentage( void )
|
||||||
|
{
|
||||||
|
float dt = gpGlobals->curtime - m_flStartTime;
|
||||||
|
|
||||||
|
if ( dt > m_flFadeOutStart )
|
||||||
|
return 1.0f;
|
||||||
|
|
||||||
|
if ( dt < m_flFadeInStart )
|
||||||
|
return 0.0f;
|
||||||
|
|
||||||
|
if ( (dt > m_flFadeInStart) && (dt < m_flFadeInStart + m_flFadeInLength) )
|
||||||
|
{
|
||||||
|
dt -= m_flFadeInStart;
|
||||||
|
|
||||||
|
return ( dt / m_flFadeInLength );
|
||||||
|
}
|
||||||
|
|
||||||
|
return 1.0f;
|
||||||
|
}
|
||||||
|
|
||||||
|
//-----------------------------------------------------------------------------
|
||||||
|
// Purpose:
|
||||||
|
// Output : float
|
||||||
|
//-----------------------------------------------------------------------------
|
||||||
|
float C_EntityDissolve::GetFadeOutPercentage( void )
|
||||||
|
{
|
||||||
|
float dt = gpGlobals->curtime - m_flStartTime;
|
||||||
|
|
||||||
|
if ( dt < m_flFadeInStart )
|
||||||
|
return 1.0f;
|
||||||
|
|
||||||
|
if ( dt > m_flFadeOutStart )
|
||||||
|
{
|
||||||
|
dt -= m_flFadeOutStart;
|
||||||
|
|
||||||
|
if ( dt > m_flFadeOutLength )
|
||||||
|
return 0.0f;
|
||||||
|
|
||||||
|
return 1.0f - ( dt / m_flFadeOutLength );
|
||||||
|
}
|
||||||
|
|
||||||
|
return 1.0f;
|
||||||
|
}
|
||||||
|
|
||||||
|
//-----------------------------------------------------------------------------
|
||||||
|
// Purpose:
|
||||||
|
// Output : float
|
||||||
|
//-----------------------------------------------------------------------------
|
||||||
|
float C_EntityDissolve::GetModelFadeOutPercentage( void )
|
||||||
|
{
|
||||||
|
float dt = gpGlobals->curtime - m_flStartTime;
|
||||||
|
|
||||||
|
if ( dt < m_flFadeOutModelStart )
|
||||||
|
return 1.0f;
|
||||||
|
|
||||||
|
if ( dt > m_flFadeOutModelStart )
|
||||||
|
{
|
||||||
|
dt -= m_flFadeOutModelStart;
|
||||||
|
|
||||||
|
if ( dt > m_flFadeOutModelLength )
|
||||||
|
return 0.0f;
|
||||||
|
|
||||||
|
return 1.0f - ( dt / m_flFadeOutModelLength );
|
||||||
|
}
|
||||||
|
|
||||||
|
return 1.0f;
|
||||||
|
}
|
||||||
|
|
||||||
|
//-----------------------------------------------------------------------------
|
||||||
|
// Purpose:
|
||||||
|
//-----------------------------------------------------------------------------
|
||||||
|
void C_EntityDissolve::ClientThink( void )
|
||||||
|
{
|
||||||
|
C_BaseAnimating *pAnimating = GetMoveParent() ? GetMoveParent()->GetBaseAnimating() : NULL;
|
||||||
|
if (!pAnimating)
|
||||||
|
return;
|
||||||
|
|
||||||
|
// NOTE: IsRagdoll means *client-side* ragdoll. We shouldn't be trying to fight
|
||||||
|
// the server ragdoll (or any server physics) on the client
|
||||||
|
if (( !m_pController ) && ( m_nDissolveType == ENTITY_DISSOLVE_NORMAL ) && pAnimating->IsRagdoll())
|
||||||
|
{
|
||||||
|
IPhysicsObject *ppList[32];
|
||||||
|
int nCount = pAnimating->VPhysicsGetObjectList( ppList, 32 );
|
||||||
|
if ( nCount > 0 )
|
||||||
|
{
|
||||||
|
m_pController = physenv->CreateMotionController( this );
|
||||||
|
for ( int i = 0; i < nCount; ++i )
|
||||||
|
{
|
||||||
|
m_pController->AttachObject( ppList[i], true );
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
color32 color;
|
||||||
|
|
||||||
|
color.r = color.g = color.b = ( 1.0f - GetFadeInPercentage() ) * 255.0f;
|
||||||
|
color.a = GetModelFadeOutPercentage() * 255.0f;
|
||||||
|
|
||||||
|
// Setup the entity fade
|
||||||
|
pAnimating->SetRenderMode( kRenderTransColor );
|
||||||
|
pAnimating->SetRenderColor( color.r, color.g, color.b, color.a );
|
||||||
|
|
||||||
|
if ( GetModelFadeOutPercentage() <= 0.2f )
|
||||||
|
{
|
||||||
|
m_bCoreExplode = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
// If we're dead, fade out
|
||||||
|
if ( GetFadeOutPercentage() <= 0.0f )
|
||||||
|
{
|
||||||
|
// Do NOT remove from the client entity list. It'll confuse the local network backdoor, and the entity will never get destroyed
|
||||||
|
// because when the server says to destroy it, the client won't be able to find it.
|
||||||
|
// ClientEntityList().RemoveEntity( GetClientHandle() );
|
||||||
|
|
||||||
|
partition->Remove( PARTITION_CLIENT_SOLID_EDICTS | PARTITION_CLIENT_RESPONSIVE_EDICTS | PARTITION_CLIENT_NON_STATIC_EDICTS, CollisionProp()->GetPartitionHandle() );
|
||||||
|
|
||||||
|
RemoveFromLeafSystem();
|
||||||
|
|
||||||
|
//FIXME: Ick!
|
||||||
|
//Adrian: I'll assume we don't need the ragdoll either so I'll remove that too.
|
||||||
|
if ( m_bLinkedToServerEnt == false )
|
||||||
|
{
|
||||||
|
Release();
|
||||||
|
|
||||||
|
C_ClientRagdoll *pRagdoll = dynamic_cast <C_ClientRagdoll *> ( pAnimating );
|
||||||
|
|
||||||
|
if ( pRagdoll )
|
||||||
|
{
|
||||||
|
pRagdoll->ReleaseRagdoll();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
//-----------------------------------------------------------------------------
|
||||||
|
// Purpose:
|
||||||
|
// Input : flags -
|
||||||
|
// Output : int
|
||||||
|
//-----------------------------------------------------------------------------
|
||||||
|
int C_EntityDissolve::DrawModel( int flags )
|
||||||
|
{
|
||||||
|
// See if we should draw
|
||||||
|
if ( gpGlobals->frametime == 0 || m_bReadyToDraw == false )
|
||||||
|
return 0;
|
||||||
|
|
||||||
|
C_BaseAnimating *pAnimating = GetMoveParent() ? GetMoveParent()->GetBaseAnimating() : NULL;
|
||||||
|
if ( pAnimating == NULL )
|
||||||
|
return 0;
|
||||||
|
|
||||||
|
matrix3x4_t *hitboxbones[MAXSTUDIOBONES];
|
||||||
|
if ( pAnimating->HitboxToWorldTransforms( hitboxbones ) == false )
|
||||||
|
return 0;
|
||||||
|
|
||||||
|
studiohdr_t *pStudioHdr = modelinfo->GetStudiomodel( pAnimating->GetModel() );
|
||||||
|
if ( pStudioHdr == NULL )
|
||||||
|
return false;
|
||||||
|
|
||||||
|
mstudiohitboxset_t *set = pStudioHdr->pHitboxSet( pAnimating->GetHitboxSet() );
|
||||||
|
if ( set == NULL )
|
||||||
|
return false;
|
||||||
|
|
||||||
|
// Make sure the emitter is setup properly
|
||||||
|
SetupEmitter();
|
||||||
|
|
||||||
|
// Get fade percentages for the effect
|
||||||
|
float fadeInPerc = GetFadeInPercentage();
|
||||||
|
float fadeOutPerc = GetFadeOutPercentage();
|
||||||
|
|
||||||
|
float fadePerc = ( fadeInPerc >= 1.0f ) ? fadeOutPerc : fadeInPerc;
|
||||||
|
|
||||||
|
Vector vecSkew = vec3_origin;
|
||||||
|
|
||||||
|
// Do extra effects under certain circumstances
|
||||||
|
if ( ( fadePerc < 0.99f ) && ( (m_nDissolveType == ENTITY_DISSOLVE_ELECTRICAL) || (m_nDissolveType == ENTITY_DISSOLVE_ELECTRICAL_LIGHT) ) )
|
||||||
|
{
|
||||||
|
DoSparks( set, hitboxbones );
|
||||||
|
}
|
||||||
|
|
||||||
|
// Skew the particles in front or in back of their targets
|
||||||
|
vecSkew = CurrentViewForward() * ( 8.0f - ( ( 1.0f - fadePerc ) * 32.0f ) );
|
||||||
|
|
||||||
|
float spriteScale = ( ( gpGlobals->curtime - m_flStartTime ) / m_flFadeOutLength );
|
||||||
|
spriteScale = clamp( spriteScale, 0.75f, 1.0f );
|
||||||
|
|
||||||
|
// Cache off this material reference
|
||||||
|
if ( g_Material_Spark == NULL )
|
||||||
|
{
|
||||||
|
g_Material_Spark = ParticleMgr()->GetPMaterial( "effects/spark" );
|
||||||
|
}
|
||||||
|
|
||||||
|
if ( g_Material_AR2Glow == NULL )
|
||||||
|
{
|
||||||
|
g_Material_AR2Glow = ParticleMgr()->GetPMaterial( "effects/combinemuzzle2" );
|
||||||
|
}
|
||||||
|
|
||||||
|
SimpleParticle *sParticle;
|
||||||
|
|
||||||
|
for ( int i = 0; i < set->numhitboxes; ++i )
|
||||||
|
{
|
||||||
|
Vector vecAbsOrigin, xvec, yvec;
|
||||||
|
mstudiobbox_t *pBox = set->pHitbox(i);
|
||||||
|
ComputeRenderInfo( pBox, *hitboxbones[pBox->bone], &vecAbsOrigin, &xvec, &yvec );
|
||||||
|
|
||||||
|
Vector offset;
|
||||||
|
Vector xDir, yDir;
|
||||||
|
|
||||||
|
xDir = xvec;
|
||||||
|
float xScale = VectorNormalize( xDir ) * 0.75f;
|
||||||
|
|
||||||
|
yDir = yvec;
|
||||||
|
float yScale = VectorNormalize( yDir ) * 0.75f;
|
||||||
|
|
||||||
|
int numParticles = clamp( 3.0f * fadePerc, 0, 3 );
|
||||||
|
|
||||||
|
int iTempParts = 2;
|
||||||
|
|
||||||
|
if ( m_nDissolveType == ENTITY_DISSOLVE_CORE )
|
||||||
|
{
|
||||||
|
if ( m_bCoreExplode == true )
|
||||||
|
{
|
||||||
|
numParticles = 15;
|
||||||
|
iTempParts = 20;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
for ( int j = 0; j < iTempParts; j++ )
|
||||||
|
{
|
||||||
|
// Skew the origin
|
||||||
|
offset = xDir * Helper_RandomFloat( -xScale*0.5f, xScale*0.5f ) + yDir * Helper_RandomFloat( -yScale*0.5f, yScale*0.5f );
|
||||||
|
offset += vecSkew;
|
||||||
|
|
||||||
|
if ( random->RandomInt( 0, 2 ) != 0 )
|
||||||
|
continue;
|
||||||
|
|
||||||
|
sParticle = (SimpleParticle *) m_pEmitter->AddParticle( sizeof(SimpleParticle), g_Material_Spark, vecAbsOrigin + offset );
|
||||||
|
|
||||||
|
if ( sParticle == NULL )
|
||||||
|
return 1;
|
||||||
|
|
||||||
|
sParticle->m_vecVelocity = Vector( Helper_RandomFloat( -4.0f, 4.0f ), Helper_RandomFloat( -4.0f, 4.0f ), Helper_RandomFloat( 16.0f, 64.0f ) );
|
||||||
|
|
||||||
|
if ( m_nDissolveType == ENTITY_DISSOLVE_CORE )
|
||||||
|
{
|
||||||
|
if ( m_bCoreExplode == true )
|
||||||
|
{
|
||||||
|
Vector vDirection = (vecAbsOrigin + offset) - m_vDissolverOrigin;
|
||||||
|
VectorNormalize( vDirection );
|
||||||
|
sParticle->m_vecVelocity = vDirection * m_nMagnitude;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if ( sParticle->m_vecVelocity.z > 0 )
|
||||||
|
{
|
||||||
|
sParticle->m_uchStartSize = random->RandomFloat( 4, 6 ) * spriteScale;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
sParticle->m_uchStartSize = 2 * spriteScale;
|
||||||
|
}
|
||||||
|
|
||||||
|
sParticle->m_flDieTime = random->RandomFloat( 0.4f, 0.5f );
|
||||||
|
|
||||||
|
// If we're the last particles, last longer
|
||||||
|
if ( numParticles == 0 )
|
||||||
|
{
|
||||||
|
sParticle->m_flDieTime *= 2.0f;
|
||||||
|
sParticle->m_uchStartSize = 2 * spriteScale;
|
||||||
|
sParticle->m_flRollDelta = Helper_RandomFloat( -4.0f, 4.0f );
|
||||||
|
|
||||||
|
if ( m_nDissolveType == ENTITY_DISSOLVE_CORE )
|
||||||
|
{
|
||||||
|
if ( m_bCoreExplode == true )
|
||||||
|
{
|
||||||
|
sParticle->m_flDieTime *= 2.0f;
|
||||||
|
sParticle->m_flRollDelta = Helper_RandomFloat( -1.0f, 1.0f );
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
sParticle->m_flRollDelta = Helper_RandomFloat( -8.0f, 8.0f );
|
||||||
|
}
|
||||||
|
|
||||||
|
sParticle->m_flLifetime = 0.0f;
|
||||||
|
|
||||||
|
sParticle->m_flRoll = Helper_RandomInt( 0, 360 );
|
||||||
|
|
||||||
|
float alpha = 255;
|
||||||
|
|
||||||
|
sParticle->m_uchColor[0] = alpha;
|
||||||
|
sParticle->m_uchColor[1] = alpha;
|
||||||
|
sParticle->m_uchColor[2] = alpha;
|
||||||
|
sParticle->m_uchStartAlpha = alpha;
|
||||||
|
sParticle->m_uchEndAlpha = 0;
|
||||||
|
sParticle->m_uchEndSize = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
for ( int j = 0; j < numParticles; j++ )
|
||||||
|
{
|
||||||
|
offset = xDir * Helper_RandomFloat( -xScale*0.5f, xScale*0.5f ) + yDir * Helper_RandomFloat( -yScale*0.5f, yScale*0.5f );
|
||||||
|
offset += vecSkew;
|
||||||
|
|
||||||
|
sParticle = (SimpleParticle *) m_pEmitter->AddParticle( sizeof(SimpleParticle), g_Material_AR2Glow, vecAbsOrigin + offset );
|
||||||
|
|
||||||
|
if ( sParticle == NULL )
|
||||||
|
return 1;
|
||||||
|
|
||||||
|
sParticle->m_vecVelocity = Vector( Helper_RandomFloat( -4.0f, 4.0f ), Helper_RandomFloat( -4.0f, 4.0f ), Helper_RandomFloat( -64.0f, 128.0f ) );
|
||||||
|
sParticle->m_uchStartSize = random->RandomFloat( 8, 12 ) * spriteScale;
|
||||||
|
sParticle->m_flDieTime = 0.1f;
|
||||||
|
sParticle->m_flLifetime = 0.0f;
|
||||||
|
|
||||||
|
sParticle->m_flRoll = Helper_RandomInt( 0, 360 );
|
||||||
|
sParticle->m_flRollDelta = Helper_RandomFloat( -2.0f, 2.0f );
|
||||||
|
|
||||||
|
float alpha = 255;
|
||||||
|
|
||||||
|
sParticle->m_uchColor[0] = alpha;
|
||||||
|
sParticle->m_uchColor[1] = alpha;
|
||||||
|
sParticle->m_uchColor[2] = alpha;
|
||||||
|
sParticle->m_uchStartAlpha = alpha;
|
||||||
|
sParticle->m_uchEndAlpha = 0;
|
||||||
|
sParticle->m_uchEndSize = 0;
|
||||||
|
|
||||||
|
if ( m_nDissolveType == ENTITY_DISSOLVE_CORE )
|
||||||
|
{
|
||||||
|
if ( m_bCoreExplode == true )
|
||||||
|
{
|
||||||
|
Vector vDirection = (vecAbsOrigin + offset) - m_vDissolverOrigin;
|
||||||
|
|
||||||
|
VectorNormalize( vDirection );
|
||||||
|
|
||||||
|
sParticle->m_vecVelocity = vDirection * m_nMagnitude;
|
||||||
|
|
||||||
|
sParticle->m_flDieTime = 0.5f;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return 1;
|
||||||
|
}
|
77
cl_dll/c_entitydissolve.h
Normal file
77
cl_dll/c_entitydissolve.h
Normal file
@ -0,0 +1,77 @@
|
|||||||
|
//========= Copyright © 1996-2005, Valve Corporation, All rights reserved. ============//
|
||||||
|
//
|
||||||
|
// Purpose:
|
||||||
|
//
|
||||||
|
// $NoKeywords: $
|
||||||
|
//=============================================================================//
|
||||||
|
|
||||||
|
#ifndef C_ENTITY_DISSOLVE_H
|
||||||
|
#define C_ENTITY_DISSOLVE_H
|
||||||
|
|
||||||
|
#include "cbase.h"
|
||||||
|
|
||||||
|
//-----------------------------------------------------------------------------
|
||||||
|
// Entity Dissolve, client-side implementation
|
||||||
|
//-----------------------------------------------------------------------------
|
||||||
|
class C_EntityDissolve : public C_BaseEntity, public IMotionEvent
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
DECLARE_CLIENTCLASS();
|
||||||
|
DECLARE_CLASS( C_EntityDissolve, C_BaseEntity );
|
||||||
|
|
||||||
|
C_EntityDissolve( void );
|
||||||
|
|
||||||
|
// Inherited from C_BaseEntity
|
||||||
|
virtual void GetRenderBounds( Vector& theMins, Vector& theMaxs );
|
||||||
|
virtual int DrawModel( int flags );
|
||||||
|
virtual bool ShouldDraw() { return true; }
|
||||||
|
virtual void OnDataChanged( DataUpdateType_t updateType );
|
||||||
|
virtual void UpdateOnRemove( void );
|
||||||
|
|
||||||
|
// Inherited from IMotionEvent
|
||||||
|
virtual simresult_e Simulate( IPhysicsMotionController *pController, IPhysicsObject *pObject, float deltaTime, Vector &linear, AngularImpulse &angular );
|
||||||
|
|
||||||
|
void SetupEmitter( void );
|
||||||
|
|
||||||
|
void ClientThink( void );
|
||||||
|
|
||||||
|
void SetServerLinkState( bool state ) { m_bLinkedToServerEnt = state; }
|
||||||
|
|
||||||
|
float m_flStartTime;
|
||||||
|
float m_flFadeOutStart;
|
||||||
|
float m_flFadeOutLength;
|
||||||
|
float m_flFadeOutModelStart;
|
||||||
|
float m_flFadeOutModelLength;
|
||||||
|
float m_flFadeInStart;
|
||||||
|
float m_flFadeInLength;
|
||||||
|
int m_nDissolveType;
|
||||||
|
float m_flNextSparkTime;
|
||||||
|
|
||||||
|
Vector m_vDissolverOrigin;
|
||||||
|
int m_nMagnitude;
|
||||||
|
|
||||||
|
bool m_bCoreExplode;
|
||||||
|
|
||||||
|
protected:
|
||||||
|
|
||||||
|
float GetFadeInPercentage( void ); // Fade in amount (entity fading to black)
|
||||||
|
float GetFadeOutPercentage( void ); // Fade out amount (particles fading away)
|
||||||
|
float GetModelFadeOutPercentage( void );// Mode fade out amount
|
||||||
|
|
||||||
|
// Compute the bounding box's center, size, and basis
|
||||||
|
void ComputeRenderInfo( mstudiobbox_t *pHitBox, const matrix3x4_t &hitboxToWorld,
|
||||||
|
Vector *pVecAbsOrigin, Vector *pXVec, Vector *pYVec );
|
||||||
|
void BuildTeslaEffect( mstudiobbox_t *pHitBox, const matrix3x4_t &hitboxToWorld, bool bRandom, float flYawOffset );
|
||||||
|
|
||||||
|
void DoSparks( mstudiohitboxset_t *set, matrix3x4_t *hitboxbones[MAXSTUDIOBONES] );
|
||||||
|
|
||||||
|
private:
|
||||||
|
|
||||||
|
CSmartPtr<CSimpleEmitter> m_pEmitter;
|
||||||
|
|
||||||
|
bool m_bLinkedToServerEnt;
|
||||||
|
IPhysicsMotionController *m_pController;
|
||||||
|
};
|
||||||
|
|
||||||
|
#endif // C_ENTITY_DISSOLVE_H
|
||||||
|
|
250
cl_dll/c_entityparticletrail.cpp
Normal file
250
cl_dll/c_entityparticletrail.cpp
Normal file
@ -0,0 +1,250 @@
|
|||||||
|
//========= Copyright © 1996-2005, Valve Corporation, All rights reserved. ============//
|
||||||
|
//
|
||||||
|
// Purpose:
|
||||||
|
//
|
||||||
|
// $NoKeywords: $
|
||||||
|
//=============================================================================//
|
||||||
|
|
||||||
|
#include "cbase.h"
|
||||||
|
#include "baseparticleentity.h"
|
||||||
|
#include "entityparticletrail_shared.h"
|
||||||
|
#include "particlemgr.h"
|
||||||
|
#include "particle_util.h"
|
||||||
|
#include "particles_simple.h"
|
||||||
|
|
||||||
|
// memdbgon must be the last include file in a .cpp file!!!
|
||||||
|
#include "tier0/memdbgon.h"
|
||||||
|
|
||||||
|
//-----------------------------------------------------------------------------
|
||||||
|
// Entity particle trail, client-side implementation
|
||||||
|
//-----------------------------------------------------------------------------
|
||||||
|
class C_EntityParticleTrail : public C_BaseParticleEntity
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
DECLARE_CLIENTCLASS();
|
||||||
|
DECLARE_CLASS( C_EntityParticleTrail, C_BaseParticleEntity );
|
||||||
|
|
||||||
|
C_EntityParticleTrail( );
|
||||||
|
~C_EntityParticleTrail( );
|
||||||
|
|
||||||
|
// C_BaseEntity
|
||||||
|
virtual void OnDataChanged( DataUpdateType_t updateType );
|
||||||
|
|
||||||
|
// IParticleEffect
|
||||||
|
void Update( float fTimeDelta );
|
||||||
|
virtual void RenderParticles( CParticleRenderIterator *pIterator );
|
||||||
|
virtual void SimulateParticles( CParticleSimulateIterator *pIterator );
|
||||||
|
|
||||||
|
private:
|
||||||
|
|
||||||
|
C_EntityParticleTrail( const C_EntityParticleTrail & ); // not defined, not accessible
|
||||||
|
|
||||||
|
void Start( );
|
||||||
|
void AddParticle( float flInitialDeltaTime, const Vector &vecMins, const Vector &vecMaxs, const matrix3x4_t &boxToWorld );
|
||||||
|
|
||||||
|
int m_iMaterialName;
|
||||||
|
EntityParticleTrailInfo_t m_Info;
|
||||||
|
EHANDLE m_hConstraintEntity;
|
||||||
|
|
||||||
|
PMaterialHandle m_hMaterial;
|
||||||
|
TimedEvent m_teParticleSpawn;
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
//-----------------------------------------------------------------------------
|
||||||
|
// Networking
|
||||||
|
//-----------------------------------------------------------------------------
|
||||||
|
IMPLEMENT_CLIENTCLASS_DT( C_EntityParticleTrail, DT_EntityParticleTrail, CEntityParticleTrail )
|
||||||
|
RecvPropInt(RECVINFO(m_iMaterialName)),
|
||||||
|
RecvPropDataTable( RECVINFO_DT( m_Info ), 0, &REFERENCE_RECV_TABLE(DT_EntityParticleTrailInfo) ),
|
||||||
|
RecvPropEHandle(RECVINFO(m_hConstraintEntity)),
|
||||||
|
END_RECV_TABLE()
|
||||||
|
|
||||||
|
|
||||||
|
//-----------------------------------------------------------------------------
|
||||||
|
// Purpose:
|
||||||
|
//-----------------------------------------------------------------------------
|
||||||
|
C_EntityParticleTrail::C_EntityParticleTrail( void )
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
C_EntityParticleTrail::~C_EntityParticleTrail()
|
||||||
|
{
|
||||||
|
ParticleMgr()->RemoveEffect( &m_ParticleEffect );
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
//-----------------------------------------------------------------------------
|
||||||
|
// On data changed
|
||||||
|
//-----------------------------------------------------------------------------
|
||||||
|
void C_EntityParticleTrail::OnDataChanged( DataUpdateType_t updateType )
|
||||||
|
{
|
||||||
|
BaseClass::OnDataChanged( updateType );
|
||||||
|
if ( updateType == DATA_UPDATE_CREATED )
|
||||||
|
{
|
||||||
|
Start( );
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
//-----------------------------------------------------------------------------
|
||||||
|
// Purpose:
|
||||||
|
// Input : *pParticleMgr -
|
||||||
|
// *pArgs -
|
||||||
|
//-----------------------------------------------------------------------------
|
||||||
|
void C_EntityParticleTrail::Start( )
|
||||||
|
{
|
||||||
|
if( ParticleMgr()->AddEffect( &m_ParticleEffect, this ) == false )
|
||||||
|
return;
|
||||||
|
|
||||||
|
const char *pMaterialName = GetMaterialNameFromIndex( m_iMaterialName );
|
||||||
|
if ( !pMaterialName )
|
||||||
|
return;
|
||||||
|
|
||||||
|
m_hMaterial = ParticleMgr()->GetPMaterial( pMaterialName );
|
||||||
|
m_teParticleSpawn.Init( 150 );
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
//-----------------------------------------------------------------------------
|
||||||
|
// Purpose:
|
||||||
|
//-----------------------------------------------------------------------------
|
||||||
|
void C_EntityParticleTrail::AddParticle( float flInitialDeltaTime, const Vector &vecMins, const Vector &vecMaxs, const matrix3x4_t &boxToWorld )
|
||||||
|
{
|
||||||
|
// Select a random point somewhere in the hitboxes of the entity.
|
||||||
|
Vector vecLocalPosition, vecWorldPosition;
|
||||||
|
vecLocalPosition.x = Lerp( random->RandomFloat( 0.0f, 1.0f ), vecMins.x, vecMaxs.x );
|
||||||
|
vecLocalPosition.y = Lerp( random->RandomFloat( 0.0f, 1.0f ), vecMins.y, vecMaxs.y );
|
||||||
|
vecLocalPosition.z = Lerp( random->RandomFloat( 0.0f, 1.0f ), vecMins.z, vecMaxs.z );
|
||||||
|
VectorTransform( vecLocalPosition, boxToWorld, vecWorldPosition );
|
||||||
|
|
||||||
|
// Don't emit the particle unless it's inside the model
|
||||||
|
if ( m_hConstraintEntity.Get() )
|
||||||
|
{
|
||||||
|
Ray_t ray;
|
||||||
|
trace_t tr;
|
||||||
|
ray.Init( vecWorldPosition, vecWorldPosition );
|
||||||
|
enginetrace->ClipRayToEntity( ray, MASK_ALL, m_hConstraintEntity, &tr );
|
||||||
|
|
||||||
|
if ( !tr.startsolid )
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Make a new particle
|
||||||
|
SimpleParticle *pParticle = (SimpleParticle *)m_ParticleEffect.AddParticle( sizeof(SimpleParticle), m_hMaterial );
|
||||||
|
if ( pParticle == NULL )
|
||||||
|
return;
|
||||||
|
|
||||||
|
pParticle->m_Pos = vecWorldPosition;
|
||||||
|
pParticle->m_flRoll = Helper_RandomInt( 0, 360 );
|
||||||
|
pParticle->m_flRollDelta = Helper_RandomFloat( -2.0f, 2.0f );
|
||||||
|
|
||||||
|
pParticle->m_flLifetime = flInitialDeltaTime;
|
||||||
|
pParticle->m_flDieTime = m_Info.m_flLifetime;
|
||||||
|
|
||||||
|
pParticle->m_uchColor[0] = 64;
|
||||||
|
pParticle->m_uchColor[1] = 140;
|
||||||
|
pParticle->m_uchColor[2] = 225;
|
||||||
|
pParticle->m_uchStartAlpha = Helper_RandomInt( 64, 64 );
|
||||||
|
pParticle->m_uchEndAlpha = 0;
|
||||||
|
|
||||||
|
pParticle->m_uchStartSize = m_Info.m_flStartSize;
|
||||||
|
pParticle->m_uchEndSize = m_Info.m_flEndSize;
|
||||||
|
|
||||||
|
pParticle->m_vecVelocity = vec3_origin;
|
||||||
|
VectorMA( pParticle->m_Pos, flInitialDeltaTime, pParticle->m_vecVelocity, pParticle->m_Pos );
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
//-----------------------------------------------------------------------------
|
||||||
|
// Purpose:
|
||||||
|
// Input : fTimeDelta -
|
||||||
|
//-----------------------------------------------------------------------------
|
||||||
|
void C_EntityParticleTrail::Update( float fTimeDelta )
|
||||||
|
{
|
||||||
|
float tempDelta = fTimeDelta;
|
||||||
|
studiohdr_t *pStudioHdr;
|
||||||
|
mstudiohitboxset_t *set;
|
||||||
|
matrix3x4_t *hitboxbones[MAXSTUDIOBONES];
|
||||||
|
|
||||||
|
C_BaseEntity *pMoveParent = GetMoveParent();
|
||||||
|
if ( !pMoveParent )
|
||||||
|
return;
|
||||||
|
|
||||||
|
C_BaseAnimating *pAnimating = pMoveParent->GetBaseAnimating();
|
||||||
|
if (!pAnimating)
|
||||||
|
goto trailNoHitboxes;
|
||||||
|
|
||||||
|
if ( !pAnimating->HitboxToWorldTransforms( hitboxbones ) )
|
||||||
|
goto trailNoHitboxes;
|
||||||
|
|
||||||
|
pStudioHdr = modelinfo->GetStudiomodel( pAnimating->GetModel() );
|
||||||
|
if (!pStudioHdr)
|
||||||
|
goto trailNoHitboxes;
|
||||||
|
|
||||||
|
set = pStudioHdr->pHitboxSet( pAnimating->GetHitboxSet() );
|
||||||
|
if ( !set )
|
||||||
|
goto trailNoHitboxes;
|
||||||
|
|
||||||
|
//Add new particles
|
||||||
|
while ( m_teParticleSpawn.NextEvent( tempDelta ) )
|
||||||
|
{
|
||||||
|
int nHitbox = random->RandomInt( 0, set->numhitboxes - 1 );
|
||||||
|
mstudiobbox_t *pBox = set->pHitbox(nHitbox);
|
||||||
|
|
||||||
|
AddParticle( tempDelta, pBox->bbmin, pBox->bbmax, *hitboxbones[pBox->bone] );
|
||||||
|
}
|
||||||
|
return;
|
||||||
|
|
||||||
|
trailNoHitboxes:
|
||||||
|
while ( m_teParticleSpawn.NextEvent( tempDelta ) )
|
||||||
|
{
|
||||||
|
AddParticle( tempDelta, pMoveParent->CollisionProp()->OBBMins(), pMoveParent->CollisionProp()->OBBMaxs(), pMoveParent->EntityToWorldTransform() );
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
inline void C_EntityParticleTrail::RenderParticles( CParticleRenderIterator *pIterator )
|
||||||
|
{
|
||||||
|
const SimpleParticle *pParticle = (const SimpleParticle*)pIterator->GetFirst();
|
||||||
|
while ( pParticle )
|
||||||
|
{
|
||||||
|
float t = pParticle->m_flLifetime / pParticle->m_flDieTime;
|
||||||
|
|
||||||
|
// Render
|
||||||
|
Vector tPos;
|
||||||
|
TransformParticle( ParticleMgr()->GetModelView(), pParticle->m_Pos, tPos );
|
||||||
|
float sortKey = tPos.z;
|
||||||
|
|
||||||
|
Vector color = Vector( pParticle->m_uchColor[0] / 255.0f, pParticle->m_uchColor[1] / 255.0f, pParticle->m_uchColor[2] / 255.0f );
|
||||||
|
float alpha = Lerp( t, pParticle->m_uchStartAlpha / 255.0f, pParticle->m_uchEndAlpha / 255.0f );
|
||||||
|
float flSize = Lerp( t, pParticle->m_uchStartSize, pParticle->m_uchEndSize );
|
||||||
|
|
||||||
|
// Render it
|
||||||
|
RenderParticle_ColorSize( pIterator->GetParticleDraw(), tPos, color, alpha, flSize );
|
||||||
|
|
||||||
|
pParticle = (const SimpleParticle*)pIterator->GetNext( sortKey );
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
inline void C_EntityParticleTrail::SimulateParticles( CParticleSimulateIterator *pIterator )
|
||||||
|
{
|
||||||
|
SimpleParticle *pParticle = (SimpleParticle*)pIterator->GetFirst();
|
||||||
|
while ( pParticle )
|
||||||
|
{
|
||||||
|
// Update position
|
||||||
|
float flTimeDelta = pIterator->GetTimeDelta();
|
||||||
|
pParticle->m_Pos += pParticle->m_vecVelocity * flTimeDelta;
|
||||||
|
|
||||||
|
// NOTE: I'm overloading "die time" to be the actual start time.
|
||||||
|
pParticle->m_flLifetime += flTimeDelta;
|
||||||
|
|
||||||
|
if ( pParticle->m_flLifetime >= pParticle->m_flDieTime )
|
||||||
|
pIterator->RemoveParticle( pParticle );
|
||||||
|
|
||||||
|
pParticle = (SimpleParticle*)pIterator->GetNext();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
304
cl_dll/c_env_particlescript.cpp
Normal file
304
cl_dll/c_env_particlescript.cpp
Normal file
@ -0,0 +1,304 @@
|
|||||||
|
//===== Copyright © 1996-2005, Valve Corporation, All rights reserved. ======//
|
||||||
|
//
|
||||||
|
// Purpose:
|
||||||
|
//
|
||||||
|
// $NoKeywords: $
|
||||||
|
//===========================================================================//
|
||||||
|
|
||||||
|
#include "cbase.h"
|
||||||
|
#include "c_baseanimating.h"
|
||||||
|
#include "particlemgr.h"
|
||||||
|
#include "materialsystem/imaterialvar.h"
|
||||||
|
#include "cl_animevent.h"
|
||||||
|
#include "particle_util.h"
|
||||||
|
|
||||||
|
// memdbgon must be the last include file in a .cpp file!!!
|
||||||
|
#include "tier0/memdbgon.h"
|
||||||
|
|
||||||
|
//-----------------------------------------------------------------------------
|
||||||
|
// An entity which emits other entities at points
|
||||||
|
//-----------------------------------------------------------------------------
|
||||||
|
class C_EnvParticleScript : public C_BaseAnimating, public IParticleEffect
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
DECLARE_CLASS( C_EnvParticleScript, C_BaseAnimating );
|
||||||
|
DECLARE_CLIENTCLASS();
|
||||||
|
|
||||||
|
C_EnvParticleScript();
|
||||||
|
|
||||||
|
// IParticleEffect overrides.
|
||||||
|
public:
|
||||||
|
virtual bool ShouldSimulate() const { return m_bSimulate; }
|
||||||
|
virtual void SetShouldSimulate( bool bSim ) { m_bSimulate = bSim; }
|
||||||
|
|
||||||
|
virtual void RenderParticles( CParticleRenderIterator *pIterator );
|
||||||
|
virtual void SimulateParticles( CParticleSimulateIterator *pIterator );
|
||||||
|
|
||||||
|
virtual const Vector &GetSortOrigin();
|
||||||
|
|
||||||
|
// C_BaseAnimating overrides
|
||||||
|
public:
|
||||||
|
// NOTE: Ths enclosed particle effect binding will do all the drawing
|
||||||
|
// But we have to return true, unlike other particle systems, for the animation events to work
|
||||||
|
virtual bool ShouldDraw() { return true; }
|
||||||
|
virtual int DrawModel( int flags ) { return 0; }
|
||||||
|
virtual int GetFxBlend( void ) { return 0; }
|
||||||
|
|
||||||
|
virtual void FireEvent( const Vector& origin, const QAngle& angles, int event, const char *options );
|
||||||
|
virtual void OnPreDataChanged( DataUpdateType_t updateType );
|
||||||
|
virtual void OnDataChanged( DataUpdateType_t updateType );
|
||||||
|
|
||||||
|
private:
|
||||||
|
|
||||||
|
// Creates, destroys particles attached to an attachment
|
||||||
|
void CreateParticle( const char *pAttachmentName, const char *pSpriteName );
|
||||||
|
void DestroyAllParticles( const char *pAttachmentName );
|
||||||
|
void DestroyAllParticles( );
|
||||||
|
|
||||||
|
private:
|
||||||
|
struct ParticleScriptParticle_t : public Particle
|
||||||
|
{
|
||||||
|
int m_nAttachment;
|
||||||
|
float m_flSize;
|
||||||
|
};
|
||||||
|
|
||||||
|
CParticleEffectBinding m_ParticleEffect;
|
||||||
|
float m_flMaxParticleSize;
|
||||||
|
int m_nOldSequence;
|
||||||
|
float m_flSequenceScale;
|
||||||
|
bool m_bSimulate;
|
||||||
|
};
|
||||||
|
|
||||||
|
REGISTER_EFFECT( C_EnvParticleScript );
|
||||||
|
|
||||||
|
//-----------------------------------------------------------------------------
|
||||||
|
// Datatable
|
||||||
|
//-----------------------------------------------------------------------------
|
||||||
|
IMPLEMENT_CLIENTCLASS_DT( C_EnvParticleScript, DT_EnvParticleScript, CEnvParticleScript )
|
||||||
|
RecvPropFloat( RECVINFO(m_flSequenceScale) ),
|
||||||
|
END_RECV_TABLE()
|
||||||
|
|
||||||
|
|
||||||
|
//-----------------------------------------------------------------------------
|
||||||
|
// Constructor
|
||||||
|
//-----------------------------------------------------------------------------
|
||||||
|
C_EnvParticleScript::C_EnvParticleScript()
|
||||||
|
{
|
||||||
|
m_flMaxParticleSize = 0.0f;
|
||||||
|
m_bSimulate = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
//-----------------------------------------------------------------------------
|
||||||
|
// Check for changed sequence numbers
|
||||||
|
//-----------------------------------------------------------------------------
|
||||||
|
void C_EnvParticleScript::OnPreDataChanged( DataUpdateType_t updateType )
|
||||||
|
{
|
||||||
|
BaseClass::OnPreDataChanged( updateType );
|
||||||
|
|
||||||
|
m_nOldSequence = GetSequence();
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
//-----------------------------------------------------------------------------
|
||||||
|
// Starts up the particle system
|
||||||
|
//-----------------------------------------------------------------------------
|
||||||
|
void C_EnvParticleScript::OnDataChanged( DataUpdateType_t updateType )
|
||||||
|
{
|
||||||
|
BaseClass::OnDataChanged( updateType );
|
||||||
|
|
||||||
|
if(updateType == DATA_UPDATE_CREATED)
|
||||||
|
{
|
||||||
|
ParticleMgr()->AddEffect( &m_ParticleEffect, this );
|
||||||
|
}
|
||||||
|
|
||||||
|
if ( m_nOldSequence != GetSequence() )
|
||||||
|
{
|
||||||
|
DestroyAllParticles();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
//-----------------------------------------------------------------------------
|
||||||
|
// Creates, destroys particles attached to an attachment
|
||||||
|
//-----------------------------------------------------------------------------
|
||||||
|
void C_EnvParticleScript::CreateParticle( const char *pAttachmentName, const char *pSpriteName )
|
||||||
|
{
|
||||||
|
// Find the attachment
|
||||||
|
int nAttachment = LookupAttachment( pAttachmentName );
|
||||||
|
if ( nAttachment <= 0 )
|
||||||
|
return;
|
||||||
|
|
||||||
|
// Get the sprite materials
|
||||||
|
PMaterialHandle hMat = m_ParticleEffect.FindOrAddMaterial( pSpriteName );
|
||||||
|
ParticleScriptParticle_t *pParticle =
|
||||||
|
(ParticleScriptParticle_t*)m_ParticleEffect.AddParticle(sizeof(ParticleScriptParticle_t), hMat);
|
||||||
|
|
||||||
|
if ( pParticle == NULL )
|
||||||
|
return;
|
||||||
|
|
||||||
|
// Get the sprite size from the material's materialvars
|
||||||
|
bool bFound = false;
|
||||||
|
IMaterialVar *pMaterialVar = NULL;
|
||||||
|
IMaterial *pMaterial = ParticleMgr()->PMaterialToIMaterial( hMat );
|
||||||
|
if ( pMaterial )
|
||||||
|
{
|
||||||
|
pMaterialVar = pMaterial->FindVar( "$spritesize", &bFound, false );
|
||||||
|
}
|
||||||
|
|
||||||
|
if ( bFound )
|
||||||
|
{
|
||||||
|
pParticle->m_flSize = pMaterialVar->GetFloatValue();
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
pParticle->m_flSize = 100.0f;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Make sure the particle cull size reflects our particles
|
||||||
|
if ( pParticle->m_flSize > m_flMaxParticleSize )
|
||||||
|
{
|
||||||
|
m_flMaxParticleSize = pParticle->m_flSize;
|
||||||
|
m_ParticleEffect.SetParticleCullRadius( m_flMaxParticleSize );
|
||||||
|
}
|
||||||
|
|
||||||
|
// Place the particle on the attachment specified
|
||||||
|
pParticle->m_nAttachment = nAttachment;
|
||||||
|
QAngle vecAngles;
|
||||||
|
GetAttachment( nAttachment, pParticle->m_Pos, vecAngles );
|
||||||
|
|
||||||
|
if ( m_flSequenceScale != 1.0f )
|
||||||
|
{
|
||||||
|
pParticle->m_Pos -= GetAbsOrigin();
|
||||||
|
pParticle->m_Pos *= m_flSequenceScale;
|
||||||
|
pParticle->m_Pos += GetAbsOrigin();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void C_EnvParticleScript::DestroyAllParticles( const char *pAttachmentName )
|
||||||
|
{
|
||||||
|
int nAttachment = LookupAttachment( pAttachmentName );
|
||||||
|
if ( nAttachment <= 0 )
|
||||||
|
return;
|
||||||
|
|
||||||
|
int nCount = m_ParticleEffect.GetNumActiveParticles();
|
||||||
|
Particle** ppParticles = (Particle**)stackalloc( nCount * sizeof(Particle*) );
|
||||||
|
int nActualCount = m_ParticleEffect.GetActiveParticleList( nCount, ppParticles );
|
||||||
|
Assert( nActualCount == nCount );
|
||||||
|
|
||||||
|
for ( int i = 0; i < nActualCount; ++i )
|
||||||
|
{
|
||||||
|
ParticleScriptParticle_t *pParticle = (ParticleScriptParticle_t*)ppParticles[i];
|
||||||
|
if ( pParticle->m_nAttachment == nAttachment )
|
||||||
|
{
|
||||||
|
// Mark for deletion
|
||||||
|
pParticle->m_nAttachment = -1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void C_EnvParticleScript::DestroyAllParticles( )
|
||||||
|
{
|
||||||
|
int nCount = m_ParticleEffect.GetNumActiveParticles();
|
||||||
|
Particle** ppParticles = (Particle**)stackalloc( nCount * sizeof(Particle*) );
|
||||||
|
int nActualCount = m_ParticleEffect.GetActiveParticleList( nCount, ppParticles );
|
||||||
|
Assert( nActualCount == nCount );
|
||||||
|
|
||||||
|
for ( int i = 0; i < nActualCount; ++i )
|
||||||
|
{
|
||||||
|
ParticleScriptParticle_t *pParticle = (ParticleScriptParticle_t*)ppParticles[i];
|
||||||
|
|
||||||
|
// Mark for deletion
|
||||||
|
pParticle->m_nAttachment = -1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
//-----------------------------------------------------------------------------
|
||||||
|
// The animation events will create particles on the attachment points
|
||||||
|
//-----------------------------------------------------------------------------
|
||||||
|
void C_EnvParticleScript::FireEvent( const Vector& origin, const QAngle& angles, int event, const char *options )
|
||||||
|
{
|
||||||
|
// Handle events to create + destroy particles
|
||||||
|
switch( event )
|
||||||
|
{
|
||||||
|
case CL_EVENT_SPRITEGROUP_CREATE:
|
||||||
|
{
|
||||||
|
char pAttachmentName[256];
|
||||||
|
char pSpriteName[256];
|
||||||
|
int nArgs = sscanf( options, "%255s %255s", pAttachmentName, pSpriteName );
|
||||||
|
if ( nArgs == 2 )
|
||||||
|
{
|
||||||
|
CreateParticle( pAttachmentName, pSpriteName );
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return;
|
||||||
|
|
||||||
|
case CL_EVENT_SPRITEGROUP_DESTROY:
|
||||||
|
{
|
||||||
|
char pAttachmentName[256];
|
||||||
|
int nArgs = sscanf( options, "%255s", pAttachmentName );
|
||||||
|
if ( nArgs == 1 )
|
||||||
|
{
|
||||||
|
DestroyAllParticles( pAttachmentName );
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Fall back
|
||||||
|
BaseClass::FireEvent( origin, angles, event, options );
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
//-----------------------------------------------------------------------------
|
||||||
|
// Simulate the particles
|
||||||
|
//-----------------------------------------------------------------------------
|
||||||
|
void C_EnvParticleScript::RenderParticles( CParticleRenderIterator *pIterator )
|
||||||
|
{
|
||||||
|
const ParticleScriptParticle_t* pParticle = (const ParticleScriptParticle_t*)pIterator->GetFirst();
|
||||||
|
while ( pParticle )
|
||||||
|
{
|
||||||
|
Vector vecRenderPos;
|
||||||
|
TransformParticle( ParticleMgr()->GetModelView(), pParticle->m_Pos, vecRenderPos );
|
||||||
|
float sortKey = vecRenderPos.z;
|
||||||
|
|
||||||
|
Vector color( 1, 1, 1 );
|
||||||
|
RenderParticle_ColorSize( pIterator->GetParticleDraw(), vecRenderPos, color, 1.0f, pParticle->m_flSize );
|
||||||
|
|
||||||
|
pParticle = (const ParticleScriptParticle_t*)pIterator->GetNext( sortKey );
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void C_EnvParticleScript::SimulateParticles( CParticleSimulateIterator *pIterator )
|
||||||
|
{
|
||||||
|
ParticleScriptParticle_t* pParticle = (ParticleScriptParticle_t*)pIterator->GetFirst();
|
||||||
|
while ( pParticle )
|
||||||
|
{
|
||||||
|
// Here's how we retire particles
|
||||||
|
if ( pParticle->m_nAttachment == -1 )
|
||||||
|
{
|
||||||
|
pIterator->RemoveParticle( pParticle );
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
// Move the particle to the attachment point
|
||||||
|
QAngle vecAngles;
|
||||||
|
GetAttachment( pParticle->m_nAttachment, pParticle->m_Pos, vecAngles );
|
||||||
|
|
||||||
|
if ( m_flSequenceScale != 1.0f )
|
||||||
|
{
|
||||||
|
pParticle->m_Pos -= GetAbsOrigin();
|
||||||
|
pParticle->m_Pos *= m_flSequenceScale;
|
||||||
|
pParticle->m_Pos += GetAbsOrigin();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
pParticle = (ParticleScriptParticle_t*)pIterator->GetNext();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
const Vector &C_EnvParticleScript::GetSortOrigin()
|
||||||
|
{
|
||||||
|
return GetAbsOrigin();
|
||||||
|
}
|
197
cl_dll/c_env_projectedtexture.cpp
Normal file
197
cl_dll/c_env_projectedtexture.cpp
Normal file
@ -0,0 +1,197 @@
|
|||||||
|
//====== Copyright © 1996-2003, Valve Corporation, All rights reserved. =======
|
||||||
|
//
|
||||||
|
// Purpose:
|
||||||
|
//
|
||||||
|
//=============================================================================
|
||||||
|
|
||||||
|
#include "cbase.h"
|
||||||
|
#include "shareddefs.h"
|
||||||
|
#include "materialsystem/imesh.h"
|
||||||
|
#include "materialsystem/imaterial.h"
|
||||||
|
#include "view.h"
|
||||||
|
#include "iviewrender.h"
|
||||||
|
#include "view_shared.h"
|
||||||
|
#include "texture_group_names.h"
|
||||||
|
#include "vstdlib/icommandline.h"
|
||||||
|
|
||||||
|
// memdbgon must be the last include file in a .cpp file!!!
|
||||||
|
#include "tier0/memdbgon.h"
|
||||||
|
|
||||||
|
//-----------------------------------------------------------------------------
|
||||||
|
// Purpose:
|
||||||
|
//-----------------------------------------------------------------------------
|
||||||
|
class C_EnvProjectedTexture : public C_BaseEntity
|
||||||
|
{
|
||||||
|
DECLARE_CLASS( C_EnvProjectedTexture, C_BaseEntity );
|
||||||
|
public:
|
||||||
|
DECLARE_CLIENTCLASS();
|
||||||
|
|
||||||
|
virtual void OnDataChanged( DataUpdateType_t updateType );
|
||||||
|
void ShutDownLightHandle( void );
|
||||||
|
|
||||||
|
virtual void Simulate();
|
||||||
|
|
||||||
|
void UpdateLight( bool bForceUpdate );
|
||||||
|
|
||||||
|
C_EnvProjectedTexture();
|
||||||
|
~C_EnvProjectedTexture();
|
||||||
|
|
||||||
|
private:
|
||||||
|
|
||||||
|
ClientShadowHandle_t m_LightHandle;
|
||||||
|
|
||||||
|
EHANDLE m_hTargetEntity;
|
||||||
|
|
||||||
|
bool m_bState;
|
||||||
|
float m_flLightFOV;
|
||||||
|
bool m_bEnableShadows;
|
||||||
|
bool m_bLightOnlyTarget;
|
||||||
|
bool m_bLightWorld;
|
||||||
|
bool m_bCameraSpace;
|
||||||
|
color32 m_cLightColor;
|
||||||
|
};
|
||||||
|
|
||||||
|
IMPLEMENT_CLIENTCLASS_DT( C_EnvProjectedTexture, DT_EnvProjectedTexture, CEnvProjectedTexture )
|
||||||
|
RecvPropEHandle( RECVINFO( m_hTargetEntity ) ),
|
||||||
|
RecvPropBool( RECVINFO( m_bState ) ),
|
||||||
|
RecvPropFloat( RECVINFO( m_flLightFOV ) ),
|
||||||
|
RecvPropBool( RECVINFO( m_bEnableShadows ) ),
|
||||||
|
RecvPropBool( RECVINFO( m_bLightOnlyTarget ) ),
|
||||||
|
RecvPropBool( RECVINFO( m_bLightWorld ) ),
|
||||||
|
RecvPropBool( RECVINFO( m_bCameraSpace ) ),
|
||||||
|
RecvPropInt( RECVINFO( m_cLightColor ) ),
|
||||||
|
END_RECV_TABLE()
|
||||||
|
|
||||||
|
C_EnvProjectedTexture::C_EnvProjectedTexture( void )
|
||||||
|
{
|
||||||
|
m_LightHandle = CLIENTSHADOW_INVALID_HANDLE;
|
||||||
|
}
|
||||||
|
|
||||||
|
C_EnvProjectedTexture::~C_EnvProjectedTexture( void )
|
||||||
|
{
|
||||||
|
ShutDownLightHandle();
|
||||||
|
}
|
||||||
|
|
||||||
|
void C_EnvProjectedTexture::ShutDownLightHandle( void )
|
||||||
|
{
|
||||||
|
// Clear out the light
|
||||||
|
if( m_LightHandle != CLIENTSHADOW_INVALID_HANDLE )
|
||||||
|
{
|
||||||
|
g_pClientShadowMgr->DestroyFlashlight( m_LightHandle );
|
||||||
|
m_LightHandle = CLIENTSHADOW_INVALID_HANDLE;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
//-----------------------------------------------------------------------------
|
||||||
|
// Purpose:
|
||||||
|
// Input : updateType -
|
||||||
|
//-----------------------------------------------------------------------------
|
||||||
|
void C_EnvProjectedTexture::OnDataChanged( DataUpdateType_t updateType )
|
||||||
|
{
|
||||||
|
UpdateLight( true );
|
||||||
|
BaseClass::OnDataChanged( updateType );
|
||||||
|
}
|
||||||
|
|
||||||
|
void C_EnvProjectedTexture::UpdateLight( bool bForceUpdate )
|
||||||
|
{
|
||||||
|
if ( m_bState == false )
|
||||||
|
{
|
||||||
|
if ( m_LightHandle != CLIENTSHADOW_INVALID_HANDLE )
|
||||||
|
{
|
||||||
|
ShutDownLightHandle();
|
||||||
|
}
|
||||||
|
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
Vector vPos = GetAbsOrigin();
|
||||||
|
Vector vForward;
|
||||||
|
FlashlightState_t state;
|
||||||
|
|
||||||
|
if ( m_hTargetEntity != NULL )
|
||||||
|
{
|
||||||
|
if ( m_bCameraSpace )
|
||||||
|
{
|
||||||
|
const QAngle &angles = GetLocalAngles();
|
||||||
|
|
||||||
|
C_BasePlayer *pPlayer = C_BasePlayer::GetLocalPlayer();
|
||||||
|
if( pPlayer )
|
||||||
|
{
|
||||||
|
const QAngle playerAngles = pPlayer->GetAbsAngles();
|
||||||
|
|
||||||
|
Vector vPlayerForward;
|
||||||
|
AngleVectors( playerAngles, &vPlayerForward );
|
||||||
|
|
||||||
|
matrix3x4_t mRotMatrix;
|
||||||
|
AngleMatrix( angles, mRotMatrix );
|
||||||
|
|
||||||
|
VectorTransform( vPlayerForward, mRotMatrix, vForward );
|
||||||
|
|
||||||
|
float dist = (m_hTargetEntity->GetAbsOrigin() - GetAbsOrigin()).Length();
|
||||||
|
vPos = m_hTargetEntity->GetAbsOrigin() - vForward*dist;
|
||||||
|
|
||||||
|
VectorNormalize( vForward );
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
vForward = m_hTargetEntity->GetAbsOrigin() - GetAbsOrigin();
|
||||||
|
VectorNormalize( vForward );
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
AngleVectors( GetAbsAngles(), &vForward );
|
||||||
|
}
|
||||||
|
|
||||||
|
state.m_fHorizontalFOVDegrees = m_flLightFOV;
|
||||||
|
state.m_fVerticalFOVDegrees = m_flLightFOV;
|
||||||
|
|
||||||
|
state.m_vecLightOrigin = vPos;
|
||||||
|
state.m_vecLightDirection = vForward;
|
||||||
|
|
||||||
|
state.m_fQuadraticAtten = 0.0;
|
||||||
|
state.m_fLinearAtten = 100;
|
||||||
|
state.m_fConstantAtten = 0.0f;
|
||||||
|
state.m_Color.Init( (float)m_cLightColor.r/255.0f, (float)m_cLightColor.g/255.0f, (float)m_cLightColor.b/255.0f );
|
||||||
|
state.m_NearZ = 1.0f;
|
||||||
|
state.m_FarZ = 750;
|
||||||
|
|
||||||
|
state.m_bEnableShadows = m_bEnableShadows;
|
||||||
|
|
||||||
|
if( m_LightHandle == CLIENTSHADOW_INVALID_HANDLE )
|
||||||
|
{
|
||||||
|
m_LightHandle = g_pClientShadowMgr->CreateFlashlight( state );
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
if ( m_hTargetEntity != NULL || bForceUpdate == true )
|
||||||
|
{
|
||||||
|
g_pClientShadowMgr->UpdateFlashlightState( m_LightHandle, state );
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if( m_bLightOnlyTarget )
|
||||||
|
{
|
||||||
|
g_pClientShadowMgr->SetFlashlightTarget( m_LightHandle, m_hTargetEntity );
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
g_pClientShadowMgr->SetFlashlightTarget( m_LightHandle, NULL );
|
||||||
|
}
|
||||||
|
|
||||||
|
g_pClientShadowMgr->SetFlashlightLightWorld( m_LightHandle, m_bLightWorld );
|
||||||
|
|
||||||
|
if ( bForceUpdate == false )
|
||||||
|
{
|
||||||
|
g_pClientShadowMgr->UpdateProjectedTexture( m_LightHandle, true );
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void C_EnvProjectedTexture::Simulate( void )
|
||||||
|
{
|
||||||
|
UpdateLight( false );
|
||||||
|
|
||||||
|
BaseClass::Simulate();
|
||||||
|
}
|
||||||
|
|
297
cl_dll/c_env_screenoverlay.cpp
Normal file
297
cl_dll/c_env_screenoverlay.cpp
Normal file
@ -0,0 +1,297 @@
|
|||||||
|
//========= Copyright © 1996-2005, Valve Corporation, All rights reserved. ============//
|
||||||
|
//
|
||||||
|
// Purpose:
|
||||||
|
//
|
||||||
|
//=============================================================================//
|
||||||
|
|
||||||
|
#include "cbase.h"
|
||||||
|
#include "shareddefs.h"
|
||||||
|
#include "materialsystem/imesh.h"
|
||||||
|
#include "materialsystem/imaterial.h"
|
||||||
|
#include "view.h"
|
||||||
|
#include "iviewrender.h"
|
||||||
|
#include "view_shared.h"
|
||||||
|
#include "texture_group_names.h"
|
||||||
|
#include "vstdlib/icommandline.h"
|
||||||
|
#include "keyvalues.h"
|
||||||
|
#include "ScreenSpaceEffects.h"
|
||||||
|
#include "materialsystem/imaterialsystemhardwareconfig.h"
|
||||||
|
|
||||||
|
// memdbgon must be the last include file in a .cpp file!!!
|
||||||
|
#include "tier0/memdbgon.h"
|
||||||
|
|
||||||
|
//-----------------------------------------------------------------------------
|
||||||
|
// Purpose:
|
||||||
|
//-----------------------------------------------------------------------------
|
||||||
|
class C_EnvScreenOverlay : public C_BaseEntity
|
||||||
|
{
|
||||||
|
DECLARE_CLASS( C_EnvScreenOverlay, C_BaseEntity );
|
||||||
|
public:
|
||||||
|
DECLARE_CLIENTCLASS();
|
||||||
|
|
||||||
|
void PreDataUpdate( DataUpdateType_t updateType );
|
||||||
|
void PostDataUpdate( DataUpdateType_t updateType );
|
||||||
|
|
||||||
|
void HandleOverlaySwitch( void );
|
||||||
|
void StartOverlays( void );
|
||||||
|
void StopOverlays( void );
|
||||||
|
void StartCurrentOverlay( void );
|
||||||
|
void ClientThink( void );
|
||||||
|
|
||||||
|
protected:
|
||||||
|
char m_iszOverlayNames[ MAX_SCREEN_OVERLAYS ][255];
|
||||||
|
float m_flOverlayTimes[ MAX_SCREEN_OVERLAYS ];
|
||||||
|
float m_flStartTime;
|
||||||
|
int m_iDesiredOverlay;
|
||||||
|
bool m_bIsActive;
|
||||||
|
bool m_bWasActive;
|
||||||
|
int m_iCachedDesiredOverlay;
|
||||||
|
int m_iCurrentOverlay;
|
||||||
|
float m_flCurrentOverlayTime;
|
||||||
|
};
|
||||||
|
|
||||||
|
IMPLEMENT_CLIENTCLASS_DT( C_EnvScreenOverlay, DT_EnvScreenOverlay, CEnvScreenOverlay )
|
||||||
|
RecvPropArray( RecvPropString( RECVINFO( m_iszOverlayNames[0]) ), m_iszOverlayNames ),
|
||||||
|
RecvPropArray( RecvPropFloat( RECVINFO( m_flOverlayTimes[0] ) ), m_flOverlayTimes ),
|
||||||
|
RecvPropFloat( RECVINFO( m_flStartTime ) ),
|
||||||
|
RecvPropInt( RECVINFO( m_iDesiredOverlay ) ),
|
||||||
|
RecvPropBool( RECVINFO( m_bIsActive ) ),
|
||||||
|
END_RECV_TABLE()
|
||||||
|
|
||||||
|
//-----------------------------------------------------------------------------
|
||||||
|
// Purpose:
|
||||||
|
// Input : updateType -
|
||||||
|
//-----------------------------------------------------------------------------
|
||||||
|
void C_EnvScreenOverlay::PreDataUpdate( DataUpdateType_t updateType )
|
||||||
|
{
|
||||||
|
BaseClass::PreDataUpdate( updateType );
|
||||||
|
|
||||||
|
m_bWasActive = m_bIsActive;
|
||||||
|
}
|
||||||
|
|
||||||
|
//-----------------------------------------------------------------------------
|
||||||
|
// Purpose:
|
||||||
|
//-----------------------------------------------------------------------------
|
||||||
|
void C_EnvScreenOverlay::PostDataUpdate( DataUpdateType_t updateType )
|
||||||
|
{
|
||||||
|
BaseClass::PostDataUpdate( updateType );
|
||||||
|
|
||||||
|
// If we have a start time now, start the overlays going
|
||||||
|
if ( m_bIsActive && m_flStartTime > 0 && view->GetScreenOverlayMaterial() == NULL )
|
||||||
|
{
|
||||||
|
StartOverlays();
|
||||||
|
}
|
||||||
|
|
||||||
|
if ( m_flStartTime == -1 )
|
||||||
|
{
|
||||||
|
StopOverlays();
|
||||||
|
}
|
||||||
|
|
||||||
|
HandleOverlaySwitch();
|
||||||
|
|
||||||
|
if ( updateType == DATA_UPDATE_CREATED &&
|
||||||
|
CommandLine()->FindParm( "-makereslists" ) )
|
||||||
|
{
|
||||||
|
for ( int i = 0; i < MAX_SCREEN_OVERLAYS; ++i )
|
||||||
|
{
|
||||||
|
if ( m_iszOverlayNames[ i ] && m_iszOverlayNames[ i ][ 0 ] )
|
||||||
|
{
|
||||||
|
materials->FindMaterial( m_iszOverlayNames[ i ], TEXTURE_GROUP_CLIENT_EFFECTS, false );
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
//-----------------------------------------------------------------------------
|
||||||
|
// Purpose:
|
||||||
|
//-----------------------------------------------------------------------------
|
||||||
|
void C_EnvScreenOverlay::StopOverlays( void )
|
||||||
|
{
|
||||||
|
SetNextClientThink( CLIENT_THINK_NEVER );
|
||||||
|
|
||||||
|
if ( m_bWasActive && !m_bIsActive )
|
||||||
|
{
|
||||||
|
view->SetScreenOverlayMaterial( NULL );
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
//-----------------------------------------------------------------------------
|
||||||
|
// Purpose:
|
||||||
|
//-----------------------------------------------------------------------------
|
||||||
|
void C_EnvScreenOverlay::StartOverlays( void )
|
||||||
|
{
|
||||||
|
m_iCurrentOverlay = 0;
|
||||||
|
m_flCurrentOverlayTime = 0;
|
||||||
|
m_iCachedDesiredOverlay = 0;
|
||||||
|
SetNextClientThink( CLIENT_THINK_ALWAYS );
|
||||||
|
|
||||||
|
StartCurrentOverlay();
|
||||||
|
HandleOverlaySwitch();
|
||||||
|
}
|
||||||
|
|
||||||
|
//-----------------------------------------------------------------------------
|
||||||
|
// Purpose:
|
||||||
|
//-----------------------------------------------------------------------------
|
||||||
|
void C_EnvScreenOverlay::HandleOverlaySwitch( void )
|
||||||
|
{
|
||||||
|
if( m_iCachedDesiredOverlay != m_iDesiredOverlay )
|
||||||
|
{
|
||||||
|
m_iCurrentOverlay = m_iDesiredOverlay;
|
||||||
|
m_iCachedDesiredOverlay = m_iDesiredOverlay;
|
||||||
|
StartCurrentOverlay();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
//-----------------------------------------------------------------------------
|
||||||
|
// Purpose:
|
||||||
|
//-----------------------------------------------------------------------------
|
||||||
|
void C_EnvScreenOverlay::StartCurrentOverlay( void )
|
||||||
|
{
|
||||||
|
if ( m_iCurrentOverlay == MAX_SCREEN_OVERLAYS || !m_iszOverlayNames[m_iCurrentOverlay] || !m_iszOverlayNames[m_iCurrentOverlay][0] )
|
||||||
|
{
|
||||||
|
// Hit the end of our overlays, so stop.
|
||||||
|
m_flStartTime = 0;
|
||||||
|
StopOverlays();
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if ( m_flOverlayTimes[m_iCurrentOverlay] == -1 )
|
||||||
|
m_flCurrentOverlayTime = -1;
|
||||||
|
else
|
||||||
|
m_flCurrentOverlayTime = gpGlobals->curtime + m_flOverlayTimes[m_iCurrentOverlay];
|
||||||
|
|
||||||
|
// Bring up the current overlay
|
||||||
|
IMaterial *pMaterial = materials->FindMaterial( m_iszOverlayNames[m_iCurrentOverlay], TEXTURE_GROUP_CLIENT_EFFECTS, false );
|
||||||
|
if ( !IsErrorMaterial( pMaterial ) )
|
||||||
|
{
|
||||||
|
view->SetScreenOverlayMaterial( pMaterial );
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
Warning("env_screenoverlay couldn't find overlay %s.\n", m_iszOverlayNames[m_iCurrentOverlay] );
|
||||||
|
StopOverlays();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
//-----------------------------------------------------------------------------
|
||||||
|
// Purpose:
|
||||||
|
//-----------------------------------------------------------------------------
|
||||||
|
void C_EnvScreenOverlay::ClientThink( void )
|
||||||
|
{
|
||||||
|
// If the current overlay's run out, go to the next one
|
||||||
|
if ( m_flCurrentOverlayTime != -1 && m_flCurrentOverlayTime < gpGlobals->curtime )
|
||||||
|
{
|
||||||
|
m_iCurrentOverlay++;
|
||||||
|
StartCurrentOverlay();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Effect types
|
||||||
|
enum
|
||||||
|
{
|
||||||
|
SCREENEFFECT_EP2_ADVISOR_STUN,
|
||||||
|
SCREENEFFECT_EP1_INTRO,
|
||||||
|
};
|
||||||
|
|
||||||
|
// ============================================================================
|
||||||
|
// Screenspace effect
|
||||||
|
// ============================================================================
|
||||||
|
|
||||||
|
class C_EnvScreenEffect : public C_BaseEntity
|
||||||
|
{
|
||||||
|
DECLARE_CLASS( C_EnvScreenEffect, C_BaseEntity );
|
||||||
|
public:
|
||||||
|
DECLARE_CLIENTCLASS();
|
||||||
|
|
||||||
|
virtual void ReceiveMessage( int classID, bf_read &msg );
|
||||||
|
|
||||||
|
private:
|
||||||
|
float m_flDuration;
|
||||||
|
int m_nType;
|
||||||
|
};
|
||||||
|
|
||||||
|
IMPLEMENT_CLIENTCLASS_DT( C_EnvScreenEffect, DT_EnvScreenEffect, CEnvScreenEffect )
|
||||||
|
RecvPropFloat( RECVINFO( m_flDuration ) ),
|
||||||
|
RecvPropInt( RECVINFO( m_nType ) ),
|
||||||
|
END_RECV_TABLE()
|
||||||
|
|
||||||
|
//-----------------------------------------------------------------------------
|
||||||
|
// Purpose:
|
||||||
|
// Input : classID -
|
||||||
|
// &msg -
|
||||||
|
//-----------------------------------------------------------------------------
|
||||||
|
void C_EnvScreenEffect::ReceiveMessage( int classID, bf_read &msg )
|
||||||
|
{
|
||||||
|
// Make sure our IDs match
|
||||||
|
if ( classID != GetClientClass()->m_ClassID )
|
||||||
|
{
|
||||||
|
// Message is for subclass
|
||||||
|
BaseClass::ReceiveMessage( classID, msg );
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
int messageType = msg.ReadByte();
|
||||||
|
switch( messageType )
|
||||||
|
{
|
||||||
|
// Effect turning on
|
||||||
|
case 0: // FIXME: Declare
|
||||||
|
{
|
||||||
|
// Create a keyvalue block to set these params
|
||||||
|
KeyValues *pKeys = new KeyValues( "keys" );
|
||||||
|
if ( pKeys == NULL )
|
||||||
|
return;
|
||||||
|
|
||||||
|
if ( m_nType == SCREENEFFECT_EP1_INTRO )
|
||||||
|
{
|
||||||
|
if( g_pMaterialSystemHardwareConfig->GetDXSupportLevel() < 80 )
|
||||||
|
{
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Set our keys
|
||||||
|
pKeys->SetFloat( "duration", m_flDuration );
|
||||||
|
pKeys->SetInt( "fadeout", 0 );
|
||||||
|
|
||||||
|
g_pScreenSpaceEffects->SetScreenSpaceEffectParams( "episodic_intro", pKeys );
|
||||||
|
g_pScreenSpaceEffects->EnableScreenSpaceEffect( "episodic_intro" );
|
||||||
|
}
|
||||||
|
else if ( m_nType == SCREENEFFECT_EP2_ADVISOR_STUN )
|
||||||
|
{
|
||||||
|
// Set our keys
|
||||||
|
pKeys->SetFloat( "duration", m_flDuration );
|
||||||
|
|
||||||
|
g_pScreenSpaceEffects->SetScreenSpaceEffectParams( "episodic_stun", pKeys );
|
||||||
|
g_pScreenSpaceEffects->EnableScreenSpaceEffect( "episodic_stun" );
|
||||||
|
}
|
||||||
|
|
||||||
|
pKeys->deleteThis();
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
|
||||||
|
// Effect turning off
|
||||||
|
case 1: // FIXME: Declare
|
||||||
|
|
||||||
|
if ( m_nType == SCREENEFFECT_EP1_INTRO )
|
||||||
|
{
|
||||||
|
if( g_pMaterialSystemHardwareConfig->GetDXSupportLevel() < 80 )
|
||||||
|
{
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
// Create a keyvalue block to set these params
|
||||||
|
KeyValues *pKeys = new KeyValues( "keys" );
|
||||||
|
if ( pKeys == NULL )
|
||||||
|
return;
|
||||||
|
|
||||||
|
// Set our keys
|
||||||
|
pKeys->SetFloat( "duration", m_flDuration );
|
||||||
|
pKeys->SetInt( "fadeout", 1 );
|
||||||
|
|
||||||
|
g_pScreenSpaceEffects->SetScreenSpaceEffectParams( "episodic_intro", pKeys );
|
||||||
|
}
|
||||||
|
else if ( m_nType == SCREENEFFECT_EP2_ADVISOR_STUN )
|
||||||
|
{
|
||||||
|
g_pScreenSpaceEffects->DisableScreenSpaceEffect( "episodic_stun" );
|
||||||
|
}
|
||||||
|
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
90
cl_dll/c_env_tonemap_controller.cpp
Normal file
90
cl_dll/c_env_tonemap_controller.cpp
Normal file
@ -0,0 +1,90 @@
|
|||||||
|
//====== Copyright © 1996-2005, Valve Corporation, All rights reserved. =======
|
||||||
|
//
|
||||||
|
// Purpose:
|
||||||
|
//
|
||||||
|
//=============================================================================
|
||||||
|
#include "cbase.h"
|
||||||
|
|
||||||
|
extern bool g_bUseCustomAutoExposureMin;
|
||||||
|
extern bool g_bUseCustomAutoExposureMax;
|
||||||
|
extern bool g_bUseCustomBloomScale;
|
||||||
|
extern float g_flCustomAutoExposureMin;
|
||||||
|
extern float g_flCustomAutoExposureMax;
|
||||||
|
extern float g_flCustomBloomScale;
|
||||||
|
extern float g_flCustomBloomScaleMinimum;
|
||||||
|
|
||||||
|
//-----------------------------------------------------------------------------
|
||||||
|
// Purpose:
|
||||||
|
//-----------------------------------------------------------------------------
|
||||||
|
class C_EnvTonemapController : public C_BaseEntity
|
||||||
|
{
|
||||||
|
DECLARE_CLASS( C_EnvTonemapController, C_BaseEntity );
|
||||||
|
public:
|
||||||
|
DECLARE_CLIENTCLASS();
|
||||||
|
|
||||||
|
C_EnvTonemapController();
|
||||||
|
~C_EnvTonemapController();
|
||||||
|
virtual void OnDataChanged( DataUpdateType_t updateType );
|
||||||
|
|
||||||
|
private:
|
||||||
|
bool m_bUseCustomAutoExposureMin;
|
||||||
|
bool m_bUseCustomAutoExposureMax;
|
||||||
|
bool m_bUseCustomBloomScale;
|
||||||
|
float m_flCustomAutoExposureMin;
|
||||||
|
float m_flCustomAutoExposureMax;
|
||||||
|
float m_flCustomBloomScale;
|
||||||
|
float m_flCustomBloomScaleMinimum;
|
||||||
|
private:
|
||||||
|
C_EnvTonemapController( const C_EnvTonemapController & );
|
||||||
|
};
|
||||||
|
|
||||||
|
IMPLEMENT_CLIENTCLASS_DT( C_EnvTonemapController, DT_EnvTonemapController, CEnvTonemapController )
|
||||||
|
RecvPropInt( RECVINFO(m_bUseCustomAutoExposureMin) ),
|
||||||
|
RecvPropInt( RECVINFO(m_bUseCustomAutoExposureMax) ),
|
||||||
|
RecvPropInt( RECVINFO(m_bUseCustomBloomScale) ),
|
||||||
|
RecvPropFloat( RECVINFO(m_flCustomAutoExposureMin) ),
|
||||||
|
RecvPropFloat( RECVINFO(m_flCustomAutoExposureMax) ),
|
||||||
|
RecvPropFloat( RECVINFO(m_flCustomBloomScale) ),
|
||||||
|
RecvPropFloat( RECVINFO(m_flCustomBloomScaleMinimum) ),
|
||||||
|
END_RECV_TABLE()
|
||||||
|
|
||||||
|
//-----------------------------------------------------------------------------
|
||||||
|
// Purpose:
|
||||||
|
//-----------------------------------------------------------------------------
|
||||||
|
C_EnvTonemapController::C_EnvTonemapController( void )
|
||||||
|
{
|
||||||
|
m_bUseCustomAutoExposureMin = false;
|
||||||
|
m_bUseCustomAutoExposureMax = false;
|
||||||
|
m_bUseCustomBloomScale = false;
|
||||||
|
m_flCustomAutoExposureMin = 0;
|
||||||
|
m_flCustomAutoExposureMax = 0;
|
||||||
|
m_flCustomBloomScale = 0.0f;
|
||||||
|
m_flCustomBloomScaleMinimum = 0.0f;
|
||||||
|
}
|
||||||
|
|
||||||
|
//-----------------------------------------------------------------------------
|
||||||
|
// Purpose:
|
||||||
|
//-----------------------------------------------------------------------------
|
||||||
|
C_EnvTonemapController::~C_EnvTonemapController( void )
|
||||||
|
{
|
||||||
|
g_bUseCustomAutoExposureMin = false;
|
||||||
|
g_bUseCustomAutoExposureMax = false;
|
||||||
|
g_bUseCustomBloomScale = false;
|
||||||
|
}
|
||||||
|
|
||||||
|
//-----------------------------------------------------------------------------
|
||||||
|
// Purpose:
|
||||||
|
//-----------------------------------------------------------------------------
|
||||||
|
void C_EnvTonemapController::OnDataChanged( DataUpdateType_t updateType )
|
||||||
|
{
|
||||||
|
BaseClass::OnDataChanged(updateType);
|
||||||
|
|
||||||
|
g_bUseCustomAutoExposureMin = m_bUseCustomAutoExposureMin;
|
||||||
|
g_bUseCustomAutoExposureMax = m_bUseCustomAutoExposureMax;
|
||||||
|
g_bUseCustomBloomScale = m_bUseCustomBloomScale;
|
||||||
|
g_flCustomAutoExposureMin = m_flCustomAutoExposureMin;
|
||||||
|
g_flCustomAutoExposureMax = m_flCustomAutoExposureMax;
|
||||||
|
g_flCustomBloomScale = m_flCustomBloomScale;
|
||||||
|
g_flCustomBloomScaleMinimum = m_flCustomBloomScaleMinimum;
|
||||||
|
}
|
||||||
|
|
1470
cl_dll/c_fire_smoke.cpp
Normal file
1470
cl_dll/c_fire_smoke.cpp
Normal file
File diff suppressed because it is too large
Load Diff
322
cl_dll/c_fire_smoke.h
Normal file
322
cl_dll/c_fire_smoke.h
Normal file
@ -0,0 +1,322 @@
|
|||||||
|
//========= Copyright © 1996-2005, Valve Corporation, All rights reserved. ============//
|
||||||
|
//
|
||||||
|
// Purpose:
|
||||||
|
//
|
||||||
|
// $NoKeywords: $
|
||||||
|
//
|
||||||
|
//=============================================================================//
|
||||||
|
#ifndef C_FIRE_SMOKE_H
|
||||||
|
#define C_FIRE_SMOKE_H
|
||||||
|
|
||||||
|
#include "particles_simple.h"
|
||||||
|
#include "tempent.h"
|
||||||
|
#include "glow_overlay.h"
|
||||||
|
#include "view.h"
|
||||||
|
#include "particle_litsmokeemitter.h"
|
||||||
|
|
||||||
|
class CFireOverlay;
|
||||||
|
|
||||||
|
class C_FireSprite : public C_Sprite
|
||||||
|
{
|
||||||
|
DECLARE_CLASS( C_FireSprite, C_Sprite );
|
||||||
|
|
||||||
|
private:
|
||||||
|
virtual int DrawModel( int flags )
|
||||||
|
{
|
||||||
|
if ( m_bFadeFromAbove )
|
||||||
|
{
|
||||||
|
// The sprites become less visible the more you look down or up at them
|
||||||
|
Vector vToPos = GetLocalOrigin() - CurrentViewOrigin();
|
||||||
|
VectorNormalize( vToPos );
|
||||||
|
|
||||||
|
float fUpAmount = vToPos.z;
|
||||||
|
|
||||||
|
int iAlpha = 255;
|
||||||
|
|
||||||
|
if ( fUpAmount < -0.75f )
|
||||||
|
iAlpha = 0;
|
||||||
|
else if ( fUpAmount < -0.65f )
|
||||||
|
iAlpha = 255 - (int)( ( fUpAmount + 0.65f ) * 10.0f * -255.0f );
|
||||||
|
else if ( fUpAmount > 0.85f )
|
||||||
|
iAlpha = 0;
|
||||||
|
else if ( fUpAmount > 0.75f )
|
||||||
|
iAlpha = 255 - (int)( ( fUpAmount - 0.75f ) * 10.0f * 255.0f );
|
||||||
|
|
||||||
|
SetColor( iAlpha, iAlpha, iAlpha );
|
||||||
|
}
|
||||||
|
|
||||||
|
return BaseClass::DrawModel( flags );
|
||||||
|
}
|
||||||
|
|
||||||
|
public:
|
||||||
|
Vector m_vecMoveDir;
|
||||||
|
bool m_bFadeFromAbove;
|
||||||
|
};
|
||||||
|
|
||||||
|
class C_FireFromAboveSprite : public C_Sprite
|
||||||
|
{
|
||||||
|
DECLARE_CLASS( C_FireFromAboveSprite, C_Sprite );
|
||||||
|
|
||||||
|
virtual int DrawModel( int flags )
|
||||||
|
{
|
||||||
|
// The sprites become more visible the more you look down or up at them
|
||||||
|
Vector vToPos = GetLocalOrigin() - CurrentViewOrigin();
|
||||||
|
VectorNormalize( vToPos );
|
||||||
|
|
||||||
|
float fUpAmount = vToPos.z;
|
||||||
|
|
||||||
|
int iAlpha = 0;
|
||||||
|
|
||||||
|
if ( fUpAmount < -0.85f )
|
||||||
|
iAlpha = 255;
|
||||||
|
else if ( fUpAmount < -0.65f )
|
||||||
|
iAlpha = (int)( ( fUpAmount + 0.65f ) * 5.0f * -255.0f );
|
||||||
|
else if ( fUpAmount > 0.75f )
|
||||||
|
iAlpha = 255;
|
||||||
|
else if ( fUpAmount > 0.55f )
|
||||||
|
iAlpha = (int)( ( fUpAmount - 0.55f ) * 5.0f * 255.0f );
|
||||||
|
|
||||||
|
SetColor( iAlpha, iAlpha, iAlpha );
|
||||||
|
|
||||||
|
return BaseClass::DrawModel( flags );
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
#ifdef _XBOX
|
||||||
|
// XBox reduces the flame count
|
||||||
|
#define NUM_CHILD_FLAMES 1
|
||||||
|
#else
|
||||||
|
#define NUM_CHILD_FLAMES 4
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#define SMOKE_RISE_RATE 92.0f
|
||||||
|
#define SMOKE_LIFETIME 2.0f
|
||||||
|
#define EMBER_LIFETIME 2.0f
|
||||||
|
|
||||||
|
#define FLAME_CHILD_SPREAD 64.0f
|
||||||
|
#define FLAME_SOURCE_HEIGHT 128.0f
|
||||||
|
#define FLAME_FROM_ABOVE_SOURCE_HEIGHT 32.0f
|
||||||
|
|
||||||
|
//==================================================
|
||||||
|
// C_FireSmoke
|
||||||
|
//==================================================
|
||||||
|
|
||||||
|
//NOTENOTE: Mirrored in dlls/fire_smoke.h
|
||||||
|
#define bitsFIRESMOKE_NONE 0x00000000
|
||||||
|
#define bitsFIRESMOKE_ACTIVE 0x00000001
|
||||||
|
#define bitsFIRESMOKE_SMOKE 0x00000002
|
||||||
|
#define bitsFIRESMOKE_SMOKE_COLLISION 0x00000004
|
||||||
|
#define bitsFIRESMOKE_GLOW 0x00000008
|
||||||
|
#define bitsFIRESMOKE_VISIBLE_FROM_ABOVE 0x00000010
|
||||||
|
|
||||||
|
#define OVERLAY_MAX_VISIBLE_RANGE 512.0f
|
||||||
|
|
||||||
|
|
||||||
|
class C_FireSmoke : public C_BaseEntity
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
DECLARE_CLIENTCLASS();
|
||||||
|
DECLARE_CLASS( C_FireSmoke, C_BaseEntity );
|
||||||
|
|
||||||
|
C_FireSmoke();
|
||||||
|
~C_FireSmoke();
|
||||||
|
|
||||||
|
void Start( void );
|
||||||
|
void Simulate( void );
|
||||||
|
|
||||||
|
void StartClientOnly( void );
|
||||||
|
void RemoveClientOnly( void );
|
||||||
|
|
||||||
|
protected:
|
||||||
|
void Update( void );
|
||||||
|
void UpdateAnimation( void );
|
||||||
|
void UpdateScale( void );
|
||||||
|
void UpdateFlames( void );
|
||||||
|
void AddFlames( void );
|
||||||
|
void SpawnSmoke( void );
|
||||||
|
void FindClipPlane( void );
|
||||||
|
|
||||||
|
//C_BaseEntity
|
||||||
|
public:
|
||||||
|
|
||||||
|
virtual void OnDataChanged( DataUpdateType_t updateType );
|
||||||
|
virtual bool ShouldDraw();
|
||||||
|
|
||||||
|
float GetScale( void ) const { return m_flScaleRegister; }
|
||||||
|
|
||||||
|
//From the server
|
||||||
|
public:
|
||||||
|
float m_flStartScale;
|
||||||
|
float m_flScale;
|
||||||
|
float m_flScaleTime;
|
||||||
|
int m_nFlags;
|
||||||
|
int m_nFlameModelIndex;
|
||||||
|
int m_nFlameFromAboveModelIndex;
|
||||||
|
|
||||||
|
//Client-side only
|
||||||
|
public:
|
||||||
|
float m_flScaleRegister;
|
||||||
|
float m_flScaleStart;
|
||||||
|
float m_flScaleEnd;
|
||||||
|
float m_flScaleTimeStart;
|
||||||
|
float m_flScaleTimeEnd;
|
||||||
|
float m_flChildFlameSpread;
|
||||||
|
|
||||||
|
VPlane m_planeClip;
|
||||||
|
float m_flClipPerc;
|
||||||
|
bool m_bClipTested;
|
||||||
|
|
||||||
|
bool m_bFadingOut;
|
||||||
|
|
||||||
|
protected:
|
||||||
|
|
||||||
|
void UpdateEffects( void );
|
||||||
|
|
||||||
|
//CSmartPtr<CEmberEffect> m_pEmberEmitter;
|
||||||
|
CSmartPtr<CLitSmokeEmitter> m_pSmokeEmitter;
|
||||||
|
|
||||||
|
C_FireSprite m_entFlames[NUM_CHILD_FLAMES];
|
||||||
|
C_FireFromAboveSprite m_entFlamesFromAbove[NUM_CHILD_FLAMES];
|
||||||
|
float m_entFlameScales[NUM_CHILD_FLAMES];
|
||||||
|
|
||||||
|
TimedEvent m_tParticleSpawn;
|
||||||
|
|
||||||
|
CFireOverlay *m_pFireOverlay;
|
||||||
|
|
||||||
|
private:
|
||||||
|
C_FireSmoke( const C_FireSmoke & );
|
||||||
|
};
|
||||||
|
|
||||||
|
//Fire overlay
|
||||||
|
class CFireOverlay : public CGlowOverlay
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
|
||||||
|
//Constructor
|
||||||
|
CFireOverlay( C_FireSmoke *owner )
|
||||||
|
{
|
||||||
|
m_pOwner = owner;
|
||||||
|
m_flScale = 0.0f;
|
||||||
|
m_nGUID = random->RandomInt( -999999, 999999 );
|
||||||
|
}
|
||||||
|
|
||||||
|
//-----------------------------------------------------------------------------
|
||||||
|
// Purpose: Generate a flicker value
|
||||||
|
// Output : scalar value
|
||||||
|
//-----------------------------------------------------------------------------
|
||||||
|
float GetFlickerScale( void )
|
||||||
|
{
|
||||||
|
float result = 0.0f;
|
||||||
|
|
||||||
|
float time = Helper_GetTime() + m_nGUID;
|
||||||
|
|
||||||
|
result = sin( time * 1000.0f );
|
||||||
|
result += 0.5f * sin( time * 2000.0f );
|
||||||
|
result -= 0.5f * cos( time * 8000.0f );
|
||||||
|
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
//-----------------------------------------------------------------------------
|
||||||
|
// Purpose: Update the overlay
|
||||||
|
//-----------------------------------------------------------------------------
|
||||||
|
virtual bool Update( void )
|
||||||
|
{
|
||||||
|
if ( m_pOwner == NULL )
|
||||||
|
return false;
|
||||||
|
|
||||||
|
float scale = m_pOwner->GetScale();
|
||||||
|
float dscale = scale - m_flScale;
|
||||||
|
|
||||||
|
m_vPos[2] += dscale * FLAME_SOURCE_HEIGHT;
|
||||||
|
m_flScale = scale;
|
||||||
|
|
||||||
|
scale *= 0.75f;
|
||||||
|
|
||||||
|
float flickerScale = GetFlickerScale();
|
||||||
|
|
||||||
|
float newScale = scale + ( scale * flickerScale * 0.1f );
|
||||||
|
|
||||||
|
m_Sprites[0].m_flHorzSize = ( newScale * 0.2f ) + ( m_Sprites[0].m_flHorzSize * 0.8f );
|
||||||
|
m_Sprites[0].m_flVertSize = m_Sprites[0].m_flHorzSize * 1.5f;
|
||||||
|
|
||||||
|
float cameraDistance = ( CurrentViewOrigin() - (m_pOwner->GetAbsOrigin())).Length();
|
||||||
|
|
||||||
|
C_BasePlayer *local = C_BasePlayer::GetLocalPlayer();
|
||||||
|
if ( local )
|
||||||
|
{
|
||||||
|
cameraDistance *= local->GetFOVDistanceAdjustFactor();
|
||||||
|
}
|
||||||
|
|
||||||
|
if ( cameraDistance > OVERLAY_MAX_VISIBLE_RANGE )
|
||||||
|
cameraDistance = OVERLAY_MAX_VISIBLE_RANGE;
|
||||||
|
|
||||||
|
float alpha = 1.0f - ( cameraDistance / OVERLAY_MAX_VISIBLE_RANGE );
|
||||||
|
|
||||||
|
Vector newColor = m_vBaseColors[0] + ( m_vBaseColors[0] * flickerScale * 0.5f );
|
||||||
|
m_Sprites[0].m_vColor = ( newColor * 0.1f ) + ( m_Sprites[0].m_vColor * 0.9f ) * alpha;
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
public:
|
||||||
|
|
||||||
|
C_FireSmoke *m_pOwner;
|
||||||
|
Vector m_vBaseColors[MAX_SUN_LAYERS];
|
||||||
|
float m_flScale;
|
||||||
|
int m_nGUID;
|
||||||
|
};
|
||||||
|
|
||||||
|
//
|
||||||
|
// Entity flame, client-side implementation
|
||||||
|
//
|
||||||
|
|
||||||
|
#define NUM_FLAMELETS 5
|
||||||
|
|
||||||
|
class C_EntityFlame : public C_BaseEntity
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
DECLARE_CLIENTCLASS();
|
||||||
|
DECLARE_CLASS( C_EntityFlame, C_BaseEntity );
|
||||||
|
|
||||||
|
C_EntityFlame( void );
|
||||||
|
~C_EntityFlame( void );
|
||||||
|
|
||||||
|
void UpdateOnRemove( void );
|
||||||
|
void CleanUpRagdollOnRemove( void );
|
||||||
|
void OnDataChanged( DataUpdateType_t updateType );
|
||||||
|
RenderGroup_t GetRenderGroup();
|
||||||
|
void Simulate( void );
|
||||||
|
|
||||||
|
EHANDLE m_hEntAttached; // The entity that we are burning (attached to).
|
||||||
|
bool m_bUseHitboxes;
|
||||||
|
bool m_bCreatedClientside;
|
||||||
|
virtual void ClientThink( void );
|
||||||
|
|
||||||
|
C_FireSmoke *m_pFireSmoke[NUM_HITBOX_FIRES];
|
||||||
|
|
||||||
|
protected:
|
||||||
|
|
||||||
|
void AttachToHitBoxes( void );
|
||||||
|
void UpdateHitBoxFlames( void );
|
||||||
|
void DeleteHitBoxFlames( void );
|
||||||
|
|
||||||
|
float m_flSize;
|
||||||
|
CSmartPtr<CEmberEffect> m_pEmitter;
|
||||||
|
TimedEvent m_ParticleSpawn;
|
||||||
|
bool m_bAttachedToHitboxes;
|
||||||
|
float m_flLifetime;
|
||||||
|
bool m_bStartedFading;
|
||||||
|
|
||||||
|
const model_t *m_pCachedModel; // Holds the model pointer to detect when it changes
|
||||||
|
|
||||||
|
Vector m_vecLastPosition;
|
||||||
|
|
||||||
|
PMaterialHandle m_MaterialHandle[NUM_FLAMELETS];
|
||||||
|
|
||||||
|
// For attaching to the hitboxes of an animating model.
|
||||||
|
Vector m_vecFireOrigin[NUM_HITBOX_FIRES];
|
||||||
|
int m_nHitbox[NUM_HITBOX_FIRES];
|
||||||
|
};
|
||||||
|
|
||||||
|
#endif //C_FIRE_SMOKE_H
|
352
cl_dll/c_fish.cpp
Normal file
352
cl_dll/c_fish.cpp
Normal file
@ -0,0 +1,352 @@
|
|||||||
|
//========= Copyright © 1996-2005, Valve Corporation, All rights reserved. ============//
|
||||||
|
//
|
||||||
|
// Purpose:
|
||||||
|
//
|
||||||
|
// $NoKeywords: $
|
||||||
|
//
|
||||||
|
//=============================================================================//
|
||||||
|
// c_fish.cpp
|
||||||
|
// Simple fish client-side logic
|
||||||
|
// Author: Michael S. Booth, April 2005
|
||||||
|
|
||||||
|
#include "cbase.h"
|
||||||
|
#include <bitbuf.h>
|
||||||
|
#include "engine/IVDebugOverlay.h"
|
||||||
|
|
||||||
|
// memdbgon must be the last include file in a .cpp file!!!
|
||||||
|
#include "tier0/memdbgon.h"
|
||||||
|
|
||||||
|
extern float UTIL_WaterLevel( const Vector &position, float minz, float maxz );
|
||||||
|
|
||||||
|
|
||||||
|
ConVar FishDebug( "fish_debug", "0", FCVAR_CHEAT, "Show debug info for fish" );
|
||||||
|
|
||||||
|
|
||||||
|
//-----------------------------------------------------------------------------
|
||||||
|
/**
|
||||||
|
* Client-side fish entity
|
||||||
|
*/
|
||||||
|
class C_Fish : public C_BaseAnimating
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
DECLARE_CLASS( C_Fish, C_BaseAnimating );
|
||||||
|
DECLARE_CLIENTCLASS();
|
||||||
|
|
||||||
|
virtual void Spawn( void );
|
||||||
|
virtual void ClientThink();
|
||||||
|
|
||||||
|
virtual void OnDataChanged( DataUpdateType_t type );
|
||||||
|
|
||||||
|
private:
|
||||||
|
friend void RecvProxy_FishOriginX( const CRecvProxyData *pData, void *pStruct, void *pOut );
|
||||||
|
friend void RecvProxy_FishOriginY( const CRecvProxyData *pData, void *pStruct, void *pOut );
|
||||||
|
|
||||||
|
Vector m_pos; ///< local position
|
||||||
|
Vector m_vel; ///< local velocity
|
||||||
|
QAngle m_angles; ///< local angles
|
||||||
|
|
||||||
|
int m_localLifeState; ///< our version of m_lifeState
|
||||||
|
|
||||||
|
float m_deathDepth; ///< water depth when we died
|
||||||
|
float m_deathAngle; ///< angle to float at when dead
|
||||||
|
float m_buoyancy; ///< so each fish floats at a different rate when dead
|
||||||
|
|
||||||
|
CountdownTimer m_wiggleTimer; ///< for simulating swimming motions
|
||||||
|
float m_wigglePhase; ///< where in the wiggle sinusoid we are
|
||||||
|
float m_wiggleRate; ///< the speed of our wiggling
|
||||||
|
|
||||||
|
Vector m_actualPos; ///< position from server
|
||||||
|
QAngle m_actualAngles; ///< angles from server
|
||||||
|
|
||||||
|
Vector m_poolOrigin;
|
||||||
|
float m_waterLevel; ///< Z coordinate of water surface
|
||||||
|
|
||||||
|
bool m_gotUpdate; ///< true after we have received a network update
|
||||||
|
|
||||||
|
enum { MAX_ERROR_HISTORY = 20 };
|
||||||
|
float m_errorHistory[ MAX_ERROR_HISTORY ]; ///< error history samples
|
||||||
|
int m_errorHistoryIndex;
|
||||||
|
int m_errorHistoryCount;
|
||||||
|
float m_averageError;
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
//-----------------------------------------------------------------------------
|
||||||
|
void RecvProxy_FishOriginX( const CRecvProxyData *pData, void *pStruct, void *pOut )
|
||||||
|
{
|
||||||
|
C_Fish *fish = (C_Fish *)pStruct;
|
||||||
|
float *out = (float *)pOut;
|
||||||
|
|
||||||
|
*out = pData->m_Value.m_Float + fish->m_poolOrigin.x;
|
||||||
|
}
|
||||||
|
|
||||||
|
void RecvProxy_FishOriginY( const CRecvProxyData *pData, void *pStruct, void *pOut )
|
||||||
|
{
|
||||||
|
C_Fish *fish = (C_Fish *)pStruct;
|
||||||
|
float *out = (float *)pOut;
|
||||||
|
|
||||||
|
*out = pData->m_Value.m_Float + fish->m_poolOrigin.y;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
IMPLEMENT_CLIENTCLASS_DT_NOBASE( C_Fish, DT_CFish, CFish )
|
||||||
|
|
||||||
|
RecvPropVector( RECVINFO(m_poolOrigin) ),
|
||||||
|
|
||||||
|
RecvPropFloat( RECVINFO_NAME( m_actualPos.x, m_x ), 0, RecvProxy_FishOriginX ),
|
||||||
|
RecvPropFloat( RECVINFO_NAME( m_actualPos.y, m_y ), 0, RecvProxy_FishOriginY ),
|
||||||
|
RecvPropFloat( RECVINFO_NAME( m_actualPos.z, m_z ) ),
|
||||||
|
|
||||||
|
RecvPropFloat( RECVINFO_NAME( m_actualAngles.y, m_angle ) ),
|
||||||
|
|
||||||
|
RecvPropInt( RECVINFO(m_nModelIndex) ),
|
||||||
|
RecvPropInt( RECVINFO(m_lifeState) ),
|
||||||
|
|
||||||
|
RecvPropFloat( RECVINFO(m_waterLevel) ), ///< get this from the server in case we die when slightly out of the water due to error correction
|
||||||
|
|
||||||
|
END_RECV_TABLE()
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
//-----------------------------------------------------------------------------
|
||||||
|
void C_Fish::Spawn( void )
|
||||||
|
{
|
||||||
|
BaseClass::Spawn();
|
||||||
|
|
||||||
|
m_angles = QAngle( 0, 0, 0 );
|
||||||
|
m_actualAngles = m_angles;
|
||||||
|
|
||||||
|
m_vel = Vector( 0, 0, 0 );
|
||||||
|
m_gotUpdate = false;
|
||||||
|
m_localLifeState = LIFE_ALIVE;
|
||||||
|
m_buoyancy = RandomFloat( 0.4f, 1.0f );
|
||||||
|
|
||||||
|
m_errorHistoryIndex = 0;
|
||||||
|
m_errorHistoryCount = 0;
|
||||||
|
m_averageError = 0.0f;
|
||||||
|
|
||||||
|
SetNextClientThink( CLIENT_THINK_ALWAYS );
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
//-----------------------------------------------------------------------------
|
||||||
|
void C_Fish::ClientThink()
|
||||||
|
{
|
||||||
|
if (FishDebug.GetBool())
|
||||||
|
{
|
||||||
|
debugoverlay->AddLineOverlay( m_pos, m_actualPos, 255, 0, 0, true, 0.1f );
|
||||||
|
switch( m_localLifeState )
|
||||||
|
{
|
||||||
|
case LIFE_DYING:
|
||||||
|
debugoverlay->AddTextOverlay( m_pos, 0.1f, "DYING" );
|
||||||
|
break;
|
||||||
|
|
||||||
|
case LIFE_DEAD:
|
||||||
|
debugoverlay->AddTextOverlay( m_pos, 0.1f, "DEAD" );
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
float deltaT = gpGlobals->frametime;
|
||||||
|
|
||||||
|
|
||||||
|
// check if we just died
|
||||||
|
if (m_localLifeState == LIFE_ALIVE && m_lifeState != LIFE_ALIVE)
|
||||||
|
{
|
||||||
|
// we have died
|
||||||
|
m_localLifeState = LIFE_DYING;
|
||||||
|
|
||||||
|
m_deathDepth = m_pos.z;
|
||||||
|
|
||||||
|
// determine surface float angle
|
||||||
|
m_deathAngle = RandomFloat( 87.0f, 93.0f ) * ((RandomInt( 0, 100 ) < 50) ? 1.0f : -1.0f);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
switch( m_localLifeState )
|
||||||
|
{
|
||||||
|
case LIFE_DYING:
|
||||||
|
{
|
||||||
|
// depth parameter
|
||||||
|
float t = (m_pos.z - m_deathDepth) / (m_waterLevel - m_deathDepth);
|
||||||
|
t *= t;
|
||||||
|
|
||||||
|
// roll onto side
|
||||||
|
m_angles.z = m_deathAngle * t;
|
||||||
|
|
||||||
|
// float to surface
|
||||||
|
const float fudge = 2.0f;
|
||||||
|
if (m_pos.z < m_waterLevel - fudge)
|
||||||
|
{
|
||||||
|
m_vel.z += (1.0f - t) * m_buoyancy * deltaT;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
m_localLifeState = LIFE_DEAD;
|
||||||
|
}
|
||||||
|
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
case LIFE_DEAD:
|
||||||
|
{
|
||||||
|
// depth parameter
|
||||||
|
float t = (m_pos.z - m_deathDepth) / (m_waterLevel - m_deathDepth);
|
||||||
|
t *= t;
|
||||||
|
|
||||||
|
// roll onto side
|
||||||
|
m_angles.z = m_deathAngle * t;
|
||||||
|
|
||||||
|
// keep near water surface
|
||||||
|
const float sub = 0.5f;
|
||||||
|
m_vel.z += 10.0f * (m_waterLevel - m_pos.z - sub) * deltaT;
|
||||||
|
|
||||||
|
// bob on surface
|
||||||
|
const float rollAmp = 5.0f;
|
||||||
|
const float rollFreq = 2.33f;
|
||||||
|
m_angles.z += rollAmp * sin( rollFreq * (gpGlobals->curtime + 10.0f * entindex()) ) * deltaT;
|
||||||
|
|
||||||
|
const float rollAmp2 = 7.0f;
|
||||||
|
const float rollFreq2 = 4.0f;
|
||||||
|
m_angles.x += rollAmp2 * sin( rollFreq2 * (gpGlobals->curtime + 10.0f * entindex()) ) * deltaT;
|
||||||
|
|
||||||
|
const float bobAmp = 0.75f;
|
||||||
|
const float bobFreq = 4.0f;
|
||||||
|
m_vel.z += bobAmp * sin( bobFreq * (gpGlobals->curtime + 10.0f * entindex()) ) * deltaT;
|
||||||
|
|
||||||
|
const float bobAmp2 = 0.75f;
|
||||||
|
const float bobFreq2 = 3.333f;
|
||||||
|
m_vel.z += bobAmp2 * sin( bobFreq2 * (gpGlobals->curtime + 10.0f * entindex()) ) * deltaT;
|
||||||
|
|
||||||
|
// decay movement speed to zero
|
||||||
|
const float drag = 1.0f;
|
||||||
|
m_vel.z -= drag * m_vel.z * deltaT;
|
||||||
|
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
case LIFE_ALIVE:
|
||||||
|
{
|
||||||
|
// use server-side Z coordinate directly
|
||||||
|
m_pos.z = m_actualPos.z;
|
||||||
|
|
||||||
|
// use server-side angles
|
||||||
|
m_angles = m_actualAngles;
|
||||||
|
|
||||||
|
// fishy wiggle based on movement
|
||||||
|
if (!m_wiggleTimer.IsElapsed())
|
||||||
|
{
|
||||||
|
float swimPower = 1.0f - (m_wiggleTimer.GetElapsedTime() / m_wiggleTimer.GetCountdownDuration());
|
||||||
|
const float amp = 6.0f * swimPower;
|
||||||
|
float wiggle = amp * sin( m_wigglePhase );
|
||||||
|
|
||||||
|
m_wigglePhase += m_wiggleRate * deltaT;
|
||||||
|
|
||||||
|
// wiggle decay
|
||||||
|
const float wiggleDecay = 5.0f;
|
||||||
|
m_wiggleRate -= wiggleDecay * deltaT;
|
||||||
|
|
||||||
|
m_angles.y += wiggle;
|
||||||
|
}
|
||||||
|
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// compute error between our local position and actual server position
|
||||||
|
Vector error = m_actualPos - m_pos;
|
||||||
|
error.z = 0.0f;
|
||||||
|
float errorLen = error.Length();
|
||||||
|
|
||||||
|
if (m_localLifeState == LIFE_ALIVE)
|
||||||
|
{
|
||||||
|
// if error is far above average, start swimming
|
||||||
|
const float wiggleThreshold = 2.0f;
|
||||||
|
if (errorLen - m_averageError > wiggleThreshold)
|
||||||
|
{
|
||||||
|
// if error is large, we must have started swimming
|
||||||
|
const float swimTime = 5.0f;
|
||||||
|
m_wiggleTimer.Start( swimTime );
|
||||||
|
|
||||||
|
m_wiggleRate = 2.0f * errorLen;
|
||||||
|
|
||||||
|
const float maxWiggleRate = 30.0f;
|
||||||
|
if (m_wiggleRate > maxWiggleRate)
|
||||||
|
{
|
||||||
|
m_wiggleRate = maxWiggleRate;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// update average error
|
||||||
|
m_errorHistory[ m_errorHistoryIndex++ ] = errorLen;
|
||||||
|
if (m_errorHistoryIndex >= MAX_ERROR_HISTORY)
|
||||||
|
{
|
||||||
|
m_errorHistoryIndex = 0;
|
||||||
|
m_errorHistoryCount = MAX_ERROR_HISTORY;
|
||||||
|
}
|
||||||
|
else if (m_errorHistoryCount < MAX_ERROR_HISTORY)
|
||||||
|
{
|
||||||
|
++m_errorHistoryCount;
|
||||||
|
}
|
||||||
|
|
||||||
|
m_averageError = 0.0f;
|
||||||
|
if (m_errorHistoryCount)
|
||||||
|
{
|
||||||
|
for( int r=0; r<m_errorHistoryCount; ++r )
|
||||||
|
{
|
||||||
|
m_averageError += m_errorHistory[r];
|
||||||
|
}
|
||||||
|
m_averageError /= (float)m_errorHistoryCount;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// keep fish motion smooth by correcting towards actual server position
|
||||||
|
// NOTE: This only tracks XY motion
|
||||||
|
const float maxError = 20.0f;
|
||||||
|
float errorT = errorLen / maxError;
|
||||||
|
if (errorT > 1.0f)
|
||||||
|
{
|
||||||
|
errorT = 1.0f;
|
||||||
|
}
|
||||||
|
|
||||||
|
// we want a nonlinear spring force for tracking
|
||||||
|
errorT *= errorT;
|
||||||
|
|
||||||
|
// as fish move faster, their error increases - use a stiffer spring when fast, and a weak one when slow
|
||||||
|
const float trackRate = 0.0f + errorT * 115.0f;
|
||||||
|
m_vel.x += trackRate * error.x * deltaT;
|
||||||
|
m_vel.y += trackRate * error.y * deltaT;
|
||||||
|
|
||||||
|
const float trackDrag = 2.0f + errorT * 6.0f;
|
||||||
|
m_vel.x -= trackDrag * m_vel.x * deltaT;
|
||||||
|
m_vel.y -= trackDrag * m_vel.y * deltaT;
|
||||||
|
|
||||||
|
|
||||||
|
// euler integration
|
||||||
|
m_pos += m_vel * deltaT;
|
||||||
|
|
||||||
|
SetNetworkOrigin( m_pos );
|
||||||
|
SetAbsOrigin( m_pos );
|
||||||
|
|
||||||
|
SetNetworkAngles( m_angles );
|
||||||
|
SetAbsAngles( m_angles );
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
//-----------------------------------------------------------------------------
|
||||||
|
void C_Fish::OnDataChanged( DataUpdateType_t type )
|
||||||
|
{
|
||||||
|
//if (!m_gotUpdate)
|
||||||
|
|
||||||
|
if (type == DATA_UPDATE_CREATED)
|
||||||
|
{
|
||||||
|
// initial update
|
||||||
|
m_gotUpdate = true;
|
||||||
|
|
||||||
|
m_pos = m_actualPos;
|
||||||
|
m_vel = Vector( 0, 0, 0 );
|
||||||
|
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
301
cl_dll/c_forcefeedback.cpp
Normal file
301
cl_dll/c_forcefeedback.cpp
Normal file
@ -0,0 +1,301 @@
|
|||||||
|
#include "cbase.h"
|
||||||
|
#include "forcefeedback.h"
|
||||||
|
#include "hud_macros.h"
|
||||||
|
#include "input.h"
|
||||||
|
|
||||||
|
#define FF_CLIENT_FLAG 0x8000
|
||||||
|
|
||||||
|
class FFParams
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
FORCEFEEDBACK_t m_nEffectType;
|
||||||
|
FFBaseParams_t m_BaseParams;
|
||||||
|
};
|
||||||
|
|
||||||
|
struct FFEffectInfo_t
|
||||||
|
{
|
||||||
|
FORCEFEEDBACK_t effectType;
|
||||||
|
char const *name;
|
||||||
|
};
|
||||||
|
|
||||||
|
#define DECLARE_FFEFFECT( name ) { name, #name }
|
||||||
|
|
||||||
|
static FFEffectInfo_t g_EffectTypes[] =
|
||||||
|
{
|
||||||
|
DECLARE_FFEFFECT( FORCE_FEEDBACK_SHOT_SINGLE ),
|
||||||
|
DECLARE_FFEFFECT( FORCE_FEEDBACK_SHOT_DOUBLE ),
|
||||||
|
DECLARE_FFEFFECT( FORCE_FEEDBACK_TAKEDAMAGE ),
|
||||||
|
DECLARE_FFEFFECT( FORCE_FEEDBACK_SCREENSHAKE ),
|
||||||
|
DECLARE_FFEFFECT( FORCE_FEEDBACK_SKIDDING ),
|
||||||
|
DECLARE_FFEFFECT( FORCE_FEEDBACK_BREAKING )
|
||||||
|
};
|
||||||
|
|
||||||
|
//-----------------------------------------------------------------------------
|
||||||
|
// Purpose:
|
||||||
|
// Input : effect -
|
||||||
|
// Output : char const
|
||||||
|
//-----------------------------------------------------------------------------
|
||||||
|
char const *NameForForceFeedbackEffect( FORCEFEEDBACK_t effect )
|
||||||
|
{
|
||||||
|
int c = ARRAYSIZE( g_EffectTypes );
|
||||||
|
if ( (int)effect < 0 || (int)effect >= c )
|
||||||
|
return "???";
|
||||||
|
|
||||||
|
const FFEffectInfo_t& info = g_EffectTypes[ (int)effect ];
|
||||||
|
Assert( info.effectType == effect );
|
||||||
|
return info.name;
|
||||||
|
}
|
||||||
|
|
||||||
|
//-----------------------------------------------------------------------------
|
||||||
|
// Purpose:
|
||||||
|
// Input : *name -
|
||||||
|
// Output : FORCEFEEDBACK_t
|
||||||
|
//-----------------------------------------------------------------------------
|
||||||
|
FORCEFEEDBACK_t ForceFeedbackEffectForName( const char *name )
|
||||||
|
{
|
||||||
|
int c = ARRAYSIZE( g_EffectTypes );
|
||||||
|
for ( int i = 0 ; i < c; ++i )
|
||||||
|
{
|
||||||
|
const FFEffectInfo_t& info = g_EffectTypes[ i ];
|
||||||
|
|
||||||
|
if ( !Q_stricmp( info.name, name ) )
|
||||||
|
return info.effectType;
|
||||||
|
}
|
||||||
|
|
||||||
|
return ( FORCEFEEDBACK_t )-1;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
//-----------------------------------------------------------------------------
|
||||||
|
// Purpose:
|
||||||
|
//-----------------------------------------------------------------------------
|
||||||
|
class CForceFeedback : public IForceFeedback, public CAutoGameSystem
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
virtual bool Init();
|
||||||
|
virtual void Shutdown();
|
||||||
|
|
||||||
|
// API
|
||||||
|
virtual void StopAllEffects( CBasePlayer *player );
|
||||||
|
virtual void StopEffect( CBasePlayer *player, FORCEFEEDBACK_t effect );
|
||||||
|
virtual void StartEffect( CBasePlayer *player, FORCEFEEDBACK_t effect, const FFBaseParams_t& params );
|
||||||
|
|
||||||
|
virtual void PauseAll( CBasePlayer *player );
|
||||||
|
virtual void ResumeAll( CBasePlayer *player );
|
||||||
|
|
||||||
|
void MsgFunc_ForceFeedback( bf_read &msg );
|
||||||
|
|
||||||
|
private:
|
||||||
|
|
||||||
|
void Internal_StopAllEffects();
|
||||||
|
void Internal_StopEffect( FORCEFEEDBACK_t effect );
|
||||||
|
void Internal_StartEffect( FORCEFEEDBACK_t, const FFBaseParams_t& params );
|
||||||
|
void Internal_PauseAll();
|
||||||
|
void Internal_ResumeAll();
|
||||||
|
};
|
||||||
|
|
||||||
|
static CForceFeedback g_ForceFeedbackSingleton;
|
||||||
|
IForceFeedback *forcefeedback = &g_ForceFeedbackSingleton;
|
||||||
|
|
||||||
|
//-----------------------------------------------------------------------------
|
||||||
|
// Purpose:
|
||||||
|
// Input : &msg -
|
||||||
|
//-----------------------------------------------------------------------------
|
||||||
|
void __MsgFunc_ForceFeedback( bf_read &msg )
|
||||||
|
{
|
||||||
|
g_ForceFeedbackSingleton.MsgFunc_ForceFeedback( msg );
|
||||||
|
}
|
||||||
|
|
||||||
|
//-----------------------------------------------------------------------------
|
||||||
|
// Purpose:
|
||||||
|
// Output : Returns true on success, false on failure.
|
||||||
|
//-----------------------------------------------------------------------------
|
||||||
|
bool CForceFeedback::Init()
|
||||||
|
{
|
||||||
|
HOOK_MESSAGE( ForceFeedback );
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
//-----------------------------------------------------------------------------
|
||||||
|
// Purpose:
|
||||||
|
//-----------------------------------------------------------------------------
|
||||||
|
void CForceFeedback::Shutdown()
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
//-----------------------------------------------------------------------------
|
||||||
|
// Purpose:
|
||||||
|
// Input : *player -
|
||||||
|
//-----------------------------------------------------------------------------
|
||||||
|
void CForceFeedback::StopAllEffects( CBasePlayer *player )
|
||||||
|
{
|
||||||
|
if ( !player )
|
||||||
|
return;
|
||||||
|
|
||||||
|
Internal_StopAllEffects();
|
||||||
|
}
|
||||||
|
|
||||||
|
//-----------------------------------------------------------------------------
|
||||||
|
// Purpose:
|
||||||
|
// Input : *player -
|
||||||
|
// effect -
|
||||||
|
//-----------------------------------------------------------------------------
|
||||||
|
void CForceFeedback::StopEffect( CBasePlayer *player, FORCEFEEDBACK_t effect )
|
||||||
|
{
|
||||||
|
if ( !player )
|
||||||
|
return;
|
||||||
|
|
||||||
|
Internal_StopEffect( effect );
|
||||||
|
}
|
||||||
|
|
||||||
|
//-----------------------------------------------------------------------------
|
||||||
|
// Purpose:
|
||||||
|
// Input : *player -
|
||||||
|
// effect -
|
||||||
|
// params -
|
||||||
|
//-----------------------------------------------------------------------------
|
||||||
|
void CForceFeedback::StartEffect( CBasePlayer *player, FORCEFEEDBACK_t effect, const FFBaseParams_t& params )
|
||||||
|
{
|
||||||
|
if ( !player )
|
||||||
|
{
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
Internal_StartEffect( effect, params );
|
||||||
|
}
|
||||||
|
|
||||||
|
//-----------------------------------------------------------------------------
|
||||||
|
// Purpose:
|
||||||
|
// Input : *player -
|
||||||
|
//-----------------------------------------------------------------------------
|
||||||
|
void CForceFeedback::PauseAll( CBasePlayer *player )
|
||||||
|
{
|
||||||
|
if ( !player )
|
||||||
|
return;
|
||||||
|
|
||||||
|
Internal_PauseAll();
|
||||||
|
}
|
||||||
|
|
||||||
|
//-----------------------------------------------------------------------------
|
||||||
|
// Purpose:
|
||||||
|
// Input : *player -
|
||||||
|
//-----------------------------------------------------------------------------
|
||||||
|
void CForceFeedback::ResumeAll( CBasePlayer *player )
|
||||||
|
{
|
||||||
|
if ( !player )
|
||||||
|
return;
|
||||||
|
|
||||||
|
Internal_ResumeAll();
|
||||||
|
}
|
||||||
|
|
||||||
|
//-----------------------------------------------------------------------------
|
||||||
|
// Purpose:
|
||||||
|
//-----------------------------------------------------------------------------
|
||||||
|
void CForceFeedback::Internal_StopAllEffects()
|
||||||
|
{
|
||||||
|
input->ForceFeedback_StopAll();
|
||||||
|
}
|
||||||
|
|
||||||
|
//-----------------------------------------------------------------------------
|
||||||
|
// Purpose:
|
||||||
|
// Input : heffect -
|
||||||
|
//-----------------------------------------------------------------------------
|
||||||
|
void CForceFeedback::Internal_StopEffect( FORCEFEEDBACK_t effect )
|
||||||
|
{
|
||||||
|
input->ForceFeedback_Stop( effect );
|
||||||
|
}
|
||||||
|
|
||||||
|
//-----------------------------------------------------------------------------
|
||||||
|
// Purpose:
|
||||||
|
// Input : effect -
|
||||||
|
//-----------------------------------------------------------------------------
|
||||||
|
void CForceFeedback::Internal_StartEffect( FORCEFEEDBACK_t effect, const FFBaseParams_t& params)
|
||||||
|
{
|
||||||
|
char const *name = NameForForceFeedbackEffect( effect );
|
||||||
|
Msg( "Starting FF effect '%s'\n", name );
|
||||||
|
|
||||||
|
FFParams p;
|
||||||
|
p.m_nEffectType = effect;
|
||||||
|
p.m_BaseParams = params;
|
||||||
|
|
||||||
|
input->ForceFeedback_Start( effect, params );
|
||||||
|
}
|
||||||
|
|
||||||
|
//-----------------------------------------------------------------------------
|
||||||
|
// Purpose:
|
||||||
|
//-----------------------------------------------------------------------------
|
||||||
|
void CForceFeedback::Internal_PauseAll()
|
||||||
|
{
|
||||||
|
input->ForceFeedback_Pause();
|
||||||
|
}
|
||||||
|
|
||||||
|
//-----------------------------------------------------------------------------
|
||||||
|
// Purpose:
|
||||||
|
//-----------------------------------------------------------------------------
|
||||||
|
void CForceFeedback::Internal_ResumeAll()
|
||||||
|
{
|
||||||
|
input->ForceFeedback_Resume();
|
||||||
|
}
|
||||||
|
|
||||||
|
//-----------------------------------------------------------------------------
|
||||||
|
// Purpose:
|
||||||
|
// Input : *pszName -
|
||||||
|
// iSize -
|
||||||
|
// *pbuf -
|
||||||
|
//-----------------------------------------------------------------------------
|
||||||
|
void CForceFeedback::MsgFunc_ForceFeedback( bf_read &msg )
|
||||||
|
{
|
||||||
|
byte msgType = msg.ReadByte();
|
||||||
|
|
||||||
|
switch ( msgType )
|
||||||
|
{
|
||||||
|
default:
|
||||||
|
{
|
||||||
|
Warning( "Bad parse in MsgFunc_ForceFeedback!\n" );
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
case FFMSG_STOPALL:
|
||||||
|
{
|
||||||
|
Internal_StopAllEffects();
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
case FFMSG_START:
|
||||||
|
{
|
||||||
|
FORCEFEEDBACK_t effectType = (FORCEFEEDBACK_t)msg.ReadByte();
|
||||||
|
|
||||||
|
FFBaseParams_t params;
|
||||||
|
params.m_flDirection = 360.0f * ( (byte)msg.ReadByte() / 255.0f );
|
||||||
|
params.m_flDuration = (float)msg.ReadLong() / 1000.0f;
|
||||||
|
params.m_flGain = ( (byte)msg.ReadByte() / 255.0f );
|
||||||
|
params.m_nPriority = msg.ReadByte();
|
||||||
|
params.m_bSolo = msg.ReadByte() == 0 ? false : true;
|
||||||
|
|
||||||
|
if ( effectType >= 0 && effectType < NUM_FORCE_FEEDBACK_PRESETS )
|
||||||
|
{
|
||||||
|
Internal_StartEffect( effectType, params );
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
Warning( "Bad parse in MsgFunc_ForceFeedback, FFMSG_START (%i)!\n", effectType );
|
||||||
|
}
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
case FFMSG_STOP:
|
||||||
|
{
|
||||||
|
FORCEFEEDBACK_t effectType = (FORCEFEEDBACK_t)msg.ReadByte();
|
||||||
|
|
||||||
|
Internal_StopEffect( effectType );
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
case FFMSG_PAUSE:
|
||||||
|
{
|
||||||
|
Internal_PauseAll();
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
case FFMSG_RESUME:
|
||||||
|
{
|
||||||
|
Internal_ResumeAll();
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
139
cl_dll/c_func_areaportalwindow.cpp
Normal file
139
cl_dll/c_func_areaportalwindow.cpp
Normal file
@ -0,0 +1,139 @@
|
|||||||
|
//========= Copyright © 1996-2005, Valve Corporation, All rights reserved. ============//
|
||||||
|
//
|
||||||
|
// Purpose:
|
||||||
|
//
|
||||||
|
// $NoKeywords: $
|
||||||
|
//
|
||||||
|
//=============================================================================//
|
||||||
|
#include "cbase.h"
|
||||||
|
#include "view.h"
|
||||||
|
#include "model_types.h"
|
||||||
|
#include "IVRenderView.h"
|
||||||
|
#include "engine/ivmodelinfo.h"
|
||||||
|
|
||||||
|
// memdbgon must be the last include file in a .cpp file!!!
|
||||||
|
#include "tier0/memdbgon.h"
|
||||||
|
|
||||||
|
class C_FuncAreaPortalWindow : public C_BaseEntity
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
DECLARE_CLIENTCLASS();
|
||||||
|
DECLARE_CLASS( C_FuncAreaPortalWindow, C_BaseEntity );
|
||||||
|
|
||||||
|
|
||||||
|
// Overrides.
|
||||||
|
public:
|
||||||
|
|
||||||
|
virtual void ComputeFxBlend();
|
||||||
|
virtual bool IsTransparent();
|
||||||
|
virtual int DrawModel( int flags );
|
||||||
|
virtual bool ShouldReceiveProjectedTextures( int flags );
|
||||||
|
|
||||||
|
private:
|
||||||
|
|
||||||
|
float GetDistanceBlend();
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
public:
|
||||||
|
float m_flFadeStartDist; // Distance at which it starts fading (when <= this, alpha=m_flTranslucencyLimit).
|
||||||
|
float m_flFadeDist; // Distance at which it becomes solid.
|
||||||
|
|
||||||
|
// 0-1 value - minimum translucency it's allowed to get to.
|
||||||
|
float m_flTranslucencyLimit;
|
||||||
|
|
||||||
|
int m_iBackgroundModelIndex;
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
IMPLEMENT_CLIENTCLASS_DT( C_FuncAreaPortalWindow, DT_FuncAreaPortalWindow, CFuncAreaPortalWindow )
|
||||||
|
RecvPropFloat( RECVINFO( m_flFadeStartDist ) ),
|
||||||
|
RecvPropFloat( RECVINFO( m_flFadeDist ) ),
|
||||||
|
RecvPropFloat( RECVINFO( m_flTranslucencyLimit ) ),
|
||||||
|
RecvPropInt( RECVINFO( m_iBackgroundModelIndex ) )
|
||||||
|
END_RECV_TABLE()
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
void C_FuncAreaPortalWindow::ComputeFxBlend()
|
||||||
|
{
|
||||||
|
// We reset our blend down below so pass anything except 0 to the renderer.
|
||||||
|
m_nRenderFXBlend = 255;
|
||||||
|
|
||||||
|
#ifdef _DEBUG
|
||||||
|
m_nFXComputeFrame = gpGlobals->framecount;
|
||||||
|
#endif
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
bool C_FuncAreaPortalWindow::IsTransparent()
|
||||||
|
{
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
int C_FuncAreaPortalWindow::DrawModel( int flags )
|
||||||
|
{
|
||||||
|
if ( !m_bReadyToDraw )
|
||||||
|
return 0;
|
||||||
|
|
||||||
|
if( !GetModel() )
|
||||||
|
return 0;
|
||||||
|
|
||||||
|
// Make sure we're a brush model.
|
||||||
|
int modelType = modelinfo->GetModelType( GetModel() );
|
||||||
|
if( modelType != mod_brush )
|
||||||
|
return 0;
|
||||||
|
|
||||||
|
// Draw the fading version.
|
||||||
|
render->SetBlend( GetDistanceBlend() );
|
||||||
|
render->DrawBrushModel(
|
||||||
|
this,
|
||||||
|
(model_t *)GetModel(),
|
||||||
|
GetAbsOrigin(),
|
||||||
|
GetAbsAngles(),
|
||||||
|
!!(flags & STUDIO_TRANSPARENCY) );
|
||||||
|
|
||||||
|
// Draw the optional foreground model next.
|
||||||
|
// Only use the alpha in the texture from the thing in the front.
|
||||||
|
if (m_iBackgroundModelIndex >= 0)
|
||||||
|
{
|
||||||
|
render->SetBlend( 1 );
|
||||||
|
model_t *pBackground = ( model_t * )modelinfo->GetModel( m_iBackgroundModelIndex );
|
||||||
|
if( pBackground && modelinfo->GetModelType( pBackground ) == mod_brush )
|
||||||
|
{
|
||||||
|
render->DrawBrushModel(
|
||||||
|
this,
|
||||||
|
pBackground,
|
||||||
|
GetAbsOrigin(),
|
||||||
|
GetAbsAngles(),
|
||||||
|
!!(flags & STUDIO_TRANSPARENCY) );
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
float C_FuncAreaPortalWindow::GetDistanceBlend()
|
||||||
|
{
|
||||||
|
// Get the viewer's distance to us.
|
||||||
|
float flDist = CollisionProp()->CalcDistanceFromPoint( CurrentViewOrigin() );
|
||||||
|
C_BasePlayer *local = C_BasePlayer::GetLocalPlayer();
|
||||||
|
if ( local )
|
||||||
|
{
|
||||||
|
flDist *= local->GetFOVDistanceAdjustFactor();
|
||||||
|
}
|
||||||
|
float flAlpha = RemapVal( flDist, m_flFadeStartDist, m_flFadeDist, m_flTranslucencyLimit, 1 );
|
||||||
|
flAlpha = clamp( flAlpha, m_flTranslucencyLimit, 1 );
|
||||||
|
return flAlpha;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool C_FuncAreaPortalWindow::ShouldReceiveProjectedTextures( int flags )
|
||||||
|
{
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
1323
cl_dll/c_func_breakablesurf.cpp
Normal file
1323
cl_dll/c_func_breakablesurf.cpp
Normal file
File diff suppressed because it is too large
Load Diff
144
cl_dll/c_func_conveyor.cpp
Normal file
144
cl_dll/c_func_conveyor.cpp
Normal file
@ -0,0 +1,144 @@
|
|||||||
|
//========= Copyright © 1996-2005, Valve Corporation, All rights reserved. ============//
|
||||||
|
//
|
||||||
|
// Purpose:
|
||||||
|
//
|
||||||
|
//=============================================================================//
|
||||||
|
|
||||||
|
#include "cbase.h"
|
||||||
|
#include "materialsystem/IMaterialProxy.h"
|
||||||
|
#include "materialsystem/IMaterial.h"
|
||||||
|
#include "materialsystem/IMaterialVar.h"
|
||||||
|
#include "FunctionProxy.h"
|
||||||
|
#include <KeyValues.h>
|
||||||
|
#include "VMatrix.h"
|
||||||
|
#include "FunctionProxy.h"
|
||||||
|
|
||||||
|
// memdbgon must be the last include file in a .cpp file!!!
|
||||||
|
#include "tier0/memdbgon.h"
|
||||||
|
|
||||||
|
class C_FuncConveyor : public C_BaseEntity
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
DECLARE_CLASS( C_FuncConveyor, C_BaseEntity );
|
||||||
|
DECLARE_CLIENTCLASS();
|
||||||
|
|
||||||
|
C_FuncConveyor();
|
||||||
|
|
||||||
|
float GetConveyorSpeed() { return m_flConveyorSpeed; }
|
||||||
|
|
||||||
|
private:
|
||||||
|
float m_flConveyorSpeed;
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
IMPLEMENT_CLIENTCLASS_DT( C_FuncConveyor, DT_FuncConveyor, CFuncConveyor )
|
||||||
|
RecvPropFloat( RECVINFO( m_flConveyorSpeed ) ),
|
||||||
|
END_RECV_TABLE()
|
||||||
|
|
||||||
|
|
||||||
|
C_FuncConveyor::C_FuncConveyor()
|
||||||
|
{
|
||||||
|
m_flConveyorSpeed = 0.0;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
class CConveyorMaterialProxy : public IMaterialProxy
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
CConveyorMaterialProxy();
|
||||||
|
virtual ~CConveyorMaterialProxy();
|
||||||
|
|
||||||
|
virtual bool Init( IMaterial *pMaterial, KeyValues *pKeyValues );
|
||||||
|
virtual void OnBind( void *pC_BaseEntity );
|
||||||
|
virtual void Release( void ) { delete this; }
|
||||||
|
|
||||||
|
private:
|
||||||
|
C_BaseEntity *BindArgToEntity( void *pArg );
|
||||||
|
|
||||||
|
IMaterialVar *m_pTextureScrollVar;
|
||||||
|
};
|
||||||
|
|
||||||
|
CConveyorMaterialProxy::CConveyorMaterialProxy()
|
||||||
|
{
|
||||||
|
m_pTextureScrollVar = NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
CConveyorMaterialProxy::~CConveyorMaterialProxy()
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
bool CConveyorMaterialProxy::Init( IMaterial *pMaterial, KeyValues *pKeyValues )
|
||||||
|
{
|
||||||
|
char const* pScrollVarName = pKeyValues->GetString( "textureScrollVar" );
|
||||||
|
if( !pScrollVarName )
|
||||||
|
return false;
|
||||||
|
|
||||||
|
bool foundVar;
|
||||||
|
m_pTextureScrollVar = pMaterial->FindVar( pScrollVarName, &foundVar, false );
|
||||||
|
if( !foundVar )
|
||||||
|
return false;
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
C_BaseEntity *CConveyorMaterialProxy::BindArgToEntity( void *pArg )
|
||||||
|
{
|
||||||
|
IClientRenderable *pRend = (IClientRenderable *)pArg;
|
||||||
|
return pRend->GetIClientUnknown()->GetBaseEntity();
|
||||||
|
}
|
||||||
|
|
||||||
|
void CConveyorMaterialProxy::OnBind( void *pC_BaseEntity )
|
||||||
|
{
|
||||||
|
if( !pC_BaseEntity )
|
||||||
|
return;
|
||||||
|
|
||||||
|
C_BaseEntity *pEntity = BindArgToEntity( pC_BaseEntity );
|
||||||
|
|
||||||
|
if ( !pEntity )
|
||||||
|
return;
|
||||||
|
|
||||||
|
C_FuncConveyor *pConveyor = dynamic_cast<C_FuncConveyor*>(pEntity);
|
||||||
|
|
||||||
|
if ( !pConveyor )
|
||||||
|
return;
|
||||||
|
|
||||||
|
if ( !m_pTextureScrollVar )
|
||||||
|
{
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
float flConveyorSpeed = pConveyor->GetConveyorSpeed();
|
||||||
|
float flRate = abs( flConveyorSpeed ) / 128.0;
|
||||||
|
float flAngle = (flConveyorSpeed >= 0) ? 180 : 0;
|
||||||
|
|
||||||
|
float sOffset = gpGlobals->curtime * cos( flAngle * ( M_PI / 180.0f ) ) * flRate;
|
||||||
|
float tOffset = gpGlobals->curtime * sin( flAngle * ( M_PI / 180.0f ) ) * flRate;
|
||||||
|
|
||||||
|
// make sure that we are positive
|
||||||
|
if( sOffset < 0.0f )
|
||||||
|
{
|
||||||
|
sOffset += 1.0f + -( int )sOffset;
|
||||||
|
}
|
||||||
|
if( tOffset < 0.0f )
|
||||||
|
{
|
||||||
|
tOffset += 1.0f + -( int )tOffset;
|
||||||
|
}
|
||||||
|
|
||||||
|
// make sure that we are in a [0,1] range
|
||||||
|
sOffset = sOffset - ( int )sOffset;
|
||||||
|
tOffset = tOffset - ( int )tOffset;
|
||||||
|
|
||||||
|
if (m_pTextureScrollVar->GetType() == MATERIAL_VAR_TYPE_MATRIX)
|
||||||
|
{
|
||||||
|
VMatrix mat;
|
||||||
|
MatrixBuildTranslation( mat, sOffset, tOffset, 0.0f );
|
||||||
|
m_pTextureScrollVar->SetMatrixValue( mat );
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
m_pTextureScrollVar->SetVecValue( sOffset, tOffset, 0.0f );
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
EXPOSE_INTERFACE( CConveyorMaterialProxy, IMaterialProxy, "ConveyorScroll" IMATERIAL_PROXY_INTERFACE_VERSION );
|
455
cl_dll/c_func_dust.cpp
Normal file
455
cl_dll/c_func_dust.cpp
Normal file
@ -0,0 +1,455 @@
|
|||||||
|
//========= Copyright © 1996-2005, Valve Corporation, All rights reserved. ============//
|
||||||
|
//
|
||||||
|
// Purpose:
|
||||||
|
//
|
||||||
|
// $NoKeywords: $
|
||||||
|
//=============================================================================//
|
||||||
|
#include "cbase.h"
|
||||||
|
#include "c_func_dust.h"
|
||||||
|
#include "func_dust_shared.h"
|
||||||
|
#include "c_te_particlesystem.h"
|
||||||
|
#include "env_wind_shared.h"
|
||||||
|
#include "engine/IEngineTrace.h"
|
||||||
|
#include "tier0/vprof.h"
|
||||||
|
#include "ClientEffectPrecacheSystem.h"
|
||||||
|
|
||||||
|
#ifdef _XBOX
|
||||||
|
#include "particles_ez.h"
|
||||||
|
#endif // XBOX
|
||||||
|
|
||||||
|
// memdbgon must be the last include file in a .cpp file!!!
|
||||||
|
#include "tier0/memdbgon.h"
|
||||||
|
|
||||||
|
IMPLEMENT_CLIENTCLASS_DT_NOBASE( C_Func_Dust, DT_Func_Dust, CFunc_Dust )
|
||||||
|
RecvPropInt( RECVINFO(m_Color) ),
|
||||||
|
RecvPropInt( RECVINFO(m_SpawnRate) ),
|
||||||
|
RecvPropFloat( RECVINFO(m_flSizeMin) ),
|
||||||
|
RecvPropFloat( RECVINFO(m_flSizeMax) ),
|
||||||
|
RecvPropInt( RECVINFO(m_LifetimeMin) ),
|
||||||
|
RecvPropInt( RECVINFO(m_LifetimeMax) ),
|
||||||
|
RecvPropInt( RECVINFO(m_DustFlags) ),
|
||||||
|
RecvPropInt( RECVINFO(m_SpeedMax) ),
|
||||||
|
RecvPropInt( RECVINFO(m_DistMax) ),
|
||||||
|
RecvPropInt( RECVINFO( m_nModelIndex ) ),
|
||||||
|
RecvPropFloat( RECVINFO( m_FallSpeed ) ),
|
||||||
|
RecvPropDataTable( RECVINFO_DT( m_Collision ), 0, &REFERENCE_RECV_TABLE(DT_CollisionProperty) ),
|
||||||
|
END_RECV_TABLE()
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
// ------------------------------------------------------------------------------------ //
|
||||||
|
// CDustEffect implementation.
|
||||||
|
// ------------------------------------------------------------------------------------ //
|
||||||
|
#define DUST_ACCEL 50
|
||||||
|
|
||||||
|
|
||||||
|
void CDustEffect::RenderParticles( CParticleRenderIterator *pIterator )
|
||||||
|
{
|
||||||
|
const CFuncDustParticle *pParticle = (const CFuncDustParticle*)pIterator->GetFirst();
|
||||||
|
while ( pParticle )
|
||||||
|
{
|
||||||
|
// Velocity.
|
||||||
|
float flAlpha;
|
||||||
|
if( m_pDust->m_DustFlags & DUSTFLAGS_FROZEN )
|
||||||
|
{
|
||||||
|
flAlpha = 1;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
// Alpha.
|
||||||
|
float flAngle = (pParticle->m_flLifetime / pParticle->m_flDieTime) * M_PI * 2;
|
||||||
|
flAlpha = sin( flAngle - (M_PI * 0.5f) ) * 0.5f + 0.5f;
|
||||||
|
}
|
||||||
|
|
||||||
|
Vector tPos;
|
||||||
|
TransformParticle( ParticleMgr()->GetModelView(), pParticle->m_Pos, tPos );
|
||||||
|
float sortKey = (int) tPos.z;
|
||||||
|
|
||||||
|
if( -tPos.z <= m_pDust->m_DistMax )
|
||||||
|
{
|
||||||
|
flAlpha *= 1 + (tPos.z / m_pDust->m_DistMax);
|
||||||
|
|
||||||
|
// Draw it.
|
||||||
|
float flSize = pParticle->m_flSize;
|
||||||
|
if( m_pDust->m_DustFlags & DUSTFLAGS_SCALEMOTES )
|
||||||
|
flSize *= -tPos.z;
|
||||||
|
|
||||||
|
RenderParticle_Color255Size(
|
||||||
|
pIterator->GetParticleDraw(),
|
||||||
|
tPos,
|
||||||
|
Vector( m_pDust->m_Color.r, m_pDust->m_Color.g, m_pDust->m_Color.b ),
|
||||||
|
flAlpha * m_pDust->m_Color.a,
|
||||||
|
flSize
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
pParticle = (const CFuncDustParticle*)pIterator->GetNext( sortKey );
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void CDustEffect::SimulateParticles( CParticleSimulateIterator *pIterator )
|
||||||
|
{
|
||||||
|
Vector vecWind;
|
||||||
|
GetWindspeedAtTime( gpGlobals->curtime, vecWind );
|
||||||
|
|
||||||
|
|
||||||
|
CFuncDustParticle *pParticle = (CFuncDustParticle*)pIterator->GetFirst();
|
||||||
|
while ( pParticle )
|
||||||
|
{
|
||||||
|
// Velocity.
|
||||||
|
if( !(m_pDust->m_DustFlags & DUSTFLAGS_FROZEN) )
|
||||||
|
{
|
||||||
|
// Kill the particle?
|
||||||
|
pParticle->m_flLifetime += pIterator->GetTimeDelta();
|
||||||
|
if( pParticle->m_flLifetime >= pParticle->m_flDieTime )
|
||||||
|
{
|
||||||
|
pIterator->RemoveParticle( pParticle );
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
for ( int i = 0 ; i < 2 ; i++ )
|
||||||
|
{
|
||||||
|
if ( pParticle->m_vVelocity[i] < vecWind[i] )
|
||||||
|
{
|
||||||
|
pParticle->m_vVelocity[i] += ( gpGlobals->frametime * DUST_ACCEL );
|
||||||
|
|
||||||
|
// clamp
|
||||||
|
if ( pParticle->m_vVelocity[i] > vecWind[i] )
|
||||||
|
pParticle->m_vVelocity[i] = vecWind[i];
|
||||||
|
}
|
||||||
|
else if (pParticle->m_vVelocity[i] > vecWind[i] )
|
||||||
|
{
|
||||||
|
pParticle->m_vVelocity[i] -= ( gpGlobals->frametime * DUST_ACCEL );
|
||||||
|
|
||||||
|
// clamp.
|
||||||
|
if ( pParticle->m_vVelocity[i] < vecWind[i] )
|
||||||
|
pParticle->m_vVelocity[i] = vecWind[i];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Apply velocity.
|
||||||
|
pParticle->m_Pos.MulAdd( pParticle->m_Pos, pParticle->m_vVelocity, pIterator->GetTimeDelta() );
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
pParticle = (CFuncDustParticle*)pIterator->GetNext();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
// ------------------------------------------------------------------------------------ //
|
||||||
|
// C_Func_Dust implementation.
|
||||||
|
// ------------------------------------------------------------------------------------ //
|
||||||
|
|
||||||
|
C_Func_Dust::C_Func_Dust() : m_Effect( "C_Func_Dust" )
|
||||||
|
{
|
||||||
|
m_Effect.m_pDust = this;
|
||||||
|
m_Effect.SetDynamicallyAllocated( false ); // So it doesn't try to delete itself.
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
C_Func_Dust::~C_Func_Dust()
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
CLIENTEFFECT_REGISTER_BEGIN( PrecacheFuncDust )
|
||||||
|
CLIENTEFFECT_MATERIAL( "particle/sparkles" )
|
||||||
|
CLIENTEFFECT_REGISTER_END()
|
||||||
|
|
||||||
|
void C_Func_Dust::OnDataChanged( DataUpdateType_t updateType )
|
||||||
|
{
|
||||||
|
BaseClass::OnDataChanged( updateType );
|
||||||
|
|
||||||
|
if( updateType == DATA_UPDATE_CREATED )
|
||||||
|
{
|
||||||
|
m_hMaterial = m_Effect.GetPMaterial( "particle/sparkles" );
|
||||||
|
|
||||||
|
m_Effect.SetSortOrigin( WorldSpaceCenter( ) );
|
||||||
|
|
||||||
|
// Let us think each frame.
|
||||||
|
SetNextClientThink( CLIENT_THINK_ALWAYS );
|
||||||
|
|
||||||
|
// If we're setup to be frozen, just make a bunch of particles initially.
|
||||||
|
if( m_DustFlags & DUSTFLAGS_FROZEN )
|
||||||
|
{
|
||||||
|
for( int i=0; i < m_SpawnRate; i++ )
|
||||||
|
{
|
||||||
|
AttemptSpawnNewParticle();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
m_Spawner.Init( m_SpawnRate ); // N particles per second
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void C_Func_Dust::ClientThink()
|
||||||
|
{
|
||||||
|
// If frozen, don't make new particles.
|
||||||
|
if( m_DustFlags & DUSTFLAGS_FROZEN )
|
||||||
|
return;
|
||||||
|
|
||||||
|
// Spawn particles?
|
||||||
|
if( m_DustFlags & DUSTFLAGS_ON )
|
||||||
|
{
|
||||||
|
float flDelta = min( gpGlobals->frametime, 0.1f );
|
||||||
|
while( m_Spawner.NextEvent( flDelta ) )
|
||||||
|
{
|
||||||
|
AttemptSpawnNewParticle();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Tell the particle manager our bbox.
|
||||||
|
Vector vWorldMins, vWorldMaxs;
|
||||||
|
CollisionProp()->WorldSpaceAABB( &vWorldMins, &vWorldMaxs );
|
||||||
|
vWorldMins -= Vector( m_flSizeMax, m_flSizeMax, m_flSizeMax );
|
||||||
|
vWorldMaxs += Vector( m_flSizeMax, m_flSizeMax, m_flSizeMax );
|
||||||
|
m_Effect.GetBinding().SetBBox( vWorldMins, vWorldMaxs );
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
bool C_Func_Dust::ShouldDraw()
|
||||||
|
{
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void C_Func_Dust::AttemptSpawnNewParticle()
|
||||||
|
{
|
||||||
|
// Find a random spot inside our bmodel.
|
||||||
|
static int nTests=10;
|
||||||
|
|
||||||
|
for( int iTest=0; iTest < nTests; iTest++ )
|
||||||
|
{
|
||||||
|
Vector vPercent = RandomVector( 0, 1 );
|
||||||
|
Vector vTest = WorldAlignMins() + (WorldAlignMaxs() - WorldAlignMins()) * vPercent;
|
||||||
|
|
||||||
|
int contents = enginetrace->GetPointContents_Collideable( GetCollideable(), vTest );
|
||||||
|
if( contents & CONTENTS_SOLID )
|
||||||
|
{
|
||||||
|
CFuncDustParticle *pParticle = (CFuncDustParticle*)m_Effect.AddParticle( 10, m_hMaterial, vTest );
|
||||||
|
if( pParticle )
|
||||||
|
{
|
||||||
|
pParticle->m_vVelocity = RandomVector( -m_SpeedMax, m_SpeedMax );
|
||||||
|
pParticle->m_vVelocity.z -= m_FallSpeed;
|
||||||
|
|
||||||
|
pParticle->m_flLifetime = 0;
|
||||||
|
pParticle->m_flDieTime = RemapVal( rand(), 0, RAND_MAX, m_LifetimeMin, m_LifetimeMax );
|
||||||
|
|
||||||
|
if( m_DustFlags & DUSTFLAGS_SCALEMOTES )
|
||||||
|
pParticle->m_flSize = RemapVal( rand(), 0, RAND_MAX, m_flSizeMin/10000.0f, m_flSizeMax/10000.0f );
|
||||||
|
else
|
||||||
|
pParticle->m_flSize = RemapVal( rand(), 0, RAND_MAX, m_flSizeMin, m_flSizeMax );
|
||||||
|
|
||||||
|
pParticle->m_Color = m_Color;
|
||||||
|
}
|
||||||
|
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
//
|
||||||
|
// Dust
|
||||||
|
//
|
||||||
|
|
||||||
|
//-----------------------------------------------------------------------------
|
||||||
|
// Spew out dust!
|
||||||
|
//-----------------------------------------------------------------------------
|
||||||
|
void FX_Dust( const Vector &vecOrigin, const Vector &vecDirection, float flSize, float flSpeed )
|
||||||
|
{
|
||||||
|
#ifdef _XBOX
|
||||||
|
|
||||||
|
//
|
||||||
|
// XBox Version
|
||||||
|
//
|
||||||
|
|
||||||
|
VPROF_BUDGET( "FX_Dust", VPROF_BUDGETGROUP_PARTICLE_RENDERING );
|
||||||
|
|
||||||
|
int numPuffs = (flSize*0.5f);
|
||||||
|
|
||||||
|
if ( numPuffs < 1 )
|
||||||
|
numPuffs = 1;
|
||||||
|
if ( numPuffs > 32 )
|
||||||
|
numPuffs = 32;
|
||||||
|
|
||||||
|
float speed = flSpeed * 0.1f;
|
||||||
|
|
||||||
|
if ( speed < 0 )
|
||||||
|
speed = 1.0f;
|
||||||
|
if (speed > 48.0f )
|
||||||
|
speed = 48.0f;
|
||||||
|
|
||||||
|
//FIXME: Better sampling area
|
||||||
|
Vector offset = vecOrigin + ( vecDirection * flSize );
|
||||||
|
|
||||||
|
//Find area ambient light color and use it to tint smoke
|
||||||
|
Vector worldLight = WorldGetLightForPoint( offset, true );
|
||||||
|
|
||||||
|
// FIXME: Reduce
|
||||||
|
PMaterialHandle hMaterial[2];
|
||||||
|
hMaterial[0] = ParticleMgr()->GetPMaterial("particle/particle_smokegrenade");
|
||||||
|
hMaterial[1] = ParticleMgr()->GetPMaterial("particle/particle_noisesphere");
|
||||||
|
|
||||||
|
// Throw puffs
|
||||||
|
SimpleParticle particle;
|
||||||
|
for ( int i = 0; i < numPuffs; i++ )
|
||||||
|
{
|
||||||
|
offset.Random( -(flSize*0.25f), flSize*0.25f );
|
||||||
|
offset += vecOrigin + ( vecDirection * flSize );
|
||||||
|
|
||||||
|
particle.m_Pos = offset;
|
||||||
|
particle.m_flLifetime = 0.0f;
|
||||||
|
particle.m_flDieTime = random->RandomFloat( 0.4f, 1.0f );
|
||||||
|
|
||||||
|
particle.m_vecVelocity = vecDirection * random->RandomFloat( speed*0.5f, speed ) * i;
|
||||||
|
particle.m_vecVelocity[2] = 0.0f;
|
||||||
|
|
||||||
|
int color = random->RandomInt( 48, 64 );
|
||||||
|
|
||||||
|
particle.m_uchColor[0] = (color+16) + ( worldLight[0] * (float) color );
|
||||||
|
particle.m_uchColor[1] = (color+8) + ( worldLight[1] * (float) color );
|
||||||
|
particle.m_uchColor[2] = color + ( worldLight[2] * (float) color );
|
||||||
|
|
||||||
|
particle.m_uchStartAlpha= random->RandomInt( 64, 128 );
|
||||||
|
particle.m_uchEndAlpha = 0;
|
||||||
|
particle.m_uchStartSize = random->RandomInt( 2, 8 );
|
||||||
|
particle.m_uchEndSize = random->RandomInt( 24, 48 );
|
||||||
|
particle.m_flRoll = random->RandomInt( 0, 360 );
|
||||||
|
particle.m_flRollDelta = random->RandomFloat( -0.5f, 0.5f );
|
||||||
|
|
||||||
|
AddSimpleParticle( &particle, hMaterial[random->RandomInt(0,1)] );
|
||||||
|
}
|
||||||
|
#else
|
||||||
|
|
||||||
|
//
|
||||||
|
// PC Version
|
||||||
|
//
|
||||||
|
|
||||||
|
VPROF_BUDGET( "FX_Dust", VPROF_BUDGETGROUP_PARTICLE_RENDERING );
|
||||||
|
CSmartPtr<CSimpleEmitter> pSimple = CSimpleEmitter::Create( "dust" );
|
||||||
|
pSimple->SetSortOrigin( vecOrigin );
|
||||||
|
pSimple->SetNearClip( 32, 64 );
|
||||||
|
|
||||||
|
SimpleParticle *pParticle;
|
||||||
|
|
||||||
|
Vector offset;
|
||||||
|
|
||||||
|
int numPuffs = (flSize*0.5f);
|
||||||
|
|
||||||
|
if ( numPuffs < 1 )
|
||||||
|
numPuffs = 1;
|
||||||
|
if ( numPuffs > 32 )
|
||||||
|
numPuffs = 32;
|
||||||
|
|
||||||
|
float speed = flSpeed * 0.1f;
|
||||||
|
|
||||||
|
if ( speed < 0 )
|
||||||
|
speed = 1.0f;
|
||||||
|
|
||||||
|
if (speed > 48.0f )
|
||||||
|
speed = 48.0f;
|
||||||
|
|
||||||
|
//FIXME: Better sampling area
|
||||||
|
offset = vecOrigin + ( vecDirection * flSize );
|
||||||
|
|
||||||
|
//Find area ambient light color and use it to tint smoke
|
||||||
|
Vector worldLight = WorldGetLightForPoint( offset, true );
|
||||||
|
|
||||||
|
PMaterialHandle hMaterial[2];
|
||||||
|
|
||||||
|
hMaterial[0] = pSimple->GetPMaterial("particle/particle_smokegrenade");
|
||||||
|
hMaterial[1] = pSimple->GetPMaterial("particle/particle_noisesphere");
|
||||||
|
|
||||||
|
//Throw puffs
|
||||||
|
for ( int i = 0; i < numPuffs; i++ )
|
||||||
|
{
|
||||||
|
offset.Random( -(flSize*0.25f), flSize*0.25f );
|
||||||
|
offset += vecOrigin + ( vecDirection * flSize );
|
||||||
|
|
||||||
|
pParticle = (SimpleParticle *) pSimple->AddParticle( sizeof(SimpleParticle), hMaterial[random->RandomInt(0,1)], offset );
|
||||||
|
|
||||||
|
if ( pParticle != NULL )
|
||||||
|
{
|
||||||
|
pParticle->m_flLifetime = 0.0f;
|
||||||
|
pParticle->m_flDieTime = random->RandomFloat( 0.4f, 1.5f );
|
||||||
|
|
||||||
|
pParticle->m_vecVelocity = vecDirection * random->RandomFloat( speed*0.5f, speed ) * i;
|
||||||
|
|
||||||
|
pParticle->m_vecVelocity[2] = 0.0f;
|
||||||
|
|
||||||
|
int color = random->RandomInt( 48, 64 );
|
||||||
|
|
||||||
|
pParticle->m_uchColor[0] = (color+16) + ( worldLight[0] * (float) color );
|
||||||
|
pParticle->m_uchColor[1] = (color+8) + ( worldLight[1] * (float) color );
|
||||||
|
pParticle->m_uchColor[2] = color + ( worldLight[2] * (float) color );
|
||||||
|
|
||||||
|
pParticle->m_uchStartAlpha = random->RandomInt( 32, 128 );
|
||||||
|
pParticle->m_uchEndAlpha = 0;
|
||||||
|
pParticle->m_uchStartSize = random->RandomInt( 2, 8 );
|
||||||
|
pParticle->m_uchEndSize = random->RandomInt( 24, 48 );
|
||||||
|
pParticle->m_flRoll = random->RandomInt( 0, 360 );
|
||||||
|
pParticle->m_flRollDelta = random->RandomFloat( -1.0f, 1.0f );
|
||||||
|
}
|
||||||
|
}
|
||||||
|
#endif // _XBOX
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
class C_TEDust: public C_TEParticleSystem
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
DECLARE_CLASS( C_TEDust, C_TEParticleSystem );
|
||||||
|
DECLARE_CLIENTCLASS();
|
||||||
|
|
||||||
|
C_TEDust();
|
||||||
|
virtual ~C_TEDust();
|
||||||
|
|
||||||
|
public:
|
||||||
|
virtual void PostDataUpdate( DataUpdateType_t updateType );
|
||||||
|
virtual bool ShouldDraw() { return true; }
|
||||||
|
|
||||||
|
public:
|
||||||
|
|
||||||
|
float m_flSize;
|
||||||
|
float m_flSpeed;
|
||||||
|
Vector m_vecDirection;
|
||||||
|
|
||||||
|
protected:
|
||||||
|
void GetDustColor( Vector &color );
|
||||||
|
};
|
||||||
|
|
||||||
|
IMPLEMENT_CLIENTCLASS_EVENT_DT( C_TEDust, DT_TEDust, CTEDust )
|
||||||
|
RecvPropFloat(RECVINFO(m_flSize)),
|
||||||
|
RecvPropFloat(RECVINFO(m_flSpeed)),
|
||||||
|
RecvPropVector(RECVINFO(m_vecDirection)),
|
||||||
|
END_RECV_TABLE()
|
||||||
|
|
||||||
|
//==================================================
|
||||||
|
// C_TEDust
|
||||||
|
//==================================================
|
||||||
|
|
||||||
|
C_TEDust::C_TEDust()
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
C_TEDust::~C_TEDust()
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
//-----------------------------------------------------------------------------
|
||||||
|
// Purpose:
|
||||||
|
// Input : bNewEntity - whether or not to start a new entity
|
||||||
|
//-----------------------------------------------------------------------------
|
||||||
|
void C_TEDust::PostDataUpdate( DataUpdateType_t updateType )
|
||||||
|
{
|
||||||
|
FX_Dust( m_vecOrigin, m_vecDirection, m_flSize, m_flSpeed );
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void TE_Dust( IRecipientFilter& filter, float delay,
|
||||||
|
const Vector &pos, const Vector &dir, float size, float speed )
|
||||||
|
{
|
||||||
|
FX_Dust( pos, dir, size, speed );
|
||||||
|
}
|
112
cl_dll/c_func_dust.h
Normal file
112
cl_dll/c_func_dust.h
Normal file
@ -0,0 +1,112 @@
|
|||||||
|
//========= Copyright © 1996-2005, Valve Corporation, All rights reserved. ============//
|
||||||
|
//
|
||||||
|
// Purpose:
|
||||||
|
//
|
||||||
|
// $NoKeywords: $
|
||||||
|
//=============================================================================//
|
||||||
|
|
||||||
|
#ifndef C_FUNC_DUST_H
|
||||||
|
#define C_FUNC_DUST_H
|
||||||
|
#ifdef _WIN32
|
||||||
|
#pragma once
|
||||||
|
#endif
|
||||||
|
|
||||||
|
|
||||||
|
#include "c_baseentity.h"
|
||||||
|
#include "particles_simple.h"
|
||||||
|
#include "particle_util.h"
|
||||||
|
#include "bspflags.h"
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
// ------------------------------------------------------------------------------------ //
|
||||||
|
// CDustEffect particle renderer.
|
||||||
|
// ------------------------------------------------------------------------------------ //
|
||||||
|
|
||||||
|
class C_Func_Dust;
|
||||||
|
|
||||||
|
class CFuncDustParticle : public Particle
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
Vector m_vVelocity;
|
||||||
|
float m_flLifetime;
|
||||||
|
float m_flDieTime;
|
||||||
|
float m_flSize;
|
||||||
|
color32 m_Color;
|
||||||
|
};
|
||||||
|
|
||||||
|
class CDustEffect : public CParticleEffect
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
CDustEffect( const char *pDebugName ) : CParticleEffect( pDebugName ) {}
|
||||||
|
|
||||||
|
virtual void RenderParticles( CParticleRenderIterator *pIterator );
|
||||||
|
virtual void SimulateParticles( CParticleSimulateIterator *pIterator );
|
||||||
|
|
||||||
|
C_Func_Dust *m_pDust;
|
||||||
|
|
||||||
|
private:
|
||||||
|
CDustEffect( const CDustEffect & ); // not defined, not accessible
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
// ------------------------------------------------------------------------------------ //
|
||||||
|
// C_Func_Dust class.
|
||||||
|
// ------------------------------------------------------------------------------------ //
|
||||||
|
|
||||||
|
class C_Func_Dust : public C_BaseEntity
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
DECLARE_CLASS( C_Func_Dust, C_BaseEntity );
|
||||||
|
DECLARE_CLIENTCLASS();
|
||||||
|
|
||||||
|
C_Func_Dust();
|
||||||
|
virtual ~C_Func_Dust();
|
||||||
|
virtual void OnDataChanged( DataUpdateType_t updateType );
|
||||||
|
virtual void ClientThink();
|
||||||
|
virtual bool ShouldDraw();
|
||||||
|
|
||||||
|
|
||||||
|
private:
|
||||||
|
|
||||||
|
void AttemptSpawnNewParticle();
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
// Vars from server.
|
||||||
|
public:
|
||||||
|
|
||||||
|
color32 m_Color;
|
||||||
|
int m_SpawnRate;
|
||||||
|
|
||||||
|
float m_flSizeMin;
|
||||||
|
float m_flSizeMax;
|
||||||
|
|
||||||
|
int m_SpeedMax;
|
||||||
|
|
||||||
|
int m_LifetimeMin;
|
||||||
|
int m_LifetimeMax;
|
||||||
|
|
||||||
|
int m_DistMax;
|
||||||
|
|
||||||
|
float m_FallSpeed; // extra 'gravity'
|
||||||
|
|
||||||
|
|
||||||
|
public:
|
||||||
|
|
||||||
|
int m_DustFlags; // Combination of DUSTFLAGS_
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
public:
|
||||||
|
CDustEffect m_Effect;
|
||||||
|
PMaterialHandle m_hMaterial;
|
||||||
|
TimedEvent m_Spawner;
|
||||||
|
|
||||||
|
private:
|
||||||
|
C_Func_Dust( const C_Func_Dust & ); // not defined, not accessible
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
#endif // C_FUNC_DUST_H
|
72
cl_dll/c_func_lod.cpp
Normal file
72
cl_dll/c_func_lod.cpp
Normal file
@ -0,0 +1,72 @@
|
|||||||
|
//========= Copyright © 1996-2005, Valve Corporation, All rights reserved. ============//
|
||||||
|
//
|
||||||
|
// Purpose:
|
||||||
|
//
|
||||||
|
// $NoKeywords: $
|
||||||
|
//
|
||||||
|
//=============================================================================//
|
||||||
|
#include "cbase.h"
|
||||||
|
#include "view.h"
|
||||||
|
#include "iviewrender.h"
|
||||||
|
|
||||||
|
// memdbgon must be the last include file in a .cpp file!!!
|
||||||
|
#include "tier0/memdbgon.h"
|
||||||
|
|
||||||
|
extern Vector g_vecRenderOrigin;
|
||||||
|
extern ConVar r_DoCovertTransitions;
|
||||||
|
|
||||||
|
|
||||||
|
class C_Func_LOD : public C_BaseEntity
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
DECLARE_CLASS( C_Func_LOD, C_BaseEntity );
|
||||||
|
DECLARE_CLIENTCLASS();
|
||||||
|
|
||||||
|
C_Func_LOD();
|
||||||
|
|
||||||
|
// C_BaseEntity overrides.
|
||||||
|
public:
|
||||||
|
|
||||||
|
unsigned char GetClientSideFade();
|
||||||
|
|
||||||
|
public:
|
||||||
|
// Replicated vars from the server.
|
||||||
|
// These are documented in the server-side entity.
|
||||||
|
public:
|
||||||
|
float m_fDisappearDist;
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
ConVar lod_TransitionDist("lod_TransitionDist", "800");
|
||||||
|
ConVar lod_Enable("lod_Enable", "0");
|
||||||
|
|
||||||
|
|
||||||
|
// ------------------------------------------------------------------------- //
|
||||||
|
// Tables.
|
||||||
|
// ------------------------------------------------------------------------- //
|
||||||
|
|
||||||
|
// Datatable..
|
||||||
|
IMPLEMENT_CLIENTCLASS_DT(C_Func_LOD, DT_Func_LOD, CFunc_LOD)
|
||||||
|
RecvPropFloat(RECVINFO(m_fDisappearDist)),
|
||||||
|
END_RECV_TABLE()
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
// ------------------------------------------------------------------------- //
|
||||||
|
// C_Func_LOD implementation.
|
||||||
|
// ------------------------------------------------------------------------- //
|
||||||
|
|
||||||
|
C_Func_LOD::C_Func_LOD()
|
||||||
|
{
|
||||||
|
m_fDisappearDist = 5000.0f;
|
||||||
|
}
|
||||||
|
|
||||||
|
//-----------------------------------------------------------------------------
|
||||||
|
// Purpose: Calculate a fade.
|
||||||
|
//-----------------------------------------------------------------------------
|
||||||
|
unsigned char C_Func_LOD::GetClientSideFade()
|
||||||
|
{
|
||||||
|
return UTIL_ComputeEntityFade( this, m_fDisappearDist, m_fDisappearDist + lod_TransitionDist.GetFloat(), 1.0f );
|
||||||
|
}
|
||||||
|
|
||||||
|
|
51
cl_dll/c_func_occluder.cpp
Normal file
51
cl_dll/c_func_occluder.cpp
Normal file
@ -0,0 +1,51 @@
|
|||||||
|
//========= Copyright © 1996-2005, Valve Corporation, All rights reserved. ============//
|
||||||
|
//
|
||||||
|
// Purpose:
|
||||||
|
//
|
||||||
|
// $NoKeywords: $
|
||||||
|
//
|
||||||
|
//=============================================================================//
|
||||||
|
#include "cbase.h"
|
||||||
|
|
||||||
|
// memdbgon must be the last include file in a .cpp file!!!
|
||||||
|
#include "tier0/memdbgon.h"
|
||||||
|
|
||||||
|
class C_FuncOccluder : public C_BaseEntity
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
DECLARE_CLIENTCLASS();
|
||||||
|
DECLARE_CLASS( C_FuncOccluder, C_BaseEntity );
|
||||||
|
|
||||||
|
// Overrides.
|
||||||
|
public:
|
||||||
|
virtual bool ShouldDraw();
|
||||||
|
virtual int DrawModel( int flags );
|
||||||
|
virtual void OnDataChanged( DataUpdateType_t updateType );
|
||||||
|
|
||||||
|
private:
|
||||||
|
int m_nOccluderIndex;
|
||||||
|
bool m_bActive;
|
||||||
|
};
|
||||||
|
|
||||||
|
IMPLEMENT_CLIENTCLASS_DT( C_FuncOccluder, DT_FuncOccluder, CFuncOccluder )
|
||||||
|
RecvPropBool( RECVINFO( m_bActive ) ),
|
||||||
|
RecvPropInt( RECVINFO(m_nOccluderIndex) ),
|
||||||
|
END_RECV_TABLE()
|
||||||
|
|
||||||
|
|
||||||
|
void C_FuncOccluder::OnDataChanged( DataUpdateType_t updateType )
|
||||||
|
{
|
||||||
|
BaseClass::OnDataChanged( updateType );
|
||||||
|
engine->ActivateOccluder( m_nOccluderIndex, m_bActive );
|
||||||
|
}
|
||||||
|
|
||||||
|
bool C_FuncOccluder::ShouldDraw()
|
||||||
|
{
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
int C_FuncOccluder::DrawModel( int flags )
|
||||||
|
{
|
||||||
|
Assert(0);
|
||||||
|
return 0;
|
||||||
|
}
|
626
cl_dll/c_func_smokevolume.cpp
Normal file
626
cl_dll/c_func_smokevolume.cpp
Normal file
@ -0,0 +1,626 @@
|
|||||||
|
//========= Copyright © 1996-2005, Valve Corporation, All rights reserved. ============//
|
||||||
|
//
|
||||||
|
// Purpose:
|
||||||
|
//
|
||||||
|
// $NoKeywords: $
|
||||||
|
//=============================================================================//
|
||||||
|
#include "cbase.h"
|
||||||
|
#include "c_smoke_trail.h"
|
||||||
|
#include "smoke_fog_overlay.h"
|
||||||
|
#include "engine/IEngineTrace.h"
|
||||||
|
|
||||||
|
// memdbgon must be the last include file in a .cpp file!!!
|
||||||
|
#include "tier0/memdbgon.h"
|
||||||
|
|
||||||
|
#define SF_EMISSIVE 0x00000001
|
||||||
|
|
||||||
|
// ------------------------------------------------------------------------- //
|
||||||
|
// Definitions
|
||||||
|
// ------------------------------------------------------------------------- //
|
||||||
|
|
||||||
|
static Vector s_FadePlaneDirections[] =
|
||||||
|
{
|
||||||
|
Vector( 1,0,0),
|
||||||
|
Vector(-1,0,0),
|
||||||
|
Vector(0, 1,0),
|
||||||
|
Vector(0,-1,0),
|
||||||
|
Vector(0,0, 1),
|
||||||
|
Vector(0,0,-1)
|
||||||
|
};
|
||||||
|
#define NUM_FADE_PLANES (sizeof(s_FadePlaneDirections)/sizeof(s_FadePlaneDirections[0]))
|
||||||
|
|
||||||
|
// ------------------------------------------------------------------------- //
|
||||||
|
// Classes
|
||||||
|
// ------------------------------------------------------------------------- //
|
||||||
|
class C_FuncSmokeVolume : public C_BaseParticleEntity, public IPrototypeAppEffect
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
DECLARE_CLASS( C_FuncSmokeVolume, C_BaseParticleEntity );
|
||||||
|
DECLARE_CLIENTCLASS();
|
||||||
|
|
||||||
|
C_FuncSmokeVolume();
|
||||||
|
~C_FuncSmokeVolume();
|
||||||
|
|
||||||
|
int IsEmissive( void ) { return ( m_spawnflags & SF_EMISSIVE ); }
|
||||||
|
|
||||||
|
private:
|
||||||
|
class SmokeGrenadeParticle : public Particle
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
float m_RotationFactor;
|
||||||
|
float m_CurRotation;
|
||||||
|
float m_FadeAlpha; // Set as it moves around.
|
||||||
|
unsigned char m_ColorInterp; // Amount between min and max colors.
|
||||||
|
unsigned char m_Color[4];
|
||||||
|
};
|
||||||
|
|
||||||
|
// C_BaseEntity.
|
||||||
|
public:
|
||||||
|
virtual void OnDataChanged( DataUpdateType_t updateType );
|
||||||
|
|
||||||
|
// IPrototypeAppEffect.
|
||||||
|
public:
|
||||||
|
virtual void Start( CParticleMgr *pParticleMgr, IPrototypeArgAccess *pArgs );
|
||||||
|
|
||||||
|
// IParticleEffect.
|
||||||
|
public:
|
||||||
|
virtual void Update(float fTimeDelta);
|
||||||
|
virtual void RenderParticles( CParticleRenderIterator *pIterator );
|
||||||
|
virtual void SimulateParticles( CParticleSimulateIterator *pIterator );
|
||||||
|
virtual void NotifyRemove();
|
||||||
|
|
||||||
|
private:
|
||||||
|
// The SmokeEmitter represents a grid in 3D space.
|
||||||
|
class SmokeParticleInfo
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
SmokeGrenadeParticle *m_pParticle;
|
||||||
|
int m_TradeIndex; // -1 if not exchanging yet.
|
||||||
|
float m_TradeClock; // How long since they started trading.
|
||||||
|
float m_TradeDuration; // How long the trade will take to finish.
|
||||||
|
float m_FadeAlpha; // Calculated from nearby world geometry.
|
||||||
|
unsigned char m_Color[4];
|
||||||
|
};
|
||||||
|
|
||||||
|
inline int GetSmokeParticleIndex(int x, int y, int z)
|
||||||
|
{
|
||||||
|
Assert( IsValidXYZCoords( x, y, z ) );
|
||||||
|
return z*m_xCount*m_yCount+y*m_xCount+x;
|
||||||
|
}
|
||||||
|
|
||||||
|
inline SmokeParticleInfo *GetSmokeParticleInfo(int x, int y, int z)
|
||||||
|
{
|
||||||
|
Assert( IsValidXYZCoords( x, y, z ) );
|
||||||
|
return &m_pSmokeParticleInfos[GetSmokeParticleIndex(x,y,z)];
|
||||||
|
}
|
||||||
|
|
||||||
|
inline void GetParticleInfoXYZ(int index, int &x, int &y, int &z)
|
||||||
|
{
|
||||||
|
Assert( index >= 0 && index < m_xCount * m_yCount * m_zCount );
|
||||||
|
z = index / (m_xCount*m_yCount);
|
||||||
|
int zIndex = z*m_xCount*m_yCount;
|
||||||
|
y = (index - zIndex) / m_xCount;
|
||||||
|
int yIndex = y*m_xCount;
|
||||||
|
x = index - zIndex - yIndex;
|
||||||
|
Assert( IsValidXYZCoords( x, y, z ) );
|
||||||
|
}
|
||||||
|
|
||||||
|
inline bool IsValidXYZCoords(int x, int y, int z)
|
||||||
|
{
|
||||||
|
return x >= 0 && y >= 0 && z >= 0 && x < m_xCount && y < m_yCount && z < m_zCount;
|
||||||
|
}
|
||||||
|
|
||||||
|
inline Vector GetSmokeParticlePos(int x, int y, int z )
|
||||||
|
{
|
||||||
|
return WorldAlignMins() +
|
||||||
|
Vector( x * m_SpacingRadius * 2 + m_SpacingRadius,
|
||||||
|
y * m_SpacingRadius * 2 + m_SpacingRadius,
|
||||||
|
z * m_SpacingRadius * 2 + m_SpacingRadius );
|
||||||
|
}
|
||||||
|
|
||||||
|
inline Vector GetSmokeParticlePosIndex(int index)
|
||||||
|
{
|
||||||
|
int x, y, z;
|
||||||
|
GetParticleInfoXYZ(index, x, y, z);
|
||||||
|
return GetSmokeParticlePos(x, y, z);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Start filling the smoke volume
|
||||||
|
void FillVolume();
|
||||||
|
|
||||||
|
private:
|
||||||
|
// State variables from server.
|
||||||
|
color32 m_Color1;
|
||||||
|
color32 m_Color2;
|
||||||
|
char m_MaterialName[255];
|
||||||
|
float m_ParticleDrawWidth;
|
||||||
|
float m_ParticleSpacingDistance;
|
||||||
|
float m_DensityRampSpeed;
|
||||||
|
float m_RotationSpeed;
|
||||||
|
float m_MovementSpeed;
|
||||||
|
float m_Density;
|
||||||
|
int m_spawnflags;
|
||||||
|
|
||||||
|
private:
|
||||||
|
C_FuncSmokeVolume( const C_FuncSmokeVolume & );
|
||||||
|
|
||||||
|
float m_CurrentDensity;
|
||||||
|
float m_ParticleRadius;
|
||||||
|
bool m_bStarted;
|
||||||
|
|
||||||
|
PMaterialHandle m_MaterialHandle;
|
||||||
|
|
||||||
|
SmokeParticleInfo *m_pSmokeParticleInfos;
|
||||||
|
int m_xCount, m_yCount, m_zCount;
|
||||||
|
float m_SpacingRadius;
|
||||||
|
|
||||||
|
Vector m_MinColor;
|
||||||
|
Vector m_MaxColor;
|
||||||
|
|
||||||
|
Vector m_vLastOrigin;
|
||||||
|
QAngle m_vLastAngles;
|
||||||
|
bool m_bFirstUpdate;
|
||||||
|
};
|
||||||
|
|
||||||
|
IMPLEMENT_CLIENTCLASS_DT( C_FuncSmokeVolume, DT_FuncSmokeVolume, CFuncSmokeVolume )
|
||||||
|
RecvPropInt( RECVINFO( m_Color1 ), 0, RecvProxy_IntToColor32 ),
|
||||||
|
RecvPropInt( RECVINFO( m_Color2 ), 0, RecvProxy_IntToColor32 ),
|
||||||
|
RecvPropString( RECVINFO( m_MaterialName ) ),
|
||||||
|
RecvPropFloat( RECVINFO( m_ParticleDrawWidth ) ),
|
||||||
|
RecvPropFloat( RECVINFO( m_ParticleSpacingDistance ) ),
|
||||||
|
RecvPropFloat( RECVINFO( m_DensityRampSpeed ) ),
|
||||||
|
RecvPropFloat( RECVINFO( m_RotationSpeed ) ),
|
||||||
|
RecvPropFloat( RECVINFO( m_MovementSpeed ) ),
|
||||||
|
RecvPropFloat( RECVINFO( m_Density ) ),
|
||||||
|
RecvPropInt( RECVINFO( m_spawnflags ) ),
|
||||||
|
RecvPropDataTable( RECVINFO_DT( m_Collision ), 0, &REFERENCE_RECV_TABLE(DT_CollisionProperty) ),
|
||||||
|
END_RECV_TABLE()
|
||||||
|
|
||||||
|
// Helpers.
|
||||||
|
// ------------------------------------------------------------------------- //
|
||||||
|
|
||||||
|
static inline void InterpColor(unsigned char dest[4], unsigned char src1[4], unsigned char src2[4], float percent)
|
||||||
|
{
|
||||||
|
dest[0] = (unsigned char)(src1[0] + (src2[0] - src1[0]) * percent);
|
||||||
|
dest[1] = (unsigned char)(src1[1] + (src2[1] - src1[1]) * percent);
|
||||||
|
dest[2] = (unsigned char)(src1[2] + (src2[2] - src1[2]) * percent);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
static inline int GetWorldPointContents(const Vector &vPos)
|
||||||
|
{
|
||||||
|
#if defined(PARTICLEPROTOTYPE_APP)
|
||||||
|
return 0;
|
||||||
|
#else
|
||||||
|
return enginetrace->GetPointContents( vPos );
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
|
static inline void WorldTraceLine( const Vector &start, const Vector &end, int contentsMask, trace_t *trace )
|
||||||
|
{
|
||||||
|
#if defined(PARTICLEPROTOTYPE_APP)
|
||||||
|
trace->fraction = 1;
|
||||||
|
#else
|
||||||
|
UTIL_TraceLine(start, end, contentsMask, NULL, COLLISION_GROUP_NONE, trace);
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
|
static inline Vector EngineGetLightForPoint(const Vector &vPos)
|
||||||
|
{
|
||||||
|
#if defined(PARTICLEPROTOTYPE_APP)
|
||||||
|
return Vector(1,1,1);
|
||||||
|
#else
|
||||||
|
return engine->GetLightForPoint(vPos, true);
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
|
static inline Vector& EngineGetVecRenderOrigin()
|
||||||
|
{
|
||||||
|
#if defined(PARTICLEPROTOTYPE_APP)
|
||||||
|
static Vector dummy(0,0,0);
|
||||||
|
return dummy;
|
||||||
|
#else
|
||||||
|
extern Vector g_vecRenderOrigin;
|
||||||
|
return g_vecRenderOrigin;
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
|
static inline float& EngineGetSmokeFogOverlayAlpha()
|
||||||
|
{
|
||||||
|
#if defined(PARTICLEPROTOTYPE_APP)
|
||||||
|
static float dummy;
|
||||||
|
return dummy;
|
||||||
|
#else
|
||||||
|
return g_SmokeFogOverlayAlpha;
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
|
static inline C_BaseEntity* ParticleGetEntity( int index )
|
||||||
|
{
|
||||||
|
#if defined(PARTICLEPROTOTYPE_APP)
|
||||||
|
return NULL;
|
||||||
|
#else
|
||||||
|
return cl_entitylist->GetEnt( index );
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
|
// ------------------------------------------------------------------------- //
|
||||||
|
// C_FuncSmokeVolume
|
||||||
|
// ------------------------------------------------------------------------- //
|
||||||
|
C_FuncSmokeVolume::C_FuncSmokeVolume()
|
||||||
|
{
|
||||||
|
m_bFirstUpdate = true;
|
||||||
|
m_vLastOrigin.Init();
|
||||||
|
m_vLastAngles.Init();
|
||||||
|
|
||||||
|
m_pSmokeParticleInfos = NULL;
|
||||||
|
m_SpacingRadius = 0.0f;;
|
||||||
|
m_ParticleRadius = 0.0f;
|
||||||
|
m_MinColor.Init( 1.0, 1.0, 1.0 );
|
||||||
|
m_MaxColor.Init( 1.0, 1.0, 1.0 );
|
||||||
|
}
|
||||||
|
|
||||||
|
C_FuncSmokeVolume::~C_FuncSmokeVolume()
|
||||||
|
{
|
||||||
|
delete [] m_pSmokeParticleInfos;
|
||||||
|
}
|
||||||
|
|
||||||
|
void C_FuncSmokeVolume::OnDataChanged( DataUpdateType_t updateType )
|
||||||
|
{
|
||||||
|
m_MinColor[0] = ( 1.0f / 255.0f ) * m_Color1.r;
|
||||||
|
m_MinColor[1] = ( 1.0f / 255.0f ) * m_Color1.g;
|
||||||
|
m_MinColor[2] = ( 1.0f / 255.0f ) * m_Color1.b;
|
||||||
|
|
||||||
|
m_MaxColor[0] = ( 1.0f / 255.0f ) * m_Color2.r;
|
||||||
|
m_MaxColor[1] = ( 1.0f / 255.0f ) * m_Color2.g;
|
||||||
|
m_MaxColor[2] = ( 1.0f / 255.0f ) * m_Color2.b;
|
||||||
|
|
||||||
|
m_ParticleRadius = m_ParticleDrawWidth * 0.5f;
|
||||||
|
m_SpacingRadius = m_ParticleSpacingDistance * 0.5f;
|
||||||
|
|
||||||
|
m_ParticleEffect.SetParticleCullRadius( m_ParticleRadius );
|
||||||
|
|
||||||
|
// Warning( "m_Density: %f\n", m_Density );
|
||||||
|
// Warning( "m_MovementSpeed: %f\n", m_MovementSpeed );
|
||||||
|
|
||||||
|
if(updateType == DATA_UPDATE_CREATED)
|
||||||
|
{
|
||||||
|
Vector size = WorldAlignMaxs() - WorldAlignMins();
|
||||||
|
m_xCount = 0.5f + ( size.x / ( m_SpacingRadius * 2.0f ) );
|
||||||
|
m_yCount = 0.5f + ( size.y / ( m_SpacingRadius * 2.0f ) );
|
||||||
|
m_zCount = 0.5f + ( size.z / ( m_SpacingRadius * 2.0f ) );
|
||||||
|
m_CurrentDensity = m_Density;
|
||||||
|
|
||||||
|
delete [] m_pSmokeParticleInfos;
|
||||||
|
m_pSmokeParticleInfos = new SmokeParticleInfo[m_xCount * m_yCount * m_zCount];
|
||||||
|
Start( ParticleMgr(), NULL );
|
||||||
|
}
|
||||||
|
BaseClass::OnDataChanged( updateType );
|
||||||
|
}
|
||||||
|
|
||||||
|
void C_FuncSmokeVolume::Start( CParticleMgr *pParticleMgr, IPrototypeArgAccess *pArgs )
|
||||||
|
{
|
||||||
|
if( !pParticleMgr->AddEffect( &m_ParticleEffect, this ) )
|
||||||
|
return;
|
||||||
|
|
||||||
|
m_MaterialHandle = m_ParticleEffect.FindOrAddMaterial( m_MaterialName );
|
||||||
|
FillVolume();
|
||||||
|
|
||||||
|
m_bStarted = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void C_FuncSmokeVolume::Update( float fTimeDelta )
|
||||||
|
{
|
||||||
|
// Update our world space bbox if we've moved at all.
|
||||||
|
// We do this manually because sometimes people make HUGE bboxes, and if they're constantly changing because their
|
||||||
|
// particles wander outside the current bounds sometimes, it'll be linking them into all the leaves repeatedly.
|
||||||
|
const Vector &curOrigin = GetAbsOrigin();
|
||||||
|
const QAngle &curAngles = GetAbsAngles();
|
||||||
|
if ( !VectorsAreEqual( curOrigin, m_vLastOrigin, 0.1 ) ||
|
||||||
|
fabs( curAngles.x - m_vLastAngles.x ) > 0.1 ||
|
||||||
|
fabs( curAngles.y - m_vLastAngles.y ) > 0.1 ||
|
||||||
|
fabs( curAngles.z - m_vLastAngles.z ) > 0.1 ||
|
||||||
|
m_bFirstUpdate )
|
||||||
|
{
|
||||||
|
m_bFirstUpdate = false;
|
||||||
|
m_vLastAngles = curAngles;
|
||||||
|
m_vLastOrigin = curOrigin;
|
||||||
|
|
||||||
|
Vector vWorldMins, vWorldMaxs;
|
||||||
|
CollisionProp()->WorldSpaceAABB( &vWorldMins, &vWorldMaxs );
|
||||||
|
vWorldMins -= Vector( m_ParticleRadius, m_ParticleRadius, m_ParticleRadius );
|
||||||
|
vWorldMaxs += Vector( m_ParticleRadius, m_ParticleRadius, m_ParticleRadius );
|
||||||
|
|
||||||
|
m_ParticleEffect.SetBBox( vWorldMins, vWorldMaxs );
|
||||||
|
}
|
||||||
|
|
||||||
|
// lerp m_CurrentDensity towards m_Density at a rate of m_DensityRampSpeed
|
||||||
|
if( m_CurrentDensity < m_Density )
|
||||||
|
{
|
||||||
|
m_CurrentDensity += m_DensityRampSpeed * fTimeDelta;
|
||||||
|
if( m_CurrentDensity > m_Density )
|
||||||
|
{
|
||||||
|
m_CurrentDensity = m_Density;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else if( m_CurrentDensity > m_Density )
|
||||||
|
{
|
||||||
|
m_CurrentDensity -= m_DensityRampSpeed * fTimeDelta;
|
||||||
|
if( m_CurrentDensity < m_Density )
|
||||||
|
{
|
||||||
|
m_CurrentDensity = m_Density;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if( m_CurrentDensity == 0.0f )
|
||||||
|
{
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
// This is used to randomize the direction it chooses to move a particle in.
|
||||||
|
|
||||||
|
int offsetLookup[3] = {-1,0,1};
|
||||||
|
|
||||||
|
float tradeDurationMax = m_ParticleSpacingDistance / ( m_MovementSpeed + 0.1f );
|
||||||
|
float tradeDurationMin = tradeDurationMax * 0.5f;
|
||||||
|
|
||||||
|
if ( IS_NAN( tradeDurationMax ) || IS_NAN( tradeDurationMin ) )
|
||||||
|
return;
|
||||||
|
|
||||||
|
// Warning( "tradeDuration: [%f,%f]\n", tradeDurationMin, tradeDurationMax );
|
||||||
|
|
||||||
|
// Update all the moving traders and establish new ones.
|
||||||
|
int nTotal = m_xCount * m_yCount * m_zCount;
|
||||||
|
for( int i=0; i < nTotal; i++ )
|
||||||
|
{
|
||||||
|
SmokeParticleInfo *pInfo = &m_pSmokeParticleInfos[i];
|
||||||
|
|
||||||
|
if(!pInfo->m_pParticle)
|
||||||
|
continue;
|
||||||
|
|
||||||
|
if(pInfo->m_TradeIndex == -1)
|
||||||
|
{
|
||||||
|
pInfo->m_pParticle->m_FadeAlpha = pInfo->m_FadeAlpha;
|
||||||
|
pInfo->m_pParticle->m_Color[0] = pInfo->m_Color[0];
|
||||||
|
pInfo->m_pParticle->m_Color[1] = pInfo->m_Color[1];
|
||||||
|
pInfo->m_pParticle->m_Color[2] = pInfo->m_Color[2];
|
||||||
|
|
||||||
|
// Is there an adjacent one that's not trading?
|
||||||
|
int x, y, z;
|
||||||
|
GetParticleInfoXYZ(i, x, y, z);
|
||||||
|
|
||||||
|
int xCountOffset = rand();
|
||||||
|
int yCountOffset = rand();
|
||||||
|
int zCountOffset = rand();
|
||||||
|
|
||||||
|
bool bFound = false;
|
||||||
|
for(int xCount=0; xCount < 3 && !bFound; xCount++)
|
||||||
|
{
|
||||||
|
for(int yCount=0; yCount < 3 && !bFound; yCount++)
|
||||||
|
{
|
||||||
|
for(int zCount=0; zCount < 3; zCount++)
|
||||||
|
{
|
||||||
|
int testX = x + offsetLookup[(xCount+xCountOffset) % 3];
|
||||||
|
int testY = y + offsetLookup[(yCount+yCountOffset) % 3];
|
||||||
|
int testZ = z + offsetLookup[(zCount+zCountOffset) % 3];
|
||||||
|
|
||||||
|
if(testX == x && testY == y && testZ == z)
|
||||||
|
continue;
|
||||||
|
|
||||||
|
if(IsValidXYZCoords(testX, testY, testZ))
|
||||||
|
{
|
||||||
|
SmokeParticleInfo *pOther = GetSmokeParticleInfo(testX, testY, testZ);
|
||||||
|
if(pOther->m_pParticle && pOther->m_TradeIndex == -1)
|
||||||
|
{
|
||||||
|
// Ok, this one is looking to trade also.
|
||||||
|
pInfo->m_TradeIndex = GetSmokeParticleIndex(testX, testY, testZ);
|
||||||
|
pOther->m_TradeIndex = i;
|
||||||
|
pInfo->m_TradeClock = pOther->m_TradeClock = 0;
|
||||||
|
pOther->m_TradeDuration = pInfo->m_TradeDuration = FRand( tradeDurationMin, tradeDurationMax );
|
||||||
|
|
||||||
|
bFound = true;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
SmokeParticleInfo *pOther = &m_pSmokeParticleInfos[pInfo->m_TradeIndex];
|
||||||
|
assert(pOther->m_TradeIndex == i);
|
||||||
|
|
||||||
|
// This makes sure the trade only gets updated once per frame.
|
||||||
|
if(pInfo < pOther)
|
||||||
|
{
|
||||||
|
// Increment the trade clock..
|
||||||
|
pInfo->m_TradeClock = (pOther->m_TradeClock += fTimeDelta);
|
||||||
|
int x, y, z;
|
||||||
|
GetParticleInfoXYZ(i, x, y, z);
|
||||||
|
Vector myPos = GetSmokeParticlePos(x, y, z);
|
||||||
|
|
||||||
|
int otherX, otherY, otherZ;
|
||||||
|
GetParticleInfoXYZ(pInfo->m_TradeIndex, otherX, otherY, otherZ);
|
||||||
|
Vector otherPos = GetSmokeParticlePos(otherX, otherY, otherZ);
|
||||||
|
|
||||||
|
// Is the trade finished?
|
||||||
|
if(pInfo->m_TradeClock >= pInfo->m_TradeDuration)
|
||||||
|
{
|
||||||
|
pInfo->m_TradeIndex = pOther->m_TradeIndex = -1;
|
||||||
|
|
||||||
|
pInfo->m_pParticle->m_Pos = otherPos;
|
||||||
|
pOther->m_pParticle->m_Pos = myPos;
|
||||||
|
|
||||||
|
SmokeGrenadeParticle *temp = pInfo->m_pParticle;
|
||||||
|
pInfo->m_pParticle = pOther->m_pParticle;
|
||||||
|
pOther->m_pParticle = temp;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
// Ok, move them closer.
|
||||||
|
float percent = (float)cos(pInfo->m_TradeClock * 2 * 1.57079632f / pInfo->m_TradeDuration);
|
||||||
|
percent = percent * 0.5 + 0.5;
|
||||||
|
|
||||||
|
pInfo->m_pParticle->m_FadeAlpha = pInfo->m_FadeAlpha + (pOther->m_FadeAlpha - pInfo->m_FadeAlpha) * (1 - percent);
|
||||||
|
pOther->m_pParticle->m_FadeAlpha = pInfo->m_FadeAlpha + (pOther->m_FadeAlpha - pInfo->m_FadeAlpha) * percent;
|
||||||
|
|
||||||
|
InterpColor(pInfo->m_pParticle->m_Color, pInfo->m_Color, pOther->m_Color, 1-percent);
|
||||||
|
InterpColor(pOther->m_pParticle->m_Color, pInfo->m_Color, pOther->m_Color, percent);
|
||||||
|
|
||||||
|
pInfo->m_pParticle->m_Pos = myPos + (otherPos - myPos) * (1 - percent);
|
||||||
|
pOther->m_pParticle->m_Pos = myPos + (otherPos - myPos) * percent;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void C_FuncSmokeVolume::RenderParticles( CParticleRenderIterator *pIterator )
|
||||||
|
{
|
||||||
|
if ( m_CurrentDensity == 0 )
|
||||||
|
return;
|
||||||
|
|
||||||
|
const SmokeGrenadeParticle *pParticle = (const SmokeGrenadeParticle*)pIterator->GetFirst();
|
||||||
|
while ( pParticle )
|
||||||
|
{
|
||||||
|
Vector renderPos = pParticle->m_Pos;
|
||||||
|
|
||||||
|
// Fade out globally.
|
||||||
|
float alpha = m_CurrentDensity;
|
||||||
|
|
||||||
|
// Apply the precalculated fade alpha from world geometry.
|
||||||
|
alpha *= pParticle->m_FadeAlpha;
|
||||||
|
|
||||||
|
// TODO: optimize this whole routine!
|
||||||
|
Vector color = m_MinColor + (m_MaxColor - m_MinColor) * (pParticle->m_ColorInterp / 255.1f);
|
||||||
|
if ( IsEmissive() )
|
||||||
|
{
|
||||||
|
color.x += pParticle->m_Color[0] / 255.0f;
|
||||||
|
color.y += pParticle->m_Color[1] / 255.0f;
|
||||||
|
color.z += pParticle->m_Color[2] / 255.0f;
|
||||||
|
|
||||||
|
color.x = clamp( color.x, 0.0f, 1.0f );
|
||||||
|
color.y = clamp( color.y, 0.0f, 1.0f );
|
||||||
|
color.z = clamp( color.z, 0.0f, 1.0f );
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
color.x *= pParticle->m_Color[0] / 255.0f;
|
||||||
|
color.y *= pParticle->m_Color[1] / 255.0f;
|
||||||
|
color.z *= pParticle->m_Color[2] / 255.0f;
|
||||||
|
}
|
||||||
|
|
||||||
|
Vector tRenderPos;
|
||||||
|
TransformParticle( ParticleMgr()->GetModelView(), renderPos, tRenderPos );
|
||||||
|
float sortKey = 1;//tRenderPos.z;
|
||||||
|
|
||||||
|
RenderParticle_ColorSizeAngle(
|
||||||
|
pIterator->GetParticleDraw(),
|
||||||
|
tRenderPos,
|
||||||
|
color,
|
||||||
|
alpha * GetAlphaDistanceFade(tRenderPos, 10, 30), // Alpha
|
||||||
|
m_ParticleRadius,
|
||||||
|
pParticle->m_CurRotation
|
||||||
|
);
|
||||||
|
|
||||||
|
pParticle = (const SmokeGrenadeParticle*)pIterator->GetNext( sortKey );
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void C_FuncSmokeVolume::SimulateParticles( CParticleSimulateIterator *pIterator )
|
||||||
|
{
|
||||||
|
if ( m_CurrentDensity == 0 )
|
||||||
|
return;
|
||||||
|
|
||||||
|
SmokeGrenadeParticle *pParticle = (SmokeGrenadeParticle*)pIterator->GetFirst();
|
||||||
|
while ( pParticle )
|
||||||
|
{
|
||||||
|
pParticle->m_CurRotation += pParticle->m_RotationFactor * ( M_PI / 180.0f ) * m_RotationSpeed * pIterator->GetTimeDelta();
|
||||||
|
pParticle = (SmokeGrenadeParticle*)pIterator->GetNext();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void C_FuncSmokeVolume::NotifyRemove()
|
||||||
|
{
|
||||||
|
m_xCount = m_yCount = m_zCount = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void C_FuncSmokeVolume::FillVolume()
|
||||||
|
{
|
||||||
|
Vector vPos;
|
||||||
|
for(int x=0; x < m_xCount; x++)
|
||||||
|
{
|
||||||
|
for(int y=0; y < m_yCount; y++)
|
||||||
|
{
|
||||||
|
for(int z=0; z < m_zCount; z++)
|
||||||
|
{
|
||||||
|
vPos = GetSmokeParticlePos( x, y, z );
|
||||||
|
if(SmokeParticleInfo *pInfo = GetSmokeParticleInfo(x,y,z))
|
||||||
|
{
|
||||||
|
int contents = GetWorldPointContents(vPos);
|
||||||
|
if(contents & CONTENTS_SOLID)
|
||||||
|
{
|
||||||
|
pInfo->m_pParticle = NULL;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
SmokeGrenadeParticle *pParticle =
|
||||||
|
(SmokeGrenadeParticle*)m_ParticleEffect.AddParticle(sizeof(SmokeGrenadeParticle), m_MaterialHandle);
|
||||||
|
|
||||||
|
if(pParticle)
|
||||||
|
{
|
||||||
|
pParticle->m_Pos = vPos;
|
||||||
|
pParticle->m_ColorInterp = (unsigned char)((rand() * 255) / RAND_MAX);
|
||||||
|
pParticle->m_RotationFactor = FRand( -1.0f, 1.0f ); // Rotation factor.
|
||||||
|
pParticle->m_CurRotation = FRand( -m_RotationSpeed, m_RotationSpeed );
|
||||||
|
}
|
||||||
|
|
||||||
|
#ifdef _DEBUG
|
||||||
|
int testX, testY, testZ;
|
||||||
|
int index = GetSmokeParticleIndex(x,y,z);
|
||||||
|
GetParticleInfoXYZ(index, testX, testY, testZ);
|
||||||
|
assert(testX == x && testY == y && testZ == z);
|
||||||
|
#endif
|
||||||
|
|
||||||
|
Vector vColor = EngineGetLightForPoint(vPos);
|
||||||
|
pInfo->m_Color[0] = LinearToTexture( vColor.x );
|
||||||
|
pInfo->m_Color[1] = LinearToTexture( vColor.y );
|
||||||
|
pInfo->m_Color[2] = LinearToTexture( vColor.z );
|
||||||
|
|
||||||
|
// Cast some rays and if it's too close to anything, fade its alpha down.
|
||||||
|
pInfo->m_FadeAlpha = 1;
|
||||||
|
|
||||||
|
for(int i=0; i < NUM_FADE_PLANES; i++)
|
||||||
|
{
|
||||||
|
trace_t trace;
|
||||||
|
WorldTraceLine(vPos, vPos + s_FadePlaneDirections[i] * 100, MASK_SOLID_BRUSHONLY, &trace);
|
||||||
|
if(trace.fraction < 1.0f)
|
||||||
|
{
|
||||||
|
float dist = DotProduct(trace.plane.normal, vPos) - trace.plane.dist;
|
||||||
|
if(dist < 0)
|
||||||
|
{
|
||||||
|
pInfo->m_FadeAlpha = 0;
|
||||||
|
}
|
||||||
|
else if(dist < m_ParticleRadius)
|
||||||
|
{
|
||||||
|
float alphaScale = dist / m_ParticleRadius;
|
||||||
|
alphaScale *= alphaScale * alphaScale;
|
||||||
|
pInfo->m_FadeAlpha *= alphaScale;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
pInfo->m_pParticle = pParticle;
|
||||||
|
pInfo->m_TradeIndex = -1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
119
cl_dll/c_func_tracktrain.cpp
Normal file
119
cl_dll/c_func_tracktrain.cpp
Normal file
@ -0,0 +1,119 @@
|
|||||||
|
//========= Copyright © 1996-2005, Valve Corporation, All rights reserved. ============//
|
||||||
|
//
|
||||||
|
// Purpose:
|
||||||
|
//
|
||||||
|
// $NoKeywords: $
|
||||||
|
//=============================================================================//
|
||||||
|
|
||||||
|
#include "cbase.h"
|
||||||
|
#include "c_baseentity.h"
|
||||||
|
#include "soundinfo.h"
|
||||||
|
|
||||||
|
// memdbgon must be the last include file in a .cpp file!!!
|
||||||
|
#include "tier0/memdbgon.h"
|
||||||
|
|
||||||
|
//-----------------------------------------------------------------------------
|
||||||
|
// An entity which emits other entities at points
|
||||||
|
//-----------------------------------------------------------------------------
|
||||||
|
class C_FuncTrackTrain : public C_BaseEntity
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
DECLARE_CLASS( C_FuncTrackTrain, C_BaseEntity );
|
||||||
|
DECLARE_CLIENTCLASS();
|
||||||
|
|
||||||
|
public:
|
||||||
|
virtual void OnDataChanged( DataUpdateType_t updateType );
|
||||||
|
virtual bool GetSoundSpatialization( SpatializationInfo_t& info );
|
||||||
|
|
||||||
|
private:
|
||||||
|
int m_nLongAxis;
|
||||||
|
float m_flRadius;
|
||||||
|
float m_flLineLength;
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
//-----------------------------------------------------------------------------
|
||||||
|
// Datatable
|
||||||
|
//-----------------------------------------------------------------------------
|
||||||
|
IMPLEMENT_CLIENTCLASS_DT( C_FuncTrackTrain, DT_FuncTrackTrain, CFuncTrackTrain )
|
||||||
|
END_RECV_TABLE()
|
||||||
|
|
||||||
|
|
||||||
|
//-----------------------------------------------------------------------------
|
||||||
|
// Sound spatialization
|
||||||
|
//-----------------------------------------------------------------------------
|
||||||
|
void C_FuncTrackTrain::OnDataChanged( DataUpdateType_t updateType )
|
||||||
|
{
|
||||||
|
BaseClass::OnDataChanged( updateType );
|
||||||
|
|
||||||
|
if (updateType == DATA_UPDATE_CREATED)
|
||||||
|
{
|
||||||
|
// Compute the cross-sectional area and dimension and length of the line segment
|
||||||
|
int nIndex1, nIndex2;
|
||||||
|
const Vector &vecOBBSize = CollisionProp()->OBBSize();
|
||||||
|
if ( ( vecOBBSize.x > vecOBBSize.y ) && ( vecOBBSize.x > vecOBBSize.z ) )
|
||||||
|
{
|
||||||
|
m_nLongAxis = 0;
|
||||||
|
nIndex1 = 1; nIndex2 = 2;
|
||||||
|
}
|
||||||
|
else if ( vecOBBSize.y > vecOBBSize.z )
|
||||||
|
{
|
||||||
|
m_nLongAxis = 1;
|
||||||
|
nIndex1 = 0; nIndex2 = 2;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
m_nLongAxis = 2;
|
||||||
|
nIndex1 = 0; nIndex2 = 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
m_flRadius = sqrt( vecOBBSize[nIndex1] * vecOBBSize[nIndex1] + vecOBBSize[nIndex2] * vecOBBSize[nIndex2] ) * 0.5f;
|
||||||
|
m_flLineLength = vecOBBSize[m_nLongAxis];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
//-----------------------------------------------------------------------------
|
||||||
|
// Sound spatialization
|
||||||
|
//-----------------------------------------------------------------------------
|
||||||
|
bool C_FuncTrackTrain::GetSoundSpatialization( SpatializationInfo_t& info )
|
||||||
|
{
|
||||||
|
// Out of PVS
|
||||||
|
if ( IsDormant() )
|
||||||
|
return false;
|
||||||
|
|
||||||
|
if ( info.pflRadius )
|
||||||
|
{
|
||||||
|
*info.pflRadius = m_flRadius;
|
||||||
|
}
|
||||||
|
|
||||||
|
if ( info.pOrigin )
|
||||||
|
{
|
||||||
|
Vector vecStart, vecEnd, vecWorldDir;
|
||||||
|
Vector vecDir = vec3_origin;
|
||||||
|
vecDir[m_nLongAxis] = 1.0f;
|
||||||
|
VectorRotate( vecDir, EntityToWorldTransform(), vecWorldDir );
|
||||||
|
VectorMA( WorldSpaceCenter(), -0.5f * m_flLineLength, vecWorldDir, vecStart );
|
||||||
|
VectorMA( vecStart, m_flLineLength, vecWorldDir, vecEnd );
|
||||||
|
|
||||||
|
float t;
|
||||||
|
CalcClosestPointOnLine( info.info.vListenerOrigin, vecStart, vecEnd, *info.pOrigin, &t );
|
||||||
|
if ( t < 0.0f )
|
||||||
|
{
|
||||||
|
*info.pOrigin = vecStart;
|
||||||
|
}
|
||||||
|
else if ( t > 1.0f )
|
||||||
|
{
|
||||||
|
*info.pOrigin = vecEnd;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if ( info.pAngles )
|
||||||
|
{
|
||||||
|
VectorCopy( CollisionProp()->GetCollisionAngles(), *info.pAngles );
|
||||||
|
}
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
133
cl_dll/c_gib.cpp
Normal file
133
cl_dll/c_gib.cpp
Normal file
@ -0,0 +1,133 @@
|
|||||||
|
//========= Copyright © 1996-2005, Valve Corporation, All rights reserved. ============//
|
||||||
|
//
|
||||||
|
// Purpose:
|
||||||
|
//
|
||||||
|
//=============================================================================//
|
||||||
|
|
||||||
|
#include "cbase.h"
|
||||||
|
#include "vcollide_parse.h"
|
||||||
|
#include "c_gib.h"
|
||||||
|
|
||||||
|
// memdbgon must be the last include file in a .cpp file!!!
|
||||||
|
#include "tier0/memdbgon.h"
|
||||||
|
|
||||||
|
//NOTENOTE: This is not yet coupled with the server-side implementation of CGib
|
||||||
|
// This is only a client-side version of gibs at the moment
|
||||||
|
|
||||||
|
//-----------------------------------------------------------------------------
|
||||||
|
// Purpose:
|
||||||
|
//-----------------------------------------------------------------------------
|
||||||
|
C_Gib::~C_Gib( void )
|
||||||
|
{
|
||||||
|
VPhysicsDestroyObject();
|
||||||
|
}
|
||||||
|
|
||||||
|
//-----------------------------------------------------------------------------
|
||||||
|
// Purpose:
|
||||||
|
// Input : *pszModelName -
|
||||||
|
// vecOrigin -
|
||||||
|
// vecForceDir -
|
||||||
|
// vecAngularImp -
|
||||||
|
// Output : Returns true on success, false on failure.
|
||||||
|
//-----------------------------------------------------------------------------
|
||||||
|
C_Gib *C_Gib::CreateClientsideGib( const char *pszModelName, Vector vecOrigin, Vector vecForceDir, AngularImpulse vecAngularImp, float flLifetime )
|
||||||
|
{
|
||||||
|
C_Gib *pGib = new C_Gib;
|
||||||
|
|
||||||
|
if ( pGib == NULL )
|
||||||
|
return NULL;
|
||||||
|
|
||||||
|
if ( pGib->InitializeGib( pszModelName, vecOrigin, vecForceDir, vecAngularImp, flLifetime ) == false )
|
||||||
|
return NULL;
|
||||||
|
|
||||||
|
return pGib;
|
||||||
|
}
|
||||||
|
|
||||||
|
//-----------------------------------------------------------------------------
|
||||||
|
// Purpose:
|
||||||
|
// Input : *pszModelName -
|
||||||
|
// vecOrigin -
|
||||||
|
// vecForceDir -
|
||||||
|
// vecAngularImp -
|
||||||
|
// Output : Returns true on success, false on failure.
|
||||||
|
//-----------------------------------------------------------------------------
|
||||||
|
bool C_Gib::InitializeGib( const char *pszModelName, Vector vecOrigin, Vector vecForceDir, AngularImpulse vecAngularImp, float flLifetime )
|
||||||
|
{
|
||||||
|
if ( InitializeAsClientEntity( pszModelName, RENDER_GROUP_OPAQUE_ENTITY ) == false )
|
||||||
|
{
|
||||||
|
Release();
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
SetAbsOrigin( vecOrigin );
|
||||||
|
SetCollisionGroup( COLLISION_GROUP_DEBRIS );
|
||||||
|
|
||||||
|
solid_t tmpSolid;
|
||||||
|
PhysModelParseSolid( tmpSolid, this, GetModelIndex() );
|
||||||
|
|
||||||
|
m_pPhysicsObject = VPhysicsInitNormal( SOLID_VPHYSICS, 0, false, &tmpSolid );
|
||||||
|
|
||||||
|
if ( m_pPhysicsObject )
|
||||||
|
{
|
||||||
|
float flForce = m_pPhysicsObject->GetMass();
|
||||||
|
vecForceDir *= flForce;
|
||||||
|
|
||||||
|
m_pPhysicsObject->ApplyForceOffset( vecForceDir, GetAbsOrigin() );
|
||||||
|
m_pPhysicsObject->SetCallbackFlags( m_pPhysicsObject->GetCallbackFlags() | CALLBACK_GLOBAL_TOUCH | CALLBACK_GLOBAL_TOUCH_STATIC );
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
// failed to create a physics object
|
||||||
|
Release();
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
SetNextClientThink( gpGlobals->curtime + flLifetime );
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
//-----------------------------------------------------------------------------
|
||||||
|
// Purpose:
|
||||||
|
//-----------------------------------------------------------------------------
|
||||||
|
void C_Gib::ClientThink( void )
|
||||||
|
{
|
||||||
|
SetRenderMode( kRenderTransAlpha );
|
||||||
|
m_nRenderFX = kRenderFxFadeFast;
|
||||||
|
|
||||||
|
if ( m_clrRender->a == 0 )
|
||||||
|
{
|
||||||
|
#ifdef HL2_CLIENT_DLL
|
||||||
|
s_AntlionGibManager.RemoveGib( this );
|
||||||
|
#endif
|
||||||
|
Release();
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
SetNextClientThink( gpGlobals->curtime + 1.0f );
|
||||||
|
}
|
||||||
|
|
||||||
|
//-----------------------------------------------------------------------------
|
||||||
|
// Purpose:
|
||||||
|
// Input : *pOther -
|
||||||
|
//-----------------------------------------------------------------------------
|
||||||
|
void C_Gib::StartTouch( C_BaseEntity *pOther )
|
||||||
|
{
|
||||||
|
// Limit the amount of times we can bounce
|
||||||
|
if ( m_flTouchDelta < gpGlobals->curtime )
|
||||||
|
{
|
||||||
|
HitSurface( pOther );
|
||||||
|
m_flTouchDelta = gpGlobals->curtime + 0.1f;
|
||||||
|
}
|
||||||
|
|
||||||
|
BaseClass::StartTouch( pOther );
|
||||||
|
}
|
||||||
|
|
||||||
|
//-----------------------------------------------------------------------------
|
||||||
|
// Purpose:
|
||||||
|
// Input : *pOther -
|
||||||
|
//-----------------------------------------------------------------------------
|
||||||
|
void C_Gib::HitSurface( C_BaseEntity *pOther )
|
||||||
|
{
|
||||||
|
//TODO: Implement splatter or effects in child versions
|
||||||
|
}
|
64
cl_dll/c_gib.h
Normal file
64
cl_dll/c_gib.h
Normal file
@ -0,0 +1,64 @@
|
|||||||
|
//========= Copyright © 1996-2005, Valve Corporation, All rights reserved. ============//
|
||||||
|
//
|
||||||
|
// Purpose:
|
||||||
|
//
|
||||||
|
//=============================================================================//
|
||||||
|
|
||||||
|
#ifndef C_GIB_H
|
||||||
|
#define C_GIB_H
|
||||||
|
#ifdef _WIN32
|
||||||
|
#pragma once
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#define DEFAULT_GIB_LIFETIME 4.0f
|
||||||
|
|
||||||
|
// Base client gibs
|
||||||
|
|
||||||
|
class C_Gib : public C_BaseAnimating
|
||||||
|
{
|
||||||
|
typedef C_BaseAnimating BaseClass;
|
||||||
|
public:
|
||||||
|
|
||||||
|
C_Gib::~C_Gib( void );
|
||||||
|
|
||||||
|
static C_Gib *CreateClientsideGib( const char *pszModelName, Vector vecOrigin, Vector vecForceDir, AngularImpulse vecAngularImp, float flLifetime = DEFAULT_GIB_LIFETIME );
|
||||||
|
|
||||||
|
bool InitializeGib( const char *pszModelName, Vector vecOrigin, Vector vecForceDir, AngularImpulse vecAngularImp, float flLifetime = DEFAULT_GIB_LIFETIME );
|
||||||
|
void ClientThink( void );
|
||||||
|
void StartTouch( C_BaseEntity *pOther );
|
||||||
|
|
||||||
|
virtual void HitSurface( C_BaseEntity *pOther );
|
||||||
|
|
||||||
|
protected:
|
||||||
|
|
||||||
|
float m_flTouchDelta; // Amount of time that must pass before another touch function can be called
|
||||||
|
};
|
||||||
|
|
||||||
|
#ifdef HL2_CLIENT_DLL
|
||||||
|
class CAntlionGibManager : public CAutoGameSystemPerFrame
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
CAntlionGibManager( char const *name ) : CAutoGameSystemPerFrame( name )
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
// Methods of IGameSystem
|
||||||
|
virtual void Update( float frametime );
|
||||||
|
virtual void LevelInitPreEntity( void );
|
||||||
|
|
||||||
|
void AddGib( C_BaseEntity *pEntity );
|
||||||
|
void RemoveGib( C_BaseEntity *pEntity );
|
||||||
|
|
||||||
|
private:
|
||||||
|
typedef CHandle<C_BaseEntity> CGibHandle;
|
||||||
|
CUtlLinkedList< CGibHandle > m_LRU;
|
||||||
|
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
extern CAntlionGibManager s_AntlionGibManager;
|
||||||
|
|
||||||
|
#endif
|
||||||
|
|
||||||
|
|
||||||
|
#endif // C_GIB_H
|
349
cl_dll/c_hairball.cpp
Normal file
349
cl_dll/c_hairball.cpp
Normal file
@ -0,0 +1,349 @@
|
|||||||
|
//========= Copyright © 1996-2005, Valve Corporation, All rights reserved. ============//
|
||||||
|
//
|
||||||
|
// Purpose:
|
||||||
|
//
|
||||||
|
// $NoKeywords: $
|
||||||
|
//=============================================================================//
|
||||||
|
#include "cbase.h"
|
||||||
|
#include "simple_physics.h"
|
||||||
|
#include "vmatrix.h"
|
||||||
|
#include "beamdraw.h"
|
||||||
|
|
||||||
|
// memdbgon must be the last include file in a .cpp file!!!
|
||||||
|
#include "tier0/memdbgon.h"
|
||||||
|
|
||||||
|
class C_Hairball : public C_BaseEntity
|
||||||
|
{
|
||||||
|
DECLARE_CLASS( C_Hairball, C_BaseEntity );
|
||||||
|
private:
|
||||||
|
|
||||||
|
class CHairballDelegate : public CSimplePhysics::IHelper
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
virtual void GetNodeForces( CSimplePhysics::CNode *pNodes, int iNode, Vector *pAccel );
|
||||||
|
virtual void ApplyConstraints( CSimplePhysics::CNode *pNodes, int nNodes );
|
||||||
|
|
||||||
|
C_Hairball *m_pParent;
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
public:
|
||||||
|
|
||||||
|
C_Hairball();
|
||||||
|
|
||||||
|
void Init();
|
||||||
|
|
||||||
|
|
||||||
|
// IClientThinkable.
|
||||||
|
public:
|
||||||
|
|
||||||
|
virtual void ClientThink();
|
||||||
|
|
||||||
|
|
||||||
|
// IClientRenderable.
|
||||||
|
public:
|
||||||
|
|
||||||
|
virtual int DrawModel( int flags );
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
public:
|
||||||
|
|
||||||
|
float m_flSphereRadius;
|
||||||
|
|
||||||
|
int m_nHairs;
|
||||||
|
int m_nNodesPerHair;
|
||||||
|
float m_flSpringDist; // = hair length / (m_nNodesPerHair-1)
|
||||||
|
|
||||||
|
CUtlVector<CSimplePhysics::CNode> m_Nodes; // This is m_nHairs * m_nNodesPerHair large.
|
||||||
|
CUtlVector<Vector> m_HairPositions; // Untransformed base hair positions, distributed on the sphere.
|
||||||
|
CUtlVector<Vector> m_TransformedHairPositions; // Transformed base hair positions, distributed on the sphere.
|
||||||
|
|
||||||
|
CHairballDelegate m_Delegate;
|
||||||
|
CSimplePhysics m_Physics;
|
||||||
|
|
||||||
|
IMaterial *m_pMaterial;
|
||||||
|
|
||||||
|
|
||||||
|
// Super sophisticated AI.
|
||||||
|
float m_flSitStillTime;
|
||||||
|
Vector m_vMoveDir;
|
||||||
|
|
||||||
|
float m_flSpinDuration;
|
||||||
|
float m_flCurSpinTime;
|
||||||
|
float m_flSpinRateX, m_flSpinRateY;
|
||||||
|
|
||||||
|
bool m_bFirstThink;
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
void C_Hairball::CHairballDelegate::GetNodeForces( CSimplePhysics::CNode *pNodes, int iNode, Vector *pAccel )
|
||||||
|
{
|
||||||
|
pAccel->Init( 0, 0, -1500 );
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void C_Hairball::CHairballDelegate::ApplyConstraints( CSimplePhysics::CNode *pNodes, int nNodes )
|
||||||
|
{
|
||||||
|
int nSegments = m_pParent->m_nNodesPerHair - 1;
|
||||||
|
float flSpringDistSqr = m_pParent->m_flSpringDist * m_pParent->m_flSpringDist;
|
||||||
|
|
||||||
|
static int nIterations = 1;
|
||||||
|
for( int iIteration=0; iIteration < nIterations; iIteration++ )
|
||||||
|
{
|
||||||
|
for ( int iHair=0; iHair < m_pParent->m_nHairs; iHair++ )
|
||||||
|
{
|
||||||
|
CSimplePhysics::CNode *pBase = &pNodes[iHair * m_pParent->m_nNodesPerHair];
|
||||||
|
|
||||||
|
for( int i=0; i < nSegments; i++ )
|
||||||
|
{
|
||||||
|
Vector &vNode1 = pBase[i].m_vPos;
|
||||||
|
Vector &vNode2 = pBase[i+1].m_vPos;
|
||||||
|
Vector vTo = vNode1 - vNode2;
|
||||||
|
|
||||||
|
float flDistSqr = vTo.LengthSqr();
|
||||||
|
if( flDistSqr > flSpringDistSqr )
|
||||||
|
{
|
||||||
|
float flDist = (float)sqrt( flDistSqr );
|
||||||
|
vTo *= 1 - (m_pParent->m_flSpringDist / flDist);
|
||||||
|
|
||||||
|
vNode1 -= vTo * 0.5f;
|
||||||
|
vNode2 += vTo * 0.5f;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Lock the base of each hair to the right spot.
|
||||||
|
pBase->m_vPos = m_pParent->m_TransformedHairPositions[iHair];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
C_Hairball::C_Hairball()
|
||||||
|
{
|
||||||
|
m_nHairs = 100;
|
||||||
|
m_nNodesPerHair = 3;
|
||||||
|
|
||||||
|
float flHairLength = 20;
|
||||||
|
m_flSpringDist = flHairLength / (m_nNodesPerHair - 1);
|
||||||
|
|
||||||
|
m_Nodes.SetSize( m_nHairs * m_nNodesPerHair );
|
||||||
|
m_HairPositions.SetSize( m_nHairs );
|
||||||
|
m_TransformedHairPositions.SetSize( m_nHairs );
|
||||||
|
|
||||||
|
m_flSphereRadius = 20;
|
||||||
|
m_vMoveDir.Init();
|
||||||
|
|
||||||
|
m_flSpinDuration = 1;
|
||||||
|
m_flCurSpinTime = 0;
|
||||||
|
m_flSpinRateX = m_flSpinRateY = 0;
|
||||||
|
|
||||||
|
// Distribute on the sphere (need a better random distribution for the sphere).
|
||||||
|
for ( int i=0; i < m_HairPositions.Count(); i++ )
|
||||||
|
{
|
||||||
|
float theta = RandomFloat( -M_PI, M_PI );
|
||||||
|
float phi = RandomFloat( -M_PI/2, M_PI/2 );
|
||||||
|
|
||||||
|
float cosPhi = cos( phi );
|
||||||
|
|
||||||
|
m_HairPositions[i].Init(
|
||||||
|
cos(theta) * cosPhi * m_flSphereRadius,
|
||||||
|
sin(theta) * cosPhi * m_flSphereRadius,
|
||||||
|
sin(phi) * m_flSphereRadius );
|
||||||
|
}
|
||||||
|
|
||||||
|
m_Delegate.m_pParent = this;
|
||||||
|
|
||||||
|
m_Physics.Init( 1.0 / 20 ); // NOTE: PLAY WITH THIS FOR EFFICIENCY
|
||||||
|
m_pMaterial = NULL;
|
||||||
|
|
||||||
|
m_bFirstThink = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void C_Hairball::Init()
|
||||||
|
{
|
||||||
|
ClientEntityList().AddNonNetworkableEntity( this );
|
||||||
|
ClientThinkList()->SetNextClientThink( GetClientHandle(), CLIENT_THINK_ALWAYS );
|
||||||
|
|
||||||
|
AddToLeafSystem( RENDER_GROUP_OPAQUE_ENTITY );
|
||||||
|
|
||||||
|
m_pMaterial = materials->FindMaterial( "cable/cable", TEXTURE_GROUP_OTHER );
|
||||||
|
m_flSitStillTime = 5;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void C_Hairball::ClientThink()
|
||||||
|
{
|
||||||
|
// Do some AI-type stuff.. move the entity around.
|
||||||
|
//C_BasePlayer *pPlayer = C_BasePlayer::GetLocalPlayer();
|
||||||
|
//m_vecAngles = SetAbsAngles( pPlayer->GetAbsAngles() ); // copy player angles.
|
||||||
|
|
||||||
|
Assert( !GetMoveParent() );
|
||||||
|
|
||||||
|
// Sophisticated AI.
|
||||||
|
m_flCurSpinTime += gpGlobals->frametime;
|
||||||
|
if ( m_flCurSpinTime < m_flSpinDuration )
|
||||||
|
{
|
||||||
|
float div = m_flCurSpinTime / m_flSpinDuration;
|
||||||
|
|
||||||
|
QAngle angles = GetLocalAngles();
|
||||||
|
|
||||||
|
angles.x += m_flSpinRateX * SmoothCurve( div );
|
||||||
|
angles.y += m_flSpinRateY * SmoothCurve( div );
|
||||||
|
|
||||||
|
SetLocalAngles( angles );
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
// Flip between stopped and starting.
|
||||||
|
if ( fabs( m_flSpinRateX ) > 0.01f )
|
||||||
|
{
|
||||||
|
m_flSpinRateX = m_flSpinRateY = 0;
|
||||||
|
|
||||||
|
m_flSpinDuration = RandomFloat( 1, 2 );
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
static float flXSpeed = 3;
|
||||||
|
static float flYSpeed = flXSpeed * 0.1f;
|
||||||
|
m_flSpinRateX = RandomFloat( -M_PI*flXSpeed, M_PI*flXSpeed );
|
||||||
|
m_flSpinRateY = RandomFloat( -M_PI*flYSpeed, M_PI*flYSpeed );
|
||||||
|
|
||||||
|
m_flSpinDuration = RandomFloat( 1, 4 );
|
||||||
|
}
|
||||||
|
|
||||||
|
m_flCurSpinTime = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
if ( m_flSitStillTime > 0 )
|
||||||
|
{
|
||||||
|
m_flSitStillTime -= gpGlobals->frametime;
|
||||||
|
|
||||||
|
if ( m_flSitStillTime <= 0 )
|
||||||
|
{
|
||||||
|
// Shoot out some random lines and find the longest one.
|
||||||
|
m_vMoveDir.Init( 1, 0, 0 );
|
||||||
|
float flLongestFraction = 0;
|
||||||
|
for ( int i=0; i < 15; i++ )
|
||||||
|
{
|
||||||
|
Vector vDir( RandomFloat( -1, 1 ), RandomFloat( -1, 1 ), RandomFloat( -1, 1 ) );
|
||||||
|
VectorNormalize( vDir );
|
||||||
|
|
||||||
|
trace_t trace;
|
||||||
|
UTIL_TraceLine( GetAbsOrigin(), GetAbsOrigin() + vDir * 10000, MASK_SOLID, NULL, COLLISION_GROUP_NONE, &trace );
|
||||||
|
|
||||||
|
if ( trace.fraction != 1.0 )
|
||||||
|
{
|
||||||
|
if ( trace.fraction > flLongestFraction )
|
||||||
|
{
|
||||||
|
flLongestFraction = trace.fraction;
|
||||||
|
m_vMoveDir = vDir;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
m_vMoveDir *= 650; // set speed.
|
||||||
|
m_flSitStillTime = -1; // Move in this direction..
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
// Move in the specified direction.
|
||||||
|
Vector vEnd = GetAbsOrigin() + m_vMoveDir * gpGlobals->frametime;
|
||||||
|
|
||||||
|
trace_t trace;
|
||||||
|
UTIL_TraceLine( GetAbsOrigin(), vEnd, MASK_SOLID, NULL, COLLISION_GROUP_NONE, &trace );
|
||||||
|
|
||||||
|
if ( trace.fraction < 1 )
|
||||||
|
{
|
||||||
|
// Ok, stop moving.
|
||||||
|
m_flSitStillTime = RandomFloat( 1, 3 );
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
SetLocalOrigin( GetLocalOrigin() + m_vMoveDir * gpGlobals->frametime );
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
// Transform the base hair positions so we can lock them down.
|
||||||
|
VMatrix mTransform;
|
||||||
|
mTransform.SetupMatrixOrgAngles( GetLocalOrigin(), GetLocalAngles() );
|
||||||
|
|
||||||
|
for ( int i=0; i < m_HairPositions.Count(); i++ )
|
||||||
|
{
|
||||||
|
Vector3DMultiplyPosition( mTransform, m_HairPositions[i], m_TransformedHairPositions[i] );
|
||||||
|
}
|
||||||
|
|
||||||
|
if ( m_bFirstThink )
|
||||||
|
{
|
||||||
|
m_bFirstThink = false;
|
||||||
|
for ( int i=0; i < m_HairPositions.Count(); i++ )
|
||||||
|
{
|
||||||
|
for ( int j=0; j < m_nNodesPerHair; j++ )
|
||||||
|
{
|
||||||
|
m_Nodes[i*m_nNodesPerHair+j].Init( m_TransformedHairPositions[i] );
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Simulate the physics and apply constraints.
|
||||||
|
m_Physics.Simulate( m_Nodes.Base(), m_Nodes.Count(), &m_Delegate, gpGlobals->frametime, 0.98 );
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
int C_Hairball::DrawModel( int flags )
|
||||||
|
{
|
||||||
|
if ( !m_pMaterial )
|
||||||
|
return 0;
|
||||||
|
|
||||||
|
for ( int iHair=0; iHair < m_nHairs; iHair++ )
|
||||||
|
{
|
||||||
|
CSimplePhysics::CNode *pBase = &m_Nodes[iHair * m_nNodesPerHair];
|
||||||
|
|
||||||
|
CBeamSegDraw beamDraw;
|
||||||
|
beamDraw.Start( m_nNodesPerHair-1, m_pMaterial );
|
||||||
|
|
||||||
|
for ( int i=0; i < m_nNodesPerHair; i++ )
|
||||||
|
{
|
||||||
|
CBeamSeg seg;
|
||||||
|
seg.m_vPos = pBase[i].m_vPredicted;
|
||||||
|
seg.m_vColor.Init( 0, 0, 0 );
|
||||||
|
seg.m_flTexCoord = 0;
|
||||||
|
static float flHairWidth = 1;
|
||||||
|
seg.m_flWidth = flHairWidth;
|
||||||
|
seg.m_flAlpha = 0;
|
||||||
|
|
||||||
|
beamDraw.NextSeg( &seg );
|
||||||
|
}
|
||||||
|
|
||||||
|
beamDraw.End();
|
||||||
|
}
|
||||||
|
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void CreateHairballCallback()
|
||||||
|
{
|
||||||
|
for ( int i=0; i < 20; i++ )
|
||||||
|
{
|
||||||
|
C_Hairball *pHairball = new C_Hairball;
|
||||||
|
pHairball->Init();
|
||||||
|
|
||||||
|
// Put it a short distance in front of the player.
|
||||||
|
C_BasePlayer *pPlayer = C_BasePlayer::GetLocalPlayer();
|
||||||
|
|
||||||
|
if ( !pPlayer )
|
||||||
|
return;
|
||||||
|
|
||||||
|
Vector vForward;
|
||||||
|
AngleVectors( pPlayer->GetAbsAngles(), &vForward );
|
||||||
|
pHairball->SetLocalOrigin( pPlayer->GetAbsOrigin() + vForward * 300 + RandomVector( 0, 100 ) );
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
ConCommand cc_CreateHairball( "CreateHairball", CreateHairballCallback, 0, FCVAR_CHEAT );
|
||||||
|
|
1416
cl_dll/c_impact_effects.cpp
Normal file
1416
cl_dll/c_impact_effects.cpp
Normal file
File diff suppressed because it is too large
Load Diff
108
cl_dll/c_impact_effects.h
Normal file
108
cl_dll/c_impact_effects.h
Normal file
@ -0,0 +1,108 @@
|
|||||||
|
//========= Copyright © 1996-2005, Valve Corporation, All rights reserved. ============//
|
||||||
|
//
|
||||||
|
// Purpose:
|
||||||
|
//
|
||||||
|
//=============================================================================//
|
||||||
|
|
||||||
|
#ifndef C_IMPACT_EFFECTS_H
|
||||||
|
#define C_IMPACT_EFFECTS_H
|
||||||
|
#ifdef _WIN32
|
||||||
|
#pragma once
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#include "tier0/memdbgon.h"
|
||||||
|
|
||||||
|
//-----------------------------------------------------------------------------
|
||||||
|
// Purpose: DustParticle emitter
|
||||||
|
//-----------------------------------------------------------------------------
|
||||||
|
class CDustParticle : public CSimpleEmitter
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
|
||||||
|
CDustParticle( const char *pDebugName ) : CSimpleEmitter( pDebugName ) {}
|
||||||
|
|
||||||
|
//Create
|
||||||
|
static CDustParticle *Create( const char *pDebugName="dust" )
|
||||||
|
{
|
||||||
|
return new CDustParticle( pDebugName );
|
||||||
|
}
|
||||||
|
|
||||||
|
//Roll
|
||||||
|
virtual float UpdateRoll( SimpleParticle *pParticle, float timeDelta )
|
||||||
|
{
|
||||||
|
pParticle->m_flRoll += pParticle->m_flRollDelta * timeDelta;
|
||||||
|
|
||||||
|
pParticle->m_flRollDelta += pParticle->m_flRollDelta * ( timeDelta * -8.0f );
|
||||||
|
|
||||||
|
#ifdef _XBOX
|
||||||
|
//Cap the minimum roll
|
||||||
|
if ( fabs( pParticle->m_flRollDelta ) < 0.1f )
|
||||||
|
{
|
||||||
|
pParticle->m_flRollDelta = ( pParticle->m_flRollDelta > 0.0f ) ? 0.1f : -0.1f;
|
||||||
|
}
|
||||||
|
#else
|
||||||
|
if ( fabs( pParticle->m_flRollDelta ) < 0.5f )
|
||||||
|
{
|
||||||
|
pParticle->m_flRollDelta = ( pParticle->m_flRollDelta > 0.0f ) ? 0.5f : -0.5f;
|
||||||
|
}
|
||||||
|
#endif // _XBOX
|
||||||
|
|
||||||
|
return pParticle->m_flRoll;
|
||||||
|
}
|
||||||
|
|
||||||
|
//Velocity
|
||||||
|
virtual void UpdateVelocity( SimpleParticle *pParticle, float timeDelta )
|
||||||
|
{
|
||||||
|
Vector saveVelocity = pParticle->m_vecVelocity;
|
||||||
|
|
||||||
|
//Decellerate
|
||||||
|
static float dtime;
|
||||||
|
static float decay;
|
||||||
|
|
||||||
|
if ( dtime != timeDelta )
|
||||||
|
{
|
||||||
|
dtime = timeDelta;
|
||||||
|
float expected = 0.5;
|
||||||
|
decay = exp( log( 0.0001f ) * dtime / expected );
|
||||||
|
}
|
||||||
|
|
||||||
|
pParticle->m_vecVelocity = pParticle->m_vecVelocity * decay;
|
||||||
|
|
||||||
|
#ifdef _XBOX
|
||||||
|
//Cap the minimum speed
|
||||||
|
if ( pParticle->m_vecVelocity.LengthSqr() < (8.0f*8.0f) )
|
||||||
|
{
|
||||||
|
VectorNormalize( saveVelocity );
|
||||||
|
pParticle->m_vecVelocity = saveVelocity * 8.0f;
|
||||||
|
}
|
||||||
|
#else
|
||||||
|
if ( pParticle->m_vecVelocity.LengthSqr() < (32.0f*32.0f) )
|
||||||
|
{
|
||||||
|
VectorNormalize( saveVelocity );
|
||||||
|
pParticle->m_vecVelocity = saveVelocity * 32.0f;
|
||||||
|
}
|
||||||
|
#endif // _XBOX
|
||||||
|
}
|
||||||
|
|
||||||
|
//Alpha
|
||||||
|
virtual float UpdateAlpha( const SimpleParticle *pParticle )
|
||||||
|
{
|
||||||
|
float tLifetime = pParticle->m_flLifetime / pParticle->m_flDieTime;
|
||||||
|
float ramp = 1.0f - tLifetime;
|
||||||
|
|
||||||
|
//Non-linear fade
|
||||||
|
if ( ramp < 0.75f )
|
||||||
|
ramp *= ramp;
|
||||||
|
|
||||||
|
return ramp;
|
||||||
|
}
|
||||||
|
|
||||||
|
private:
|
||||||
|
CDustParticle( const CDustParticle & ); // not defined, not accessible
|
||||||
|
};
|
||||||
|
|
||||||
|
void GetColorForSurface( trace_t *trace, Vector *color );
|
||||||
|
|
||||||
|
#include "tier0/memdbgoff.h"
|
||||||
|
|
||||||
|
#endif // C_IMPACT_EFFECTS_H
|
214
cl_dll/c_lightglow.cpp
Normal file
214
cl_dll/c_lightglow.cpp
Normal file
@ -0,0 +1,214 @@
|
|||||||
|
//========= Copyright © 1996-2005, Valve Corporation, All rights reserved. ============//
|
||||||
|
//
|
||||||
|
// Purpose:
|
||||||
|
//
|
||||||
|
// $NoKeywords: $
|
||||||
|
//=============================================================================//
|
||||||
|
#include "cbase.h"
|
||||||
|
#include "glow_overlay.h"
|
||||||
|
#include "view.h"
|
||||||
|
#include "c_pixel_visibility.h"
|
||||||
|
|
||||||
|
// memdbgon must be the last include file in a .cpp file!!!
|
||||||
|
#include "tier0/memdbgon.h"
|
||||||
|
|
||||||
|
class C_LightGlowOverlay : public CGlowOverlay
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
|
||||||
|
virtual void CalcSpriteColorAndSize( float flDot, CGlowSprite *pSprite, float *flHorzSize, float *flVertSize, Vector *vColor )
|
||||||
|
{
|
||||||
|
*flHorzSize = pSprite->m_flHorzSize;
|
||||||
|
*flVertSize = pSprite->m_flVertSize;
|
||||||
|
|
||||||
|
Vector viewDir = ( CurrentViewOrigin() - m_vecOrigin );
|
||||||
|
float distToViewer = VectorNormalize( viewDir );
|
||||||
|
|
||||||
|
if ( m_bOneSided )
|
||||||
|
{
|
||||||
|
if ( DotProduct( viewDir, m_vecDirection ) < 0.0f )
|
||||||
|
{
|
||||||
|
*vColor = Vector(0,0,0);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
float fade;
|
||||||
|
|
||||||
|
// See if we're in the outer fade distance range
|
||||||
|
if ( m_nOuterMaxDist > m_nMaxDist && distToViewer > m_nMaxDist )
|
||||||
|
{
|
||||||
|
fade = RemapValClamped( distToViewer, m_nMaxDist, m_nOuterMaxDist, 1.0f, 0.0f );
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
fade = RemapValClamped( distToViewer, m_nMinDist, m_nMaxDist, 0.0f, 1.0f );
|
||||||
|
}
|
||||||
|
|
||||||
|
*vColor = pSprite->m_vColor * fade * m_flGlowObstructionScale;
|
||||||
|
}
|
||||||
|
|
||||||
|
void SetOrigin( const Vector &origin ) { m_vecOrigin = origin; }
|
||||||
|
|
||||||
|
void SetFadeDistances( int minDist, int maxDist, int outerMaxDist )
|
||||||
|
{
|
||||||
|
m_nMinDist = minDist;
|
||||||
|
m_nMaxDist = maxDist;
|
||||||
|
m_nOuterMaxDist = outerMaxDist;
|
||||||
|
}
|
||||||
|
|
||||||
|
void SetOneSided( bool state = true ) { m_bOneSided = state; }
|
||||||
|
void SetModulateByDot( bool state = true ) { m_bModulateByDot = state; }
|
||||||
|
|
||||||
|
void SetDirection( const Vector &dir ) { m_vecDirection = dir; VectorNormalize( m_vecDirection ); }
|
||||||
|
|
||||||
|
protected:
|
||||||
|
|
||||||
|
Vector m_vecOrigin;
|
||||||
|
Vector m_vecDirection;
|
||||||
|
int m_nMinDist;
|
||||||
|
int m_nMaxDist;
|
||||||
|
int m_nOuterMaxDist;
|
||||||
|
bool m_bOneSided;
|
||||||
|
bool m_bModulateByDot;
|
||||||
|
};
|
||||||
|
|
||||||
|
class C_LightGlow : public C_BaseEntity
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
DECLARE_CLASS( C_LightGlow, C_BaseEntity );
|
||||||
|
DECLARE_CLIENTCLASS();
|
||||||
|
|
||||||
|
C_LightGlow();
|
||||||
|
|
||||||
|
// C_BaseEntity overrides.
|
||||||
|
public:
|
||||||
|
|
||||||
|
virtual void OnDataChanged( DataUpdateType_t updateType );
|
||||||
|
virtual void NotifyShouldTransmit( ShouldTransmitState_t state );
|
||||||
|
virtual void Simulate( void );
|
||||||
|
|
||||||
|
public:
|
||||||
|
|
||||||
|
int m_nHorizontalSize;
|
||||||
|
int m_nVerticalSize;
|
||||||
|
int m_nMinDist;
|
||||||
|
int m_nMaxDist;
|
||||||
|
int m_nOuterMaxDist;
|
||||||
|
int m_spawnflags;
|
||||||
|
C_LightGlowOverlay m_Glow;
|
||||||
|
|
||||||
|
float m_flGlowProxySize;
|
||||||
|
};
|
||||||
|
|
||||||
|
static void RecvProxy_HDRColorScale( const CRecvProxyData *pData, void *pStruct, void *pOut )
|
||||||
|
{
|
||||||
|
C_LightGlow *pLightGlow = ( C_LightGlow * )pStruct;
|
||||||
|
|
||||||
|
pLightGlow->m_Glow.m_flHDRColorScale = pData->m_Value.m_Float;
|
||||||
|
}
|
||||||
|
|
||||||
|
IMPLEMENT_CLIENTCLASS_DT_NOBASE( C_LightGlow, DT_LightGlow, CLightGlow )
|
||||||
|
RecvPropInt( RECVINFO(m_clrRender), 0, RecvProxy_IntToColor32 ),
|
||||||
|
RecvPropInt( RECVINFO( m_nHorizontalSize ) ),
|
||||||
|
RecvPropInt( RECVINFO( m_nVerticalSize ) ),
|
||||||
|
RecvPropInt( RECVINFO( m_nMinDist ) ),
|
||||||
|
RecvPropInt( RECVINFO( m_nMaxDist ) ),
|
||||||
|
RecvPropInt( RECVINFO( m_nOuterMaxDist ) ),
|
||||||
|
RecvPropInt( RECVINFO( m_spawnflags ) ),
|
||||||
|
RecvPropVector( RECVINFO_NAME( m_vecNetworkOrigin, m_vecOrigin ) ),
|
||||||
|
RecvPropQAngles( RECVINFO_NAME( m_angNetworkAngles, m_angRotation ) ),
|
||||||
|
RecvPropInt( RECVINFO_NAME(m_hNetworkMoveParent, moveparent), 0, RecvProxy_IntToMoveParent ),
|
||||||
|
RecvPropFloat(RECVINFO(m_flGlowProxySize)),
|
||||||
|
RecvPropFloat("HDRColorScale", 0, SIZEOF_IGNORE, 0, RecvProxy_HDRColorScale),
|
||||||
|
END_RECV_TABLE()
|
||||||
|
|
||||||
|
//-----------------------------------------------------------------------------
|
||||||
|
// Constructor
|
||||||
|
//-----------------------------------------------------------------------------
|
||||||
|
C_LightGlow::C_LightGlow() :
|
||||||
|
m_nHorizontalSize( 0 ), m_nVerticalSize( 0 ), m_nMinDist( 0 ), m_nMaxDist( 0 )
|
||||||
|
{
|
||||||
|
m_Glow.m_bDirectional = false;
|
||||||
|
m_Glow.m_bInSky = false;
|
||||||
|
}
|
||||||
|
|
||||||
|
void C_LightGlow::Simulate( void )
|
||||||
|
{
|
||||||
|
BaseClass::Simulate();
|
||||||
|
|
||||||
|
m_Glow.m_vPos = GetAbsOrigin();
|
||||||
|
}
|
||||||
|
|
||||||
|
//-----------------------------------------------------------------------------
|
||||||
|
// Purpose:
|
||||||
|
// Input : updateType -
|
||||||
|
//-----------------------------------------------------------------------------
|
||||||
|
void C_LightGlow::OnDataChanged( DataUpdateType_t updateType )
|
||||||
|
{
|
||||||
|
BaseClass::OnDataChanged( updateType );
|
||||||
|
|
||||||
|
m_Glow.m_vPos = GetAbsOrigin();
|
||||||
|
|
||||||
|
if ( updateType == DATA_UPDATE_CREATED )
|
||||||
|
{
|
||||||
|
// Setup our flare.
|
||||||
|
Vector vColor(
|
||||||
|
m_clrRender->r / 255.0f,
|
||||||
|
m_clrRender->g / 255.0f,
|
||||||
|
m_clrRender->b / 255.0f );
|
||||||
|
|
||||||
|
m_Glow.m_nSprites = 1;
|
||||||
|
|
||||||
|
m_Glow.m_Sprites[0].m_flVertSize = (float) m_nVerticalSize;
|
||||||
|
m_Glow.m_Sprites[0].m_flHorzSize = (float) m_nHorizontalSize;
|
||||||
|
m_Glow.m_Sprites[0].m_vColor = vColor;
|
||||||
|
|
||||||
|
m_Glow.SetOrigin( GetAbsOrigin() );
|
||||||
|
m_Glow.SetFadeDistances( m_nMinDist, m_nMaxDist, m_nOuterMaxDist );
|
||||||
|
m_Glow.m_flProxyRadius = m_flGlowProxySize;
|
||||||
|
|
||||||
|
if ( m_spawnflags & SF_LIGHTGLOW_DIRECTIONAL )
|
||||||
|
{
|
||||||
|
m_Glow.SetOneSided();
|
||||||
|
}
|
||||||
|
|
||||||
|
m_Glow.Activate();
|
||||||
|
}
|
||||||
|
else if ( updateType == DATA_UPDATE_DATATABLE_CHANGED ) //Right now only color should change.
|
||||||
|
{
|
||||||
|
// Setup our flare.
|
||||||
|
Vector vColor(
|
||||||
|
m_clrRender->r / 255.0f,
|
||||||
|
m_clrRender->g / 255.0f,
|
||||||
|
m_clrRender->b / 255.0f );
|
||||||
|
|
||||||
|
m_Glow.m_Sprites[0].m_vColor = vColor;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
Vector forward;
|
||||||
|
AngleVectors( GetAbsAngles(), &forward, NULL, NULL );
|
||||||
|
|
||||||
|
m_Glow.SetDirection( forward );
|
||||||
|
}
|
||||||
|
|
||||||
|
//-----------------------------------------------------------------------------
|
||||||
|
// Purpose:
|
||||||
|
//-----------------------------------------------------------------------------
|
||||||
|
void C_LightGlow::NotifyShouldTransmit( ShouldTransmitState_t state )
|
||||||
|
{
|
||||||
|
BaseClass::NotifyShouldTransmit( state );
|
||||||
|
|
||||||
|
// Turn off
|
||||||
|
if ( state == SHOULDTRANSMIT_END )
|
||||||
|
{
|
||||||
|
m_Glow.Deactivate();
|
||||||
|
}
|
||||||
|
|
||||||
|
// Turn on
|
||||||
|
if ( state == SHOULDTRANSMIT_START )
|
||||||
|
{
|
||||||
|
m_Glow.Activate();
|
||||||
|
}
|
||||||
|
}
|
218
cl_dll/c_movie_explosion.cpp
Normal file
218
cl_dll/c_movie_explosion.cpp
Normal file
@ -0,0 +1,218 @@
|
|||||||
|
//========= Copyright © 1996-2005, Valve Corporation, All rights reserved. ============//
|
||||||
|
//
|
||||||
|
// Purpose:
|
||||||
|
//
|
||||||
|
// $NoKeywords: $
|
||||||
|
//=============================================================================//
|
||||||
|
|
||||||
|
#include "cbase.h"
|
||||||
|
#include "particle_prototype.h"
|
||||||
|
#include "particle_util.h"
|
||||||
|
#include "baseparticleentity.h"
|
||||||
|
|
||||||
|
// memdbgon must be the last include file in a .cpp file!!!
|
||||||
|
#include "tier0/memdbgon.h"
|
||||||
|
|
||||||
|
// ------------------------------------------------------------------------- //
|
||||||
|
// Definitions
|
||||||
|
// ------------------------------------------------------------------------- //
|
||||||
|
#define NUM_MOVIEEXPLOSION_EMITTERS 50
|
||||||
|
#define EXPLOSION_EMITTER_LIFETIME 3
|
||||||
|
#define EMITTED_PARTICLE_LIFETIME 1
|
||||||
|
|
||||||
|
|
||||||
|
// ------------------------------------------------------------------------- //
|
||||||
|
// Classes
|
||||||
|
// ------------------------------------------------------------------------- //
|
||||||
|
class MovieExplosionEmitter
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
Vector m_Pos;
|
||||||
|
Vector m_Velocity;
|
||||||
|
float m_Lifetime;
|
||||||
|
TimedEvent m_ParticleSpawn;
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
class C_MovieExplosion : public C_BaseParticleEntity, public IPrototypeAppEffect
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
DECLARE_CLASS( C_MovieExplosion, C_BaseParticleEntity );
|
||||||
|
DECLARE_CLIENTCLASS();
|
||||||
|
|
||||||
|
C_MovieExplosion();
|
||||||
|
~C_MovieExplosion();
|
||||||
|
|
||||||
|
// C_BaseEntity.
|
||||||
|
public:
|
||||||
|
virtual void OnDataChanged(DataUpdateType_t updateType);
|
||||||
|
|
||||||
|
// IPrototypeAppEffect.
|
||||||
|
public:
|
||||||
|
virtual void Start(CParticleMgr *pParticleMgr, IPrototypeArgAccess *pArgs);
|
||||||
|
|
||||||
|
// IParticleEffect.
|
||||||
|
public:
|
||||||
|
virtual void Update(float fTimeDelta);
|
||||||
|
virtual void RenderParticles( CParticleRenderIterator *pIterator );
|
||||||
|
virtual void SimulateParticles( CParticleSimulateIterator *pIterator );
|
||||||
|
|
||||||
|
|
||||||
|
public:
|
||||||
|
MovieExplosionEmitter m_Emitters[NUM_MOVIEEXPLOSION_EMITTERS];
|
||||||
|
float m_EmitterLifetime;
|
||||||
|
|
||||||
|
CParticleMgr *m_pParticleMgr;
|
||||||
|
PMaterialHandle m_iFireballMaterial;
|
||||||
|
|
||||||
|
// Setup for temporary usage in SimulateAndRender.
|
||||||
|
float m_EmitterAlpha;
|
||||||
|
|
||||||
|
private:
|
||||||
|
C_MovieExplosion( const C_MovieExplosion & );
|
||||||
|
|
||||||
|
};
|
||||||
|
|
||||||
|
// Expose to the particle app.
|
||||||
|
EXPOSE_PROTOTYPE_EFFECT(MovieExplosion, C_MovieExplosion);
|
||||||
|
|
||||||
|
IMPLEMENT_CLIENTCLASS_DT(C_MovieExplosion, DT_MovieExplosion, MovieExplosion)
|
||||||
|
END_RECV_TABLE()
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
// ------------------------------------------------------------------------- //
|
||||||
|
// C_MovieExplosion
|
||||||
|
// ------------------------------------------------------------------------- //
|
||||||
|
C_MovieExplosion::C_MovieExplosion()
|
||||||
|
{
|
||||||
|
m_pParticleMgr = NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
C_MovieExplosion::~C_MovieExplosion()
|
||||||
|
{
|
||||||
|
if(m_pParticleMgr)
|
||||||
|
m_pParticleMgr->RemoveEffect( &m_ParticleEffect );
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void C_MovieExplosion::OnDataChanged(DataUpdateType_t updateType)
|
||||||
|
{
|
||||||
|
C_BaseEntity::OnDataChanged(updateType);
|
||||||
|
|
||||||
|
if(updateType == DATA_UPDATE_CREATED)
|
||||||
|
{
|
||||||
|
Start( ParticleMgr(), NULL );
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void C_MovieExplosion::Start(CParticleMgr *pParticleMgr, IPrototypeArgAccess *pArgs)
|
||||||
|
{
|
||||||
|
if(!pParticleMgr->AddEffect(&m_ParticleEffect, this))
|
||||||
|
return;
|
||||||
|
|
||||||
|
// Setup our emitters.
|
||||||
|
for(int iEmitter=0; iEmitter < NUM_MOVIEEXPLOSION_EMITTERS; iEmitter++)
|
||||||
|
{
|
||||||
|
MovieExplosionEmitter *pEmitter = &m_Emitters[iEmitter];
|
||||||
|
pEmitter->m_Velocity = RandomVector(-1, 1) * 200;
|
||||||
|
|
||||||
|
pEmitter->m_Pos = GetAbsOrigin();
|
||||||
|
|
||||||
|
pEmitter->m_Lifetime = 0;
|
||||||
|
pEmitter->m_ParticleSpawn.Init(15);
|
||||||
|
}
|
||||||
|
m_EmitterLifetime = 0;
|
||||||
|
|
||||||
|
// Get our materials.
|
||||||
|
m_iFireballMaterial = m_ParticleEffect.FindOrAddMaterial("particle/particle_sphere");
|
||||||
|
|
||||||
|
m_pParticleMgr = pParticleMgr;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void C_MovieExplosion::Update(float fTimeDelta)
|
||||||
|
{
|
||||||
|
if(!m_pParticleMgr)
|
||||||
|
return;
|
||||||
|
|
||||||
|
m_EmitterLifetime += fTimeDelta;
|
||||||
|
if(m_EmitterLifetime > EXPLOSION_EMITTER_LIFETIME)
|
||||||
|
return;
|
||||||
|
|
||||||
|
m_EmitterAlpha = (float)sin(m_EmitterLifetime * 3.14159f / EXPLOSION_EMITTER_LIFETIME);
|
||||||
|
|
||||||
|
// Simulate the emitters and have them spit out particles.
|
||||||
|
for(int iEmitter=0; iEmitter < NUM_MOVIEEXPLOSION_EMITTERS; iEmitter++)
|
||||||
|
{
|
||||||
|
MovieExplosionEmitter *pEmitter = &m_Emitters[iEmitter];
|
||||||
|
|
||||||
|
pEmitter->m_Pos = pEmitter->m_Pos + pEmitter->m_Velocity * fTimeDelta;
|
||||||
|
pEmitter->m_Velocity = pEmitter->m_Velocity * 0.9;
|
||||||
|
|
||||||
|
float tempDelta = fTimeDelta;
|
||||||
|
while(pEmitter->m_ParticleSpawn.NextEvent(tempDelta))
|
||||||
|
{
|
||||||
|
StandardParticle_t *pParticle =
|
||||||
|
(StandardParticle_t*)m_ParticleEffect.AddParticle( sizeof(StandardParticle_t), m_iFireballMaterial);
|
||||||
|
|
||||||
|
if(pParticle)
|
||||||
|
{
|
||||||
|
pParticle->m_Pos = pEmitter->m_Pos;
|
||||||
|
pParticle->m_Velocity = pEmitter->m_Velocity * 0.2f + RandomVector(-20, 20);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void C_MovieExplosion::RenderParticles( CParticleRenderIterator *pIterator )
|
||||||
|
{
|
||||||
|
const StandardParticle_t *pParticle = (const StandardParticle_t*)pIterator->GetFirst();
|
||||||
|
while ( pParticle )
|
||||||
|
{
|
||||||
|
// Draw.
|
||||||
|
Vector tPos;
|
||||||
|
TransformParticle(m_pParticleMgr->GetModelView(), pParticle->m_Pos, tPos);
|
||||||
|
float sortKey = tPos.z;
|
||||||
|
|
||||||
|
float lifetimePercent = pParticle->m_Lifetime / EMITTED_PARTICLE_LIFETIME;
|
||||||
|
Vector color;
|
||||||
|
color.x = sin(lifetimePercent * 3.14159);
|
||||||
|
color.y = color.x * 0.5f;
|
||||||
|
color.z = 0;
|
||||||
|
RenderParticle_ColorSize(
|
||||||
|
pIterator->GetParticleDraw(),
|
||||||
|
tPos,
|
||||||
|
color,
|
||||||
|
m_EmitterAlpha * sin(3.14159 * lifetimePercent),
|
||||||
|
10);
|
||||||
|
|
||||||
|
pParticle = (const StandardParticle_t*)pIterator->GetNext( sortKey );
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void C_MovieExplosion::SimulateParticles( CParticleSimulateIterator *pIterator )
|
||||||
|
{
|
||||||
|
StandardParticle_t *pParticle = (StandardParticle_t*)pIterator->GetFirst();
|
||||||
|
while ( pParticle )
|
||||||
|
{
|
||||||
|
// Update its lifetime.
|
||||||
|
pParticle->m_Lifetime += pIterator->GetTimeDelta();
|
||||||
|
if(pParticle->m_Lifetime > 1)
|
||||||
|
{
|
||||||
|
pIterator->RemoveParticle( pParticle );
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
// Move it (this comes after rendering to make it clear that moving the particle here won't change
|
||||||
|
// its rendering for this frame since m_TransformedPos has already been set).
|
||||||
|
pParticle->m_Pos = pParticle->m_Pos + pParticle->m_Velocity * pIterator->GetTimeDelta();
|
||||||
|
}
|
||||||
|
|
||||||
|
pParticle = (StandardParticle_t*)pIterator->GetNext();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
339
cl_dll/c_particle_fire.cpp
Normal file
339
cl_dll/c_particle_fire.cpp
Normal file
@ -0,0 +1,339 @@
|
|||||||
|
//========= Copyright © 1996-2005, Valve Corporation, All rights reserved. ============//
|
||||||
|
//
|
||||||
|
// Purpose:
|
||||||
|
//
|
||||||
|
// $NoKeywords: $
|
||||||
|
//=============================================================================//
|
||||||
|
|
||||||
|
#include "cbase.h"
|
||||||
|
#include "particle_prototype.h"
|
||||||
|
#include "particle_util.h"
|
||||||
|
#include "baseparticleentity.h"
|
||||||
|
#include "engine/IEngineTrace.h"
|
||||||
|
|
||||||
|
// memdbgon must be the last include file in a .cpp file!!!
|
||||||
|
#include "tier0/memdbgon.h"
|
||||||
|
|
||||||
|
// ------------------------------------------------------------------------- //
|
||||||
|
// Defines.
|
||||||
|
// ------------------------------------------------------------------------- //
|
||||||
|
|
||||||
|
#define MAX_FIRE_EMITTERS 128
|
||||||
|
#define FIRE_PARTICLE_LIFETIME 2
|
||||||
|
|
||||||
|
Vector g_FireSpreadDirection(0,0,1);
|
||||||
|
|
||||||
|
|
||||||
|
class FireRamp
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
FireRamp(const Vector &s, const Vector &e)
|
||||||
|
{
|
||||||
|
m_Start=s;
|
||||||
|
m_End=e;
|
||||||
|
}
|
||||||
|
|
||||||
|
Vector m_Start;
|
||||||
|
Vector m_End;
|
||||||
|
};
|
||||||
|
|
||||||
|
FireRamp g_FireRamps[] =
|
||||||
|
{
|
||||||
|
FireRamp(Vector(1,0,0), Vector(1,1,0)),
|
||||||
|
FireRamp(Vector(0.5,0.5,0), Vector(0,0,0))
|
||||||
|
};
|
||||||
|
#define NUM_FIRE_RAMPS (sizeof(g_FireRamps) / sizeof(g_FireRamps[0]))
|
||||||
|
|
||||||
|
|
||||||
|
#define NUM_FIREGRID_OFFSETS 8
|
||||||
|
Vector g_Offsets[NUM_FIREGRID_OFFSETS] =
|
||||||
|
{
|
||||||
|
Vector(-1,-1,-1),
|
||||||
|
Vector( 1,-1,-1),
|
||||||
|
Vector(-1, 1,-1),
|
||||||
|
Vector( 1, 1,-1),
|
||||||
|
|
||||||
|
Vector(-1,-1, 1),
|
||||||
|
Vector( 1,-1, 1),
|
||||||
|
Vector(-1, 1, 1),
|
||||||
|
Vector( 1, 1, 1),
|
||||||
|
};
|
||||||
|
|
||||||
|
// If you follow g_Offset[index], you can follow g_Offsets[GetOppositeOffset(index)] to get back.
|
||||||
|
inline int GetOppositeOffset(int offset)
|
||||||
|
{
|
||||||
|
return NUM_FIREGRID_OFFSETS - offset - 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
// ------------------------------------------------------------------------- //
|
||||||
|
// Classes.
|
||||||
|
// ------------------------------------------------------------------------- //
|
||||||
|
|
||||||
|
class C_ParticleFire : public C_BaseParticleEntity, public IPrototypeAppEffect
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
DECLARE_CLASS( C_ParticleFire, C_BaseParticleEntity );
|
||||||
|
DECLARE_CLIENTCLASS();
|
||||||
|
|
||||||
|
C_ParticleFire();
|
||||||
|
~C_ParticleFire();
|
||||||
|
|
||||||
|
class FireEmitter
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
Vector m_Pos;
|
||||||
|
TimedEvent m_SpawnEvent;
|
||||||
|
float m_Lifetime; // How long it's been emitting.
|
||||||
|
unsigned char m_DirectionsTested; // 1 bit for each of g_Offsets.
|
||||||
|
};
|
||||||
|
|
||||||
|
class FireParticle : public Particle
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
Vector m_StartPos; // The particle moves from m_StartPos to (m_StartPos+m_Direction) over its lifetime.
|
||||||
|
Vector m_Direction;
|
||||||
|
|
||||||
|
float m_Lifetime;
|
||||||
|
float m_SpinAngle;
|
||||||
|
unsigned char m_iRamp; // Which fire ramp are we using?
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
// C_BaseEntity.
|
||||||
|
public:
|
||||||
|
|
||||||
|
virtual void OnDataChanged( DataUpdateType_t updateType );
|
||||||
|
|
||||||
|
|
||||||
|
// IPrototypeAppEffect.
|
||||||
|
public:
|
||||||
|
virtual void Start(CParticleMgr *pParticleMgr, IPrototypeArgAccess *pArgs);
|
||||||
|
|
||||||
|
|
||||||
|
// IParticleEffect.
|
||||||
|
public:
|
||||||
|
virtual void Update(float fTimeDelta);
|
||||||
|
virtual void RenderParticles( CParticleRenderIterator *pIterator );
|
||||||
|
virtual void SimulateParticles( CParticleSimulateIterator *pIterator );
|
||||||
|
|
||||||
|
|
||||||
|
public:
|
||||||
|
CParticleMgr *m_pParticleMgr;
|
||||||
|
PMaterialHandle m_MaterialHandle;
|
||||||
|
|
||||||
|
// Controls where the initial fire goes.
|
||||||
|
Vector m_vOrigin;
|
||||||
|
Vector m_vDirection;
|
||||||
|
|
||||||
|
TimedEvent m_EmitterSpawn;
|
||||||
|
FireEmitter m_Emitters[MAX_FIRE_EMITTERS];
|
||||||
|
int m_nEmitters;
|
||||||
|
|
||||||
|
private:
|
||||||
|
C_ParticleFire( const C_ParticleFire & );
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
// ------------------------------------------------------------------------- //
|
||||||
|
// Tables.
|
||||||
|
// ------------------------------------------------------------------------- //
|
||||||
|
|
||||||
|
// Expose to the particle app.
|
||||||
|
EXPOSE_PROTOTYPE_EFFECT(ParticleFire, C_ParticleFire);
|
||||||
|
|
||||||
|
|
||||||
|
// Datatable..
|
||||||
|
IMPLEMENT_CLIENTCLASS_DT_NOBASE(C_ParticleFire, DT_ParticleFire, CParticleFire)
|
||||||
|
RecvPropVector(RECVINFO(m_vOrigin)),
|
||||||
|
RecvPropVector(RECVINFO(m_vDirection)),
|
||||||
|
END_RECV_TABLE()
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
// ------------------------------------------------------------------------- //
|
||||||
|
// C_FireSmoke implementation.
|
||||||
|
// ------------------------------------------------------------------------- //
|
||||||
|
C_ParticleFire::C_ParticleFire()
|
||||||
|
{
|
||||||
|
m_pParticleMgr = NULL;
|
||||||
|
m_MaterialHandle = INVALID_MATERIAL_HANDLE;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
C_ParticleFire::~C_ParticleFire()
|
||||||
|
{
|
||||||
|
if(m_pParticleMgr)
|
||||||
|
m_pParticleMgr->RemoveEffect( &m_ParticleEffect );
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void C_ParticleFire::OnDataChanged(DataUpdateType_t updateType)
|
||||||
|
{
|
||||||
|
C_BaseEntity::OnDataChanged(updateType);
|
||||||
|
|
||||||
|
if(updateType == DATA_UPDATE_CREATED)
|
||||||
|
{
|
||||||
|
Start(ParticleMgr(), NULL);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void C_ParticleFire::Start(CParticleMgr *pParticleMgr, IPrototypeArgAccess *pArgs)
|
||||||
|
{
|
||||||
|
m_pParticleMgr = pParticleMgr;
|
||||||
|
m_pParticleMgr->AddEffect( &m_ParticleEffect, this );
|
||||||
|
m_MaterialHandle = m_ParticleEffect.FindOrAddMaterial("particle/particle_fire");
|
||||||
|
|
||||||
|
// Start
|
||||||
|
m_nEmitters = 0;
|
||||||
|
m_EmitterSpawn.Init(15);
|
||||||
|
}
|
||||||
|
|
||||||
|
static float fireSpreadDist = 15;
|
||||||
|
static float size = 20;
|
||||||
|
|
||||||
|
void C_ParticleFire::Update(float fTimeDelta)
|
||||||
|
{
|
||||||
|
if(!m_pParticleMgr)
|
||||||
|
{
|
||||||
|
assert(false);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
// Add new emitters.
|
||||||
|
if(m_nEmitters < MAX_FIRE_EMITTERS)
|
||||||
|
{
|
||||||
|
float tempDelta = fTimeDelta;
|
||||||
|
while(m_EmitterSpawn.NextEvent(tempDelta))
|
||||||
|
{
|
||||||
|
FireEmitter *pEmitter = NULL;
|
||||||
|
|
||||||
|
if(m_nEmitters == 0)
|
||||||
|
{
|
||||||
|
// Make the first emitter.
|
||||||
|
trace_t trace;
|
||||||
|
UTIL_TraceLine(m_vOrigin, m_vOrigin+m_vDirection*1000, MASK_SOLID_BRUSHONLY, NULL, COLLISION_GROUP_NONE, &trace);
|
||||||
|
if(trace.fraction < 1)
|
||||||
|
{
|
||||||
|
pEmitter = &m_Emitters[m_nEmitters];
|
||||||
|
pEmitter->m_Pos = trace.endpos + trace.plane.normal * (size - 1);
|
||||||
|
pEmitter->m_DirectionsTested = 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
static int nTries = 50;
|
||||||
|
for(int iTry=0; iTry < nTries; iTry++)
|
||||||
|
{
|
||||||
|
FireEmitter *pSourceEmitter = &m_Emitters[rand() % m_nEmitters];
|
||||||
|
|
||||||
|
int iOffset = rand() % NUM_FIREGRID_OFFSETS;
|
||||||
|
if(pSourceEmitter->m_DirectionsTested & (1 << iOffset))
|
||||||
|
continue;
|
||||||
|
|
||||||
|
// Test the corners of the new cube. If some points are solid and some are not, then
|
||||||
|
// we can put fire here.
|
||||||
|
Vector basePos = pSourceEmitter->m_Pos + g_Offsets[iOffset] * fireSpreadDist;
|
||||||
|
int nSolidCorners = 0;
|
||||||
|
for(int iCorner=0; iCorner < NUM_FIREGRID_OFFSETS; iCorner++)
|
||||||
|
{
|
||||||
|
Vector vCorner = basePos + g_Offsets[iCorner]*fireSpreadDist;
|
||||||
|
if ( enginetrace->GetPointContents(vCorner) & CONTENTS_SOLID )
|
||||||
|
++nSolidCorners;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Don't test this square again.
|
||||||
|
pSourceEmitter->m_DirectionsTested |= 1 << iOffset;
|
||||||
|
|
||||||
|
if(nSolidCorners != 0 && nSolidCorners != NUM_FIREGRID_OFFSETS)
|
||||||
|
{
|
||||||
|
pEmitter = &m_Emitters[m_nEmitters];
|
||||||
|
pEmitter->m_Pos = basePos;
|
||||||
|
pEmitter->m_DirectionsTested = 1 << GetOppositeOffset(iOffset);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if(pEmitter)
|
||||||
|
{
|
||||||
|
pEmitter->m_Lifetime = 0;
|
||||||
|
pEmitter->m_SpawnEvent.Init(1);
|
||||||
|
++m_nEmitters;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Spawn particles out of the emitters.
|
||||||
|
for(int i=0; i < m_nEmitters; i++)
|
||||||
|
{
|
||||||
|
FireEmitter *pEmitter = &m_Emitters[i];
|
||||||
|
|
||||||
|
float tempDelta = fTimeDelta;
|
||||||
|
while(pEmitter->m_SpawnEvent.NextEvent(tempDelta))
|
||||||
|
{
|
||||||
|
FireParticle *pParticle = (FireParticle*)m_ParticleEffect.AddParticle(sizeof(FireParticle), m_MaterialHandle);
|
||||||
|
if(pParticle)
|
||||||
|
{
|
||||||
|
static float particleSpeed = 15;
|
||||||
|
pParticle->m_StartPos = pEmitter->m_Pos;
|
||||||
|
pParticle->m_Direction = g_FireSpreadDirection * particleSpeed + RandomVector(0, particleSpeed*0.5);
|
||||||
|
pParticle->m_iRamp = rand() % NUM_FIRE_RAMPS;
|
||||||
|
pParticle->m_Lifetime = 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void C_ParticleFire::RenderParticles( CParticleRenderIterator *pIterator )
|
||||||
|
{
|
||||||
|
const FireParticle *pParticle = (const FireParticle*)pIterator->GetFirst();
|
||||||
|
while ( pParticle )
|
||||||
|
{
|
||||||
|
float smooth01 = 1 - (cos(pParticle->m_Lifetime * 3.14159 / FIRE_PARTICLE_LIFETIME) * 0.5 + 0.5);
|
||||||
|
float smooth00 = 1 - (cos(pParticle->m_Lifetime * 3.14159 * 2 / FIRE_PARTICLE_LIFETIME) * 0.5 + 0.5);
|
||||||
|
|
||||||
|
FireRamp *pRamp = &g_FireRamps[pParticle->m_iRamp];
|
||||||
|
Vector curColor = pRamp->m_Start + (pRamp->m_End - pRamp->m_Start) * smooth01;
|
||||||
|
|
||||||
|
// Render.
|
||||||
|
Vector tPos;
|
||||||
|
TransformParticle(m_pParticleMgr->GetModelView(), pParticle->m_Pos, tPos);
|
||||||
|
float sortKey = (int)tPos.z;
|
||||||
|
|
||||||
|
RenderParticle_ColorSize(
|
||||||
|
pIterator->GetParticleDraw(),
|
||||||
|
tPos,
|
||||||
|
curColor,
|
||||||
|
smooth00,
|
||||||
|
size);
|
||||||
|
|
||||||
|
pParticle = (const FireParticle*)pIterator->GetNext( sortKey );
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void C_ParticleFire::SimulateParticles( CParticleSimulateIterator *pIterator )
|
||||||
|
{
|
||||||
|
FireParticle *pParticle = (FireParticle*)pIterator->GetFirst();
|
||||||
|
while ( pParticle )
|
||||||
|
{
|
||||||
|
// Should this particle die?
|
||||||
|
pParticle->m_Lifetime += pIterator->GetTimeDelta();
|
||||||
|
if(pParticle->m_Lifetime > FIRE_PARTICLE_LIFETIME)
|
||||||
|
{
|
||||||
|
pIterator->RemoveParticle( pParticle );
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
float smooth01 = 1 - (cos(pParticle->m_Lifetime * 3.14159 / FIRE_PARTICLE_LIFETIME) * 0.5 + 0.5);
|
||||||
|
pParticle->m_Pos = pParticle->m_StartPos + pParticle->m_Direction * smooth01;
|
||||||
|
}
|
||||||
|
|
||||||
|
pParticle = (FireParticle*)pIterator->GetNext();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
1021
cl_dll/c_particle_smokegrenade.cpp
Normal file
1021
cl_dll/c_particle_smokegrenade.cpp
Normal file
File diff suppressed because it is too large
Load Diff
35
cl_dll/c_physbox.cpp
Normal file
35
cl_dll/c_physbox.cpp
Normal file
@ -0,0 +1,35 @@
|
|||||||
|
//========= Copyright © 1996-2005, Valve Corporation, All rights reserved. ============//
|
||||||
|
//
|
||||||
|
// Purpose:
|
||||||
|
//
|
||||||
|
// $NoKeywords: $
|
||||||
|
//=============================================================================//
|
||||||
|
#include "cbase.h"
|
||||||
|
#include "c_physbox.h"
|
||||||
|
|
||||||
|
// memdbgon must be the last include file in a .cpp file!!!
|
||||||
|
#include "tier0/memdbgon.h"
|
||||||
|
|
||||||
|
IMPLEMENT_CLIENTCLASS_DT(C_PhysBox, DT_PhysBox, CPhysBox)
|
||||||
|
RecvPropFloat(RECVINFO(m_mass), 0), // Test..
|
||||||
|
END_RECV_TABLE()
|
||||||
|
|
||||||
|
|
||||||
|
C_PhysBox::C_PhysBox()
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
//-----------------------------------------------------------------------------
|
||||||
|
// Should this object cast shadows?
|
||||||
|
//-----------------------------------------------------------------------------
|
||||||
|
ShadowType_t C_PhysBox::ShadowCastType()
|
||||||
|
{
|
||||||
|
if (IsEffectActive(EF_NODRAW | EF_NOSHADOW))
|
||||||
|
return SHADOWS_NONE;
|
||||||
|
return SHADOWS_RENDER_TO_TEXTURE;
|
||||||
|
}
|
||||||
|
|
||||||
|
C_PhysBox::~C_PhysBox()
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
39
cl_dll/c_physbox.h
Normal file
39
cl_dll/c_physbox.h
Normal file
@ -0,0 +1,39 @@
|
|||||||
|
//========= Copyright © 1996-2005, Valve Corporation, All rights reserved. ============//
|
||||||
|
//
|
||||||
|
// Purpose:
|
||||||
|
//
|
||||||
|
// $NoKeywords: $
|
||||||
|
//
|
||||||
|
//=============================================================================//
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
// Client-side CBasePlayer
|
||||||
|
|
||||||
|
#ifndef C_PHYSBOX_H
|
||||||
|
#define C_PHYSBOX_H
|
||||||
|
#pragma once
|
||||||
|
|
||||||
|
|
||||||
|
#include "c_baseentity.h"
|
||||||
|
|
||||||
|
|
||||||
|
class C_PhysBox : public C_BaseEntity
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
DECLARE_CLASS( C_PhysBox, C_BaseEntity );
|
||||||
|
DECLARE_CLIENTCLASS();
|
||||||
|
|
||||||
|
C_PhysBox();
|
||||||
|
virtual ~C_PhysBox();
|
||||||
|
virtual ShadowType_t ShadowCastType();
|
||||||
|
|
||||||
|
public:
|
||||||
|
float m_mass; // TEST..
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
#endif
|
||||||
|
|
||||||
|
|
||||||
|
|
158
cl_dll/c_physicsprop.cpp
Normal file
158
cl_dll/c_physicsprop.cpp
Normal file
@ -0,0 +1,158 @@
|
|||||||
|
//========= Copyright © 1996-2005, Valve Corporation, All rights reserved. ============//
|
||||||
|
//
|
||||||
|
// Purpose:
|
||||||
|
//
|
||||||
|
//=============================================================================//
|
||||||
|
#include "cbase.h"
|
||||||
|
#include "model_types.h"
|
||||||
|
#include "vcollide.h"
|
||||||
|
#include "vcollide_parse.h"
|
||||||
|
#include "solidsetdefaults.h"
|
||||||
|
#include "bone_setup.h"
|
||||||
|
#include "engine/ivmodelinfo.h"
|
||||||
|
#include "physics.h"
|
||||||
|
#include "view.h"
|
||||||
|
#include "clienteffectprecachesystem.h"
|
||||||
|
#include "c_physicsprop.h"
|
||||||
|
#include "tier0/vprof.h"
|
||||||
|
#include "ivrenderview.h"
|
||||||
|
|
||||||
|
// memdbgon must be the last include file in a .cpp file!!!
|
||||||
|
#include "tier0/memdbgon.h"
|
||||||
|
|
||||||
|
IMPLEMENT_CLIENTCLASS_DT(C_PhysicsProp, DT_PhysicsProp, CPhysicsProp)
|
||||||
|
RecvPropBool( RECVINFO( m_bAwake ) ),
|
||||||
|
END_RECV_TABLE()
|
||||||
|
|
||||||
|
ConVar r_PhysPropStaticLighting( "r_PhysPropStaticLighting", "1" );
|
||||||
|
|
||||||
|
|
||||||
|
//-----------------------------------------------------------------------------
|
||||||
|
// Purpose:
|
||||||
|
//-----------------------------------------------------------------------------
|
||||||
|
C_PhysicsProp::C_PhysicsProp( void )
|
||||||
|
{
|
||||||
|
m_pPhysicsObject = NULL;
|
||||||
|
m_takedamage = DAMAGE_YES;
|
||||||
|
|
||||||
|
// default true so static lighting will get recomputed when we go to sleep
|
||||||
|
m_bAwakeLastTime = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
//-----------------------------------------------------------------------------
|
||||||
|
// Purpose:
|
||||||
|
//-----------------------------------------------------------------------------
|
||||||
|
C_PhysicsProp::~C_PhysicsProp( void )
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
ConVar r_visualizeproplightcaching( "r_visualizeproplightcaching", "0" );
|
||||||
|
|
||||||
|
//-----------------------------------------------------------------------------
|
||||||
|
// Purpose: Draws the object
|
||||||
|
// Input : flags -
|
||||||
|
//-----------------------------------------------------------------------------
|
||||||
|
// FIXME!!!! I hate the fact that InternalDrawModel is always such a huge cut-and-paste job.
|
||||||
|
int C_PhysicsProp::InternalDrawModel( int flags )
|
||||||
|
{
|
||||||
|
VPROF( "C_PhysicsProp::InternalDrawModel" );
|
||||||
|
|
||||||
|
//-----------------------------------------------------------------------------
|
||||||
|
// Overriding C_BaseAnimating::InternalDrawModel so that we can detect when the
|
||||||
|
// prop is asleep. This allows us to bake the lighting for the model.
|
||||||
|
//-----------------------------------------------------------------------------
|
||||||
|
if ( !GetModel() )
|
||||||
|
{
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
if ( IsEffectActive( EF_ITEM_BLINK ) )
|
||||||
|
{
|
||||||
|
flags |= STUDIO_ITEM_BLINK;
|
||||||
|
}
|
||||||
|
|
||||||
|
// This should never happen, but if the server class hierarchy has bmodel entities derived from CBaseAnimating or does a
|
||||||
|
// SetModel with the wrong type of model, this could occur.
|
||||||
|
if ( modelinfo->GetModelType( GetModel() ) != mod_studio )
|
||||||
|
{
|
||||||
|
return BaseClass::DrawModel( flags );
|
||||||
|
}
|
||||||
|
|
||||||
|
// Make sure hdr is valid for drawing
|
||||||
|
if ( !GetModelPtr() )
|
||||||
|
{
|
||||||
|
// inhibit drawing and state setting until all data available
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
CreateModelInstance();
|
||||||
|
|
||||||
|
if ( r_PhysPropStaticLighting.GetBool() && m_bAwakeLastTime != m_bAwake )
|
||||||
|
{
|
||||||
|
if ( m_bAwakeLastTime && !m_bAwake )
|
||||||
|
{
|
||||||
|
// transition to sleep, bake lighting now, once
|
||||||
|
if ( !modelrender->RecomputeStaticLighting( GetModelInstance() ) )
|
||||||
|
{
|
||||||
|
// not valid for drawing
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
if ( r_visualizeproplightcaching.GetBool() )
|
||||||
|
{
|
||||||
|
float color[] = { 0.0f, 1.0f, 0.0f, 1.0f };
|
||||||
|
render->SetColorModulation( color );
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else if ( r_visualizeproplightcaching.GetBool() )
|
||||||
|
{
|
||||||
|
float color[] = { 1.0f, 0.0f, 0.0f, 1.0f };
|
||||||
|
render->SetColorModulation( color );
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if ( !m_bAwake && r_PhysPropStaticLighting.GetBool() )
|
||||||
|
{
|
||||||
|
// going to sleep, have static lighting
|
||||||
|
flags |= STUDIO_STATIC_LIGHTING;
|
||||||
|
}
|
||||||
|
|
||||||
|
Vector tmpOrigin = GetRenderOrigin();
|
||||||
|
|
||||||
|
int drawn = modelrender->DrawModel(
|
||||||
|
flags,
|
||||||
|
this,
|
||||||
|
GetModelInstance(),
|
||||||
|
index,
|
||||||
|
GetModel(),
|
||||||
|
GetRenderOrigin(),
|
||||||
|
GetRenderAngles(),
|
||||||
|
m_nSkin,
|
||||||
|
m_nBody,
|
||||||
|
m_nHitboxSet );
|
||||||
|
|
||||||
|
if ( vcollide_wireframe.GetBool() )
|
||||||
|
{
|
||||||
|
if ( IsRagdoll() )
|
||||||
|
{
|
||||||
|
m_pRagdoll->DrawWireframe();
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
vcollide_t *pCollide = modelinfo->GetVCollide( GetModelIndex() );
|
||||||
|
if ( pCollide && pCollide->solidCount == 1 )
|
||||||
|
{
|
||||||
|
static color32 debugColor = {0,255,255,0};
|
||||||
|
matrix3x4_t matrix;
|
||||||
|
AngleMatrix( GetAbsAngles(), GetAbsOrigin(), matrix );
|
||||||
|
engine->DebugDrawPhysCollide( pCollide->solids[0], NULL, matrix, debugColor );
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// track state
|
||||||
|
m_bAwakeLastTime = m_bAwake;
|
||||||
|
|
||||||
|
return drawn;
|
||||||
|
}
|
34
cl_dll/c_physicsprop.h
Normal file
34
cl_dll/c_physicsprop.h
Normal file
@ -0,0 +1,34 @@
|
|||||||
|
//========= Copyright © 1996-2005, Valve Corporation, All rights reserved. ============//
|
||||||
|
//
|
||||||
|
// Purpose:
|
||||||
|
//
|
||||||
|
//=============================================================================//
|
||||||
|
|
||||||
|
#ifndef C_PHYSICSPROP_H
|
||||||
|
#define C_PHYSICSPROP_H
|
||||||
|
#ifdef _WIN32
|
||||||
|
#pragma once
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#include "c_breakableprop.h"
|
||||||
|
//-----------------------------------------------------------------------------
|
||||||
|
// Purpose:
|
||||||
|
//-----------------------------------------------------------------------------
|
||||||
|
class C_PhysicsProp : public C_BreakableProp
|
||||||
|
{
|
||||||
|
typedef C_BreakableProp BaseClass;
|
||||||
|
public:
|
||||||
|
DECLARE_CLIENTCLASS();
|
||||||
|
|
||||||
|
C_PhysicsProp();
|
||||||
|
~C_PhysicsProp();
|
||||||
|
|
||||||
|
int InternalDrawModel( int flags );
|
||||||
|
|
||||||
|
protected:
|
||||||
|
// Networked vars.
|
||||||
|
bool m_bAwake;
|
||||||
|
bool m_bAwakeLastTime;
|
||||||
|
};
|
||||||
|
|
||||||
|
#endif // C_PHYSICSPROP_H
|
134
cl_dll/c_physmagnet.cpp
Normal file
134
cl_dll/c_physmagnet.cpp
Normal file
@ -0,0 +1,134 @@
|
|||||||
|
//========= Copyright © 1996-2005, Valve Corporation, All rights reserved. ============//
|
||||||
|
//
|
||||||
|
// Purpose:
|
||||||
|
//
|
||||||
|
//=============================================================================//
|
||||||
|
#include "cbase.h"
|
||||||
|
#include "c_baseentity.h"
|
||||||
|
|
||||||
|
// memdbgon must be the last include file in a .cpp file!!!
|
||||||
|
#include "tier0/memdbgon.h"
|
||||||
|
|
||||||
|
//-----------------------------------------------------------------------------
|
||||||
|
// Purpose:
|
||||||
|
//-----------------------------------------------------------------------------
|
||||||
|
class C_PhysMagnet : public C_BaseAnimating
|
||||||
|
{
|
||||||
|
DECLARE_CLASS( C_PhysMagnet, C_BaseAnimating );
|
||||||
|
public:
|
||||||
|
DECLARE_CLIENTCLASS();
|
||||||
|
|
||||||
|
C_PhysMagnet();
|
||||||
|
virtual ~C_PhysMagnet();
|
||||||
|
|
||||||
|
void PostDataUpdate( DataUpdateType_t updateType );
|
||||||
|
bool GetShadowCastDirection( Vector *pDirection, ShadowType_t shadowType ) const;
|
||||||
|
|
||||||
|
public:
|
||||||
|
// Data received from the server
|
||||||
|
CUtlVector< int > m_aAttachedObjectsFromServer;
|
||||||
|
|
||||||
|
// Private list of entities on the magnet
|
||||||
|
CUtlVector< EHANDLE > m_aAttachedObjects;
|
||||||
|
};
|
||||||
|
|
||||||
|
//-----------------------------------------------------------------------------
|
||||||
|
// Purpose: RecvProxy that converts the Magnet's attached object entindexes to handles
|
||||||
|
//-----------------------------------------------------------------------------
|
||||||
|
void RecvProxy_MagnetAttachedObjectList( const CRecvProxyData *pData, void *pStruct, void *pOut )
|
||||||
|
{
|
||||||
|
C_PhysMagnet *pMagnet = (C_PhysMagnet*)pOut;
|
||||||
|
pMagnet->m_aAttachedObjectsFromServer[pData->m_iElement] = pData->m_Value.m_Int;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void RecvProxyArrayLength_MagnetAttachedArray( void *pStruct, int objectID, int currentArrayLength )
|
||||||
|
{
|
||||||
|
C_PhysMagnet *pMagnet = (C_PhysMagnet*)pStruct;
|
||||||
|
|
||||||
|
if ( pMagnet->m_aAttachedObjectsFromServer.Size() != currentArrayLength )
|
||||||
|
pMagnet->m_aAttachedObjectsFromServer.SetSize( currentArrayLength );
|
||||||
|
}
|
||||||
|
|
||||||
|
IMPLEMENT_CLIENTCLASS_DT(C_PhysMagnet, DT_PhysMagnet, CPhysMagnet)
|
||||||
|
|
||||||
|
// ROBIN: Disabled because we don't need it anymore
|
||||||
|
/*
|
||||||
|
RecvPropArray2(
|
||||||
|
RecvProxyArrayLength_MagnetAttachedArray,
|
||||||
|
RecvPropInt( "magnetattached_array_element", 0, SIZEOF_IGNORE, 0, RecvProxy_MagnetAttachedObjectList ),
|
||||||
|
128,
|
||||||
|
0,
|
||||||
|
"magnetattached_array"
|
||||||
|
)
|
||||||
|
*/
|
||||||
|
|
||||||
|
END_RECV_TABLE()
|
||||||
|
|
||||||
|
//-----------------------------------------------------------------------------
|
||||||
|
// Purpose:
|
||||||
|
//-----------------------------------------------------------------------------
|
||||||
|
C_PhysMagnet::C_PhysMagnet()
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
//-----------------------------------------------------------------------------
|
||||||
|
// Purpose:
|
||||||
|
//-----------------------------------------------------------------------------
|
||||||
|
C_PhysMagnet::~C_PhysMagnet()
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
//-----------------------------------------------------------------------------
|
||||||
|
// Purpose:
|
||||||
|
//-----------------------------------------------------------------------------
|
||||||
|
void C_PhysMagnet::PostDataUpdate( DataUpdateType_t updateType )
|
||||||
|
{
|
||||||
|
BaseClass::PostDataUpdate( updateType );
|
||||||
|
|
||||||
|
/*
|
||||||
|
// First, detect any entities removed from the magnet and restore their shadows
|
||||||
|
int iCount = m_aAttachedObjects.Count();
|
||||||
|
int iServerCount = m_aAttachedObjectsFromServer.Count();
|
||||||
|
for ( int i = 0; i < iCount; i++ )
|
||||||
|
{
|
||||||
|
int iEntIndex = m_aAttachedObjects[i]->entindex();
|
||||||
|
for ( int j = 0; j < iServerCount; j++ )
|
||||||
|
{
|
||||||
|
if ( iEntIndex == m_aAttachedObjectsFromServer[j] )
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
if ( j == iServerCount )
|
||||||
|
{
|
||||||
|
// Ok, a previously attached object is no longer attached
|
||||||
|
m_aAttachedObjects[i]->SetShadowUseOtherEntity( NULL );
|
||||||
|
m_aAttachedObjects.Remove(i);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Make sure newly attached entities have vertical shadows too
|
||||||
|
for ( i = 0; i < iServerCount; i++ )
|
||||||
|
{
|
||||||
|
C_BaseEntity *pEntity = cl_entitylist->GetEnt( m_aAttachedObjectsFromServer[i] );
|
||||||
|
if ( m_aAttachedObjects.Find( pEntity ) == m_aAttachedObjects.InvalidIndex() )
|
||||||
|
{
|
||||||
|
pEntity->SetShadowUseOtherEntity( this );
|
||||||
|
m_aAttachedObjects.AddToTail( pEntity );
|
||||||
|
}
|
||||||
|
}
|
||||||
|
*/
|
||||||
|
}
|
||||||
|
|
||||||
|
//-----------------------------------------------------------------------------
|
||||||
|
// Purpose: Return a per-entity shadow cast direction
|
||||||
|
//-----------------------------------------------------------------------------
|
||||||
|
bool C_PhysMagnet::GetShadowCastDirection( Vector *pDirection, ShadowType_t shadowType ) const
|
||||||
|
{
|
||||||
|
// Magnets shadow is more vertical than others
|
||||||
|
//Vector vecDown = g_pClientShadowMgr->GetShadowDirection() - Vector(0,0,1);
|
||||||
|
//VectorNormalize( vecDown );
|
||||||
|
//*pDirection = vecDown;
|
||||||
|
*pDirection = Vector(0,0,-1);
|
||||||
|
return true;
|
||||||
|
}
|
769
cl_dll/c_pixel_visibility.cpp
Normal file
769
cl_dll/c_pixel_visibility.cpp
Normal file
@ -0,0 +1,769 @@
|
|||||||
|
//========= Copyright © 1996-2005, Valve Corporation, All rights reserved. ============//
|
||||||
|
//
|
||||||
|
// Purpose:
|
||||||
|
//
|
||||||
|
// $NoKeywords: $
|
||||||
|
//
|
||||||
|
//=============================================================================//
|
||||||
|
#include "cbase.h"
|
||||||
|
#include "c_pixel_visibility.h"
|
||||||
|
#include "materialsystem/imesh.h"
|
||||||
|
#include "materialsystem/imaterial.h"
|
||||||
|
#include "ClientEffectPrecacheSystem.h"
|
||||||
|
#include "view.h"
|
||||||
|
#include "utlmultilist.h"
|
||||||
|
|
||||||
|
static void PixelvisDrawChanged( ConVar *pPixelvisVar, const char *pOld );
|
||||||
|
|
||||||
|
ConVar r_pixelvisibility_partial( "r_pixelvisibility_partial", "1" );
|
||||||
|
ConVar r_dopixelvisibility( "r_dopixelvisibility", "1" );
|
||||||
|
ConVar r_drawpixelvisibility( "r_drawpixelvisibility", "0", 0, "Show the occlusion proxies", PixelvisDrawChanged );
|
||||||
|
ConVar r_pixelvisibility_spew( "r_pixelvisibility_spew", "0" );
|
||||||
|
|
||||||
|
extern ConVar building_cubemaps;
|
||||||
|
|
||||||
|
const float MIN_PROXY_PIXELS = 5.0f;
|
||||||
|
|
||||||
|
float PixelVisibility_DrawProxy( OcclusionQueryObjectHandle_t queryHandle, Vector origin, float scale, float proxyAspect, IMaterial *pMaterial, bool screenspace )
|
||||||
|
{
|
||||||
|
Vector point;
|
||||||
|
|
||||||
|
// don't expand this with distance to fit pixels or the sprite will poke through
|
||||||
|
// only expand the parts perpendicular to the view
|
||||||
|
float forwardScale = scale;
|
||||||
|
// draw a pyramid of points touching a sphere of radius "scale" at origin
|
||||||
|
float pixelsPerUnit = materials->ComputePixelWidthOfSphere( origin, 1.0f );
|
||||||
|
pixelsPerUnit = max( pixelsPerUnit, 1e-4f );
|
||||||
|
if ( screenspace )
|
||||||
|
{
|
||||||
|
// Force this to be the size of a sphere of diameter "scale" at some reference distance (1.0 unit)
|
||||||
|
float pixelsPerUnit2 = materials->ComputePixelWidthOfSphere( CurrentViewOrigin() + CurrentViewForward()*1.0f, scale*0.5f );
|
||||||
|
// force drawing of "scale" pixels
|
||||||
|
scale = pixelsPerUnit2 / pixelsPerUnit;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
float pixels = scale * pixelsPerUnit;
|
||||||
|
|
||||||
|
// make the radius larger to ensure a minimum screen space size of the proxy geometry
|
||||||
|
if ( pixels < MIN_PROXY_PIXELS )
|
||||||
|
{
|
||||||
|
scale = MIN_PROXY_PIXELS / pixelsPerUnit;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// collapses the pyramid to a plane - so this could be a quad instead
|
||||||
|
Vector dir = origin - CurrentViewOrigin();
|
||||||
|
VectorNormalize(dir);
|
||||||
|
origin -= dir * forwardScale;
|
||||||
|
forwardScale = 0.0f;
|
||||||
|
//
|
||||||
|
|
||||||
|
Vector verts[5];
|
||||||
|
const float sqrt2 = 0.707106781f; // sqrt(2) - keeps all vectors the same length from origin
|
||||||
|
scale *= sqrt2;
|
||||||
|
float scale45x = scale;
|
||||||
|
float scale45y = scale / proxyAspect;
|
||||||
|
verts[0] = origin - CurrentViewForward() * forwardScale; // the apex of the pyramid
|
||||||
|
verts[1] = origin + CurrentViewUp() * scale45y - CurrentViewRight() * scale45x; // these four form the base
|
||||||
|
verts[2] = origin + CurrentViewUp() * scale45y + CurrentViewRight() * scale45x; // the pyramid is a sprite with a point that
|
||||||
|
verts[3] = origin - CurrentViewUp() * scale45y + CurrentViewRight() * scale45x; // pokes back toward the camera through any nearby
|
||||||
|
verts[4] = origin - CurrentViewUp() * scale45y - CurrentViewRight() * scale45x; // geometry
|
||||||
|
|
||||||
|
// get screen coords of edges
|
||||||
|
Vector screen[4];
|
||||||
|
for ( int i = 0; i < 4; i++ )
|
||||||
|
{
|
||||||
|
extern int ScreenTransform( const Vector& point, Vector& screen );
|
||||||
|
if ( ScreenTransform( verts[i+1], screen[i] ) )
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
// compute area and screen-clipped area
|
||||||
|
float w = screen[1].x - screen[0].x;
|
||||||
|
float h = screen[0].y - screen[3].y;
|
||||||
|
float ws = min(1.0f, screen[1].x) - max(-1.0f, screen[0].x);
|
||||||
|
float hs = min(1.0f, screen[0].y) - max(-1.0f, screen[3].y);
|
||||||
|
float area = w*h; // area can be zero when we ALT-TAB
|
||||||
|
float areaClipped = ws*hs;
|
||||||
|
float ratio = 0.0f;
|
||||||
|
if ( area != 0 )
|
||||||
|
{
|
||||||
|
// compute the ratio of the area not clipped by the frustum to total area
|
||||||
|
ratio = areaClipped / area;
|
||||||
|
ratio = clamp(ratio, 0.0f, 1.0f);
|
||||||
|
}
|
||||||
|
|
||||||
|
IMesh* pMesh = materials->GetDynamicMesh( true, NULL, NULL, pMaterial );
|
||||||
|
|
||||||
|
CMeshBuilder meshBuilder;
|
||||||
|
materials->BeginOcclusionQueryDrawing( queryHandle );
|
||||||
|
meshBuilder.Begin( pMesh, MATERIAL_TRIANGLES, 4 );
|
||||||
|
// draw a pyramid
|
||||||
|
for ( int i = 0; i < 4; i++ )
|
||||||
|
{
|
||||||
|
int a = i+1;
|
||||||
|
int b = (a%4)+1;
|
||||||
|
meshBuilder.Position3fv( verts[0].Base() );
|
||||||
|
meshBuilder.AdvanceVertex();
|
||||||
|
meshBuilder.Position3fv( verts[a].Base() );
|
||||||
|
meshBuilder.AdvanceVertex();
|
||||||
|
meshBuilder.Position3fv( verts[b].Base() );
|
||||||
|
meshBuilder.AdvanceVertex();
|
||||||
|
}
|
||||||
|
meshBuilder.End();
|
||||||
|
pMesh->Draw();
|
||||||
|
|
||||||
|
// sprite/quad proxy
|
||||||
|
#if 0
|
||||||
|
meshBuilder.Begin( pMesh, MATERIAL_QUADS, 1 );
|
||||||
|
|
||||||
|
VectorMA (origin, -scale, CurrentViewUp(), point);
|
||||||
|
VectorMA (point, -scale, CurrentViewRight(), point);
|
||||||
|
meshBuilder.Position3fv (point.Base());
|
||||||
|
meshBuilder.AdvanceVertex();
|
||||||
|
|
||||||
|
VectorMA (origin, scale, CurrentViewUp(), point);
|
||||||
|
VectorMA (point, -scale, CurrentViewRight(), point);
|
||||||
|
meshBuilder.Position3fv (point.Base());
|
||||||
|
meshBuilder.AdvanceVertex();
|
||||||
|
|
||||||
|
VectorMA (origin, scale, CurrentViewUp(), point);
|
||||||
|
VectorMA (point, scale, CurrentViewRight(), point);
|
||||||
|
meshBuilder.Position3fv (point.Base());
|
||||||
|
meshBuilder.AdvanceVertex();
|
||||||
|
|
||||||
|
VectorMA (origin, -scale, CurrentViewUp(), point);
|
||||||
|
VectorMA (point, scale, CurrentViewRight(), point);
|
||||||
|
meshBuilder.Position3fv (point.Base());
|
||||||
|
meshBuilder.AdvanceVertex();
|
||||||
|
|
||||||
|
meshBuilder.End();
|
||||||
|
pMesh->Draw();
|
||||||
|
#endif
|
||||||
|
materials->EndOcclusionQueryDrawing( queryHandle );
|
||||||
|
|
||||||
|
// fraction clipped by frustum
|
||||||
|
return ratio;
|
||||||
|
}
|
||||||
|
|
||||||
|
class CPixelVisSet
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
void Init( const pixelvis_queryparams_t ¶ms );
|
||||||
|
void MarkActive();
|
||||||
|
bool IsActive();
|
||||||
|
CPixelVisSet()
|
||||||
|
{
|
||||||
|
frameIssued = 0;
|
||||||
|
serial = 0;
|
||||||
|
queryList = 0xFFFF;
|
||||||
|
sizeIsScreenSpace = false;
|
||||||
|
}
|
||||||
|
|
||||||
|
public:
|
||||||
|
float proxySize;
|
||||||
|
float proxyAspect;
|
||||||
|
float fadeTimeInv;
|
||||||
|
unsigned short queryList;
|
||||||
|
unsigned short serial;
|
||||||
|
bool sizeIsScreenSpace;
|
||||||
|
private:
|
||||||
|
int frameIssued;
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
void CPixelVisSet::Init( const pixelvis_queryparams_t ¶ms )
|
||||||
|
{
|
||||||
|
Assert( params.bSetup );
|
||||||
|
proxySize = params.proxySize;
|
||||||
|
proxyAspect = params.proxyAspect;
|
||||||
|
if ( params.fadeTime > 0.0f )
|
||||||
|
{
|
||||||
|
fadeTimeInv = 1.0f / params.fadeTime;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
// fade in over 0.125 seconds
|
||||||
|
fadeTimeInv = 1.0f / 0.125f;
|
||||||
|
}
|
||||||
|
frameIssued = 0;
|
||||||
|
sizeIsScreenSpace = params.bSizeInScreenspace;
|
||||||
|
}
|
||||||
|
|
||||||
|
void CPixelVisSet::MarkActive()
|
||||||
|
{
|
||||||
|
frameIssued = gpGlobals->framecount;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool CPixelVisSet::IsActive()
|
||||||
|
{
|
||||||
|
return (gpGlobals->framecount - frameIssued) > 1 ? false : true;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
class CPixelVisibilityQuery
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
CPixelVisibilityQuery();
|
||||||
|
~CPixelVisibilityQuery();
|
||||||
|
bool IsValid();
|
||||||
|
bool IsForView( int viewID );
|
||||||
|
bool IsActive();
|
||||||
|
float GetFractionVisible( float fadeTimeInv );
|
||||||
|
void IssueQuery( float proxySize, float proxyAspect, IMaterial *pMaterial, bool sizeIsScreenSpace );
|
||||||
|
void IssueCountingQuery( float proxySize, float proxyAspect, IMaterial *pMaterial, bool sizeIsScreenSpace );
|
||||||
|
void SetView( int viewID )
|
||||||
|
{
|
||||||
|
m_viewID = viewID;
|
||||||
|
m_brightnessTarget = 0.0f;
|
||||||
|
m_clipFraction = 1.0f;
|
||||||
|
m_frameIssued = -1;
|
||||||
|
m_failed = false;
|
||||||
|
m_wasQueriedThisFrame = false;
|
||||||
|
m_hasValidQueryResults = false;
|
||||||
|
}
|
||||||
|
|
||||||
|
public:
|
||||||
|
Vector m_origin;
|
||||||
|
int m_frameIssued;
|
||||||
|
private:
|
||||||
|
float m_brightnessTarget;
|
||||||
|
float m_clipFraction;
|
||||||
|
OcclusionQueryObjectHandle_t m_queryHandle;
|
||||||
|
OcclusionQueryObjectHandle_t m_queryHandleCount;
|
||||||
|
unsigned short m_wasQueriedThisFrame : 1;
|
||||||
|
unsigned short m_failed : 1;
|
||||||
|
unsigned short m_hasValidQueryResults : 1;
|
||||||
|
unsigned short m_pad : 13;
|
||||||
|
unsigned short m_viewID;
|
||||||
|
};
|
||||||
|
|
||||||
|
CPixelVisibilityQuery::CPixelVisibilityQuery()
|
||||||
|
{
|
||||||
|
SetView( 0xFFFF );
|
||||||
|
m_queryHandle = materials->CreateOcclusionQueryObject();
|
||||||
|
m_queryHandleCount = materials->CreateOcclusionQueryObject();
|
||||||
|
}
|
||||||
|
|
||||||
|
CPixelVisibilityQuery::~CPixelVisibilityQuery()
|
||||||
|
{
|
||||||
|
if ( m_queryHandle != INVALID_OCCLUSION_QUERY_OBJECT_HANDLE )
|
||||||
|
{
|
||||||
|
materials->DestroyOcclusionQueryObject( m_queryHandle );
|
||||||
|
}
|
||||||
|
if ( m_queryHandleCount != INVALID_OCCLUSION_QUERY_OBJECT_HANDLE )
|
||||||
|
{
|
||||||
|
materials->DestroyOcclusionQueryObject( m_queryHandleCount );
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
bool CPixelVisibilityQuery::IsValid()
|
||||||
|
{
|
||||||
|
return (m_queryHandle != INVALID_OCCLUSION_QUERY_OBJECT_HANDLE) ? true : false;
|
||||||
|
}
|
||||||
|
bool CPixelVisibilityQuery::IsForView( int viewID )
|
||||||
|
{
|
||||||
|
return m_viewID == viewID ? true : false;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool CPixelVisibilityQuery::IsActive()
|
||||||
|
{
|
||||||
|
return (gpGlobals->framecount - m_frameIssued) > 1 ? false : true;
|
||||||
|
}
|
||||||
|
|
||||||
|
float CPixelVisibilityQuery::GetFractionVisible( float fadeTimeInv )
|
||||||
|
{
|
||||||
|
if ( !IsValid() )
|
||||||
|
return 0.0f;
|
||||||
|
|
||||||
|
if ( !m_wasQueriedThisFrame )
|
||||||
|
{
|
||||||
|
m_wasQueriedThisFrame = true;
|
||||||
|
int pixels = -1;
|
||||||
|
int pixelsPossible = -1;
|
||||||
|
if ( r_pixelvisibility_partial.GetBool() )
|
||||||
|
{
|
||||||
|
if ( m_frameIssued != -1 )
|
||||||
|
{
|
||||||
|
pixelsPossible = materials->OcclusionQuery_GetNumPixelsRendered( m_queryHandleCount );
|
||||||
|
pixels = materials->OcclusionQuery_GetNumPixelsRendered( m_queryHandle );
|
||||||
|
}
|
||||||
|
|
||||||
|
if ( r_pixelvisibility_spew.GetBool() && CurrentViewID() == 0 )
|
||||||
|
{
|
||||||
|
DevMsg( 1, "Pixels visible: %d (qh:%d) Pixels possible: %d (qh:%d) (frame:%d)\n", pixels, m_queryHandle, pixelsPossible, m_queryHandleCount, gpGlobals->framecount );
|
||||||
|
}
|
||||||
|
|
||||||
|
if ( pixels < 0 || pixelsPossible < 0 )
|
||||||
|
{
|
||||||
|
m_failed = m_frameIssued != -1 ? true : false;
|
||||||
|
return m_brightnessTarget * m_clipFraction;
|
||||||
|
}
|
||||||
|
m_hasValidQueryResults = true;
|
||||||
|
|
||||||
|
if ( pixelsPossible > 0 )
|
||||||
|
{
|
||||||
|
float target = (float)pixels / (float)pixelsPossible;
|
||||||
|
target = (target >= 0.95f) ? 1.0f : (target < 0.0f) ? 0.0f : target;
|
||||||
|
float rate = gpGlobals->frametime * fadeTimeInv;
|
||||||
|
m_brightnessTarget = Approach( target, m_brightnessTarget, rate ); // fade in / out
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
m_brightnessTarget = 0.0f;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
if ( m_frameIssued != -1 )
|
||||||
|
{
|
||||||
|
pixels = materials->OcclusionQuery_GetNumPixelsRendered( m_queryHandle );
|
||||||
|
}
|
||||||
|
|
||||||
|
if ( r_pixelvisibility_spew.GetBool() && CurrentViewID() == 0 )
|
||||||
|
{
|
||||||
|
DevMsg( 1, "Pixels visible: %d (qh:%d) (frame:%d)\n", pixels, m_queryHandle, gpGlobals->framecount );
|
||||||
|
}
|
||||||
|
|
||||||
|
if ( pixels < 0 )
|
||||||
|
{
|
||||||
|
m_failed = m_frameIssued != -1 ? true : false;
|
||||||
|
return m_brightnessTarget * m_clipFraction;
|
||||||
|
}
|
||||||
|
m_hasValidQueryResults = true;
|
||||||
|
if ( m_frameIssued == gpGlobals->framecount-1 )
|
||||||
|
{
|
||||||
|
float rate = gpGlobals->frametime * fadeTimeInv;
|
||||||
|
float target = 0.0f;
|
||||||
|
if ( pixels > 0 )
|
||||||
|
{
|
||||||
|
// fade in slower than you fade out
|
||||||
|
rate *= 0.5f;
|
||||||
|
target = 1.0f;
|
||||||
|
}
|
||||||
|
m_brightnessTarget = Approach( target, m_brightnessTarget, rate ); // fade in / out
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
m_brightnessTarget = 0.0f;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return m_brightnessTarget * m_clipFraction;
|
||||||
|
}
|
||||||
|
|
||||||
|
void CPixelVisibilityQuery::IssueQuery( float proxySize, float proxyAspect, IMaterial *pMaterial, bool sizeIsScreenSpace )
|
||||||
|
{
|
||||||
|
if ( !m_failed )
|
||||||
|
{
|
||||||
|
Assert( IsValid() );
|
||||||
|
|
||||||
|
if ( r_pixelvisibility_spew.GetBool() && CurrentViewID() == 0 )
|
||||||
|
{
|
||||||
|
DevMsg( 1, "Draw Proxy: qh:%d org:<%d,%d,%d> (frame:%d)\n", m_queryHandle, (int)m_origin[0], (int)m_origin[1], (int)m_origin[2], gpGlobals->framecount );
|
||||||
|
}
|
||||||
|
|
||||||
|
m_clipFraction = PixelVisibility_DrawProxy( m_queryHandle, m_origin, proxySize, proxyAspect, pMaterial, sizeIsScreenSpace );
|
||||||
|
|
||||||
|
|
||||||
|
}
|
||||||
|
m_frameIssued = gpGlobals->framecount;
|
||||||
|
m_wasQueriedThisFrame = false;
|
||||||
|
m_failed = false;
|
||||||
|
}
|
||||||
|
|
||||||
|
void CPixelVisibilityQuery::IssueCountingQuery( float proxySize, float proxyAspect, IMaterial *pMaterial, bool sizeIsScreenSpace )
|
||||||
|
{
|
||||||
|
if ( !m_failed )
|
||||||
|
{
|
||||||
|
Assert( IsValid() );
|
||||||
|
#if 0
|
||||||
|
// this centers it on the screen.
|
||||||
|
// This is nice because it makes the glows fade as they get partially clipped by the view frustum
|
||||||
|
// But it introduces sub-pixel errors (off by one row/column of pixels) so the glows shimmer
|
||||||
|
// UNDONE: Compute an offset center coord that matches sub-pixel coords with the real glow position
|
||||||
|
// UNDONE: Or frustum clip the sphere/geometry and fade based on proxy size
|
||||||
|
Vector origin = m_origin - CurrentViewOrigin();
|
||||||
|
float dot = DotProduct(CurrentViewForward(), origin);
|
||||||
|
origin = CurrentViewOrigin() + dot * CurrentViewForward();
|
||||||
|
#endif
|
||||||
|
PixelVisibility_DrawProxy( m_queryHandleCount, m_origin, proxySize, proxyAspect, pMaterial, sizeIsScreenSpace );
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
//Precahce the effects
|
||||||
|
CLIENTEFFECT_REGISTER_BEGIN( PrecacheOcclusionProxy )
|
||||||
|
CLIENTEFFECT_MATERIAL( "engine/occlusionproxy" )
|
||||||
|
CLIENTEFFECT_MATERIAL( "engine/occlusionproxy_countdraw" )
|
||||||
|
CLIENTEFFECT_REGISTER_END()
|
||||||
|
|
||||||
|
class CPixelVisibilitySystem : public CAutoGameSystem
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
|
||||||
|
// GameSystem: Level init, shutdown
|
||||||
|
virtual void LevelInitPreEntity();
|
||||||
|
virtual void LevelShutdownPostEntity();
|
||||||
|
|
||||||
|
// locals
|
||||||
|
CPixelVisibilitySystem();
|
||||||
|
float GetFractionVisible( const pixelvis_queryparams_t ¶ms, pixelvis_handle_t *queryHandle );
|
||||||
|
void EndView();
|
||||||
|
void EndScene();
|
||||||
|
unsigned short FindQueryForView( CPixelVisSet *pSet, int viewID );
|
||||||
|
unsigned short FindOrCreateQueryForView( CPixelVisSet *pSet, int viewID );
|
||||||
|
|
||||||
|
void DeleteUnusedQueries( CPixelVisSet *pSet, bool bDeleteAll );
|
||||||
|
void DeleteUnusedSets( bool bDeleteAll );
|
||||||
|
void ShowQueries( bool show );
|
||||||
|
unsigned short AllocQuery();
|
||||||
|
unsigned short AllocSet();
|
||||||
|
void FreeSet( unsigned short node );
|
||||||
|
CPixelVisSet *FindOrCreatePixelVisSet( const pixelvis_queryparams_t ¶ms, pixelvis_handle_t *queryHandle );
|
||||||
|
bool SupportsOcclusion() { return m_hwCanTestGlows; }
|
||||||
|
void DebugInfo()
|
||||||
|
{
|
||||||
|
Msg("Pixel vis system using %d sets total (%d in free list), %d queries total (%d in free list)\n",
|
||||||
|
m_setList.TotalCount(), m_setList.Count(m_freeSetsList), m_queryList.TotalCount(), m_queryList.Count( m_freeQueriesList ) );
|
||||||
|
}
|
||||||
|
private:
|
||||||
|
CUtlMultiList< CPixelVisSet, unsigned short > m_setList;
|
||||||
|
CUtlMultiList<CPixelVisibilityQuery, unsigned short> m_queryList;
|
||||||
|
unsigned short m_freeQueriesList;
|
||||||
|
unsigned short m_activeSetsList;
|
||||||
|
unsigned short m_freeSetsList;
|
||||||
|
unsigned short m_pad0;
|
||||||
|
|
||||||
|
IMaterial *m_pProxyMaterial;
|
||||||
|
IMaterial *m_pDrawMaterial;
|
||||||
|
bool m_hwCanTestGlows;
|
||||||
|
bool m_drawQueries;
|
||||||
|
};
|
||||||
|
|
||||||
|
static CPixelVisibilitySystem g_PixelVisibilitySystem;
|
||||||
|
|
||||||
|
CPixelVisibilitySystem::CPixelVisibilitySystem() : CAutoGameSystem( "CPixelVisibilitySystem" )
|
||||||
|
{
|
||||||
|
m_hwCanTestGlows = true;
|
||||||
|
m_drawQueries = false;
|
||||||
|
}
|
||||||
|
// Level init, shutdown
|
||||||
|
void CPixelVisibilitySystem::LevelInitPreEntity()
|
||||||
|
{
|
||||||
|
m_hwCanTestGlows = r_dopixelvisibility.GetBool() && engine->GetDXSupportLevel() >= 80;
|
||||||
|
if ( m_hwCanTestGlows )
|
||||||
|
{
|
||||||
|
unsigned short query = materials->CreateOcclusionQueryObject();
|
||||||
|
if ( query != INVALID_OCCLUSION_QUERY_OBJECT_HANDLE )
|
||||||
|
{
|
||||||
|
materials->DestroyOcclusionQueryObject( query );
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
m_hwCanTestGlows = false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
m_pProxyMaterial = materials->FindMaterial("engine/occlusionproxy", TEXTURE_GROUP_CLIENT_EFFECTS);
|
||||||
|
m_pProxyMaterial->IncrementReferenceCount();
|
||||||
|
m_pDrawMaterial = materials->FindMaterial("engine/occlusionproxy_countdraw", TEXTURE_GROUP_CLIENT_EFFECTS);
|
||||||
|
m_pDrawMaterial->IncrementReferenceCount();
|
||||||
|
m_freeQueriesList = m_queryList.CreateList();
|
||||||
|
m_activeSetsList = m_setList.CreateList();
|
||||||
|
m_freeSetsList = m_setList.CreateList();
|
||||||
|
}
|
||||||
|
|
||||||
|
void CPixelVisibilitySystem::LevelShutdownPostEntity()
|
||||||
|
{
|
||||||
|
m_pProxyMaterial->DecrementReferenceCount();
|
||||||
|
m_pProxyMaterial = NULL;
|
||||||
|
m_pDrawMaterial->DecrementReferenceCount();
|
||||||
|
m_pDrawMaterial = NULL;
|
||||||
|
DeleteUnusedSets(true);
|
||||||
|
m_setList.Purge();
|
||||||
|
m_queryList.Purge();
|
||||||
|
m_freeQueriesList = m_queryList.InvalidIndex();
|
||||||
|
m_activeSetsList = m_setList.InvalidIndex();
|
||||||
|
m_freeSetsList = m_setList.InvalidIndex();
|
||||||
|
}
|
||||||
|
|
||||||
|
float CPixelVisibilitySystem::GetFractionVisible( const pixelvis_queryparams_t ¶ms, pixelvis_handle_t *queryHandle )
|
||||||
|
{
|
||||||
|
if ( !m_hwCanTestGlows || building_cubemaps.GetBool() )
|
||||||
|
{
|
||||||
|
return GlowSightDistance( params.position, true ) > 0 ? 1.0f : 0.0f;
|
||||||
|
}
|
||||||
|
if ( CurrentViewID() < 0 )
|
||||||
|
return 0.0f;
|
||||||
|
|
||||||
|
CPixelVisSet *pSet = FindOrCreatePixelVisSet( params, queryHandle );
|
||||||
|
Assert( pSet );
|
||||||
|
unsigned short node = FindOrCreateQueryForView( pSet, CurrentViewID() );
|
||||||
|
m_queryList[node].m_origin = params.position;
|
||||||
|
float fraction = m_queryList[node].GetFractionVisible( pSet->fadeTimeInv );
|
||||||
|
pSet->MarkActive();
|
||||||
|
|
||||||
|
|
||||||
|
return fraction;
|
||||||
|
}
|
||||||
|
|
||||||
|
void CPixelVisibilitySystem::EndView()
|
||||||
|
{
|
||||||
|
if ( !PixelVisibility_IsAvailable() && CurrentViewID() >= 0 )
|
||||||
|
return;
|
||||||
|
|
||||||
|
if ( m_setList.Head( m_activeSetsList ) == m_setList.InvalidIndex() )
|
||||||
|
return;
|
||||||
|
|
||||||
|
IMaterial *pProxy = m_drawQueries ? m_pDrawMaterial : m_pProxyMaterial;
|
||||||
|
materials->Bind( pProxy );
|
||||||
|
|
||||||
|
// BUGBUG: If you draw both queries, the measure query fails for some reason.
|
||||||
|
if ( r_pixelvisibility_partial.GetBool() && !m_drawQueries )
|
||||||
|
{
|
||||||
|
materials->DepthRange( 0.0f, 0.01f );
|
||||||
|
unsigned short node = m_setList.Head( m_activeSetsList );
|
||||||
|
while( node != m_setList.InvalidIndex() )
|
||||||
|
{
|
||||||
|
CPixelVisSet *pSet = &m_setList[node];
|
||||||
|
unsigned short queryNode = FindQueryForView( pSet, CurrentViewID() );
|
||||||
|
if ( queryNode != m_queryList.InvalidIndex() )
|
||||||
|
{
|
||||||
|
m_queryList[queryNode].IssueCountingQuery( pSet->proxySize, pSet->proxyAspect, pProxy, pSet->sizeIsScreenSpace );
|
||||||
|
}
|
||||||
|
node = m_setList.Next( node );
|
||||||
|
}
|
||||||
|
materials->DepthRange( 0.0f, 1.0f );
|
||||||
|
}
|
||||||
|
|
||||||
|
{
|
||||||
|
unsigned short node = m_setList.Head( m_activeSetsList );
|
||||||
|
while( node != m_setList.InvalidIndex() )
|
||||||
|
{
|
||||||
|
CPixelVisSet *pSet = &m_setList[node];
|
||||||
|
unsigned short queryNode = FindQueryForView( pSet, CurrentViewID() );
|
||||||
|
if ( queryNode != m_queryList.InvalidIndex() )
|
||||||
|
{
|
||||||
|
m_queryList[queryNode].IssueQuery( pSet->proxySize, pSet->proxyAspect, pProxy, pSet->sizeIsScreenSpace );
|
||||||
|
}
|
||||||
|
node = m_setList.Next( node );
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void CPixelVisibilitySystem::EndScene()
|
||||||
|
{
|
||||||
|
DeleteUnusedSets(false);
|
||||||
|
}
|
||||||
|
|
||||||
|
unsigned short CPixelVisibilitySystem::FindQueryForView( CPixelVisSet *pSet, int viewID )
|
||||||
|
{
|
||||||
|
unsigned short node = m_queryList.Head( pSet->queryList );
|
||||||
|
while ( node != m_queryList.InvalidIndex() )
|
||||||
|
{
|
||||||
|
if ( m_queryList[node].IsForView( viewID ) )
|
||||||
|
return node;
|
||||||
|
node = m_queryList.Next( node );
|
||||||
|
}
|
||||||
|
return m_queryList.InvalidIndex();
|
||||||
|
}
|
||||||
|
unsigned short CPixelVisibilitySystem::FindOrCreateQueryForView( CPixelVisSet *pSet, int viewID )
|
||||||
|
{
|
||||||
|
unsigned short node = FindQueryForView( pSet, viewID );
|
||||||
|
if ( node != m_queryList.InvalidIndex() )
|
||||||
|
return node;
|
||||||
|
|
||||||
|
node = AllocQuery();
|
||||||
|
m_queryList.LinkToHead( pSet->queryList, node );
|
||||||
|
m_queryList[node].SetView( viewID );
|
||||||
|
return node;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void CPixelVisibilitySystem::DeleteUnusedQueries( CPixelVisSet *pSet, bool bDeleteAll )
|
||||||
|
{
|
||||||
|
unsigned short node = m_queryList.Head( pSet->queryList );
|
||||||
|
while ( node != m_queryList.InvalidIndex() )
|
||||||
|
{
|
||||||
|
unsigned short next = m_queryList.Next( node );
|
||||||
|
if ( bDeleteAll || !m_queryList[node].IsActive() )
|
||||||
|
{
|
||||||
|
m_queryList.Unlink( pSet->queryList, node);
|
||||||
|
m_queryList.LinkToHead( m_freeQueriesList, node );
|
||||||
|
}
|
||||||
|
node = next;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
void CPixelVisibilitySystem::DeleteUnusedSets( bool bDeleteAll )
|
||||||
|
{
|
||||||
|
unsigned short node = m_setList.Head( m_activeSetsList );
|
||||||
|
while ( node != m_setList.InvalidIndex() )
|
||||||
|
{
|
||||||
|
unsigned short next = m_setList.Next( node );
|
||||||
|
CPixelVisSet *pSet = &m_setList[node];
|
||||||
|
if ( bDeleteAll || !m_setList[node].IsActive() )
|
||||||
|
{
|
||||||
|
DeleteUnusedQueries( pSet, true );
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
DeleteUnusedQueries( pSet, false );
|
||||||
|
}
|
||||||
|
if ( m_queryList.Head(pSet->queryList) == m_queryList.InvalidIndex() )
|
||||||
|
{
|
||||||
|
FreeSet( node );
|
||||||
|
}
|
||||||
|
node = next;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void CPixelVisibilitySystem::ShowQueries( bool show )
|
||||||
|
{
|
||||||
|
m_drawQueries = show;
|
||||||
|
}
|
||||||
|
|
||||||
|
unsigned short CPixelVisibilitySystem::AllocQuery()
|
||||||
|
{
|
||||||
|
unsigned short node = m_queryList.Head(m_freeQueriesList);
|
||||||
|
if ( node != m_queryList.InvalidIndex() )
|
||||||
|
{
|
||||||
|
m_queryList.Unlink( m_freeQueriesList, node );
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
node = m_queryList.Alloc();
|
||||||
|
}
|
||||||
|
return node;
|
||||||
|
}
|
||||||
|
|
||||||
|
unsigned short CPixelVisibilitySystem::AllocSet()
|
||||||
|
{
|
||||||
|
unsigned short node = m_setList.Head(m_freeSetsList);
|
||||||
|
if ( node != m_setList.InvalidIndex() )
|
||||||
|
{
|
||||||
|
m_setList.Unlink( m_freeSetsList, node );
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
node = m_setList.Alloc();
|
||||||
|
m_setList[node].queryList = m_queryList.CreateList();
|
||||||
|
}
|
||||||
|
m_setList.LinkToHead( m_activeSetsList, node );
|
||||||
|
return node;
|
||||||
|
}
|
||||||
|
|
||||||
|
void CPixelVisibilitySystem::FreeSet( unsigned short node )
|
||||||
|
{
|
||||||
|
m_setList.Unlink( m_activeSetsList, node );
|
||||||
|
m_setList.LinkToHead( m_freeSetsList, node );
|
||||||
|
m_setList[node].serial++;
|
||||||
|
}
|
||||||
|
|
||||||
|
CPixelVisSet *CPixelVisibilitySystem::FindOrCreatePixelVisSet( const pixelvis_queryparams_t ¶ms, pixelvis_handle_t *queryHandle )
|
||||||
|
{
|
||||||
|
if ( queryHandle[0] )
|
||||||
|
{
|
||||||
|
unsigned short handle = queryHandle[0] & 0xFFFF;
|
||||||
|
handle--;
|
||||||
|
unsigned short serial = queryHandle[0] >> 16;
|
||||||
|
if ( m_setList.IsValidIndex(handle) && m_setList[handle].serial == serial )
|
||||||
|
{
|
||||||
|
return &m_setList[handle];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
unsigned short node = AllocSet();
|
||||||
|
m_setList[node].Init( params );
|
||||||
|
unsigned int out = m_setList[node].serial;
|
||||||
|
unsigned short nodeHandle = node + 1;
|
||||||
|
out <<= 16;
|
||||||
|
out |= nodeHandle;
|
||||||
|
queryHandle[0] = out;
|
||||||
|
return &m_setList[node];
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void PixelvisDrawChanged( ConVar *pPixelvisVar, const char *pOld )
|
||||||
|
{
|
||||||
|
g_PixelVisibilitySystem.ShowQueries( pPixelvisVar->GetBool() );
|
||||||
|
}
|
||||||
|
|
||||||
|
class CTraceFilterGlow : public CTraceFilterSimple
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
DECLARE_CLASS( CTraceFilterGlow, CTraceFilterSimple );
|
||||||
|
|
||||||
|
CTraceFilterGlow( const IHandleEntity *passentity, int collisionGroup ) : CTraceFilterSimple(passentity, collisionGroup) {}
|
||||||
|
virtual bool ShouldHitEntity( IHandleEntity *pHandleEntity, int contentsMask )
|
||||||
|
{
|
||||||
|
IClientUnknown *pUnk = (IClientUnknown*)pHandleEntity;
|
||||||
|
ICollideable *pCollide = pUnk->GetCollideable();
|
||||||
|
if ( pCollide->GetSolid() != SOLID_VPHYSICS && pCollide->GetSolid() != SOLID_BSP )
|
||||||
|
return false;
|
||||||
|
return BaseClass::ShouldHitEntity( pHandleEntity, contentsMask );
|
||||||
|
}
|
||||||
|
};
|
||||||
|
float GlowSightDistance( const Vector &glowOrigin, bool bShouldTrace )
|
||||||
|
{
|
||||||
|
float dist = (glowOrigin - CurrentViewOrigin()).Length();
|
||||||
|
C_BasePlayer *local = C_BasePlayer::GetLocalPlayer();
|
||||||
|
if ( local )
|
||||||
|
{
|
||||||
|
dist *= local->GetFOVDistanceAdjustFactor();
|
||||||
|
}
|
||||||
|
|
||||||
|
if ( bShouldTrace )
|
||||||
|
{
|
||||||
|
Vector end = glowOrigin;
|
||||||
|
// HACKHACK: trace 4" from destination in case the glow is inside some parent object
|
||||||
|
// allow a little error...
|
||||||
|
if ( dist > 4 )
|
||||||
|
{
|
||||||
|
end -= CurrentViewForward()*4;
|
||||||
|
}
|
||||||
|
int traceFlags = MASK_OPAQUE|CONTENTS_MONSTER|CONTENTS_DEBRIS;
|
||||||
|
|
||||||
|
CTraceFilterGlow filter(NULL, COLLISION_GROUP_NONE);
|
||||||
|
trace_t tr;
|
||||||
|
UTIL_TraceLine( CurrentViewOrigin(), end, traceFlags, &filter, &tr );
|
||||||
|
if ( tr.fraction != 1.0f )
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
return dist;
|
||||||
|
}
|
||||||
|
|
||||||
|
void PixelVisibility_EndCurrentView()
|
||||||
|
{
|
||||||
|
g_PixelVisibilitySystem.EndView();
|
||||||
|
}
|
||||||
|
|
||||||
|
void PixelVisibility_EndScene()
|
||||||
|
{
|
||||||
|
g_PixelVisibilitySystem.EndScene();
|
||||||
|
}
|
||||||
|
|
||||||
|
float PixelVisibility_FractionVisible( const pixelvis_queryparams_t ¶ms, pixelvis_handle_t *queryHandle )
|
||||||
|
{
|
||||||
|
if ( !queryHandle )
|
||||||
|
{
|
||||||
|
return GlowSightDistance( params.position, true ) > 0.0f ? 1.0f : 0.0f;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
return g_PixelVisibilitySystem.GetFractionVisible( params, queryHandle );
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
bool PixelVisibility_IsAvailable()
|
||||||
|
{
|
||||||
|
return r_dopixelvisibility.GetBool() && g_PixelVisibilitySystem.SupportsOcclusion();
|
||||||
|
}
|
||||||
|
|
||||||
|
CON_COMMAND( pixelvis_debug, "Dump debug info" )
|
||||||
|
{
|
||||||
|
g_PixelVisibilitySystem.DebugInfo();
|
||||||
|
}
|
53
cl_dll/c_pixel_visibility.h
Normal file
53
cl_dll/c_pixel_visibility.h
Normal file
@ -0,0 +1,53 @@
|
|||||||
|
//========= Copyright © 1996-2005, Valve Corporation, All rights reserved. ============//
|
||||||
|
//
|
||||||
|
// Purpose:
|
||||||
|
//
|
||||||
|
//=============================================================================//
|
||||||
|
|
||||||
|
#ifndef C_PIXEL_VISIBILITY_H
|
||||||
|
#define C_PIXEL_VISIBILITY_H
|
||||||
|
#ifdef _WIN32
|
||||||
|
#pragma once
|
||||||
|
#endif
|
||||||
|
|
||||||
|
|
||||||
|
const float PIXELVIS_DEFAULT_PROXY_SIZE = 2.0f;
|
||||||
|
const float PIXELVIS_DEFAULT_FADE_TIME = 0.0625f;
|
||||||
|
|
||||||
|
typedef int pixelvis_handle_t;
|
||||||
|
struct pixelvis_queryparams_t
|
||||||
|
{
|
||||||
|
pixelvis_queryparams_t()
|
||||||
|
{
|
||||||
|
bSetup = false;
|
||||||
|
}
|
||||||
|
|
||||||
|
void Init( const Vector &origin, float proxySizeIn = PIXELVIS_DEFAULT_PROXY_SIZE, float proxyAspectIn = 1.0f, float fadeTimeIn = PIXELVIS_DEFAULT_FADE_TIME )
|
||||||
|
{
|
||||||
|
position = origin;
|
||||||
|
proxySize = proxySizeIn;
|
||||||
|
proxyAspect = proxyAspectIn;
|
||||||
|
fadeTime = fadeTimeIn;
|
||||||
|
bSetup = true;
|
||||||
|
bSizeInScreenspace = false;
|
||||||
|
}
|
||||||
|
|
||||||
|
Vector position;
|
||||||
|
float proxySize;
|
||||||
|
float proxyAspect;
|
||||||
|
float fadeTime;
|
||||||
|
bool bSetup;
|
||||||
|
bool bSizeInScreenspace;
|
||||||
|
};
|
||||||
|
|
||||||
|
float PixelVisibility_FractionVisible( const pixelvis_queryparams_t ¶ms, pixelvis_handle_t *queryHandle );
|
||||||
|
float StandardGlowBlend( const pixelvis_queryparams_t ¶ms, pixelvis_handle_t *queryHandle, int rendermode, int renderfx, int alpha, float *pscale );
|
||||||
|
|
||||||
|
void PixelVisibility_EndCurrentView();
|
||||||
|
void PixelVisibility_EndScene();
|
||||||
|
float GlowSightDistance( const Vector &glowOrigin, bool bShouldTrace );
|
||||||
|
|
||||||
|
// returns true if the video hardware is doing the tests, false is traceline is doing so.
|
||||||
|
bool PixelVisibility_IsAvailable();
|
||||||
|
|
||||||
|
#endif // C_PIXEL_VISIBILITY_H
|
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in New Issue
Block a user