mirror of
https://github.com/blendogames/thirtyflightsofloving.git
synced 2024-11-14 00:21:18 +00:00
Rewrote Com_strcpy() and Com_strcat() in game DLLs to not be based on strncpy() and to return size copied.
Changed Zaero and 3ZB2 game DLLs to use WORLD_SIZE for various calculations instead of 8192. Cleaned up string handling in 3ZB2 game DLL. Added func_plat2, func_door_secret2, and func_force_wall from Rogue to 3ZB2 game DLL. Added alternate attack contact explode for grenade launcher in 3ZB2 game DLL. Added awakening2 game DLL source.
This commit is contained in:
parent
4afc95c317
commit
9481c7c513
80 changed files with 64904 additions and 2172 deletions
|
@ -153,6 +153,10 @@ SOURCE=.\g_mtrain.c
|
|||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=.\g_newfnc.c
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=.\g_phys.c
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
|
|
@ -112,101 +112,6 @@
|
|||
Name="VCPostBuildEventTool"
|
||||
/>
|
||||
</Configuration>
|
||||
<Configuration
|
||||
Name="Debug|Win32"
|
||||
OutputDirectory=".\Debug"
|
||||
IntermediateDirectory=".\Debug"
|
||||
ConfigurationType="2"
|
||||
InheritedPropertySheets="$(VCInstallDir)VCProjectDefaults\UpgradeFromVC60.vsprops"
|
||||
UseOfMFC="0"
|
||||
ATLMinimizesCRunTimeLibraryUsage="false"
|
||||
>
|
||||
<Tool
|
||||
Name="VCPreBuildEventTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCCustomBuildTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCXMLDataGeneratorTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCWebServiceProxyGeneratorTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCMIDLTool"
|
||||
PreprocessorDefinitions="_DEBUG"
|
||||
MkTypLibCompatible="true"
|
||||
SuppressStartupBanner="true"
|
||||
TargetEnvironment="1"
|
||||
TypeLibraryName=".\Debug/3zb2_2008.tlb"
|
||||
HeaderFileName=""
|
||||
/>
|
||||
<Tool
|
||||
Name="VCCLCompilerTool"
|
||||
Optimization="0"
|
||||
PreprocessorDefinitions="WIN32;_DEBUG;_WINDOWS;BUILDING_REF_GL"
|
||||
RuntimeLibrary="1"
|
||||
PrecompiledHeaderFile=".\Debug/3zb2_2008.pch"
|
||||
AssemblerListingLocation=".\Debug/"
|
||||
ObjectFile=".\Debug/"
|
||||
ProgramDataBaseFileName=".\Debug/"
|
||||
WarningLevel="3"
|
||||
SuppressStartupBanner="true"
|
||||
DebugInformationFormat="1"
|
||||
DisableSpecificWarnings="4996"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCManagedResourceCompilerTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCResourceCompilerTool"
|
||||
PreprocessorDefinitions="_DEBUG"
|
||||
Culture="1033"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCPreLinkEventTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCLinkerTool"
|
||||
AdditionalDependencies="winmm.lib"
|
||||
OutputFile=".\gamex86.dll"
|
||||
LinkIncremental="1"
|
||||
SuppressStartupBanner="true"
|
||||
ModuleDefinitionFile=".\game.def"
|
||||
GenerateDebugInformation="true"
|
||||
ProgramDatabaseFile=".\Debug/gamex86.pdb"
|
||||
SubSystem="2"
|
||||
BaseAddress="0x20000000"
|
||||
RandomizedBaseAddress="1"
|
||||
DataExecutionPrevention="0"
|
||||
ImportLibrary=".\Debug/gamex86.lib"
|
||||
TargetMachine="1"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCALinkTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCManifestTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCXDCMakeTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCBscMakeTool"
|
||||
SuppressStartupBanner="true"
|
||||
OutputFile=".\Debug/3zb2_2008.bsc"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCFxCopTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCAppVerifierTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCPostBuildEventTool"
|
||||
/>
|
||||
</Configuration>
|
||||
<Configuration
|
||||
Name="Release|x64"
|
||||
OutputDirectory="$(PlatformName)\$(ConfigurationName)"
|
||||
|
@ -302,6 +207,101 @@
|
|||
Name="VCPostBuildEventTool"
|
||||
/>
|
||||
</Configuration>
|
||||
<Configuration
|
||||
Name="Debug|Win32"
|
||||
OutputDirectory=".\Debug"
|
||||
IntermediateDirectory=".\Debug"
|
||||
ConfigurationType="2"
|
||||
InheritedPropertySheets="$(VCInstallDir)VCProjectDefaults\UpgradeFromVC60.vsprops"
|
||||
UseOfMFC="0"
|
||||
ATLMinimizesCRunTimeLibraryUsage="false"
|
||||
>
|
||||
<Tool
|
||||
Name="VCPreBuildEventTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCCustomBuildTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCXMLDataGeneratorTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCWebServiceProxyGeneratorTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCMIDLTool"
|
||||
PreprocessorDefinitions="_DEBUG"
|
||||
MkTypLibCompatible="true"
|
||||
SuppressStartupBanner="true"
|
||||
TargetEnvironment="1"
|
||||
TypeLibraryName=".\Debug/3zb2_2008.tlb"
|
||||
HeaderFileName=""
|
||||
/>
|
||||
<Tool
|
||||
Name="VCCLCompilerTool"
|
||||
Optimization="0"
|
||||
PreprocessorDefinitions="WIN32;_DEBUG;_WINDOWS;BUILDING_REF_GL"
|
||||
RuntimeLibrary="1"
|
||||
PrecompiledHeaderFile=".\Debug/3zb2_2008.pch"
|
||||
AssemblerListingLocation=".\Debug/"
|
||||
ObjectFile=".\Debug/"
|
||||
ProgramDataBaseFileName=".\Debug/"
|
||||
WarningLevel="3"
|
||||
SuppressStartupBanner="true"
|
||||
DebugInformationFormat="1"
|
||||
DisableSpecificWarnings="4996"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCManagedResourceCompilerTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCResourceCompilerTool"
|
||||
PreprocessorDefinitions="_DEBUG"
|
||||
Culture="1033"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCPreLinkEventTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCLinkerTool"
|
||||
AdditionalDependencies="winmm.lib"
|
||||
OutputFile=".\gamex86.dll"
|
||||
LinkIncremental="1"
|
||||
SuppressStartupBanner="true"
|
||||
ModuleDefinitionFile=".\game.def"
|
||||
GenerateDebugInformation="true"
|
||||
ProgramDatabaseFile=".\Debug/gamex86.pdb"
|
||||
SubSystem="2"
|
||||
BaseAddress="0x20000000"
|
||||
RandomizedBaseAddress="1"
|
||||
DataExecutionPrevention="0"
|
||||
ImportLibrary=".\Debug/gamex86.lib"
|
||||
TargetMachine="1"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCALinkTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCManifestTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCXDCMakeTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCBscMakeTool"
|
||||
SuppressStartupBanner="true"
|
||||
OutputFile=".\Debug/3zb2_2008.bsc"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCFxCopTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCAppVerifierTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCPostBuildEventTool"
|
||||
/>
|
||||
</Configuration>
|
||||
<Configuration
|
||||
Name="Debug|x64"
|
||||
OutputDirectory="$(PlatformName)\$(ConfigurationName)"
|
||||
|
@ -417,7 +417,7 @@
|
|||
/>
|
||||
</FileConfiguration>
|
||||
<FileConfiguration
|
||||
Name="Debug|Win32"
|
||||
Name="Release|x64"
|
||||
>
|
||||
<Tool
|
||||
Name="VCCLCompilerTool"
|
||||
|
@ -425,7 +425,7 @@
|
|||
/>
|
||||
</FileConfiguration>
|
||||
<FileConfiguration
|
||||
Name="Release|x64"
|
||||
Name="Debug|Win32"
|
||||
>
|
||||
<Tool
|
||||
Name="VCCLCompilerTool"
|
||||
|
@ -453,7 +453,7 @@
|
|||
/>
|
||||
</FileConfiguration>
|
||||
<FileConfiguration
|
||||
Name="Debug|Win32"
|
||||
Name="Release|x64"
|
||||
>
|
||||
<Tool
|
||||
Name="VCCLCompilerTool"
|
||||
|
@ -461,7 +461,7 @@
|
|||
/>
|
||||
</FileConfiguration>
|
||||
<FileConfiguration
|
||||
Name="Release|x64"
|
||||
Name="Debug|Win32"
|
||||
>
|
||||
<Tool
|
||||
Name="VCCLCompilerTool"
|
||||
|
@ -489,7 +489,7 @@
|
|||
/>
|
||||
</FileConfiguration>
|
||||
<FileConfiguration
|
||||
Name="Debug|Win32"
|
||||
Name="Release|x64"
|
||||
>
|
||||
<Tool
|
||||
Name="VCCLCompilerTool"
|
||||
|
@ -497,7 +497,7 @@
|
|||
/>
|
||||
</FileConfiguration>
|
||||
<FileConfiguration
|
||||
Name="Release|x64"
|
||||
Name="Debug|Win32"
|
||||
>
|
||||
<Tool
|
||||
Name="VCCLCompilerTool"
|
||||
|
@ -525,7 +525,7 @@
|
|||
/>
|
||||
</FileConfiguration>
|
||||
<FileConfiguration
|
||||
Name="Debug|Win32"
|
||||
Name="Release|x64"
|
||||
>
|
||||
<Tool
|
||||
Name="VCCLCompilerTool"
|
||||
|
@ -533,7 +533,7 @@
|
|||
/>
|
||||
</FileConfiguration>
|
||||
<FileConfiguration
|
||||
Name="Release|x64"
|
||||
Name="Debug|Win32"
|
||||
>
|
||||
<Tool
|
||||
Name="VCCLCompilerTool"
|
||||
|
@ -561,7 +561,7 @@
|
|||
/>
|
||||
</FileConfiguration>
|
||||
<FileConfiguration
|
||||
Name="Debug|Win32"
|
||||
Name="Release|x64"
|
||||
>
|
||||
<Tool
|
||||
Name="VCCLCompilerTool"
|
||||
|
@ -569,7 +569,7 @@
|
|||
/>
|
||||
</FileConfiguration>
|
||||
<FileConfiguration
|
||||
Name="Release|x64"
|
||||
Name="Debug|Win32"
|
||||
>
|
||||
<Tool
|
||||
Name="VCCLCompilerTool"
|
||||
|
@ -597,7 +597,7 @@
|
|||
/>
|
||||
</FileConfiguration>
|
||||
<FileConfiguration
|
||||
Name="Debug|Win32"
|
||||
Name="Release|x64"
|
||||
>
|
||||
<Tool
|
||||
Name="VCCLCompilerTool"
|
||||
|
@ -605,7 +605,7 @@
|
|||
/>
|
||||
</FileConfiguration>
|
||||
<FileConfiguration
|
||||
Name="Release|x64"
|
||||
Name="Debug|Win32"
|
||||
>
|
||||
<Tool
|
||||
Name="VCCLCompilerTool"
|
||||
|
@ -633,7 +633,7 @@
|
|||
/>
|
||||
</FileConfiguration>
|
||||
<FileConfiguration
|
||||
Name="Debug|Win32"
|
||||
Name="Release|x64"
|
||||
>
|
||||
<Tool
|
||||
Name="VCCLCompilerTool"
|
||||
|
@ -641,7 +641,7 @@
|
|||
/>
|
||||
</FileConfiguration>
|
||||
<FileConfiguration
|
||||
Name="Release|x64"
|
||||
Name="Debug|Win32"
|
||||
>
|
||||
<Tool
|
||||
Name="VCCLCompilerTool"
|
||||
|
@ -669,7 +669,7 @@
|
|||
/>
|
||||
</FileConfiguration>
|
||||
<FileConfiguration
|
||||
Name="Debug|Win32"
|
||||
Name="Release|x64"
|
||||
>
|
||||
<Tool
|
||||
Name="VCCLCompilerTool"
|
||||
|
@ -677,7 +677,7 @@
|
|||
/>
|
||||
</FileConfiguration>
|
||||
<FileConfiguration
|
||||
Name="Release|x64"
|
||||
Name="Debug|Win32"
|
||||
>
|
||||
<Tool
|
||||
Name="VCCLCompilerTool"
|
||||
|
@ -705,7 +705,7 @@
|
|||
/>
|
||||
</FileConfiguration>
|
||||
<FileConfiguration
|
||||
Name="Debug|Win32"
|
||||
Name="Release|x64"
|
||||
>
|
||||
<Tool
|
||||
Name="VCCLCompilerTool"
|
||||
|
@ -713,7 +713,7 @@
|
|||
/>
|
||||
</FileConfiguration>
|
||||
<FileConfiguration
|
||||
Name="Release|x64"
|
||||
Name="Debug|Win32"
|
||||
>
|
||||
<Tool
|
||||
Name="VCCLCompilerTool"
|
||||
|
@ -741,7 +741,7 @@
|
|||
/>
|
||||
</FileConfiguration>
|
||||
<FileConfiguration
|
||||
Name="Debug|Win32"
|
||||
Name="Release|x64"
|
||||
>
|
||||
<Tool
|
||||
Name="VCCLCompilerTool"
|
||||
|
@ -749,7 +749,7 @@
|
|||
/>
|
||||
</FileConfiguration>
|
||||
<FileConfiguration
|
||||
Name="Release|x64"
|
||||
Name="Debug|Win32"
|
||||
>
|
||||
<Tool
|
||||
Name="VCCLCompilerTool"
|
||||
|
@ -777,7 +777,7 @@
|
|||
/>
|
||||
</FileConfiguration>
|
||||
<FileConfiguration
|
||||
Name="Debug|Win32"
|
||||
Name="Release|x64"
|
||||
>
|
||||
<Tool
|
||||
Name="VCCLCompilerTool"
|
||||
|
@ -785,7 +785,7 @@
|
|||
/>
|
||||
</FileConfiguration>
|
||||
<FileConfiguration
|
||||
Name="Release|x64"
|
||||
Name="Debug|Win32"
|
||||
>
|
||||
<Tool
|
||||
Name="VCCLCompilerTool"
|
||||
|
@ -813,7 +813,7 @@
|
|||
/>
|
||||
</FileConfiguration>
|
||||
<FileConfiguration
|
||||
Name="Debug|Win32"
|
||||
Name="Release|x64"
|
||||
>
|
||||
<Tool
|
||||
Name="VCCLCompilerTool"
|
||||
|
@ -821,7 +821,7 @@
|
|||
/>
|
||||
</FileConfiguration>
|
||||
<FileConfiguration
|
||||
Name="Release|x64"
|
||||
Name="Debug|Win32"
|
||||
>
|
||||
<Tool
|
||||
Name="VCCLCompilerTool"
|
||||
|
@ -853,7 +853,7 @@
|
|||
/>
|
||||
</FileConfiguration>
|
||||
<FileConfiguration
|
||||
Name="Debug|Win32"
|
||||
Name="Release|x64"
|
||||
>
|
||||
<Tool
|
||||
Name="VCCLCompilerTool"
|
||||
|
@ -861,7 +861,7 @@
|
|||
/>
|
||||
</FileConfiguration>
|
||||
<FileConfiguration
|
||||
Name="Release|x64"
|
||||
Name="Debug|Win32"
|
||||
>
|
||||
<Tool
|
||||
Name="VCCLCompilerTool"
|
||||
|
@ -881,6 +881,10 @@
|
|||
RelativePath=".\g_mtrain.c"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath=".\g_newfnc.c"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath="g_phys.c"
|
||||
>
|
||||
|
@ -893,7 +897,7 @@
|
|||
/>
|
||||
</FileConfiguration>
|
||||
<FileConfiguration
|
||||
Name="Debug|Win32"
|
||||
Name="Release|x64"
|
||||
>
|
||||
<Tool
|
||||
Name="VCCLCompilerTool"
|
||||
|
@ -901,7 +905,7 @@
|
|||
/>
|
||||
</FileConfiguration>
|
||||
<FileConfiguration
|
||||
Name="Release|x64"
|
||||
Name="Debug|Win32"
|
||||
>
|
||||
<Tool
|
||||
Name="VCCLCompilerTool"
|
||||
|
@ -929,7 +933,7 @@
|
|||
/>
|
||||
</FileConfiguration>
|
||||
<FileConfiguration
|
||||
Name="Debug|Win32"
|
||||
Name="Release|x64"
|
||||
>
|
||||
<Tool
|
||||
Name="VCCLCompilerTool"
|
||||
|
@ -937,7 +941,7 @@
|
|||
/>
|
||||
</FileConfiguration>
|
||||
<FileConfiguration
|
||||
Name="Release|x64"
|
||||
Name="Debug|Win32"
|
||||
>
|
||||
<Tool
|
||||
Name="VCCLCompilerTool"
|
||||
|
@ -965,7 +969,7 @@
|
|||
/>
|
||||
</FileConfiguration>
|
||||
<FileConfiguration
|
||||
Name="Debug|Win32"
|
||||
Name="Release|x64"
|
||||
>
|
||||
<Tool
|
||||
Name="VCCLCompilerTool"
|
||||
|
@ -973,7 +977,7 @@
|
|||
/>
|
||||
</FileConfiguration>
|
||||
<FileConfiguration
|
||||
Name="Release|x64"
|
||||
Name="Debug|Win32"
|
||||
>
|
||||
<Tool
|
||||
Name="VCCLCompilerTool"
|
||||
|
@ -1001,7 +1005,7 @@
|
|||
/>
|
||||
</FileConfiguration>
|
||||
<FileConfiguration
|
||||
Name="Debug|Win32"
|
||||
Name="Release|x64"
|
||||
>
|
||||
<Tool
|
||||
Name="VCCLCompilerTool"
|
||||
|
@ -1009,7 +1013,7 @@
|
|||
/>
|
||||
</FileConfiguration>
|
||||
<FileConfiguration
|
||||
Name="Release|x64"
|
||||
Name="Debug|Win32"
|
||||
>
|
||||
<Tool
|
||||
Name="VCCLCompilerTool"
|
||||
|
@ -1037,7 +1041,7 @@
|
|||
/>
|
||||
</FileConfiguration>
|
||||
<FileConfiguration
|
||||
Name="Debug|Win32"
|
||||
Name="Release|x64"
|
||||
>
|
||||
<Tool
|
||||
Name="VCCLCompilerTool"
|
||||
|
@ -1045,7 +1049,7 @@
|
|||
/>
|
||||
</FileConfiguration>
|
||||
<FileConfiguration
|
||||
Name="Release|x64"
|
||||
Name="Debug|Win32"
|
||||
>
|
||||
<Tool
|
||||
Name="VCCLCompilerTool"
|
||||
|
@ -1073,7 +1077,7 @@
|
|||
/>
|
||||
</FileConfiguration>
|
||||
<FileConfiguration
|
||||
Name="Debug|Win32"
|
||||
Name="Release|x64"
|
||||
>
|
||||
<Tool
|
||||
Name="VCCLCompilerTool"
|
||||
|
@ -1081,7 +1085,7 @@
|
|||
/>
|
||||
</FileConfiguration>
|
||||
<FileConfiguration
|
||||
Name="Release|x64"
|
||||
Name="Debug|Win32"
|
||||
>
|
||||
<Tool
|
||||
Name="VCCLCompilerTool"
|
||||
|
@ -1109,7 +1113,7 @@
|
|||
/>
|
||||
</FileConfiguration>
|
||||
<FileConfiguration
|
||||
Name="Debug|Win32"
|
||||
Name="Release|x64"
|
||||
>
|
||||
<Tool
|
||||
Name="VCCLCompilerTool"
|
||||
|
@ -1117,7 +1121,7 @@
|
|||
/>
|
||||
</FileConfiguration>
|
||||
<FileConfiguration
|
||||
Name="Release|x64"
|
||||
Name="Debug|Win32"
|
||||
>
|
||||
<Tool
|
||||
Name="VCCLCompilerTool"
|
||||
|
@ -1145,7 +1149,7 @@
|
|||
/>
|
||||
</FileConfiguration>
|
||||
<FileConfiguration
|
||||
Name="Debug|Win32"
|
||||
Name="Release|x64"
|
||||
>
|
||||
<Tool
|
||||
Name="VCCLCompilerTool"
|
||||
|
@ -1153,7 +1157,7 @@
|
|||
/>
|
||||
</FileConfiguration>
|
||||
<FileConfiguration
|
||||
Name="Release|x64"
|
||||
Name="Debug|Win32"
|
||||
>
|
||||
<Tool
|
||||
Name="VCCLCompilerTool"
|
||||
|
@ -1181,7 +1185,7 @@
|
|||
/>
|
||||
</FileConfiguration>
|
||||
<FileConfiguration
|
||||
Name="Debug|Win32"
|
||||
Name="Release|x64"
|
||||
>
|
||||
<Tool
|
||||
Name="VCCLCompilerTool"
|
||||
|
@ -1189,7 +1193,7 @@
|
|||
/>
|
||||
</FileConfiguration>
|
||||
<FileConfiguration
|
||||
Name="Release|x64"
|
||||
Name="Debug|Win32"
|
||||
>
|
||||
<Tool
|
||||
Name="VCCLCompilerTool"
|
||||
|
@ -1217,7 +1221,7 @@
|
|||
/>
|
||||
</FileConfiguration>
|
||||
<FileConfiguration
|
||||
Name="Debug|Win32"
|
||||
Name="Release|x64"
|
||||
>
|
||||
<Tool
|
||||
Name="VCCLCompilerTool"
|
||||
|
@ -1225,7 +1229,7 @@
|
|||
/>
|
||||
</FileConfiguration>
|
||||
<FileConfiguration
|
||||
Name="Release|x64"
|
||||
Name="Debug|Win32"
|
||||
>
|
||||
<Tool
|
||||
Name="VCCLCompilerTool"
|
||||
|
@ -1253,7 +1257,7 @@
|
|||
/>
|
||||
</FileConfiguration>
|
||||
<FileConfiguration
|
||||
Name="Debug|Win32"
|
||||
Name="Release|x64"
|
||||
>
|
||||
<Tool
|
||||
Name="VCCLCompilerTool"
|
||||
|
@ -1261,7 +1265,7 @@
|
|||
/>
|
||||
</FileConfiguration>
|
||||
<FileConfiguration
|
||||
Name="Release|x64"
|
||||
Name="Debug|Win32"
|
||||
>
|
||||
<Tool
|
||||
Name="VCCLCompilerTool"
|
||||
|
@ -1289,7 +1293,7 @@
|
|||
/>
|
||||
</FileConfiguration>
|
||||
<FileConfiguration
|
||||
Name="Debug|Win32"
|
||||
Name="Release|x64"
|
||||
>
|
||||
<Tool
|
||||
Name="VCCLCompilerTool"
|
||||
|
@ -1297,7 +1301,7 @@
|
|||
/>
|
||||
</FileConfiguration>
|
||||
<FileConfiguration
|
||||
Name="Release|x64"
|
||||
Name="Debug|Win32"
|
||||
>
|
||||
<Tool
|
||||
Name="VCCLCompilerTool"
|
||||
|
@ -1325,7 +1329,7 @@
|
|||
/>
|
||||
</FileConfiguration>
|
||||
<FileConfiguration
|
||||
Name="Debug|Win32"
|
||||
Name="Release|x64"
|
||||
>
|
||||
<Tool
|
||||
Name="VCCLCompilerTool"
|
||||
|
@ -1333,7 +1337,7 @@
|
|||
/>
|
||||
</FileConfiguration>
|
||||
<FileConfiguration
|
||||
Name="Release|x64"
|
||||
Name="Debug|Win32"
|
||||
>
|
||||
<Tool
|
||||
Name="VCCLCompilerTool"
|
||||
|
@ -1361,7 +1365,7 @@
|
|||
/>
|
||||
</FileConfiguration>
|
||||
<FileConfiguration
|
||||
Name="Debug|Win32"
|
||||
Name="Release|x64"
|
||||
>
|
||||
<Tool
|
||||
Name="VCCLCompilerTool"
|
||||
|
@ -1369,7 +1373,7 @@
|
|||
/>
|
||||
</FileConfiguration>
|
||||
<FileConfiguration
|
||||
Name="Release|x64"
|
||||
Name="Debug|Win32"
|
||||
>
|
||||
<Tool
|
||||
Name="VCCLCompilerTool"
|
||||
|
@ -1397,7 +1401,7 @@
|
|||
/>
|
||||
</FileConfiguration>
|
||||
<FileConfiguration
|
||||
Name="Debug|Win32"
|
||||
Name="Release|x64"
|
||||
>
|
||||
<Tool
|
||||
Name="VCCLCompilerTool"
|
||||
|
@ -1405,7 +1409,7 @@
|
|||
/>
|
||||
</FileConfiguration>
|
||||
<FileConfiguration
|
||||
Name="Release|x64"
|
||||
Name="Debug|Win32"
|
||||
>
|
||||
<Tool
|
||||
Name="VCCLCompilerTool"
|
||||
|
@ -1433,7 +1437,7 @@
|
|||
/>
|
||||
</FileConfiguration>
|
||||
<FileConfiguration
|
||||
Name="Debug|Win32"
|
||||
Name="Release|x64"
|
||||
>
|
||||
<Tool
|
||||
Name="VCCLCompilerTool"
|
||||
|
@ -1441,7 +1445,7 @@
|
|||
/>
|
||||
</FileConfiguration>
|
||||
<FileConfiguration
|
||||
Name="Release|x64"
|
||||
Name="Debug|Win32"
|
||||
>
|
||||
<Tool
|
||||
Name="VCCLCompilerTool"
|
||||
|
|
202
3zb2/bot_func.c
202
3zb2/bot_func.c
|
@ -10,18 +10,18 @@ qboolean Get_YenPos(char *Buff,int *curr)
|
|||
|
||||
while(1)
|
||||
{
|
||||
// if(i >= strlen(Buff)) return false;
|
||||
if(Buff[i] == 0 || Buff[i] == 10 || Buff[i] == 13)
|
||||
// if (i >= strlen(Buff)) return false;
|
||||
if (Buff[i] == 0 || Buff[i] == 10 || Buff[i] == 13)
|
||||
{
|
||||
*curr = i;
|
||||
return true;
|
||||
}
|
||||
if(Buff[i] == '\\')
|
||||
if (Buff[i] == '\\')
|
||||
{
|
||||
*curr = i;
|
||||
return true;
|
||||
}
|
||||
if(Buff[i] == '\t') Buff[i] = 0;
|
||||
if (Buff[i] == '\t') Buff[i] = 0;
|
||||
i++;
|
||||
}
|
||||
}
|
||||
|
@ -45,10 +45,14 @@ void Load_BotInfo()
|
|||
//init message
|
||||
memset(ClientMessage,0,sizeof(ClientMessage));
|
||||
//set message section
|
||||
if(!ctf->value && chedit->value) strcpy(MessageSection,MESS_CHAIN_DM);
|
||||
else if(ctf->value && !chedit->value) strcpy(MessageSection,MESS_CTF);
|
||||
else if(ctf->value && chedit->value) strcpy(MessageSection,MESS_CHAIN_CTF);
|
||||
else strcpy(MessageSection,MESS_DEATHMATCH);
|
||||
if (!ctf->value && chedit->value)
|
||||
Com_strcpy (MessageSection, sizeof(MessageSection), MESS_CHAIN_DM);
|
||||
else if (ctf->value && !chedit->value)
|
||||
Com_strcpy (MessageSection, sizeof(MessageSection), MESS_CTF);
|
||||
else if (ctf->value && chedit->value)
|
||||
Com_strcpy (MessageSection, sizeof(MessageSection), MESS_CHAIN_CTF);
|
||||
else
|
||||
Com_strcpy (MessageSection, sizeof(MessageSection), MESS_DEATHMATCH);
|
||||
|
||||
//init botlist
|
||||
ListedBots = 0;
|
||||
|
@ -56,12 +60,12 @@ void Load_BotInfo()
|
|||
for(i = 0;i < MAXBOTS;i++)
|
||||
{
|
||||
//netname
|
||||
sprintf(Buff,"Zigock[%i]",i);
|
||||
strcpy(Bot[i].netname,Buff);
|
||||
Com_sprintf (Buff, sizeof(Buff), "Zigock[%i]",i);
|
||||
Com_strcpy (Bot[i].netname, sizeof(Bot[i].netname), Buff);
|
||||
//model
|
||||
strcpy(Bot[i].model,"male");
|
||||
Com_strcpy (Bot[i].model, sizeof(Bot[i].model), "male");
|
||||
//skin
|
||||
strcpy(Bot[i].model,"grunt");
|
||||
Com_strcpy (Bot[i].model, sizeof(Bot[i].model), "grunt");
|
||||
|
||||
//param
|
||||
Bot[i].param[BOP_WALK] = 0;
|
||||
|
@ -77,7 +81,7 @@ void Load_BotInfo()
|
|||
Bot[i].spflg = 0;
|
||||
//team
|
||||
Bot[i].team = j;
|
||||
if(++j > 2) j = 1;
|
||||
if (++j > 2) j = 1;
|
||||
}
|
||||
|
||||
//botlist value
|
||||
|
@ -85,9 +89,9 @@ void Load_BotInfo()
|
|||
gamepath = gi.cvar ("game", "0", CVAR_NOSET);
|
||||
|
||||
//load info
|
||||
sprintf(Buff,".\\%s\\3ZBconfig.cfg",gamepath->string);
|
||||
fp = fopen(Buff,"rt");
|
||||
if(fp == NULL)
|
||||
Com_sprintf (Buff, sizeof(Buff), ".\\%s\\3ZBconfig.cfg",gamepath->string);
|
||||
fp = fopen(Buff, "rt");
|
||||
if (fp == NULL)
|
||||
{
|
||||
gi.dprintf("3ZB CFG: file not found.\n");
|
||||
return;
|
||||
|
@ -97,75 +101,79 @@ void Load_BotInfo()
|
|||
fseek( fp, 0, SEEK_SET); //先頭へ移動
|
||||
while(1)
|
||||
{
|
||||
if(fgets( Buff, sizeof(Buff), fp ) == NULL) goto MESS_NOTFOUND;
|
||||
if(!Q_strncasecmp(MessageSection,Buff,strlen(MessageSection))) break; // Knightmare- was _strnicmp()
|
||||
if (fgets( Buff, sizeof(Buff), fp ) == NULL) goto MESS_NOTFOUND;
|
||||
if (!Q_strncasecmp(MessageSection,Buff,strlen(MessageSection))) break; // Knightmare- was _strnicmp()
|
||||
}
|
||||
|
||||
while(1)
|
||||
{
|
||||
if(fgets( Buff, sizeof(Buff), fp ) == NULL) goto MESS_NOTFOUND;
|
||||
if(Buff[0] == '.' || Buff[0] == '[' || Buff[0] == '#') break;
|
||||
if (fgets( Buff, sizeof(Buff), fp ) == NULL) goto MESS_NOTFOUND;
|
||||
if (Buff[0] == '.' || Buff[0] == '[' || Buff[0] == '#') break;
|
||||
k = (int)strlen(Buff);
|
||||
if((strlen(Buff) + strlen(ClientMessage)) > MAX_STRING_CHARS - 1) break;
|
||||
strcat(ClientMessage,Buff);
|
||||
if ((strlen(Buff) + strlen(ClientMessage)) > MAX_STRING_CHARS - 1) break;
|
||||
Com_strcat (ClientMessage, sizeof(ClientMessage), Buff);
|
||||
}
|
||||
MESS_NOTFOUND:
|
||||
//if(botlist->string == NULL) strcpy(MessageSection,BOTLIST_SECTION_DM);
|
||||
//else
|
||||
sprintf(MessageSection,"[%s]",botlist->string);
|
||||
// if (botlist->string == NULL)
|
||||
// Com_strcpy (MessageSection, sizeof(MessageSection), BOTLIST_SECTION_DM);
|
||||
// else
|
||||
Com_sprintf (MessageSection, sizeof(MessageSection), "[%s]",botlist->string);
|
||||
fseek( fp, 0, SEEK_SET); //先頭へ移動
|
||||
while(1)
|
||||
{
|
||||
if(fgets( Buff, sizeof(Buff), fp ) == NULL)
|
||||
if (fgets( Buff, sizeof(Buff), fp ) == NULL)
|
||||
{
|
||||
MessageSection[0] = 0;
|
||||
break;
|
||||
}
|
||||
if(!Q_strncasecmp(MessageSection,Buff,strlen(MessageSection))) break; // Knightmare- was _strnicmp()
|
||||
if (!Q_strncasecmp(MessageSection, Buff,strlen(MessageSection))) break; // Knightmare- was _strnicmp()
|
||||
}
|
||||
//when not found
|
||||
if(MessageSection[0] == 0)
|
||||
if (MessageSection[0] == 0)
|
||||
{
|
||||
strcpy(MessageSection,BOTLIST_SECTION_DM);
|
||||
Com_strcpy (MessageSection, sizeof(MessageSection), BOTLIST_SECTION_DM);
|
||||
fseek( fp, 0, SEEK_SET); //先頭へ移動
|
||||
while(1)
|
||||
{
|
||||
if(fgets( Buff, sizeof(Buff), fp ) == NULL) goto BOTLIST_NOTFOUND;
|
||||
if(!Q_strncasecmp(MessageSection,Buff,strlen(MessageSection))) break; // Knightmare- was _strnicmp()
|
||||
if (fgets( Buff, sizeof(Buff), fp ) == NULL) goto BOTLIST_NOTFOUND;
|
||||
if (!Q_strncasecmp(MessageSection, Buff, strlen(MessageSection))) break; // Knightmare- was _strnicmp()
|
||||
}
|
||||
}
|
||||
|
||||
i = 0;
|
||||
for(i = 0;i < MAXBOTS;i++)
|
||||
{
|
||||
if(fgets( Buff, sizeof(Buff), fp ) == NULL) break;
|
||||
if(Buff[0] == '[') break;
|
||||
if(Buff[0] == '\n' || Buff[0] == '#') {i--;continue;}
|
||||
if (fgets( Buff, sizeof(Buff), fp ) == NULL) break;
|
||||
if (Buff[0] == '[') break;
|
||||
if (Buff[0] == '\n' || Buff[0] == '#') {i--;continue;}
|
||||
j = 2,k = 1;
|
||||
if(!strncmp(Buff,"\\\\",2))
|
||||
if (!strncmp(Buff,"\\\\",2))
|
||||
{
|
||||
//netname
|
||||
if(Get_YenPos(Buff,&k))
|
||||
if (Get_YenPos(Buff,&k))
|
||||
{
|
||||
Buff[k] = 0;
|
||||
if(strlen(&Buff[j]) < 21) strcpy(Bot[i].netname,&Buff[j]);
|
||||
if (strlen(&Buff[j]) < 21)
|
||||
Com_strcpy (Bot[i].netname, sizeof(Bot[i].netname), &Buff[j]);
|
||||
j = k + 1;
|
||||
}
|
||||
else break;
|
||||
//model name
|
||||
if(Get_YenPos(Buff,&k))
|
||||
if (Get_YenPos(Buff,&k))
|
||||
{
|
||||
Buff[k] = 0;
|
||||
if(strlen(&Buff[j]) < 21) strcpy(Bot[i].model,&Buff[j]);
|
||||
if (strlen(&Buff[j]) < 21)
|
||||
Com_strcpy (Bot[i].model, sizeof(Bot[i].model), &Buff[j]);
|
||||
j = k + 1;
|
||||
k++;
|
||||
}
|
||||
else break;
|
||||
//skin name
|
||||
if(Get_YenPos(Buff,&k))
|
||||
if (Get_YenPos(Buff,&k))
|
||||
{
|
||||
Buff[k] = 0;
|
||||
if(strlen(&Buff[j]) < 21) strcpy(Bot[i].skin,&Buff[j]);
|
||||
if (strlen(&Buff[j]) < 21)
|
||||
Com_strcpy (Bot[i].skin, sizeof(Bot[i].skin), &Buff[j]);
|
||||
j = k + 1;
|
||||
k++;
|
||||
}
|
||||
|
@ -173,7 +181,7 @@ MESS_NOTFOUND:
|
|||
for(l = 0;l < MAXBOP;l++)
|
||||
{
|
||||
//param0-7
|
||||
if(Get_YenPos(Buff,&k))
|
||||
if (Get_YenPos(Buff,&k))
|
||||
{
|
||||
Buff[k] = 0;
|
||||
Bot[i].param[l] = (unsigned char)atoi(&Buff[j]);
|
||||
|
@ -182,25 +190,25 @@ MESS_NOTFOUND:
|
|||
}
|
||||
else break;
|
||||
}
|
||||
if(l < MAXBOP) break;
|
||||
if (l < MAXBOP) break;
|
||||
//team
|
||||
if(Get_YenPos(Buff,&k))
|
||||
if (Get_YenPos(Buff,&k))
|
||||
{
|
||||
Buff[k] = 0;
|
||||
if(Buff[j] == 'R') Bot[i].team = 1;
|
||||
else if(Buff[j] == 'B') Bot[i].team = 2;
|
||||
if (Buff[j] == 'R') Bot[i].team = 1;
|
||||
else if (Buff[j] == 'B') Bot[i].team = 2;
|
||||
else Bot[i].team = 1;
|
||||
j = k + 1;
|
||||
k++;
|
||||
}
|
||||
else break;
|
||||
//auto spawn
|
||||
if(Get_YenPos(Buff,&k))
|
||||
if (Get_YenPos(Buff,&k))
|
||||
{
|
||||
Buff[k] = 0;
|
||||
Bot[i].spflg = atoi(&Buff[j]);
|
||||
//gi.dprintf("%i %s\n",Bot[i].spflg,&Buff[j]);
|
||||
if(Bot[i].spflg == BOT_SPRESERVED && autospawn->value && !chedit->value) SpawnWaitingBots++;
|
||||
if (Bot[i].spflg == BOT_SPRESERVED && autospawn->value && !chedit->value) SpawnWaitingBots++;
|
||||
else Bot[i].spflg = BOT_SPAWNNOT;
|
||||
}
|
||||
else break;
|
||||
|
@ -282,21 +290,21 @@ void Bot_Think (edict_t *self)
|
|||
M_CheckGround (self);
|
||||
}
|
||||
|
||||
if(self->deadflag)
|
||||
if (self->deadflag)
|
||||
{
|
||||
if(self->client->ctf_grapple) CTFPlayerResetGrapple(self);
|
||||
if (self->client->ctf_grapple) CTFPlayerResetGrapple(self);
|
||||
|
||||
if(self->s.modelindex == skullindex || self->s.modelindex == headindex) self->s.frame = 0;
|
||||
else if(self->s.frame < FRAME_crdeath1 && self->s.frame != 0) self->s.frame = FRAME_death308;
|
||||
if (self->s.modelindex == skullindex || self->s.modelindex == headindex) self->s.frame = 0;
|
||||
else if (self->s.frame < FRAME_crdeath1 && self->s.frame != 0) self->s.frame = FRAME_death308;
|
||||
self->s.modelindex2 = 0; // remove linked weapon model
|
||||
//ZOID
|
||||
self->s.modelindex3 = 0; // remove linked ctf flag
|
||||
//ZOID
|
||||
|
||||
self->client->zc.route_trace = false;
|
||||
if(self->client->respawn_time <= level.time)
|
||||
if (self->client->respawn_time <= level.time)
|
||||
{
|
||||
if(self->svflags & SVF_MONSTER)
|
||||
if (self->svflags & SVF_MONSTER)
|
||||
{
|
||||
self->client->respawn_time = level.time;
|
||||
CopyToBodyQue (self);
|
||||
|
@ -307,7 +315,7 @@ void Bot_Think (edict_t *self)
|
|||
else
|
||||
{
|
||||
Bots_Move_NORM (self);
|
||||
if(!self->inuse) return; //removed botself
|
||||
if (!self->inuse) return; //removed botself
|
||||
|
||||
client = self->client;
|
||||
|
||||
|
@ -353,7 +361,7 @@ void InitializeBot (edict_t *ent,int botindex )
|
|||
client->resp.enterframe = level.framenum;
|
||||
|
||||
//set netname model skil and CTF team
|
||||
sprintf(pinfo,"\\rate\\25000\\msg\\1\\fov\\90\\skin\\%s/%s\\name\\%s\\hand\\0",Bot[botindex].model,Bot[botindex].skin,Bot[botindex].netname);
|
||||
Com_sprintf (pinfo, sizeof(pinfo), "\\rate\\25000\\msg\\1\\fov\\90\\skin\\%s/%s\\name\\%s\\hand\\0",Bot[botindex].model,Bot[botindex].skin,Bot[botindex].netname);
|
||||
ent->client->resp.ctf_team = Bot[botindex].team; //CTF_TEAM1,CTF_TEAM2
|
||||
|
||||
ClientUserinfoChanged (ent, pinfo);
|
||||
|
@ -376,7 +384,7 @@ void InitializeBot (edict_t *ent,int botindex )
|
|||
gi.dprintf ("%s connected\n", ent->client->pers.netname);
|
||||
// gi.bprintf (PRINT_HIGH, "%s entered the game\n", ent->client->pers.netname);
|
||||
|
||||
if(ctf->value) gi.bprintf(PRINT_HIGH, "%s joined the %s team.\n",
|
||||
if (ctf->value) gi.bprintf(PRINT_HIGH, "%s joined the %s team.\n",
|
||||
client->pers.netname, CTFTeamName(ent->client->resp.ctf_team));
|
||||
else gi.bprintf (PRINT_HIGH, "%s entered the game\n",
|
||||
client->pers.netname);
|
||||
|
@ -429,7 +437,7 @@ void PutBotInServer (edict_t *ent)
|
|||
client->ctf_grapple = NULL;
|
||||
|
||||
item = FindItem("Grapple");
|
||||
if(ctf->value) client->pers.inventory[ITEM_INDEX(item)] = 1; //ponpoko
|
||||
if (ctf->value) client->pers.inventory[ITEM_INDEX(item)] = 1; //ponpoko
|
||||
//ZOID
|
||||
|
||||
// clear entity values
|
||||
|
@ -480,7 +488,7 @@ void PutBotInServer (edict_t *ent)
|
|||
VectorCopy (spawn_angles, ent->s.angles);
|
||||
spawn_origin[2] -= 300;
|
||||
rs_trace = gi.trace(ent->s.origin,ent->mins,ent->maxs,spawn_origin,ent,MASK_SOLID);
|
||||
if(!rs_trace.allsolid) VectorCopy (rs_trace.endpos, ent->s.origin);
|
||||
if (!rs_trace.allsolid) VectorCopy (rs_trace.endpos, ent->s.origin);
|
||||
VectorSet(ent->velocity,0,0,0);
|
||||
ent->moveinfo.speed = 0;
|
||||
ent->groundentity = rs_trace.ent;
|
||||
|
@ -512,14 +520,14 @@ void PutBotInServer (edict_t *ent)
|
|||
zc->first_target = NULL;
|
||||
zc->zcstate = STS_IDLE;
|
||||
|
||||
if(ent->client->resp.enterframe == level.framenum && !chedit->value)
|
||||
if (ent->client->resp.enterframe == level.framenum && !chedit->value)
|
||||
{
|
||||
gi.WriteByte (svc_muzzleflash);
|
||||
gi.WriteShort (ent-g_edicts);
|
||||
gi.WriteByte (MZ_LOGIN);
|
||||
gi.multicast (ent->s.origin, MULTICAST_PVS);
|
||||
}
|
||||
else if(!chedit->value)
|
||||
else if (!chedit->value)
|
||||
{
|
||||
gi.WriteByte (svc_muzzleflash);
|
||||
gi.WriteShort (ent-g_edicts);
|
||||
|
@ -532,12 +540,12 @@ void PutBotInServer (edict_t *ent)
|
|||
entcount = gi.BoxEdicts ( ent->absmin ,ent->absmax,touch,MAX_EDICTS,AREA_SOLID);
|
||||
while (entcount-- > 0)
|
||||
{
|
||||
if(Q_stricmp (touch[entcount]->classname, "player") == 0)
|
||||
if(touch[entcount] != ent)
|
||||
if (Q_stricmp (touch[entcount]->classname, "player") == 0)
|
||||
if (touch[entcount] != ent)
|
||||
T_Damage (touch[entcount], ent, ent, vec3_origin, touch[entcount]->s.origin, vec3_origin, 100000, 0, DAMAGE_NO_PROTECTION, MOD_TELEFRAG);
|
||||
}
|
||||
|
||||
if(ctf->value)
|
||||
if (ctf->value)
|
||||
{
|
||||
CTFPlayerResetGrapple(ent);
|
||||
client->zc.ctfstate = CTFS_OFFENCER;
|
||||
|
@ -566,28 +574,28 @@ qboolean SpawnBot(int i)
|
|||
//gi.cprintf (NULL,PRINT_HIGH,"Called %s %s %s\n",Bot[i].netname,Bot[i].model,Bot[i].skin);
|
||||
//return false;
|
||||
|
||||
if( Get_NumOfPlayer () >= game.maxclients )
|
||||
if ( Get_NumOfPlayer () >= game.maxclients )
|
||||
{
|
||||
gi.cprintf (NULL,PRINT_HIGH,"Can't add bots\n");
|
||||
return false;
|
||||
}
|
||||
|
||||
bot = Get_NewClient();
|
||||
if(bot == NULL) return false;
|
||||
if (bot == NULL) return false;
|
||||
|
||||
InitializeBot( bot , i);
|
||||
PutBotInServer ( bot );
|
||||
|
||||
j = targetindex;
|
||||
if(chedit->value)
|
||||
if (chedit->value)
|
||||
{
|
||||
for(k = CurrentIndex - 1;k > 0 ;k--)
|
||||
{
|
||||
if(Route[k].index == 0) break;
|
||||
if (Route[k].index == 0) break;
|
||||
|
||||
if(Route[k].state == GRS_NORMAL)
|
||||
if (Route[k].state == GRS_NORMAL)
|
||||
{
|
||||
if(--j <= 0) break;
|
||||
if (--j <= 0) break;
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -607,7 +615,7 @@ qboolean SpawnBot(int i)
|
|||
gi.multicast (bot->s.origin, MULTICAST_PVS);
|
||||
|
||||
ent = &g_edicts[1];
|
||||
if(ent->inuse && ent->client && !(ent->svflags & SVF_MONSTER))
|
||||
if (ent->inuse && ent->client && !(ent->svflags & SVF_MONSTER))
|
||||
{
|
||||
ent->takedamage = DAMAGE_NO;
|
||||
ent->movetype = MOVETYPE_NOCLIP;
|
||||
|
@ -636,9 +644,9 @@ void Bot_SpawnCall()
|
|||
|
||||
for(i = 0;i < MAXBOTS;i++)
|
||||
{
|
||||
if(Bot[i].spflg == BOT_SPRESERVED)
|
||||
if (Bot[i].spflg == BOT_SPRESERVED)
|
||||
{
|
||||
if(SpawnBot(i)) Bot[i].spflg = BOT_SPAWNED;
|
||||
if (SpawnBot(i)) Bot[i].spflg = BOT_SPAWNED;
|
||||
else
|
||||
{
|
||||
Bot[i].spflg = BOT_SPAWNNOT;
|
||||
|
@ -661,7 +669,7 @@ void SpawnBotReserving()
|
|||
|
||||
for(i = 0;i < MAXBOTS; i++)
|
||||
{
|
||||
if(Bot[i].spflg == BOT_SPAWNNOT)
|
||||
if (Bot[i].spflg == BOT_SPAWNNOT)
|
||||
{
|
||||
Bot[i].spflg = BOT_SPRESERVED;
|
||||
SpawnWaitingBots++;
|
||||
|
@ -684,16 +692,16 @@ void SpawnBotReserving2(int *red,int *blue)
|
|||
|
||||
for(i = 0;i < ListedBots; i++,j++)
|
||||
{
|
||||
if(j >= ListedBots) j = 0;
|
||||
if(Bot[j].spflg == BOT_SPAWNNOT)
|
||||
if (j >= ListedBots) j = 0;
|
||||
if (Bot[j].spflg == BOT_SPAWNNOT)
|
||||
{
|
||||
Bot[j].spflg = BOT_SPRESERVED;
|
||||
SpawnWaitingBots++;
|
||||
if(*red > *blue) Bot[j].team = 2;
|
||||
if (*red > *blue) Bot[j].team = 2;
|
||||
else Bot[j].team = 1;
|
||||
|
||||
if(Bot[j].team == 1) *red = *red + 1;
|
||||
else if(Bot[j].team == 2) *blue = *blue + 1;
|
||||
if (Bot[j].team == 1) *red = *red + 1;
|
||||
else if (Bot[j].team == 2) *blue = *blue + 1;
|
||||
//gi.cprintf(NULL,PRINT_HIGH,"team %i\n",Bot[j].team);
|
||||
return;
|
||||
}
|
||||
|
@ -718,13 +726,13 @@ void RemoveBot()
|
|||
|
||||
for(i = MAXBOTS - 1;i >= 0;i--)
|
||||
{
|
||||
if(Bot[i].spflg == BOT_SPAWNED || Bot[i].spflg == BOT_NEXTLEVEL)
|
||||
if (Bot[i].spflg == BOT_SPAWNED || Bot[i].spflg == BOT_NEXTLEVEL)
|
||||
{
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if(i < 0)
|
||||
if (i < 0)
|
||||
{
|
||||
gi.cprintf (NULL, PRINT_HIGH, "No Bots in server.");
|
||||
return;
|
||||
|
@ -735,16 +743,16 @@ void RemoveBot()
|
|||
e = &g_edicts[(int)maxclients->value];
|
||||
for ( i = maxclients->value ; i >= 1 ; i--, e--)
|
||||
{
|
||||
if(!e->inuse) continue;
|
||||
if (!e->inuse) continue;
|
||||
client = /*e->client;*/&game.clients[i - 1];
|
||||
if(client == NULL) continue;
|
||||
if (client == NULL) continue;
|
||||
// the first couple seconds of server time can involve a lot of
|
||||
// freeing and allocating, so relax the replacement policy
|
||||
if (!client->pers.connected && (e->svflags & SVF_MONSTER))
|
||||
{
|
||||
if(client->zc.botindex == botindex)
|
||||
if (client->zc.botindex == botindex)
|
||||
{
|
||||
if(Bot[botindex].spflg != BOT_NEXTLEVEL) Bot[botindex].spflg = BOT_SPAWNNOT;
|
||||
if (Bot[botindex].spflg != BOT_NEXTLEVEL) Bot[botindex].spflg = BOT_SPAWNNOT;
|
||||
else Bot[botindex].spflg = BOT_SPRESERVED;
|
||||
|
||||
gi.bprintf (PRINT_HIGH, "%s disconnected\n", e->client->pers.netname);
|
||||
|
@ -771,11 +779,11 @@ void RemoveBot()
|
|||
e->inuse = false;
|
||||
G_FreeEdict (e);
|
||||
|
||||
if(targetindex)
|
||||
if (targetindex)
|
||||
{
|
||||
ent = &g_edicts[1];
|
||||
|
||||
if(ent->inuse)
|
||||
if (ent->inuse)
|
||||
{
|
||||
ent->health = 100;
|
||||
ent->movetype = MOVETYPE_WALK;
|
||||
|
@ -810,9 +818,9 @@ void Bot_LevelChange()
|
|||
|
||||
for(i = 0;i < MAXBOTS;i++)
|
||||
{
|
||||
if(Bot[i].spflg)
|
||||
if (Bot[i].spflg)
|
||||
{
|
||||
if(Bot[i].spflg == BOT_SPAWNED)
|
||||
if (Bot[i].spflg == BOT_SPAWNED)
|
||||
{
|
||||
k++;
|
||||
Bot[i].spflg = BOT_NEXTLEVEL;
|
||||
|
@ -845,7 +853,7 @@ void ZigockClientJoin(edict_t *ent,int zclass)
|
|||
ent->client->ps.pmove.pm_flags = PMF_TIME_TELEPORT;
|
||||
ent->client->ps.pmove.pm_time = 14;
|
||||
|
||||
if(ctf->value)
|
||||
if (ctf->value)
|
||||
{
|
||||
gi.bprintf(PRINT_HIGH, "%s joined the %s team.\n",
|
||||
ent->client->pers.netname, CTFTeamName(ent->client->resp.ctf_team/*desired_team*/));
|
||||
|
@ -944,7 +952,7 @@ void AirSight_Think(edict_t *ent)
|
|||
ent->s.modelindex = gi.modelindex ("sprites/airsight.sp2");
|
||||
VectorCopy(ent->target_ent->s.origin,ent->s.origin);
|
||||
|
||||
if( ent->owner->client->resp.ctf_team == CTF_TEAM2 && ctf->value)
|
||||
if ( ent->owner->client->resp.ctf_team == CTF_TEAM2 && ctf->value)
|
||||
{
|
||||
ent->s.frame = 1;
|
||||
}
|
||||
|
@ -973,16 +981,16 @@ void AirStrike_Think(edict_t *ent)
|
|||
for ( i = 1 ; i <= maxclients->value; i++)
|
||||
{
|
||||
target = &g_edicts[i];
|
||||
if(!target->inuse || target->deadflag || target == ent->owner) continue;
|
||||
if (!target->inuse || target->deadflag || target == ent->owner) continue;
|
||||
|
||||
if( target->classname[0] == 'p')
|
||||
if ( target->classname[0] == 'p')
|
||||
{
|
||||
//ctf ならチームメイト無視
|
||||
if(!ctf->value || (ctf->value && ent->owner->client->resp.ctf_team != target->client->resp.ctf_team))
|
||||
if (!ctf->value || (ctf->value && ent->owner->client->resp.ctf_team != target->client->resp.ctf_team))
|
||||
{
|
||||
rs_trace = gi.trace (point,NULL,NULL,target->s.origin,ent, CONTENTS_SOLID | CONTENTS_WINDOW | CONTENTS_LAVA | CONTENTS_SLIME);
|
||||
|
||||
if(rs_trace.fraction == 1.0)
|
||||
if (rs_trace.fraction == 1.0)
|
||||
{
|
||||
sight = G_Spawn();
|
||||
|
||||
|
@ -1015,12 +1023,12 @@ void Cmd_AirStrike(edict_t *ent)
|
|||
|
||||
rs_trace = gi.trace (ent->s.origin,NULL,NULL,strpoint,ent, MASK_SHOT);
|
||||
|
||||
if(!(rs_trace.surface && (rs_trace.surface->flags & SURF_SKY)))
|
||||
if (!(rs_trace.surface && (rs_trace.surface->flags & SURF_SKY)))
|
||||
{
|
||||
gi.cprintf(ent,PRINT_HIGH,"can't call Viper.\n");
|
||||
return;
|
||||
}
|
||||
/* if((rs_trace.endpos[2] - ent->s.origin[2]) < 300)
|
||||
/* if ((rs_trace.endpos[2] - ent->s.origin[2]) < 300)
|
||||
{
|
||||
gi.cprintf(ent,PRINT_HIGH,"can't call Viper.\n");
|
||||
}*/
|
||||
|
|
2496
3zb2/bot_za.c
2496
3zb2/bot_za.c
File diff suppressed because it is too large
Load diff
|
@ -12,7 +12,7 @@ char *ClientTeam (edict_t *ent)
|
|||
if (!ent->client)
|
||||
return value;
|
||||
|
||||
strcpy(value, Info_ValueForKey (ent->client->pers.userinfo, "skin"));
|
||||
Com_strcpy (value, sizeof(value), Info_ValueForKey (ent->client->pers.userinfo, "skin"));
|
||||
p = strchr(value, '/');
|
||||
if (!p)
|
||||
return value;
|
||||
|
@ -35,8 +35,8 @@ qboolean OnSameTeam (edict_t *ent1, edict_t *ent2)
|
|||
if (!((int)(dmflags->value) & (DF_MODELTEAMS | DF_SKINTEAMS)))
|
||||
return false;
|
||||
|
||||
strcpy (ent1Team, ClientTeam (ent1));
|
||||
strcpy (ent2Team, ClientTeam (ent2));
|
||||
Com_strcpy (ent1Team, sizeof(ent1Team), ClientTeam (ent1));
|
||||
Com_strcpy (ent2Team, sizeof(ent2Team), ClientTeam (ent2));
|
||||
|
||||
if (strcmp(ent1Team, ent2Team) == 0)
|
||||
return true;
|
||||
|
@ -829,10 +829,10 @@ void Cmd_Players_f (edict_t *ent)
|
|||
game.clients[index[i]].pers.netname);
|
||||
if (strlen (small) + strlen(large) > sizeof(large) - 100 )
|
||||
{ // can't print all of them in one packet
|
||||
strcat (large, "...\n");
|
||||
Com_strcat (large, sizeof(large), "...\n");
|
||||
break;
|
||||
}
|
||||
strcat (large, small);
|
||||
Com_strcat (large, sizeof(large), small);
|
||||
}
|
||||
|
||||
gi.cprintf (ent, PRINT_HIGH, "%s\n%i players\n", large, count);
|
||||
|
@ -914,9 +914,9 @@ void Cmd_Say_f (edict_t *ent, qboolean team, qboolean arg0)
|
|||
|
||||
if (arg0)
|
||||
{
|
||||
strcat (text, gi.argv(0));
|
||||
strcat (text, " ");
|
||||
strcat (text, gi.args());
|
||||
Com_strcat (text, sizeof(text), gi.argv(0));
|
||||
Com_strcat (text, sizeof(text), " ");
|
||||
Com_strcat (text, sizeof(text), gi.args());
|
||||
}
|
||||
else
|
||||
{
|
||||
|
@ -927,14 +927,14 @@ void Cmd_Say_f (edict_t *ent, qboolean team, qboolean arg0)
|
|||
p++;
|
||||
p[strlen(p)-1] = 0;
|
||||
}
|
||||
strcat(text, p);
|
||||
Com_strcat (text, sizeof(text), p);
|
||||
}
|
||||
|
||||
// don't let text be too long for malicious reasons
|
||||
if (strlen(text) > 150)
|
||||
text[150] = 0;
|
||||
|
||||
strcat(text, "\n");
|
||||
Com_strcat (text, sizeof(text), "\n");
|
||||
|
||||
if (dedicated->value)
|
||||
gi.cprintf(NULL, PRINT_CHAT, "%s", text);
|
||||
|
|
417
3zb2/g_ctf.c
417
3zb2/g_ctf.c
File diff suppressed because it is too large
Load diff
529
3zb2/g_func.c
529
3zb2/g_func.c
|
@ -100,13 +100,13 @@ void train_spline (edict_t *self)
|
|||
VectorScale(train->velocity, 10 ,train->velocity);
|
||||
VectorSubtract(a, train->s.angles, train->avelocity);
|
||||
VectorScale(train->avelocity, 10, train->avelocity);
|
||||
if(train->pitch_speed < 0)
|
||||
if (train->pitch_speed < 0)
|
||||
train->avelocity[PITCH] = 0;
|
||||
if (train->yaw_speed < 0)
|
||||
train->avelocity[YAW] = 0;
|
||||
gi.linkentity(train);
|
||||
train->moveinfo.ratio += train->moveinfo.speed * FRAMETIME / train->moveinfo.distance;
|
||||
// if(train->movewith_next && (train->movewith_next->movewith_ent == train))
|
||||
// if (train->movewith_next && (train->movewith_next->movewith_ent == train))
|
||||
// set_child_movement(train);
|
||||
if (train->moveinfo.ratio >= 1.0)
|
||||
{
|
||||
|
@ -155,6 +155,14 @@ void train_spline (edict_t *self)
|
|||
|
||||
#define PLAT_LOW_TRIGGER 1
|
||||
|
||||
//====
|
||||
//PGM
|
||||
#define PLAT2_TOGGLE 2
|
||||
#define PLAT2_TOP 4
|
||||
#define PLAT2_TRIGGER_TOP 8
|
||||
#define PLAT2_TRIGGER_BOTTOM 16
|
||||
#define PLAT2_BOX_LIFT 32
|
||||
|
||||
#define STATE_TOP 0
|
||||
#define STATE_BOTTOM 1
|
||||
#define STATE_UP 2
|
||||
|
@ -466,6 +474,9 @@ void plat_hit_top (edict_t *ent)
|
|||
// ent->s.sound = 0;
|
||||
}
|
||||
ent->s.sound = 0; // Knightmare- make sure this is always set to 0, lead mover or not!
|
||||
#ifdef LOOP_SOUND_ATTENUATION // Knightmare added
|
||||
ent->s.attenuation = ent->attenuation;
|
||||
#endif
|
||||
|
||||
ent->moveinfo.state = STATE_TOP;
|
||||
|
||||
|
@ -482,6 +493,9 @@ void plat_hit_bottom (edict_t *ent)
|
|||
// ent->s.sound = 0;
|
||||
}
|
||||
ent->s.sound = 0; // Knightmare- make sure this is always set to 0, lead mover or not!
|
||||
#ifdef LOOP_SOUND_ATTENUATION // Knightmare added
|
||||
ent->s.attenuation = ent->attenuation;
|
||||
#endif
|
||||
|
||||
ent->moveinfo.state = STATE_BOTTOM;
|
||||
}
|
||||
|
@ -528,7 +542,7 @@ void plat_blocked (edict_t *self, edict_t *other)
|
|||
return;
|
||||
}
|
||||
|
||||
if(other->deadflag) T_Damage (other, self, self, vec3_origin, other->s.origin, vec3_origin, 100000, 1, 0, MOD_CRUSH);
|
||||
if (other->deadflag) T_Damage (other, self, self, vec3_origin, other->s.origin, vec3_origin, 100000, 1, 0, MOD_CRUSH);
|
||||
else T_Damage (other, self, self, vec3_origin, other->s.origin, vec3_origin, self->dmg, 1, 0, MOD_CRUSH);
|
||||
|
||||
if (self->moveinfo.state == STATE_UP)
|
||||
|
@ -561,7 +575,9 @@ void Touch_Plat_Center (edict_t *ent, edict_t *other, cplane_t *plane, csurface_
|
|||
ent->nextthink = level.time + 1; // the player is still on the plat, so delay going down
|
||||
}
|
||||
|
||||
void plat_spawn_inside_trigger (edict_t *ent)
|
||||
// PGM - plat2's change the trigger field
|
||||
//void plat_spawn_inside_trigger (edict_t *ent)
|
||||
edict_t *plat_spawn_inside_trigger (edict_t *ent)
|
||||
{
|
||||
edict_t *trigger;
|
||||
vec3_t tmin, tmax;
|
||||
|
@ -608,6 +624,8 @@ void plat_spawn_inside_trigger (edict_t *ent)
|
|||
VectorCopy (tmax, trigger->maxs);
|
||||
|
||||
gi.linkentity (trigger);
|
||||
|
||||
return trigger; // PGM 11/17/97
|
||||
}
|
||||
|
||||
|
||||
|
@ -720,6 +738,432 @@ void SP_func_plat (edict_t *ent)
|
|||
SpawnItem3 (it_ent, it);
|
||||
}
|
||||
|
||||
// ==========================================
|
||||
// PLAT 2
|
||||
// ==========================================
|
||||
#define PLAT2_CALLED 1
|
||||
#define PLAT2_MOVING 2
|
||||
#define PLAT2_WAITING 4
|
||||
|
||||
void plat2_go_down (edict_t *ent);
|
||||
void plat2_go_up (edict_t *ent);
|
||||
|
||||
void plat2_spawn_danger_area (edict_t *ent)
|
||||
{
|
||||
vec3_t mins, maxs;
|
||||
|
||||
VectorCopy(ent->mins, mins);
|
||||
VectorCopy(ent->maxs, maxs);
|
||||
maxs[2] = ent->mins[2] + 64;
|
||||
|
||||
// SpawnBadArea(mins, maxs, 0, ent);
|
||||
}
|
||||
|
||||
void plat2_kill_danger_area (edict_t *ent)
|
||||
{
|
||||
edict_t *t;
|
||||
|
||||
t = NULL;
|
||||
while ((t = G_Find (t, FOFS(classname), "bad_area")))
|
||||
{
|
||||
if (t->owner == ent)
|
||||
G_FreeEdict(t);
|
||||
}
|
||||
}
|
||||
|
||||
void plat2_hit_top (edict_t *ent)
|
||||
{
|
||||
if (!(ent->flags & FL_TEAMSLAVE))
|
||||
{
|
||||
if (ent->moveinfo.sound_end)
|
||||
gi.sound (ent, CHAN_NO_PHS_ADD+CHAN_VOICE, ent->moveinfo.sound_end, 1, ent->attenuation, 0);
|
||||
ent->s.sound = 0;
|
||||
}
|
||||
ent->moveinfo.state = STATE_TOP;
|
||||
|
||||
if (ent->plat2flags & PLAT2_CALLED)
|
||||
{
|
||||
ent->plat2flags = PLAT2_WAITING;
|
||||
if (!(ent->spawnflags & PLAT2_TOGGLE))
|
||||
{
|
||||
ent->think = plat2_go_down;
|
||||
ent->nextthink = level.time + 5.0;
|
||||
}
|
||||
if (deathmatch->value)
|
||||
ent->last_move_time = level.time - 1.0;
|
||||
else
|
||||
ent->last_move_time = level.time - 2.0;
|
||||
}
|
||||
else if (!(ent->spawnflags & PLAT2_TOP) && !(ent->spawnflags & PLAT2_TOGGLE))
|
||||
{
|
||||
ent->plat2flags = 0;
|
||||
ent->think = plat2_go_down;
|
||||
ent->nextthink = level.time + 2.0;
|
||||
ent->last_move_time = level.time;
|
||||
}
|
||||
else
|
||||
{
|
||||
ent->plat2flags = 0;
|
||||
ent->last_move_time = level.time;
|
||||
}
|
||||
|
||||
G_UseTargets (ent, ent);
|
||||
}
|
||||
|
||||
void plat2_hit_bottom (edict_t *ent)
|
||||
{
|
||||
if (!(ent->flags & FL_TEAMSLAVE))
|
||||
{
|
||||
if (ent->moveinfo.sound_end)
|
||||
gi.sound (ent, CHAN_NO_PHS_ADD+CHAN_VOICE, ent->moveinfo.sound_end, 1, ent->attenuation, 0);
|
||||
ent->s.sound = 0;
|
||||
}
|
||||
ent->moveinfo.state = STATE_BOTTOM;
|
||||
|
||||
if (ent->plat2flags & PLAT2_CALLED)
|
||||
{
|
||||
ent->plat2flags = PLAT2_WAITING;
|
||||
if (!(ent->spawnflags & PLAT2_TOGGLE))
|
||||
{
|
||||
ent->think = plat2_go_up;
|
||||
ent->nextthink = level.time + 5.0;
|
||||
}
|
||||
if (deathmatch->value)
|
||||
ent->last_move_time = level.time - 1.0;
|
||||
else
|
||||
ent->last_move_time = level.time - 2.0;
|
||||
}
|
||||
else if ((ent->spawnflags & PLAT2_TOP) && !(ent->spawnflags & PLAT2_TOGGLE))
|
||||
{
|
||||
ent->plat2flags = 0;
|
||||
ent->think = plat2_go_up;
|
||||
ent->nextthink = level.time + 2.0;
|
||||
ent->last_move_time = level.time;
|
||||
}
|
||||
else
|
||||
{
|
||||
ent->plat2flags = 0;
|
||||
ent->last_move_time = level.time;
|
||||
}
|
||||
|
||||
plat2_kill_danger_area (ent);
|
||||
G_UseTargets (ent, ent);
|
||||
}
|
||||
|
||||
void plat2_go_down (edict_t *ent)
|
||||
{
|
||||
if (!(ent->flags & FL_TEAMSLAVE))
|
||||
{
|
||||
if (ent->moveinfo.sound_start)
|
||||
gi.sound (ent, CHAN_NO_PHS_ADD+CHAN_VOICE, ent->moveinfo.sound_start, 1, ent->attenuation, 0);
|
||||
ent->s.sound = ent->moveinfo.sound_middle;
|
||||
}
|
||||
ent->moveinfo.state = STATE_DOWN;
|
||||
ent->plat2flags |= PLAT2_MOVING;
|
||||
|
||||
Move_Calc (ent, ent->moveinfo.end_origin, plat2_hit_bottom);
|
||||
}
|
||||
|
||||
void plat2_go_up (edict_t *ent)
|
||||
{
|
||||
if (!(ent->flags & FL_TEAMSLAVE))
|
||||
{
|
||||
if (ent->moveinfo.sound_start)
|
||||
gi.sound (ent, CHAN_NO_PHS_ADD+CHAN_VOICE, ent->moveinfo.sound_start, 1, ent->attenuation, 0);
|
||||
ent->s.sound = ent->moveinfo.sound_middle;
|
||||
}
|
||||
ent->moveinfo.state = STATE_UP;
|
||||
ent->plat2flags |= PLAT2_MOVING;
|
||||
|
||||
plat2_spawn_danger_area(ent);
|
||||
|
||||
Move_Calc (ent, ent->moveinfo.start_origin, plat2_hit_top);
|
||||
}
|
||||
|
||||
void plat2_operate (edict_t *ent, edict_t *other)
|
||||
{
|
||||
int otherState;
|
||||
float pauseTime;
|
||||
float platCenter;
|
||||
edict_t *trigger;
|
||||
|
||||
trigger = ent;
|
||||
ent = ent->enemy; // now point at the plat, not the trigger
|
||||
|
||||
if (ent->plat2flags & PLAT2_MOVING)
|
||||
return;
|
||||
|
||||
if ((ent->last_move_time + 2) > level.time)
|
||||
return;
|
||||
|
||||
platCenter = (trigger->absmin[2] + trigger->absmax[2]) / 2;
|
||||
|
||||
if (ent->moveinfo.state == STATE_TOP)
|
||||
{
|
||||
otherState = STATE_TOP;
|
||||
if (ent->spawnflags & PLAT2_BOX_LIFT)
|
||||
{
|
||||
if (platCenter > other->s.origin[2])
|
||||
otherState = STATE_BOTTOM;
|
||||
}
|
||||
else
|
||||
{
|
||||
if (trigger->absmax[2] > other->s.origin[2])
|
||||
otherState = STATE_BOTTOM;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
otherState = STATE_BOTTOM;
|
||||
if (other->s.origin[2] > platCenter)
|
||||
otherState = STATE_TOP;
|
||||
}
|
||||
|
||||
ent->plat2flags = PLAT2_MOVING;
|
||||
|
||||
if (deathmatch->value)
|
||||
pauseTime = 0.3;
|
||||
else
|
||||
pauseTime = 0.5;
|
||||
|
||||
if (ent->moveinfo.state != otherState)
|
||||
{
|
||||
ent->plat2flags |= PLAT2_CALLED;
|
||||
pauseTime = 0.1;
|
||||
}
|
||||
|
||||
ent->last_move_time = level.time;
|
||||
|
||||
if (ent->moveinfo.state == STATE_BOTTOM)
|
||||
{
|
||||
ent->think = plat2_go_up;
|
||||
ent->nextthink = level.time + pauseTime;
|
||||
}
|
||||
else
|
||||
{
|
||||
ent->think = plat2_go_down;
|
||||
ent->nextthink = level.time + pauseTime;
|
||||
}
|
||||
}
|
||||
|
||||
void Touch_Plat_Center2 (edict_t *ent, edict_t *other, cplane_t *plane, csurface_t *surf)
|
||||
{
|
||||
// this requires monsters to actively trigger plats, not just step on them.
|
||||
|
||||
//FIXME - commented out for E3
|
||||
//if (!other->client)
|
||||
// return;
|
||||
|
||||
if (other->health <= 0)
|
||||
return;
|
||||
|
||||
// PMM - don't let non-monsters activate plat2s
|
||||
if ((!(other->svflags & SVF_MONSTER)) && (!other->client))
|
||||
return;
|
||||
|
||||
plat2_operate (ent, other);
|
||||
}
|
||||
|
||||
void plat2_blocked (edict_t *self, edict_t *other)
|
||||
{
|
||||
if (!(other->svflags & SVF_MONSTER) && (!other->client))
|
||||
{
|
||||
// give it a chance to go away on it's own terms (like gibs)
|
||||
T_Damage (other, self, self, vec3_origin, other->s.origin, vec3_origin, 100000, 1, 0, MOD_CRUSH);
|
||||
// if it's still there, nuke it
|
||||
if (other && other->inuse)
|
||||
BecomeExplosion1 (other);
|
||||
return;
|
||||
}
|
||||
|
||||
// gib dead things
|
||||
if (other->health < 1)
|
||||
{
|
||||
T_Damage(other, self, self, vec3_origin, other->s.origin, vec3_origin, 100, 1, 0, MOD_CRUSH);
|
||||
}
|
||||
|
||||
T_Damage (other, self, self, vec3_origin, other->s.origin, vec3_origin, self->dmg, 1, 0, MOD_CRUSH);
|
||||
|
||||
if (self->moveinfo.state == STATE_UP)
|
||||
plat2_go_down (self);
|
||||
else if (self->moveinfo.state == STATE_DOWN)
|
||||
plat2_go_up (self);
|
||||
}
|
||||
|
||||
void Use_Plat2 (edict_t *ent, edict_t *other, edict_t *activator)
|
||||
{
|
||||
edict_t *trigger;
|
||||
int i;
|
||||
|
||||
if (ent->moveinfo.state > STATE_BOTTOM)
|
||||
return;
|
||||
if ((ent->last_move_time + 2) > level.time)
|
||||
return;
|
||||
|
||||
for (i = 1, trigger = g_edicts + 1; i < globals.num_edicts; i++, trigger++)
|
||||
{
|
||||
if (!trigger->inuse)
|
||||
continue;
|
||||
if (trigger->touch == Touch_Plat_Center2)
|
||||
{
|
||||
if (trigger->enemy == ent)
|
||||
{
|
||||
// Touch_Plat_Center2 (trigger, activator, NULL, NULL);
|
||||
plat2_operate (trigger, activator);
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void plat2_activate (edict_t *ent, edict_t *other, edict_t *activator)
|
||||
{
|
||||
edict_t *trigger;
|
||||
|
||||
// if (ent->targetname)
|
||||
// ent->targetname[0] = 0;
|
||||
|
||||
ent->use = Use_Plat2;
|
||||
|
||||
trigger = plat_spawn_inside_trigger (ent); // the "start moving" trigger
|
||||
|
||||
trigger->maxs[0]+=10;
|
||||
trigger->maxs[1]+=10;
|
||||
trigger->mins[0]-=10;
|
||||
trigger->mins[1]-=10;
|
||||
|
||||
gi.linkentity (trigger);
|
||||
|
||||
trigger->touch = Touch_Plat_Center2; // Override trigger touch function
|
||||
|
||||
plat2_go_down(ent);
|
||||
}
|
||||
|
||||
/*QUAKED func_plat2 (0 .5 .8) ? PLAT_LOW_TRIGGER PLAT2_TOGGLE PLAT2_TOP PLAT2_TRIGGER_TOP PLAT2_TRIGGER_BOTTOM BOX_LIFT
|
||||
speed default 150
|
||||
|
||||
PLAT_LOW_TRIGGER - creates a short trigger field at the bottom
|
||||
PLAT2_TOGGLE - plat will not return to default position.
|
||||
PLAT2_TOP - plat's default position will the the top.
|
||||
PLAT2_TRIGGER_TOP - plat will trigger it's targets each time it hits top
|
||||
PLAT2_TRIGGER_BOTTOM - plat will trigger it's targets each time it hits bottom
|
||||
BOX_LIFT - this indicates that the lift is a box, rather than just a platform
|
||||
|
||||
Plats are always drawn in the extended position, so they will light correctly.
|
||||
|
||||
If the plat is the target of another trigger or button, it will start out disabled in the extended position until it is trigger, when it will lower and become a normal plat.
|
||||
|
||||
"speed" overrides default 200.
|
||||
"accel" overrides default 500
|
||||
"lip" no default
|
||||
|
||||
If the "height" key is set, that will determine the amount the plat moves, instead of being implicitly determoveinfoned by the model's height.
|
||||
|
||||
*/
|
||||
void SP_func_plat2 (edict_t *ent)
|
||||
{
|
||||
edict_t *trigger;
|
||||
|
||||
VectorClear (ent->s.angles);
|
||||
ent->solid = SOLID_BSP;
|
||||
ent->movetype = MOVETYPE_PUSH;
|
||||
|
||||
gi.setmodel (ent, ent->model);
|
||||
|
||||
ent->blocked = plat2_blocked;
|
||||
|
||||
if (!ent->speed)
|
||||
ent->speed = 20;
|
||||
else
|
||||
ent->speed *= 0.1;
|
||||
|
||||
if (!ent->accel)
|
||||
ent->accel = 5;
|
||||
else
|
||||
ent->accel *= 0.1;
|
||||
|
||||
if (!ent->decel)
|
||||
ent->decel = 5;
|
||||
else
|
||||
ent->decel *= 0.1;
|
||||
|
||||
if (deathmatch->value)
|
||||
{
|
||||
ent->speed *= 2;
|
||||
ent->accel *= 2;
|
||||
ent->decel *= 2;
|
||||
}
|
||||
|
||||
|
||||
//PMM Added to kill things it's being blocked by
|
||||
if (!ent->dmg)
|
||||
ent->dmg = 2;
|
||||
|
||||
// if (!st.lip)
|
||||
// st.lip = 8;
|
||||
|
||||
// pos1 is the top position, pos2 is the bottom
|
||||
VectorCopy (ent->s.origin, ent->pos1);
|
||||
VectorCopy (ent->s.origin, ent->pos2);
|
||||
|
||||
if (st.height)
|
||||
ent->pos2[2] -= (st.height - st.lip);
|
||||
else
|
||||
ent->pos2[2] -= (ent->maxs[2] - ent->mins[2]) - st.lip;
|
||||
|
||||
ent->moveinfo.state = STATE_TOP;
|
||||
|
||||
if (ent->targetname)
|
||||
{
|
||||
ent->use = plat2_activate;
|
||||
}
|
||||
else
|
||||
{
|
||||
ent->use = Use_Plat2;
|
||||
|
||||
trigger = plat_spawn_inside_trigger (ent); // the "start moving" trigger
|
||||
|
||||
// PGM - debugging??
|
||||
trigger->maxs[0]+=10;
|
||||
trigger->maxs[1]+=10;
|
||||
trigger->mins[0]-=10;
|
||||
trigger->mins[1]-=10;
|
||||
|
||||
gi.linkentity (trigger);
|
||||
|
||||
trigger->touch = Touch_Plat_Center2; // Override trigger touch function
|
||||
|
||||
if (!(ent->spawnflags & PLAT2_TOP))
|
||||
{
|
||||
VectorCopy (ent->pos2, ent->s.origin);
|
||||
ent->moveinfo.state = STATE_BOTTOM;
|
||||
}
|
||||
}
|
||||
|
||||
gi.linkentity (ent);
|
||||
|
||||
ent->moveinfo.speed = ent->speed;
|
||||
ent->moveinfo.accel = ent->accel;
|
||||
ent->moveinfo.decel = ent->decel;
|
||||
ent->moveinfo.wait = ent->wait;
|
||||
VectorCopy (ent->pos1, ent->moveinfo.start_origin);
|
||||
VectorCopy (ent->s.angles, ent->moveinfo.start_angles);
|
||||
VectorCopy (ent->pos2, ent->moveinfo.end_origin);
|
||||
VectorCopy (ent->s.angles, ent->moveinfo.end_angles);
|
||||
|
||||
ent->moveinfo.sound_start = gi.soundindex ("plats/pt1_strt.wav");
|
||||
ent->moveinfo.sound_middle = gi.soundindex ("plats/pt1_mid.wav");
|
||||
ent->moveinfo.sound_end = gi.soundindex ("plats/pt1_end.wav");
|
||||
|
||||
if (ent->attenuation <= 0) // Knightmare added
|
||||
ent->attenuation = ATTN_STATIC;
|
||||
|
||||
//Maj++
|
||||
// bFuncPlat(ent);
|
||||
//Maj--
|
||||
|
||||
}
|
||||
|
||||
//====================================================================
|
||||
|
||||
/*QUAKED func_rotating (0 .5 .8) ? START_ON REVERSE X_AXIS Y_AXIS TOUCH_PAIN STOP ANIMATED ANIMATED_FAST
|
||||
|
@ -742,7 +1186,7 @@ void rotating_blocked (edict_t *self, edict_t *other)
|
|||
void rotating_touch (edict_t *self, edict_t *other, cplane_t *plane, csurface_t *surf)
|
||||
{
|
||||
//ponko
|
||||
if(other->svflags & SVF_MONSTER) return;
|
||||
if (other->svflags & SVF_MONSTER) return;
|
||||
|
||||
if (self->avelocity[0] || self->avelocity[1] || self->avelocity[2])
|
||||
T_Damage (other, self, self, vec3_origin, other->s.origin, vec3_origin, self->dmg, 1, 0, MOD_CRUSH);
|
||||
|
@ -880,14 +1324,14 @@ void button_fire (edict_t *self)
|
|||
return;
|
||||
|
||||
|
||||
if(self->activator)
|
||||
if (self->activator)
|
||||
{
|
||||
if(chedit->value && CurrentIndex < MAXNODES && !self->activator->deadflag && self->activator == &g_edicts[1])
|
||||
if (chedit->value && CurrentIndex < MAXNODES && !self->activator->deadflag && self->activator == &g_edicts[1])
|
||||
{
|
||||
VectorCopy(self->monsterinfo.last_sighting,Route[CurrentIndex].Pt);
|
||||
Route[CurrentIndex].ent = self;
|
||||
Route[CurrentIndex].state = GRS_PUSHBUTTON;
|
||||
if(++CurrentIndex < MAXNODES)
|
||||
if (++CurrentIndex < MAXNODES)
|
||||
{
|
||||
gi.bprintf(PRINT_HIGH,"Last %i pod(s).\n",MAXNODES - CurrentIndex);
|
||||
memset(&Route[CurrentIndex],0,sizeof(route_t));
|
||||
|
@ -924,7 +1368,7 @@ void button_touch (edict_t *self, edict_t *other, cplane_t *plane, csurface_t *s
|
|||
|
||||
void button_killed (edict_t *self, edict_t *inflictor, edict_t *attacker, int damage, vec3_t point)
|
||||
{
|
||||
// if(self->takedamage) self->monsterinfo.attack_finished = level.time + FRAMETIME * 40;
|
||||
// if (self->takedamage) self->monsterinfo.attack_finished = level.time + FRAMETIME * 40;
|
||||
|
||||
self->activator = attacker;
|
||||
self->health = self->max_health;
|
||||
|
@ -998,7 +1442,7 @@ void SP_func_button (edict_t *ent)
|
|||
VectorAdd(ent->s.origin,ent->mins,ent->monsterinfo.last_sighting);
|
||||
// VectorCopy(ent->s.origin,ent->monsterinfo.last_sighting);
|
||||
|
||||
if(1/*!ent->health*/)
|
||||
if (1/*!ent->health*/)
|
||||
{
|
||||
//sp roam navi
|
||||
it = FindItem("Roam Navi2");
|
||||
|
@ -1020,7 +1464,7 @@ void SP_func_button (edict_t *ent)
|
|||
VectorScale (abs_movedir, dist, tdir);
|
||||
VectorAdd(it_ent->s.origin,tdir,tdir2);
|
||||
i = gi.pointcontents(tdir2);
|
||||
if(!(i & CONTENTS_SOLID) ) break;
|
||||
if (!(i & CONTENTS_SOLID) ) break;
|
||||
dist++;
|
||||
}
|
||||
VectorScale (abs_movedir, (dist + 20), tdir);
|
||||
|
@ -1107,7 +1551,7 @@ void door_hit_top (edict_t *self)
|
|||
self->moveinfo.state = STATE_TOP;
|
||||
if (self->spawnflags & DOOR_TOGGLE)
|
||||
{
|
||||
if(self->union_ent)
|
||||
if (self->union_ent)
|
||||
{
|
||||
self->union_ent->solid = SOLID_NOT;
|
||||
}
|
||||
|
@ -1130,7 +1574,7 @@ void door_hit_bottom (edict_t *self)
|
|||
}
|
||||
self->s.sound = 0; // Knightmare- make sure this is always set to 0, lead mover or not!
|
||||
|
||||
if(self->union_ent)
|
||||
if (self->union_ent)
|
||||
{
|
||||
self->union_ent->solid = SOLID_NOT;
|
||||
}
|
||||
|
@ -1335,7 +1779,7 @@ void door_blocked (edict_t *self, edict_t *other)
|
|||
BecomeExplosion1 (other);
|
||||
return;
|
||||
}
|
||||
if(other->deadflag) T_Damage (other, self, self, vec3_origin, other->s.origin, vec3_origin, 100000, 1, 0, MOD_CRUSH);
|
||||
if (other->deadflag) T_Damage (other, self, self, vec3_origin, other->s.origin, vec3_origin, 100000, 1, 0, MOD_CRUSH);
|
||||
else T_Damage (other, self, self, vec3_origin, other->s.origin, vec3_origin, self->dmg, 1, 0, MOD_CRUSH);
|
||||
|
||||
//bot's state change
|
||||
|
@ -1343,9 +1787,9 @@ void door_blocked (edict_t *self, edict_t *other)
|
|||
{
|
||||
ent = &g_edicts[i];
|
||||
|
||||
if(ent->inuse && (ent->svflags & SVF_MONSTER) && ent->client)
|
||||
if (ent->inuse && (ent->svflags & SVF_MONSTER) && ent->client)
|
||||
{
|
||||
if(ent->client->zc.waitin_obj == self && ent->client->zc.zcstate )
|
||||
if (ent->client->zc.waitin_obj == self && ent->client->zc.zcstate )
|
||||
{
|
||||
ent->client->zc.zcstate |= STS_W_DONT;
|
||||
}
|
||||
|
@ -1397,7 +1841,7 @@ void door_touch (edict_t *self, edict_t *other, cplane_t *plane, csurface_t *sur
|
|||
return;
|
||||
self->touch_debounce_time = level.time + 5.0;
|
||||
|
||||
if(!(other->svflags & SVF_MONSTER))
|
||||
if (!(other->svflags & SVF_MONSTER))
|
||||
{
|
||||
gi.centerprintf (other, "%s", self->message);
|
||||
gi.sound (other, CHAN_AUTO, gi.soundindex ("misc/talk1.wav"), 1, ATTN_NORM, 0);
|
||||
|
@ -1506,7 +1950,7 @@ void SP_func_door (edict_t *ent)
|
|||
// VectorCopy(ent->s.origin,ent->monsterinfo.last_sighting);
|
||||
|
||||
/////////
|
||||
if(fabs(ent->moveinfo.start_origin[2] - ent->moveinfo.end_origin[2]) >20)
|
||||
if (fabs(ent->moveinfo.start_origin[2] - ent->moveinfo.end_origin[2]) >20)
|
||||
{
|
||||
it = FindItem("Roam Navi3");
|
||||
it_ent = G_Spawn();
|
||||
|
@ -1753,12 +2197,13 @@ dmg default 2
|
|||
noise looping sound to play when the train is in motion
|
||||
|
||||
*/
|
||||
|
||||
// Lazarus: Added health key to func_train
|
||||
void train_die (edict_t *self, edict_t *inflictor, edict_t *attacker, int damage, vec3_t point)
|
||||
{
|
||||
// edict_t *e, *next;
|
||||
|
||||
if(self->deathtarget)
|
||||
if (self->deathtarget)
|
||||
{
|
||||
self->target = self->deathtarget;
|
||||
G_UseTargets (self, attacker);
|
||||
|
@ -1768,11 +2213,11 @@ void train_die (edict_t *self, edict_t *inflictor, edict_t *attacker, int damage
|
|||
while(e) {
|
||||
next = e->movewith_next;
|
||||
e->nextthink = 0;
|
||||
if(e->takedamage)
|
||||
if (e->takedamage)
|
||||
T_Damage (e, self, self, vec3_origin, e->s.origin, vec3_origin, 100000, 1, DAMAGE_NO_PROTECTION, MOD_CRUSH);
|
||||
else if(e->die)
|
||||
else if (e->die)
|
||||
e->die(e,self,self,100000,e->s.origin);
|
||||
else if(e->solid == SOLID_NOT)
|
||||
else if (e->solid == SOLID_NOT)
|
||||
G_FreeEdict(e);
|
||||
else
|
||||
BecomeExplosion1 (e);
|
||||
|
@ -1860,7 +2305,7 @@ void train_wait (edict_t *self)
|
|||
{
|
||||
VectorClear(self->avelocity);
|
||||
VectorClear(self->velocity);
|
||||
// if(self->movewith_next && (self->movewith_next->movewith_ent == self))
|
||||
// if (self->movewith_next && (self->movewith_next->movewith_ent == self))
|
||||
// set_child_movement(self);
|
||||
}
|
||||
|
||||
|
@ -1879,7 +2324,7 @@ void train_wait (edict_t *self)
|
|||
VectorClear (self->velocity);
|
||||
// Knightmare added
|
||||
if (!self->spawnflags & TRAIN_ROTATE_CONSTANT)
|
||||
VectorClear (self->avelocity); //Knightmare added
|
||||
VectorClear (self->avelocity);
|
||||
// Lazarus: turn off animation for stationary trains
|
||||
if (!strcmp(self->classname, "func_train"))
|
||||
self->s.effects &= ~(EF_ANIM_ALL | EF_ANIM_ALLFAST);
|
||||
|
@ -1970,7 +2415,7 @@ void train_yaw (edict_t *self)
|
|||
if ((cur_yaw == idl_yaw) && (cur_pitch == idl_pitch) && (cur_roll == idl_roll) )
|
||||
{
|
||||
self->nextthink = level.time + FRAMETIME;
|
||||
// if(self->enemy->movewith_next && (self->enemy->movewith_next->movewith_ent == self->enemy))
|
||||
// if (self->enemy->movewith_next && (self->enemy->movewith_next->movewith_ent == self->enemy))
|
||||
// set_child_movement(self->enemy);
|
||||
return;
|
||||
}
|
||||
|
@ -2170,7 +2615,7 @@ void train_next (edict_t *self)
|
|||
again:
|
||||
if (!self->target)
|
||||
{
|
||||
// gi.dprintf ("train_next: no next target\n");
|
||||
// gi.dprintf ("train_next: no next target\n");
|
||||
self->s.sound = 0; // Knightmare added
|
||||
return;
|
||||
}
|
||||
|
@ -2225,7 +2670,7 @@ again:
|
|||
VectorCopy (dest, self->moveinfo.end_origin);
|
||||
|
||||
// Knightmare added
|
||||
if(self->spawnflags & TRAIN_SPLINE)
|
||||
if (self->spawnflags & TRAIN_SPLINE)
|
||||
{
|
||||
float speed;
|
||||
int frames;
|
||||
|
@ -2237,14 +2682,14 @@ again:
|
|||
VectorSubtract(dest,self->s.origin,v);
|
||||
self->moveinfo.distance = VectorLength(v);
|
||||
frames = (int)(10 * self->moveinfo.distance/self->speed);
|
||||
if(frames < 1) frames = 1;
|
||||
if (frames < 1) frames = 1;
|
||||
speed = (10*self->moveinfo.distance)/(float)frames;
|
||||
self->moveinfo.speed = speed;
|
||||
self->moveinfo.accel = self->moveinfo.decel = self->moveinfo.speed;
|
||||
}
|
||||
|
||||
// Rroff rotating
|
||||
if (self->spawnflags & TRAIN_ROTATE && !(ent->spawnflags & 2))
|
||||
if ( (self->spawnflags & TRAIN_ROTATE) && !(ent->spawnflags & 2))
|
||||
{
|
||||
// Lazarus: No no no :-). This is measuring from the center
|
||||
// of the func_train to the path_corner. Should
|
||||
|
@ -2260,12 +2705,11 @@ again:
|
|||
vectoangles2(v,angles);
|
||||
self->ideal_yaw = angles[YAW];
|
||||
self->ideal_pitch = angles[PITCH];
|
||||
if(self->ideal_pitch < 0) self->ideal_pitch += 360;
|
||||
if (self->ideal_pitch < 0) self->ideal_pitch += 360;
|
||||
self->ideal_roll = ent->roll;
|
||||
|
||||
VectorClear(self->movedir);
|
||||
self->movedir[1] = 1.0;
|
||||
|
||||
}
|
||||
/* Lazarus: We don't want to do this... this would give an
|
||||
// instantaneous change in pitch and roll and look
|
||||
|
@ -2283,7 +2727,7 @@ again:
|
|||
// end Rroff
|
||||
|
||||
// Lazarus:
|
||||
if(self->spawnflags & TRAIN_ROTATE_CONSTANT)
|
||||
if (self->spawnflags & TRAIN_ROTATE_CONSTANT)
|
||||
{
|
||||
self->avelocity[PITCH] = self->pitch_speed;
|
||||
self->avelocity[YAW] = self->yaw_speed;
|
||||
|
@ -2313,8 +2757,8 @@ void train_resume (edict_t *self)
|
|||
Move_Calc (self, dest, train_wait);
|
||||
self->spawnflags |= TRAIN_START_ON;
|
||||
|
||||
// Knighmare added from Lazarus
|
||||
if(self->spawnflags & TRAIN_ROTATE_CONSTANT)
|
||||
// Knightmare- added from Lazarus
|
||||
if (self->spawnflags & TRAIN_ROTATE_CONSTANT)
|
||||
{
|
||||
self->avelocity[PITCH] = self->pitch_speed;
|
||||
self->avelocity[YAW] = self->yaw_speed;
|
||||
|
@ -2341,16 +2785,16 @@ void func_train_find (edict_t *self)
|
|||
|
||||
// Knightmare added
|
||||
// Lazarus: trains can change speed at path_corners
|
||||
if(ent->speed) {
|
||||
if (ent->speed) {
|
||||
self->speed = ent->speed;
|
||||
self->moveinfo.speed = self->speed;
|
||||
self->moveinfo.accel = self->moveinfo.decel = self->moveinfo.speed;
|
||||
}
|
||||
if(ent->pitch_speed)
|
||||
if (ent->pitch_speed)
|
||||
self->pitch_speed = ent->pitch_speed;
|
||||
if(ent->yaw_speed)
|
||||
if (ent->yaw_speed)
|
||||
self->yaw_speed = ent->yaw_speed;
|
||||
if(ent->roll_speed)
|
||||
if (ent->roll_speed)
|
||||
self->roll_speed = ent->roll_speed;
|
||||
|
||||
// Lazarus: spline stuff
|
||||
|
@ -2376,6 +2820,7 @@ void func_train_find (edict_t *self)
|
|||
VectorCopy (ent->s.origin, self->s.origin);
|
||||
else
|
||||
VectorSubtract (ent->s.origin, self->mins, self->s.origin);
|
||||
|
||||
VectorCopy (self->s.origin, self->s.old_origin);
|
||||
gi.linkentity (self);
|
||||
|
||||
|
@ -2433,7 +2878,7 @@ void train_use (edict_t *self, edict_t *other, edict_t *activator)
|
|||
{
|
||||
// Back up a step
|
||||
self->moveinfo.ratio -= self->moveinfo.speed * FRAMETIME / self->moveinfo.distance;
|
||||
if(self->moveinfo.ratio < 0.)
|
||||
if (self->moveinfo.ratio < 0.)
|
||||
self->moveinfo.ratio = 0.;
|
||||
}
|
||||
// end Knightmare
|
||||
|
@ -2528,8 +2973,8 @@ void SP_func_train (edict_t *self)
|
|||
|
||||
|
||||
///////////
|
||||
VectorAdd(self->s.origin,self->mins,self->monsterinfo.last_sighting);
|
||||
// VectorCopy(self->s.origin,self->monsterinfo.last_sighting);
|
||||
VectorAdd(self->s.origin, self->mins, self->monsterinfo.last_sighting);
|
||||
// VectorCopy(self->s.origin, self->monsterinfo.last_sighting);
|
||||
|
||||
|
||||
it = FindItem("Roam Navi");
|
||||
|
@ -2814,7 +3259,7 @@ void door_secret_blocked (edict_t *self, edict_t *other)
|
|||
return;
|
||||
self->touch_debounce_time = level.time + 0.5;
|
||||
|
||||
if(other->deadflag) T_Damage (other, self, self, vec3_origin, other->s.origin, vec3_origin, 100000, 1, 0, MOD_CRUSH);
|
||||
if (other->deadflag) T_Damage (other, self, self, vec3_origin, other->s.origin, vec3_origin, 100000, 1, 0, MOD_CRUSH);
|
||||
else T_Damage (other, self, self, vec3_origin, other->s.origin, vec3_origin, self->dmg, 1, 0, MOD_CRUSH);
|
||||
|
||||
// T_Damage (other, self, self, vec3_origin, other->s.origin, vec3_origin, self->dmg, 1, 0, MOD_CRUSH);
|
||||
|
|
|
@ -802,7 +802,7 @@ qboolean fire_hit (edict_t *self, vec3_t aim, int damage, int kick);
|
|||
void fire_bullet (edict_t *self, vec3_t start, vec3_t aimdir, int damage, int kick, int hspread, int vspread, int mod);
|
||||
void fire_shotgun (edict_t *self, vec3_t start, vec3_t aimdir, int damage, int kick, int hspread, int vspread, int count, int mod);
|
||||
void fire_blaster (edict_t *self, vec3_t start, vec3_t aimdir, int damage, int speed, int effect, qboolean hyper);
|
||||
void fire_grenade (edict_t *self, vec3_t start, vec3_t aimdir, int damage, int speed, float timer, float damage_radius);
|
||||
void fire_grenade (edict_t *self, vec3_t start, vec3_t aimdir, int damage, int speed, float timer, float damage_radius, qboolean contact);
|
||||
void fire_grenade2 (edict_t *self, vec3_t start, vec3_t aimdir, int damage, int speed, float timer, float damage_radius, qboolean held);
|
||||
void fire_rocket (edict_t *self, vec3_t start, vec3_t dir, int damage, int speed, float damage_radius, int radius_damage);
|
||||
void fire_rail (edict_t *self, vec3_t start, vec3_t aimdir, int damage, int kick);
|
||||
|
@ -867,7 +867,7 @@ void DeathmatchScoreboardMessage (edict_t *client, edict_t *killer);
|
|||
//
|
||||
void PlayerNoise(edict_t *who, vec3_t where, int type);
|
||||
void P_ProjectSource (gclient_t *client, vec3_t point, vec3_t distance, vec3_t forward, vec3_t right, vec3_t result);
|
||||
void Weapon_Generic (edict_t *ent, int FRAME_ACTIVATE_LAST, int FRAME_FIRE_LAST, int FRAME_IDLE_LAST, int FRAME_DEACTIVATE_LAST, int *pause_frames, int *fire_frames, void (*fire)(edict_t *ent));
|
||||
void Weapon_Generic (edict_t *ent, int FRAME_ACTIVATE_LAST, int FRAME_FIRE_LAST, int FRAME_IDLE_LAST, int FRAME_DEACTIVATE_LAST, int *pause_frames, int *fire_frames, void (*fire)(edict_t *ent, qboolean altfire));
|
||||
|
||||
|
||||
//
|
||||
|
@ -1291,6 +1291,21 @@ struct edict_s
|
|||
// RAFAEL
|
||||
int orders;
|
||||
|
||||
//=========
|
||||
//ROGUE
|
||||
int plat2flags;
|
||||
vec3_t offset;
|
||||
vec3_t gravityVector;
|
||||
edict_t *bad_area;
|
||||
edict_t *hint_chain;
|
||||
edict_t *monster_hint_chain;
|
||||
edict_t *target_hint_chain;
|
||||
int hint_chain_id;
|
||||
// FIXME - debug help!
|
||||
float lastMoveTime;
|
||||
//ROGUE
|
||||
//=========
|
||||
|
||||
// Knightmare added
|
||||
char *usermodel;
|
||||
int startframe;
|
||||
|
|
|
@ -189,7 +189,7 @@ void ClientEndServerFrames (void)
|
|||
ent = g_edicts + 1 + i;
|
||||
if (!ent->inuse || !ent->client)
|
||||
continue;
|
||||
if(!(ent->svflags & SVF_MONSTER))
|
||||
if (!(ent->svflags & SVF_MONSTER))
|
||||
ClientEndServerFrame (ent);
|
||||
}
|
||||
|
||||
|
@ -212,95 +212,95 @@ void Get_NextMap()
|
|||
char nextmap[MAX_QPATH];
|
||||
int i;
|
||||
|
||||
if(!maplist->string) return;
|
||||
if (!maplist->string) return;
|
||||
|
||||
sprintf(Buff,".\\%s\\3ZBMAPS.LST",gamepath->string);
|
||||
Com_sprintf (Buff, sizeof(Buff), ".\\%s\\3ZBMAPS.LST",gamepath->string);
|
||||
fp = fopen(Buff,"r");
|
||||
if(fp == NULL) return;
|
||||
if (fp == NULL) return;
|
||||
|
||||
//search section
|
||||
while(1)
|
||||
{
|
||||
if(fgets( Buff, sizeof(Buff), fp ) == NULL) goto NONEXTMAP;
|
||||
if (fgets( Buff, sizeof(Buff), fp ) == NULL) goto NONEXTMAP;
|
||||
|
||||
if(Buff[0] != '[') continue;
|
||||
if (Buff[0] != '[') continue;
|
||||
|
||||
i = 0;
|
||||
while(1)
|
||||
{
|
||||
if(Buff[i] == ']') Buff[i] = 0;
|
||||
if (Buff[i] == ']') Buff[i] = 0;
|
||||
|
||||
if(Buff[i] == 0) break;
|
||||
if (Buff[i] == 0) break;
|
||||
|
||||
if(++i >= sizeof(Buff))
|
||||
if (++i >= sizeof(Buff))
|
||||
{
|
||||
Buff[i - 1] = 0;
|
||||
break;
|
||||
}
|
||||
}
|
||||
//compare map section name
|
||||
if(Q_stricmp (&Buff[1], maplist->string) == 0) break;
|
||||
if (Q_stricmp (&Buff[1], maplist->string) == 0) break;
|
||||
}
|
||||
|
||||
//search current mapname
|
||||
while(1)
|
||||
{
|
||||
if(fgets( Buff, sizeof(Buff), fp ) == NULL) goto NONEXTMAP;
|
||||
if (fgets( Buff, sizeof(Buff), fp ) == NULL) goto NONEXTMAP;
|
||||
|
||||
if(Buff[0] == '[')
|
||||
if (Buff[0] == '[')
|
||||
{
|
||||
if( firstflag )
|
||||
if ( firstflag )
|
||||
{
|
||||
strcpy(nextmap,top);
|
||||
Com_strcpy (nextmap, sizeof(nextmap),top);
|
||||
goto SETNEXTMAP;
|
||||
}
|
||||
else goto NONEXTMAP;
|
||||
}
|
||||
|
||||
if(Buff[0] == '\n') continue;
|
||||
if (Buff[0] == '\n') continue;
|
||||
|
||||
sscanf(Buff,"%s",nextmap);
|
||||
|
||||
if(!firstflag)
|
||||
if (!firstflag)
|
||||
{
|
||||
firstflag = true;
|
||||
strcpy(top,nextmap);
|
||||
Com_strcpy (top, sizeof(top), nextmap);
|
||||
}
|
||||
|
||||
if(Q_stricmp (level.mapname, nextmap) == 0) break;
|
||||
if (Q_stricmp (level.mapname, nextmap) == 0) break;
|
||||
}
|
||||
|
||||
//search nextmap
|
||||
while(1)
|
||||
{
|
||||
if(fgets( Buff, sizeof(Buff), fp ) == NULL)
|
||||
if (fgets( Buff, sizeof(Buff), fp ) == NULL)
|
||||
{
|
||||
if( firstflag )
|
||||
if ( firstflag )
|
||||
{
|
||||
strcpy(nextmap,top);
|
||||
Com_strcpy (nextmap, sizeof(nextmap) ,top);
|
||||
goto SETNEXTMAP;
|
||||
}
|
||||
else goto NONEXTMAP;
|
||||
}
|
||||
|
||||
if(Buff[0] == '[')
|
||||
if (Buff[0] == '[')
|
||||
{
|
||||
if( firstflag )
|
||||
if ( firstflag )
|
||||
{
|
||||
strcpy(nextmap,top);
|
||||
Com_strcpy (nextmap, sizeof(nextmap), top);
|
||||
goto SETNEXTMAP;
|
||||
}
|
||||
else goto NONEXTMAP;
|
||||
}
|
||||
|
||||
if(Buff[0] == '\n') continue;
|
||||
if (Buff[0] == '\n') continue;
|
||||
|
||||
sscanf(Buff,"%s",nextmap);
|
||||
break;
|
||||
}
|
||||
SETNEXTMAP:
|
||||
|
||||
strcpy(level.nextmap,nextmap);
|
||||
Com_strcpy (level.nextmap, sizeof(level.nextmap), nextmap);
|
||||
|
||||
NONEXTMAP:
|
||||
fclose(fp);
|
||||
|
@ -510,9 +510,9 @@ void G_RunFrame (void)
|
|||
//
|
||||
// Bot Spawning
|
||||
//
|
||||
if(SpawnWaitingBots && !level.intermissiontime)
|
||||
if (SpawnWaitingBots && !level.intermissiontime)
|
||||
{
|
||||
if(spawncycle < level.time)
|
||||
if (spawncycle < level.time)
|
||||
{
|
||||
Bot_SpawnCall();
|
||||
spawncycle = level.time + FRAMETIME * 10 + 0.01 * SpawnWaitingBots;
|
||||
|
@ -520,7 +520,7 @@ void G_RunFrame (void)
|
|||
}
|
||||
else
|
||||
{
|
||||
if(spawncycle < level.time) spawncycle = level.time + FRAMETIME * 10;
|
||||
if (spawncycle < level.time) spawncycle = level.time + FRAMETIME * 10;
|
||||
}
|
||||
//
|
||||
// treat each object in turn
|
||||
|
@ -548,9 +548,9 @@ void G_RunFrame (void)
|
|||
}
|
||||
|
||||
//ctf job assign
|
||||
if(ctf->value)
|
||||
if (ctf->value)
|
||||
{
|
||||
if(ctfjob_update < level.time)
|
||||
if (ctfjob_update < level.time)
|
||||
{
|
||||
//gi.bprintf(PRINT_HIGH,"Assigned!!!\n");
|
||||
CTFJobAssign();
|
||||
|
@ -558,13 +558,13 @@ void G_RunFrame (void)
|
|||
}
|
||||
}
|
||||
//////////旗のスコアチェック
|
||||
if(zigmode->value == 1)
|
||||
if (zigmode->value == 1)
|
||||
{
|
||||
if(next_fragadd < level.time)
|
||||
if (next_fragadd < level.time)
|
||||
{
|
||||
if(i > 0 && i <= maxclients->value && g_edicts[i].client)
|
||||
if (i > 0 && i <= maxclients->value && g_edicts[i].client)
|
||||
{
|
||||
if(g_edicts[i].client->pers.inventory[ITEM_INDEX(zflag_item)])
|
||||
if (g_edicts[i].client->pers.inventory[ITEM_INDEX(zflag_item)])
|
||||
{
|
||||
zflag_ent = NULL;
|
||||
haveflag = true;
|
||||
|
@ -576,23 +576,23 @@ void G_RunFrame (void)
|
|||
//旗を持ってるとフラッグを足す
|
||||
for ( j = 1 ; j <= maxclients->value ; j++)
|
||||
{
|
||||
if(g_edicts[j].inuse)
|
||||
if (g_edicts[j].inuse)
|
||||
{
|
||||
if(OnSameTeam(&g_edicts[i],&g_edicts[j]))
|
||||
if (OnSameTeam(&g_edicts[i],&g_edicts[j]))
|
||||
g_edicts[j].client->resp.score += 1;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
if(zflag_ent != NULL)
|
||||
if (zflag_ent != NULL)
|
||||
{
|
||||
if(!zflag_ent->inuse)
|
||||
if (!zflag_ent->inuse)
|
||||
{
|
||||
// item = FindItem("Zig Flag");
|
||||
SelectSpawnPoint (ent, v, vv);
|
||||
// VectorCopy (v, ent->s.origin);
|
||||
if(ZIGDrop_Flag(ent,zflag_item))
|
||||
if (ZIGDrop_Flag(ent,zflag_item))
|
||||
{
|
||||
VectorCopy (v, zflag_ent->s.origin);
|
||||
}
|
||||
|
@ -610,14 +610,14 @@ void G_RunFrame (void)
|
|||
G_RunEntity (ent);
|
||||
}
|
||||
|
||||
if(next_fragadd < level.time)
|
||||
if (next_fragadd < level.time)
|
||||
{
|
||||
if(zflag_ent == NULL && !haveflag && !ctf->value
|
||||
if (zflag_ent == NULL && !haveflag && !ctf->value
|
||||
&& zigmode->value == 1 && zigflag_spawn == 2)
|
||||
{
|
||||
SelectSpawnPoint (ent, v, vv);
|
||||
//VectorCopy (v, ent->s.origin);
|
||||
if(ZIGDrop_Flag(ent,zflag_item))
|
||||
if (ZIGDrop_Flag(ent,zflag_item))
|
||||
{
|
||||
VectorCopy (v, zflag_ent->s.origin);
|
||||
}
|
||||
|
|
|
@ -365,7 +365,7 @@ void ThrowClientHead (edict_t *self, int damage)
|
|||
|
||||
if (self->client) // bodies in the queue don't have a client anymore
|
||||
{
|
||||
if(!(self->svflags & SVF_MONSTER))
|
||||
if (!(self->svflags & SVF_MONSTER))
|
||||
{
|
||||
self->client->anim_priority = ANIM_DEATH;
|
||||
self->client->anim_end = self->s.frame;
|
||||
|
@ -1443,7 +1443,7 @@ void viper_die (edict_t *self, edict_t *inflictor, edict_t *attacker, int damage
|
|||
/* e = self->movewith_next;
|
||||
while(e) {
|
||||
next = e->movewith_next;
|
||||
if(e->solid == SOLID_NOT) {
|
||||
if (e->solid == SOLID_NOT) {
|
||||
e->nextthink = 0;
|
||||
G_FreeEdict(e);
|
||||
} else
|
||||
|
@ -1489,9 +1489,9 @@ void SP_misc_viper (edict_t *ent)
|
|||
VectorSet (ent->maxs, 32, 24, 16);
|
||||
ent->takedamage = DAMAGE_YES;
|
||||
ent->die = viper_die;
|
||||
if(!ent->dmg)
|
||||
if (!ent->dmg)
|
||||
ent->dmg = 200;
|
||||
if(!ent->mass)
|
||||
if (!ent->mass)
|
||||
ent->mass = 800;
|
||||
}
|
||||
else
|
||||
|
@ -1668,9 +1668,9 @@ void SP_misc_strogg_ship (edict_t *ent)
|
|||
VectorSet (ent->maxs, 72, 60, 38);
|
||||
ent->takedamage = DAMAGE_YES;
|
||||
ent->die = viper_die;
|
||||
if(!ent->dmg)
|
||||
if (!ent->dmg)
|
||||
ent->dmg = 200;
|
||||
if(!ent->mass)
|
||||
if (!ent->mass)
|
||||
ent->mass = 1200;
|
||||
}
|
||||
else
|
||||
|
@ -2122,24 +2122,24 @@ void teleporter_touch (edict_t *self, edict_t *other, cplane_t *plane, csurface_
|
|||
|
||||
|
||||
//route update
|
||||
if(chedit->value && CurrentIndex < MAXNODES && other == &g_edicts[1])
|
||||
if (chedit->value && CurrentIndex < MAXNODES && other == &g_edicts[1])
|
||||
{
|
||||
gi.bprintf(PRINT_HIGH,"teleport!\n");
|
||||
VectorCopy(self->s.origin,Route[CurrentIndex].Pt);
|
||||
Route[CurrentIndex].ent = NULL;
|
||||
Route[CurrentIndex].state = GRS_TELEPORT;
|
||||
if(++CurrentIndex < MAXNODES)
|
||||
if (++CurrentIndex < MAXNODES)
|
||||
{
|
||||
memset(&Route[CurrentIndex],0,sizeof(route_t));
|
||||
Route[CurrentIndex].index = Route[CurrentIndex - 1].index +1;
|
||||
}
|
||||
}
|
||||
|
||||
if(other->svflags & SVF_MONSTER)
|
||||
if (other->svflags & SVF_MONSTER)
|
||||
{
|
||||
if(other->client->zc.route_trace && other->client->zc.routeindex < CurrentIndex )
|
||||
if (other->client->zc.route_trace && other->client->zc.routeindex < CurrentIndex )
|
||||
{
|
||||
if(Route[other->client->zc.routeindex].state == GRS_TELEPORT
|
||||
if (Route[other->client->zc.routeindex].state == GRS_TELEPORT
|
||||
/*&& Route[other->client->zc.routeindex].ent == self*/)
|
||||
{
|
||||
other->client->zc.routeindex++;
|
||||
|
@ -2147,9 +2147,9 @@ void teleporter_touch (edict_t *self, edict_t *other, cplane_t *plane, csurface_
|
|||
|
||||
}
|
||||
|
||||
if(other->client->zc.routeindex < CurrentIndex)
|
||||
if (other->client->zc.routeindex < CurrentIndex)
|
||||
{
|
||||
if(Route[other->client->zc.routeindex].state == GRS_GRAPRELEASE)
|
||||
if (Route[other->client->zc.routeindex].state == GRS_GRAPRELEASE)
|
||||
{
|
||||
other->client->zc.routeindex++;
|
||||
//gi.bprintf(PRINT_HIGH,"Groff!\n");
|
||||
|
|
|
@ -65,7 +65,7 @@ void modelspawn_think (edict_t *self)
|
|||
if (self->s.frame >= self->framenumbers)
|
||||
{
|
||||
self->s.frame = self->startframe;
|
||||
if(self->spawnflags & ANIM_ONCE)
|
||||
if (self->spawnflags & ANIM_ONCE)
|
||||
{
|
||||
model_spawn_use(self,world,world);
|
||||
return;
|
||||
|
@ -81,7 +81,7 @@ void model_spawn_use (edict_t *self, edict_t *other, edict_t *activator)
|
|||
{
|
||||
self->svflags &= ~SVF_NOCLIENT;
|
||||
self->delay = 0;
|
||||
if(self->framenumbers > 1)
|
||||
if (self->framenumbers > 1)
|
||||
{
|
||||
self->think = modelspawn_think;
|
||||
self->nextthink = level.time + FRAMETIME;
|
||||
|
@ -109,7 +109,7 @@ void model_die (edict_t *self, edict_t *inflictor, edict_t *attacker, int damage
|
|||
e = self->movewith_next;
|
||||
while(e) {
|
||||
next = e->movewith_next;
|
||||
if(e->solid == SOLID_NOT) {
|
||||
if (e->solid == SOLID_NOT) {
|
||||
e->nextthink = 0;
|
||||
G_FreeEdict(e);
|
||||
} else
|
||||
|
@ -196,8 +196,8 @@ void SP_model_spawn (edict_t *ent)
|
|||
}
|
||||
}
|
||||
|
||||
// if(ent->movewith && (ent->solid == SOLID_BBOX))
|
||||
// if(ent->movewith)
|
||||
// if (ent->movewith && (ent->solid == SOLID_BBOX))
|
||||
// if (ent->movewith)
|
||||
// ent->movetype = MOVETYPE_PUSH;
|
||||
|
||||
if (ent->solid != SOLID_NOT)
|
||||
|
@ -211,7 +211,7 @@ void SP_model_spawn (edict_t *ent)
|
|||
else
|
||||
{
|
||||
if (ent->spawnflags & PLAYER_MODEL) {
|
||||
if(!ent->usermodel || !strlen(ent->usermodel))
|
||||
if (!ent->usermodel || !strlen(ent->usermodel))
|
||||
ent->s.modelindex = MAX_MODELS-1;
|
||||
else
|
||||
{
|
||||
|
@ -262,7 +262,7 @@ void SP_model_spawn (edict_t *ent)
|
|||
ent->use = model_spawn_use;
|
||||
}
|
||||
|
||||
if(!(ent->s.effects & ANIM_MASK) && (ent->framenumbers > 1))
|
||||
if (!(ent->s.effects & ANIM_MASK) && (ent->framenumbers > 1))
|
||||
{
|
||||
ent->think = modelspawn_think;
|
||||
ent->nextthink = level.time + 2*FRAMETIME;
|
||||
|
|
|
@ -41,7 +41,7 @@ void monster_fire_blaster (edict_t *self, vec3_t start, vec3_t dir, int damage,
|
|||
|
||||
void monster_fire_grenade (edict_t *self, vec3_t start, vec3_t aimdir, int damage, int speed, int flashtype)
|
||||
{
|
||||
fire_grenade (self, start, aimdir, damage, speed, 2.5, damage+40);
|
||||
fire_grenade (self, start, aimdir, damage, speed, 2.5, damage+40, false);
|
||||
|
||||
gi.WriteByte (svc_muzzleflash2);
|
||||
gi.WriteShort (self - g_edicts);
|
||||
|
|
|
@ -41,18 +41,18 @@ void model_train_animator(edict_t *animator)
|
|||
edict_t *train;
|
||||
|
||||
train = animator->owner;
|
||||
if(!train || !train->inuse)
|
||||
if (!train || !train->inuse)
|
||||
{
|
||||
G_FreeEdict(animator);
|
||||
return;
|
||||
}
|
||||
if(Q_stricmp(train->classname,"model_train"))
|
||||
if (Q_stricmp(train->classname,"model_train"))
|
||||
{
|
||||
G_FreeEdict(animator);
|
||||
return;
|
||||
}
|
||||
animator->nextthink = level.time + FRAMETIME;
|
||||
if(VectorLength(train->velocity) == 0)
|
||||
if (VectorLength(train->velocity) == 0)
|
||||
return;
|
||||
train->s.frame++;
|
||||
if (train->s.frame >= train->framenumbers)
|
||||
|
@ -70,7 +70,7 @@ void SP_model_train (edict_t *self)
|
|||
self->moveinfo.sound_middle = self->s.sound;
|
||||
self->s.sound = 0;
|
||||
|
||||
if(!self->inuse) return;
|
||||
if (!self->inuse) return;
|
||||
|
||||
// Reset some things from SP_model_spawn
|
||||
self->delay = 0;
|
||||
|
@ -82,7 +82,7 @@ void SP_model_train (edict_t *self)
|
|||
self->takedamage = DAMAGE_YES;
|
||||
}
|
||||
|
||||
if(self->framenumbers > self->startframe+1)
|
||||
if (self->framenumbers > self->startframe+1)
|
||||
{
|
||||
edict_t *animator;
|
||||
animator = G_Spawn();
|
||||
|
@ -97,24 +97,24 @@ void SP_model_train (edict_t *self)
|
|||
// to func_train spawnflags. PLAYER_MODEL and NO_MODEL have
|
||||
// already been checked in SP_model_spawn and are never re-used,
|
||||
// so it's OK to overwrite those.
|
||||
if(self->spawnflags & MTRAIN_ROTATE)
|
||||
if (self->spawnflags & MTRAIN_ROTATE)
|
||||
{
|
||||
self->spawnflags &= ~MTRAIN_ROTATE;
|
||||
self->spawnflags |= TRAIN_ROTATE;
|
||||
}
|
||||
if(self->spawnflags & MTRAIN_ROTATE_CONSTANT)
|
||||
if (self->spawnflags & MTRAIN_ROTATE_CONSTANT)
|
||||
{
|
||||
self->spawnflags &= ~MTRAIN_ROTATE_CONSTANT;
|
||||
self->spawnflags |= TRAIN_ROTATE_CONSTANT;
|
||||
}
|
||||
if( (self->spawnflags & (TRAIN_ROTATE | TRAIN_ROTATE_CONSTANT)) == (TRAIN_ROTATE | TRAIN_ROTATE_CONSTANT))
|
||||
if ( (self->spawnflags & (TRAIN_ROTATE | TRAIN_ROTATE_CONSTANT)) == (TRAIN_ROTATE | TRAIN_ROTATE_CONSTANT))
|
||||
{
|
||||
self->spawnflags &= ~(TRAIN_ROTATE | TRAIN_ROTATE_CONSTANT);
|
||||
self->spawnflags |= TRAIN_SPLINE;
|
||||
}
|
||||
if(self->style == 3)
|
||||
if (self->style == 3)
|
||||
self->spawnflags |= TRAIN_ANIMATE; // 32
|
||||
if(self->style == 4)
|
||||
if (self->style == 4)
|
||||
self->spawnflags |= TRAIN_ANIMATE_FAST; // 64
|
||||
|
||||
// TRAIN_SMOOTH forces trains to go directly to Move_Done from
|
||||
|
|
347
3zb2/g_newfnc.c
Normal file
347
3zb2/g_newfnc.c
Normal file
|
@ -0,0 +1,347 @@
|
|||
#include "g_local.h"
|
||||
|
||||
//void plat_CalcMove (edict_t *ent, vec3_t dest, void(*func)(edict_t*));
|
||||
void Move_Calc (edict_t *ent, vec3_t dest, void(*func)(edict_t*));
|
||||
|
||||
void fd_secret_move1(edict_t *self);
|
||||
void fd_secret_move2(edict_t *self);
|
||||
void fd_secret_move3(edict_t *self);
|
||||
void fd_secret_move4(edict_t *self);
|
||||
void fd_secret_move5(edict_t *self);
|
||||
void fd_secret_move6(edict_t *self);
|
||||
void fd_secret_done(edict_t *self);
|
||||
|
||||
/*
|
||||
=============================================================================
|
||||
|
||||
SECRET DOORS
|
||||
|
||||
=============================================================================
|
||||
*/
|
||||
|
||||
#define SEC_OPEN_ONCE 1 // stays open
|
||||
#define SEC_1ST_LEFT 2 // 1st move is left of arrow
|
||||
#define SEC_1ST_DOWN 4 // 1st move is down from arrow
|
||||
#define SEC_NO_SHOOT 8 // only opened by trigger
|
||||
#define SEC_YES_SHOOT 16 // shootable even if targeted
|
||||
#define SEC_MOVE_RIGHT 32
|
||||
#define SEC_MOVE_FORWARD 64
|
||||
|
||||
void fd_secret_use (edict_t *self, edict_t *other, edict_t *activator)
|
||||
{
|
||||
edict_t *ent;
|
||||
|
||||
// gi.dprintf("fd_secret_use\n");
|
||||
if (self->flags & FL_TEAMSLAVE)
|
||||
return;
|
||||
|
||||
// trigger all paired doors
|
||||
for (ent = self ; ent ; ent = ent->teamchain)
|
||||
Move_Calc(ent, ent->moveinfo.start_origin, fd_secret_move1);
|
||||
|
||||
}
|
||||
|
||||
void fd_secret_killed (edict_t *self, edict_t *inflictor, edict_t *attacker, int damage, vec3_t point)
|
||||
{
|
||||
// gi.dprintf("fd_secret_killed\n");
|
||||
self->health = self->max_health;
|
||||
self->takedamage = DAMAGE_NO;
|
||||
|
||||
if (self->flags & FL_TEAMSLAVE && self->teammaster && self->teammaster->takedamage != DAMAGE_NO)
|
||||
fd_secret_killed (self->teammaster, inflictor, attacker, damage, point);
|
||||
else
|
||||
fd_secret_use (self, inflictor, attacker);
|
||||
}
|
||||
|
||||
// Wait after first movement...
|
||||
void fd_secret_move1(edict_t *self)
|
||||
{
|
||||
// gi.dprintf("fd_secret_move1\n");
|
||||
self->nextthink = level.time + 1.0;
|
||||
self->think = fd_secret_move2;
|
||||
}
|
||||
|
||||
// Start moving sideways w/sound...
|
||||
void fd_secret_move2(edict_t *self)
|
||||
{
|
||||
// gi.dprintf("fd_secret_move2\n");
|
||||
Move_Calc(self, self->moveinfo.end_origin, fd_secret_move3);
|
||||
}
|
||||
|
||||
// Wait here until time to go back...
|
||||
void fd_secret_move3(edict_t *self)
|
||||
{
|
||||
// gi.dprintf("fd_secret_move3\n");
|
||||
if (!(self->spawnflags & SEC_OPEN_ONCE))
|
||||
{
|
||||
self->nextthink = level.time + self->wait;
|
||||
self->think = fd_secret_move4;
|
||||
}
|
||||
}
|
||||
|
||||
// Move backward...
|
||||
void fd_secret_move4(edict_t *self)
|
||||
{
|
||||
// gi.dprintf("fd_secret_move4\n");
|
||||
Move_Calc(self, self->moveinfo.start_origin, fd_secret_move5);
|
||||
}
|
||||
|
||||
// Wait 1 second...
|
||||
void fd_secret_move5(edict_t *self)
|
||||
{
|
||||
// gi.dprintf("fd_secret_move5\n");
|
||||
self->nextthink = level.time + 1.0;
|
||||
self->think = fd_secret_move6;
|
||||
}
|
||||
|
||||
void fd_secret_move6(edict_t *self)
|
||||
{
|
||||
// gi.dprintf("fd_secret_move6\n");
|
||||
Move_Calc(self, self->move_origin, fd_secret_done);
|
||||
}
|
||||
|
||||
void fd_secret_done(edict_t *self)
|
||||
{
|
||||
// gi.dprintf("fd_secret_done\n");
|
||||
if (!self->targetname || self->spawnflags & SEC_YES_SHOOT)
|
||||
{
|
||||
self->health = 1;
|
||||
self->takedamage = DAMAGE_YES;
|
||||
self->die = fd_secret_killed;
|
||||
}
|
||||
}
|
||||
|
||||
void secret_blocked(edict_t *self, edict_t *other)
|
||||
{
|
||||
if (!(self->flags & FL_TEAMSLAVE))
|
||||
T_Damage (other, self, self, vec3_origin, other->s.origin, vec3_origin, self->dmg, 0, 0, MOD_CRUSH);
|
||||
|
||||
// if (time < self->attack_finished)
|
||||
// return;
|
||||
// self->attack_finished = time + 0.5;
|
||||
// T_Damage (other, self, self, self->dmg);
|
||||
}
|
||||
|
||||
/*
|
||||
================
|
||||
secret_touch
|
||||
|
||||
Prints messages
|
||||
================
|
||||
*/
|
||||
void secret_touch(edict_t *self, edict_t *other, cplane_t *plane, csurface_t *surf)
|
||||
{
|
||||
if (other->health <= 0)
|
||||
return;
|
||||
|
||||
if (!(other->client))
|
||||
return;
|
||||
|
||||
if (self->monsterinfo.attack_finished > level.time)
|
||||
return;
|
||||
|
||||
self->monsterinfo.attack_finished = level.time + 2;
|
||||
|
||||
if (self->message)
|
||||
{
|
||||
gi.centerprintf (other, self->message);
|
||||
// fixme - put this sound back??
|
||||
// gi.sound (other, CHAN_BODY, "misc/talk.wav", 1, ATTN_NORM);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/*QUAKED func_door_secret2 (0 .5 .8) ? open_once 1st_left 1st_down no_shoot always_shoot slide_right slide_forward
|
||||
Basic secret door. Slides back, then to the left. Angle determines direction.
|
||||
|
||||
FLAGS:
|
||||
open_once = not implemented yet
|
||||
1st_left = 1st move is left/right of arrow
|
||||
1st_down = 1st move is forwards/backwards
|
||||
no_shoot = not implemented yet
|
||||
always_shoot = even if targeted, keep shootable
|
||||
reverse_left = the sideways move will be to right of arrow
|
||||
reverse_back = the to/fro move will be forward
|
||||
|
||||
VALUES:
|
||||
wait = # of seconds before coming back (5 default)
|
||||
dmg = damage to inflict when blocked (2 default)
|
||||
|
||||
*/
|
||||
|
||||
void SP_func_door_secret2 (edict_t *ent)
|
||||
{
|
||||
vec3_t forward,right,up;
|
||||
float lrSize, fbSize;
|
||||
|
||||
ent->moveinfo.sound_start = gi.soundindex ("doors/dr1_strt.wav");
|
||||
ent->moveinfo.sound_middle = gi.soundindex ("doors/dr1_mid.wav");
|
||||
ent->moveinfo.sound_end = gi.soundindex ("doors/dr1_end.wav");
|
||||
|
||||
if (!ent->dmg)
|
||||
ent->dmg = 2;
|
||||
|
||||
AngleVectors(ent->s.angles, forward, right, up);
|
||||
VectorCopy(ent->s.origin, ent->move_origin);
|
||||
VectorCopy(ent->s.angles, ent->move_angles);
|
||||
|
||||
G_SetMovedir (ent->s.angles, ent->movedir);
|
||||
ent->movetype = MOVETYPE_PUSH;
|
||||
ent->solid = SOLID_BSP;
|
||||
gi.setmodel (ent, ent->model);
|
||||
|
||||
if(ent->move_angles[1] == 0 || ent->move_angles[1] == 180)
|
||||
{
|
||||
lrSize = ent->size[1];
|
||||
fbSize = ent->size[0];
|
||||
}
|
||||
else if(ent->move_angles[1] == 90 || ent->move_angles[1] == 270)
|
||||
{
|
||||
lrSize = ent->size[0];
|
||||
fbSize = ent->size[1];
|
||||
}
|
||||
else
|
||||
{
|
||||
gi.dprintf("Secret door not at 0,90,180,270!\n");
|
||||
}
|
||||
|
||||
if(ent->spawnflags & SEC_MOVE_FORWARD)
|
||||
VectorScale(forward, fbSize, forward);
|
||||
else
|
||||
{
|
||||
VectorScale(forward, fbSize * -1 , forward);
|
||||
}
|
||||
|
||||
if(ent->spawnflags & SEC_MOVE_RIGHT)
|
||||
VectorScale(right, lrSize, right);
|
||||
else
|
||||
{
|
||||
VectorScale(right, lrSize * -1, right);
|
||||
}
|
||||
|
||||
if(ent->spawnflags & SEC_1ST_DOWN)
|
||||
{
|
||||
VectorAdd(ent->s.origin, forward, ent->moveinfo.start_origin);
|
||||
VectorAdd(ent->moveinfo.start_origin, right, ent->moveinfo.end_origin);
|
||||
}
|
||||
else
|
||||
{
|
||||
VectorAdd(ent->s.origin, right, ent->moveinfo.start_origin);
|
||||
VectorAdd(ent->moveinfo.start_origin, forward, ent->moveinfo.end_origin);
|
||||
}
|
||||
|
||||
ent->touch = secret_touch;
|
||||
ent->blocked = secret_blocked;
|
||||
ent->use = fd_secret_use;
|
||||
ent->moveinfo.speed = 50;
|
||||
ent->moveinfo.accel = 50;
|
||||
ent->moveinfo.decel = 50;
|
||||
|
||||
if (!ent->targetname || ent->spawnflags & SEC_YES_SHOOT)
|
||||
{
|
||||
ent->health = 1;
|
||||
ent->max_health = ent->health;
|
||||
ent->takedamage = DAMAGE_YES;
|
||||
ent->die = fd_secret_killed;
|
||||
}
|
||||
if (!ent->wait)
|
||||
ent->wait = 5; // 5 seconds before closing
|
||||
|
||||
gi.linkentity(ent);
|
||||
}
|
||||
|
||||
// ==================================================
|
||||
|
||||
#define FWALL_START_ON 1
|
||||
|
||||
void force_wall_think(edict_t *self)
|
||||
{
|
||||
if(!self->wait)
|
||||
{
|
||||
gi.WriteByte (svc_temp_entity);
|
||||
gi.WriteByte (TE_FORCEWALL);
|
||||
gi.WritePosition (self->pos1);
|
||||
gi.WritePosition (self->pos2);
|
||||
gi.WriteByte (self->style);
|
||||
gi.multicast (self->offset, MULTICAST_PVS);
|
||||
}
|
||||
|
||||
self->think = force_wall_think;
|
||||
self->nextthink = level.time + 0.1;
|
||||
}
|
||||
|
||||
void force_wall_use (edict_t *self, edict_t *other, edict_t *activator)
|
||||
{
|
||||
if(!self->wait)
|
||||
{
|
||||
self->wait = 1;
|
||||
self->think = NULL;
|
||||
self->nextthink = 0;
|
||||
self->solid = SOLID_NOT;
|
||||
gi.linkentity( self );
|
||||
}
|
||||
else
|
||||
{
|
||||
self->wait = 0;
|
||||
self->think = force_wall_think;
|
||||
self->nextthink = level.time + 0.1;
|
||||
self->solid = SOLID_BSP;
|
||||
KillBox(self); // Is this appropriate?
|
||||
gi.linkentity (self);
|
||||
}
|
||||
}
|
||||
|
||||
/*QUAKED func_force_wall (1 0 1) ? start_on
|
||||
A vertical particle force wall. Turns on and solid when triggered.
|
||||
If someone is in the force wall when it turns on, they're telefragged.
|
||||
|
||||
start_on - forcewall begins activated. triggering will turn it off.
|
||||
style - color of particles to use.
|
||||
208: green, 240: red, 241: blue, 224: orange
|
||||
*/
|
||||
void SP_func_force_wall(edict_t *ent)
|
||||
{
|
||||
gi.setmodel (ent, ent->model);
|
||||
|
||||
ent->offset[0] = (ent->absmax[0] + ent->absmin[0]) / 2;
|
||||
ent->offset[1] = (ent->absmax[1] + ent->absmin[1]) / 2;
|
||||
ent->offset[2] = (ent->absmax[2] + ent->absmin[2]) / 2;
|
||||
|
||||
ent->pos1[2] = ent->absmax[2];
|
||||
ent->pos2[2] = ent->absmax[2];
|
||||
if(ent->size[0] > ent->size[1])
|
||||
{
|
||||
ent->pos1[0] = ent->absmin[0];
|
||||
ent->pos2[0] = ent->absmax[0];
|
||||
ent->pos1[1] = ent->offset[1];
|
||||
ent->pos2[1] = ent->offset[1];
|
||||
}
|
||||
else
|
||||
{
|
||||
ent->pos1[0] = ent->offset[0];
|
||||
ent->pos2[0] = ent->offset[0];
|
||||
ent->pos1[1] = ent->absmin[1];
|
||||
ent->pos2[1] = ent->absmax[1];
|
||||
}
|
||||
|
||||
if(!ent->style)
|
||||
ent->style = 208;
|
||||
|
||||
ent->movetype = MOVETYPE_NONE;
|
||||
ent->wait = 1;
|
||||
|
||||
if(ent->spawnflags & FWALL_START_ON)
|
||||
{
|
||||
ent->solid = SOLID_BSP;
|
||||
ent->think = force_wall_think;
|
||||
ent->nextthink = level.time + 0.1;
|
||||
}
|
||||
else
|
||||
ent->solid = SOLID_NOT;
|
||||
|
||||
ent->use = force_wall_use;
|
||||
|
||||
ent->svflags = SVF_NOCLIENT;
|
||||
|
||||
gi.linkentity(ent);
|
||||
}
|
|
@ -246,23 +246,23 @@ int SV_FlyMove (edict_t *ent, float time, int mask)
|
|||
//numplanes = 0;
|
||||
//PON-CTF
|
||||
i = false;
|
||||
if(ctf->value)
|
||||
if (ctf->value)
|
||||
{
|
||||
if(ent->client->ctf_grapple != NULL
|
||||
if (ent->client->ctf_grapple != NULL
|
||||
&& ent->client->ctf_grapplestate != CTF_GRAPPLE_STATE_FLY
|
||||
/*&& ent->waterlevel <= 1*/) i = true;
|
||||
}
|
||||
if(!i){if(!ent->groundentity) i = true;}
|
||||
if (!i){if (!ent->groundentity) i = true;}
|
||||
//PON-CTF
|
||||
if(!i/*ent->client*/)
|
||||
if (!i/*ent->client*/)
|
||||
{
|
||||
if(!ent->client->zc.trapped
|
||||
if (!ent->client->zc.trapped
|
||||
&& !i)
|
||||
{
|
||||
numplanes = 0;
|
||||
if(ent->waterlevel || (!ent->groundentity && ent->velocity[2] > 10 )) goto VELCX;
|
||||
if (ent->waterlevel || (!ent->groundentity && ent->velocity[2] > 10 )) goto VELCX;
|
||||
i =0;
|
||||
if(/*ent->groundentity ||*/ ent->velocity[2] > 10) goto VELC;
|
||||
if (/*ent->groundentity ||*/ ent->velocity[2] > 10) goto VELC;
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -391,21 +391,22 @@ typedef struct
|
|||
vec3_t angles;
|
||||
float deltayaw;
|
||||
} pushed_t;
|
||||
pushed_t pushed[MAX_EDICTS], *pushed_p;
|
||||
|
||||
pushed_t pushed[MAX_EDICTS], *pushed_p;
|
||||
edict_t *obstacle;
|
||||
|
||||
// Knightmare- added from Lazarus
|
||||
void MoveRiders(edict_t *platform, edict_t *ignore, vec3_t move, vec3_t amove, qboolean turn)
|
||||
void MoveRiders (edict_t *platform, edict_t *ignore, vec3_t move, vec3_t amove, qboolean turn)
|
||||
{
|
||||
int i;
|
||||
edict_t *rider;
|
||||
|
||||
for(i=1, rider=g_edicts+i; i<=globals.num_edicts; i++, rider++) {
|
||||
if((rider->groundentity == platform) && (rider != ignore)) {
|
||||
for (i=1, rider=g_edicts+i; i<=globals.num_edicts; i++, rider++)
|
||||
{
|
||||
if ((rider->groundentity == platform) && (rider != ignore)) {
|
||||
VectorAdd(rider->s.origin,move,rider->s.origin);
|
||||
if (turn && (amove[YAW] != 0.)) {
|
||||
if(!rider->client)
|
||||
if (!rider->client)
|
||||
rider->s.angles[YAW] += amove[YAW];
|
||||
else
|
||||
{
|
||||
|
@ -416,13 +417,13 @@ void MoveRiders(edict_t *platform, edict_t *ignore, vec3_t move, vec3_t amove, q
|
|||
}
|
||||
}
|
||||
gi.linkentity(rider);
|
||||
if(SV_TestEntityPosition(rider)) {
|
||||
if (SV_TestEntityPosition(rider)) {
|
||||
// Move is blocked. Since this is for riders, not pushees,
|
||||
// it should be ok to just back the move for this rider off
|
||||
VectorSubtract(rider->s.origin,move,rider->s.origin);
|
||||
if(turn && (amove[YAW] != 0.)) {
|
||||
if (turn && (amove[YAW] != 0.)) {
|
||||
rider->s.angles[YAW] -= amove[YAW];
|
||||
if(rider->client)
|
||||
if (rider->client)
|
||||
{
|
||||
rider->client->ps.pmove.delta_angles[YAW] -= ANGLE2SHORT(amove[YAW]);
|
||||
rider->client->ps.viewangles[YAW] -= amove[YAW];
|
||||
|
@ -431,11 +432,12 @@ void MoveRiders(edict_t *platform, edict_t *ignore, vec3_t move, vec3_t amove, q
|
|||
gi.linkentity(rider);
|
||||
} else {
|
||||
// move this rider's riders
|
||||
MoveRiders(rider,ignore,move,amove,turn);
|
||||
MoveRiders (rider,ignore,move,amove,turn);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
============
|
||||
RealBoundingBox
|
||||
|
@ -454,27 +456,27 @@ void RealBoundingBox(edict_t *ent, vec3_t mins, vec3_t maxs)
|
|||
vec3_t p[8];
|
||||
int i, j, k, j2, k4;
|
||||
|
||||
for(k=0; k<2; k++)
|
||||
for (k=0; k<2; k++)
|
||||
{
|
||||
k4 = k*4;
|
||||
if(k)
|
||||
if (k)
|
||||
p[k4][2] = ent->maxs[2];
|
||||
else
|
||||
p[k4][2] = ent->mins[2];
|
||||
p[k4+1][2] = p[k4][2];
|
||||
p[k4+2][2] = p[k4][2];
|
||||
p[k4+3][2] = p[k4][2];
|
||||
for(j=0; j<2; j++)
|
||||
for (j=0; j<2; j++)
|
||||
{
|
||||
j2 = j*2;
|
||||
if(j)
|
||||
if (j)
|
||||
p[j2+k4][1] = ent->maxs[1];
|
||||
else
|
||||
p[j2+k4][1] = ent->mins[1];
|
||||
p[j2+k4+1][1] = p[j2+k4][1];
|
||||
for(i=0; i<2; i++)
|
||||
for (i=0; i<2; i++)
|
||||
{
|
||||
if(i)
|
||||
if (i)
|
||||
p[i+j2+k4][0] = ent->maxs[0];
|
||||
else
|
||||
p[i+j2+k4][0] = ent->mins[0];
|
||||
|
@ -482,7 +484,7 @@ void RealBoundingBox(edict_t *ent, vec3_t mins, vec3_t maxs)
|
|||
}
|
||||
}
|
||||
AngleVectors(ent->s.angles,forward,left,up);
|
||||
for(i=0; i<8; i++)
|
||||
for (i=0; i<8; i++)
|
||||
{
|
||||
VectorScale(forward,p[i][0],f1);
|
||||
VectorScale(left,-p[i][1],l1);
|
||||
|
@ -493,7 +495,7 @@ void RealBoundingBox(edict_t *ent, vec3_t mins, vec3_t maxs)
|
|||
}
|
||||
VectorCopy(p[0],mins);
|
||||
VectorCopy(p[0],maxs);
|
||||
for(i=1; i<8; i++)
|
||||
for (i=1; i<8; i++)
|
||||
{
|
||||
mins[0] = min(mins[0],p[i][0]);
|
||||
mins[1] = min(mins[1],p[i][1]);
|
||||
|
@ -606,7 +608,7 @@ qboolean SV_Push (edict_t *pusher, vec3_t move, vec3_t amove)
|
|||
|| check->movetype == MOVETYPE_NOCLIP)
|
||||
continue;
|
||||
|
||||
// if(check->movetype == MOVETYPE_STEP) M_CheckGround(check);
|
||||
// if (check->movetype == MOVETYPE_STEP) M_CheckGround(check);
|
||||
if (!check->area.prev)
|
||||
continue; // not linked in anywhere
|
||||
|
||||
|
@ -652,13 +654,13 @@ qboolean SV_Push (edict_t *pusher, vec3_t move, vec3_t amove)
|
|||
// Lazarus: if turn_rider is set, do it. We don't do this by default
|
||||
// 'cause it can be a fairly drastic change in gameplay
|
||||
if (turn && (check->groundentity == pusher)) {
|
||||
if(!check->client)
|
||||
if (!check->client)
|
||||
{
|
||||
check->s.angles[YAW] += amove[YAW];
|
||||
}
|
||||
else
|
||||
{
|
||||
if(amove[YAW] != 0.)
|
||||
if (amove[YAW] != 0.)
|
||||
{
|
||||
check->client->ps.pmove.delta_angles[YAW] += ANGLE2SHORT(amove[YAW]);
|
||||
check->client->ps.viewangles[YAW] += amove[YAW];
|
||||
|
@ -673,7 +675,7 @@ qboolean SV_Push (edict_t *pusher, vec3_t move, vec3_t amove)
|
|||
// player is riding a MOVETYPE_PUSH
|
||||
check->client->ps.pmove.pm_flags |= PMF_NO_PREDICTION;
|
||||
}
|
||||
if(amove[PITCH] != 0.)
|
||||
if (amove[PITCH] != 0.)
|
||||
{
|
||||
float delta_yaw;
|
||||
float pitch = amove[PITCH];
|
||||
|
@ -691,7 +693,7 @@ qboolean SV_Push (edict_t *pusher, vec3_t move, vec3_t amove)
|
|||
|
||||
// Lazarus: This is where we attempt to move check due to a rotation, WITHOUT embedding
|
||||
// check in pusher (or anything else)
|
||||
if((amove[PITCH] != 0) || (amove[YAW] != 0) || (amove[ROLL] != 0))
|
||||
if ((amove[PITCH] != 0) || (amove[YAW] != 0) || (amove[ROLL] != 0))
|
||||
{
|
||||
// Argh! - always need to do this, except for pendulums
|
||||
// if (pusher->movetype != MOVETYPE_PENDULUM)
|
||||
|
@ -714,7 +716,7 @@ qboolean SV_Push (edict_t *pusher, vec3_t move, vec3_t amove)
|
|||
VectorCopy(check->s.origin,org);
|
||||
org[2] += 2*check->mins[2];
|
||||
//tr = gi.trace(check->s.origin,vec3_origin,vec3_origin,org,check,MASK_SOLID);
|
||||
//if(!tr.startsolid && tr.fraction < 1)
|
||||
//if (!tr.startsolid && tr.fraction < 1)
|
||||
// check->s.origin[2] = tr.endpos[2] - check->mins[2]
|
||||
// + fabs(tr.plane.normal[0])*check->size[0]/2
|
||||
// + fabs(tr.plane.normal[1])*check->size[1]/2;
|
||||
|
@ -723,7 +725,7 @@ qboolean SV_Push (edict_t *pusher, vec3_t move, vec3_t amove)
|
|||
// rotating pushers, trains still seem okay too but
|
||||
// I haven't tested them thoroughly
|
||||
tr = gi.trace(check->s.origin, check->mins, check->maxs, org, check, MASK_SOLID);
|
||||
if(!tr.startsolid && tr.fraction < 1)
|
||||
if (!tr.startsolid && tr.fraction < 1)
|
||||
check->s.origin[2] = tr.endpos[2];
|
||||
}
|
||||
}
|
||||
|
@ -756,7 +758,7 @@ qboolean SV_Push (edict_t *pusher, vec3_t move, vec3_t amove)
|
|||
// Knightmare added
|
||||
// Lazarus: Move check riders, and riders of riders, and... well, you get the pic
|
||||
VectorAdd(move,move2,move3);
|
||||
MoveRiders(check,NULL,move3,amove,turn);
|
||||
MoveRiders (check,NULL,move3,amove,turn);
|
||||
// end Knightmare
|
||||
// impact?
|
||||
continue;
|
||||
|
@ -998,7 +1000,7 @@ void SV_Physics_Toss (edict_t *ent)
|
|||
VectorScale (ent->velocity, FRAMETIME, move);
|
||||
|
||||
|
||||
if(ent->classname[0] == 'R' && (ent->classname[6] == 'X' || ent->classname[6] == '3'))
|
||||
if (ent->classname[0] == 'R' && (ent->classname[6] == 'X' || ent->classname[6] == '3'))
|
||||
{
|
||||
ent->groundentity = ent->union_ent;
|
||||
ent->groundentity_linkcount = ent->union_ent->linkcount;
|
||||
|
@ -1189,7 +1191,7 @@ void SV_Physics_Step (edict_t *ent)
|
|||
ent->velocity[2] *= newspeed;
|
||||
}
|
||||
|
||||
// if(ent->client){if(ent->client->ctf_grapple) if(ent->client->ctf_grapplestate == CTF_GRAPPLE_STATE_FLY) ent->velocity[2] = 0;}
|
||||
// if (ent->client){if (ent->client->ctf_grapple) if (ent->client->ctf_grapplestate == CTF_GRAPPLE_STATE_FLY) ent->velocity[2] = 0;}
|
||||
|
||||
if (ent->velocity[2] || ent->velocity[1] || ent->velocity[0])
|
||||
{
|
||||
|
@ -1218,7 +1220,7 @@ void SV_Physics_Step (edict_t *ent)
|
|||
|
||||
if (ent->svflags & SVF_MONSTER)
|
||||
{
|
||||
if(!deathmatch->value) mask = MASK_MONSTERSOLID;
|
||||
if (!deathmatch->value) mask = MASK_MONSTERSOLID;
|
||||
else mask = MASK_BOTSOLIDX;//MASK_PLAYERSOLID;
|
||||
}
|
||||
else
|
||||
|
@ -1238,13 +1240,13 @@ void SV_Physics_Step (edict_t *ent)
|
|||
if (hitsound && !ent->waterlevel && speed > 0)
|
||||
{
|
||||
|
||||
if( speed < 5 ) gi.sound (ent, 0, gi.soundindex("player/land1.wav"), 1, 1, 0);
|
||||
else if( speed < 40 || ent->client == NULL)
|
||||
if ( speed < 5 ) gi.sound (ent, 0, gi.soundindex("player/land1.wav"), 1, 1, 0);
|
||||
else if ( speed < 40 || ent->client == NULL)
|
||||
{
|
||||
gi.sound (ent, 0, gi.soundindex("player/step3.wav"), 1, 1, 0);
|
||||
// gi.bprintf(PRINT_HIGH,"level 1\n");
|
||||
}
|
||||
else if( speed < 60 )
|
||||
else if ( speed < 60 )
|
||||
{
|
||||
gi.sound (ent, 0, gi.soundindex("*fall2.wav"), 1, 1, 0);
|
||||
ent->pain_debounce_time = level.time + FRAMETIME * 10;
|
||||
|
|
|
@ -476,7 +476,7 @@ void WriteGame (char *filename, qboolean autosave)
|
|||
gi.error ("Couldn't open %s", filename);
|
||||
|
||||
memset (str, 0, sizeof(str));
|
||||
strcpy (str, __DATE__);
|
||||
Com_strcpy (str, sizeof(str), __DATE__);
|
||||
fwrite (str, sizeof(str), 1, f);
|
||||
|
||||
game.autosaved = autosave;
|
||||
|
|
|
@ -156,6 +156,11 @@ void SP_model_train_origin (edict_t *self);
|
|||
void SP_misc_viper_origin (edict_t *ent);
|
||||
void SP_misc_strogg_ship_origin (edict_t *ent);
|
||||
void SP_misc_transport_origin (edict_t *ent);
|
||||
|
||||
// Knightmare- these are from Rogue
|
||||
void SP_func_plat2 (edict_t *ent);
|
||||
void SP_func_door_secret2 (edict_t *ent);
|
||||
void SP_func_force_wall (edict_t *ent);
|
||||
// end Knightmare
|
||||
|
||||
spawn_t spawns[] = {
|
||||
|
@ -294,6 +299,10 @@ spawn_t spawns[] = {
|
|||
{"misc_viper_origin", SP_misc_viper_origin},
|
||||
{"misc_strogg_ship_origin", SP_misc_strogg_ship_origin},
|
||||
{"misc_transport_origin", SP_misc_transport_origin},
|
||||
// Knightmare- these are from Rogue
|
||||
{"func_plat2", SP_func_plat2},
|
||||
{"func_door_secret2", SP_func_door_secret2},
|
||||
{"func_force_wall", SP_func_force_wall},
|
||||
// end Knightmare
|
||||
|
||||
#if 0 // remove monster code
|
||||
|
@ -1580,7 +1589,7 @@ void SP_worldspawn (edict_t *ent)
|
|||
SetItemNames ();
|
||||
|
||||
if (st.nextmap)
|
||||
strcpy (level.nextmap, st.nextmap);
|
||||
Com_strcpy (level.nextmap, sizeof(level.nextmap), st.nextmap);
|
||||
|
||||
// make some data visible to the server
|
||||
|
||||
|
|
|
@ -224,9 +224,9 @@ void SVCmd_WriteIP_f (void)
|
|||
game = gi.cvar("game", "", 0);
|
||||
|
||||
if (!*game->string)
|
||||
sprintf (name, "%s/listip.cfg", GAMEVERSION);
|
||||
Com_sprintf (name, sizeof(name), "%s/listip.cfg", GAMEVERSION);
|
||||
else
|
||||
sprintf (name, "%s/listip.cfg", game->string);
|
||||
Com_sprintf (name, sizeof(name), "%s/listip.cfg", game->string);
|
||||
|
||||
gi.cprintf (NULL, PRINT_HIGH, "Writing %s.\n", name);
|
||||
|
||||
|
@ -297,7 +297,7 @@ void Svcmd_Test_f (void)
|
|||
}
|
||||
|
||||
//chainファイルのセーブ
|
||||
void SaveChain()
|
||||
void SaveChain (void)
|
||||
{
|
||||
char name[256];
|
||||
FILE *fpout;
|
||||
|
@ -310,10 +310,12 @@ void SaveChain()
|
|||
}
|
||||
|
||||
//とりあえずCTFだめ
|
||||
if(ctf->value) sprintf(name,".\\%s\\chctf\\%s.chf",gamepath->string,level.mapname);
|
||||
else sprintf(name,".\\%s\\chdtm\\%s.chn",gamepath->string,level.mapname);
|
||||
if (ctf->value)
|
||||
Com_sprintf (name, sizeof(name), ".\\%s\\chctf\\%s.chf",gamepath->string,level.mapname);
|
||||
else
|
||||
Com_sprintf (name, sizeof(name), ".\\%s\\chdtm\\%s.chn",gamepath->string,level.mapname);
|
||||
|
||||
fpout = fopen(name,"wb");
|
||||
fpout = fopen(name, "wb");
|
||||
if(fpout == NULL) gi.cprintf(NULL,PRINT_HIGH,"Can't open %s\n",name);
|
||||
else
|
||||
{
|
||||
|
|
|
@ -397,9 +397,11 @@ void vectoangles2 (vec3_t value1, vec3_t angles)
|
|||
char *G_CopyString (char *in)
|
||||
{
|
||||
char *out;
|
||||
size_t outSize;
|
||||
|
||||
out = gi.TagMalloc (strlen(in)+1, TAG_LEVEL);
|
||||
strcpy (out, in);
|
||||
outSize = strlen(in)+1;
|
||||
out = gi.TagMalloc (outSize, TAG_LEVEL);
|
||||
Com_strcpy (out, outSize, in);
|
||||
return out;
|
||||
}
|
||||
|
||||
|
|
|
@ -48,7 +48,7 @@ static void check_dodge (edict_t *self, vec3_t start, vec3_t dir, int speed)
|
|||
VectorSet(vn,-8,-8,-8);
|
||||
VectorSet(vx, 8, 8, 8);
|
||||
|
||||
VectorMA (start, 8192, dir, end);
|
||||
VectorMA (start, WORLD_SIZE, dir, end); // was 8192
|
||||
tr = gi.trace (start, vn, vx, end, self, MASK_SHOT);
|
||||
if ((tr.ent) && tr.ent->client && Q_stricmp (tr.ent->classname, "player") == 0 && (tr.ent->health > 0))
|
||||
{
|
||||
|
@ -158,7 +158,12 @@ static void fire_lead (edict_t *self, vec3_t start, vec3_t aimdir, int damage, i
|
|||
|
||||
r = crandom()*hspread;
|
||||
u = crandom()*vspread;
|
||||
VectorMA (start, 8192, forward, end);
|
||||
// Knightmare- adjust spread for expanded world size
|
||||
#ifdef KMQUAKE2_ENGINE_MOD
|
||||
r *= (WORLD_SIZE / 8192);
|
||||
u *= (WORLD_SIZE / 8192);
|
||||
#endif
|
||||
VectorMA (start, WORLD_SIZE, forward, end); // was 8192
|
||||
VectorMA (end, r, right, end);
|
||||
VectorMA (end, u, up, end);
|
||||
|
||||
|
@ -212,7 +217,12 @@ static void fire_lead (edict_t *self, vec3_t start, vec3_t aimdir, int damage, i
|
|||
AngleVectors (dir, forward, right, up);
|
||||
r = crandom()*hspread*2;
|
||||
u = crandom()*vspread*2;
|
||||
VectorMA (water_start, 8192, forward, end);
|
||||
// Knightmare- adjust spread for expanded world size
|
||||
#ifdef KMQUAKE2_ENGINE_MOD
|
||||
r *= (WORLD_SIZE / 8192);
|
||||
u *= (WORLD_SIZE / 8192);
|
||||
#endif
|
||||
VectorMA (water_start, WORLD_SIZE, forward, end); // was 8192
|
||||
VectorMA (end, r, right, end);
|
||||
VectorMA (end, u, up, end);
|
||||
}
|
||||
|
@ -453,7 +463,7 @@ static void Grenade_Explode (edict_t *ent)
|
|||
gi.multicast (ent->s.origin, MULTICAST_PHS);
|
||||
|
||||
G_FreeEdict (ent);
|
||||
UpdateExplIndex(NULL);
|
||||
UpdateExplIndex (NULL);
|
||||
}
|
||||
|
||||
static void Grenade_Touch (edict_t *ent, edict_t *other, cplane_t *plane, csurface_t *surf)
|
||||
|
@ -466,7 +476,7 @@ static void Grenade_Touch (edict_t *ent, edict_t *other, cplane_t *plane, csurfa
|
|||
if (surf && (surf->flags & SURF_SKY))
|
||||
{
|
||||
G_FreeEdict (ent);
|
||||
UpdateExplIndex(NULL);
|
||||
UpdateExplIndex (NULL);
|
||||
return;
|
||||
}
|
||||
|
||||
|
@ -490,7 +500,27 @@ UpdateExplIndex(NULL);
|
|||
Grenade_Explode (ent);
|
||||
}
|
||||
|
||||
void fire_grenade (edict_t *self, vec3_t start, vec3_t aimdir, int damage, int speed, float timer, float damage_radius)
|
||||
// Knightmare added
|
||||
void ContactGrenade_Touch (edict_t *ent, edict_t *other, cplane_t *plane, csurface_t *surf)
|
||||
{
|
||||
if (other == ent->owner)
|
||||
return;
|
||||
|
||||
if (surf && (surf->flags & SURF_SKY))
|
||||
{
|
||||
G_FreeEdict (ent);
|
||||
UpdateExplIndex (NULL);
|
||||
return;
|
||||
}
|
||||
|
||||
if (other->takedamage)
|
||||
ent->enemy = other;
|
||||
|
||||
Grenade_Explode (ent);
|
||||
}
|
||||
// end Knightmare
|
||||
|
||||
void fire_grenade (edict_t *self, vec3_t start, vec3_t aimdir, int damage, int speed, float timer, float damage_radius, qboolean contact)
|
||||
{
|
||||
edict_t *grenade;
|
||||
vec3_t dir;
|
||||
|
@ -513,14 +543,18 @@ void fire_grenade (edict_t *self, vec3_t start, vec3_t aimdir, int damage, int s
|
|||
VectorClear (grenade->maxs);
|
||||
grenade->s.modelindex = gi.modelindex ("models/objects/grenade/tris.md2");
|
||||
grenade->owner = self;
|
||||
grenade->touch = Grenade_Touch;
|
||||
// Knightmare- added contact explode
|
||||
if (contact)
|
||||
grenade->touch = ContactGrenade_Touch;
|
||||
else
|
||||
grenade->touch = Grenade_Touch;
|
||||
grenade->nextthink = level.time + timer;
|
||||
grenade->think = Grenade_Explode;
|
||||
grenade->dmg = damage;
|
||||
grenade->dmg_radius = damage_radius;
|
||||
grenade->classname = "grenade";
|
||||
|
||||
UpdateExplIndex(grenade);
|
||||
UpdateExplIndex (grenade);
|
||||
|
||||
gi.linkentity (grenade);
|
||||
}
|
||||
|
@ -585,7 +619,7 @@ void rocket_touch (edict_t *ent, edict_t *other, cplane_t *plane, csurface_t *su
|
|||
if (surf && (surf->flags & SURF_SKY))
|
||||
{
|
||||
G_FreeEdict (ent);
|
||||
UpdateExplIndex(NULL);
|
||||
UpdateExplIndex (NULL);
|
||||
return;
|
||||
}
|
||||
|
||||
|
@ -627,7 +661,7 @@ UpdateExplIndex(NULL);
|
|||
gi.multicast (ent->s.origin, MULTICAST_PHS);
|
||||
|
||||
G_FreeEdict (ent);
|
||||
UpdateExplIndex(NULL);
|
||||
UpdateExplIndex (NULL);
|
||||
}
|
||||
|
||||
void fire_rocket (edict_t *self, vec3_t start, vec3_t dir, int damage, int speed, float damage_radius, int radius_damage)
|
||||
|
@ -656,7 +690,7 @@ void fire_rocket (edict_t *self, vec3_t start, vec3_t dir, int damage, int speed
|
|||
rocket->s.sound = gi.soundindex ("weapons/rockfly.wav");
|
||||
rocket->classname = "rocket";
|
||||
|
||||
UpdateExplIndex(rocket);
|
||||
UpdateExplIndex (rocket);
|
||||
|
||||
if (self->client)
|
||||
check_dodge (self, rocket->s.origin, dir, speed);
|
||||
|
@ -787,7 +821,7 @@ void fire_rail (edict_t *self, vec3_t start, vec3_t aimdir, int damage, int kick
|
|||
int mask, i=0;
|
||||
qboolean water;
|
||||
|
||||
VectorMA (start, 8192, aimdir, end);
|
||||
VectorMA (start, WORLD_SIZE, aimdir, end); // was 8192
|
||||
VectorCopy (start, from);
|
||||
ignore = self;
|
||||
water = false;
|
||||
|
@ -845,7 +879,7 @@ void fire_sniperail (edict_t *self, vec3_t start, vec3_t aimdir, int damage, int
|
|||
int mask;
|
||||
qboolean water;
|
||||
|
||||
VectorMA (start, 8192, aimdir, end);
|
||||
VectorMA (start, WORLD_SIZE, aimdir, end); // was 8192
|
||||
VectorCopy (start, from);
|
||||
ignore = self;
|
||||
water = false;
|
||||
|
|
204
3zb2/p_client.c
204
3zb2/p_client.c
|
@ -55,7 +55,7 @@ static void SP_CreateCoopSpots (edict_t *self)
|
|||
{
|
||||
edict_t *spot;
|
||||
|
||||
if(Q_stricmp(level.mapname, "security") == 0)
|
||||
if (Q_stricmp(level.mapname, "security") == 0)
|
||||
{
|
||||
spot = G_Spawn();
|
||||
spot->classname = "info_player_coop";
|
||||
|
@ -93,7 +93,7 @@ void SP_info_player_start(edict_t *self)
|
|||
{
|
||||
if (!coop->value)
|
||||
return;
|
||||
if(Q_stricmp(level.mapname, "security") == 0)
|
||||
if (Q_stricmp(level.mapname, "security") == 0)
|
||||
{
|
||||
// invoke one of our gross, ugly, disgusting hacks
|
||||
self->think = SP_CreateCoopSpots;
|
||||
|
@ -126,7 +126,7 @@ void SP_info_player_coop(edict_t *self)
|
|||
return;
|
||||
}
|
||||
|
||||
if((Q_stricmp(level.mapname, "jail2") == 0) ||
|
||||
if ((Q_stricmp(level.mapname, "jail2") == 0) ||
|
||||
(Q_stricmp(level.mapname, "jail4") == 0) ||
|
||||
(Q_stricmp(level.mapname, "mine1") == 0) ||
|
||||
(Q_stricmp(level.mapname, "mine2") == 0) ||
|
||||
|
@ -418,14 +418,14 @@ void TossClientWeapon (edict_t *self)
|
|||
edict_t *enemy = NULL;
|
||||
float spread;
|
||||
|
||||
if(self->enemy && self->enemy != self)
|
||||
if (self->enemy && self->enemy != self)
|
||||
{
|
||||
if(self->enemy->classname[0] == 'p')
|
||||
if (self->enemy->classname[0] == 'p')
|
||||
{
|
||||
|
||||
VectorSubtract(self->s.origin,self->enemy->s.origin,v);
|
||||
dist = VectorLength(v);
|
||||
if(dist < 200) enemy = self->enemy;
|
||||
if (dist < 200) enemy = self->enemy;
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -463,7 +463,7 @@ void TossClientWeapon (edict_t *self)
|
|||
drop = Drop_Item (self, item);
|
||||
self->client->v_angle[YAW] += spread;
|
||||
drop->spawnflags = DROPPED_PLAYER_ITEM;
|
||||
if(enemy) enemy->client->zc.second_target = drop;
|
||||
if (enemy) enemy->client->zc.second_target = drop;
|
||||
}
|
||||
|
||||
if (quad)
|
||||
|
@ -476,7 +476,7 @@ void TossClientWeapon (edict_t *self)
|
|||
drop->touch = Touch_Item;
|
||||
drop->nextthink = level.time + (self->client->quad_framenum - level.framenum) * FRAMETIME;
|
||||
drop->think = G_FreeEdict;
|
||||
if(enemy) enemy->client->zc.second_target = drop;
|
||||
if (enemy) enemy->client->zc.second_target = drop;
|
||||
}
|
||||
// RAFAEL
|
||||
if (quadfire)
|
||||
|
@ -489,7 +489,7 @@ void TossClientWeapon (edict_t *self)
|
|||
drop->touch = Touch_Item;
|
||||
drop->nextthink = level.time + (self->client->quadfire_framenum - level.framenum) * FRAMETIME;
|
||||
drop->think = G_FreeEdict;
|
||||
if(enemy) enemy->client->zc.second_target = drop;
|
||||
if (enemy) enemy->client->zc.second_target = drop;
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -552,7 +552,7 @@ void player_die (edict_t *self, edict_t *inflictor, edict_t *attacker, int damag
|
|||
|
||||
if (!self->deadflag)
|
||||
{
|
||||
if(self->svflags & SVF_MONSTER)
|
||||
if (self->svflags & SVF_MONSTER)
|
||||
{
|
||||
LookAtKiller (self, inflictor, attacker);
|
||||
self->nextthink = level.time + FRAMETIME;
|
||||
|
@ -568,16 +568,16 @@ void player_die (edict_t *self, edict_t *inflictor, edict_t *attacker, int damag
|
|||
self->client->ps.pmove.pm_type = PM_DEAD;
|
||||
ClientObituary (self, inflictor, attacker);
|
||||
//ZOID
|
||||
if(ctf->value) CTFFragBonuses(self, inflictor, attacker);
|
||||
if (ctf->value) CTFFragBonuses(self, inflictor, attacker);
|
||||
//ZOID
|
||||
|
||||
//旗持ってる場合は落とす
|
||||
if(self->client->pers.inventory[ITEM_INDEX(zflag_item)])
|
||||
if (self->client->pers.inventory[ITEM_INDEX(zflag_item)])
|
||||
zflag_item->drop(self,zflag_item);
|
||||
|
||||
TossClientWeapon (self);
|
||||
//ZOID
|
||||
if(ctf->value)
|
||||
if (ctf->value)
|
||||
{
|
||||
CTFPlayerResetGrapple(self);
|
||||
CTFDeadDropFlag(self);
|
||||
|
@ -713,7 +713,7 @@ void player_die (edict_t *self, edict_t *inflictor, edict_t *attacker, int damag
|
|||
self->deadflag = DEAD_DEAD;
|
||||
|
||||
//routing last index move
|
||||
if(chedit->value && self == &g_edicts[1]) Move_LastRouteIndex();
|
||||
if (chedit->value && self == &g_edicts[1]) Move_LastRouteIndex();
|
||||
|
||||
gi.linkentity (self);
|
||||
}
|
||||
|
@ -753,7 +753,7 @@ void InitClientPersistant (gclient_t *client)
|
|||
|
||||
//ZOID
|
||||
item = FindItem("Grapple");
|
||||
if(ctf->value) client->pers.inventory[ITEM_INDEX(item)] = 1; //ponpoko
|
||||
if (ctf->value) client->pers.inventory[ITEM_INDEX(item)] = 1; //ponpoko
|
||||
//ZOID
|
||||
|
||||
client->pers.health = 100;
|
||||
|
@ -1075,7 +1075,7 @@ void SelectSpawnPoint (edict_t *ent, vec3_t origin, vec3_t angles)
|
|||
}
|
||||
|
||||
VectorCopy (spot->s.origin, origin);
|
||||
if(ent->svflags & SVF_MONSTER) origin[2] += 32;
|
||||
if (ent->svflags & SVF_MONSTER) origin[2] += 32;
|
||||
else origin[2] += 9;
|
||||
VectorCopy (spot->s.angles, angles);
|
||||
}
|
||||
|
@ -1131,7 +1131,7 @@ void CopyToBodyQue (edict_t *ent)
|
|||
body->s.number = body - g_edicts;
|
||||
|
||||
//強引にフレームセット
|
||||
if(body->s.modelindex == skullindex || body->s.modelindex == headindex) body->s.frame = 0;
|
||||
if (body->s.modelindex == skullindex || body->s.modelindex == headindex) body->s.frame = 0;
|
||||
|
||||
body->svflags = ent->svflags;
|
||||
VectorCopy (ent->mins, body->mins);
|
||||
|
@ -1145,7 +1145,7 @@ void CopyToBodyQue (edict_t *ent)
|
|||
body->movetype = MOVETYPE_TOSS;//ent->movetype;
|
||||
|
||||
body->die = body_die;
|
||||
if(ent->health < -40)
|
||||
if (ent->health < -40)
|
||||
{
|
||||
body->takedamage = DAMAGE_NO;//DAMAGE_YES;
|
||||
body->solid = SOLID_NOT;
|
||||
|
@ -1438,16 +1438,16 @@ void PutClientInServer (edict_t *ent)
|
|||
client->resp.spectator = false;
|
||||
|
||||
//ZOID
|
||||
if(ctf->value)
|
||||
if (ctf->value)
|
||||
{
|
||||
if (CTFStartClient(ent))
|
||||
return;
|
||||
}
|
||||
//ZOID
|
||||
//ponpoko
|
||||
/* if(hokuto->value)
|
||||
/* if (hokuto->value)
|
||||
{
|
||||
if(ZigockStartClient(ent))
|
||||
if (ZigockStartClient(ent))
|
||||
return;
|
||||
}*/
|
||||
//ponpoko
|
||||
|
@ -1582,7 +1582,7 @@ void ClientUserinfoChanged (edict_t *ent, char *userinfo)
|
|||
// check for malformed or illegal info strings
|
||||
if (!Info_Validate(userinfo))
|
||||
{
|
||||
strcpy (userinfo, "\\name\\badinfo\\skin\\male/grunt");
|
||||
Com_strcpy (userinfo, MAX_INFO_STRING, "\\name\\badinfo\\skin\\male/grunt"); // userinfo is always length of MAX_INFO_STRING
|
||||
}
|
||||
|
||||
// set name
|
||||
|
@ -1823,7 +1823,7 @@ void Get_Position ( edict_t *ent, vec3_t position )
|
|||
|
||||
void ChainPodThink (edict_t *ent)
|
||||
{
|
||||
if(ent->owner == NULL )return;
|
||||
if (ent->owner == NULL )return;
|
||||
|
||||
gi.WriteByte (svc_temp_entity);
|
||||
gi.WriteByte (TE_BFG_LASER);
|
||||
|
@ -1831,9 +1831,9 @@ void ChainPodThink (edict_t *ent)
|
|||
gi.WritePosition (ent->owner->s.origin);
|
||||
gi.multicast (ent->s.origin, MULTICAST_PHS);
|
||||
|
||||
if(ent->target_ent != NULL)
|
||||
if (ent->target_ent != NULL)
|
||||
{
|
||||
if(Q_stricmp (ent->target_ent->classname, "item_flag_team2") == 0)
|
||||
if (Q_stricmp (ent->target_ent->classname, "item_flag_team2") == 0)
|
||||
{
|
||||
gi.WriteByte (svc_temp_entity);
|
||||
gi.WriteByte (TE_BFG_LASER);
|
||||
|
@ -1858,9 +1858,9 @@ qboolean TraceX (edict_t *ent,vec3_t p2)
|
|||
|
||||
contents = CONTENTS_SOLID | CONTENTS_WINDOW;
|
||||
|
||||
if(!(ent->svflags & SVF_MONSTER))
|
||||
if (!(ent->svflags & SVF_MONSTER))
|
||||
{
|
||||
if(ent->client->zc.waterstate)
|
||||
if (ent->client->zc.waterstate)
|
||||
{
|
||||
VectorCopy(ent->mins,v1);
|
||||
VectorCopy(ent->maxs,v2);
|
||||
|
@ -1870,7 +1870,7 @@ qboolean TraceX (edict_t *ent,vec3_t p2)
|
|||
v2[0] += 4;
|
||||
v2[1] += 4;*/
|
||||
}
|
||||
else if(!(ent->client->ps.pmove.pm_flags & PMF_DUCKED))
|
||||
else if (!(ent->client->ps.pmove.pm_flags & PMF_DUCKED))
|
||||
{
|
||||
VectorSet(v1,-16,-16,-4);
|
||||
VectorSet(v2,16,16,32);
|
||||
|
@ -1891,17 +1891,17 @@ qboolean TraceX (edict_t *ent,vec3_t p2)
|
|||
}
|
||||
|
||||
rs_trace = gi.trace (ent->s.origin, v1, v2, p2 ,ent, contents );
|
||||
if(rs_trace.fraction == 1.0 && !rs_trace.allsolid && !rs_trace.startsolid ) return true;
|
||||
if (rs_trace.fraction == 1.0 && !rs_trace.allsolid && !rs_trace.startsolid ) return true;
|
||||
|
||||
if(ent->client->zc.route_trace && rs_trace.ent && (ent->svflags & SVF_MONSTER))
|
||||
if (ent->client->zc.route_trace && rs_trace.ent && (ent->svflags & SVF_MONSTER))
|
||||
{
|
||||
//if(!rs_trace.ent->targetname)
|
||||
if(!Q_stricmp(rs_trace.ent->classname, "func_door"))
|
||||
//if (!rs_trace.ent->targetname)
|
||||
if (!Q_stricmp(rs_trace.ent->classname, "func_door"))
|
||||
{
|
||||
if(rs_trace.ent->moveinfo.state == PSTATE_UP) return true;
|
||||
if (rs_trace.ent->moveinfo.state == PSTATE_UP) return true;
|
||||
else return false;
|
||||
}
|
||||
// if(!Q_stricmp(rs_trace.ent->classname, "func_train")) return true;
|
||||
// if (!Q_stricmp(rs_trace.ent->classname, "func_train")) return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
|
@ -1932,7 +1932,7 @@ void ClientThink (edict_t *ent, usercmd_t *ucmd)
|
|||
else
|
||||
ground_speed = 0;
|
||||
|
||||
if( (ent->client->ctf_grapplestate == CTF_GRAPPLE_STATE_PULL) ||
|
||||
if ( (ent->client->ctf_grapplestate == CTF_GRAPPLE_STATE_PULL) ||
|
||||
(ent->client->chase_target != NULL) ||
|
||||
(ground_speed > 0) )
|
||||
ent->client->ps.pmove.pm_flags |= PMF_NO_PREDICTION;
|
||||
|
@ -1943,19 +1943,19 @@ void ClientThink (edict_t *ent, usercmd_t *ucmd)
|
|||
impulse = ucmd->impulse;
|
||||
|
||||
|
||||
if(impulse == 1) gi.bprintf(PRINT_HIGH,"%f\n",ent->s.origin[2]);
|
||||
if (impulse == 1) gi.bprintf(PRINT_HIGH,"%f\n",ent->s.origin[2]);
|
||||
|
||||
//--------------------------------------------------------------------------------------
|
||||
//Target check
|
||||
if(ent->client->zc.first_target)
|
||||
if (ent->client->zc.first_target)
|
||||
{
|
||||
if(!ent->client->zc.first_target->inuse) ent->client->zc.first_target = NULL;
|
||||
else if(!ent->client->zc.first_target->deadflag) ent->client->zc.first_target = NULL;
|
||||
if (!ent->client->zc.first_target->inuse) ent->client->zc.first_target = NULL;
|
||||
else if (!ent->client->zc.first_target->deadflag) ent->client->zc.first_target = NULL;
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------------------
|
||||
//get JumpMax
|
||||
if(JumpMax == 0)
|
||||
if (JumpMax == 0)
|
||||
{
|
||||
x = VEL_BOT_JUMP - ent->gravity * sv_gravity->value * FRAMETIME;
|
||||
JumpMax = 0;
|
||||
|
@ -1963,33 +1963,33 @@ void ClientThink (edict_t *ent, usercmd_t *ucmd)
|
|||
{
|
||||
JumpMax += x * FRAMETIME;
|
||||
x -= ent->gravity * sv_gravity->value * FRAMETIME;
|
||||
if( x < 0 ) break;
|
||||
if ( x < 0 ) break;
|
||||
}
|
||||
}
|
||||
|
||||
//route nodeput
|
||||
j = 0;
|
||||
if(ent->client->ctf_grapple && ent->client->ctf_grapplestate > CTF_GRAPPLE_STATE_FLY) j = 1;
|
||||
if (ent->client->ctf_grapple && ent->client->ctf_grapplestate > CTF_GRAPPLE_STATE_FLY) j = 1;
|
||||
|
||||
if(!j && chedit->value && CurrentIndex < MAXNODES && !ent->deadflag && ent == &g_edicts[1])
|
||||
if (!j && chedit->value && CurrentIndex < MAXNODES && !ent->deadflag && ent == &g_edicts[1])
|
||||
{
|
||||
if(targetindex > 0)
|
||||
if (targetindex > 0)
|
||||
{
|
||||
if(ent->target_ent == NULL) return;
|
||||
if (ent->target_ent == NULL) return;
|
||||
other = ent->target_ent;
|
||||
|
||||
if(!TraceX(ent,other->s.origin))
|
||||
if (!TraceX(ent,other->s.origin))
|
||||
{
|
||||
k = 0;
|
||||
i = other->client->zc.routeindex;
|
||||
while(1)
|
||||
{
|
||||
if(i + 1 >= CurrentIndex)
|
||||
if (i + 1 >= CurrentIndex)
|
||||
{
|
||||
j = Route[i + 1].state;
|
||||
if(j == GRS_ONTRAIN) if(Route[i + 1].ent->trainteam) break;
|
||||
if (j == GRS_ONTRAIN) if (Route[i + 1].ent->trainteam) break;
|
||||
Get_RouteOrigin(i + 1,v);
|
||||
if(!TraceX(ent,other->s.origin))
|
||||
if (!TraceX(ent,other->s.origin))
|
||||
{
|
||||
break;
|
||||
}
|
||||
|
@ -2020,45 +2020,46 @@ void ClientThink (edict_t *ent, usercmd_t *ucmd)
|
|||
Get_WaterState(ent);
|
||||
i = false;
|
||||
l = GRS_NORMAL;
|
||||
if(CurrentIndex > 0) Get_RouteOrigin(CurrentIndex - 1,v);
|
||||
if(!Route[CurrentIndex].index)
|
||||
if (CurrentIndex > 0) Get_RouteOrigin(CurrentIndex - 1,v);
|
||||
if (!Route[CurrentIndex].index)
|
||||
{
|
||||
VectorCopy(ent->s.origin,v);
|
||||
old_ground = ent->groundentity;
|
||||
//gi.bprintf(PRINT_HIGH,"1\n");
|
||||
if(ent->groundentity)
|
||||
if (ent->groundentity)
|
||||
i = true;
|
||||
}
|
||||
else if(!TraceX(ent,v) /*&& ent->groundentity*/)
|
||||
else if (!TraceX(ent,v) /*&& ent->groundentity*/)
|
||||
{
|
||||
VectorCopy(ent->s.old_origin,v);
|
||||
//gi.bprintf(PRINT_HIGH,"2\n");
|
||||
i = 3;
|
||||
if(0/*ent->groundentity*/)
|
||||
if (0/*ent->groundentity*/)
|
||||
{
|
||||
if(ent->groundentity->classname[0] == 'f') i = false;
|
||||
if (ent->groundentity->classname[0] == 'f') i = false;
|
||||
}
|
||||
}
|
||||
else if(ent->client->zc.waterstate != oldwaterstate)
|
||||
else if (ent->client->zc.waterstate != oldwaterstate)
|
||||
{
|
||||
i = true;
|
||||
if(ent->groundentity )
|
||||
if (ent->groundentity )
|
||||
{
|
||||
if(!Q_stricmp(ent->groundentity->classname, "func_train")
|
||||
if (!Q_stricmp(ent->groundentity->classname, "func_train")
|
||||
|| !Q_stricmp(ent->groundentity->classname, "func_plat")
|
||||
|| !Q_stricmp(ent->groundentity->classname, "func_plat2")
|
||||
|| !Q_stricmp(ent->groundentity->classname, "func_door")) i = false;
|
||||
}
|
||||
|
||||
if(ent->client->zc.waterstate > oldwaterstate) VectorCopy(ent->s.origin,v);
|
||||
if (ent->client->zc.waterstate > oldwaterstate) VectorCopy(ent->s.origin,v);
|
||||
else VectorCopy(ent->s.old_origin,v);
|
||||
//gi.bprintf(PRINT_HIGH,"5\n");
|
||||
}
|
||||
else if(fabs(v[2] - ent->s.origin[2]) > 20)
|
||||
else if (fabs(v[2] - ent->s.origin[2]) > 20)
|
||||
{
|
||||
if(ent->groundentity && ent->waterlevel < 2)
|
||||
if (ent->groundentity && ent->waterlevel < 2)
|
||||
{
|
||||
k = true;
|
||||
if(k)
|
||||
if (k)
|
||||
{
|
||||
VectorCopy(ent->s.origin,v);
|
||||
//gi.bprintf(PRINT_HIGH,"3\n");
|
||||
|
@ -2067,7 +2068,7 @@ void ClientThink (edict_t *ent, usercmd_t *ucmd)
|
|||
}
|
||||
|
||||
}
|
||||
else if(((/*ent->velocity[2] > 10 &&*/ !ent->groundentity && wasground == true)
|
||||
else if (((/*ent->velocity[2] > 10 &&*/ !ent->groundentity && wasground == true)
|
||||
|| (/*ent->velocity[2] < -0.5 &&*/ ent->groundentity && wasground == false))
|
||||
&& Route[CurrentIndex - 1].state <= GRS_ITEMS)
|
||||
{
|
||||
|
@ -2076,21 +2077,22 @@ void ClientThink (edict_t *ent, usercmd_t *ucmd)
|
|||
VectorCopy(ent->s.old_origin,v);
|
||||
v[2] -= 2;
|
||||
rs_trace = gi.trace(ent->s.old_origin,ent->mins ,ent->maxs, v ,ent,MASK_PLAYERSOLID);
|
||||
if(rs_trace.fraction != 1.0) j = true;
|
||||
if (rs_trace.fraction != 1.0) j = true;
|
||||
|
||||
if(old_ground)
|
||||
if (old_ground)
|
||||
{
|
||||
if(!Q_stricmp(old_ground->classname, "func_train")
|
||||
if (!Q_stricmp(old_ground->classname, "func_train")
|
||||
|| !Q_stricmp(old_ground->classname, "func_plat")
|
||||
|| !Q_stricmp(old_ground->classname, "func_plat2")
|
||||
|| !Q_stricmp(old_ground->classname, "func_door")) k = false;
|
||||
}
|
||||
if(!ent->groundentity /*&& j*/&& wasground == true && k)
|
||||
if (!ent->groundentity /*&& j*/&& wasground == true && k)
|
||||
{
|
||||
VectorCopy(ent->s.old_origin,v);
|
||||
//gi.bprintf(PRINT_HIGH,"6\n");
|
||||
i = true;
|
||||
}
|
||||
else if(ent->groundentity /*&& !j*/&& wasground == false && k)
|
||||
else if (ent->groundentity /*&& !j*/&& wasground == false && k)
|
||||
{
|
||||
// VectorSubtract(ent->s.origin)
|
||||
|
||||
|
@ -2100,13 +2102,14 @@ void ClientThink (edict_t *ent, usercmd_t *ucmd)
|
|||
}
|
||||
|
||||
}
|
||||
else if(Route[CurrentIndex-1].index > 1)
|
||||
else if (Route[CurrentIndex-1].index > 1)
|
||||
{
|
||||
k = true;
|
||||
if(0/*old_ground*/)
|
||||
if (0/*old_ground*/)
|
||||
{
|
||||
if(!Q_stricmp(old_ground->classname, "func_train")
|
||||
if (!Q_stricmp(old_ground->classname, "func_train")
|
||||
|| !Q_stricmp(old_ground->classname, "func_plat")
|
||||
|| !Q_stricmp(old_ground->classname, "func_plat2")
|
||||
|| !Q_stricmp(old_ground->classname, "func_door")) k = false;
|
||||
}
|
||||
Get_RouteOrigin(CurrentIndex - 1,min);
|
||||
|
@ -2114,7 +2117,7 @@ void ClientThink (edict_t *ent, usercmd_t *ucmd)
|
|||
VectorSubtract(min,max,v);
|
||||
x = Get_yaw(v);
|
||||
VectorSubtract(ent->s.origin,/*Route[CurrentIndex-1].Pt*/ent->s.old_origin,v);
|
||||
if(VectorLength(v) > 0 && Get_vec_yaw(v,x) > 45 && k )
|
||||
if (VectorLength(v) > 0 && Get_vec_yaw(v,x) > 45 && k )
|
||||
{
|
||||
VectorCopy(ent->s.old_origin,v);
|
||||
//gi.bprintf(PRINT_HIGH,"8\n");
|
||||
|
@ -2122,17 +2125,17 @@ void ClientThink (edict_t *ent, usercmd_t *ucmd)
|
|||
}
|
||||
}
|
||||
|
||||
if(ent->groundentity)
|
||||
if (ent->groundentity)
|
||||
{
|
||||
if(ent->groundentity != old_ground)
|
||||
if (ent->groundentity != old_ground)
|
||||
{
|
||||
other = old_ground;
|
||||
old_ground = ent->groundentity;
|
||||
if(!Q_stricmp(old_ground->classname, "func_plat"))
|
||||
if ( !Q_stricmp(old_ground->classname, "func_plat") || !Q_stricmp(old_ground->classname, "func_plat2") )
|
||||
{
|
||||
if(old_ground->union_ent)
|
||||
if (old_ground->union_ent)
|
||||
{
|
||||
if(old_ground->union_ent->inuse && old_ground->union_ent->classname[0] == 'R')
|
||||
if (old_ground->union_ent->inuse && old_ground->union_ent->classname[0] == 'R')
|
||||
{
|
||||
//gi.bprintf(PRINT_HIGH,"plat put\n");
|
||||
VectorCopy(old_ground->monsterinfo.last_sighting,v);
|
||||
|
@ -2141,11 +2144,11 @@ void ClientThink (edict_t *ent, usercmd_t *ucmd)
|
|||
}
|
||||
}
|
||||
}
|
||||
else if(!Q_stricmp(old_ground->classname, "func_train"))
|
||||
else if (!Q_stricmp(old_ground->classname, "func_train"))
|
||||
{
|
||||
if(old_ground->union_ent)
|
||||
if (old_ground->union_ent)
|
||||
{
|
||||
if(old_ground->union_ent->inuse && old_ground->union_ent->classname[0] == 'R')
|
||||
if (old_ground->union_ent->inuse && old_ground->union_ent->classname[0] == 'R')
|
||||
{
|
||||
VectorCopy(old_ground->monsterinfo.last_sighting,v);
|
||||
l = GRS_ONTRAIN;
|
||||
|
@ -2153,12 +2156,12 @@ void ClientThink (edict_t *ent, usercmd_t *ucmd)
|
|||
}
|
||||
}
|
||||
}
|
||||
else if(!Q_stricmp(old_ground->classname, "func_door"))
|
||||
else if (!Q_stricmp(old_ground->classname, "func_door"))
|
||||
{
|
||||
k = false;
|
||||
if(old_ground->targetname && old_ground->union_ent)
|
||||
if (old_ground->targetname && old_ground->union_ent)
|
||||
{
|
||||
if(TraceX(ent,old_ground->union_ent->s.origin)
|
||||
if (TraceX(ent,old_ground->union_ent->s.origin)
|
||||
&& fabs(ent->s.origin[2] - old_ground->union_ent->s.origin[2]) < JumpMax)
|
||||
{
|
||||
VectorCopy(old_ground->monsterinfo.last_sighting,v);
|
||||
|
@ -2168,7 +2171,7 @@ void ClientThink (edict_t *ent, usercmd_t *ucmd)
|
|||
else k = true;
|
||||
}
|
||||
else k = true;
|
||||
if(k && i)
|
||||
if (k && i)
|
||||
{
|
||||
i = 2;
|
||||
old_ground = other;
|
||||
|
@ -2176,33 +2179,34 @@ void ClientThink (edict_t *ent, usercmd_t *ucmd)
|
|||
}
|
||||
}
|
||||
}
|
||||
if(old_ground)
|
||||
if (old_ground)
|
||||
{
|
||||
if(old_ground->classname[0] == 'f' && i != 2)
|
||||
if (old_ground->classname[0] == 'f' && i != 2)
|
||||
{
|
||||
if(!Q_stricmp(old_ground->classname, "func_train")
|
||||
if (!Q_stricmp(old_ground->classname, "func_train")
|
||||
|| !Q_stricmp(old_ground->classname, "func_plat")
|
||||
|| !Q_stricmp(old_ground->classname, "func_plat2")
|
||||
|| !Q_stricmp(old_ground->classname, "func_door")) i = false;
|
||||
}
|
||||
}
|
||||
|
||||
if(Route[CurrentIndex-1].index > 0 && i == true)
|
||||
if (Route[CurrentIndex-1].index > 0 && i == true)
|
||||
{
|
||||
Get_RouteOrigin(CurrentIndex - 1,max);
|
||||
VectorSubtract(max,v,vv);
|
||||
if(VectorLength(vv) <= 32 ) i = false;
|
||||
if (VectorLength(vv) <= 32 ) i = false;
|
||||
}
|
||||
|
||||
if(l == GRS_ONTRAIN || l == GRS_ONPLAT || l == GRS_ONDOOR)
|
||||
if (l == GRS_ONTRAIN || l == GRS_ONPLAT || l == GRS_ONDOOR)
|
||||
{
|
||||
if(Route[CurrentIndex - 1].ent == old_ground) i = false;
|
||||
if (Route[CurrentIndex - 1].ent == old_ground) i = false;
|
||||
}
|
||||
|
||||
if(i)
|
||||
if (i)
|
||||
{
|
||||
if(l == GRS_NORMAL && ent->groundentity)
|
||||
if (l == GRS_NORMAL && ent->groundentity)
|
||||
{
|
||||
if(!Q_stricmp(old_ground->classname, "func_rotating"))
|
||||
if (!Q_stricmp(old_ground->classname, "func_rotating"))
|
||||
{
|
||||
l = GRS_ONROTATE;
|
||||
// gi.bprintf(PRINT_HIGH,"On Rotate\n");
|
||||
|
@ -2211,18 +2215,18 @@ void ClientThink (edict_t *ent, usercmd_t *ucmd)
|
|||
|
||||
VectorCopy(v,Route[CurrentIndex].Pt);
|
||||
Route[CurrentIndex].state = l;
|
||||
if(l > GRS_ITEMS && l <= GRS_ONTRAIN) Route[CurrentIndex].ent = old_ground;
|
||||
else if(l == GRS_ONDOOR) Route[CurrentIndex].ent = old_ground;
|
||||
if (l > GRS_ITEMS && l <= GRS_ONTRAIN) Route[CurrentIndex].ent = old_ground;
|
||||
else if (l == GRS_ONDOOR) Route[CurrentIndex].ent = old_ground;
|
||||
|
||||
if(l == GRS_ONTRAIN && old_ground->trainteam && old_ground->target_ent)
|
||||
if (l == GRS_ONTRAIN && old_ground->trainteam && old_ground->target_ent)
|
||||
{
|
||||
if(!Q_stricmp(old_ground->target_ent->classname,"path_corner"))
|
||||
if (!Q_stricmp(old_ground->target_ent->classname,"path_corner"))
|
||||
VectorCopy(old_ground->target_ent->s.origin,Route[CurrentIndex].Tcourner);
|
||||
|
||||
//gi.bprintf(PRINT_HIGH,"get chain\n");
|
||||
}
|
||||
//when normal or items
|
||||
if(++CurrentIndex < MAXNODES)
|
||||
if (++CurrentIndex < MAXNODES)
|
||||
{
|
||||
gi.bprintf(PRINT_HIGH,"Last %i pod(s).\n",MAXNODES - CurrentIndex);
|
||||
memset(&Route[CurrentIndex],0,sizeof(route_t)); //initialize
|
||||
|
@ -2230,7 +2234,7 @@ void ClientThink (edict_t *ent, usercmd_t *ucmd)
|
|||
}
|
||||
}
|
||||
// VectorCopy(ent->s.origin,old_origin);
|
||||
if(ent->groundentity != NULL) wasground = true;
|
||||
if (ent->groundentity != NULL) wasground = true;
|
||||
else wasground = false;
|
||||
}
|
||||
|
||||
|
|
|
@ -218,7 +218,8 @@ void DeathmatchScoreboardMessage (edict_t *ent, edict_t *killer)
|
|||
j = (int)strlen(entry);
|
||||
if (stringlength + j > 1024)
|
||||
break;
|
||||
strcpy (string + stringlength, entry);
|
||||
// strcpy (string + stringlength, entry);
|
||||
Com_strcpy (string + stringlength, sizeof(string) - stringlength, entry);
|
||||
stringlength += j;
|
||||
}
|
||||
|
||||
|
@ -229,7 +230,8 @@ void DeathmatchScoreboardMessage (edict_t *ent, edict_t *killer)
|
|||
j = (int)strlen(entry);
|
||||
if (stringlength + j > 1024)
|
||||
break;
|
||||
strcpy (string + stringlength, entry);
|
||||
// strcpy (string + stringlength, entry);
|
||||
Com_strcpy (string + stringlength, sizeof(string) - stringlength, entry);
|
||||
stringlength += j;
|
||||
}
|
||||
|
||||
|
|
|
@ -69,7 +69,7 @@ void PMenu_Update(edict_t *ent)
|
|||
|
||||
hnd = ent->client->menu;
|
||||
|
||||
strcpy(string, "xv 32 yv 8 picn inventory ");
|
||||
Com_strcpy (string, sizeof(string), "xv 32 yv 8 picn inventory ");
|
||||
|
||||
for (i = 0, p = hnd->entries; i < hnd->num; i++, p++) {
|
||||
if (!p->text || !*(p->text))
|
||||
|
@ -79,7 +79,8 @@ void PMenu_Update(edict_t *ent)
|
|||
alt = true;
|
||||
t++;
|
||||
}
|
||||
sprintf(string + strlen(string), "yv %d ", 32 + i * 8);
|
||||
// sprintf (string + strlen(string), "yv %d ", 32 + i * 8);
|
||||
Com_sprintf (string + strlen(string), sizeof(string)-strlen(string), "yv %d ", 32 + i * 8);
|
||||
if (p->align == PMENU_ALIGN_CENTER)
|
||||
x = 196/2 - (int)strlen(t)*4 + 64;
|
||||
else if (p->align == PMENU_ALIGN_RIGHT)
|
||||
|
@ -87,15 +88,18 @@ void PMenu_Update(edict_t *ent)
|
|||
else
|
||||
x = 64;
|
||||
|
||||
sprintf(string + strlen(string), "xv %d ",
|
||||
x - ((hnd->cur == i) ? 8 : 0));
|
||||
// sprintf (string + strlen(string), "xv %d ", x - ((hnd->cur == i) ? 8 : 0));
|
||||
Com_sprintf (string + strlen(string), sizeof(string)-strlen(string), "xv %d ", x - ((hnd->cur == i) ? 8 : 0));
|
||||
|
||||
if (hnd->cur == i)
|
||||
sprintf(string + strlen(string), "string2 \"\x0d%s\" ", t);
|
||||
// sprintf (string + strlen(string), "string2 \"\x0d%s\" ", t);
|
||||
Com_sprintf (string + strlen(string), sizeof(string)-strlen(string), "string2 \"\x0d%s\" ", t);
|
||||
else if (alt)
|
||||
sprintf(string + strlen(string), "string2 \"%s\" ", t);
|
||||
// sprintf (string + strlen(string), "string2 \"%s\" ", t);
|
||||
Com_sprintf (string + strlen(string), sizeof(string)-strlen(string), "string2 \"%s\" ", t);
|
||||
else
|
||||
sprintf(string + strlen(string), "string \"%s\" ", t);
|
||||
// sprintf (string + strlen(string), "string \"%s\" ", t);
|
||||
Com_sprintf (string + strlen(string), sizeof(string)-strlen(string), "string \"%s\" ", t);
|
||||
alt = false;
|
||||
}
|
||||
|
||||
|
|
247
3zb2/p_weapon.c
247
3zb2/p_weapon.c
|
@ -139,17 +139,17 @@ qboolean Pickup_Weapon (edict_t *ent, edict_t *other)
|
|||
}
|
||||
}
|
||||
|
||||
if((other->svflags & SVF_MONSTER) && ctf->value && other->client->zc.route_trace)
|
||||
if ((other->svflags & SVF_MONSTER) && ctf->value && other->client->zc.route_trace)
|
||||
{
|
||||
if(!other->client->zc.first_target)
|
||||
if (!other->client->zc.first_target)
|
||||
{
|
||||
for(i = 0;i < (5 * 2);i++)
|
||||
for (i = 0;i < (5 * 2);i++)
|
||||
{
|
||||
if((other->client->zc.routeindex + i) >= CurrentIndex) break;
|
||||
if(Route[other->client->zc.routeindex + i].state == GRS_GRAPSHOT)
|
||||
if ((other->client->zc.routeindex + i) >= CurrentIndex) break;
|
||||
if (Route[other->client->zc.routeindex + i].state == GRS_GRAPSHOT)
|
||||
{
|
||||
item = Fdi_GRAPPLE;//FindItem("Grapple");
|
||||
if( other->client->pers.inventory[ITEM_INDEX(item)]) item->use(other,item);
|
||||
if ( other->client->pers.inventory[ITEM_INDEX(item)]) item->use(other,item);
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
@ -160,11 +160,11 @@ qboolean Pickup_Weapon (edict_t *ent, edict_t *other)
|
|||
(other->client->pers.inventory[index] == 1) &&
|
||||
( !deathmatch->value || other->client->pers.weapon == Fdi_BLASTER/*FindItem("blaster")*/ ) )
|
||||
{
|
||||
if(other->svflags & SVF_MONSTER) ent->item->use(other,ent->item);
|
||||
if (other->svflags & SVF_MONSTER) ent->item->use(other,ent->item);
|
||||
else other->client->newweapon = ent->item;
|
||||
}
|
||||
|
||||
if(other->svflags & SVF_MONSTER
|
||||
if (other->svflags & SVF_MONSTER
|
||||
&& (other->client->pers.weapon == Fdi_BLASTER/*FindItem("blaster") */
|
||||
|| other->client->pers.weapon == Fdi_GRENADES/*FindItem("Grenades")*/))
|
||||
{
|
||||
|
@ -188,19 +188,19 @@ void ShowGun(edict_t *ent)
|
|||
{
|
||||
int i,j;
|
||||
|
||||
if(!ent->client->pers.weapon)
|
||||
if (!ent->client->pers.weapon)
|
||||
{
|
||||
ent->s.modelindex2 = 0;
|
||||
return;
|
||||
}
|
||||
if(!vwep->value)
|
||||
if (!vwep->value)
|
||||
{
|
||||
ent->s.modelindex2 = MAX_MODELS-1;
|
||||
return;
|
||||
}
|
||||
|
||||
j = Get_KindWeapon(ent->client->pers.weapon);
|
||||
if(j == WEAP_GRAPPLE) j = WEAP_BLASTER;
|
||||
if (j == WEAP_GRAPPLE) j = WEAP_BLASTER;
|
||||
|
||||
ent->s.modelindex2 = MAX_MODELS-1;
|
||||
if (ent->client->pers.weapon)
|
||||
|
@ -245,9 +245,9 @@ void ChangeWeapon (edict_t *ent)
|
|||
ent->client->ps.gunframe = 0;
|
||||
//lm ctf
|
||||
mdl = ent->client->pers.weapon->view_model;
|
||||
if(ctf->value == 2)
|
||||
if (ctf->value == 2)
|
||||
{
|
||||
if(Q_stricmp (ent->client->pers.weapon->classname, "weapon_grapple") == 0)
|
||||
if (Q_stricmp (ent->client->pers.weapon->classname, "weapon_grapple") == 0)
|
||||
{
|
||||
mdl = "models/weapons/v_hook/tris.md2";
|
||||
}
|
||||
|
@ -258,7 +258,7 @@ void ChangeWeapon (edict_t *ent)
|
|||
|
||||
// ### Hentai ### BEGIN
|
||||
ent->client->anim_priority = ANIM_PAIN;
|
||||
if(ent->client->ps.pmove.pm_flags & PMF_DUCKED)
|
||||
if (ent->client->ps.pmove.pm_flags & PMF_DUCKED)
|
||||
{
|
||||
ent->s.frame = FRAME_crpain1;
|
||||
ent->client->anim_end = FRAME_crpain4;
|
||||
|
@ -333,9 +333,9 @@ void NoAmmoWeaponChange (edict_t *ent)
|
|||
item = Fdi_SHOTGUN;//FindItem ("shotgun");
|
||||
// return;
|
||||
}
|
||||
if(item == NULL) item = Fdi_BLASTER;//FindItem ("blaster");
|
||||
if (item == NULL) item = Fdi_BLASTER;//FindItem ("blaster");
|
||||
|
||||
if(ent->svflags & SVF_MONSTER) item->use(ent,item);
|
||||
if (ent->svflags & SVF_MONSTER) item->use(ent,item);
|
||||
else ent->client->newweapon = item;
|
||||
|
||||
}
|
||||
|
@ -417,10 +417,10 @@ void Use_Weapon (edict_t *ent, gitem_t *item)
|
|||
if (item == ent->client->pers.weapon)
|
||||
return;
|
||||
|
||||
if(ent->svflags & SVF_MONSTER)
|
||||
if (ent->svflags & SVF_MONSTER)
|
||||
{
|
||||
if(ent->client->newweapon != NULL) return;
|
||||
if(!Q_stricmp (item->pickup_name, "Blaster"))
|
||||
if (ent->client->newweapon != NULL) return;
|
||||
if (!Q_stricmp (item->pickup_name, "Blaster"))
|
||||
{
|
||||
ent->client->newweapon = item;
|
||||
return;
|
||||
|
@ -434,13 +434,13 @@ void Use_Weapon (edict_t *ent, gitem_t *item)
|
|||
|
||||
if (!ent->client->pers.inventory[ammo_index])
|
||||
{
|
||||
if(!(ent->svflags & SVF_MONSTER)) gi.cprintf (ent, PRINT_HIGH, "No %s for %s.\n", ammo_item->pickup_name, item->pickup_name);
|
||||
if (!(ent->svflags & SVF_MONSTER)) gi.cprintf (ent, PRINT_HIGH, "No %s for %s.\n", ammo_item->pickup_name, item->pickup_name);
|
||||
return;
|
||||
}
|
||||
|
||||
if (ent->client->pers.inventory[ammo_index] < item->quantity)
|
||||
{
|
||||
if(!(ent->svflags & SVF_MONSTER)) gi.cprintf (ent, PRINT_HIGH, "Not enough %s for %s.\n", ammo_item->pickup_name, item->pickup_name);
|
||||
if (!(ent->svflags & SVF_MONSTER)) gi.cprintf (ent, PRINT_HIGH, "Not enough %s for %s.\n", ammo_item->pickup_name, item->pickup_name);
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
@ -457,7 +457,7 @@ void Use_Weapon2 (edict_t *ent, gitem_t *item)
|
|||
gitem_t *nextitem;
|
||||
int index;
|
||||
|
||||
if(ent->svflags & SVF_MONSTER)
|
||||
if (ent->svflags & SVF_MONSTER)
|
||||
{
|
||||
Use_Weapon(ent,item);
|
||||
return;
|
||||
|
@ -544,7 +544,7 @@ void Drop_Weapon (edict_t *ent, gitem_t *item)
|
|||
// see if we're already using it
|
||||
if ( ((item == ent->client->pers.weapon) || (item == ent->client->newweapon))&& (ent->client->pers.inventory[index] == 1) )
|
||||
{
|
||||
if(!(ent->svflags & SVF_MONSTER)) gi.cprintf (ent, PRINT_HIGH, "Can't drop current weapon\n");
|
||||
if (!(ent->svflags & SVF_MONSTER)) gi.cprintf (ent, PRINT_HIGH, "Can't drop current weapon\n");
|
||||
return;
|
||||
}
|
||||
|
||||
|
@ -564,9 +564,10 @@ A generic function to handle the basics of weapon thinking
|
|||
#define FRAME_IDLE_FIRST (FRAME_FIRE_LAST + 1)
|
||||
#define FRAME_DEACTIVATE_FIRST (FRAME_IDLE_LAST + 1)
|
||||
|
||||
void Weapon_Generic2 (edict_t *ent, int FRAME_ACTIVATE_LAST, int FRAME_FIRE_LAST, int FRAME_IDLE_LAST, int FRAME_DEACTIVATE_LAST, int *pause_frames, int *fire_frames, void (*fire)(edict_t *ent))
|
||||
void Weapon_Generic2 (edict_t *ent, int FRAME_ACTIVATE_LAST, int FRAME_FIRE_LAST, int FRAME_IDLE_LAST, int FRAME_DEACTIVATE_LAST, int *pause_frames, int *fire_frames, void (*fire)(edict_t *ent, qboolean altfire))
|
||||
{
|
||||
int n;
|
||||
int current_weapon_index = ITEM_INDEX(ent->client->pers.weapon);
|
||||
|
||||
if (ent->client->weaponstate == WEAPON_DROPPING)
|
||||
{
|
||||
|
@ -575,10 +576,10 @@ void Weapon_Generic2 (edict_t *ent, int FRAME_ACTIVATE_LAST, int FRAME_FIRE_LAST
|
|||
ChangeWeapon (ent);
|
||||
return;
|
||||
}// ### Hentai ### BEGIN
|
||||
else if((FRAME_DEACTIVATE_LAST - ent->client->ps.gunframe) == 4)
|
||||
else if ((FRAME_DEACTIVATE_LAST - ent->client->ps.gunframe) == 4)
|
||||
{
|
||||
ent->client->anim_priority = ANIM_REVERSE;
|
||||
if(ent->client->ps.pmove.pm_flags & PMF_DUCKED)
|
||||
if (ent->client->ps.pmove.pm_flags & PMF_DUCKED)
|
||||
{
|
||||
ent->s.frame = FRAME_crpain4+1;
|
||||
ent->client->anim_end = FRAME_crpain1;
|
||||
|
@ -614,10 +615,10 @@ void Weapon_Generic2 (edict_t *ent, int FRAME_ACTIVATE_LAST, int FRAME_FIRE_LAST
|
|||
ent->client->weaponstate = WEAPON_DROPPING;
|
||||
ent->client->ps.gunframe = FRAME_DEACTIVATE_FIRST;
|
||||
// ### Hentai ### BEGIN
|
||||
if((FRAME_DEACTIVATE_LAST - FRAME_DEACTIVATE_FIRST) < 4)
|
||||
if ((FRAME_DEACTIVATE_LAST - FRAME_DEACTIVATE_FIRST) < 4)
|
||||
{
|
||||
ent->client->anim_priority = ANIM_REVERSE;
|
||||
if(ent->client->ps.pmove.pm_flags & PMF_DUCKED)
|
||||
if (ent->client->ps.pmove.pm_flags & PMF_DUCKED)
|
||||
{
|
||||
ent->s.frame = FRAME_crpain4+1;
|
||||
ent->client->anim_end = FRAME_crpain1;
|
||||
|
@ -636,9 +637,33 @@ void Weapon_Generic2 (edict_t *ent, int FRAME_ACTIVATE_LAST, int FRAME_FIRE_LAST
|
|||
|
||||
if (ent->client->weaponstate == WEAPON_READY)
|
||||
{
|
||||
if ( ((ent->client->latched_buttons|ent->client->buttons) & BUTTON_ATTACK) )
|
||||
|
||||
// Knightmare- catch alt fire commands
|
||||
if ((ent->client->latched_buttons|ent->client->buttons) & BUTTON_ATTACK2)
|
||||
{
|
||||
ent->client->latched_buttons &= ~BUTTON_ATTACK;
|
||||
// Add weapon alt attack handlers here
|
||||
// Examples:
|
||||
/* if (current_weapon_index == rl_index) // homing rocket switch
|
||||
{
|
||||
if (ent->client->pers.inventory[homing_index] > 0)
|
||||
Use_Weapon (ent, FindItem("homing rocket launcher"));
|
||||
ent->client->latched_buttons &= ~BUTTONS_ATTACK;
|
||||
ent->client->buttons &= ~BUTTONS_ATTACK;
|
||||
return;
|
||||
}
|
||||
else if (current_weapon_index == hml_index)
|
||||
{
|
||||
if (ent->client->pers.inventory[rockets_index] > 0)
|
||||
Use_Weapon (ent, FindItem("rocket launcher"));
|
||||
ent->client->latched_buttons &= ~BUTTONS_ATTACK;
|
||||
ent->client->buttons &= ~BUTTONS_ATTACK;
|
||||
return;
|
||||
}*/
|
||||
}
|
||||
|
||||
if ( ((ent->client->latched_buttons|ent->client->buttons) & BUTTONS_ATTACK) )
|
||||
{
|
||||
ent->client->latched_buttons &= ~BUTTONS_ATTACK;
|
||||
if ((!ent->client->ammo_index) ||
|
||||
( ent->client->pers.inventory[ent->client->ammo_index] >= ent->client->pers.weapon->quantity))
|
||||
{
|
||||
|
@ -665,7 +690,7 @@ void Weapon_Generic2 (edict_t *ent, int FRAME_ACTIVATE_LAST, int FRAME_FIRE_LAST
|
|||
gi.sound(ent, CHAN_VOICE, gi.soundindex("weapons/noammo.wav"), 1, ATTN_NORM, 0);
|
||||
ent->pain_debounce_time = level.time + 1;
|
||||
}
|
||||
/*if(ent->client->pers.weapon) gi.bprintf(PRINT_HIGH,"weapon %s %i\n"
|
||||
/*if (ent->client->pers.weapon) gi.bprintf(PRINT_HIGH,"weapon %s %i\n"
|
||||
,ent->client->pers.weapon->pickup_name
|
||||
,ent->client->ammo_index);*/
|
||||
// ,ent->client->pers.inventory[ITEM_INDEX(FindItem(ent->client->pers.weapon->ammo))]
|
||||
|
@ -715,7 +740,7 @@ void Weapon_Generic2 (edict_t *ent, int FRAME_ACTIVATE_LAST, int FRAME_FIRE_LAST
|
|||
//ZOID
|
||||
CTFApplyHasteSound(ent);
|
||||
//ZOID
|
||||
fire (ent);
|
||||
fire (ent, ((ent->client->latched_buttons|ent->client->buttons) & BUTTON_ATTACK2));
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
@ -729,7 +754,7 @@ void Weapon_Generic2 (edict_t *ent, int FRAME_ACTIVATE_LAST, int FRAME_FIRE_LAST
|
|||
}
|
||||
|
||||
//ZOID
|
||||
void Weapon_Generic (edict_t *ent, int FRAME_ACTIVATE_LAST, int FRAME_FIRE_LAST, int FRAME_IDLE_LAST, int FRAME_DEACTIVATE_LAST, int *pause_frames, int *fire_frames, void (*fire)(edict_t *ent))
|
||||
void Weapon_Generic (edict_t *ent, int FRAME_ACTIVATE_LAST, int FRAME_FIRE_LAST, int FRAME_IDLE_LAST, int FRAME_DEACTIVATE_LAST, int *pause_frames, int *fire_frames, void (*fire)(edict_t *ent, qboolean altfire))
|
||||
{
|
||||
int oldstate = ent->client->weaponstate;
|
||||
|
||||
|
@ -810,7 +835,7 @@ void weapon_grenade_fire (edict_t *ent, qboolean held)
|
|||
|
||||
ent->client->grenade_time = level.time + 1.0;
|
||||
|
||||
if(ent->deadflag || ent->s.modelindex != MAX_MODELS-1) // VWep animations screw up corpses
|
||||
if (ent->deadflag || ent->s.modelindex != MAX_MODELS-1) // VWep animations screw up corpses
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
@ -849,9 +874,9 @@ void Weapon_Grenade (edict_t *ent)
|
|||
|
||||
if (ent->client->weaponstate == WEAPON_READY)
|
||||
{
|
||||
if ( ((ent->client->latched_buttons|ent->client->buttons) & BUTTON_ATTACK) )
|
||||
if ( ((ent->client->latched_buttons|ent->client->buttons) & BUTTONS_ATTACK) )
|
||||
{
|
||||
ent->client->latched_buttons &= ~BUTTON_ATTACK;
|
||||
ent->client->latched_buttons &= ~BUTTONS_ATTACK;
|
||||
if (ent->client->pers.inventory[ent->client->ammo_index])
|
||||
{
|
||||
ent->client->ps.gunframe = 1;
|
||||
|
@ -902,7 +927,7 @@ void Weapon_Grenade (edict_t *ent)
|
|||
ent->client->grenade_blew_up = true;
|
||||
}
|
||||
|
||||
if (ent->client->buttons & BUTTON_ATTACK)
|
||||
if (ent->client->buttons & BUTTONS_ATTACK)
|
||||
return;
|
||||
|
||||
if (ent->client->grenade_blew_up)
|
||||
|
@ -946,7 +971,7 @@ GRENADE LAUNCHER
|
|||
======================================================================
|
||||
*/
|
||||
|
||||
void weapon_grenadelauncher_fire (edict_t *ent)
|
||||
void weapon_grenadelauncher_fire (edict_t *ent, qboolean altfire)
|
||||
{
|
||||
vec3_t offset;
|
||||
vec3_t forward, right;
|
||||
|
@ -966,7 +991,7 @@ void weapon_grenadelauncher_fire (edict_t *ent)
|
|||
VectorScale (forward, -2, ent->client->kick_origin);
|
||||
ent->client->kick_angles[0] = -1;
|
||||
|
||||
fire_grenade (ent, start, forward, damage, 600, 2.5, radius);
|
||||
fire_grenade (ent, start, forward, damage, 600, 2.5, radius, altfire);
|
||||
|
||||
gi.WriteByte (svc_muzzleflash);
|
||||
gi.WriteShort (ent-g_edicts);
|
||||
|
@ -1003,7 +1028,7 @@ ROCKET
|
|||
void fire_lockon_rocket (edict_t *self, vec3_t start, vec3_t dir, int damage, int speed, float damage_radius, int radius_damage);
|
||||
|
||||
|
||||
void Weapon_RocketLauncher_Fire (edict_t *ent)
|
||||
void Weapon_RocketLauncher_Fire (edict_t *ent, qboolean altfire)
|
||||
{
|
||||
vec3_t offset, start;
|
||||
vec3_t forward, right;
|
||||
|
@ -1029,7 +1054,7 @@ void Weapon_RocketLauncher_Fire (edict_t *ent)
|
|||
|
||||
VectorSet(offset, 8, 8, ent->viewheight-8);
|
||||
P_ProjectSource (ent->client, ent->s.origin, offset, forward, right, start);
|
||||
if(ent->client->zc.aiming != 4) fire_rocket (ent, start, forward, damage, 650, damage_radius, radius_damage);
|
||||
if (ent->client->zc.aiming != 4) fire_rocket (ent, start, forward, damage, 650, damage_radius, radius_damage);
|
||||
else
|
||||
{
|
||||
damage -= 20;//ロックオンは20ダメージ減り
|
||||
|
@ -1054,20 +1079,20 @@ void Weapon_RocketLauncher_Fire (edict_t *ent)
|
|||
}
|
||||
|
||||
//ロックオンロケットランチャー
|
||||
void Weapon_LockonRocketLauncher_Fire (edict_t *ent)
|
||||
void Weapon_LockonRocketLauncher_Fire (edict_t *ent, qboolean altfire)
|
||||
{
|
||||
vec3_t tmp,out,aim,min,max;
|
||||
vec_t f;
|
||||
trace_t rs_trace;
|
||||
|
||||
if (ent->client->buttons & BUTTON_ATTACK)
|
||||
if (ent->client->buttons & BUTTONS_ATTACK)
|
||||
{
|
||||
ent->client->zc.lockon = false; //スナイパーにロックオン機能なし
|
||||
if(ent->client->zc.aiming == 0)
|
||||
if (ent->client->zc.aiming == 0)
|
||||
{
|
||||
gi.sound (ent, CHAN_WEAPON, gi.soundindex("weapons/sshotr1b.wav"), 1, ATTN_NONE, 0);
|
||||
ent->client->zc.aiming = 3;
|
||||
if(ent->client->zc.distance <10 || ent->client->zc.distance > 90) ent->client->zc.distance = 90;
|
||||
if (ent->client->zc.distance <10 || ent->client->zc.distance > 90) ent->client->zc.distance = 90;
|
||||
ent->client->ps.fov = ent->client->zc.distance;//ズーム開始
|
||||
}
|
||||
|
||||
|
@ -1077,20 +1102,20 @@ void Weapon_LockonRocketLauncher_Fire (edict_t *ent)
|
|||
VectorNormalize(aim);
|
||||
VectorScale (aim, 8193, out);
|
||||
VectorCopy(ent->s.origin,tmp);
|
||||
if(ent->maxs[2] >= 32) tmp[2] += 22;
|
||||
if (ent->maxs[2] >= 32) tmp[2] += 22;
|
||||
else tmp[2] -= 2;
|
||||
VectorAdd(tmp,out,aim);
|
||||
rs_trace = gi.trace (tmp, min, max, aim,ent, MASK_PLAYERSOLID);
|
||||
if(rs_trace.ent != NULL)
|
||||
if (rs_trace.ent != NULL)
|
||||
{
|
||||
if(Q_stricmp (rs_trace.ent->classname, "player") == 0)
|
||||
if (Q_stricmp (rs_trace.ent->classname, "player") == 0)
|
||||
{
|
||||
if(ctf->value)
|
||||
if (ctf->value)
|
||||
{
|
||||
if(ent->client->resp.ctf_team != rs_trace.ent->client->resp.ctf_team)
|
||||
if (ent->client->resp.ctf_team != rs_trace.ent->client->resp.ctf_team)
|
||||
{
|
||||
ent->client->zc.lockon = true;
|
||||
if(ent->client->zc.first_target != rs_trace.ent)
|
||||
if (ent->client->zc.first_target != rs_trace.ent)
|
||||
gi.sound (ent, CHAN_AUTO, gi.soundindex("3zb/locrloc.wav"), 1, ATTN_NORM, 0);
|
||||
ent->client->zc.first_target = rs_trace.ent;
|
||||
}
|
||||
|
@ -1099,7 +1124,7 @@ void Weapon_LockonRocketLauncher_Fire (edict_t *ent)
|
|||
else
|
||||
{
|
||||
ent->client->zc.lockon = true;
|
||||
if(ent->client->zc.first_target != rs_trace.ent)
|
||||
if (ent->client->zc.first_target != rs_trace.ent)
|
||||
gi.sound (ent, CHAN_AUTO, gi.soundindex("3zb/locrloc.wav"), 1, ATTN_NORM, 0);
|
||||
ent->client->zc.first_target = rs_trace.ent;
|
||||
}
|
||||
|
@ -1109,25 +1134,25 @@ void Weapon_LockonRocketLauncher_Fire (edict_t *ent)
|
|||
}
|
||||
else ent->client->zc.first_target = NULL;
|
||||
|
||||
if(ent->client->zc.autozoom )
|
||||
if (ent->client->zc.autozoom )
|
||||
{
|
||||
VectorSubtract(ent->s.origin,rs_trace.endpos,tmp);
|
||||
f = VectorLength(tmp);
|
||||
|
||||
if(f < 200) ent->client->zc.distance = 90;
|
||||
// else if(f < 300) ent->client->zc.distance = 75;
|
||||
// else if(f < 500) ent->client->zc.distance = 60;
|
||||
// else if(f < 800) ent->client->zc.distance = 45;
|
||||
else if(f < 1300)
|
||||
if (f < 200) ent->client->zc.distance = 90;
|
||||
// else if (f < 300) ent->client->zc.distance = 75;
|
||||
// else if (f < 500) ent->client->zc.distance = 60;
|
||||
// else if (f < 800) ent->client->zc.distance = 45;
|
||||
else if (f < 1300)
|
||||
{
|
||||
ent->client->zc.distance = 90 - (f - 200) / 14.6;//30;
|
||||
}
|
||||
else ent->client->zc.distance = 14;
|
||||
|
||||
if(ent->client->ps.fov != ent->client->zc.distance)
|
||||
if (ent->client->ps.fov != ent->client->zc.distance)
|
||||
{
|
||||
f = ent->client->ps.fov - ent->client->zc.distance;
|
||||
if(f > 15 || f < -15 )
|
||||
if (f > 15 || f < -15 )
|
||||
gi.sound (ent, CHAN_AUTO, gi.soundindex("3zb/zoom.wav"), 1, ATTN_NORM, 0);
|
||||
|
||||
ent->client->ps.fov = ent->client->zc.distance;
|
||||
|
@ -1136,7 +1161,7 @@ void Weapon_LockonRocketLauncher_Fire (edict_t *ent)
|
|||
return;
|
||||
}
|
||||
ent->client->zc.aiming = 4;
|
||||
Weapon_RocketLauncher_Fire(ent);
|
||||
Weapon_RocketLauncher_Fire (ent, altfire);
|
||||
}
|
||||
|
||||
|
||||
|
@ -1145,9 +1170,9 @@ void Weapon_RocketLauncher (edict_t *ent)
|
|||
static int pause_frames[] = {25, 33, 42, 50, 0};
|
||||
static int fire_frames[] = {5, 0};
|
||||
|
||||
if(!(ent->client->buttons & BUTTON_ATTACK)) ent->client->zc.aiming = 0; //アクティベート0
|
||||
if (!(ent->client->buttons & BUTTONS_ATTACK)) ent->client->zc.aiming = 0; //アクティベート0
|
||||
|
||||
if(0/*1*/)
|
||||
if (0/*1*/)
|
||||
{
|
||||
Weapon_Generic (ent, 4, 12, 50, 54, pause_frames, fire_frames, Weapon_LockonRocketLauncher_Fire);
|
||||
}
|
||||
|
@ -1183,7 +1208,7 @@ void Blaster_Fire (edict_t *ent, vec3_t g_offset, int damage, qboolean hyper, in
|
|||
AngleVectors (ent->client->v_angle, forward, right, NULL);
|
||||
VectorSet(offset, 24, 8, ent->viewheight-8);
|
||||
|
||||
if(!(ent->svflags & SVF_MONSTER))
|
||||
if (!(ent->svflags & SVF_MONSTER))
|
||||
{
|
||||
VectorAdd (offset, g_offset, offset);
|
||||
P_ProjectSource (ent->client, ent->s.origin, offset, forward, right, start);
|
||||
|
@ -1214,7 +1239,7 @@ void Blaster_Fire (edict_t *ent, vec3_t g_offset, int damage, qboolean hyper, in
|
|||
}
|
||||
|
||||
|
||||
void Weapon_Blaster_Fire (edict_t *ent)
|
||||
void Weapon_Blaster_Fire (edict_t *ent, qboolean altfire)
|
||||
{
|
||||
int damage;
|
||||
|
||||
|
@ -1238,7 +1263,7 @@ void Weapon_Blaster (edict_t *ent)
|
|||
}
|
||||
|
||||
|
||||
void Weapon_HyperBlaster_Fire (edict_t *ent)
|
||||
void Weapon_HyperBlaster_Fire (edict_t *ent, qboolean altfire)
|
||||
{
|
||||
float rotation;
|
||||
vec3_t offset;
|
||||
|
@ -1247,7 +1272,7 @@ void Weapon_HyperBlaster_Fire (edict_t *ent)
|
|||
|
||||
ent->client->weapon_sound = gi.soundindex("weapons/hyprbl1a.wav");
|
||||
|
||||
if (!(ent->client->buttons & BUTTON_ATTACK))
|
||||
if (!(ent->client->buttons & BUTTONS_ATTACK))
|
||||
{
|
||||
ent->client->ps.gunframe++;
|
||||
}
|
||||
|
@ -1332,7 +1357,7 @@ MACHINEGUN / CHAINGUN
|
|||
======================================================================
|
||||
*/
|
||||
|
||||
void Machinegun_Fire (edict_t *ent)
|
||||
void Machinegun_Fire (edict_t *ent, qboolean altfire)
|
||||
{
|
||||
int i;
|
||||
vec3_t start;
|
||||
|
@ -1342,7 +1367,7 @@ void Machinegun_Fire (edict_t *ent)
|
|||
int kick = 2;
|
||||
vec3_t offset;
|
||||
|
||||
if (!(ent->client->buttons & BUTTON_ATTACK))
|
||||
if (!(ent->client->buttons & BUTTONS_ATTACK))
|
||||
{
|
||||
ent->client->machinegun_shots = 0;
|
||||
ent->client->ps.gunframe++;
|
||||
|
@ -1433,7 +1458,7 @@ void Weapon_Machinegun (edict_t *ent)
|
|||
Weapon_Generic (ent, 3, 5, 45, 49, pause_frames, fire_frames, Machinegun_Fire);
|
||||
}
|
||||
|
||||
void Chaingun_Fire (edict_t *ent)
|
||||
void Chaingun_Fire (edict_t *ent, qboolean altfire)
|
||||
{
|
||||
int i;
|
||||
int shots;
|
||||
|
@ -1452,13 +1477,13 @@ void Chaingun_Fire (edict_t *ent)
|
|||
if (ent->client->ps.gunframe == 5)
|
||||
gi.sound(ent, CHAN_AUTO, gi.soundindex("weapons/chngnu1a.wav"), 1, ATTN_IDLE, 0);
|
||||
|
||||
if ((ent->client->ps.gunframe == 14) && !(ent->client->buttons & BUTTON_ATTACK))
|
||||
if ((ent->client->ps.gunframe == 14) && !(ent->client->buttons & BUTTONS_ATTACK))
|
||||
{
|
||||
ent->client->ps.gunframe = 32;
|
||||
ent->client->weapon_sound = 0;
|
||||
return;
|
||||
}
|
||||
else if ((ent->client->ps.gunframe == 21) && (ent->client->buttons & BUTTON_ATTACK)
|
||||
else if ((ent->client->ps.gunframe == 21) && (ent->client->buttons & BUTTONS_ATTACK)
|
||||
&& ent->client->pers.inventory[ent->client->ammo_index])
|
||||
{
|
||||
ent->client->ps.gunframe = 15;
|
||||
|
@ -1482,7 +1507,7 @@ void Chaingun_Fire (edict_t *ent)
|
|||
shots = 1;
|
||||
else if (ent->client->ps.gunframe <= 14)
|
||||
{
|
||||
if (ent->client->buttons & BUTTON_ATTACK)
|
||||
if (ent->client->buttons & BUTTONS_ATTACK)
|
||||
shots = 2;
|
||||
else
|
||||
shots = 1;
|
||||
|
@ -1559,7 +1584,7 @@ void Chaingun_Fire (edict_t *ent)
|
|||
ent->client->pers.inventory[ent->client->ammo_index] -= shots;
|
||||
}
|
||||
|
||||
void Gatringgun_Fire (edict_t *ent)
|
||||
void Gatringgun_Fire (edict_t *ent, qboolean altfire)
|
||||
{
|
||||
int i;
|
||||
int shots;
|
||||
|
@ -1578,13 +1603,13 @@ void Gatringgun_Fire (edict_t *ent)
|
|||
if (ent->client->ps.gunframe == 5)
|
||||
gi.sound(ent, CHAN_AUTO, gi.soundindex("weapons/chngnu1a.wav"), 1, ATTN_IDLE, 0);
|
||||
|
||||
if ((ent->client->ps.gunframe == 14) && !(ent->client->buttons & BUTTON_ATTACK))
|
||||
if ((ent->client->ps.gunframe == 14) && !(ent->client->buttons & BUTTONS_ATTACK))
|
||||
{
|
||||
ent->client->ps.gunframe = 32;
|
||||
ent->client->weapon_sound = 0;
|
||||
return;
|
||||
}
|
||||
else if ((ent->client->ps.gunframe == 21) && (ent->client->buttons & BUTTON_ATTACK)
|
||||
else if ((ent->client->ps.gunframe == 21) && (ent->client->buttons & BUTTONS_ATTACK)
|
||||
&& ent->client->pers.inventory[ent->client->ammo_index])
|
||||
{
|
||||
ent->client->ps.gunframe = 15;
|
||||
|
@ -1608,7 +1633,7 @@ void Gatringgun_Fire (edict_t *ent)
|
|||
shots = 10;//1;
|
||||
else if (ent->client->ps.gunframe <= 14)
|
||||
{
|
||||
if (ent->client->buttons & BUTTON_ATTACK)
|
||||
if (ent->client->buttons & BUTTONS_ATTACK)
|
||||
shots = 10;//2;
|
||||
else
|
||||
shots = 10;//1;
|
||||
|
@ -1658,7 +1683,7 @@ void Gatringgun_Fire (edict_t *ent)
|
|||
fire_bullet (ent, start, forward, damage, kick, DEFAULT_BULLET_HSPREAD, DEFAULT_BULLET_VSPREAD, MOD_CHAINGUN);
|
||||
}
|
||||
|
||||
if(is_silenced) u = 0.5;
|
||||
if (is_silenced) u = 0.5;
|
||||
else u = 1.0;
|
||||
|
||||
gi.sound (ent, CHAN_AUTO, gi.soundindex("3zb/gatgf.wav"), u, ATTN_NORM, 0);
|
||||
|
@ -1697,7 +1722,7 @@ void Weapon_Chaingun (edict_t *ent)
|
|||
static int pause_frames[] = {38, 43, 51, 61, 0};
|
||||
static int fire_frames[] = {5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 0};
|
||||
|
||||
if(0) Weapon_Generic (ent, 4, 31, 61, 64, pause_frames, fire_frames, Gatringgun_Fire);
|
||||
if (0) Weapon_Generic (ent, 4, 31, 61, 64, pause_frames, fire_frames, Gatringgun_Fire);
|
||||
else
|
||||
{
|
||||
Weapon_Generic (ent, 4, 31, 61, 64, pause_frames, fire_frames, Chaingun_Fire);
|
||||
|
@ -1717,7 +1742,7 @@ SHOTGUN / SUPERSHOTGUN
|
|||
======================================================================
|
||||
*/
|
||||
|
||||
void weapon_shotgun_fire (edict_t *ent)
|
||||
void weapon_shotgun_fire (edict_t *ent, qboolean altfire)
|
||||
{
|
||||
vec3_t start;
|
||||
vec3_t forward, right;
|
||||
|
@ -1777,7 +1802,7 @@ void Weapon_Shotgun (edict_t *ent)
|
|||
}
|
||||
|
||||
|
||||
void weapon_supershotgun_fire (edict_t *ent)
|
||||
void weapon_supershotgun_fire (edict_t *ent, qboolean altfire)
|
||||
{
|
||||
vec3_t start;
|
||||
vec3_t forward, right;
|
||||
|
@ -1846,7 +1871,7 @@ RAILGUN
|
|||
*/
|
||||
void fire_sniperail (edict_t *self, vec3_t start, vec3_t aimdir, int damage, int kick);
|
||||
|
||||
void RSight_think(edict_t *ent)
|
||||
void RSight_think (edict_t *ent)
|
||||
{
|
||||
trace_t rs_trace;
|
||||
vec3_t aim,out,tmp;
|
||||
|
@ -1854,7 +1879,7 @@ void RSight_think(edict_t *ent)
|
|||
|
||||
vec_t f;
|
||||
|
||||
if(ent->owner->client->ps.gunframe != 4 || ent->owner->deadflag)
|
||||
if (ent->owner->client->ps.gunframe != 4 || ent->owner->deadflag)
|
||||
{
|
||||
G_FreeEdict(ent);
|
||||
return;
|
||||
|
@ -1865,37 +1890,37 @@ void RSight_think(edict_t *ent)
|
|||
VectorNormalize(aim);
|
||||
VectorScale (aim, 8193, out);
|
||||
VectorCopy(ent->owner->s.origin,tmp);
|
||||
if(ent->owner->maxs[2] >= 32) tmp[2] += 22;
|
||||
if (ent->owner->maxs[2] >= 32) tmp[2] += 22;
|
||||
else tmp[2] -= 2;
|
||||
VectorAdd(tmp,out,aim);
|
||||
rs_trace = gi.trace (tmp, min, max, aim,ent->owner, MASK_PLAYERSOLID);
|
||||
VectorCopy(rs_trace.endpos,ent->s.origin);
|
||||
ent->nextthink = level.time + FRAMETIME;
|
||||
|
||||
if(rs_trace.ent != NULL)
|
||||
if (rs_trace.ent != NULL)
|
||||
{
|
||||
if(Q_stricmp (rs_trace.ent->classname, "player") == 0) return;//オートズーム反応せず
|
||||
if (Q_stricmp (rs_trace.ent->classname, "player") == 0) return;//オートズーム反応せず
|
||||
}
|
||||
|
||||
if(ent->owner->client->zc.autozoom )
|
||||
if (ent->owner->client->zc.autozoom )
|
||||
{
|
||||
VectorSubtract(ent->s.origin,ent->owner->s.origin,tmp);
|
||||
f = VectorLength(tmp);
|
||||
|
||||
if(f < 100) ent->owner->client->zc.distance = 90;
|
||||
// else if(f < 300) ent->owner->client->zc.distance = 75;
|
||||
// else if(f < 500) ent->owner->client->zc.distance = 60;
|
||||
// else if(f < 800) ent->owner->client->zc.distance = 45;
|
||||
else if(f < 1000)
|
||||
if (f < 100) ent->owner->client->zc.distance = 90;
|
||||
// else if (f < 300) ent->owner->client->zc.distance = 75;
|
||||
// else if (f < 500) ent->owner->client->zc.distance = 60;
|
||||
// else if (f < 800) ent->owner->client->zc.distance = 45;
|
||||
else if (f < 1000)
|
||||
{
|
||||
ent->owner->client->zc.distance = 90 - (f - 100) / 12;//30;
|
||||
}
|
||||
else ent->owner->client->zc.distance = 15;
|
||||
|
||||
if(ent->owner->client->ps.fov != ent->owner->client->zc.distance)
|
||||
if (ent->owner->client->ps.fov != ent->owner->client->zc.distance)
|
||||
{
|
||||
f = ent->owner->client->ps.fov - ent->owner->client->zc.distance;
|
||||
if( f > 15 || f < -15)
|
||||
if ( f > 15 || f < -15)
|
||||
gi.sound (ent->owner, CHAN_AUTO, gi.soundindex("3zb/zoom.wav"), 1, ATTN_NORM, 0);
|
||||
|
||||
ent->owner->client->ps.fov = ent->owner->client->zc.distance;
|
||||
|
@ -1904,7 +1929,7 @@ void RSight_think(edict_t *ent)
|
|||
}
|
||||
|
||||
|
||||
void weapon_railgun_fire (edict_t *ent)
|
||||
void weapon_railgun_fire (edict_t *ent, qboolean altfire)
|
||||
{
|
||||
vec3_t start;
|
||||
vec3_t forward, right;
|
||||
|
@ -1940,7 +1965,7 @@ void weapon_railgun_fire (edict_t *ent)
|
|||
|
||||
P_ProjectSource (ent->client, ent->s.origin, offset, forward, right, start);
|
||||
|
||||
if(ent->client->zc.aiming == 0) fire_rail (ent, start, forward, damage, kick);
|
||||
if (ent->client->zc.aiming == 0) fire_rail (ent, start, forward, damage, kick);
|
||||
else
|
||||
{
|
||||
damage += 20;
|
||||
|
@ -1965,14 +1990,14 @@ void weapon_railgun_fire (edict_t *ent)
|
|||
ent->client->zc.aiming = 0; //ズーム不可
|
||||
}
|
||||
//スナイパー用railガン
|
||||
void Weapon_SnipeRailgun (edict_t *ent)
|
||||
void Weapon_SnipeRailgun (edict_t *ent, qboolean altfire)
|
||||
{
|
||||
edict_t *sight;
|
||||
|
||||
if (ent->client->buttons & BUTTON_ATTACK)
|
||||
if (ent->client->buttons & BUTTONS_ATTACK)
|
||||
{
|
||||
ent->client->zc.lockon = false; //スナイパーにロックオン機能なし
|
||||
if( ent->client->zc.aiming == 0)
|
||||
if ( ent->client->zc.aiming == 0)
|
||||
{
|
||||
//サイトの作成
|
||||
sight = G_Spawn();
|
||||
|
@ -1987,7 +2012,7 @@ void Weapon_SnipeRailgun (edict_t *ent)
|
|||
sight->think = RSight_think;
|
||||
sight->nextthink = level.time + FRAMETIME;
|
||||
sight->classname = "rail sight";
|
||||
if( ent->client->resp.ctf_team == CTF_TEAM2 && ctf->value)
|
||||
if ( ent->client->resp.ctf_team == CTF_TEAM2 && ctf->value)
|
||||
{
|
||||
sight->s.frame = 1;
|
||||
}
|
||||
|
@ -1995,15 +2020,15 @@ void Weapon_SnipeRailgun (edict_t *ent)
|
|||
|
||||
gi.sound (ent, CHAN_WEAPON, gi.soundindex("weapons/sshotr1b.wav"), 1, ATTN_NONE, 0);
|
||||
ent->client->zc.aiming = 1;
|
||||
if(ent->client->zc.distance <10 || ent->client->zc.distance > 90) ent->client->zc.distance = 90;
|
||||
if (ent->client->zc.distance <10 || ent->client->zc.distance > 90) ent->client->zc.distance = 90;
|
||||
ent->client->ps.fov = ent->client->zc.distance;//ズーム開始
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
// if (ent->client->buttons & BUTTON_ATTACK) return;
|
||||
// if (ent->client->buttons & BUTTONS_ATTACK) return;
|
||||
ent->client->zc.aiming = 2;
|
||||
weapon_railgun_fire(ent);
|
||||
weapon_railgun_fire (ent, altfire);
|
||||
}
|
||||
|
||||
void Weapon_Railgun (edict_t *ent)
|
||||
|
@ -2011,9 +2036,9 @@ void Weapon_Railgun (edict_t *ent)
|
|||
static int pause_frames[] = {56, 0};
|
||||
static int fire_frames[] = {4, 0};
|
||||
|
||||
if(!(ent->client->buttons & BUTTON_ATTACK)) ent->client->zc.aiming = 0; //アクティベート0
|
||||
if (!(ent->client->buttons & BUTTONS_ATTACK)) ent->client->zc.aiming = 0; //アクティベート0
|
||||
|
||||
if(0)
|
||||
if (0)
|
||||
{
|
||||
Weapon_Generic (ent, 3, 18, 56, 61, pause_frames, fire_frames, Weapon_SnipeRailgun/*weapon_railgun_fire*/);
|
||||
}
|
||||
|
@ -2035,7 +2060,7 @@ BFG10K
|
|||
======================================================================
|
||||
*/
|
||||
|
||||
void weapon_bfg_fire (edict_t *ent)
|
||||
void weapon_bfg_fire (edict_t *ent, qboolean altfire)
|
||||
{
|
||||
vec3_t offset, start;
|
||||
vec3_t forward, right;
|
||||
|
@ -2112,7 +2137,7 @@ void Weapon_BFG (edict_t *ent)
|
|||
RipperGun
|
||||
*/
|
||||
|
||||
void weapon_ionripper_fire (edict_t *ent)
|
||||
void weapon_ionripper_fire (edict_t *ent, qboolean altfire)
|
||||
{
|
||||
vec3_t start;
|
||||
vec3_t forward, right;
|
||||
|
@ -2189,7 +2214,7 @@ void Weapon_Ionripper (edict_t *ent)
|
|||
// Phalanx
|
||||
//
|
||||
|
||||
void weapon_phalanx_fire (edict_t *ent)
|
||||
void weapon_phalanx_fire (edict_t *ent, qboolean altfire)
|
||||
{
|
||||
vec3_t start;
|
||||
vec3_t forward, right, up;
|
||||
|
@ -2329,9 +2354,9 @@ void Weapon_Trap (edict_t *ent)
|
|||
|
||||
if (ent->client->weaponstate == WEAPON_READY)
|
||||
{
|
||||
if ( ((ent->client->latched_buttons|ent->client->buttons) & BUTTON_ATTACK) )
|
||||
if ( ((ent->client->latched_buttons|ent->client->buttons) & BUTTONS_ATTACK) )
|
||||
{
|
||||
ent->client->latched_buttons &= ~BUTTON_ATTACK;
|
||||
ent->client->latched_buttons &= ~BUTTONS_ATTACK;
|
||||
if (ent->client->pers.inventory[ent->client->ammo_index])
|
||||
{
|
||||
ent->client->ps.gunframe = 1;
|
||||
|
@ -2387,7 +2412,7 @@ void Weapon_Trap (edict_t *ent)
|
|||
ent->client->grenade_blew_up = true;
|
||||
}
|
||||
|
||||
if (ent->client->buttons & BUTTON_ATTACK)
|
||||
if (ent->client->buttons & BUTTONS_ATTACK)
|
||||
return;
|
||||
|
||||
if (ent->client->grenade_blew_up)
|
||||
|
|
|
@ -1226,50 +1226,81 @@ void Com_sprintf (char *dest, size_t size, char *fmt, ...)
|
|||
}
|
||||
|
||||
|
||||
void Com_strcpy (char *dest, size_t destSize, const char *src)
|
||||
// Knightmare added
|
||||
size_t Com_strcpy (char *dest, size_t destSize, const char *src)
|
||||
{
|
||||
char *d = dest;
|
||||
const char *s = src;
|
||||
size_t decSize = destSize;
|
||||
|
||||
if (!dest) {
|
||||
Com_Printf ("Com_strcpy: NULL dst\n");
|
||||
return;
|
||||
return 0;
|
||||
}
|
||||
if (!src) {
|
||||
Com_Printf ("Com_strcpy: NULL src\n");
|
||||
return;
|
||||
return 0;
|
||||
}
|
||||
if (destSize < 1) {
|
||||
Com_Printf ("Com_strcpy: dstSize < 1\n");
|
||||
return;
|
||||
return 0;
|
||||
}
|
||||
|
||||
strncpy(dest, src, destSize-1);
|
||||
// strncpy(dest, src, destSize-1);
|
||||
// dest[destSize-1] = 0;
|
||||
|
||||
while (--decSize && *s)
|
||||
*d++ = *s++;
|
||||
*d = 0;
|
||||
dest[destSize-1] = 0;
|
||||
|
||||
if (decSize == 0) // Insufficent room in dst, return count + length of remaining src
|
||||
return (s - src - 1 + strlen(s));
|
||||
else
|
||||
return (s - src - 1); // returned count excludes NULL terminator
|
||||
}
|
||||
|
||||
|
||||
void Com_strcat (char *dest, size_t destSize, const char *src)
|
||||
// Knightmare added
|
||||
size_t Com_strcat (char *dest, size_t destSize, const char *src)
|
||||
{
|
||||
char *d = dest;
|
||||
const char *s = src;
|
||||
size_t decSize = destSize;
|
||||
size_t dLen;
|
||||
|
||||
if (!dest) {
|
||||
Com_Printf ("Com_strcat: NULL dst\n");
|
||||
return;
|
||||
return 0;
|
||||
}
|
||||
if (!src) {
|
||||
Com_Printf ("Com_strcat: NULL src\n");
|
||||
return;
|
||||
return 0;
|
||||
}
|
||||
if (destSize < 1) {
|
||||
Com_Printf ("Com_strcat: dstSize < 1\n");
|
||||
return;
|
||||
return 0;
|
||||
}
|
||||
|
||||
while (--destSize && *dest)
|
||||
/* while (--destSize && *dest)
|
||||
dest++;
|
||||
|
||||
if (destSize > 0) {
|
||||
if (destSize > 0){
|
||||
while (--destSize && *src)
|
||||
*dest++ = *src++;
|
||||
|
||||
*dest = 0;
|
||||
}*/
|
||||
|
||||
while (--decSize && *d)
|
||||
d++;
|
||||
dLen = d - dest;
|
||||
|
||||
if (decSize == 0)
|
||||
return (dLen + strlen(s));
|
||||
|
||||
if (decSize > 0) {
|
||||
while (--decSize && *s)
|
||||
*d++ = *s++;
|
||||
|
||||
*d = 0;
|
||||
}
|
||||
dest[destSize-1] = 0;
|
||||
|
||||
return (dLen + (s - src)); // returned count excludes NULL terminator
|
||||
}
|
||||
|
||||
/*
|
||||
|
|
|
@ -107,9 +107,25 @@ typedef enum {false, true} qboolean;
|
|||
#define OLD_MAX_IMAGES 256
|
||||
// end Knightmare
|
||||
|
||||
// Knightmare- hacked offsets for old demos
|
||||
#define OLD_MAX_MODELS 256
|
||||
#define OLD_MAX_SOUNDS 256
|
||||
#define OLD_MAX_IMAGES 256
|
||||
// end Knightmare
|
||||
|
||||
#define MAX_ITEMS 256
|
||||
#define MAX_GENERAL (MAX_CLIENTS*2) // general config strings
|
||||
|
||||
// Knightmare- world size
|
||||
#ifdef KMQUAKE2_ENGINE_MOD
|
||||
#define MAX_WORLD_COORD (16384)
|
||||
#define MIN_WORLD_COORD (-16384)
|
||||
#else
|
||||
#define MAX_WORLD_COORD (4096)
|
||||
#define MIN_WORLD_COORD (-4096)
|
||||
#endif
|
||||
#define WORLD_SIZE (MAX_WORLD_COORD - MIN_WORLD_COORD)
|
||||
// end Knightmare
|
||||
|
||||
// game print flags
|
||||
#define PRINT_LOW 0 // pickup messages
|
||||
|
@ -245,8 +261,9 @@ char *COM_Parse (char **data_p);
|
|||
// data is an in/out parm, returns a parsed out token
|
||||
|
||||
void Com_sprintf (char *dest, size_t size, char *fmt, ...);
|
||||
void Com_strcpy (char *dest, size_t destSize, const char *src);
|
||||
void Com_strcat (char *dest, size_t destSize, const char *src);
|
||||
// Knightmare added
|
||||
size_t Com_strcpy (char *dest, size_t destSize, const char *src);
|
||||
size_t Com_strcat (char *dest, size_t destSize, const char *src);
|
||||
|
||||
void Com_PageInMemory (byte *buffer, int size);
|
||||
|
||||
|
@ -572,6 +589,8 @@ typedef struct
|
|||
//
|
||||
#define BUTTON_ATTACK 1
|
||||
#define BUTTON_USE 2
|
||||
#define BUTTON_ATTACK2 4
|
||||
#define BUTTONS_ATTACK (BUTTON_ATTACK | BUTTON_ATTACK2)
|
||||
#define BUTTON_ANY 128 // any key whatsoever
|
||||
|
||||
|
||||
|
|
|
@ -1,5 +1,6 @@
|
|||
This is the source code to the 3ZB2 support DLL for KMQuake2 .
|
||||
It also supports the model_train, model_spawn, and rotating func_train entities from the Lazarus mod.
|
||||
This is the source code to the 3ZB2 support DLL for KMQuake2.
|
||||
It supports the model_train, model_spawn, and rotating func_train entities from the Lazarus mod,
|
||||
and also the func_plat2 and func_door_secret2 entities from the Ground Zero mission pack.
|
||||
|
||||
Note this source code is under the original "Limited Program Source Code License" from id Software,
|
||||
NOT the GPL. It should not be mixed with GPLed code.
|
||||
|
|
24
awaken2/Readme_source.txt
Normal file
24
awaken2/Readme_source.txt
Normal file
|
@ -0,0 +1,24 @@
|
|||
==========================================
|
||||
AWAKENING II: The Resurrection
|
||||
v2.05
|
||||
28-April-2007
|
||||
==========================================
|
||||
Site : http://awakening2.planetquake.gamespy.com/
|
||||
IRC : irc://irc.accessirc.net/awaken2
|
||||
|
||||
------------------------------------------
|
||||
Author : Chris "Musashi" Walker
|
||||
E-mail : musashi@planetquake.com
|
||||
Site : http://musashi.planetquake.gamespy.com/
|
||||
|
||||
|
||||
|
||||
===============================
|
||||
NOTES
|
||||
===============================
|
||||
|
||||
The original baseline for the mod was the CTF v1.50 source code (from way back in 1998). It's had a lot ripped out, and a lot more added - not just from me, but from several other authors as well who have kindly allowed their code to be used in this project.
|
||||
|
||||
Feel free to make use of the code as you like. All I ask is that you give credit where it is due if you use any of the code in your own applications or mods.
|
||||
|
||||
This source code is provided as-is with no warranties of any kind. If it causes something unspeakably evil to happen, you're on your own ;)
|
41
awaken2/action list.txt
Normal file
41
awaken2/action list.txt
Normal file
|
@ -0,0 +1,41 @@
|
|||
-------------------------------------
|
||||
BUGS:
|
||||
-------------------------------------
|
||||
|
||||
|
||||
-------------------------------------
|
||||
TO DO - GENERAL:
|
||||
-------------------------------------
|
||||
|
||||
|
||||
-------------------------------------
|
||||
TO DO - BOTS:
|
||||
-------------------------------------
|
||||
- CTF capability (check G_CTF refs).
|
||||
- Use secondary mode of Gauss Pistol.
|
||||
- Use Traps properly (eg. lay around power-items if no one around).
|
||||
- Rocket-jumping ability.
|
||||
- Shoot/avoid enemy C4 as well as traps, if touchbang or proximity set.
|
||||
|
||||
-------------------------------------
|
||||
POTENTIAL CHANGES - GENERAL:
|
||||
-------------------------------------
|
||||
- Partial invisibility powerup -> Mystery Box.
|
||||
- Jetpack powerup.
|
||||
- New RL mode: nosecam (controllable rockets).
|
||||
- Player stats for weapons (eg. accuracy, usage, etc).
|
||||
- Location markers for maps.
|
||||
- Top scores list for each map.
|
||||
- Min/max player numbers in map file.
|
||||
- Dynamically reduce 'max_traps_active' as player numbers increase.
|
||||
- Banning list should be rechecked after server restart.
|
||||
- Ability to go back to previous map in vote selection list.
|
||||
|
||||
-------------------------------------
|
||||
POTENTIAL CHANGES - BOTS:
|
||||
-------------------------------------
|
||||
- Chasecam can be used on bots.
|
||||
- Bots visible as clients in server info.
|
||||
- If there are no players present in a game, spawn 'n' bots after 't' seconds (use cvars).
|
||||
- Better camping algorithm.
|
||||
- Better bot insults.
|
26
awaken2/awakening2_2008.sln
Normal file
26
awaken2/awakening2_2008.sln
Normal file
|
@ -0,0 +1,26 @@
|
|||
|
||||
Microsoft Visual Studio Solution File, Format Version 10.00
|
||||
# Visual Studio 2008
|
||||
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "Awakening2", "awakening2_2008.vcproj", "{23875C27-60F4-4F16-B581-A32474963147}"
|
||||
EndProject
|
||||
Global
|
||||
GlobalSection(SolutionConfigurationPlatforms) = preSolution
|
||||
Debug|Win32 = Debug|Win32
|
||||
Debug|x64 = Debug|x64
|
||||
Release|Win32 = Release|Win32
|
||||
Release|x64 = Release|x64
|
||||
EndGlobalSection
|
||||
GlobalSection(ProjectConfigurationPlatforms) = postSolution
|
||||
{23875C27-60F4-4F16-B581-A32474963147}.Debug|Win32.ActiveCfg = Debug|Win32
|
||||
{23875C27-60F4-4F16-B581-A32474963147}.Debug|Win32.Build.0 = Debug|Win32
|
||||
{23875C27-60F4-4F16-B581-A32474963147}.Debug|x64.ActiveCfg = Debug|x64
|
||||
{23875C27-60F4-4F16-B581-A32474963147}.Debug|x64.Build.0 = Debug|x64
|
||||
{23875C27-60F4-4F16-B581-A32474963147}.Release|Win32.ActiveCfg = Release|Win32
|
||||
{23875C27-60F4-4F16-B581-A32474963147}.Release|Win32.Build.0 = Release|Win32
|
||||
{23875C27-60F4-4F16-B581-A32474963147}.Release|x64.ActiveCfg = Release|x64
|
||||
{23875C27-60F4-4F16-B581-A32474963147}.Release|x64.Build.0 = Release|x64
|
||||
EndGlobalSection
|
||||
GlobalSection(SolutionProperties) = preSolution
|
||||
HideSolutionNode = FALSE
|
||||
EndGlobalSection
|
||||
EndGlobal
|
1250
awaken2/awakening2_2008.vcproj
Normal file
1250
awaken2/awakening2_2008.vcproj
Normal file
File diff suppressed because it is too large
Load diff
7131
awaken2/g_bot.c
Normal file
7131
awaken2/g_bot.c
Normal file
File diff suppressed because it is too large
Load diff
281
awaken2/g_bot.h
Normal file
281
awaken2/g_bot.h
Normal file
|
@ -0,0 +1,281 @@
|
|||
// g_bot.h
|
||||
|
||||
//Maj/Pon++
|
||||
#define MAXNODES 10000
|
||||
#define MAXLINKPOD 6 // don't modify this
|
||||
#define MAXBOTS 51 // number of name/skin entries
|
||||
|
||||
//skill[]
|
||||
#define AIMACCURACY 0 // 0..9
|
||||
#define AGGRESSION 1 // 0..9
|
||||
#define COMBATSKILL 2 // 0..9
|
||||
#define VRANGEVIEW 3 // 60..120 deg - Vertical view range
|
||||
#define HRANGEVIEW 4 // 60..120 deg - Horizontal view range
|
||||
#define PRIMARYWEAP 5 // 2..14 - 2 = Desert Eagle, 14 = AGM
|
||||
|
||||
typedef struct
|
||||
{
|
||||
vec3_t Pt;
|
||||
union
|
||||
{
|
||||
vec3_t Tcorner; // target corner (train and grapple-shot only)
|
||||
unsigned short linkpod[MAXLINKPOD]; // (GRS_NORMAL, GRS_ITEMS only 0 = do not select pod)
|
||||
} podunion; //CW
|
||||
edict_t *ent; // target ent
|
||||
short index; // index num
|
||||
short state; // targetstate
|
||||
} route_t;
|
||||
|
||||
//CW++
|
||||
// Avoid nameless unions for Linux compiler.
|
||||
|
||||
#define Tcorner podunion.Tcorner
|
||||
#define linkpod podunion.linkpod
|
||||
//CW--
|
||||
|
||||
extern route_t Route[MAXNODES]; // list of bot route nodes (from chn file)
|
||||
extern int TotalRouteNodes; // number of used nodes in the 'Route[]' array
|
||||
extern int CurrentIndex; // current node number that bot is at
|
||||
extern float JumpMax; // max delta-height that bot can jump to //Pon
|
||||
|
||||
|
||||
typedef struct
|
||||
{
|
||||
char netname[MAX_NAMELEN]; // netname //CW was 21
|
||||
char skin[MAX_SKINLEN]; // skin //CW
|
||||
int ingame; // spawned
|
||||
int skill[6]; // parameters
|
||||
qboolean camper; // TRUE => bot will camp certain items //CW++
|
||||
} botinfo_t;
|
||||
|
||||
extern botinfo_t Bot[MAXBOTS+1];
|
||||
|
||||
|
||||
void gi_cprintf(edict_t *ent, int printlevel, char *fmt, ...);
|
||||
void gi_centerprintf(edict_t *ent, char *fmt, ...);
|
||||
void gi_bprintf(int printlevel, char *fmt, ...);
|
||||
|
||||
void Use_Plat(edict_t *ent, edict_t *other, edict_t *activator);
|
||||
void train_use(edict_t *self, edict_t *other, edict_t *activator);
|
||||
void button_use(edict_t *self, edict_t *other, edict_t *activator);
|
||||
void door_use(edict_t *self, edict_t *other, edict_t *activator);
|
||||
void rotating_use(edict_t *self, edict_t *other, edict_t *activator);
|
||||
void trigger_relay_use(edict_t *self, edict_t *other, edict_t *activator);
|
||||
void plat_go_up(edict_t *ent);
|
||||
void SV_Physics_Step(edict_t *ent);
|
||||
void path_corner_touch(edict_t *self, edict_t *other, cplane_t *plane, csurface_t *surf);
|
||||
void DoRespawn(edict_t *ent);
|
||||
void Cmd_Kill_f(edict_t *ent);
|
||||
void ClientUserinfoChanged(edict_t *ent, char *userinfo);
|
||||
void ClientDisconnect(edict_t *ent);
|
||||
void Use_Item(edict_t *ent, edict_t *other, edict_t *activator);
|
||||
|
||||
// weapon functions
|
||||
int WeapIndex(int weap);
|
||||
void Weapon_DesertEagle(edict_t *self); //CW
|
||||
void Weapon_GaussPistol(edict_t *self);
|
||||
void Weapon_Jackhammer(edict_t *self);
|
||||
void Weapon_Mac10(edict_t *self);
|
||||
void Weapon_ESG(edict_t *self);
|
||||
void Weapon_Flamethrower(edict_t *self);
|
||||
void Weapon_RocketLauncher (edict_t *self);
|
||||
void Weapon_C4(edict_t *self);
|
||||
void Weapon_Trap(edict_t *self);
|
||||
void Weapon_Railgun (edict_t *self);
|
||||
void Weapon_ShockRifle(edict_t *self);
|
||||
void Weapon_AGM(edict_t *self);
|
||||
void Weapon_DiscLauncher(edict_t *self);
|
||||
void Weapon_Chainsaw(edict_t *self);
|
||||
|
||||
|
||||
void LoadBots(void); //CW
|
||||
int GetKindWeapon(gitem_t *it);
|
||||
void ReadRouteFile(void);
|
||||
void droptofloor2(edict_t *ent);
|
||||
void RespawnAllBots(void);
|
||||
void TauntVictim(edict_t *ent, edict_t *victim);
|
||||
void InsultVictim(edict_t *ent, edict_t *victim);
|
||||
qboolean Pickup_Navi(edict_t *ent, edict_t *other);
|
||||
void Bot_Think(edict_t *ent);
|
||||
void CheckCampSite(edict_t *ent,edict_t *other);
|
||||
void bFuncPlat(edict_t *ent);
|
||||
void bFuncButton(edict_t *ent);
|
||||
void bDoorBlocked(edict_t *ent);
|
||||
void bFuncDoor(edict_t *ent);
|
||||
void bFuncTrain(edict_t *ent);
|
||||
void ResetGroundSlope(edict_t *ent);
|
||||
void TraceAllSolid(edict_t *ent, vec3_t point, trace_t tr);
|
||||
void CheckPrimaryWeapon(edict_t *ent, edict_t *other);
|
||||
void G_FindTrainTeam(void);
|
||||
void ForceRouteReset(edict_t *other);
|
||||
void InitAllItems(void);
|
||||
float SetBotXYSpeed(edict_t *ent, float *xyspeed);
|
||||
void SetBotThink(edict_t *ent);
|
||||
void CheckBotCrushed(edict_t *targ,edict_t *inflictor,int mod);
|
||||
void Bot_CheckEnemy(gclient_t *client, edict_t *attacker, edict_t *targ, int mod);
|
||||
void BotCheckGrapple(edict_t *ent);
|
||||
|
||||
//CW++
|
||||
qboolean TraceX(edict_t *ent, vec3_t p2);
|
||||
float Get_yaw(vec3_t vec);
|
||||
float Get_vec_yaw(vec3_t vec, float yaw);
|
||||
qboolean RemoveBot(edict_t *ent);
|
||||
void SpawnNumBots_Safe(int numbots);
|
||||
void RemoveNumBots_Safe(int numbots);
|
||||
void Move_LastRouteIndex(void);
|
||||
void Get_WaterState(edict_t *ent);
|
||||
void Get_RouteOrigin(int index, vec3_t pos);
|
||||
|
||||
|
||||
// behaviour variables/factors
|
||||
#define BOT_FALLCHK_LOOPMAX 30
|
||||
#define BOT_MAX_TAUNT_DIST 250
|
||||
#define BOT_CAMP_PROB 0.5
|
||||
|
||||
#define BOT_TELE_MINHEALTH 20 // bot teleports if health falls below this during a fight...
|
||||
#define BOT_TELE_ENEMYRANGE 480 // ...and enemy is within this range
|
||||
#define BOT_TELE_FALLSPEED -400 // bot teleports if vertical velocity exceeds this towards an enviro hazard
|
||||
|
||||
#define BOT_CHICKENAIM_FACTOR 0.7 // aiming modification for chicken-shooting
|
||||
|
||||
#define BOT_DODGE_ENEMYRANGE 300 // range within which bot will try to dodge enemy shots
|
||||
#define BOT_RUSH_ENEMYRANGE 400 // range within which bot will try to rush an enemy
|
||||
|
||||
#define BOT_PNOISE_SELF_DIST 700 // range within which bot will hear a personal noise (eg. jumping, pain, weapon firing)
|
||||
#define BOT_PNOISE_IMPACT_DIST 300 // range within which bot will hear a weapon target noise (eg. bullet wall impacts)
|
||||
#define BOT_PNOISE_RADIUS 300 // enemy's sound projected forward this much when testing for hidden sounds
|
||||
//CW--
|
||||
|
||||
// moving speed ----------------------------------------------------
|
||||
#define MOVE_SPD_DUCK 16
|
||||
#define MOVE_SPD_WATER 16
|
||||
#define MOVE_SPD_WALK 20
|
||||
#define MOVE_SPD_RUN 30
|
||||
#define MOVE_SPD_JUMP 30
|
||||
|
||||
#define VEL_BOT_JUMP 340 // jump velocity
|
||||
#define VEL_BOT_WJUMP 340 // waterjump velocity
|
||||
#define VEL_BOT_JUMP_NUDGE 20 // nudge-jump velocity
|
||||
#define VEL_BOT_LADDERUP 200 // ladder-up velocity
|
||||
#define VEL_BOT_WLADDERUP 200 // water ladder-up gain
|
||||
#define VEL_BOT_ROCJUMP 500 // rocketjump velocity
|
||||
|
||||
// function's state P ----------------------------------------------
|
||||
#define PSTATE_TOP 0
|
||||
#define PSTATE_BOTTOM 1
|
||||
#define PSTATE_UP 2
|
||||
#define PSTATE_DOWN 3
|
||||
|
||||
#define PDOOR_TOGGLE 32
|
||||
|
||||
// height ----------------------------------------------------------
|
||||
#define TOP_LIMIT 52
|
||||
#define TOP_LIMIT_WATER 100
|
||||
#define BOTTOM_LIMIT -52
|
||||
#define BOTTOM_LIMIT_WATER -8190
|
||||
#define BOTTOM_LIMITM -300
|
||||
|
||||
// waterstate ------------------------------------------------------
|
||||
#define WAS_NONE 0
|
||||
#define WAS_FLOAT 1
|
||||
#define WAS_IN 2
|
||||
|
||||
// route chaining pod state ----------------------------------------
|
||||
#define GRS_NORMAL 0
|
||||
#define GRS_ONROTATE 1
|
||||
#define GRS_TELEPORT 2
|
||||
#define GRS_ITEMS 3
|
||||
#define GRS_ONPLAT 4
|
||||
#define GRS_ONTRAIN 5
|
||||
#define GRS_ONDOOR 6
|
||||
#define GRS_PUSHBUTTON 7
|
||||
|
||||
#define GRS_GRAPSHOT 20
|
||||
#define GRS_GRAPHOOK 21
|
||||
#define GRS_GRAPRELEASE 22
|
||||
|
||||
#define GRS_REDFLAG -10
|
||||
#define GRS_BLUEFLAG -11
|
||||
|
||||
#define POD_LOCKFRAME 15
|
||||
#define POD_RELEFRAME 20
|
||||
|
||||
#define MAX_SEARCH 12 // max search count / FRAMETIME
|
||||
#define MAX_DOORSEARCH 10
|
||||
|
||||
// trace params ----------------------------------------------------
|
||||
#define TRP_NOT 0 // don't trace
|
||||
#define TRP_NORMAL 1 // trace normal
|
||||
#define TRP_ANGLEKEEP 2 // trace and keep angle
|
||||
#define TRP_MOVEKEEP 3 // angle and move vec keep but move
|
||||
#define TRP_ALLKEEP 4 // don't move
|
||||
|
||||
// combat: aiming --------------------------------------------------
|
||||
#define AIM_SFPOS 5.0 // aiming position offset scale-factor
|
||||
#define AIM_SFANG_HITSCAN 0.75 // aimimg angle scale-factor: hitscan weapons
|
||||
#define AIM_SFANG_PROJ 0.35 // aimimg angle scale-factor: projectile weapons
|
||||
|
||||
// movestate (general status list) ---------------------------------
|
||||
#define STS_IDLE 0x00000000 // normal running
|
||||
#define STS_LADDERUP 0x00000001 // climb the ladder
|
||||
#define STS_TURBOJ 0x00000002 // turbo jump
|
||||
#define STS_WATERJ 0x00000004 // water jump
|
||||
#define STS_ROCJ 0x00000008 // rocket jumping
|
||||
#define STS_TRIGPUSH 0x00001000 // hit a trigger_push //CW++
|
||||
#define STS_AGMMOVE 0x00002000 // movement due to enemy AGM //CW++
|
||||
|
||||
#define STS_SJMASK (STS_ROCJ | STS_TURBOJ | STS_TRIGPUSH | STS_AGMMOVE | STS_WATERJ) //CW
|
||||
#define STS_SJMASKEXW (STS_ROCJ | STS_TURBOJ | STS_TRIGPUSH | STS_AGMMOVE) //CW
|
||||
|
||||
// wait
|
||||
#define STS_W_DONT 0x00000010 // don't wait for door/plat/train
|
||||
#define STS_W_DOOROPEN 0x00000020 // wait for door open or down to bottom
|
||||
#define STS_W_ONPLAT 0x00000040 // wait for plat or door reach to the top
|
||||
#define STS_W_ONDOORUP 0x00000080 // wait for door reach to the top
|
||||
#define STS_W_ONDOORDWN 0x00000100 // wait for door reach to the bottom
|
||||
#define STS_W_ONTRAIN 0x00000200 // wait for door/plat/train reach to the top
|
||||
#define STS_W_COMEPLAT 0x00000400 // wait for plat to come
|
||||
#define STS_W_COMETRAIN 0x00000800 // wait for train to come
|
||||
|
||||
#define STS_WAITS (STS_W_DONT | STS_W_DOOROPEN | STS_W_ONPLAT | STS_W_ONDOORUP | STS_W_ONDOORDWN | STS_W_ONTRAIN | STS_W_COMEPLAT | STS_W_COMETRAIN) //CW
|
||||
#define STS_WAITSMASK (STS_W_DOOROPEN | STS_W_ONPLAT | STS_W_ONDOORUP | STS_W_ONDOORDWN | STS_W_ONTRAIN | STS_W_COMEPLAT)
|
||||
#define STS_WAITSMASK2 (STS_W_ONDOORUP | STS_W_ONDOORDWN | STS_W_ONPLAT | STS_W_ONTRAIN)
|
||||
#define STS_WAITSMASKCOM (STS_W_DOOROPEN | STS_W_ONPLAT | STS_W_ONDOORUP | STS_W_ONDOORDWN | STS_W_ONTRAIN)
|
||||
|
||||
// battlemode (& bot skills)----------------------------------------
|
||||
#define FIRE_NULL 0x00000000 // mode: none //CW++
|
||||
#define FIRE_SLIDEMODE 0x00000001 // mode: slide with route
|
||||
#define FIRE_PRESTAYFIRE 0x00000002 // mode/skill: stand still and fires (pre)
|
||||
#define FIRE_STAYFIRE 0x00000004 // mode/skill: stand still and fires
|
||||
#define FIRE_CHICKEN 0x00000008 // mode: chicken-shooting
|
||||
#define FIRE_RUSH 0x00000010 // mode: rush attack
|
||||
#define FIRE_ESTIMATE 0x00000020 // mode: fire in estimated enemy direction
|
||||
#define FIRE_C4 0x00000040 // mode: using C4 //CW++
|
||||
|
||||
#define FIRE_JUMPROC 0x00000100 // skill: jump whilst firing rockets
|
||||
#define FIRE_REFUGE 0x00000200 // mode/skill: retreat (back along route) whilst firing
|
||||
#define FIRE_QUADUSE 0x00000400 // skill: select good weapons when Quadded
|
||||
#define FIRE_C4USE 0x00000800 // skill: use C4 more competently //CW++
|
||||
#define FIRE_AVOIDEXPLO 0x00001000 // mode/skill: try to avoid own RL & SR explosions
|
||||
#define FIRE_AVOIDINVULN 0x00002000 // skill: avoid Invulnerable players
|
||||
#define FIRE_DODGE 0x00004000 // mode/skill: dodge when being aimed at //CW++
|
||||
#define FIRE_IGNORE 0x00008000 // mode/skill: ignore distant enemies
|
||||
|
||||
#define FIRE_SHIFT_R 0x10000000 // mode: strafe right
|
||||
#define FIRE_SHIFT_L 0x20000000 // mode: strafe left
|
||||
#define FIRE_SHIFT (FIRE_SHIFT_R | FIRE_SHIFT_L)
|
||||
|
||||
// combatstate ----------------------------------------------------
|
||||
#define CTS_ENEM_NSEE 0x00000001 // have enemy but can't see
|
||||
#define CTS_AGRBATTLE 0x00000002 // aggressive battle
|
||||
#define CTS_ESCBATTLE 0x00000004 // escaping battle (item want)
|
||||
#define CTS_HIPBATTLE 0x00000008 // high position battle (camp)
|
||||
|
||||
// combatstate: shooting
|
||||
#define CTS_PREAIMING 0x00000010 // prepare for snipe or lockon
|
||||
#define CTS_AIMING 0x00000020 // aimning for snipe or lockon
|
||||
#define CTS_GRENADE 0x00000040 // hand grenade mode
|
||||
#define CTS_JUMPSHOT 0x00000080 // jump shot
|
||||
|
||||
#define CTS_COMBS (CTS_AGRBATTLE | CTS_ESCBATTLE | CTS_HIPBATTLE | CTS_ENEM_NSEE)
|
||||
//Maj/Pon--
|
504
awaken2/g_camera.c
Normal file
504
awaken2/g_camera.c
Normal file
|
@ -0,0 +1,504 @@
|
|||
// g_camera.c
|
||||
|
||||
//CW: This camera code is taken from the Lazarus mod source (version 2.1),
|
||||
// which David Hyde released on 22-Sep-2001 for public use.
|
||||
// See 'http://planetquake.com/lazarus' for more information.
|
||||
|
||||
#include "g_local.h"
|
||||
|
||||
void camera_off(edict_t *ent)
|
||||
{
|
||||
int i;
|
||||
|
||||
//CW++
|
||||
edict_t *t_ent;
|
||||
//CW--
|
||||
|
||||
if (!ent->client)
|
||||
return;
|
||||
|
||||
if (!ent->client->spycam)
|
||||
return;
|
||||
|
||||
if (ent->client->spycam->viewer == ent)
|
||||
ent->client->spycam->viewer = NULL;
|
||||
|
||||
if (ent->client->spycam->svflags & SVF_MONSTER)
|
||||
ent->client->spycam->svflags &= ~SVF_NOCLIENT;
|
||||
|
||||
//CW++
|
||||
ent->client->frozen_framenum = ent->client->camplayer->client->frozen_framenum;
|
||||
|
||||
// If the fake entity is on fire, transfer the flame back to the player.
|
||||
|
||||
if (ent->client->camplayer->burning)
|
||||
{
|
||||
ent->burning = true;
|
||||
ent->flame = ent->client->camplayer->flame;
|
||||
ent->flame->enemy = ent;
|
||||
|
||||
ent->client->camplayer->flame = NULL;
|
||||
ent->client->camplayer->burning = false;
|
||||
}
|
||||
|
||||
// If the fake entity has been caught by a Trap, transfer the tractor beam to the player.
|
||||
|
||||
if (ent->client->camplayer->tractored)
|
||||
{
|
||||
ent->tractored = true;
|
||||
ent->client->camplayer->tractored = false;
|
||||
|
||||
for (i = 0; i < globals.num_edicts; ++i)
|
||||
{
|
||||
t_ent = &g_edicts[i];
|
||||
if ((t_ent->die == Trap_DieFromDamage) && (t_ent->enemy == ent->client->camplayer))
|
||||
{
|
||||
if (!t_ent->inuse)
|
||||
continue;
|
||||
|
||||
t_ent->enemy = ent;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
VectorCopy(ent->client->camplayer->s.origin, ent->s.old_origin);
|
||||
//CW--
|
||||
|
||||
VectorCopy(ent->client->camplayer->s.origin, ent->s.origin);
|
||||
gi.TagFree(ent->client->camplayer->client);
|
||||
G_FreeEdict(ent->client->camplayer);
|
||||
|
||||
// set angles
|
||||
ent->movetype = MOVETYPE_WALK;
|
||||
ent->client->ps.pmove.pm_type = PM_NORMAL;
|
||||
for (i = 0; i < 3; i++)
|
||||
ent->client->ps.pmove.delta_angles[i] = ANGLE2SHORT(ent->client->org_viewangles[i] - ent->client->resp.cmd_angles[i]);
|
||||
|
||||
VectorCopy(ent->client->org_viewangles, ent->client->resp.cmd_angles);
|
||||
VectorCopy(ent->client->org_viewangles, ent->s.angles);
|
||||
VectorCopy(ent->client->org_viewangles, ent->client->ps.viewangles);
|
||||
VectorCopy(ent->client->org_viewangles, ent->client->v_angle);
|
||||
|
||||
ent->client->ps.gunindex = gi.modelindex(ent->client->pers.weapon->view_model);
|
||||
ent->client->ps.pmove.pm_flags &= ~PMF_NO_PREDICTION;
|
||||
ent->svflags &= ~SVF_NOCLIENT;
|
||||
ent->clipmask = MASK_PLAYERSOLID;
|
||||
ent->solid = SOLID_BBOX;
|
||||
ent->client->camplayer = NULL;
|
||||
ent->client->spycam = NULL;
|
||||
gi.linkentity(ent);
|
||||
}
|
||||
|
||||
void faker_animate(edict_t *self)
|
||||
{
|
||||
if ((self->s.frame < 0) || (self->s.frame > 39))
|
||||
self->s.frame = 0;
|
||||
else
|
||||
{
|
||||
self->s.frame++;
|
||||
if (self->s.frame > 39)
|
||||
self->s.frame = 0;
|
||||
}
|
||||
self->nextthink = level.time + FRAMETIME;
|
||||
gi.linkentity(self);
|
||||
}
|
||||
|
||||
void camera_on(edict_t *ent)
|
||||
{
|
||||
gclient_t *cl;
|
||||
edict_t *faker;
|
||||
edict_t *camera;
|
||||
vec3_t forward;
|
||||
vec3_t left;
|
||||
vec3_t up;
|
||||
|
||||
if (!ent->client)
|
||||
return;
|
||||
|
||||
if (!ent->client->spycam)
|
||||
return;
|
||||
|
||||
// "viewer" can control camera aim (2nd player to come along and use camera cannot)
|
||||
camera = ent->client->spycam;
|
||||
|
||||
if (!camera->viewer)
|
||||
camera->viewer = ent;
|
||||
|
||||
// save current viewangles and restore them with camera_off
|
||||
VectorCopy(ent->client->v_angle, ent->client->org_viewangles);
|
||||
|
||||
// copy over all important player data to fake player
|
||||
ent->client->camplayer = G_Spawn();
|
||||
faker = ent->client->camplayer;
|
||||
faker->s.frame = ent->s.frame;
|
||||
VectorCopy(ent->s.origin, faker->s.origin);
|
||||
VectorCopy(ent->velocity, faker->velocity);
|
||||
VectorCopy(ent->s.angles, faker->s.angles);
|
||||
faker->s = ent->s;
|
||||
faker->takedamage = DAMAGE_AIM;
|
||||
faker->movetype = MOVETYPE_WALK;
|
||||
faker->groundentity = ent->groundentity;
|
||||
faker->viewheight = ent->viewheight;
|
||||
faker->inuse = true;
|
||||
faker->classname = "camplayer";
|
||||
faker->mass = ent->mass;
|
||||
faker->solid = SOLID_BBOX;
|
||||
faker->deadflag = DEAD_NO;
|
||||
faker->clipmask = MASK_PLAYERSOLID;
|
||||
faker->health = ent->health;
|
||||
faker->light_level = ent->light_level;
|
||||
faker->think = faker_animate;
|
||||
faker->nextthink = level.time + FRAMETIME;
|
||||
|
||||
//CW++
|
||||
faker->style = ENT_ID_FAKER;
|
||||
//CW--
|
||||
|
||||
VectorCopy(ent->mins, faker->mins);
|
||||
VectorCopy(ent->maxs, faker->maxs);
|
||||
|
||||
// create a client so you can pick up items/be shot/etc while in camera
|
||||
cl = (gclient_t *)gi.TagMalloc(sizeof(gclient_t), TAG_LEVEL); //CW
|
||||
memset(cl, 0, sizeof(gclient_t));
|
||||
ent->client->camplayer->client = cl;
|
||||
ent->client->camplayer->target_ent = ent;
|
||||
gi.linkentity(faker);
|
||||
|
||||
AngleVectors(camera->s.angles,forward,left,up);
|
||||
|
||||
VectorMA(camera->s.origin, camera->move_origin[0], forward, ent->s.origin);
|
||||
VectorMA(ent->s.origin, -camera->move_origin[1], left, ent->s.origin);
|
||||
VectorMA(ent->s.origin, camera->move_origin[2], up, ent->s.origin);
|
||||
|
||||
ent->movetype = MOVETYPE_NOCLIP;
|
||||
ent->clipmask = 0;
|
||||
ent->solid = SOLID_NOT;
|
||||
VectorClear(ent->velocity);
|
||||
ent->client->ps.gunindex = 0;
|
||||
ent->client->ps.pmove.pm_flags |= PMF_NO_PREDICTION;
|
||||
ent->svflags |= SVF_NOCLIENT;
|
||||
|
||||
if (ent->client->spycam->viewmessage)
|
||||
gi_centerprintf(ent, ent->client->spycam->viewmessage);
|
||||
|
||||
//CW++
|
||||
faker->delay = ent->delay;
|
||||
|
||||
// If the player is on fire, transfer the flame to the fake entity.
|
||||
|
||||
if (ent->burning)
|
||||
{
|
||||
faker->burning = true;
|
||||
faker->flame = ent->flame;
|
||||
faker->flame->enemy = faker;
|
||||
|
||||
ent->flame = NULL;
|
||||
ent->burning = false;
|
||||
}
|
||||
|
||||
// Mark the fake entity as being on the same team as the player.
|
||||
|
||||
faker->client->resp.ctf_team = ent->client->resp.ctf_team;
|
||||
//CW--
|
||||
}
|
||||
|
||||
edict_t *G_FindNextCamera(edict_t *camera, edict_t *monitor)
|
||||
{
|
||||
edict_t *next;
|
||||
|
||||
if (!monitor->target)
|
||||
return NULL;
|
||||
|
||||
// If we already have a camera that's a monster, make it visible now.
|
||||
|
||||
if (camera && (camera->svflags & SVF_MONSTER))
|
||||
{
|
||||
camera->svflags &= ~SVF_NOCLIENT;
|
||||
gi.linkentity(camera);
|
||||
}
|
||||
|
||||
// First, determine if we're going to use the "count" to get the next camera,
|
||||
// or just scan through the list of entities. If count for the first camera
|
||||
// in the map is 0, then we'll just use the map order.
|
||||
|
||||
next = G_Find(NULL, FOFS(targetname), monitor->target);
|
||||
if (!next)
|
||||
return NULL;
|
||||
|
||||
if (!next->count)
|
||||
{
|
||||
if (camera)
|
||||
{
|
||||
next = camera;
|
||||
next++;
|
||||
}
|
||||
else
|
||||
next = g_edicts;
|
||||
|
||||
for ( ; next < &g_edicts[globals.num_edicts] ; next++)
|
||||
{
|
||||
if (next == camera)
|
||||
continue;
|
||||
if (!next->inuse)
|
||||
continue;
|
||||
if (next->deadflag == DEAD_DEAD)
|
||||
continue;
|
||||
if (!next->targetname)
|
||||
continue;
|
||||
// don't select "inactive" cameras
|
||||
if (!Q_stricmp(next->classname, "turret_breach") && (next->spawnflags & 16))
|
||||
continue;
|
||||
|
||||
if (!Q_stricmp(next->targetname, monitor->target))
|
||||
goto found_one;
|
||||
}
|
||||
next = g_edicts;
|
||||
for ( ; next < camera ; next++)
|
||||
{
|
||||
if (next == camera)
|
||||
continue;
|
||||
if (!next->inuse)
|
||||
continue;
|
||||
if (next->deadflag == DEAD_DEAD)
|
||||
continue;
|
||||
if (!next->targetname)
|
||||
continue;
|
||||
// don't select "inactive" cameras
|
||||
if (!Q_stricmp(next->classname, "turret_breach") && (next->spawnflags & 16))
|
||||
continue;
|
||||
|
||||
if (!Q_stricmp(next->targetname, monitor->target))
|
||||
goto found_one;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
int which;
|
||||
int start;
|
||||
|
||||
if (camera)
|
||||
{
|
||||
which = camera->count + 1;
|
||||
if (which > monitor->count)
|
||||
which = 1;
|
||||
}
|
||||
else
|
||||
which = 1;
|
||||
|
||||
start = which;
|
||||
next = g_edicts + 1;
|
||||
while (1)
|
||||
{
|
||||
if (next->targetname)
|
||||
{
|
||||
if (!Q_stricmp(next->targetname, monitor->target))
|
||||
{
|
||||
if (next->count == which)
|
||||
{
|
||||
if (!next->inuse || (next->deadflag == DEAD_DEAD) ||
|
||||
(!Q_stricmp(next->classname, "turret_breach") && (next->spawnflags & 16)))
|
||||
{
|
||||
next = g_edicts;
|
||||
which++;
|
||||
if (which > monitor->count)
|
||||
which = 1;
|
||||
|
||||
if (which == start)
|
||||
return NULL;
|
||||
}
|
||||
else
|
||||
goto found_one;
|
||||
}
|
||||
}
|
||||
}
|
||||
if (next == &g_edicts[globals.num_edicts-1])
|
||||
{
|
||||
next = g_edicts;
|
||||
which++;
|
||||
if (which > monitor->count)
|
||||
which = 1;
|
||||
|
||||
if (which == start)
|
||||
return NULL;
|
||||
}
|
||||
next++;
|
||||
}
|
||||
}
|
||||
return NULL;
|
||||
|
||||
found_one:
|
||||
if (!(monitor->spawnflags & 32) && (next->svflags & SVF_MONSTER))
|
||||
next->svflags |= SVF_NOCLIENT;
|
||||
|
||||
return next;
|
||||
}
|
||||
|
||||
edict_t *G_FindPrevCamera(edict_t *camera, edict_t *monitor)
|
||||
{
|
||||
edict_t *prev;
|
||||
edict_t *newcamera = NULL; //CW
|
||||
|
||||
if (!monitor->target)
|
||||
return NULL;
|
||||
|
||||
// If we already have a camera that's a monster, make it visible now.
|
||||
|
||||
if (camera && (camera->svflags & SVF_MONSTER))
|
||||
{
|
||||
camera->svflags &= ~SVF_NOCLIENT;
|
||||
gi.linkentity(camera);
|
||||
}
|
||||
|
||||
// First, determine if we're going to use the "count" to get the next camera,
|
||||
// or just scan through the list of entities. If count for the first camera
|
||||
// in the map is 0, then we'll just use the map order.
|
||||
|
||||
prev = G_Find(NULL, FOFS(targetname), monitor->target);
|
||||
if (!prev)
|
||||
return NULL;
|
||||
|
||||
if (!prev->count)
|
||||
{
|
||||
newcamera = NULL;
|
||||
for (prev = g_edicts ; prev < &g_edicts[globals.num_edicts] ; prev++)
|
||||
{
|
||||
if (prev == camera)
|
||||
{
|
||||
if (newcamera)
|
||||
goto found_one;
|
||||
|
||||
continue;
|
||||
}
|
||||
if (!prev->inuse)
|
||||
continue;
|
||||
if (prev->deadflag == DEAD_DEAD)
|
||||
continue;
|
||||
if (!prev->targetname)
|
||||
continue;
|
||||
// don't select "inactive" cameras
|
||||
if (!Q_stricmp(prev->classname, "turret_breach") && (prev->spawnflags & 16))
|
||||
continue;
|
||||
|
||||
if (!Q_stricmp(prev->targetname, monitor->target))
|
||||
newcamera = prev;
|
||||
}
|
||||
goto found_one;
|
||||
}
|
||||
else
|
||||
{
|
||||
int which;
|
||||
int start;
|
||||
|
||||
if (camera)
|
||||
{
|
||||
which = camera->count - 1;
|
||||
if (which <= 0)
|
||||
which = monitor->count;
|
||||
}
|
||||
else
|
||||
which = monitor->count;
|
||||
|
||||
start = which;
|
||||
prev = g_edicts + 1;
|
||||
while (1)
|
||||
{
|
||||
if (prev->targetname)
|
||||
{
|
||||
if (!Q_stricmp(prev->targetname, monitor->target))
|
||||
{
|
||||
if (prev->count == which)
|
||||
{
|
||||
if (!prev->inuse || (prev->deadflag == DEAD_DEAD) ||
|
||||
(!Q_stricmp(prev->classname, "turret_breach") && (prev->spawnflags & 16)))
|
||||
{
|
||||
prev = g_edicts;
|
||||
which--;
|
||||
if (which <= 0)
|
||||
which = monitor->count;
|
||||
|
||||
if (which == start)
|
||||
return NULL;
|
||||
}
|
||||
else
|
||||
{
|
||||
newcamera = prev;
|
||||
goto found_one;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
if (prev == &g_edicts[globals.num_edicts-1])
|
||||
{
|
||||
prev = g_edicts;
|
||||
which--;
|
||||
if (which <= 0)
|
||||
which = monitor->count;
|
||||
|
||||
if (which == start)
|
||||
return NULL;
|
||||
}
|
||||
prev++;
|
||||
}
|
||||
}
|
||||
|
||||
found_one:
|
||||
if (!(monitor->spawnflags & 32) && (newcamera->svflags & SVF_MONSTER))
|
||||
newcamera->svflags |= SVF_NOCLIENT;
|
||||
|
||||
return newcamera;
|
||||
}
|
||||
|
||||
void use_camera(edict_t *self, edict_t *other, edict_t *activator)
|
||||
{
|
||||
edict_t *target;
|
||||
|
||||
if (!activator->client)
|
||||
return;
|
||||
|
||||
if (activator->client->spycam) // already using camera
|
||||
return;
|
||||
|
||||
target = G_FindNextCamera(NULL, self);
|
||||
if (!target)
|
||||
return;
|
||||
|
||||
activator->client->spycam = target;
|
||||
activator->client->monitor = self;
|
||||
camera_on(activator);
|
||||
}
|
||||
|
||||
void func_monitor_init(edict_t *self)
|
||||
{
|
||||
edict_t *camera;
|
||||
|
||||
self->count = 0;
|
||||
camera = NULL;
|
||||
while ((camera = G_Find(camera, FOFS(targetname), self->target)) != NULL)
|
||||
self->count++;
|
||||
|
||||
if (!self->count)
|
||||
self->s.effects = 0; // don't animate a func_monitor that has no cameras
|
||||
}
|
||||
|
||||
void SP_func_monitor(edict_t *self)
|
||||
{
|
||||
if (!self->target)
|
||||
{
|
||||
gi.dprintf("func_monitor without a target at %s\n", vtos(self->s.origin));
|
||||
G_FreeEdict(self);
|
||||
return;
|
||||
}
|
||||
|
||||
if (self->spawnflags & 8)
|
||||
self->s.effects |= EF_ANIM_ALL;
|
||||
if (self->spawnflags & 16)
|
||||
self->s.effects |= EF_ANIM_ALLFAST;
|
||||
|
||||
gi.setmodel(self, self->model);
|
||||
self->movetype = MOVETYPE_NONE;
|
||||
self->solid = SOLID_BSP;
|
||||
self->use = use_camera;
|
||||
self->think = func_monitor_init;
|
||||
self->nextthink = level.time + (2.0 * FRAMETIME);
|
||||
gi.linkentity(self);
|
||||
}
|
338
awaken2/g_chase.c
Normal file
338
awaken2/g_chase.c
Normal file
|
@ -0,0 +1,338 @@
|
|||
// g_chase.c
|
||||
|
||||
//CW: This uses modified chase-cam code that was kindly sent in by
|
||||
// Doug "Raven" Buckley; it was part of the Match Mod for Q2.
|
||||
|
||||
#include "g_local.h"
|
||||
|
||||
static char chase_modenames[][30] = {
|
||||
"FreeCam",
|
||||
"ChaseCam",
|
||||
"FloatCam",
|
||||
"EyeCam",
|
||||
//CW++
|
||||
"RearCam"
|
||||
//CW--
|
||||
};
|
||||
|
||||
void SwitchModeChaseCam(edict_t *ent)
|
||||
{
|
||||
|
||||
// If chase cam is off, turn it on.
|
||||
|
||||
if (!ent->client->chase_target)
|
||||
{
|
||||
ToggleChaseCam(ent, NULL);
|
||||
return;
|
||||
}
|
||||
|
||||
// If we are in the last chasecam mode, turn it off.
|
||||
|
||||
if (ent->client->chase_mode == CHASE_LASTMODE)
|
||||
{
|
||||
ToggleChaseCam(ent, NULL);
|
||||
return;
|
||||
}
|
||||
|
||||
// Switch modes.
|
||||
|
||||
gi_cprintf(ent, PRINT_HIGH, "Now using %s.\n", chase_modenames[++ent->client->chase_mode]); //CW
|
||||
}
|
||||
|
||||
void ToggleChaseCam(edict_t *ent, pmenu_t *p)
|
||||
{
|
||||
edict_t *e;
|
||||
int i;
|
||||
|
||||
// If it's on, turn if off.
|
||||
|
||||
if (ent->client->chase_target)
|
||||
{
|
||||
gi_cprintf(ent, PRINT_HIGH, "ChaseCam deactivated.\n"); //CW
|
||||
ent->client->chase_target = NULL;
|
||||
PMenu_Close(ent);
|
||||
return;
|
||||
}
|
||||
|
||||
// If it's off, find a new chase target and track it.
|
||||
|
||||
for (i = 1; i <= (int)maxclients->value; i++)
|
||||
{
|
||||
e = g_edicts + i;
|
||||
|
||||
if (e->inuse && (e->solid != SOLID_NOT) && !e->isabot) //CW
|
||||
{
|
||||
ent->client->chase_mode = CHASE_FIRSTMODE;
|
||||
ent->client->chase_target = e;
|
||||
ent->client->update_chase = true;
|
||||
PMenu_Close(ent);
|
||||
gi_cprintf(ent, PRINT_HIGH, "ChaseCam activated (using %s mode).\n", chase_modenames[ent->client->chase_mode]); //CW
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
gi_cprintf(ent, PRINT_HIGH, "ChaseCam - no target to chase!\n"); //CW
|
||||
}
|
||||
|
||||
void UpdateChaseCam(edict_t *ent)
|
||||
{
|
||||
edict_t *targ;
|
||||
edict_t *old;
|
||||
vec3_t org;
|
||||
vec3_t ownerv;
|
||||
vec3_t goal;
|
||||
vec3_t forward;
|
||||
vec3_t right;
|
||||
vec3_t oldgoal;
|
||||
vec3_t angles;
|
||||
trace_t trace;
|
||||
int i;
|
||||
int viewdist;
|
||||
|
||||
// If our chase target is gone, move to the next, or stop chasing if there are
|
||||
// no more valid targets.
|
||||
|
||||
if (!ent->client->chase_target->inuse || ent->client->chase_target->client->spectator) //CW
|
||||
{
|
||||
old = ent->client->chase_target;
|
||||
ChaseNext(ent);
|
||||
if (ent->client->chase_target == old)
|
||||
{
|
||||
ent->client->chase_target = NULL;
|
||||
ent->client->ps.pmove.pm_flags &= ~PMF_NO_PREDICTION;
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
targ = ent->client->chase_target;
|
||||
VectorCopy(targ->s.origin, ownerv);
|
||||
VectorCopy(ent->s.origin, oldgoal);
|
||||
ownerv[2] += targ->viewheight;
|
||||
|
||||
// If in freecam mode, use that angle (SUMFUKA).
|
||||
|
||||
if (ent->client->chase_mode == CHASE_FREECAM)
|
||||
{
|
||||
for (i = 0; i < 3; i++)
|
||||
angles[i] = ent->client->resp.cmd_angles[i] + SHORT2ANGLE(ent->client->ps.pmove.delta_angles[i]);
|
||||
}
|
||||
else
|
||||
VectorCopy(targ->client->ps.viewangles, angles);
|
||||
|
||||
if (angles[PITCH] > 56.0)
|
||||
angles[PITCH] = 56.0;
|
||||
|
||||
AngleVectors(angles, forward, right, NULL);
|
||||
VectorNormalize(forward);
|
||||
|
||||
// View at different distances (default -60) (SUMFUKA).
|
||||
|
||||
viewdist = -60;
|
||||
|
||||
// Different distances...
|
||||
|
||||
if (ent->client->chase_mode == CHASE_FLOATCAM)
|
||||
viewdist = -200;
|
||||
else if (ent->client->chase_mode == CHASE_EYECAM)
|
||||
viewdist = 20;
|
||||
|
||||
//CW++
|
||||
else if (ent->client->chase_mode == CHASE_BUTTCAM)
|
||||
viewdist = -30;
|
||||
//CW--
|
||||
|
||||
VectorMA(ownerv, viewdist, forward, org);
|
||||
if (org[2] < targ->s.origin[2] + -viewdist*0.6666667) //CW
|
||||
org[2] = targ->s.origin[2] + -viewdist*0.6666667;
|
||||
|
||||
// Jump animation lifts.
|
||||
|
||||
if (!targ->groundentity)
|
||||
org[2] += 16.0;
|
||||
|
||||
trace = gi.trace(ownerv, vec3_origin, vec3_origin, org, targ, MASK_SOLID);
|
||||
VectorCopy(trace.endpos, goal);
|
||||
VectorMA(goal, 2.0, forward, goal);
|
||||
|
||||
// Pad for floors and ceilings.
|
||||
|
||||
VectorCopy(goal, org);
|
||||
org[2] += 6.0;
|
||||
trace = gi.trace(goal, vec3_origin, vec3_origin, org, targ, MASK_SOLID);
|
||||
if (trace.fraction < 1)
|
||||
{
|
||||
VectorCopy(trace.endpos, goal);
|
||||
goal[2] -= 6.0;
|
||||
}
|
||||
|
||||
VectorCopy(goal, org);
|
||||
org[2] -= 6.0;
|
||||
trace = gi.trace(goal, vec3_origin, vec3_origin, org, targ, MASK_SOLID);
|
||||
if (trace.fraction < 1)
|
||||
{
|
||||
VectorCopy(trace.endpos, goal);
|
||||
goal[2] += 6.0;
|
||||
}
|
||||
|
||||
// Using a free-move chasecam mode? (SUMFUKA).
|
||||
|
||||
if (ent->client->chase_mode == CHASE_FREECAM)
|
||||
ent->client->ps.pmove.pm_type = PM_SPECTATOR;
|
||||
else
|
||||
ent->client->ps.pmove.pm_type = PM_FREEZE;
|
||||
|
||||
VectorCopy(goal, ent->s.origin);
|
||||
|
||||
// Only set angles if in a fixed viewangle mode (SUMFUKA).
|
||||
|
||||
if (ent->client->chase_mode != CHASE_FREECAM)
|
||||
{
|
||||
for (i = 0; i < 3; i++)
|
||||
ent->client->ps.pmove.delta_angles[i] = ANGLE2SHORT(targ->client->v_angle[i] - ent->client->resp.cmd_angles[i]);
|
||||
|
||||
//CW++
|
||||
if (ent->client->chase_mode == CHASE_BUTTCAM)
|
||||
{
|
||||
ent->client->ps.viewangles[0] = -targ->client->ps.viewangles[0];
|
||||
ent->client->ps.viewangles[1] = 180.0 + targ->client->ps.viewangles[1];
|
||||
ent->client->ps.viewangles[2] = 0.0;
|
||||
|
||||
ent->client->v_angle[0] = -targ->client->ps.viewangles[0];
|
||||
ent->client->v_angle[1] = 180.0 + targ->client->ps.viewangles[1];
|
||||
ent->client->v_angle[2] = 0.0;
|
||||
}
|
||||
else
|
||||
{
|
||||
//CW--
|
||||
VectorCopy(targ->client->v_angle, ent->client->ps.viewangles);
|
||||
VectorCopy(targ->client->v_angle, ent->client->v_angle);
|
||||
}
|
||||
}
|
||||
|
||||
ent->viewheight = 0;
|
||||
ent->client->ps.pmove.pm_flags |= PMF_NO_PREDICTION;
|
||||
gi.linkentity(ent);
|
||||
|
||||
if ((!ent->client->showscores && !ent->client->menu && !ent->client->showinventory && !ent->client->showhelp &&
|
||||
!(level.framenum & 31)) || ent->client->update_chase)
|
||||
{
|
||||
//CW++
|
||||
char s[1024];
|
||||
|
||||
Com_sprintf(s, sizeof(s), "xv 0 yb -68 string2 \"Chasing %s\"", targ->client->pers.netname);
|
||||
gi.WriteByte(svc_layout);
|
||||
gi.WriteString(s);
|
||||
gi.unicast(ent, false);
|
||||
//CW--
|
||||
ent->client->update_chase = false;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
void ChaseNext(edict_t *ent)
|
||||
{
|
||||
edict_t *e;
|
||||
int i;
|
||||
|
||||
if (!ent->client->chase_target)
|
||||
return;
|
||||
|
||||
i = ent->client->chase_target - g_edicts;
|
||||
do
|
||||
{
|
||||
i++;
|
||||
if (i > (int)maxclients->value)
|
||||
i = 1;
|
||||
|
||||
e = g_edicts + i;
|
||||
if (!e->inuse)
|
||||
continue;
|
||||
|
||||
if (e->solid != SOLID_NOT)
|
||||
break;
|
||||
} while (e != ent->client->chase_target);
|
||||
|
||||
ent->client->chase_target = e;
|
||||
ent->client->update_chase = true;
|
||||
}
|
||||
|
||||
void ChasePrev(edict_t *ent)
|
||||
{
|
||||
edict_t *e;
|
||||
int i;
|
||||
|
||||
if (!ent->client->chase_target)
|
||||
return;
|
||||
|
||||
i = ent->client->chase_target - g_edicts;
|
||||
do
|
||||
{
|
||||
i--;
|
||||
if (i < 1)
|
||||
i = (int)maxclients->value;
|
||||
|
||||
e = g_edicts + i;
|
||||
if (!e->inuse)
|
||||
continue;
|
||||
|
||||
if (e->solid != SOLID_NOT)
|
||||
break;
|
||||
} while (e != ent->client->chase_target);
|
||||
|
||||
ent->client->chase_target = e;
|
||||
ent->client->update_chase = true;
|
||||
}
|
||||
|
||||
void ChaseRemoveTarget(edict_t *target)
|
||||
{
|
||||
edict_t *ent;
|
||||
int i;
|
||||
|
||||
// Anyone chasing this target must no longer do so.
|
||||
|
||||
//CW++
|
||||
for (i = 1; i <= (int)maxclients->value; i++)
|
||||
{
|
||||
ent = g_edicts + i;
|
||||
|
||||
if (!ent->inuse)
|
||||
continue;
|
||||
if (ent->client->spectator)
|
||||
continue;
|
||||
//CW--
|
||||
if (ent->client->chase_target == target)
|
||||
{
|
||||
gi_cprintf(ent, PRINT_HIGH, "ChaseCam deactivated - target lost!\n"); //CW
|
||||
ent->client->chase_target = NULL;
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
void GetChaseTarget(edict_t *ent)
|
||||
{
|
||||
edict_t *other;
|
||||
int i;
|
||||
|
||||
for (i = 1; i <= (int)maxclients->value; i++)
|
||||
{
|
||||
other = g_edicts + i;
|
||||
|
||||
//CW++
|
||||
if (!other->inuse)
|
||||
continue;
|
||||
if (other->client->spectator)
|
||||
continue;
|
||||
//CW--
|
||||
ent->client->chase_target = other;
|
||||
ent->client->update_chase = true;
|
||||
UpdateChaseCam(ent);
|
||||
return;
|
||||
}
|
||||
|
||||
gi_centerprintf(ent, "No other players to chase."); //CW
|
||||
}
|
||||
|
||||
void ChaseHelp(edict_t *ent)
|
||||
{
|
||||
gi_centerprintf(ent, "(use fire to change ChaseCam mode)\n(and [ or ] to change ChaseCam target)\n");
|
||||
}
|
25
awaken2/g_chase.h
Normal file
25
awaken2/g_chase.h
Normal file
|
@ -0,0 +1,25 @@
|
|||
// g_chase.h
|
||||
|
||||
//CW: This code was kindly sent in by Doug "Raven" Buckley;
|
||||
// it was used as part of The Match Mod for Q2.
|
||||
|
||||
|
||||
#define CHASE_FREECAM 0
|
||||
#define CHASE_CHASECAM 1
|
||||
#define CHASE_FLOATCAM 2
|
||||
#define CHASE_EYECAM 3
|
||||
|
||||
//CW++
|
||||
#define CHASE_BUTTCAM 4
|
||||
//CW--
|
||||
|
||||
#define CHASE_FIRSTMODE CHASE_FREECAM
|
||||
#define CHASE_LASTMODE CHASE_BUTTCAM //CW
|
||||
|
||||
void ToggleChaseCam(edict_t *ent, pmenu_t *p);
|
||||
void SwitchModeChaseCam(edict_t *ent);
|
||||
void UpdateChaseCam(edict_t *ent);
|
||||
void ChaseNext(edict_t *ent);
|
||||
void ChasePrev(edict_t *ent);
|
||||
void ChaseRemoveTarget(edict_t *target);
|
||||
void ChaseHelp(edict_t *ent);
|
3280
awaken2/g_cmds.c
Normal file
3280
awaken2/g_cmds.c
Normal file
File diff suppressed because it is too large
Load diff
678
awaken2/g_combat.c
Normal file
678
awaken2/g_combat.c
Normal file
|
@ -0,0 +1,678 @@
|
|||
// g_combat.c
|
||||
|
||||
#include "g_local.h"
|
||||
|
||||
/*
|
||||
============
|
||||
CanDamage
|
||||
|
||||
Returns true if the inflictor can directly damage the target. Used for
|
||||
explosions and melee attacks.
|
||||
============
|
||||
*/
|
||||
qboolean CanDamage(edict_t *targ, edict_t *inflictor)
|
||||
{
|
||||
vec3_t dest;
|
||||
trace_t trace;
|
||||
|
||||
// bmodels need special checking because their origin is {0,0,0}.
|
||||
|
||||
if (targ->movetype == MOVETYPE_PUSH)
|
||||
{
|
||||
VectorAdd(targ->absmin, targ->absmax, dest);
|
||||
VectorScale(dest, 0.5, dest);
|
||||
trace = gi.trace(inflictor->s.origin, vec3_origin, vec3_origin, dest, inflictor, MASK_SOLID);
|
||||
if (trace.fraction == 1.0)
|
||||
return true;
|
||||
|
||||
if (trace.ent == targ)
|
||||
return true;
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
trace = gi.trace(inflictor->s.origin, vec3_origin, vec3_origin, targ->s.origin, inflictor, MASK_SOLID);
|
||||
if (trace.fraction == 1.0)
|
||||
return true;
|
||||
|
||||
VectorCopy(targ->s.origin, dest);
|
||||
dest[0] += 15.0;
|
||||
dest[1] += 15.0;
|
||||
trace = gi.trace(inflictor->s.origin, vec3_origin, vec3_origin, dest, inflictor, MASK_SOLID);
|
||||
if (trace.fraction == 1.0)
|
||||
return true;
|
||||
|
||||
VectorCopy(targ->s.origin, dest);
|
||||
dest[0] += 15.0;
|
||||
dest[1] -= 15.0;
|
||||
trace = gi.trace(inflictor->s.origin, vec3_origin, vec3_origin, dest, inflictor, MASK_SOLID);
|
||||
if (trace.fraction == 1.0)
|
||||
return true;
|
||||
|
||||
VectorCopy(targ->s.origin, dest);
|
||||
dest[0] -= 15.0;
|
||||
dest[1] += 15.0;
|
||||
trace = gi.trace (inflictor->s.origin, vec3_origin, vec3_origin, dest, inflictor, MASK_SOLID);
|
||||
if (trace.fraction == 1.0)
|
||||
return true;
|
||||
|
||||
VectorCopy(targ->s.origin, dest);
|
||||
dest[0] -= 15.0;
|
||||
dest[1] -= 15.0;
|
||||
trace = gi.trace(inflictor->s.origin, vec3_origin, vec3_origin, dest, inflictor, MASK_SOLID);
|
||||
if (trace.fraction == 1.0)
|
||||
return true;
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
============
|
||||
Killed
|
||||
============
|
||||
*/
|
||||
void Killed(edict_t *targ, edict_t *inflictor, edict_t *attacker, int damage, vec3_t point)
|
||||
{
|
||||
if (targ->health < -999)
|
||||
targ->health = -999;
|
||||
|
||||
targ->enemy = attacker;
|
||||
|
||||
if ((targ->movetype == MOVETYPE_PUSH) || (targ->movetype == MOVETYPE_STOP) || (targ->movetype == MOVETYPE_NONE))
|
||||
{ // doors, triggers, etc
|
||||
targ->die(targ, inflictor, attacker, damage, point);
|
||||
return;
|
||||
}
|
||||
|
||||
targ->die(targ, inflictor, attacker, damage, point);
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
================
|
||||
SpawnDamage
|
||||
================
|
||||
*/
|
||||
void SpawnDamage(int type, vec3_t origin, vec3_t normal, int damage)
|
||||
{
|
||||
gi.WriteByte(svc_temp_entity);
|
||||
gi.WriteByte(type);
|
||||
gi.WritePosition(origin);
|
||||
gi.WriteDir(normal);
|
||||
gi.multicast(origin, MULTICAST_PVS);
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
============
|
||||
T_Damage
|
||||
|
||||
targ entity that is being damaged
|
||||
inflictor entity that is causing the damage
|
||||
attacker entity that caused the inflictor to damage targ
|
||||
example: targ=monster, inflictor=rocket, attacker=player
|
||||
|
||||
dir direction of the attack
|
||||
point point at which the damage is being inflicted
|
||||
normal normal vector from that point
|
||||
damage amount of damage being inflicted
|
||||
knockback force to be applied against targ as a result of the damage
|
||||
|
||||
dflags these flags are used to control how T_Damage works
|
||||
DAMAGE_RADIUS damage was indirect (from a nearby explosion)
|
||||
DAMAGE_NO_ARMOR armor does not protect from this damage
|
||||
DAMAGE_ENERGY damage is from an energy based weapon
|
||||
DAMAGE_NO_KNOCKBACK do not affect velocity, just view angles
|
||||
DAMAGE_BULLET damage is from a bullet (used for ricochets)
|
||||
DAMAGE_NO_PROTECTION kills godmode, armor, everything
|
||||
============
|
||||
*/
|
||||
static int CheckPowerArmor(edict_t *ent, vec3_t point, vec3_t normal, int damage, int dflags)
|
||||
{
|
||||
gclient_t *client;
|
||||
int save;
|
||||
int power_armor_type;
|
||||
int index = 0; //CW
|
||||
int damagePerCell;
|
||||
int pa_te_type;
|
||||
int power = 0; //CW
|
||||
int power_used;
|
||||
|
||||
if (!damage)
|
||||
return 0;
|
||||
|
||||
if (dflags & DAMAGE_NO_ARMOR)
|
||||
return 0;
|
||||
|
||||
client = ent->client; //CW
|
||||
|
||||
//CW++
|
||||
if (!client)
|
||||
return 0;
|
||||
//CW--
|
||||
|
||||
power_armor_type = PowerArmorType(ent);
|
||||
if (power_armor_type != POWER_ARMOR_NONE)
|
||||
{
|
||||
index = ITEM_INDEX(FindItem("Cells"));
|
||||
power = client->pers.inventory[index];
|
||||
}
|
||||
|
||||
if (power_armor_type == POWER_ARMOR_NONE)
|
||||
return 0;
|
||||
|
||||
if (!power)
|
||||
return 0;
|
||||
|
||||
if (power_armor_type == POWER_ARMOR_SCREEN)
|
||||
{
|
||||
vec3_t vec;
|
||||
vec3_t forward;
|
||||
float dot;
|
||||
|
||||
// only works if damage point is in front
|
||||
AngleVectors(ent->s.angles, forward, NULL, NULL);
|
||||
VectorSubtract(point, ent->s.origin, vec);
|
||||
VectorNormalize(vec);
|
||||
dot = DotProduct(vec, forward);
|
||||
if (dot <= 0.3)
|
||||
return 0;
|
||||
|
||||
damagePerCell = 1;
|
||||
pa_te_type = TE_SCREEN_SPARKS;
|
||||
damage = (int)(0.333 * damage); //CW
|
||||
}
|
||||
else
|
||||
{
|
||||
if ((int)sv_gametype->value > G_FFA) //CW
|
||||
damagePerCell = 1; // power armor is weaker in CTF, TDM & Assault
|
||||
else
|
||||
damagePerCell = 2;
|
||||
|
||||
pa_te_type = TE_SHIELD_SPARKS;
|
||||
damage = (int)(0.667 * damage); //CW
|
||||
}
|
||||
|
||||
save = power * damagePerCell;
|
||||
if (!save)
|
||||
return 0;
|
||||
|
||||
if (save > damage)
|
||||
save = damage;
|
||||
|
||||
SpawnDamage(pa_te_type, point, normal, save);
|
||||
ent->powerarmor_time = level.time + 0.2;
|
||||
|
||||
power_used = (int)(save / damagePerCell); //CW
|
||||
if (client)
|
||||
client->pers.inventory[index] -= power_used;
|
||||
else
|
||||
ent->monsterinfo.power_armor_power -= power_used;
|
||||
|
||||
return save;
|
||||
}
|
||||
|
||||
static int CheckArmor(edict_t *ent, vec3_t point, vec3_t normal, int damage, int te_sparks, int dflags)
|
||||
{
|
||||
gclient_t *client;
|
||||
gitem_t *armor;
|
||||
int save;
|
||||
int index;
|
||||
|
||||
if (!damage)
|
||||
return 0;
|
||||
|
||||
client = ent->client;
|
||||
|
||||
if (!client)
|
||||
return 0;
|
||||
|
||||
if (dflags & DAMAGE_NO_ARMOR)
|
||||
return 0;
|
||||
|
||||
index = ArmorIndex(ent);
|
||||
if (!index)
|
||||
return 0;
|
||||
|
||||
armor = GetItemByIndex(index);
|
||||
if (dflags & DAMAGE_ENERGY)
|
||||
save = ceil(((gitem_armor_t *)armor->info)->energy_protection * damage);
|
||||
else
|
||||
save = ceil(((gitem_armor_t *)armor->info)->normal_protection * damage);
|
||||
if (save >= client->pers.inventory[index])
|
||||
save = client->pers.inventory[index];
|
||||
|
||||
if (!save)
|
||||
return 0;
|
||||
|
||||
client->pers.inventory[index] -= save;
|
||||
SpawnDamage(te_sparks, point, normal, save);
|
||||
|
||||
return save;
|
||||
}
|
||||
|
||||
|
||||
qboolean CheckTeamDamage(edict_t *targ, edict_t *attacker)
|
||||
{
|
||||
//ZOID++
|
||||
if (((int)sv_gametype->value > G_FFA) && targ->client && attacker->client) //CW
|
||||
{
|
||||
if ((targ->client->resp.ctf_team == attacker->client->resp.ctf_team) && (targ != attacker))
|
||||
return true;
|
||||
}
|
||||
//ZOID--
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
//CW++
|
||||
qboolean CheckTurretTeamDamage(edict_t *targ, edict_t *attacker)
|
||||
{
|
||||
edict_t *player;
|
||||
int i;
|
||||
|
||||
if (((int)sv_gametype->value > G_FFA) && targ->client && attacker)
|
||||
{
|
||||
for (i = 0, player = g_edicts + 1; i < (int)maxclients->value; ++i, ++player)
|
||||
{
|
||||
if (player->client && (player->client->spycam == attacker))
|
||||
{
|
||||
if ((targ->client->resp.ctf_team == player->client->resp.ctf_team) && (targ != attacker))
|
||||
return true;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
//CW--
|
||||
|
||||
// /--- CW: was *targ
|
||||
void T_Damage(edict_t *in_targ, edict_t *inflictor, edict_t *attacker, vec3_t dir, vec3_t point, vec3_t normal, int damage, int knockback, int dflags, int mod)
|
||||
{
|
||||
gclient_t *client;
|
||||
int take;
|
||||
int save;
|
||||
int asave;
|
||||
int psave;
|
||||
int te_sparks;
|
||||
|
||||
//DH++
|
||||
edict_t *targ;
|
||||
|
||||
targ = in_targ;
|
||||
if (!targ || !targ->inuse)
|
||||
return;
|
||||
//DH--
|
||||
|
||||
if (!targ->takedamage)
|
||||
return;
|
||||
|
||||
//Maj++
|
||||
CheckBotCrushed(targ, inflictor, mod);
|
||||
//Maj--
|
||||
|
||||
//CW++
|
||||
if ((mod == MOD_GAUSS_BEAM) && targ->client && (targ->client->antibeam_framenum > level.framenum))
|
||||
{
|
||||
gi.sound(targ, CHAN_ITEM, gi.soundindex("ctf/tech1.wav"), 1, ATTN_NORM, 0);
|
||||
return;
|
||||
}
|
||||
|
||||
targ->noise_index = 0;
|
||||
//CW--
|
||||
|
||||
//DH++
|
||||
// If targ is a fake player for the real player viewing camera, get that player
|
||||
// out of the camera and do the damage to him (CW: 'style' abused with a hardcoded
|
||||
// value so we don't have to to a slooow classname strcmp).
|
||||
|
||||
//CW++
|
||||
if (targ->style == ENT_ID_FAKER)
|
||||
//CW--
|
||||
{
|
||||
if (targ->target_ent && targ->target_ent->client && targ->target_ent->client->spycam)
|
||||
{
|
||||
//CW++
|
||||
if (targ->target_ent->client->spycam == attacker) // shot self with turret
|
||||
targ->target_ent->noise_index = 1; // abuse var so edict_t doesn't have to be extended
|
||||
//CW--
|
||||
if (attacker->enemy == targ)
|
||||
{
|
||||
attacker->enemy = targ->target_ent;
|
||||
attacker->goalentity = NULL;
|
||||
attacker->movetarget = NULL;
|
||||
}
|
||||
targ = targ->target_ent;
|
||||
camera_off(targ);
|
||||
}
|
||||
else
|
||||
return; // don't damage target_monitor camplayer
|
||||
}
|
||||
//DH--
|
||||
|
||||
//Maj++
|
||||
if (targ != attacker) //CW...
|
||||
{
|
||||
if (CheckTeamDamage(targ, attacker))
|
||||
damage = 0;
|
||||
else
|
||||
{
|
||||
if (targ->client && !targ->isabot && attacker->client)
|
||||
targ->client->current_enemy = attacker;
|
||||
}
|
||||
}
|
||||
//Maj--
|
||||
|
||||
|
||||
// friendly fire avoidance: if enabled you can't hurt teammates (but you can hurt yourself);
|
||||
// knockback still occurs
|
||||
meansOfDeath = mod;
|
||||
|
||||
client = targ->client;
|
||||
|
||||
if (dflags & DAMAGE_BULLET)
|
||||
te_sparks = TE_BULLET_SPARKS;
|
||||
else
|
||||
te_sparks = TE_SPARKS;
|
||||
|
||||
VectorNormalize(dir);
|
||||
|
||||
//ZOID++
|
||||
// strength tech
|
||||
damage = CTFApplyStrength(attacker, damage);
|
||||
//ZOID--
|
||||
|
||||
if (targ->flags & FL_NO_KNOCKBACK)
|
||||
knockback = 0;
|
||||
|
||||
// figure momentum add
|
||||
if (!(dflags & DAMAGE_NO_KNOCKBACK))
|
||||
{
|
||||
if (knockback && (targ->movetype != MOVETYPE_NONE) && (targ->movetype != MOVETYPE_BOUNCE) && (targ->movetype != MOVETYPE_PUSH) && (targ->movetype != MOVETYPE_STOP))
|
||||
{
|
||||
vec3_t kvel;
|
||||
float mass;
|
||||
|
||||
if (targ->mass < 50.0)
|
||||
mass = 50.0;
|
||||
else
|
||||
mass = (float)targ->mass;
|
||||
|
||||
if (client && (attacker == targ) && (inflictor->die != Trap_DieFromDamage)) //CW
|
||||
//CW++
|
||||
{
|
||||
if (inflictor->die == C4_DieFromDamage)
|
||||
VectorScale(dir, 2250.0 * ((float)knockback / mass), kvel); // the C4 jump hack
|
||||
else
|
||||
//CW--
|
||||
VectorScale(dir, 1600.0 * ((float)knockback / mass), kvel); // the rocket jump hack
|
||||
}
|
||||
else
|
||||
//CW++
|
||||
{
|
||||
if ((inflictor->touch == Rocket_Touch) || (inflictor->die == C4_DieFromDamage))
|
||||
VectorScale(dir, sv_rocket_kick_scale->value * ((float)knockback / mass), kvel);
|
||||
else
|
||||
//CW--
|
||||
VectorScale(dir, 500.0 * ((float)knockback / mass), kvel);
|
||||
}
|
||||
|
||||
VectorAdd(targ->velocity, kvel, targ->velocity);
|
||||
}
|
||||
}
|
||||
|
||||
take = damage;
|
||||
save = 0;
|
||||
|
||||
// check for godmode
|
||||
if ((targ->flags & FL_GODMODE) && !(dflags & DAMAGE_NO_PROTECTION))
|
||||
{
|
||||
take = 0;
|
||||
save = damage;
|
||||
SpawnDamage(te_sparks, point, normal, save);
|
||||
}
|
||||
|
||||
// check for invincibility
|
||||
if ((client && client->invincible_framenum > level.framenum ) && !(dflags & DAMAGE_NO_PROTECTION))
|
||||
{
|
||||
if (targ->pain_debounce_time < level.time)
|
||||
{
|
||||
gi.sound(targ, CHAN_ITEM, gi.soundindex("items/protect4.wav"), 1, ATTN_NORM, 0);
|
||||
targ->pain_debounce_time = level.time + 2.0;
|
||||
}
|
||||
take = 0;
|
||||
save = damage;
|
||||
}
|
||||
|
||||
//ZOID++
|
||||
//team armor protect
|
||||
if (((int)sv_gametype->value > G_FFA) && targ->client && attacker->client && //CW
|
||||
(targ->client->resp.ctf_team == attacker->client->resp.ctf_team) &&
|
||||
(targ != attacker) && ((int)dmflags->value & DF_ARMOR_PROTECT))
|
||||
{
|
||||
psave = asave = 0;
|
||||
}
|
||||
else if (CheckTurretTeamDamage(targ, attacker) && ((int)dmflags->value & DF_ARMOR_PROTECT))
|
||||
{
|
||||
psave = asave = 0;
|
||||
}
|
||||
else
|
||||
{
|
||||
//ZOID--
|
||||
psave = CheckPowerArmor(targ, point, normal, take, dflags);
|
||||
take -= psave;
|
||||
|
||||
asave = CheckArmor(targ, point, normal, take, te_sparks, dflags);
|
||||
take -= asave;
|
||||
}
|
||||
|
||||
//treat cheat/powerup savings the same as armor
|
||||
asave += save;
|
||||
|
||||
//ZOID++
|
||||
//resistance tech
|
||||
take = CTFApplyResistance(targ, take);
|
||||
//ZOID--
|
||||
|
||||
// team damage avoidance
|
||||
if (!(dflags & DAMAGE_NO_PROTECTION) && CheckTeamDamage(targ, attacker))
|
||||
return;
|
||||
|
||||
//CW++
|
||||
if (!(dflags & DAMAGE_NO_PROTECTION) && CheckTurretTeamDamage(targ, attacker))
|
||||
return;
|
||||
//CW--
|
||||
|
||||
//ZOID++
|
||||
CTFCheckHurtCarrier(targ, attacker);
|
||||
//ZOID--
|
||||
|
||||
// Do the damage.
|
||||
|
||||
if (take)
|
||||
{
|
||||
if ((targ->svflags & SVF_MONSTER) || client)
|
||||
{
|
||||
SpawnDamage(TE_BLOOD, point, normal, take);
|
||||
Bot_CheckEnemy(client, attacker, targ, mod); //Maj++
|
||||
}
|
||||
else
|
||||
SpawnDamage(te_sparks, point, normal, take);
|
||||
|
||||
if (!CTFMatchSetup())
|
||||
//CW++
|
||||
{
|
||||
// D89 (needle) power-up: damage is halved.
|
||||
|
||||
if (client && (client->needle_framenum > level.framenum))
|
||||
take = (int)(0.5 * take);
|
||||
//CW--
|
||||
|
||||
targ->health = targ->health - take;
|
||||
|
||||
//CW++
|
||||
// Awakening (siphon) power-up: attacker gets health equal to damage inflicted (unless it's us).
|
||||
|
||||
if (client && attacker->client)
|
||||
{
|
||||
if (attacker->client->siphon_framenum > level.framenum)
|
||||
{
|
||||
if ((targ != attacker) && (attacker->health < (int)sv_health_max_siphon->value))
|
||||
{
|
||||
attacker->health += take + ((targ->health < 0)?targ->health:0);
|
||||
gi.sound(attacker, CHAN_ITEM, gi.soundindex("items/siphon3.wav"), 1, ATTN_NORM, 0);
|
||||
if (attacker->health > (int)sv_health_max_siphon->value)
|
||||
attacker->health = (int)sv_health_max_siphon->value;
|
||||
}
|
||||
}
|
||||
|
||||
if ((mod == MOD_AGM_DISRUPT) && (attacker->health < (int)sv_health_max_siphon->value))
|
||||
{
|
||||
attacker->health += (int)(sv_agm_disrupt_siphon->value * (take + ((targ->health < 0)?targ->health:0)));
|
||||
gi.sound(attacker, CHAN_ITEM, gi.soundindex("parasite/paratck3.wav"), 1, ATTN_NORM, 0);
|
||||
if (attacker->health > (int)sv_health_max_siphon->value)
|
||||
attacker->health = (int)sv_health_max_siphon->value;
|
||||
}
|
||||
}
|
||||
}
|
||||
//CW--
|
||||
|
||||
if (targ->health < 1) //CW
|
||||
{
|
||||
if ((targ->svflags & SVF_MONSTER) || client)
|
||||
targ->flags |= FL_NO_KNOCKBACK;
|
||||
|
||||
Killed(targ, inflictor, attacker, take, point);
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
if (client)
|
||||
{
|
||||
if (!(targ->flags & FL_GODMODE) && take && !CTFMatchSetup())
|
||||
targ->pain(targ, attacker, knockback, take);
|
||||
}
|
||||
else if (take)
|
||||
{
|
||||
if (targ->pain)
|
||||
targ->pain(targ, attacker, knockback, take);
|
||||
}
|
||||
|
||||
// add to the damage inflicted on a player this frame
|
||||
// the total will be turned into screen blends and view angle kicks at the end of the frame
|
||||
if (client)
|
||||
{
|
||||
client->damage_parmor += psave;
|
||||
client->damage_armor += asave;
|
||||
client->damage_blood += take;
|
||||
client->damage_knockback += knockback;
|
||||
VectorCopy(point, client->damage_from);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
============
|
||||
T_RadiusDamage
|
||||
============
|
||||
*/
|
||||
void T_RadiusDamage(edict_t *inflictor, edict_t *attacker, float damage, edict_t *ignore, float radius, int mod)
|
||||
{
|
||||
edict_t *ent = NULL;
|
||||
vec3_t v;
|
||||
vec3_t dir;
|
||||
float points;
|
||||
|
||||
//CW++
|
||||
edict_t *targ;
|
||||
//CW--
|
||||
|
||||
while ((ent = FindRadius(ent, inflictor->s.origin, radius)) != NULL)
|
||||
{
|
||||
if (ent == ignore)
|
||||
continue;
|
||||
if (!ent->takedamage)
|
||||
continue;
|
||||
|
||||
//CW++
|
||||
// For detonating C4 bundles, don't apply radius damage to other C4 bundles belonging to the player.
|
||||
|
||||
if (inflictor->die == C4_DieFromDamage)
|
||||
{
|
||||
if ((ent->die == C4_DieFromDamage) && (ent->owner == inflictor->owner))
|
||||
continue;
|
||||
}
|
||||
//CW--
|
||||
VectorAdd(ent->mins, ent->maxs, v);
|
||||
VectorMA(ent->s.origin, 0.5, v, v);
|
||||
VectorSubtract(inflictor->s.origin, v, v);
|
||||
points = damage - (0.5 * VectorLength(v));
|
||||
if (ent == attacker)
|
||||
points = points * 0.5;
|
||||
|
||||
if ((points > 0) && CanDamage(ent, inflictor)) //CW
|
||||
{
|
||||
//CW++
|
||||
if (ent->client)
|
||||
{
|
||||
if (ent->target_ent && ent->target_ent->client && ent->target_ent->client->spycam)
|
||||
targ = ent->target_ent; // ...ent -> targ for all below
|
||||
else
|
||||
targ = ent;
|
||||
|
||||
// Apply freezing effect of Shock Rifle (disintegrator mode) to still-living players.
|
||||
|
||||
if (mod == MOD_SR_DISINT_WAVE)
|
||||
{
|
||||
if (CheckTeamDamage(targ, attacker))
|
||||
continue;
|
||||
if (targ->client->invincible_framenum > level.framenum)
|
||||
continue;
|
||||
|
||||
if ((ent->health > 0) && (targ->client->enviro_framenum <= level.framenum))
|
||||
{
|
||||
if (targ == attacker)
|
||||
gi_centerprintf(targ, "You've frozen yourself\n");
|
||||
else
|
||||
//CW++
|
||||
{
|
||||
if (!attacker->client)
|
||||
gi_centerprintf(targ, "You've been frozen\n");
|
||||
else
|
||||
//CW--
|
||||
gi_centerprintf(targ, "You've been frozen by %s\n", attacker->client->pers.netname);
|
||||
}
|
||||
|
||||
if (ent->client->frozen_framenum > level.framenum)
|
||||
ent->client->frozen_framenum += (int)(10.0 * sv_shock_freeze_time->value); //CW
|
||||
else
|
||||
ent->client->frozen_framenum = level.framenum + (int)(10.0 * sv_shock_freeze_time->value); //CW
|
||||
}
|
||||
}
|
||||
|
||||
// Ignite players who are caught in the blast radius of a firebomb.
|
||||
|
||||
else if (mod == MOD_FIREBOMB_SPLASH)
|
||||
{
|
||||
if (targ->client->enviro_framenum > level.framenum)
|
||||
continue;
|
||||
if (CheckTeamDamage(targ, attacker))
|
||||
continue;
|
||||
if (targ->client->invincible_framenum > level.framenum)
|
||||
continue;
|
||||
|
||||
if (!ent->burning)
|
||||
{
|
||||
ent->burning = true;
|
||||
Spawn_Flame(inflictor, ent, ent->s.origin, inflictor->radius_dmg);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
VectorSubtract(ent->s.origin, inflictor->s.origin, dir);
|
||||
T_Damage(ent, inflictor, attacker, dir, inflictor->s.origin, vec3_origin, (int)points, (int)points, DAMAGE_RADIUS, mod);
|
||||
}
|
||||
}
|
||||
}
|
3214
awaken2/g_func.c
Normal file
3214
awaken2/g_func.c
Normal file
File diff suppressed because it is too large
Load diff
3571
awaken2/g_items.c
Normal file
3571
awaken2/g_items.c
Normal file
File diff suppressed because it is too large
Load diff
2145
awaken2/g_local.h
Normal file
2145
awaken2/g_local.h
Normal file
File diff suppressed because it is too large
Load diff
1083
awaken2/g_main.c
Normal file
1083
awaken2/g_main.c
Normal file
File diff suppressed because it is too large
Load diff
3690
awaken2/g_menus.c
Normal file
3690
awaken2/g_menus.c
Normal file
File diff suppressed because it is too large
Load diff
2041
awaken2/g_misc.c
Normal file
2041
awaken2/g_misc.c
Normal file
File diff suppressed because it is too large
Load diff
259
awaken2/g_model.c
Normal file
259
awaken2/g_model.c
Normal file
|
@ -0,0 +1,259 @@
|
|||
// g_model.c
|
||||
|
||||
//CW: This turret code is taken from the Lazarus mod source (version 2.1),
|
||||
// which David Hyde released on 22-Sep-01 for public use.
|
||||
// See 'http://planetquake.com/lazarus' for more information.
|
||||
|
||||
// ----------------------------------------------------------------------------
|
||||
//
|
||||
// mappack stuff by mr. ed, modified extensively for Tremor by dwh
|
||||
//
|
||||
|
||||
//Spawns a user defined model, you can specify whether its solid, if so how big the box is, and apply nearly
|
||||
//any effect to the entity.
|
||||
//
|
||||
// PLAYER set this if you want to use a player model
|
||||
//
|
||||
// Note : These flags override any frame settings you may have enterered
|
||||
// ANIM01 cycle between frames 0 and 1 at 2 hz
|
||||
// ANIM23 cycle between frames 2 and 3 at 2 hz
|
||||
// ANIM_ALL cycle through all frames at 2hz
|
||||
// ANIM_ALLFAST cycle through all frames at 10hz
|
||||
//
|
||||
// START_OFF Start inactive, when triggered display the model
|
||||
// TOGGLE Start active, when triggered become inactive
|
||||
// NO_MODEL Don't use a model. Usefull for placeing particle effects and
|
||||
// dynamic lights on their own
|
||||
//
|
||||
// "usermodel" = The model to load (models/ is already coded)
|
||||
// "startframe" = The starting frame : default 0
|
||||
// "userframes" = The number of frames you want to display after startframe
|
||||
// "solidstate" = 1 : SOLID_NOT - not solid at all
|
||||
// 2 : SOLID_BBOX - solid and affected by gravity
|
||||
// 3 : NO DROP - solid but not affected by gravity
|
||||
// 4 : SOLID_NOT, but affect by gravity
|
||||
//
|
||||
// NOTE : if you want the model to be solid then you must enter vector values into the following fields :
|
||||
// "bleft" = the point that is at the bottom left of the models bounding box in a model editor
|
||||
// "tright" = the point that is at the top left of the models bounding box in a model editor
|
||||
//
|
||||
|
||||
#include "g_local.h"
|
||||
|
||||
#define TOGGLE 2
|
||||
#define PLAYER_MODEL 8
|
||||
#define NO_MODEL 16
|
||||
#define ANIM_ONCE 32
|
||||
|
||||
void model_spawn_use(edict_t *self, edict_t *other, edict_t *activator);
|
||||
|
||||
void modelspawn_think (edict_t *self)
|
||||
{
|
||||
self->s.frame++;
|
||||
if (self->s.frame >= self->framenumbers)
|
||||
{
|
||||
self->s.frame = self->startframe;
|
||||
if(self->spawnflags & ANIM_ONCE)
|
||||
{
|
||||
model_spawn_use(self,world,world);
|
||||
return;
|
||||
}
|
||||
}
|
||||
self->nextthink = level.time + FRAMETIME;
|
||||
gi.linkentity(self);
|
||||
}
|
||||
|
||||
void model_spawn_use (edict_t *self, edict_t *other, edict_t *activator)
|
||||
{
|
||||
if (self->delay) //we started off
|
||||
{
|
||||
self->svflags &= ~SVF_NOCLIENT;
|
||||
self->delay = 0;
|
||||
if(self->framenumbers > 1)
|
||||
{
|
||||
self->think = modelspawn_think;
|
||||
self->nextthink = level.time + FRAMETIME;
|
||||
}
|
||||
self->s.sound = self->noise_index;
|
||||
#ifdef LOOP_SOUND_ATTENUATION
|
||||
self->s.attenuation = self->attenuation;
|
||||
#endif
|
||||
}
|
||||
else //we started active
|
||||
{
|
||||
self->svflags |= SVF_NOCLIENT;
|
||||
self->delay = 1;
|
||||
self->use = model_spawn_use;
|
||||
self->think = NULL;
|
||||
self->nextthink = 0;
|
||||
self->s.sound = 0;
|
||||
}
|
||||
}
|
||||
|
||||
void model_die (edict_t *self, edict_t *inflictor, edict_t *attacker, int damage, vec3_t point)
|
||||
{
|
||||
/* edict_t *e, *next;
|
||||
|
||||
e = self->movewith_next;
|
||||
while(e) {
|
||||
next = e->movewith_next;
|
||||
if(e->solid == SOLID_NOT) {
|
||||
e->nextthink = 0;
|
||||
G_FreeEdict(e);
|
||||
} else
|
||||
BecomeExplosion1 (e);
|
||||
e = next;
|
||||
}
|
||||
*/
|
||||
BecomeExplosion1(self);
|
||||
}
|
||||
|
||||
#define ANIM_MASK (EF_ANIM01|EF_ANIM23|EF_ANIM_ALL|EF_ANIM_ALLFAST)
|
||||
|
||||
void SP_model_spawn (edict_t *ent)
|
||||
{
|
||||
char modelname[256];
|
||||
|
||||
//paranoia checks
|
||||
if ((!ent->usermodel) && !(ent->spawnflags & NO_MODEL) && !(ent->spawnflags & PLAYER_MODEL))
|
||||
{
|
||||
gi.dprintf("%s without a model at %s\n", ent->classname, vtos(ent->s.origin));
|
||||
G_FreeEdict(ent);
|
||||
return;
|
||||
}
|
||||
|
||||
switch (ent->solidstate)
|
||||
{
|
||||
case 1 : ent->solid = SOLID_NOT; ent->movetype = MOVETYPE_NONE; break;
|
||||
case 2 : ent->solid = SOLID_BBOX; ent->movetype = MOVETYPE_TOSS; break;
|
||||
case 3 : ent->solid = SOLID_BBOX; ent->movetype = MOVETYPE_NONE; break;
|
||||
case 4 : ent->solid = SOLID_NOT; ent->movetype = MOVETYPE_TOSS; break;
|
||||
default: ent->solid = SOLID_NOT; ent->movetype = MOVETYPE_NONE; break;
|
||||
}
|
||||
if (ent->solid != SOLID_NOT ) {
|
||||
if (ent->health > 0) {
|
||||
ent->die = model_die;
|
||||
ent->takedamage = DAMAGE_YES;
|
||||
}
|
||||
}
|
||||
|
||||
switch (ent->style)
|
||||
{
|
||||
case 1 : ent->s.effects |= EF_ANIM01; break;
|
||||
case 2 : ent->s.effects |= EF_ANIM23; break;
|
||||
case 3 : ent->s.effects |= EF_ANIM_ALL; break;
|
||||
case 4 : ent->s.effects |= EF_ANIM_ALLFAST; break;
|
||||
}
|
||||
|
||||
// DWH: Rather than use one value (renderfx) we use the
|
||||
// actual values for effects and renderfx. All may
|
||||
// be combined.
|
||||
ent->s.effects |= ent->effects;
|
||||
ent->s.renderfx |= ent->renderfx;
|
||||
|
||||
if (ent->startframe < 0)
|
||||
ent->startframe = 0;
|
||||
if (!ent->framenumbers)
|
||||
ent->framenumbers = 1;
|
||||
// Change framenumbers to last frame to play
|
||||
ent->framenumbers += ent->startframe;
|
||||
|
||||
if (ent->bleft)
|
||||
{
|
||||
VectorCopy (ent->bleft, ent->mins);
|
||||
}
|
||||
else
|
||||
{
|
||||
if (ent->solid != SOLID_NOT)
|
||||
{
|
||||
gi.dprintf("%s solid with no bleft vector at %s\n", ent->classname, vtos(ent->s.origin));
|
||||
ent->solid = SOLID_NOT;
|
||||
}
|
||||
}
|
||||
|
||||
if (ent->tright)
|
||||
{
|
||||
VectorCopy (ent->tright, ent->maxs);
|
||||
}
|
||||
else
|
||||
{
|
||||
if (ent->solid != SOLID_NOT)
|
||||
{
|
||||
gi.dprintf("%s solid with no tright vector at %s\n", ent->classname, vtos(ent->s.origin));
|
||||
ent->solid = SOLID_NOT;
|
||||
}
|
||||
}
|
||||
|
||||
// if (ent->movewith && (ent->solid == SOLID_BBOX))
|
||||
// if (ent->movewith)
|
||||
// ent->movetype = MOVETYPE_PUSH;
|
||||
|
||||
if (ent->solid != SOLID_NOT)
|
||||
ent->clipmask = CONTENTS_SOLID|CONTENTS_PLAYERCLIP|CONTENTS_MONSTERCLIP|CONTENTS_WINDOW|CONTENTS_MONSTER;
|
||||
|
||||
if (ent->spawnflags & NO_MODEL)
|
||||
{ // For rendering effects to work, we MUST use a model
|
||||
ent->s.modelindex = gi.modelindex ("sprites/point.sp2");
|
||||
ent->movetype = MOVETYPE_NOCLIP;
|
||||
}
|
||||
else
|
||||
{
|
||||
if (ent->spawnflags & PLAYER_MODEL) {
|
||||
if (!ent->usermodel || !strlen(ent->usermodel))
|
||||
ent->s.modelindex = MAX_MODELS-1;
|
||||
else
|
||||
{
|
||||
if (strstr(ent->usermodel,"tris.md2"))
|
||||
Com_sprintf(modelname, sizeof(modelname), "players/%s", ent->usermodel);
|
||||
else
|
||||
Com_sprintf(modelname, sizeof(modelname), "players/%s/tris.md2", ent->usermodel);
|
||||
ent->s.modelindex = gi.modelindex(modelname);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
if (strstr(ent->usermodel,".sp2")) {
|
||||
// Knightmare- check for "sprites/" already in path
|
||||
if ( !strncmp(ent->usermodel, "sprites/", 8) )
|
||||
Com_sprintf(modelname, sizeof(modelname), "%s", ent->usermodel);
|
||||
else
|
||||
Com_sprintf(modelname, sizeof(modelname), "sprites/%s", ent->usermodel);
|
||||
}
|
||||
else {
|
||||
// Knightmare- check for "models/" already in path
|
||||
if ( !strncmp(ent->usermodel, "models/", 7) )
|
||||
Com_sprintf(modelname, sizeof(modelname), "%s", ent->usermodel);
|
||||
else
|
||||
Com_sprintf(modelname, sizeof(modelname), "models/%s", ent->usermodel);
|
||||
}
|
||||
ent->s.modelindex = gi.modelindex (modelname);
|
||||
}
|
||||
ent->s.frame = ent->startframe;
|
||||
}
|
||||
|
||||
if (st.noise)
|
||||
ent->noise_index = gi.soundindex (st.noise);
|
||||
ent->s.sound = ent->noise_index;
|
||||
#ifdef LOOP_SOUND_ATTENUATION
|
||||
ent->s.attenuation = ent->attenuation;
|
||||
#endif
|
||||
|
||||
// if (ent->skinnum) // Knightmare- selectable skin
|
||||
// ent->s.skinnum = ent->skinnum;
|
||||
|
||||
if (ent->spawnflags & ANIM_ONCE)
|
||||
ent->spawnflags |= TOGGLE;
|
||||
|
||||
if (ent->spawnflags & TOGGLE)
|
||||
{
|
||||
ent->delay = 0;
|
||||
ent->use = model_spawn_use;
|
||||
}
|
||||
|
||||
if (!(ent->s.effects & ANIM_MASK) && (ent->framenumbers > 1))
|
||||
{
|
||||
ent->think = modelspawn_think;
|
||||
ent->nextthink = level.time + 2*FRAMETIME;
|
||||
}
|
||||
gi.linkentity (ent);
|
||||
}
|
426
awaken2/g_monster.c
Normal file
426
awaken2/g_monster.c
Normal file
|
@ -0,0 +1,426 @@
|
|||
// g_monster.c
|
||||
|
||||
#include "g_local.h"
|
||||
|
||||
#define STEPSIZE 18 //CW
|
||||
|
||||
/*
|
||||
===============
|
||||
M_CheckGround
|
||||
===============
|
||||
*/
|
||||
void M_CheckGround(edict_t *ent)
|
||||
{
|
||||
vec3_t point;
|
||||
trace_t trace;
|
||||
|
||||
if (ent->flags & (FL_SWIM|FL_FLY))
|
||||
return;
|
||||
|
||||
//Maj++
|
||||
ResetGroundSlope(ent);
|
||||
//Maj--
|
||||
|
||||
if (ent->velocity[2] > 100.0)
|
||||
{
|
||||
ent->groundentity = NULL;
|
||||
return;
|
||||
}
|
||||
|
||||
// if the hull point one-quarter unit down is solid the entity is on ground
|
||||
point[0] = ent->s.origin[0];
|
||||
point[1] = ent->s.origin[1];
|
||||
point[2] = ent->s.origin[2] - 0.25;
|
||||
|
||||
trace = gi.trace(ent->s.origin, ent->mins, ent->maxs, point, ent, MASK_MONSTERSOLID);
|
||||
|
||||
// check steepness
|
||||
if ((trace.plane.normal[2] < 0.7) && !trace.startsolid)
|
||||
{
|
||||
ent->groundentity = NULL;
|
||||
return;
|
||||
}
|
||||
|
||||
/* //Maj - code superseded
|
||||
if (!trace.startsolid && !trace.allsolid)
|
||||
{
|
||||
VectorCopy(trace.endpos, ent->s.origin);
|
||||
ent->groundentity = trace.ent;
|
||||
ent->groundentity_linkcount = trace.ent->linkcount;
|
||||
ent->velocity[2] = 0.0;
|
||||
}
|
||||
*/
|
||||
|
||||
//Maj++
|
||||
TraceAllSolid(ent, point, trace);
|
||||
//Maj--
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
===============
|
||||
M_CatagorizePosition
|
||||
===============
|
||||
*/
|
||||
void M_CatagorizePosition(edict_t *ent)
|
||||
{
|
||||
vec3_t point;
|
||||
int cont;
|
||||
|
||||
// Get the current waterlevel.
|
||||
|
||||
point[0] = ent->s.origin[0];
|
||||
point[1] = ent->s.origin[1];
|
||||
point[2] = ent->s.origin[2] + ent->mins[2] + 1.0;
|
||||
cont = gi.pointcontents(point);
|
||||
|
||||
if (!(cont & MASK_WATER))
|
||||
{
|
||||
ent->waterlevel = 0;
|
||||
ent->watertype = 0;
|
||||
return;
|
||||
}
|
||||
|
||||
ent->watertype = cont;
|
||||
ent->waterlevel = 1;
|
||||
point[2] += 26.0;
|
||||
cont = gi.pointcontents(point);
|
||||
if (!(cont & MASK_WATER))
|
||||
return;
|
||||
|
||||
ent->waterlevel = 2;
|
||||
point[2] += 22.0;
|
||||
cont = gi.pointcontents(point);
|
||||
if (cont & MASK_WATER)
|
||||
ent->waterlevel = 3;
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
===============
|
||||
M_DropToFloor
|
||||
===============
|
||||
*/
|
||||
void M_DropToFloor(edict_t *ent)
|
||||
{
|
||||
vec3_t end;
|
||||
trace_t trace;
|
||||
|
||||
ent->s.origin[2] += 1.0;
|
||||
VectorCopy(ent->s.origin, end);
|
||||
end[2] -= 256.0;
|
||||
|
||||
trace = gi.trace(ent->s.origin, ent->mins, ent->maxs, end, ent, MASK_MONSTERSOLID);
|
||||
|
||||
if ((trace.fraction == 1.0) || trace.allsolid)
|
||||
return;
|
||||
|
||||
VectorCopy(trace.endpos, ent->s.origin);
|
||||
gi.linkentity(ent);
|
||||
|
||||
M_CheckGround(ent);
|
||||
M_CatagorizePosition(ent);
|
||||
}
|
||||
|
||||
/*
|
||||
=============
|
||||
M_CheckBottom
|
||||
|
||||
Returns false if any part of the bottom of the entity is off an edge that
|
||||
is not a staircase.
|
||||
=============
|
||||
*/
|
||||
qboolean M_CheckBottom(edict_t *ent) //CW
|
||||
{
|
||||
vec3_t mins;
|
||||
vec3_t maxs;
|
||||
vec3_t start;
|
||||
vec3_t stop;
|
||||
trace_t trace;
|
||||
float mid;
|
||||
float bottom;
|
||||
int x;
|
||||
int y;
|
||||
|
||||
VectorAdd(ent->s.origin, ent->mins, mins);
|
||||
VectorAdd(ent->s.origin, ent->maxs, maxs);
|
||||
|
||||
// If all of the points under the corners are solid world, don't bother
|
||||
// with the tougher checks; the corners must be within 16 units of the midpoint.
|
||||
|
||||
start[2] = mins[2] - 1;
|
||||
for (x = 0; x <= 1; x++)
|
||||
{
|
||||
for (y = 0; y <= 1; y++)
|
||||
{
|
||||
start[0] = (x) ? maxs[0] : mins[0];
|
||||
start[1] = (y) ? maxs[1] : mins[1];
|
||||
if (gi.pointcontents(start) != CONTENTS_SOLID)
|
||||
goto realcheck;
|
||||
}
|
||||
}
|
||||
|
||||
return true; // we got out easy
|
||||
|
||||
realcheck:
|
||||
// Check it for real...
|
||||
|
||||
start[2] = mins[2];
|
||||
|
||||
// The midpoint must be within 16 units of the bottom.
|
||||
|
||||
start[0] = stop[0] = (mins[0] + maxs[0]) * 0.5;
|
||||
start[1] = stop[1] = (mins[1] + maxs[1]) * 0.5;
|
||||
stop[2] = start[2] - 2 * STEPSIZE;
|
||||
trace = gi.trace(start, vec3_origin, vec3_origin, stop, ent, MASK_MONSTERSOLID);
|
||||
|
||||
if (trace.fraction == 1.0)
|
||||
return false;
|
||||
|
||||
mid = bottom = trace.endpos[2];
|
||||
|
||||
// The corners must be within 16 units of the midpoint.
|
||||
|
||||
for (x = 0; x <= 1; x++)
|
||||
{
|
||||
for (y = 0; y <= 1; y++)
|
||||
{
|
||||
start[0] = stop[0] = x ? maxs[0] : mins[0];
|
||||
start[1] = stop[1] = y ? maxs[1] : mins[1];
|
||||
trace = gi.trace(start, vec3_origin, vec3_origin, stop, ent, MASK_MONSTERSOLID);
|
||||
if ((trace.fraction != 1.0) && (trace.endpos[2] > bottom))
|
||||
bottom = trace.endpos[2];
|
||||
|
||||
if ((trace.fraction == 1.0) || (mid - trace.endpos[2] > STEPSIZE))
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
=============
|
||||
SV_MoveStep
|
||||
|
||||
Called by monster program code.
|
||||
The move will be adjusted for slopes and stairs, but if the move isn't
|
||||
possible, no move is done, false is returned, and
|
||||
pr_global_struct->trace_normal is set to the normal of the blocking wall
|
||||
=============
|
||||
*/
|
||||
//FIXME since we need to test end position contents here, can we avoid doing
|
||||
//it again later in catagorize position?
|
||||
|
||||
qboolean SV_MoveStep(edict_t *ent, vec3_t move, qboolean relink) //CW
|
||||
{
|
||||
trace_t trace;
|
||||
vec3_t oldorg;
|
||||
vec3_t neworg;
|
||||
vec3_t end;
|
||||
vec3_t test;
|
||||
float dz;
|
||||
float stepsize;
|
||||
int contents;
|
||||
int i;
|
||||
|
||||
// Try the move.
|
||||
|
||||
VectorCopy(ent->s.origin, oldorg);
|
||||
VectorAdd(ent->s.origin, move, neworg);
|
||||
|
||||
// Flying monsters don't step up.
|
||||
|
||||
if (ent->flags & (FL_SWIM | FL_FLY))
|
||||
{
|
||||
|
||||
// try one move with vertical motion, then one without
|
||||
for (i = 0; i < 2; i++)
|
||||
{
|
||||
VectorAdd(ent->s.origin, move, neworg);
|
||||
if ((i == 0) && ent->enemy)
|
||||
{
|
||||
if (!ent->goalentity)
|
||||
ent->goalentity = ent->enemy;
|
||||
dz = ent->s.origin[2] - ent->goalentity->s.origin[2];
|
||||
if (ent->goalentity->client)
|
||||
{
|
||||
if (dz > 40.0)
|
||||
neworg[2] -= 8.0;
|
||||
|
||||
if (!((ent->flags & FL_SWIM) && (ent->waterlevel < 2)))
|
||||
if (dz < 30.0)
|
||||
neworg[2] += 8.0;
|
||||
}
|
||||
else
|
||||
{
|
||||
if (dz > 8.0)
|
||||
neworg[2] -= 8.0;
|
||||
else if (dz > 0.0)
|
||||
neworg[2] -= dz;
|
||||
else if (dz < -8.0)
|
||||
neworg[2] += 8.0;
|
||||
else
|
||||
neworg[2] += dz;
|
||||
}
|
||||
}
|
||||
trace = gi.trace(ent->s.origin, ent->mins, ent->maxs, neworg, ent, MASK_MONSTERSOLID);
|
||||
|
||||
// fly monsters don't enter water voluntarily
|
||||
if (ent->flags & FL_FLY)
|
||||
{
|
||||
if (!ent->waterlevel)
|
||||
{
|
||||
test[0] = trace.endpos[0];
|
||||
test[1] = trace.endpos[1];
|
||||
test[2] = trace.endpos[2] + ent->mins[2] + 1.0;
|
||||
contents = gi.pointcontents(test);
|
||||
if (contents & MASK_WATER)
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
// swim monsters don't exit water voluntarily
|
||||
if (ent->flags & FL_SWIM)
|
||||
{
|
||||
if (ent->waterlevel < 2)
|
||||
{
|
||||
test[0] = trace.endpos[0];
|
||||
test[1] = trace.endpos[1];
|
||||
test[2] = trace.endpos[2] + ent->mins[2] + 1.0;
|
||||
contents = gi.pointcontents(test);
|
||||
if (!(contents & MASK_WATER))
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
if (trace.fraction == 1.0)
|
||||
{
|
||||
VectorCopy(trace.endpos, ent->s.origin);
|
||||
if (relink)
|
||||
{
|
||||
gi.linkentity(ent);
|
||||
G_TouchTriggers(ent);
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
if (!ent->enemy)
|
||||
break;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
// Push down from a step height above the wished position.
|
||||
|
||||
if (!(ent->monsterinfo.aiflags & AI_NOSTEP))
|
||||
stepsize = STEPSIZE;
|
||||
else
|
||||
stepsize = 1;
|
||||
|
||||
neworg[2] += stepsize;
|
||||
VectorCopy(neworg, end);
|
||||
end[2] -= stepsize * 2.0;
|
||||
|
||||
trace = gi.trace(neworg, ent->mins, ent->maxs, end, ent, MASK_MONSTERSOLID);
|
||||
|
||||
if (trace.allsolid)
|
||||
return false;
|
||||
|
||||
if (trace.startsolid)
|
||||
{
|
||||
neworg[2] -= stepsize;
|
||||
trace = gi.trace(neworg, ent->mins, ent->maxs, end, ent, MASK_MONSTERSOLID);
|
||||
if (trace.allsolid || trace.startsolid)
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
// Don't go into water.
|
||||
|
||||
if (ent->waterlevel == 0)
|
||||
{
|
||||
test[0] = trace.endpos[0];
|
||||
test[1] = trace.endpos[1];
|
||||
test[2] = trace.endpos[2] + ent->mins[2] + 1.0;
|
||||
contents = gi.pointcontents(test);
|
||||
|
||||
if (contents & MASK_WATER)
|
||||
return false;
|
||||
}
|
||||
|
||||
if (trace.fraction == 1.0)
|
||||
{
|
||||
// if monster had the ground pulled out, go ahead and fall
|
||||
if (ent->flags & FL_PARTIALGROUND)
|
||||
{
|
||||
VectorAdd(ent->s.origin, move, ent->s.origin);
|
||||
if (relink)
|
||||
{
|
||||
gi.linkentity(ent);
|
||||
G_TouchTriggers(ent);
|
||||
}
|
||||
ent->groundentity = NULL;
|
||||
return true;
|
||||
}
|
||||
|
||||
return false; // walked off an edge
|
||||
}
|
||||
|
||||
// Check point traces down for dangling corners.
|
||||
|
||||
VectorCopy(trace.endpos, ent->s.origin);
|
||||
|
||||
if (!M_CheckBottom(ent))
|
||||
{
|
||||
if (ent->flags & FL_PARTIALGROUND)
|
||||
{ // entity had floor mostly pulled out from underneath it and is trying to correct
|
||||
if (relink)
|
||||
{
|
||||
gi.linkentity(ent);
|
||||
G_TouchTriggers(ent);
|
||||
}
|
||||
return true;
|
||||
}
|
||||
VectorCopy(oldorg, ent->s.origin);
|
||||
return false;
|
||||
}
|
||||
|
||||
if (ent->flags & FL_PARTIALGROUND)
|
||||
ent->flags &= ~FL_PARTIALGROUND;
|
||||
|
||||
ent->groundentity = trace.ent;
|
||||
ent->groundentity_linkcount = trace.ent->linkcount;
|
||||
|
||||
// The move is OK.
|
||||
|
||||
if (relink)
|
||||
{
|
||||
gi.linkentity(ent);
|
||||
G_TouchTriggers(ent);
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
/*
|
||||
===============
|
||||
M_WalkMove
|
||||
===============
|
||||
*/
|
||||
qboolean M_WalkMove(edict_t *ent, float yaw, float dist) //CW
|
||||
{
|
||||
vec3_t move;
|
||||
|
||||
if (!ent->groundentity && !(ent->flags & (FL_FLY|FL_SWIM)))
|
||||
return false;
|
||||
|
||||
yaw = DEG2RAD(yaw); //CW
|
||||
move[0] = cos(yaw) * dist;
|
||||
move[1] = sin(yaw) * dist;
|
||||
move[2] = 0.0;
|
||||
|
||||
return SV_MoveStep(ent, move, true);
|
||||
}
|
165
awaken2/g_mtrain.c
Normal file
165
awaken2/g_mtrain.c
Normal file
|
@ -0,0 +1,165 @@
|
|||
/*
|
||||
Copyright (C) 1997-2001 Id Software, Inc.
|
||||
Copyright (C) 2000-2002 Mr. Hyde and Mad Dog
|
||||
|
||||
This program is free software; you can redistribute it and/or
|
||||
modify it under the terms of the GNU General Public License
|
||||
as published by the Free Software Foundation; either version 2
|
||||
of the License, or (at your option) any later version.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
|
||||
|
||||
See the GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with this program; if not, write to the Free Software
|
||||
Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
|
||||
|
||||
*/
|
||||
|
||||
#include "g_local.h"
|
||||
|
||||
void func_train_find (edict_t *self);
|
||||
void SP_model_spawn (edict_t *ent);
|
||||
void train_blocked (edict_t *self, edict_t *other);
|
||||
void train_die (edict_t *self, edict_t *inflictor, edict_t *attacker, int damage, vec3_t point);
|
||||
void train_use (edict_t *self, edict_t *other, edict_t *activator);
|
||||
|
||||
#define TRAIN_START_ON 1
|
||||
#define TRAIN_TOGGLE 2
|
||||
#define TRAIN_BLOCK_STOPS 4
|
||||
#define PLAYER_MODEL 8
|
||||
#define NO_MODEL 16
|
||||
#define MTRAIN_ROTATE 32
|
||||
#define MTRAIN_ROTATE_CONSTANT 64
|
||||
#define TRAIN_SMOOTH 128
|
||||
|
||||
void model_train_animator(edict_t *animator)
|
||||
{
|
||||
edict_t *train;
|
||||
|
||||
train = animator->owner;
|
||||
if (!train || !train->inuse)
|
||||
{
|
||||
G_FreeEdict(animator);
|
||||
return;
|
||||
}
|
||||
if (Q_stricmp(train->classname,"model_train"))
|
||||
{
|
||||
G_FreeEdict(animator);
|
||||
return;
|
||||
}
|
||||
animator->nextthink = level.time + FRAMETIME;
|
||||
if (VectorLength(train->velocity) == 0)
|
||||
return;
|
||||
train->s.frame++;
|
||||
if (train->s.frame >= train->framenumbers)
|
||||
train->s.frame = train->startframe;
|
||||
gi.linkentity(train);
|
||||
}
|
||||
|
||||
void SP_model_train (edict_t *self)
|
||||
{
|
||||
SP_model_spawn (self);
|
||||
|
||||
// self->class_id = ENTITY_MODEL_TRAIN;
|
||||
|
||||
// Reset s.sound, which SP_model_spawn may have turned on
|
||||
self->moveinfo.sound_middle = self->s.sound;
|
||||
self->s.sound = 0;
|
||||
|
||||
if (!self->inuse) return;
|
||||
|
||||
// Reset some things from SP_model_spawn
|
||||
self->delay = 0;
|
||||
self->think = NULL;
|
||||
self->nextthink = 0;
|
||||
if (self->health)
|
||||
{
|
||||
self->die = train_die;
|
||||
self->takedamage = DAMAGE_YES;
|
||||
}
|
||||
|
||||
if (self->framenumbers > self->startframe+1)
|
||||
{
|
||||
edict_t *animator;
|
||||
animator = G_Spawn();
|
||||
animator->owner = self;
|
||||
animator->think = model_train_animator;
|
||||
animator->nextthink = level.time + FRAMETIME;
|
||||
}
|
||||
self->s.frame = self->startframe;
|
||||
self->movetype = MOVETYPE_PUSH;
|
||||
|
||||
// Really gross stuff here... translate model_spawn spawnflags
|
||||
// to func_train spawnflags. PLAYER_MODEL and NO_MODEL have
|
||||
// already been checked in SP_model_spawn and are never re-used,
|
||||
// so it's OK to overwrite those.
|
||||
if (self->spawnflags & MTRAIN_ROTATE)
|
||||
{
|
||||
self->spawnflags &= ~MTRAIN_ROTATE;
|
||||
self->spawnflags |= TRAIN_ROTATE;
|
||||
}
|
||||
if (self->spawnflags & MTRAIN_ROTATE_CONSTANT)
|
||||
{
|
||||
self->spawnflags &= ~MTRAIN_ROTATE_CONSTANT;
|
||||
self->spawnflags |= TRAIN_ROTATE_CONSTANT;
|
||||
}
|
||||
if ( (self->spawnflags & (TRAIN_ROTATE | TRAIN_ROTATE_CONSTANT)) == (TRAIN_ROTATE | TRAIN_ROTATE_CONSTANT))
|
||||
{
|
||||
self->spawnflags &= ~(TRAIN_ROTATE | TRAIN_ROTATE_CONSTANT);
|
||||
self->spawnflags |= TRAIN_SPLINE;
|
||||
}
|
||||
if (self->style == 3)
|
||||
self->spawnflags |= TRAIN_ANIMATE; // 32
|
||||
if (self->style == 4)
|
||||
self->spawnflags |= TRAIN_ANIMATE_FAST; // 64
|
||||
|
||||
// TRAIN_SMOOTH forces trains to go directly to Move_Done from
|
||||
// Move_Final rather than slowing down (if necessary) for one
|
||||
// frame.
|
||||
if (self->spawnflags & TRAIN_SMOOTH)
|
||||
self->smooth_movement = true;
|
||||
else
|
||||
self->smooth_movement = false;
|
||||
|
||||
self->blocked = train_blocked;
|
||||
if (self->spawnflags & TRAIN_BLOCK_STOPS)
|
||||
self->dmg = 0;
|
||||
else
|
||||
{
|
||||
if (!self->dmg)
|
||||
self->dmg = 100;
|
||||
}
|
||||
|
||||
if (!self->speed)
|
||||
self->speed = 100;
|
||||
|
||||
self->moveinfo.speed = self->speed;
|
||||
self->moveinfo.accel = self->moveinfo.decel = self->moveinfo.speed;
|
||||
|
||||
self->use = train_use;
|
||||
|
||||
gi.linkentity (self);
|
||||
|
||||
if (self->target)
|
||||
{
|
||||
// start trains on the second frame, to make sure their targets have had
|
||||
// a chance to spawn
|
||||
self->nextthink = level.time + FRAMETIME;
|
||||
self->think = func_train_find;
|
||||
}
|
||||
else
|
||||
{
|
||||
gi.dprintf ("model_train without a target at %s\n", vtos(self->absmin));
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
void SP_model_train_origin (edict_t *self)
|
||||
{
|
||||
self->spawnflags |= TRAIN_ORIGIN;
|
||||
SP_model_train (self);
|
||||
}
|
347
awaken2/g_newfnc.c
Normal file
347
awaken2/g_newfnc.c
Normal file
|
@ -0,0 +1,347 @@
|
|||
#include "g_local.h"
|
||||
|
||||
//void plat_CalcMove (edict_t *ent, vec3_t dest, void(*func)(edict_t*));
|
||||
void Move_Calc (edict_t *ent, vec3_t dest, void(*func)(edict_t*));
|
||||
|
||||
void fd_secret_move1(edict_t *self);
|
||||
void fd_secret_move2(edict_t *self);
|
||||
void fd_secret_move3(edict_t *self);
|
||||
void fd_secret_move4(edict_t *self);
|
||||
void fd_secret_move5(edict_t *self);
|
||||
void fd_secret_move6(edict_t *self);
|
||||
void fd_secret_done(edict_t *self);
|
||||
|
||||
/*
|
||||
=============================================================================
|
||||
|
||||
SECRET DOORS
|
||||
|
||||
=============================================================================
|
||||
*/
|
||||
|
||||
#define SEC_OPEN_ONCE 1 // stays open
|
||||
#define SEC_1ST_LEFT 2 // 1st move is left of arrow
|
||||
#define SEC_1ST_DOWN 4 // 1st move is down from arrow
|
||||
#define SEC_NO_SHOOT 8 // only opened by trigger
|
||||
#define SEC_YES_SHOOT 16 // shootable even if targeted
|
||||
#define SEC_MOVE_RIGHT 32
|
||||
#define SEC_MOVE_FORWARD 64
|
||||
|
||||
void fd_secret_use (edict_t *self, edict_t *other, edict_t *activator)
|
||||
{
|
||||
edict_t *ent;
|
||||
|
||||
// gi.dprintf("fd_secret_use\n");
|
||||
if (self->flags & FL_TEAMSLAVE)
|
||||
return;
|
||||
|
||||
// trigger all paired doors
|
||||
for (ent = self ; ent ; ent = ent->teamchain)
|
||||
Move_Calc(ent, ent->moveinfo.start_origin, fd_secret_move1);
|
||||
|
||||
}
|
||||
|
||||
void fd_secret_killed (edict_t *self, edict_t *inflictor, edict_t *attacker, int damage, vec3_t point)
|
||||
{
|
||||
// gi.dprintf("fd_secret_killed\n");
|
||||
self->health = self->max_health;
|
||||
self->takedamage = DAMAGE_NO;
|
||||
|
||||
if (self->flags & FL_TEAMSLAVE && self->teammaster && self->teammaster->takedamage != DAMAGE_NO)
|
||||
fd_secret_killed (self->teammaster, inflictor, attacker, damage, point);
|
||||
else
|
||||
fd_secret_use (self, inflictor, attacker);
|
||||
}
|
||||
|
||||
// Wait after first movement...
|
||||
void fd_secret_move1(edict_t *self)
|
||||
{
|
||||
// gi.dprintf("fd_secret_move1\n");
|
||||
self->nextthink = level.time + 1.0;
|
||||
self->think = fd_secret_move2;
|
||||
}
|
||||
|
||||
// Start moving sideways w/sound...
|
||||
void fd_secret_move2(edict_t *self)
|
||||
{
|
||||
// gi.dprintf("fd_secret_move2\n");
|
||||
Move_Calc(self, self->moveinfo.end_origin, fd_secret_move3);
|
||||
}
|
||||
|
||||
// Wait here until time to go back...
|
||||
void fd_secret_move3(edict_t *self)
|
||||
{
|
||||
// gi.dprintf("fd_secret_move3\n");
|
||||
if (!(self->spawnflags & SEC_OPEN_ONCE))
|
||||
{
|
||||
self->nextthink = level.time + self->wait;
|
||||
self->think = fd_secret_move4;
|
||||
}
|
||||
}
|
||||
|
||||
// Move backward...
|
||||
void fd_secret_move4(edict_t *self)
|
||||
{
|
||||
// gi.dprintf("fd_secret_move4\n");
|
||||
Move_Calc(self, self->moveinfo.start_origin, fd_secret_move5);
|
||||
}
|
||||
|
||||
// Wait 1 second...
|
||||
void fd_secret_move5(edict_t *self)
|
||||
{
|
||||
// gi.dprintf("fd_secret_move5\n");
|
||||
self->nextthink = level.time + 1.0;
|
||||
self->think = fd_secret_move6;
|
||||
}
|
||||
|
||||
void fd_secret_move6(edict_t *self)
|
||||
{
|
||||
// gi.dprintf("fd_secret_move6\n");
|
||||
Move_Calc(self, self->move_origin, fd_secret_done);
|
||||
}
|
||||
|
||||
void fd_secret_done(edict_t *self)
|
||||
{
|
||||
// gi.dprintf("fd_secret_done\n");
|
||||
if (!self->targetname || self->spawnflags & SEC_YES_SHOOT)
|
||||
{
|
||||
self->health = 1;
|
||||
self->takedamage = DAMAGE_YES;
|
||||
self->die = fd_secret_killed;
|
||||
}
|
||||
}
|
||||
|
||||
void secret_blocked(edict_t *self, edict_t *other)
|
||||
{
|
||||
if (!(self->flags & FL_TEAMSLAVE))
|
||||
T_Damage (other, self, self, vec3_origin, other->s.origin, vec3_origin, self->dmg, 0, 0, MOD_CRUSH);
|
||||
|
||||
// if (time < self->attack_finished)
|
||||
// return;
|
||||
// self->attack_finished = time + 0.5;
|
||||
// T_Damage (other, self, self, self->dmg);
|
||||
}
|
||||
|
||||
/*
|
||||
================
|
||||
secret_touch
|
||||
|
||||
Prints messages
|
||||
================
|
||||
*/
|
||||
void secret_touch(edict_t *self, edict_t *other, cplane_t *plane, csurface_t *surf)
|
||||
{
|
||||
if (other->health <= 0)
|
||||
return;
|
||||
|
||||
if (!(other->client))
|
||||
return;
|
||||
|
||||
if (self->monsterinfo.attack_finished > level.time)
|
||||
return;
|
||||
|
||||
self->monsterinfo.attack_finished = level.time + 2;
|
||||
|
||||
if (self->message)
|
||||
{
|
||||
gi.centerprintf (other, self->message);
|
||||
// fixme - put this sound back??
|
||||
// gi.sound (other, CHAN_BODY, "misc/talk.wav", 1, ATTN_NORM);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/*QUAKED func_door_secret2 (0 .5 .8) ? open_once 1st_left 1st_down no_shoot always_shoot slide_right slide_forward
|
||||
Basic secret door. Slides back, then to the left. Angle determines direction.
|
||||
|
||||
FLAGS:
|
||||
open_once = not implemented yet
|
||||
1st_left = 1st move is left/right of arrow
|
||||
1st_down = 1st move is forwards/backwards
|
||||
no_shoot = not implemented yet
|
||||
always_shoot = even if targeted, keep shootable
|
||||
reverse_left = the sideways move will be to right of arrow
|
||||
reverse_back = the to/fro move will be forward
|
||||
|
||||
VALUES:
|
||||
wait = # of seconds before coming back (5 default)
|
||||
dmg = damage to inflict when blocked (2 default)
|
||||
|
||||
*/
|
||||
|
||||
void SP_func_door_secret2 (edict_t *ent)
|
||||
{
|
||||
vec3_t forward,right,up;
|
||||
float lrSize, fbSize;
|
||||
|
||||
ent->moveinfo.sound_start = gi.soundindex ("doors/dr1_strt.wav");
|
||||
ent->moveinfo.sound_middle = gi.soundindex ("doors/dr1_mid.wav");
|
||||
ent->moveinfo.sound_end = gi.soundindex ("doors/dr1_end.wav");
|
||||
|
||||
if (!ent->dmg)
|
||||
ent->dmg = 2;
|
||||
|
||||
AngleVectors(ent->s.angles, forward, right, up);
|
||||
VectorCopy(ent->s.origin, ent->move_origin);
|
||||
VectorCopy(ent->s.angles, ent->move_angles);
|
||||
|
||||
G_SetMovedir (ent->s.angles, ent->movedir);
|
||||
ent->movetype = MOVETYPE_PUSH;
|
||||
ent->solid = SOLID_BSP;
|
||||
gi.setmodel (ent, ent->model);
|
||||
|
||||
if(ent->move_angles[1] == 0 || ent->move_angles[1] == 180)
|
||||
{
|
||||
lrSize = ent->size[1];
|
||||
fbSize = ent->size[0];
|
||||
}
|
||||
else if(ent->move_angles[1] == 90 || ent->move_angles[1] == 270)
|
||||
{
|
||||
lrSize = ent->size[0];
|
||||
fbSize = ent->size[1];
|
||||
}
|
||||
else
|
||||
{
|
||||
gi.dprintf("Secret door not at 0,90,180,270!\n");
|
||||
}
|
||||
|
||||
if(ent->spawnflags & SEC_MOVE_FORWARD)
|
||||
VectorScale(forward, fbSize, forward);
|
||||
else
|
||||
{
|
||||
VectorScale(forward, fbSize * -1 , forward);
|
||||
}
|
||||
|
||||
if(ent->spawnflags & SEC_MOVE_RIGHT)
|
||||
VectorScale(right, lrSize, right);
|
||||
else
|
||||
{
|
||||
VectorScale(right, lrSize * -1, right);
|
||||
}
|
||||
|
||||
if(ent->spawnflags & SEC_1ST_DOWN)
|
||||
{
|
||||
VectorAdd(ent->s.origin, forward, ent->moveinfo.start_origin);
|
||||
VectorAdd(ent->moveinfo.start_origin, right, ent->moveinfo.end_origin);
|
||||
}
|
||||
else
|
||||
{
|
||||
VectorAdd(ent->s.origin, right, ent->moveinfo.start_origin);
|
||||
VectorAdd(ent->moveinfo.start_origin, forward, ent->moveinfo.end_origin);
|
||||
}
|
||||
|
||||
ent->touch = secret_touch;
|
||||
ent->blocked = secret_blocked;
|
||||
ent->use = fd_secret_use;
|
||||
ent->moveinfo.speed = 50;
|
||||
ent->moveinfo.accel = 50;
|
||||
ent->moveinfo.decel = 50;
|
||||
|
||||
if (!ent->targetname || ent->spawnflags & SEC_YES_SHOOT)
|
||||
{
|
||||
ent->health = 1;
|
||||
ent->max_health = ent->health;
|
||||
ent->takedamage = DAMAGE_YES;
|
||||
ent->die = fd_secret_killed;
|
||||
}
|
||||
if (!ent->wait)
|
||||
ent->wait = 5; // 5 seconds before closing
|
||||
|
||||
gi.linkentity(ent);
|
||||
}
|
||||
|
||||
// ==================================================
|
||||
|
||||
#define FWALL_START_ON 1
|
||||
|
||||
void force_wall_think(edict_t *self)
|
||||
{
|
||||
if(!self->wait)
|
||||
{
|
||||
gi.WriteByte (svc_temp_entity);
|
||||
gi.WriteByte (TE_FORCEWALL);
|
||||
gi.WritePosition (self->pos1);
|
||||
gi.WritePosition (self->pos2);
|
||||
gi.WriteByte (self->style);
|
||||
gi.multicast (self->offset, MULTICAST_PVS);
|
||||
}
|
||||
|
||||
self->think = force_wall_think;
|
||||
self->nextthink = level.time + 0.1;
|
||||
}
|
||||
|
||||
void force_wall_use (edict_t *self, edict_t *other, edict_t *activator)
|
||||
{
|
||||
if(!self->wait)
|
||||
{
|
||||
self->wait = 1;
|
||||
self->think = NULL;
|
||||
self->nextthink = 0;
|
||||
self->solid = SOLID_NOT;
|
||||
gi.linkentity( self );
|
||||
}
|
||||
else
|
||||
{
|
||||
self->wait = 0;
|
||||
self->think = force_wall_think;
|
||||
self->nextthink = level.time + 0.1;
|
||||
self->solid = SOLID_BSP;
|
||||
KillBox(self); // Is this appropriate?
|
||||
gi.linkentity (self);
|
||||
}
|
||||
}
|
||||
|
||||
/*QUAKED func_force_wall (1 0 1) ? start_on
|
||||
A vertical particle force wall. Turns on and solid when triggered.
|
||||
If someone is in the force wall when it turns on, they're telefragged.
|
||||
|
||||
start_on - forcewall begins activated. triggering will turn it off.
|
||||
style - color of particles to use.
|
||||
208: green, 240: red, 241: blue, 224: orange
|
||||
*/
|
||||
void SP_func_force_wall(edict_t *ent)
|
||||
{
|
||||
gi.setmodel (ent, ent->model);
|
||||
|
||||
ent->offset[0] = (ent->absmax[0] + ent->absmin[0]) / 2;
|
||||
ent->offset[1] = (ent->absmax[1] + ent->absmin[1]) / 2;
|
||||
ent->offset[2] = (ent->absmax[2] + ent->absmin[2]) / 2;
|
||||
|
||||
ent->pos1[2] = ent->absmax[2];
|
||||
ent->pos2[2] = ent->absmax[2];
|
||||
if(ent->size[0] > ent->size[1])
|
||||
{
|
||||
ent->pos1[0] = ent->absmin[0];
|
||||
ent->pos2[0] = ent->absmax[0];
|
||||
ent->pos1[1] = ent->offset[1];
|
||||
ent->pos2[1] = ent->offset[1];
|
||||
}
|
||||
else
|
||||
{
|
||||
ent->pos1[0] = ent->offset[0];
|
||||
ent->pos2[0] = ent->offset[0];
|
||||
ent->pos1[1] = ent->absmin[1];
|
||||
ent->pos2[1] = ent->absmax[1];
|
||||
}
|
||||
|
||||
if(!ent->style)
|
||||
ent->style = 208;
|
||||
|
||||
ent->movetype = MOVETYPE_NONE;
|
||||
ent->wait = 1;
|
||||
|
||||
if(ent->spawnflags & FWALL_START_ON)
|
||||
{
|
||||
ent->solid = SOLID_BSP;
|
||||
ent->think = force_wall_think;
|
||||
ent->nextthink = level.time + 0.1;
|
||||
}
|
||||
else
|
||||
ent->solid = SOLID_NOT;
|
||||
|
||||
ent->use = force_wall_use;
|
||||
|
||||
ent->svflags = SVF_NOCLIENT;
|
||||
|
||||
gi.linkentity(ent);
|
||||
}
|
1425
awaken2/g_phys.c
Normal file
1425
awaken2/g_phys.c
Normal file
File diff suppressed because it is too large
Load diff
1262
awaken2/g_save.c
Normal file
1262
awaken2/g_save.c
Normal file
File diff suppressed because it is too large
Load diff
1455
awaken2/g_spawn.c
Normal file
1455
awaken2/g_spawn.c
Normal file
File diff suppressed because it is too large
Load diff
586
awaken2/g_svcmds.c
Normal file
586
awaken2/g_svcmds.c
Normal file
|
@ -0,0 +1,586 @@
|
|||
// g_svcmds.c
|
||||
|
||||
#include "g_local.h"
|
||||
|
||||
|
||||
void SVCmd_Test_f(void)
|
||||
{
|
||||
gi.cprintf(NULL, PRINT_HIGH, "SVCmd_Test_f()\n");
|
||||
}
|
||||
|
||||
/*
|
||||
==============================================================================
|
||||
|
||||
PACKET FILTERING
|
||||
|
||||
You can add or remove addresses from the filter list with:
|
||||
|
||||
addip <ip>
|
||||
removeip <ip>
|
||||
|
||||
The ip address is specified in dot format, and any unspecified digits will match any value,
|
||||
so you can specify an entire class C network with "addip 192.246.40".
|
||||
|
||||
Removeip will only remove an address specified exactly the same way. You cannot addip a
|
||||
subnet, then removeip a single host.
|
||||
|
||||
listip
|
||||
Prints the current list of filters.
|
||||
|
||||
writeip
|
||||
Dumps "addip <ip>" commands to listip.cfg so it can be execed at a later date. The filter
|
||||
lists are not saved and restored by default, because I believe it would cause too much confusion.
|
||||
|
||||
filterban <0 or 1>
|
||||
If 1 (the default), then ip addresses matching the current list will be prohibited from entering
|
||||
the game (this is the default setting).
|
||||
If 0, then only addresses matching the list will be allowed. This lets you easily set up a
|
||||
private game, or a game that only allows players from your local network.
|
||||
|
||||
|
||||
==============================================================================
|
||||
*/
|
||||
|
||||
typedef struct
|
||||
{
|
||||
unsigned mask;
|
||||
unsigned compare;
|
||||
} ipfilter_t;
|
||||
|
||||
#define MAX_IPFILTERS 1024
|
||||
|
||||
ipfilter_t ipfilters[MAX_IPFILTERS];
|
||||
int numipfilters;
|
||||
|
||||
/*
|
||||
=================
|
||||
StringToFilter
|
||||
=================
|
||||
*/
|
||||
static qboolean StringToFilter(char *s, ipfilter_t *f)
|
||||
{
|
||||
char num[128];
|
||||
int i;
|
||||
int j;
|
||||
byte b[4];
|
||||
byte m[4];
|
||||
|
||||
for (i = 0; i < 4; i++)
|
||||
{
|
||||
b[i] = 0;
|
||||
m[i] = 0;
|
||||
}
|
||||
|
||||
for (i = 0; i < 4; i++)
|
||||
{
|
||||
if ((*s < '0') || (*s > '9'))
|
||||
{
|
||||
gi.cprintf(NULL, PRINT_HIGH, "Bad filter address: %s\n", s);
|
||||
return false;
|
||||
}
|
||||
|
||||
j = 0;
|
||||
while ((*s >= '0') && (*s <= '9'))
|
||||
{
|
||||
num[j++] = *s++;
|
||||
}
|
||||
num[j] = 0;
|
||||
|
||||
b[i] = atoi(num);
|
||||
if (b[i] != 0)
|
||||
m[i] = 255;
|
||||
|
||||
if (!*s)
|
||||
break;
|
||||
|
||||
s++;
|
||||
}
|
||||
|
||||
f->mask = *(unsigned *)m;
|
||||
f->compare = *(unsigned *)b;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
/*
|
||||
=================
|
||||
SV_FilterPacket
|
||||
=================
|
||||
*/
|
||||
qboolean SV_FilterPacket(char *from)
|
||||
{
|
||||
char *p;
|
||||
byte m[4];
|
||||
int i;
|
||||
unsigned in;
|
||||
|
||||
i = 0;
|
||||
p = from;
|
||||
while (*p && (i < 4))
|
||||
{
|
||||
m[i] = 0;
|
||||
while ((*p >= '0') && (*p <= '9'))
|
||||
{
|
||||
m[i] = (m[i] * 10) + (*p - '0');
|
||||
p++;
|
||||
}
|
||||
if (!*p || (*p == ':'))
|
||||
break;
|
||||
i++, p++;
|
||||
}
|
||||
|
||||
in = *(unsigned *)m;
|
||||
for (i = 0; i < numipfilters; i++)
|
||||
{
|
||||
if ((in & ipfilters[i].mask) == ipfilters[i].compare)
|
||||
return (int)filterban->value;
|
||||
}
|
||||
|
||||
return (int)!filterban->value;
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
=================
|
||||
SVCmd_AddIP_f
|
||||
=================
|
||||
*/
|
||||
void SVCmd_AddIP_f(void)
|
||||
{
|
||||
int i;
|
||||
|
||||
if (gi.argc() < 3)
|
||||
{
|
||||
gi.cprintf(NULL, PRINT_HIGH, "Usage: addip <ip-mask>\n");
|
||||
return;
|
||||
}
|
||||
|
||||
for (i = 0; i < numipfilters; i++)
|
||||
{
|
||||
if (ipfilters[i].compare == 0xffffffff)
|
||||
break; // free spot
|
||||
}
|
||||
|
||||
if (i == numipfilters)
|
||||
{
|
||||
if (numipfilters == MAX_IPFILTERS)
|
||||
{
|
||||
gi.cprintf(NULL, PRINT_HIGH, "IP filter list is full\n");
|
||||
return;
|
||||
}
|
||||
numipfilters++;
|
||||
}
|
||||
|
||||
if (!StringToFilter(gi.argv(2), &ipfilters[i]))
|
||||
ipfilters[i].compare = 0xffffffff;
|
||||
}
|
||||
|
||||
/*
|
||||
=================
|
||||
SVCmd_RemoveIP_f
|
||||
=================
|
||||
*/
|
||||
void SVCmd_RemoveIP_f(void)
|
||||
{
|
||||
ipfilter_t f;
|
||||
int i;
|
||||
int j;
|
||||
|
||||
if (gi.argc() < 3)
|
||||
{
|
||||
gi.cprintf(NULL, PRINT_HIGH, "Usage: sv removeip <ip-mask>\n");
|
||||
return;
|
||||
}
|
||||
|
||||
if (!StringToFilter(gi.argv(2), &f))
|
||||
return;
|
||||
|
||||
for (i = 0; i < numipfilters; i++)
|
||||
{
|
||||
if ((ipfilters[i].mask == f.mask) && (ipfilters[i].compare == f.compare))
|
||||
{
|
||||
for (j = i+1; j < numipfilters; j++)
|
||||
ipfilters[j-1] = ipfilters[j];
|
||||
|
||||
numipfilters--;
|
||||
gi.cprintf(NULL, PRINT_HIGH, "Removed.\n");
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
gi.cprintf(NULL, PRINT_HIGH, "Didn't find %s.\n", gi.argv(2));
|
||||
}
|
||||
|
||||
/*
|
||||
=================
|
||||
SVCmd_ListIP_f
|
||||
=================
|
||||
*/
|
||||
void SVCmd_ListIP_f(void)
|
||||
{
|
||||
int i;
|
||||
byte b[4];
|
||||
|
||||
gi.cprintf(NULL, PRINT_HIGH, "Filter list:\n");
|
||||
for (i = 0; i < numipfilters; i++)
|
||||
{
|
||||
*(unsigned *)b = ipfilters[i].compare;
|
||||
gi.cprintf(NULL, PRINT_HIGH, "%3i.%3i.%3i.%3i\n", b[0], b[1], b[2], b[3]);
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
=================
|
||||
SVCmd_WriteIP_f
|
||||
=================
|
||||
*/
|
||||
void SVCmd_WriteIP_f(void)
|
||||
{
|
||||
FILE *f;
|
||||
cvar_t *game;
|
||||
char name[MAX_OSPATH];
|
||||
byte b[4];
|
||||
int i;
|
||||
|
||||
game = gi.cvar("game", "", 0);
|
||||
|
||||
if (!*game->string)
|
||||
Com_sprintf(name, sizeof(name), "%s/listip.cfg", GAMEVERSION);
|
||||
else
|
||||
Com_sprintf(name, sizeof(name), "%s/listip.cfg", game->string);
|
||||
|
||||
gi.cprintf(NULL, PRINT_HIGH, "Writing %s.\n", name);
|
||||
|
||||
f = fopen(name, "wb");
|
||||
if (!f)
|
||||
{
|
||||
gi.cprintf(NULL, PRINT_HIGH, "Couldn't open %s\n", name);
|
||||
return;
|
||||
}
|
||||
|
||||
fprintf(f, "set filterban %d\n", (int)filterban->value);
|
||||
|
||||
for (i = 0; i < numipfilters; i++)
|
||||
{
|
||||
*(unsigned *)b = ipfilters[i].compare;
|
||||
fprintf(f, "sv addip %i.%i.%i.%i\n", b[0], b[1], b[2], b[3]);
|
||||
}
|
||||
|
||||
fclose(f);
|
||||
}
|
||||
|
||||
//CW++
|
||||
/*
|
||||
=================
|
||||
SVCmd_AddOP_f
|
||||
=================
|
||||
*/
|
||||
void SVCmd_AddOP_f(void)
|
||||
{
|
||||
edict_t *targ;
|
||||
int i = 0;
|
||||
|
||||
if (gi.argc() < 3)
|
||||
{
|
||||
gi.cprintf(NULL, PRINT_HIGH, "Usage: sv add_op <player_num>\n");
|
||||
return;
|
||||
}
|
||||
|
||||
i = atoi(gi.argv(2));
|
||||
if ((i < 1) || (i > (int)maxclients->value))
|
||||
{
|
||||
gi.cprintf(NULL, PRINT_HIGH, "Invalid player number.\n");
|
||||
return;
|
||||
}
|
||||
|
||||
targ = g_edicts + i;
|
||||
if (!targ->inuse)
|
||||
{
|
||||
gi.cprintf(NULL, PRINT_HIGH, "That player number is not connected.\n");
|
||||
return;
|
||||
}
|
||||
|
||||
if (targ->client->pers.op_status)
|
||||
{
|
||||
gi.cprintf(NULL, PRINT_HIGH, "That player already has OP status.\n");
|
||||
return;
|
||||
}
|
||||
|
||||
targ->client->pers.op_status = true;
|
||||
gi_bprintf(PRINT_CHAT, "OP status given to %s.\n", targ->client->pers.netname);
|
||||
}
|
||||
|
||||
/*
|
||||
=================
|
||||
SVCmd_DelOP_f
|
||||
=================
|
||||
*/
|
||||
void SVCmd_DelOP_f(void)
|
||||
{
|
||||
edict_t *targ;
|
||||
int i = 0;
|
||||
|
||||
if (gi.argc() < 3)
|
||||
{
|
||||
gi.cprintf(NULL, PRINT_HIGH, "Usage: sv del_op <player_num>\n");
|
||||
return;
|
||||
}
|
||||
|
||||
i = atoi(gi.argv(2));
|
||||
if ((i < 1) || (i > (int)maxclients->value))
|
||||
{
|
||||
gi.cprintf(NULL, PRINT_HIGH, "Invalid player number.\n");
|
||||
return;
|
||||
}
|
||||
|
||||
targ = g_edicts + i;
|
||||
if (!targ->inuse)
|
||||
{
|
||||
gi.cprintf(NULL, PRINT_HIGH, "That player number is not connected.\n");
|
||||
return;
|
||||
}
|
||||
|
||||
if (!targ->client->pers.op_status)
|
||||
{
|
||||
gi.cprintf(NULL, PRINT_HIGH, "That player already lacks OP status.\n");
|
||||
return;
|
||||
}
|
||||
|
||||
targ->client->pers.op_status = false;
|
||||
gi_bprintf(PRINT_CHAT, "OP status removed from %s.\n", targ->client->pers.netname);
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
==================
|
||||
SVCmd_DevEdicts_f
|
||||
==================
|
||||
*/
|
||||
void SVCmd_DevEdicts_f(void)
|
||||
{
|
||||
edict_t *ent;
|
||||
int i;
|
||||
|
||||
ent = &g_edicts[0];
|
||||
for (i = 0; i < globals.num_edicts ; ++i, ++ent)
|
||||
gi.dprintf("%4d %-24.24s %s %s\n", i, ent->classname, (ent->inuse)?"T":".", vtosf(ent->s.origin));
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
=================
|
||||
SVCmd_AddBots_f
|
||||
=================
|
||||
*/
|
||||
void SVCmd_AddBots_f(void)
|
||||
{
|
||||
edict_t *remover = NULL;
|
||||
int i = 0;
|
||||
|
||||
if (gi.argc() < 3)
|
||||
{
|
||||
gi.cprintf(NULL, PRINT_HIGH, "Usage: sv addbots <number>\n");
|
||||
return;
|
||||
}
|
||||
|
||||
if (!(int)sv_allow_bots->value)
|
||||
{
|
||||
gi.cprintf(NULL, PRINT_HIGH, "AwakenBots are not enabled on this server.\n");
|
||||
return;
|
||||
}
|
||||
|
||||
if (((int)sv_gametype->value == G_CTF) || ((int)sv_gametype->value == G_ASLT))
|
||||
{
|
||||
gi.cprintf(NULL, PRINT_HIGH, "AwakenBots are not available for this gametype.\n");
|
||||
return;
|
||||
}
|
||||
|
||||
if ((int)chedit->value)
|
||||
{
|
||||
gi.cprintf(NULL, PRINT_HIGH, "Can't add bots during route creation.");
|
||||
return;
|
||||
}
|
||||
|
||||
if (teamgame.match > MATCH_SETUP)
|
||||
{
|
||||
gi.cprintf(NULL, PRINT_HIGH, "Cannot add bots during a match.\n");
|
||||
return;
|
||||
}
|
||||
|
||||
if ((remover = G_Find(NULL, FOFS(classname), "bot_remover")) != NULL)
|
||||
{
|
||||
gi.cprintf(NULL, PRINT_HIGH, "Cannot add bots - some are still being removed.\n");
|
||||
return;
|
||||
}
|
||||
|
||||
i = atoi(gi.argv(2));
|
||||
if (i < 1)
|
||||
{
|
||||
gi.cprintf(NULL, PRINT_HIGH, "Invalid number of bots.\n");
|
||||
return;
|
||||
}
|
||||
|
||||
SpawnNumBots_Safe(i);
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
=================
|
||||
SVCmd_ClearBots_f
|
||||
=================
|
||||
*/
|
||||
void SVCmd_ClearBots_f(void)
|
||||
{
|
||||
edict_t *spawner = NULL;
|
||||
|
||||
if (!(int)sv_allow_bots->value)
|
||||
return;
|
||||
|
||||
if ((int)chedit->value)
|
||||
return;
|
||||
|
||||
if (((int)sv_gametype->value == G_CTF) || ((int)sv_gametype->value == G_ASLT))
|
||||
return;
|
||||
|
||||
if (teamgame.match > MATCH_SETUP)
|
||||
{
|
||||
gi.cprintf(NULL, PRINT_HIGH, "Cannot remove bots during a match.\n");
|
||||
return;
|
||||
}
|
||||
|
||||
if ((spawner = G_Find(NULL, FOFS(classname), "bot_spawner")) != NULL)
|
||||
{
|
||||
gi.cprintf(NULL, PRINT_HIGH, "Cannot clear bots - some are still being added.\n");
|
||||
return;
|
||||
}
|
||||
|
||||
if (gi.argc() < 3)
|
||||
RemoveNumBots_Safe(MAXBOTS);
|
||||
else
|
||||
RemoveNumBots_Safe(atoi(gi.argv(2)));
|
||||
}
|
||||
|
||||
/*
|
||||
=================
|
||||
SVCmd_ListBots_f
|
||||
=================
|
||||
*/
|
||||
void SVCmd_ListBots_f(void)
|
||||
{
|
||||
edict_t *ent;
|
||||
int i;
|
||||
|
||||
for (i = 1; i <= (int)maxclients->value; i++)
|
||||
{
|
||||
ent = g_edicts + i;
|
||||
if (!ent->inuse)
|
||||
continue;
|
||||
|
||||
if (!ent->isabot)
|
||||
continue;
|
||||
|
||||
gi.dprintf("%3d %-16.16s %03d [%d:%d:%d]\n", i,
|
||||
ent->client->pers.netname,
|
||||
ent->client->resp.score,
|
||||
Bot[ent->client->pers.botindex].skill[AIMACCURACY],
|
||||
Bot[ent->client->pers.botindex].skill[AGGRESSION],
|
||||
Bot[ent->client->pers.botindex].skill[COMBATSKILL]);
|
||||
}
|
||||
}
|
||||
//CW--
|
||||
|
||||
//Pon++
|
||||
/*
|
||||
=================
|
||||
SVCmd_SaveChain_f
|
||||
=================
|
||||
*/
|
||||
void SVCmd_SaveChain_f(void)
|
||||
{
|
||||
unsigned int size;
|
||||
char name[256];
|
||||
FILE *fpout;
|
||||
|
||||
//CW++
|
||||
cvar_t *game;
|
||||
//CW--
|
||||
|
||||
if (!(int)chedit->value)
|
||||
{
|
||||
gi.cprintf(NULL, PRINT_HIGH, "Not in chaining mode!\n");
|
||||
return;
|
||||
}
|
||||
|
||||
//CW++
|
||||
game = gi.cvar("game", "", 0);
|
||||
if (!*game->string)
|
||||
Com_sprintf(name, sizeof(name), "%s/botroutes/%s.chn", GAMEVERSION, level.mapname);
|
||||
else
|
||||
Com_sprintf(name, sizeof(name), "%s/botroutes/%s.chn", game->string, level.mapname);
|
||||
//CW--
|
||||
|
||||
fpout = fopen(name, "wb");
|
||||
if (fpout == NULL)
|
||||
gi.cprintf(NULL, PRINT_HIGH, "Can't open %s\n", name);
|
||||
else
|
||||
{
|
||||
fwrite("3ZBRGDTM", sizeof(char), 8, fpout);
|
||||
fwrite(&CurrentIndex, sizeof(int), 1, fpout);
|
||||
size = (unsigned int)CurrentIndex * sizeof(route_t);
|
||||
fwrite(Route, size, 1, fpout);
|
||||
|
||||
gi.cprintf(NULL, PRINT_HIGH, "Route data saved to: %s\n", name);
|
||||
fclose(fpout);
|
||||
}
|
||||
}
|
||||
//Pon--
|
||||
|
||||
/*
|
||||
=================
|
||||
ServerCommand
|
||||
|
||||
ServerCommand will be called when an "sv" command is issued.
|
||||
The game can issue gi.argc() / gi.argv() commands to get the rest
|
||||
of the parameters
|
||||
=================
|
||||
*/
|
||||
void ServerCommand(void)
|
||||
{
|
||||
char *cmd;
|
||||
|
||||
cmd = gi.argv(1);
|
||||
|
||||
if (Q_stricmp(cmd, "test") == 0)
|
||||
SVCmd_Test_f();
|
||||
else if (Q_stricmp(cmd, "addip") == 0)
|
||||
SVCmd_AddIP_f();
|
||||
else if (Q_stricmp(cmd, "removeip") == 0)
|
||||
SVCmd_RemoveIP_f();
|
||||
else if (Q_stricmp(cmd, "listip") == 0)
|
||||
SVCmd_ListIP_f();
|
||||
else if (Q_stricmp(cmd, "writeip") == 0)
|
||||
SVCmd_WriteIP_f();
|
||||
|
||||
//CW++
|
||||
else if (!Q_stricmp(cmd, "add_op"))
|
||||
SVCmd_AddOP_f();
|
||||
else if (!Q_stricmp(cmd, "del_op"))
|
||||
SVCmd_DelOP_f();
|
||||
else if (!Q_stricmp(cmd, "dev_edicts"))
|
||||
SVCmd_DevEdicts_f();
|
||||
else if (!Q_stricmp(cmd, "addbots"))
|
||||
SVCmd_AddBots_f();
|
||||
else if (!Q_stricmp(cmd, "clearbots"))
|
||||
SVCmd_ClearBots_f();
|
||||
else if (!Q_stricmp(cmd, "listbots"))
|
||||
SVCmd_ListBots_f();
|
||||
//CW--
|
||||
|
||||
//Pon++
|
||||
else if (!Q_stricmp(cmd, "savechain"))
|
||||
SVCmd_SaveChain_f();
|
||||
//Pon--
|
||||
|
||||
else
|
||||
gi.cprintf(NULL, PRINT_HIGH, "Unknown server command \"%s\"\n", cmd);
|
||||
}
|
577
awaken2/g_target.c
Normal file
577
awaken2/g_target.c
Normal file
|
@ -0,0 +1,577 @@
|
|||
// g_target.c
|
||||
|
||||
#include "g_local.h"
|
||||
|
||||
|
||||
/*QUAKED target_temp_entity (1 0 0) (-8 -8 -8) (8 8 8)
|
||||
Fire an origin based temp entity event to the clients.
|
||||
"style" type byte
|
||||
*/
|
||||
void Use_Target_Tent(edict_t *ent, edict_t *other, edict_t *activator)
|
||||
{
|
||||
gi.WriteByte(svc_temp_entity);
|
||||
gi.WriteByte(ent->style);
|
||||
gi.WritePosition(ent->s.origin);
|
||||
gi.multicast(ent->s.origin, MULTICAST_PVS);
|
||||
}
|
||||
|
||||
void SP_target_temp_entity(edict_t *ent)
|
||||
{
|
||||
ent->use = Use_Target_Tent;
|
||||
|
||||
//CW++
|
||||
ent->svflags |= SVF_NOCLIENT;
|
||||
//CW--
|
||||
}
|
||||
|
||||
|
||||
//==========================================================
|
||||
|
||||
/*QUAKED target_speaker (1 0 0) (-8 -8 -8) (8 8 8) looped-on looped-off reliable
|
||||
"noise" wav file to play
|
||||
"attenuation"
|
||||
-1 = none, send to whole level
|
||||
1 = normal fighting sounds
|
||||
2 = idle sound level
|
||||
3 = ambient sound level
|
||||
"volume" 0.0 to 1.0
|
||||
|
||||
Normal sounds play each time the target is used. The reliable flag can be set for crucial voiceovers.
|
||||
|
||||
Looped sounds are allways atten 3 / vol 1, and the use function toggles it on/off.
|
||||
Multiple identical looping sounds will just increase volume without any speed cost.
|
||||
*/
|
||||
void Use_Target_Speaker(edict_t *ent, edict_t *other, edict_t *activator)
|
||||
{
|
||||
int chan;
|
||||
|
||||
if (ent->spawnflags & 3)
|
||||
{ // looping sound toggles
|
||||
if (ent->s.sound)
|
||||
ent->s.sound = 0; // turn it off
|
||||
else
|
||||
ent->s.sound = ent->noise_index; // start it
|
||||
}
|
||||
else
|
||||
{ // normal sound
|
||||
if (ent->spawnflags & 4)
|
||||
chan = CHAN_VOICE | CHAN_RELIABLE;
|
||||
else
|
||||
chan = CHAN_VOICE;
|
||||
// use a positioned_sound, because this entity won't normally be
|
||||
// sent to any clients because it is invisible
|
||||
gi.positioned_sound(ent->s.origin, ent, chan, ent->noise_index, ent->volume, ent->attenuation, 0);
|
||||
}
|
||||
}
|
||||
|
||||
void SP_target_speaker(edict_t *ent)
|
||||
{
|
||||
char buffer[MAX_QPATH];
|
||||
|
||||
if (!st.noise)
|
||||
{
|
||||
gi.dprintf("target_speaker with no noise set at %s\n", vtos(ent->s.origin));
|
||||
return;
|
||||
}
|
||||
if (!strstr (st.noise, ".wav"))
|
||||
Com_sprintf(buffer, sizeof(buffer), "%s.wav", st.noise);
|
||||
else
|
||||
strncpy(buffer, st.noise, sizeof(buffer));
|
||||
ent->noise_index = gi.soundindex (buffer);
|
||||
|
||||
if (!ent->volume)
|
||||
ent->volume = 1.0;
|
||||
|
||||
if (!ent->attenuation)
|
||||
ent->attenuation = 1.0;
|
||||
else if (ent->attenuation == -1) // use -1 so 0 defaults to 1
|
||||
ent->attenuation = 0;
|
||||
|
||||
// check for prestarted looping sound
|
||||
if (ent->spawnflags & 1)
|
||||
ent->s.sound = ent->noise_index;
|
||||
|
||||
ent->use = Use_Target_Speaker;
|
||||
|
||||
// must link the entity so we get areas and clusters so
|
||||
// the server can determine who to send updates to
|
||||
gi.linkentity(ent);
|
||||
}
|
||||
|
||||
|
||||
//==========================================================
|
||||
|
||||
/*QUAKED target_explosion (1 0 0) (-8 -8 -8) (8 8 8)
|
||||
Spawns an explosion temporary entity when used.
|
||||
|
||||
"delay" wait this long before going off
|
||||
"dmg" how much radius damage should be done, defaults to 0
|
||||
*/
|
||||
void target_explosion_explode(edict_t *self)
|
||||
{
|
||||
float save;
|
||||
|
||||
gi.WriteByte(svc_temp_entity);
|
||||
gi.WriteByte(TE_EXPLOSION1);
|
||||
gi.WritePosition(self->s.origin);
|
||||
gi.multicast(self->s.origin, MULTICAST_PHS);
|
||||
T_RadiusDamage(self, self->activator, self->dmg, NULL, self->dmg+40, MOD_EXPLOSIVE);
|
||||
|
||||
save = self->delay;
|
||||
self->delay = 0.0;
|
||||
G_UseTargets(self, self->activator);
|
||||
self->delay = save;
|
||||
}
|
||||
|
||||
void use_target_explosion(edict_t *self, edict_t *other, edict_t *activator)
|
||||
{
|
||||
self->activator = activator;
|
||||
|
||||
if (!self->delay)
|
||||
{
|
||||
target_explosion_explode(self);
|
||||
return;
|
||||
}
|
||||
|
||||
self->think = target_explosion_explode;
|
||||
self->nextthink = level.time + self->delay;
|
||||
}
|
||||
|
||||
void SP_target_explosion(edict_t *ent)
|
||||
{
|
||||
ent->use = use_target_explosion;
|
||||
ent->svflags = SVF_NOCLIENT;
|
||||
}
|
||||
|
||||
|
||||
//==========================================================
|
||||
|
||||
/*QUAKED target_changelevel (1 0 0) (-8 -8 -8) (8 8 8)
|
||||
Changes level to "map" when fired
|
||||
*/
|
||||
void use_target_changelevel(edict_t *self, edict_t *other, edict_t *activator)
|
||||
{
|
||||
// ignore if already activated
|
||||
if (level.intermissiontime)
|
||||
return;
|
||||
|
||||
// if noexit, do a ton of damage to other
|
||||
if (!((int)dmflags->value & DF_ALLOW_EXIT) && (other != world)) //CW
|
||||
{
|
||||
T_Damage(other, self, self, vec3_origin, other->s.origin, vec3_origin, 10 * other->max_health, 1000, 0, MOD_EXIT);
|
||||
return;
|
||||
}
|
||||
|
||||
// let everyone know who hit the exit
|
||||
if (activator && activator->client) //CW
|
||||
gi_bprintf (PRINT_HIGH, "%s exited the level.\n", activator->client->pers.netname);
|
||||
|
||||
// if going to a new unit, clear cross triggers
|
||||
if (strstr(self->map, "*"))
|
||||
game.serverflags &= ~(SFL_CROSS_TRIGGER_MASK);
|
||||
|
||||
BeginIntermission(self);
|
||||
}
|
||||
|
||||
void SP_target_changelevel(edict_t *ent)
|
||||
{
|
||||
if (!ent->map)
|
||||
{
|
||||
gi.dprintf("target_changelevel with no map at %s\n", vtos(ent->s.origin));
|
||||
G_FreeEdict(ent);
|
||||
return;
|
||||
}
|
||||
|
||||
// ugly hack because *SOMEBODY* screwed up their map
|
||||
if((Q_stricmp(level.mapname, "fact1") == 0) && (Q_stricmp(ent->map, "fact3") == 0))
|
||||
ent->map = "fact3$secret1";
|
||||
|
||||
ent->use = use_target_changelevel;
|
||||
ent->svflags = SVF_NOCLIENT;
|
||||
}
|
||||
|
||||
|
||||
//==========================================================
|
||||
|
||||
/*QUAKED target_splash (1 0 0) (-8 -8 -8) (8 8 8)
|
||||
Creates a particle splash effect when used.
|
||||
|
||||
Set "sounds" to one of the following:
|
||||
1) sparks
|
||||
2) blue water
|
||||
3) brown water
|
||||
4) slime
|
||||
5) lava
|
||||
6) blood
|
||||
|
||||
"count" how many pixels in the splash
|
||||
"dmg" if set, does a radius damage at this location when it splashes
|
||||
useful for lava/sparks
|
||||
*/
|
||||
|
||||
void use_target_splash(edict_t *self, edict_t *other, edict_t *activator)
|
||||
{
|
||||
gi.WriteByte(svc_temp_entity);
|
||||
gi.WriteByte(TE_SPLASH);
|
||||
gi.WriteByte(self->count);
|
||||
gi.WritePosition(self->s.origin);
|
||||
gi.WriteDir(self->movedir);
|
||||
gi.WriteByte(self->sounds);
|
||||
gi.multicast(self->s.origin, MULTICAST_PVS);
|
||||
|
||||
if (self->dmg)
|
||||
T_RadiusDamage(self, activator, self->dmg, NULL, self->dmg+40, MOD_SPLASH);
|
||||
}
|
||||
|
||||
void SP_target_splash(edict_t *self)
|
||||
{
|
||||
self->use = use_target_splash;
|
||||
G_SetMovedir(self->s.angles, self->movedir);
|
||||
|
||||
if (!self->count)
|
||||
self->count = 32;
|
||||
|
||||
self->svflags = SVF_NOCLIENT;
|
||||
}
|
||||
|
||||
|
||||
//==========================================================
|
||||
|
||||
/*QUAKED target_spawner (1 0 0) (-8 -8 -8) (8 8 8)
|
||||
Set target to the type of entity you want spawned.
|
||||
Useful for spawning monsters and gibs in the factory levels.
|
||||
|
||||
For monsters:
|
||||
Set direction to the facing you want it to have.
|
||||
|
||||
For gibs:
|
||||
Set direction if you want it moving and
|
||||
speed how fast it should be moving otherwise it
|
||||
will just be dropped
|
||||
*/
|
||||
void ED_CallSpawn(edict_t *ent);
|
||||
|
||||
void use_target_spawner(edict_t *self, edict_t *other, edict_t *activator)
|
||||
{
|
||||
edict_t *ent;
|
||||
|
||||
ent = G_Spawn();
|
||||
ent->classname = self->target;
|
||||
VectorCopy(self->s.origin, ent->s.origin);
|
||||
VectorCopy(self->s.angles, ent->s.angles);
|
||||
ED_CallSpawn(ent);
|
||||
gi.unlinkentity(ent);
|
||||
KillBox(ent);
|
||||
gi.linkentity(ent);
|
||||
|
||||
if (self->speed)
|
||||
VectorCopy(self->movedir, ent->velocity);
|
||||
}
|
||||
|
||||
void SP_target_spawner(edict_t *self)
|
||||
{
|
||||
self->use = use_target_spawner;
|
||||
self->svflags = SVF_NOCLIENT;
|
||||
if (self->speed)
|
||||
{
|
||||
G_SetMovedir(self->s.angles, self->movedir);
|
||||
VectorScale(self->movedir, self->speed, self->movedir);
|
||||
}
|
||||
}
|
||||
|
||||
//==========================================================
|
||||
|
||||
/*QUAKED target_blaster (1 0 0) (-8 -8 -8) (8 8 8) NOTRAIL NOEFFECTS
|
||||
Fires a blaster bolt in the set direction when triggered.
|
||||
|
||||
dmg default is 15
|
||||
speed default is 1000
|
||||
*/
|
||||
|
||||
void use_target_blaster(edict_t *self, edict_t *other, edict_t *activator)
|
||||
{
|
||||
int effect;
|
||||
|
||||
if (self->spawnflags & 2)
|
||||
effect = 0;
|
||||
else if (self->spawnflags & 1)
|
||||
effect = EF_HYPERBLASTER;
|
||||
else
|
||||
effect = EF_BLASTER;
|
||||
|
||||
Fire_Blaster(self, self->s.origin, self->movedir, self->dmg, self->speed, effect); //CW
|
||||
gi.sound(self, CHAN_VOICE, self->noise_index, 1, ATTN_NORM, 0);
|
||||
}
|
||||
|
||||
void SP_target_blaster(edict_t *self)
|
||||
{
|
||||
self->use = use_target_blaster;
|
||||
G_SetMovedir(self->s.angles, self->movedir);
|
||||
self->noise_index = gi.soundindex("weapons/laser2.wav");
|
||||
|
||||
if (!self->dmg)
|
||||
self->dmg = 15;
|
||||
if (!self->speed)
|
||||
self->speed = 1000.0;
|
||||
|
||||
self->svflags = SVF_NOCLIENT;
|
||||
}
|
||||
|
||||
|
||||
//==========================================================
|
||||
|
||||
/*QUAKED target_laser (0 .5 .8) (-8 -8 -8) (8 8 8) START_ON RED GREEN BLUE YELLOW ORANGE FAT
|
||||
When triggered, fires a laser. You can either set a target
|
||||
or a direction.
|
||||
*/
|
||||
|
||||
void target_laser_think(edict_t *self)
|
||||
{
|
||||
edict_t *ignore;
|
||||
trace_t tr;
|
||||
vec3_t start;
|
||||
vec3_t end;
|
||||
vec3_t point;
|
||||
vec3_t last_movedir;
|
||||
int count;
|
||||
|
||||
if (self->spawnflags & 0x80000000)
|
||||
count = 8;
|
||||
else
|
||||
count = 4;
|
||||
|
||||
if (self->enemy)
|
||||
{
|
||||
VectorCopy(self->movedir, last_movedir);
|
||||
VectorMA(self->enemy->absmin, 0.5, self->enemy->size, point);
|
||||
VectorSubtract(point, self->s.origin, self->movedir);
|
||||
VectorNormalize(self->movedir);
|
||||
if (!VectorCompare(self->movedir, last_movedir))
|
||||
self->spawnflags |= 0x80000000;
|
||||
}
|
||||
|
||||
ignore = self;
|
||||
VectorCopy(self->s.origin, start);
|
||||
VectorMA(start, 2048.0, self->movedir, end);
|
||||
while (1)
|
||||
{
|
||||
tr = gi.trace(start, NULL, NULL, end, ignore, CONTENTS_SOLID|CONTENTS_MONSTER|CONTENTS_DEADMONSTER);
|
||||
|
||||
if (!tr.ent)
|
||||
break;
|
||||
|
||||
// hurt it if we can
|
||||
if ((tr.ent->takedamage) && !(tr.ent->flags & FL_IMMUNE_LASER))
|
||||
//CW++
|
||||
{
|
||||
if (tr.ent->client && (tr.ent->client->agm_enemy != NULL))
|
||||
T_Damage(tr.ent, self, tr.ent->client->agm_enemy, self->movedir, tr.endpos, vec3_origin, self->dmg, 1, DAMAGE_ENERGY, MOD_AGM_TARG_LASER);
|
||||
else
|
||||
//CW--
|
||||
T_Damage(tr.ent, self, self->activator, self->movedir, tr.endpos, vec3_origin, self->dmg, 1, DAMAGE_ENERGY, MOD_TARGET_LASER);
|
||||
}
|
||||
|
||||
// if we hit something that's not a monster or player or is immune to lasers, we're done
|
||||
if (!(tr.ent->svflags & SVF_MONSTER) && (!tr.ent->client))
|
||||
{
|
||||
if (self->spawnflags & 0x80000000)
|
||||
{
|
||||
self->spawnflags &= ~0x80000000;
|
||||
gi.WriteByte(svc_temp_entity);
|
||||
gi.WriteByte(TE_LASER_SPARKS);
|
||||
gi.WriteByte(count);
|
||||
gi.WritePosition(tr.endpos);
|
||||
gi.WriteDir(tr.plane.normal);
|
||||
gi.WriteByte(self->s.skinnum);
|
||||
gi.multicast(tr.endpos, MULTICAST_PVS);
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
ignore = tr.ent;
|
||||
VectorCopy(tr.endpos, start);
|
||||
}
|
||||
|
||||
VectorCopy(tr.endpos, self->s.old_origin);
|
||||
|
||||
self->nextthink = level.time + FRAMETIME;
|
||||
}
|
||||
|
||||
void target_laser_on(edict_t *self)
|
||||
{
|
||||
if (!self->activator)
|
||||
self->activator = self;
|
||||
|
||||
self->spawnflags |= 0x80000001;
|
||||
self->svflags &= ~SVF_NOCLIENT;
|
||||
target_laser_think(self);
|
||||
}
|
||||
|
||||
void target_laser_off(edict_t *self)
|
||||
{
|
||||
self->spawnflags &= ~1;
|
||||
self->svflags |= SVF_NOCLIENT;
|
||||
self->nextthink = 0.0;
|
||||
}
|
||||
|
||||
void target_laser_use(edict_t *self, edict_t *other, edict_t *activator)
|
||||
{
|
||||
self->activator = activator;
|
||||
if (self->spawnflags & 1)
|
||||
target_laser_off (self);
|
||||
else
|
||||
target_laser_on (self);
|
||||
}
|
||||
|
||||
void target_laser_start(edict_t *self)
|
||||
{
|
||||
edict_t *ent;
|
||||
|
||||
self->movetype = MOVETYPE_NONE;
|
||||
self->solid = SOLID_NOT;
|
||||
self->s.renderfx |= RF_BEAM|RF_TRANSLUCENT;
|
||||
self->s.modelindex = 1; // must be non-zero
|
||||
|
||||
// set the beam diameter
|
||||
if (self->spawnflags & 64)
|
||||
self->s.frame = 16;
|
||||
else
|
||||
self->s.frame = 4;
|
||||
|
||||
// set the color
|
||||
if (self->spawnflags & 2)
|
||||
self->s.skinnum = 0xf2f2f0f0;
|
||||
else if (self->spawnflags & 4)
|
||||
self->s.skinnum = 0xd0d1d2d3;
|
||||
else if (self->spawnflags & 8)
|
||||
self->s.skinnum = 0xf3f3f1f1;
|
||||
else if (self->spawnflags & 16)
|
||||
self->s.skinnum = 0xdcdddedf;
|
||||
else if (self->spawnflags & 32)
|
||||
self->s.skinnum = 0xe0e1e2e3;
|
||||
|
||||
if (!self->enemy)
|
||||
{
|
||||
if (self->target)
|
||||
{
|
||||
ent = G_Find(NULL, FOFS(targetname), self->target);
|
||||
if (!ent)
|
||||
gi.dprintf("%s at %s: %s is a bad target\n", self->classname, vtos(self->s.origin), self->target);
|
||||
|
||||
self->enemy = ent;
|
||||
}
|
||||
else
|
||||
G_SetMovedir(self->s.angles, self->movedir);
|
||||
}
|
||||
self->use = target_laser_use;
|
||||
self->think = target_laser_think;
|
||||
|
||||
if (!self->dmg)
|
||||
self->dmg = 1;
|
||||
|
||||
VectorSet(self->mins, -8.0, -8.0, -8.0);
|
||||
VectorSet(self->maxs, 8.0, 8.0, 8.0);
|
||||
gi.linkentity(self);
|
||||
|
||||
if (self->spawnflags & 1)
|
||||
target_laser_on(self);
|
||||
else
|
||||
target_laser_off(self);
|
||||
}
|
||||
|
||||
void SP_target_laser (edict_t *self)
|
||||
{
|
||||
self->think = target_laser_start;
|
||||
self->nextthink = level.time + 1.0; // let everything else get spawned before we start firing
|
||||
}
|
||||
|
||||
|
||||
//==========================================================
|
||||
|
||||
/*QUAKED target_earthquake (1 0 0) (-8 -8 -8) (8 8 8)
|
||||
When triggered, this initiates a level-wide earthquake.
|
||||
All players and monsters are affected.
|
||||
"speed" severity of the quake (default:200)
|
||||
"count" duration of the quake (default:5)
|
||||
*/
|
||||
|
||||
void target_earthquake_think(edict_t *self)
|
||||
{
|
||||
edict_t *e;
|
||||
int i;
|
||||
|
||||
if (self->last_move_time < level.time)
|
||||
{
|
||||
gi.positioned_sound(self->s.origin, self, CHAN_AUTO, self->noise_index, 1.0, ATTN_NONE, 0);
|
||||
self->last_move_time = level.time + 0.5;
|
||||
}
|
||||
|
||||
for (i = 1, e = g_edicts + i; i < globals.num_edicts; i++, e++)
|
||||
{
|
||||
if (!e->inuse)
|
||||
continue;
|
||||
if (!e->client)
|
||||
continue;
|
||||
if (!e->groundentity)
|
||||
continue;
|
||||
|
||||
e->groundentity = NULL;
|
||||
e->velocity[0] += crandom()* 150.0;
|
||||
e->velocity[1] += crandom()* 150.0;
|
||||
e->velocity[2] = self->speed * (100.0 / e->mass);
|
||||
}
|
||||
|
||||
if (level.time < self->timestamp)
|
||||
self->nextthink = level.time + FRAMETIME;
|
||||
}
|
||||
|
||||
void target_earthquake_use(edict_t *self, edict_t *other, edict_t *activator)
|
||||
{
|
||||
self->timestamp = level.time + self->count;
|
||||
self->nextthink = level.time + FRAMETIME;
|
||||
self->activator = activator;
|
||||
self->last_move_time = 0.0;
|
||||
}
|
||||
|
||||
void SP_target_earthquake(edict_t *self)
|
||||
{
|
||||
if (!self->targetname)
|
||||
gi.dprintf("untargeted %s at %s\n", self->classname, vtos(self->s.origin));
|
||||
|
||||
if (!self->count)
|
||||
self->count = 5;
|
||||
|
||||
if (!self->speed)
|
||||
self->speed = 200.0;
|
||||
|
||||
self->svflags |= SVF_NOCLIENT;
|
||||
self->think = target_earthquake_think;
|
||||
self->use = target_earthquake_use;
|
||||
|
||||
self->noise_index = gi.soundindex("world/quake.wav");
|
||||
}
|
||||
|
||||
//==========================================================
|
||||
|
||||
/*QUAKED target_victory (1 0 0) (-8 -8 -8) (8 8 8)
|
||||
ASSAULT: When triggered, ends the game with a victory for the attacking team.
|
||||
*/
|
||||
void target_victory_use(edict_t *self, edict_t *other, edict_t *activator)
|
||||
{
|
||||
G_UseTargets(self, activator);
|
||||
asltgame.victory = true;
|
||||
}
|
||||
|
||||
void SP_target_victory(edict_t *self)
|
||||
{
|
||||
if (sv_gametype->value != G_ASLT)
|
||||
{
|
||||
G_FreeEdict(self);
|
||||
return;
|
||||
}
|
||||
|
||||
self->classname = "assault_victory";
|
||||
self->svflags |= SVF_NOCLIENT;
|
||||
self->use = target_victory_use;
|
||||
}
|
||||
//CW--
|
5767
awaken2/g_team.c
Normal file
5767
awaken2/g_team.c
Normal file
File diff suppressed because it is too large
Load diff
243
awaken2/g_team.h
Normal file
243
awaken2/g_team.h
Normal file
|
@ -0,0 +1,243 @@
|
|||
// g_team.h
|
||||
|
||||
#define STAT_CTF_TEAM1_PIC 17
|
||||
#define STAT_CTF_TEAM1_CAPS 18
|
||||
#define STAT_CTF_TEAM2_PIC 19
|
||||
#define STAT_CTF_TEAM2_CAPS 20
|
||||
#define STAT_CTF_FLAG_PIC 21 //CW: (ab)used as an attacking team indicator for Assault
|
||||
#define STAT_CTF_JOINED_TEAM1_PIC 22
|
||||
#define STAT_CTF_JOINED_TEAM2_PIC 23
|
||||
#define STAT_CTF_TEAM1_HEADER 24
|
||||
#define STAT_CTF_TEAM2_HEADER 25
|
||||
#define STAT_CTF_TECH 26
|
||||
#define STAT_CTF_ID_VIEW 27
|
||||
#define STAT_CTF_MATCH 28
|
||||
#define STAT_CTF_ID_VIEW_COLOR 29
|
||||
#define STAT_CTF_TEAMINFO 30
|
||||
//CW++
|
||||
#define STAT_ASLT_ATTACK2 31
|
||||
|
||||
#define CLIENT_ID_CHECKTIME 0.5
|
||||
//CW--
|
||||
|
||||
#define CONFIG_CTF_MATCH (CS_AIRACCEL-1)
|
||||
#define CONFIG_CTF_TEAMINFO (CS_AIRACCEL-2)
|
||||
|
||||
typedef enum
|
||||
{
|
||||
CTF_NOTEAM,
|
||||
CTF_TEAM1,
|
||||
CTF_TEAM2,
|
||||
//CW++
|
||||
CTF_TEAM_FFA
|
||||
//CW--
|
||||
} ctfteam_t;
|
||||
|
||||
typedef enum
|
||||
{
|
||||
CTF_GRAPPLE_STATE_FLY,
|
||||
CTF_GRAPPLE_STATE_PULL,
|
||||
CTF_GRAPPLE_STATE_HANG
|
||||
} ctfgrapplestate_t;
|
||||
|
||||
//CW++
|
||||
typedef enum match_s
|
||||
{
|
||||
MATCH_NONE,
|
||||
MATCH_SETUP,
|
||||
MATCH_PREGAME,
|
||||
MATCH_GAME,
|
||||
MATCH_POST
|
||||
} match_t;
|
||||
//CW--
|
||||
|
||||
typedef struct ghost_s
|
||||
{
|
||||
char netname[MAX_NAMELEN]; //CW
|
||||
int number;
|
||||
|
||||
int deaths; // stats
|
||||
int kills; //
|
||||
int caps; //
|
||||
int basedef; //
|
||||
int carrierdef; //
|
||||
|
||||
int code; // ghost code
|
||||
int team; // team
|
||||
int score; // frags at time of disconnect
|
||||
edict_t *ent;
|
||||
} ghost_t;
|
||||
|
||||
typedef struct teamgame_s //CW
|
||||
{
|
||||
int team1;
|
||||
int team2;
|
||||
int total1; // only set when going into intermission!
|
||||
int total2; // only set when going into intermission!
|
||||
float last_flag_capture;
|
||||
int last_capture_team;
|
||||
|
||||
match_t match; // match state
|
||||
float matchtime; // time for match start/end (depends on state)
|
||||
int lasttime; // last time update
|
||||
qboolean countdown; // has audio countdown started?
|
||||
|
||||
int warnactive; // true if stat string 30 is active
|
||||
|
||||
ghost_t ghosts[MAX_CLIENTS]; // ghost codes
|
||||
|
||||
//CW++
|
||||
int frags1; // scores for TDM
|
||||
int frags2; //
|
||||
//CW--
|
||||
} teamgame_t; //CW
|
||||
|
||||
//CW++
|
||||
// Assault game info (NB: teamgame_t is still used for most of the relevant team data).
|
||||
typedef struct asltgame_s
|
||||
{
|
||||
qboolean victory; // attacking team has achieved objective(s)
|
||||
int t_attack; // attacking team
|
||||
int spawn; // current spawn point selection
|
||||
char *msg_attack; // message displayed if the attackers win the level
|
||||
char *msg_defend; // message displayed if the defenders win the level
|
||||
} asltgame_t;
|
||||
//CW--
|
||||
|
||||
#define CTF_TEAM1_SKIN "ctf_r"
|
||||
#define CTF_TEAM2_SKIN "ctf_b"
|
||||
|
||||
#define CTF_CAPTURE_BONUS 15 // what you get for capture
|
||||
#define CTF_TEAM_BONUS 10 // what your team gets for capture
|
||||
#define CTF_RECOVERY_BONUS 1 // what you get for recovery
|
||||
#define CTF_FLAG_BONUS 0 // what you get for picking up enemy flag
|
||||
#define CTF_FRAG_CARRIER_BONUS 2 // what you get for fragging enemy flag carrier
|
||||
#define CTF_FLAG_RETURN_TIME 40 // seconds until auto return
|
||||
|
||||
#define CTF_CARRIER_DANGER_PROTECT_BONUS 2 // bonus for fragging someone who has recently hurt your flag carrier
|
||||
#define CTF_CARRIER_PROTECT_BONUS 1 // bonus for fragging someone while either you or your target are near your flag carrier
|
||||
#define CTF_FLAG_DEFENSE_BONUS 1 // bonus for fragging someone while either you or your target are near your flag
|
||||
#define CTF_RETURN_FLAG_ASSIST_BONUS 1 // awarded for returning a flag that causes a capture to happen almost immediately
|
||||
#define CTF_FRAG_CARRIER_ASSIST_BONUS 2 // award for fragging a flag carrier if a capture happens almost immediately
|
||||
|
||||
#define CTF_TARGET_PROTECT_RADIUS 400 // the radius around an object being defended where a target will be worth extra frags
|
||||
#define CTF_ATTACKER_PROTECT_RADIUS 400 // the radius around an object being defended where an attacker will get extra frags when making kills
|
||||
|
||||
#define CTF_CARRIER_DANGER_PROTECT_TIMEOUT 8
|
||||
#define CTF_FRAG_CARRIER_ASSIST_TIMEOUT 10
|
||||
#define CTF_RETURN_FLAG_ASSIST_TIMEOUT 10
|
||||
|
||||
#define CTF_AUTO_FLAG_RETURN_TIMEOUT 30 // number of seconds before dropped flag auto-returns
|
||||
|
||||
#define CTF_TECH_TIMEOUT 60 // seconds before techs spawn again
|
||||
|
||||
|
||||
void CTFInit(void);
|
||||
void CTFSpawn(void);
|
||||
void CTFPrecache(void);
|
||||
|
||||
void SP_info_player_team1(edict_t *self);
|
||||
void SP_info_player_team2(edict_t *self);
|
||||
|
||||
char *CTFTeamName(int team);
|
||||
char *CTFOtherTeamName(int team);
|
||||
void CTFAssignSkin(edict_t *ent, char *s);
|
||||
void CTFAssignTeam(gclient_t *who);
|
||||
edict_t *SelectCTFSpawnPoint (edict_t *ent, qboolean ctf_only); //CW
|
||||
qboolean CTFPickup_Flag(edict_t *ent, edict_t *other);
|
||||
void CTFDrop_Flag(edict_t *ent, gitem_t *item); //CW
|
||||
void CTFEffects(edict_t *player);
|
||||
void CTFCalcScores(void);
|
||||
void SetCTFStats(edict_t *ent);
|
||||
void CTFDeadDropFlag(edict_t *self);
|
||||
void CTFScoreboardMessage (edict_t *ent, edict_t *killer);
|
||||
void CTFTeam_f (edict_t *ent);
|
||||
void CTFID_f (edict_t *ent);
|
||||
void CTFSay_Team(edict_t *who, char *msg);
|
||||
void CTFFlagSetup (edict_t *ent);
|
||||
void CTFResetFlag(int ctf_team);
|
||||
void CTFFragBonuses(edict_t *targ, edict_t *inflictor, edict_t *attacker);
|
||||
void CTFCheckHurtCarrier(edict_t *targ, edict_t *attacker);
|
||||
|
||||
// GRAPPLE
|
||||
//CW++
|
||||
void CTFWeapon_Grapple_OffHand(edict_t *self);
|
||||
void CTFResetAllPlayers(void);
|
||||
//CW--
|
||||
|
||||
void CTFWeapon_Grapple (edict_t *ent);
|
||||
void CTFPlayerResetGrapple(edict_t *ent);
|
||||
void CTFGrapplePull(edict_t *self);
|
||||
void CTFResetGrapple(edict_t *self);
|
||||
|
||||
//TECH
|
||||
gitem_t *CTFWhat_Tech(edict_t *ent);
|
||||
qboolean CTFPickup_Tech (edict_t *ent, edict_t *other);
|
||||
void CTFDrop_Tech(edict_t *ent, gitem_t *item);
|
||||
void CTFDeadDropTech(edict_t *ent);
|
||||
void CTFSetupTechSpawn(void);
|
||||
int CTFApplyResistance(edict_t *ent, int dmg);
|
||||
int CTFApplyStrength(edict_t *ent, int dmg);
|
||||
qboolean CTFApplyStrengthSound(edict_t *ent);
|
||||
qboolean CTFApplyHaste(edict_t *ent);
|
||||
void CTFApplyHasteSound(edict_t *ent);
|
||||
void CTFApplyRegeneration(edict_t *ent);
|
||||
qboolean CTFHasRegeneration(edict_t *ent);
|
||||
void CTFRespawnTech(edict_t *ent);
|
||||
void CTFResetTech(void);
|
||||
|
||||
void CTFOpenJoinMenu(edict_t *ent);
|
||||
qboolean CTFStartClient(edict_t *ent);
|
||||
void CTFVoteYes(edict_t *ent);
|
||||
void CTFVoteNo(edict_t *ent);
|
||||
void CTFReady(edict_t *ent);
|
||||
void CTFNotReady(edict_t *ent);
|
||||
qboolean CTFNextMap(void);
|
||||
qboolean CTFMatchSetup(void);
|
||||
qboolean CTFMatchOn(void);
|
||||
void CTFGhost(edict_t *ent);
|
||||
qboolean CTFInMatch(void);
|
||||
void CTFStats(edict_t *ent);
|
||||
void CTFBoot(edict_t *ent, qboolean ban); //CW
|
||||
void CTFPlayerList(edict_t *ent);
|
||||
|
||||
qboolean CTFCheckRules(void);
|
||||
|
||||
void SP_misc_ctf_banner (edict_t *ent);
|
||||
void SP_misc_ctf_small_banner (edict_t *ent);
|
||||
|
||||
extern char *ctf_statusbar;
|
||||
|
||||
void CTFObserver(edict_t *ent);
|
||||
|
||||
void SP_trigger_teleport (edict_t *ent);
|
||||
void SP_info_teleport_destination (edict_t *ent);
|
||||
|
||||
void CTFSetPowerUpEffect(edict_t *ent, int def);
|
||||
|
||||
//CW++
|
||||
extern teamgame_t teamgame;
|
||||
extern asltgame_t asltgame;
|
||||
|
||||
//======================================================================
|
||||
// Team-DM stuff
|
||||
//======================================================================
|
||||
extern char *tdm_statusbar;
|
||||
|
||||
void TDMPrecache(void);
|
||||
void TDMScoreboardMessage(edict_t *ent, edict_t *killer);
|
||||
|
||||
//======================================================================
|
||||
// Assault stuff
|
||||
//======================================================================
|
||||
#define LINESIZE 23
|
||||
#define MAX_SPAWNS 32
|
||||
|
||||
extern char *aslt_statusbar;
|
||||
|
||||
void ASLTPrecache(void);
|
||||
void ASLTSpawn(void);
|
||||
void ASLTShowMission(edict_t *ent);
|
||||
edict_t *SelectASLTSpawnPoint (edict_t *ent);
|
||||
qboolean ASLTCheckRules(void);
|
||||
//CW--
|
569
awaken2/g_trigger.c
Normal file
569
awaken2/g_trigger.c
Normal file
|
@ -0,0 +1,569 @@
|
|||
// g_trigger.c
|
||||
|
||||
#include "g_local.h"
|
||||
|
||||
|
||||
void InitTrigger(edict_t *self)
|
||||
{
|
||||
if (!VectorCompare(self->s.angles, vec3_origin))
|
||||
G_SetMovedir(self->s.angles, self->movedir);
|
||||
|
||||
self->solid = SOLID_TRIGGER;
|
||||
self->movetype = MOVETYPE_NONE;
|
||||
gi.setmodel(self, self->model);
|
||||
self->svflags = SVF_NOCLIENT;
|
||||
}
|
||||
|
||||
// the wait time has passed, so set back up for another activation
|
||||
void multi_wait(edict_t *ent)
|
||||
{
|
||||
ent->nextthink = 0;
|
||||
}
|
||||
|
||||
// the trigger was just activated
|
||||
// ent->activator should be set to the activator so it can be held through a delay
|
||||
// so wait for the delay time before firing
|
||||
void multi_trigger(edict_t *ent)
|
||||
{
|
||||
if (ent->nextthink)
|
||||
return; // already been triggered
|
||||
|
||||
G_UseTargets(ent, ent->activator);
|
||||
|
||||
if (ent->wait > 0.0)
|
||||
{
|
||||
ent->think = multi_wait;
|
||||
ent->nextthink = level.time + ent->wait;
|
||||
}
|
||||
else
|
||||
{ // we can't just remove (self) here, because this is a touch function
|
||||
// called while looping through area links...
|
||||
ent->touch = NULL;
|
||||
ent->nextthink = level.time + FRAMETIME;
|
||||
ent->think = G_FreeEdict;
|
||||
}
|
||||
}
|
||||
|
||||
void Use_Multi(edict_t *ent, edict_t *other, edict_t *activator)
|
||||
{
|
||||
ent->activator = activator;
|
||||
multi_trigger(ent);
|
||||
}
|
||||
|
||||
void Touch_Multi(edict_t *self, edict_t *other, cplane_t *plane, csurface_t *surf)
|
||||
{
|
||||
if (other->client)
|
||||
{
|
||||
if (self->spawnflags & 2)
|
||||
return;
|
||||
}
|
||||
else if (other->svflags & SVF_MONSTER)
|
||||
{
|
||||
if (!(self->spawnflags & 1))
|
||||
return;
|
||||
}
|
||||
else
|
||||
return;
|
||||
|
||||
if (!VectorCompare(self->movedir, vec3_origin))
|
||||
{
|
||||
vec3_t forward;
|
||||
|
||||
AngleVectors(other->s.angles, forward, NULL, NULL);
|
||||
if (_DotProduct(forward, self->movedir) < 0.0)
|
||||
return;
|
||||
}
|
||||
|
||||
self->activator = other;
|
||||
multi_trigger(self);
|
||||
}
|
||||
|
||||
/*QUAKED trigger_multiple (.5 .5 .5) ? MONSTER NOT_PLAYER TRIGGERED
|
||||
Variable sized repeatable trigger. Must be targeted at one or more entities.
|
||||
If "delay" is set, the trigger waits some time after activating before firing.
|
||||
"wait" : Seconds between triggerings. (.2 default)
|
||||
sounds
|
||||
1) secret
|
||||
2) beep beep
|
||||
3) large switch
|
||||
|
||||
set "message" to text string
|
||||
*/
|
||||
void trigger_enable(edict_t *self, edict_t *other, edict_t *activator)
|
||||
{
|
||||
self->solid = SOLID_TRIGGER;
|
||||
self->use = Use_Multi;
|
||||
gi.linkentity(self);
|
||||
}
|
||||
|
||||
void SP_trigger_multiple(edict_t *ent)
|
||||
{
|
||||
if (ent->sounds == 1)
|
||||
ent->noise_index = gi.soundindex("misc/secret.wav");
|
||||
else if (ent->sounds == 2)
|
||||
ent->noise_index = gi.soundindex("misc/talk.wav");
|
||||
else if (ent->sounds == 3)
|
||||
ent->noise_index = gi.soundindex("misc/trigger1.wav");
|
||||
|
||||
if (!ent->wait)
|
||||
ent->wait = 0.2;
|
||||
|
||||
ent->touch = Touch_Multi;
|
||||
ent->movetype = MOVETYPE_NONE;
|
||||
ent->svflags |= SVF_NOCLIENT;
|
||||
|
||||
if (ent->spawnflags & 4)
|
||||
{
|
||||
ent->solid = SOLID_NOT;
|
||||
ent->use = trigger_enable;
|
||||
}
|
||||
else
|
||||
{
|
||||
ent->solid = SOLID_TRIGGER;
|
||||
ent->use = Use_Multi;
|
||||
}
|
||||
|
||||
if (!VectorCompare(ent->s.angles, vec3_origin))
|
||||
G_SetMovedir(ent->s.angles, ent->movedir);
|
||||
|
||||
gi.setmodel(ent, ent->model);
|
||||
gi.linkentity(ent);
|
||||
}
|
||||
|
||||
|
||||
/*QUAKED trigger_once (.5 .5 .5) ? x x TRIGGERED
|
||||
Triggers once, then removes itself.
|
||||
You must set the key "target" to the name of another object in the level that has a matching "targetname".
|
||||
|
||||
If TRIGGERED, this trigger must be triggered before it is live.
|
||||
|
||||
sounds
|
||||
1) secret
|
||||
2) beep beep
|
||||
3) large switch
|
||||
|
||||
"message" string to be displayed when triggered
|
||||
*/
|
||||
|
||||
void SP_trigger_once(edict_t *ent)
|
||||
{
|
||||
// make old maps work because I messed up on flag assignments here
|
||||
// triggered was on bit 1 when it should have been on bit 4
|
||||
if (ent->spawnflags & 1)
|
||||
{
|
||||
vec3_t v;
|
||||
|
||||
VectorMA (ent->mins, 0.5, ent->size, v);
|
||||
ent->spawnflags &= ~1;
|
||||
ent->spawnflags |= 4;
|
||||
gi.dprintf("fixed TRIGGERED flag on %s at %s\n", ent->classname, vtos(v));
|
||||
}
|
||||
|
||||
ent->wait = -1.0;
|
||||
SP_trigger_multiple(ent);
|
||||
}
|
||||
|
||||
/*QUAKED trigger_relay (.5 .5 .5) (-8 -8 -8) (8 8 8)
|
||||
This fixed size trigger cannot be touched, it can only be fired by other events.
|
||||
*/
|
||||
void trigger_relay_use(edict_t *self, edict_t *other, edict_t *activator)
|
||||
{
|
||||
G_UseTargets(self, activator);
|
||||
}
|
||||
|
||||
void SP_trigger_relay(edict_t *self)
|
||||
{
|
||||
self->use = trigger_relay_use;
|
||||
|
||||
//CW++
|
||||
self->svflags |= SVF_NOCLIENT;
|
||||
//CW--
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
==============================================================================
|
||||
trigger_key
|
||||
==============================================================================
|
||||
*/
|
||||
|
||||
/*QUAKED trigger_key (.5 .5 .5) (-8 -8 -8) (8 8 8)
|
||||
A relay trigger that only fires it's targets if player has the proper key.
|
||||
Use "item" to specify the required key, for example "key_data_cd"
|
||||
*/
|
||||
void trigger_key_use(edict_t *self, edict_t *other, edict_t *activator)
|
||||
{
|
||||
int index;
|
||||
|
||||
if (!self->item)
|
||||
return;
|
||||
|
||||
if (!activator->client)
|
||||
return;
|
||||
|
||||
index = ITEM_INDEX(self->item);
|
||||
if (!activator->client->pers.inventory[index])
|
||||
{
|
||||
if (level.time < self->touch_debounce_time)
|
||||
return;
|
||||
|
||||
self->touch_debounce_time = level.time + 5.0;
|
||||
gi_centerprintf (activator, "You need the %s", self->item->pickup_name);
|
||||
gi.sound(activator, CHAN_AUTO, gi.soundindex("misc/keytry.wav"), 1, ATTN_NORM, 0);
|
||||
return;
|
||||
}
|
||||
|
||||
gi.sound(activator, CHAN_AUTO, gi.soundindex("misc/keyuse.wav"), 1, ATTN_NORM, 0);
|
||||
activator->client->pers.inventory[index]--; //CW
|
||||
G_UseTargets(self, activator);
|
||||
self->use = NULL;
|
||||
}
|
||||
|
||||
void SP_trigger_key(edict_t *self)
|
||||
{
|
||||
if (!st.item)
|
||||
{
|
||||
gi.dprintf("no key item for trigger_key at %s\n", vtos(self->s.origin));
|
||||
return;
|
||||
}
|
||||
|
||||
self->item = FindItemByClassname(st.item);
|
||||
if (!self->item)
|
||||
{
|
||||
gi.dprintf("item %s not found for trigger_key at %s\n", st.item, vtos(self->s.origin));
|
||||
return;
|
||||
}
|
||||
|
||||
if (!self->target)
|
||||
{
|
||||
gi.dprintf("%s at %s has no target\n", self->classname, vtos(self->s.origin));
|
||||
return;
|
||||
}
|
||||
|
||||
gi.soundindex("misc/keytry.wav");
|
||||
gi.soundindex("misc/keyuse.wav");
|
||||
|
||||
self->use = trigger_key_use;
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
==============================================================================
|
||||
trigger_counter
|
||||
==============================================================================
|
||||
*/
|
||||
|
||||
/*QUAKED trigger_counter (.5 .5 .5) ? nomessage
|
||||
Acts as an intermediary for an action that takes multiple inputs.
|
||||
|
||||
If nomessage is not set, t will print "1 more.. " etc when triggered and "sequence complete" when finished.
|
||||
|
||||
After the counter has been triggered "count" times (default 2), it will fire all of it's targets and remove itself.
|
||||
*/
|
||||
|
||||
void trigger_counter_use(edict_t *self, edict_t *other, edict_t *activator)
|
||||
{
|
||||
if (self->count == 0)
|
||||
return;
|
||||
|
||||
self->count--;
|
||||
|
||||
if (self->count)
|
||||
{
|
||||
if (!(self->spawnflags & 1))
|
||||
{
|
||||
gi_centerprintf(activator, "%i more to go...", self->count);
|
||||
gi.sound(activator, CHAN_AUTO, gi.soundindex ("misc/talk1.wav"), 1, ATTN_NORM, 0);
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
if (!(self->spawnflags & 1))
|
||||
{
|
||||
gi_centerprintf(activator, "Sequence completed!");
|
||||
gi.sound(activator, CHAN_AUTO, gi.soundindex ("misc/talk1.wav"), 1, ATTN_NORM, 0);
|
||||
}
|
||||
|
||||
self->activator = activator;
|
||||
multi_trigger(self);
|
||||
}
|
||||
|
||||
void SP_trigger_counter(edict_t *self)
|
||||
{
|
||||
self->wait = -1.0;
|
||||
|
||||
if (!self->count)
|
||||
self->count = 2;
|
||||
|
||||
self->use = trigger_counter_use;
|
||||
|
||||
//CW++
|
||||
self->svflags |= SVF_NOCLIENT;
|
||||
//CW--
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
==============================================================================
|
||||
trigger_always
|
||||
==============================================================================
|
||||
*/
|
||||
|
||||
/*QUAKED trigger_always (.5 .5 .5) (-8 -8 -8) (8 8 8)
|
||||
This trigger will always fire. It is activated by the world.
|
||||
*/
|
||||
void SP_trigger_always(edict_t *ent)
|
||||
{
|
||||
// we must have some delay to make sure our use targets are present
|
||||
if (ent->delay < 0.2)
|
||||
ent->delay = 0.2;
|
||||
|
||||
//CW++
|
||||
ent->svflags |= SVF_NOCLIENT;
|
||||
//CW--
|
||||
|
||||
G_UseTargets(ent, ent);
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
==============================================================================
|
||||
trigger_push
|
||||
==============================================================================
|
||||
*/
|
||||
|
||||
#define PUSH_ONCE 1
|
||||
|
||||
static int windsound;
|
||||
|
||||
void trigger_push_touch(edict_t *self, edict_t *other, cplane_t *plane, csurface_t *surf)
|
||||
{
|
||||
if (other->health > 0)
|
||||
{
|
||||
VectorScale(self->movedir, self->speed * 10.0, other->velocity);
|
||||
|
||||
if (other->client)
|
||||
{
|
||||
// don't take falling damage immediately from this
|
||||
VectorCopy(other->velocity, other->client->oldvelocity);
|
||||
if (other->fly_sound_debounce_time < level.time)
|
||||
{
|
||||
other->fly_sound_debounce_time = level.time + 1.5;
|
||||
gi.sound(other, CHAN_AUTO, windsound, 1, ATTN_NORM, 0);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (self->spawnflags & PUSH_ONCE)
|
||||
G_FreeEdict(self);
|
||||
}
|
||||
|
||||
|
||||
/*QUAKED trigger_push (.5 .5 .5) ? PUSH_ONCE
|
||||
Pushes the player
|
||||
"speed" defaults to 1000
|
||||
*/
|
||||
void SP_trigger_push(edict_t *self)
|
||||
{
|
||||
InitTrigger(self);
|
||||
windsound = gi.soundindex("misc/windfly.wav"); //CFIXME make this customisable
|
||||
self->touch = trigger_push_touch;
|
||||
if (!self->speed)
|
||||
self->speed = 1000.0;
|
||||
|
||||
gi.linkentity(self);
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
==============================================================================
|
||||
trigger_hurt
|
||||
==============================================================================
|
||||
*/
|
||||
|
||||
/*QUAKED trigger_hurt (.5 .5 .5) ? START_OFF TOGGLE SILENT NO_PROTECTION SLOW
|
||||
Any entity that touches this will be hurt.
|
||||
|
||||
It does dmg points of damage each server frame
|
||||
|
||||
SILENT supresses playing the sound
|
||||
SLOW changes the damage rate to once per second
|
||||
NO_PROTECTION *nothing* stops the damage
|
||||
|
||||
"dmg" default 5 (whole numbers only)
|
||||
|
||||
*/
|
||||
void hurt_use(edict_t *self, edict_t *other, edict_t *activator)
|
||||
{
|
||||
if (self->solid == SOLID_NOT)
|
||||
self->solid = SOLID_TRIGGER;
|
||||
else
|
||||
self->solid = SOLID_NOT;
|
||||
|
||||
gi.linkentity(self);
|
||||
|
||||
if (!(self->spawnflags & 2))
|
||||
self->use = NULL;
|
||||
}
|
||||
|
||||
void hurt_touch(edict_t *self, edict_t *other, cplane_t *plane, csurface_t *surf)
|
||||
{
|
||||
int dflags;
|
||||
|
||||
if (!other->takedamage)
|
||||
return;
|
||||
|
||||
if (self->timestamp > level.time)
|
||||
return;
|
||||
|
||||
if (self->spawnflags & 16)
|
||||
self->timestamp = level.time + 1.0;
|
||||
else
|
||||
self->timestamp = level.time + FRAMETIME;
|
||||
|
||||
if (!(self->spawnflags & 4))
|
||||
{
|
||||
if ((level.framenum % 10) == 0)
|
||||
gi.sound(other, CHAN_AUTO, self->noise_index, 1, ATTN_NORM, 0);
|
||||
}
|
||||
|
||||
if (self->spawnflags & 8)
|
||||
dflags = DAMAGE_NO_PROTECTION;
|
||||
else
|
||||
dflags = 0;
|
||||
|
||||
//CW++
|
||||
if (other->client && (other->client->agm_enemy != NULL))
|
||||
T_Damage(other, self, other->client->agm_enemy, vec3_origin, other->s.origin, vec3_origin, self->dmg, self->dmg, dflags, MOD_AGM_TRIG_HURT);
|
||||
else
|
||||
//CW--
|
||||
T_Damage(other, self, self, vec3_origin, other->s.origin, vec3_origin, self->dmg, self->dmg, dflags, MOD_TRIGGER_HURT);
|
||||
}
|
||||
|
||||
void SP_trigger_hurt(edict_t *self)
|
||||
{
|
||||
InitTrigger(self);
|
||||
|
||||
self->noise_index = gi.soundindex("world/electro.wav");
|
||||
self->touch = hurt_touch;
|
||||
|
||||
if (!self->dmg)
|
||||
self->dmg = 5;
|
||||
|
||||
if (self->spawnflags & 1)
|
||||
self->solid = SOLID_NOT;
|
||||
else
|
||||
self->solid = SOLID_TRIGGER;
|
||||
|
||||
if (self->spawnflags & 2)
|
||||
self->use = hurt_use;
|
||||
|
||||
gi.linkentity(self);
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
==============================================================================
|
||||
trigger_gravity
|
||||
==============================================================================
|
||||
*/
|
||||
|
||||
/*QUAKED trigger_gravity (.5 .5 .5) ?
|
||||
Changes the touching entites gravity to
|
||||
the value of "gravity". 1.0 is standard
|
||||
gravity for the level.
|
||||
*/
|
||||
|
||||
void trigger_gravity_touch(edict_t *self, edict_t *other, cplane_t *plane, csurface_t *surf)
|
||||
{
|
||||
other->gravity = self->gravity;
|
||||
}
|
||||
|
||||
void SP_trigger_gravity(edict_t *self)
|
||||
{
|
||||
if (st.gravity == 0)
|
||||
{
|
||||
gi.dprintf("trigger_gravity without gravity set at %s\n", vtos(self->s.origin));
|
||||
G_FreeEdict(self);
|
||||
return;
|
||||
}
|
||||
|
||||
InitTrigger(self);
|
||||
self->gravity = atoi(st.gravity);
|
||||
self->touch = trigger_gravity_touch;
|
||||
}
|
||||
|
||||
//CW++
|
||||
|
||||
/*
|
||||
==============================================================================
|
||||
trigger_waypoint
|
||||
==============================================================================
|
||||
*/
|
||||
|
||||
/*QUAKED trigger_waypoint (0 .5 .8) ?
|
||||
ASSAULT: Selects the set of spawn points the attacking team will respawn at.
|
||||
Can only be triggered by a member of the attacking team.
|
||||
Removes itself once triggered.
|
||||
*/
|
||||
void Trigger_Waypoint_Touch(edict_t *self, edict_t *other, cplane_t *plane, csurface_t *surf)
|
||||
{
|
||||
if (!other->client)
|
||||
return;
|
||||
|
||||
if (other->client->resp.ctf_team != asltgame.t_attack)
|
||||
return;
|
||||
|
||||
G_UseTargets(self, other);
|
||||
asltgame.spawn = self->count;
|
||||
|
||||
self->touch = NULL;
|
||||
self->nextthink = level.time + FRAMETIME;
|
||||
self->think = G_FreeEdict;
|
||||
}
|
||||
|
||||
void SP_trigger_waypoint(edict_t *self)
|
||||
{
|
||||
if (sv_gametype->value != G_ASLT)
|
||||
{
|
||||
G_FreeEdict(self);
|
||||
return;
|
||||
}
|
||||
|
||||
InitTrigger(self);
|
||||
self->touch = Trigger_Waypoint_Touch;
|
||||
|
||||
if (self->count < 1)
|
||||
self->count = 1;
|
||||
|
||||
gi.linkentity(self);
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
==============================================================================
|
||||
trigger_kill
|
||||
|
||||
Internal entity used to kill players that enter its bounding box.
|
||||
Essentially a func_killbox, but without a brush model.
|
||||
==============================================================================
|
||||
*/
|
||||
void Trigger_Kill_Touch(edict_t *self, edict_t *other, cplane_t *plane, csurface_t *surf)
|
||||
{
|
||||
if (!other->client)
|
||||
return;
|
||||
|
||||
T_Damage(other, self, self, vec3_origin, other->s.origin, vec3_origin, 100000, 0, DAMAGE_NO_PROTECTION, MOD_FORBIDDEN);
|
||||
}
|
||||
|
||||
void SP_trigger_kill(edict_t *self)
|
||||
{
|
||||
self->solid = SOLID_TRIGGER;
|
||||
self->movetype = MOVETYPE_NONE;
|
||||
self->svflags = SVF_NOCLIENT;
|
||||
self->touch = Trigger_Kill_Touch;
|
||||
self->classname = "trigger_kill";
|
||||
|
||||
gi.linkentity(self);
|
||||
}
|
||||
//CW--
|
1281
awaken2/g_turret.c
Normal file
1281
awaken2/g_turret.c
Normal file
File diff suppressed because it is too large
Load diff
1790
awaken2/g_utils.c
Normal file
1790
awaken2/g_utils.c
Normal file
File diff suppressed because it is too large
Load diff
3843
awaken2/g_weapon.c
Normal file
3843
awaken2/g_weapon.c
Normal file
File diff suppressed because it is too large
Load diff
2
awaken2/game.def
Normal file
2
awaken2/game.def
Normal file
|
@ -0,0 +1,2 @@
|
|||
EXPORTS
|
||||
GetGameAPI
|
259
awaken2/game.h
Normal file
259
awaken2/game.h
Normal file
|
@ -0,0 +1,259 @@
|
|||
// game.h -- game dll information visible to server
|
||||
|
||||
#define GAME_API_VERSION 3
|
||||
|
||||
// edict->svflags
|
||||
|
||||
#define SVF_NOCLIENT 0x00000001 // don't send entity to clients, even if it has effects
|
||||
#define SVF_DEADMONSTER 0x00000002 // treat as CONTENTS_DEADMONSTER for collision
|
||||
#define SVF_MONSTER 0x00000004 // treat as CONTENTS_MONSTER for collision
|
||||
//ZOID++
|
||||
#define SVF_PROJECTILE 0x00000008 // entity is simple projectile, used for network optimization
|
||||
#define SVF_GIB 0x00000040 // Knightmare- gib flag
|
||||
// If an entity is projectile, the model index/x/y/z/pitch/yaw are sent, encoded into
|
||||
// seven (or eight) bytes. This is to speed up projectiles. Currently, only the
|
||||
// hyperblaster makes use of this. Use for items that are moving with a constant
|
||||
// velocity that don't change direction or model.
|
||||
//ZOID--
|
||||
|
||||
// edict->solid values
|
||||
|
||||
typedef enum
|
||||
{
|
||||
SOLID_NOT, // no interaction with other objects
|
||||
SOLID_TRIGGER, // only touch when inside, after moving
|
||||
SOLID_BBOX, // touch on edge
|
||||
SOLID_BSP // bsp clip, touch on edge
|
||||
} solid_t;
|
||||
|
||||
// Filesytem data types
|
||||
#ifdef GAME_INCLUDE
|
||||
typedef int fileHandle_t;
|
||||
|
||||
typedef enum {
|
||||
FS_READ,
|
||||
FS_WRITE,
|
||||
FS_APPEND
|
||||
} fsMode_t;
|
||||
#endif // GAME_INCLUDE
|
||||
|
||||
//===============================================================
|
||||
|
||||
// link_t is only used for entity area links now
|
||||
typedef struct link_s
|
||||
{
|
||||
struct link_s *prev;
|
||||
struct link_s *next;
|
||||
} link_t;
|
||||
|
||||
#define MAX_ENT_CLUSTERS 16
|
||||
|
||||
|
||||
typedef struct edict_s edict_t;
|
||||
typedef struct gclient_s gclient_t;
|
||||
|
||||
|
||||
#ifndef GAME_INCLUDE
|
||||
|
||||
struct gclient_s
|
||||
{
|
||||
player_state_t ps; // communicated by server to clients
|
||||
int ping;
|
||||
// the game dll can add anything it wants after
|
||||
// this point in the structure
|
||||
};
|
||||
|
||||
|
||||
struct edict_s
|
||||
{
|
||||
entity_state_t s;
|
||||
struct gclient_s *client;
|
||||
qboolean inuse;
|
||||
int linkcount;
|
||||
|
||||
// FIXME: move these fields to a server private sv_entity_t
|
||||
link_t area; // linked to a division node or leaf
|
||||
|
||||
int num_clusters; // if -1, use headnode instead
|
||||
int clusternums[MAX_ENT_CLUSTERS];
|
||||
int headnode; // unused if num_clusters != -1
|
||||
int areanum;
|
||||
int areanum2;
|
||||
|
||||
//================================
|
||||
|
||||
int svflags; // SVF_NOCLIENT, SVF_DEADMONSTER, SVF_MONSTER, etc
|
||||
vec3_t mins;
|
||||
vec3_t maxs;
|
||||
vec3_t absmin;
|
||||
vec3_t absmax;
|
||||
vec3_t size;
|
||||
solid_t solid;
|
||||
int clipmask;
|
||||
edict_t *owner;
|
||||
|
||||
// the game dll can add anything it wants after
|
||||
// this point in the structure
|
||||
};
|
||||
|
||||
#endif // GAME_INCLUDE
|
||||
|
||||
//===============================================================
|
||||
|
||||
//
|
||||
// functions provided by the main engine
|
||||
//
|
||||
typedef struct
|
||||
{
|
||||
// special messages
|
||||
void (*bprintf) (int printlevel, char *fmt, ...);
|
||||
void (*dprintf) (char *fmt, ...);
|
||||
void (*cprintf) (edict_t *ent, int printlevel, char *fmt, ...);
|
||||
void (*centerprintf) (edict_t *ent, char *fmt, ...);
|
||||
void (*sound) (edict_t *ent, int channel, int soundindex, float volume, float attenuation, float timeofs);
|
||||
void (*positioned_sound) (vec3_t origin, edict_t *ent, int channel, int soundinedex, float volume, float attenuation, float timeofs);
|
||||
|
||||
// config strings hold all the index strings, the lightstyles,
|
||||
// and misc data like the sky definition and cdtrack.
|
||||
// All of the current configstrings are sent to clients when
|
||||
// they connect, and changes are sent to all connected clients.
|
||||
void (*configstring) (int num, char *string);
|
||||
|
||||
void (*error) (char *fmt, ...);
|
||||
|
||||
// the *index functions create configstrings and some internal server state
|
||||
int (*modelindex) (char *name);
|
||||
int (*soundindex) (char *name);
|
||||
int (*imageindex) (char *name);
|
||||
|
||||
void (*setmodel) (edict_t *ent, char *name);
|
||||
|
||||
// collision detection
|
||||
trace_t (*trace) (vec3_t start, vec3_t mins, vec3_t maxs, vec3_t end, edict_t *passent, int contentmask);
|
||||
int (*pointcontents) (vec3_t point);
|
||||
qboolean (*inPVS) (vec3_t p1, vec3_t p2);
|
||||
qboolean (*inPHS) (vec3_t p1, vec3_t p2);
|
||||
void (*SetAreaPortalState) (int portalnum, qboolean open);
|
||||
qboolean (*AreasConnected) (int area1, int area2);
|
||||
|
||||
// an entity will never be sent to a client or used for collision
|
||||
// if it is not passed to linkentity. If the size, position, or
|
||||
// solidity changes, it must be relinked.
|
||||
void (*linkentity) (edict_t *ent);
|
||||
void (*unlinkentity) (edict_t *ent); // call before removing an interactive edict
|
||||
int (*BoxEdicts) (vec3_t mins, vec3_t maxs, edict_t **list, int maxcount, int areatype);
|
||||
void (*Pmove) (pmove_t *pmove); // player movement code common with client prediction
|
||||
|
||||
// network messaging
|
||||
void (*multicast) (vec3_t origin, multicast_t to);
|
||||
void (*unicast) (edict_t *ent, qboolean reliable);
|
||||
void (*WriteChar) (int c);
|
||||
void (*WriteByte) (int c);
|
||||
void (*WriteShort) (int c);
|
||||
void (*WriteLong) (int c);
|
||||
void (*WriteFloat) (float f);
|
||||
void (*WriteString) (char *s);
|
||||
void (*WritePosition) (vec3_t pos); // some fractional bits
|
||||
void (*WriteDir) (vec3_t pos); // single byte encoded, very coarse
|
||||
void (*WriteAngle) (float f);
|
||||
|
||||
// managed memory allocation
|
||||
void *(*TagMalloc) (int size, int tag);
|
||||
void (*TagFree) (void *block);
|
||||
void (*FreeTags) (int tag);
|
||||
|
||||
// console variable interaction
|
||||
cvar_t *(*cvar) (char *var_name, char *value, int flags);
|
||||
cvar_t *(*cvar_set) (char *var_name, char *value);
|
||||
cvar_t *(*cvar_forceset) (char *var_name, char *value);
|
||||
|
||||
// ClientCommand and ServerCommand parameter access
|
||||
int (*argc) (void);
|
||||
char *(*argv) (int n);
|
||||
char *(*args) (void); // concatenation of all argv >= 1
|
||||
|
||||
// add commands to the server console as if they were typed in
|
||||
// for map changing, etc
|
||||
void (*AddCommandString) (char *text);
|
||||
|
||||
void (*DebugGraph) (float value, int color);
|
||||
|
||||
// Knightmare- support game DLL loading from pak files thru engine
|
||||
// This can be used to load script files, etc
|
||||
// Also support open, read/write and closing files
|
||||
#ifdef KMQUAKE2_ENGINE_MOD
|
||||
char **(*ListPak) (const char *find, int *num); // Deprecated- DO NOT USE!
|
||||
int (*LoadFile) (const char *name, void **buf);
|
||||
void (*FreeFile) (void *buf);
|
||||
void (*FreeFileList) (char **list, int n);
|
||||
int (*OpenFile) (const char *name, fileHandle_t *f, fsMode_t mode);
|
||||
int (*OpenCompressedFile) (const char *zipName, const char *fileName, fileHandle_t *f, fsMode_t mode);
|
||||
void (*CloseFile) (fileHandle_t f);
|
||||
int (*FRead) (void *buffer, int size, fileHandle_t f);
|
||||
int (*FWrite) (const void *buffer, int size, fileHandle_t f);
|
||||
char *(*GameDir) (void);
|
||||
char *(*SaveGameDir) (void);
|
||||
void (*CreatePath) (const char *path);
|
||||
char **(*GetFileList) (const char *path, const char *extension, int *num);
|
||||
#endif
|
||||
|
||||
} game_import_t;
|
||||
|
||||
//
|
||||
// functions exported by the game subsystem
|
||||
//
|
||||
typedef struct
|
||||
{
|
||||
int apiversion;
|
||||
|
||||
// the init function will only be called when a game starts,
|
||||
// not each time a level is loaded. Persistant data for clients
|
||||
// and the server can be allocated in init
|
||||
void (*Init) (void);
|
||||
void (*Shutdown) (void);
|
||||
|
||||
// each new level entered will cause a call to SpawnEntities
|
||||
void (*SpawnEntities) (char *mapname, char *entstring, char *spawnpoint);
|
||||
|
||||
// Read/Write Game is for storing persistant cross level information
|
||||
// about the world state and the clients.
|
||||
// WriteGame is called every time a level is exited.
|
||||
// ReadGame is called on a loadgame.
|
||||
void (*WriteGame) (char *filename, qboolean autosave);
|
||||
void (*ReadGame) (char *filename);
|
||||
|
||||
// ReadLevel is called after the default map information has been
|
||||
// loaded with SpawnEntities
|
||||
void (*WriteLevel) (char *filename);
|
||||
void (*ReadLevel) (char *filename);
|
||||
|
||||
qboolean (*ClientConnect) (edict_t *ent, char *userinfo);
|
||||
void (*ClientBegin) (edict_t *ent);
|
||||
void (*ClientUserinfoChanged) (edict_t *ent, char *userinfo);
|
||||
void (*ClientDisconnect) (edict_t *ent);
|
||||
void (*ClientCommand) (edict_t *ent);
|
||||
void (*ClientThink) (edict_t *ent, usercmd_t *cmd);
|
||||
|
||||
void (*RunFrame) (void);
|
||||
|
||||
// ServerCommand will be called when an "sv <command>" command is issued on the
|
||||
// server console.
|
||||
// The game can issue gi.argc() / gi.argv() commands to get the rest
|
||||
// of the parameters
|
||||
void (*ServerCommand) (void);
|
||||
|
||||
//
|
||||
// global variables shared between game and server
|
||||
//
|
||||
|
||||
// The edict array is allocated in the game dll so it
|
||||
// can vary in size from one game to another.
|
||||
//
|
||||
// The size will be fixed when ge->Init() is called
|
||||
struct edict_s *edicts;
|
||||
int edict_size;
|
||||
int num_edicts; // current number, <= max_edicts
|
||||
int max_edicts;
|
||||
} game_export_t;
|
||||
|
||||
game_export_t *GetGameApi(game_import_t *import);
|
204
awaken2/m_player.h
Normal file
204
awaken2/m_player.h
Normal file
|
@ -0,0 +1,204 @@
|
|||
// m_player.h
|
||||
|
||||
// This file generated by qdata - Do NOT Modify
|
||||
|
||||
#define FRAME_stand01 0
|
||||
#define FRAME_stand02 1
|
||||
#define FRAME_stand03 2
|
||||
#define FRAME_stand04 3
|
||||
#define FRAME_stand05 4
|
||||
#define FRAME_stand06 5
|
||||
#define FRAME_stand07 6
|
||||
#define FRAME_stand08 7
|
||||
#define FRAME_stand09 8
|
||||
#define FRAME_stand10 9
|
||||
#define FRAME_stand11 10
|
||||
#define FRAME_stand12 11
|
||||
#define FRAME_stand13 12
|
||||
#define FRAME_stand14 13
|
||||
#define FRAME_stand15 14
|
||||
#define FRAME_stand16 15
|
||||
#define FRAME_stand17 16
|
||||
#define FRAME_stand18 17
|
||||
#define FRAME_stand19 18
|
||||
#define FRAME_stand20 19
|
||||
#define FRAME_stand21 20
|
||||
#define FRAME_stand22 21
|
||||
#define FRAME_stand23 22
|
||||
#define FRAME_stand24 23
|
||||
#define FRAME_stand25 24
|
||||
#define FRAME_stand26 25
|
||||
#define FRAME_stand27 26
|
||||
#define FRAME_stand28 27
|
||||
#define FRAME_stand29 28
|
||||
#define FRAME_stand30 29
|
||||
#define FRAME_stand31 30
|
||||
#define FRAME_stand32 31
|
||||
#define FRAME_stand33 32
|
||||
#define FRAME_stand34 33
|
||||
#define FRAME_stand35 34
|
||||
#define FRAME_stand36 35
|
||||
#define FRAME_stand37 36
|
||||
#define FRAME_stand38 37
|
||||
#define FRAME_stand39 38
|
||||
#define FRAME_stand40 39
|
||||
#define FRAME_run1 40
|
||||
#define FRAME_run2 41
|
||||
#define FRAME_run3 42
|
||||
#define FRAME_run4 43
|
||||
#define FRAME_run5 44
|
||||
#define FRAME_run6 45
|
||||
#define FRAME_attack1 46
|
||||
#define FRAME_attack2 47
|
||||
#define FRAME_attack3 48
|
||||
#define FRAME_attack4 49
|
||||
#define FRAME_attack5 50
|
||||
#define FRAME_attack6 51
|
||||
#define FRAME_attack7 52
|
||||
#define FRAME_attack8 53
|
||||
#define FRAME_pain101 54
|
||||
#define FRAME_pain102 55
|
||||
#define FRAME_pain103 56
|
||||
#define FRAME_pain104 57
|
||||
#define FRAME_pain201 58
|
||||
#define FRAME_pain202 59
|
||||
#define FRAME_pain203 60
|
||||
#define FRAME_pain204 61
|
||||
#define FRAME_pain301 62
|
||||
#define FRAME_pain302 63
|
||||
#define FRAME_pain303 64
|
||||
#define FRAME_pain304 65
|
||||
#define FRAME_jump1 66
|
||||
#define FRAME_jump2 67
|
||||
#define FRAME_jump3 68
|
||||
#define FRAME_jump4 69
|
||||
#define FRAME_jump5 70
|
||||
#define FRAME_jump6 71
|
||||
#define FRAME_flip01 72
|
||||
#define FRAME_flip02 73
|
||||
#define FRAME_flip03 74
|
||||
#define FRAME_flip04 75
|
||||
#define FRAME_flip05 76
|
||||
#define FRAME_flip06 77
|
||||
#define FRAME_flip07 78
|
||||
#define FRAME_flip08 79
|
||||
#define FRAME_flip09 80
|
||||
#define FRAME_flip10 81
|
||||
#define FRAME_flip11 82
|
||||
#define FRAME_flip12 83
|
||||
#define FRAME_salute01 84
|
||||
#define FRAME_salute02 85
|
||||
#define FRAME_salute03 86
|
||||
#define FRAME_salute04 87
|
||||
#define FRAME_salute05 88
|
||||
#define FRAME_salute06 89
|
||||
#define FRAME_salute07 90
|
||||
#define FRAME_salute08 91
|
||||
#define FRAME_salute09 92
|
||||
#define FRAME_salute10 93
|
||||
#define FRAME_salute11 94
|
||||
#define FRAME_taunt01 95
|
||||
#define FRAME_taunt02 96
|
||||
#define FRAME_taunt03 97
|
||||
#define FRAME_taunt04 98
|
||||
#define FRAME_taunt05 99
|
||||
#define FRAME_taunt06 100
|
||||
#define FRAME_taunt07 101
|
||||
#define FRAME_taunt08 102
|
||||
#define FRAME_taunt09 103
|
||||
#define FRAME_taunt10 104
|
||||
#define FRAME_taunt11 105
|
||||
#define FRAME_taunt12 106
|
||||
#define FRAME_taunt13 107
|
||||
#define FRAME_taunt14 108
|
||||
#define FRAME_taunt15 109
|
||||
#define FRAME_taunt16 110
|
||||
#define FRAME_taunt17 111
|
||||
#define FRAME_wave01 112
|
||||
#define FRAME_wave02 113
|
||||
#define FRAME_wave03 114
|
||||
#define FRAME_wave04 115
|
||||
#define FRAME_wave05 116
|
||||
#define FRAME_wave06 117
|
||||
#define FRAME_wave07 118
|
||||
#define FRAME_wave08 119
|
||||
#define FRAME_wave09 120
|
||||
#define FRAME_wave10 121
|
||||
#define FRAME_wave11 122
|
||||
#define FRAME_point01 123
|
||||
#define FRAME_point02 124
|
||||
#define FRAME_point03 125
|
||||
#define FRAME_point04 126
|
||||
#define FRAME_point05 127
|
||||
#define FRAME_point06 128
|
||||
#define FRAME_point07 129
|
||||
#define FRAME_point08 130
|
||||
#define FRAME_point09 131
|
||||
#define FRAME_point10 132
|
||||
#define FRAME_point11 133
|
||||
#define FRAME_point12 134
|
||||
#define FRAME_crstnd01 135
|
||||
#define FRAME_crstnd02 136
|
||||
#define FRAME_crstnd03 137
|
||||
#define FRAME_crstnd04 138
|
||||
#define FRAME_crstnd05 139
|
||||
#define FRAME_crstnd06 140
|
||||
#define FRAME_crstnd07 141
|
||||
#define FRAME_crstnd08 142
|
||||
#define FRAME_crstnd09 143
|
||||
#define FRAME_crstnd10 144
|
||||
#define FRAME_crstnd11 145
|
||||
#define FRAME_crstnd12 146
|
||||
#define FRAME_crstnd13 147
|
||||
#define FRAME_crstnd14 148
|
||||
#define FRAME_crstnd15 149
|
||||
#define FRAME_crstnd16 150
|
||||
#define FRAME_crstnd17 151
|
||||
#define FRAME_crstnd18 152
|
||||
#define FRAME_crstnd19 153
|
||||
#define FRAME_crwalk1 154
|
||||
#define FRAME_crwalk2 155
|
||||
#define FRAME_crwalk3 156
|
||||
#define FRAME_crwalk4 157
|
||||
#define FRAME_crwalk5 158
|
||||
#define FRAME_crwalk6 159
|
||||
#define FRAME_crattak1 160
|
||||
#define FRAME_crattak2 161
|
||||
#define FRAME_crattak3 162
|
||||
#define FRAME_crattak4 163
|
||||
#define FRAME_crattak5 164
|
||||
#define FRAME_crattak6 165
|
||||
#define FRAME_crattak7 166
|
||||
#define FRAME_crattak8 167
|
||||
#define FRAME_crattak9 168
|
||||
#define FRAME_crpain1 169
|
||||
#define FRAME_crpain2 170
|
||||
#define FRAME_crpain3 171
|
||||
#define FRAME_crpain4 172
|
||||
#define FRAME_crdeath1 173
|
||||
#define FRAME_crdeath2 174
|
||||
#define FRAME_crdeath3 175
|
||||
#define FRAME_crdeath4 176
|
||||
#define FRAME_crdeath5 177
|
||||
#define FRAME_death101 178
|
||||
#define FRAME_death102 179
|
||||
#define FRAME_death103 180
|
||||
#define FRAME_death104 181
|
||||
#define FRAME_death105 182
|
||||
#define FRAME_death106 183
|
||||
#define FRAME_death201 184
|
||||
#define FRAME_death202 185
|
||||
#define FRAME_death203 186
|
||||
#define FRAME_death204 187
|
||||
#define FRAME_death205 188
|
||||
#define FRAME_death206 189
|
||||
#define FRAME_death301 190
|
||||
#define FRAME_death302 191
|
||||
#define FRAME_death303 192
|
||||
#define FRAME_death304 193
|
||||
#define FRAME_death305 194
|
||||
#define FRAME_death306 195
|
||||
#define FRAME_death307 196
|
||||
#define FRAME_death308 197
|
||||
|
||||
#define MODEL_SCALE 1.000000
|
3800
awaken2/p_client.c
Normal file
3800
awaken2/p_client.c
Normal file
File diff suppressed because it is too large
Load diff
842
awaken2/p_hud.c
Normal file
842
awaken2/p_hud.c
Normal file
|
@ -0,0 +1,842 @@
|
|||
// p_hud.c
|
||||
|
||||
#include "g_local.h"
|
||||
|
||||
/*
|
||||
======================================================================
|
||||
|
||||
INTERMISSION
|
||||
|
||||
======================================================================
|
||||
*/
|
||||
|
||||
void MoveClientToIntermission(edict_t *ent)
|
||||
{
|
||||
ent->client->showscores = true; //CW
|
||||
|
||||
VectorCopy(level.intermission_origin, ent->s.origin);
|
||||
ent->client->ps.pmove.origin[0] = level.intermission_origin[0] * 8;
|
||||
ent->client->ps.pmove.origin[1] = level.intermission_origin[1] * 8;
|
||||
ent->client->ps.pmove.origin[2] = level.intermission_origin[2] * 8;
|
||||
VectorCopy(level.intermission_angle, ent->client->ps.viewangles);
|
||||
ent->client->ps.pmove.pm_type = PM_FREEZE;
|
||||
ent->client->ps.gunindex = 0;
|
||||
#ifdef KMQUAKE2_ENGINE_MOD
|
||||
ent->client->ps.gunindex2 = 0;
|
||||
#endif
|
||||
ent->client->ps.blend[3] = 0;
|
||||
ent->client->ps.rdflags &= ~RDF_UNDERWATER;
|
||||
|
||||
// Clean up powerup info.
|
||||
|
||||
ent->client->quad_framenum = 0;
|
||||
ent->client->invincible_framenum = 0;
|
||||
ent->client->breather_framenum = 0;
|
||||
ent->client->enviro_framenum = 0;
|
||||
ent->client->grenade_blew_up = false;
|
||||
ent->client->grenade_time = 0;
|
||||
//CW++
|
||||
ent->client->show_gausscharge = false;
|
||||
ent->client->show_gausstarget = 0;
|
||||
ent->client->gauss_dmg = 0;
|
||||
ent->client->gauss_framenum = 0;
|
||||
|
||||
ent->client->antibeam_framenum = 0;
|
||||
ent->client->frozen_framenum = 0;
|
||||
ent->client->siphon_framenum = 0;
|
||||
ent->client->needle_framenum = 0;
|
||||
ent->client->haste_framenum = 0;
|
||||
|
||||
ent->client->mod_changeteam = false;
|
||||
ent->burning = false;
|
||||
ent->disintegrated = false;
|
||||
ent->tractored = false;
|
||||
|
||||
ent->client->agm_charge = 0;
|
||||
ent->client->agm_showcharge = false;
|
||||
ent->client->agm_tripped = false;
|
||||
ent->client->agm_on = false;
|
||||
ent->client->agm_push = false;
|
||||
ent->client->agm_pull = false;
|
||||
ent->client->held_by_agm = false;
|
||||
ent->client->flung_by_agm = false;
|
||||
ent->client->thrown_by_agm = false;
|
||||
ent->client->agm_target = NULL;
|
||||
ent->client->agm_enemy = NULL;
|
||||
|
||||
if (ent->client->ctf_grapple)
|
||||
CTFResetGrapple(ent->client->ctf_grapple);
|
||||
//CW--
|
||||
|
||||
ent->viewheight = 0;
|
||||
ent->s.modelindex = 0;
|
||||
ent->s.modelindex2 = 0;
|
||||
ent->s.modelindex3 = 0;
|
||||
ent->s.modelindex4 = 0; //CW
|
||||
#ifdef KMQUAKE2_ENGINE_MOD
|
||||
ent->s.modelindex5 = 0;
|
||||
ent->s.modelindex6 = 0;
|
||||
#endif
|
||||
ent->s.effects = 0;
|
||||
ent->s.sound = 0;
|
||||
ent->solid = SOLID_NOT;
|
||||
|
||||
// Add the layout.
|
||||
|
||||
//Maj++
|
||||
// don't unicast() to bots!
|
||||
if (ent->isabot)
|
||||
return;
|
||||
//Maj--
|
||||
|
||||
DeathmatchScoreboardMessage(ent, NULL); //CW
|
||||
gi.unicast(ent, true);
|
||||
}
|
||||
|
||||
void BeginIntermission(edict_t *targ)
|
||||
{
|
||||
edict_t *ent;
|
||||
edict_t *client;
|
||||
edict_t *wep_ent; //CW++
|
||||
int i;
|
||||
|
||||
if (level.intermissiontime)
|
||||
return; // already activated
|
||||
|
||||
//ZOID++
|
||||
if ((int)sv_gametype->value > G_FFA) //CW
|
||||
CTFCalcScores();
|
||||
//ZOID--
|
||||
|
||||
game.autosaved = false;
|
||||
|
||||
// Respawn any dead clients.
|
||||
|
||||
for (i = 0; i < (int)maxclients->value; ++i)
|
||||
{
|
||||
client = g_edicts + 1 + i;
|
||||
if (!client->inuse)
|
||||
continue;
|
||||
|
||||
if (client->health < 1)
|
||||
Respawn(client);
|
||||
}
|
||||
|
||||
level.intermissiontime = level.time;
|
||||
level.changemap = targ->map;
|
||||
level.exitintermission = 0; //CW
|
||||
|
||||
// Find an intermission spot.
|
||||
|
||||
ent = G_Find(NULL, FOFS(classname), "info_player_intermission");
|
||||
if (!ent)
|
||||
{ // the map creator forgot to put in an intermission point...
|
||||
ent = G_Find(NULL, FOFS(classname), "info_player_start");
|
||||
if (!ent)
|
||||
ent = G_Find(NULL, FOFS(classname), "info_player_deathmatch");
|
||||
}
|
||||
else
|
||||
{ // chose one of four spots
|
||||
i = rand() & 3;
|
||||
while (i--)
|
||||
{
|
||||
ent = G_Find(ent, FOFS(classname), "info_player_intermission");
|
||||
if (!ent) // wrap around the list
|
||||
ent = G_Find(ent, FOFS(classname), "info_player_intermission");
|
||||
}
|
||||
}
|
||||
|
||||
VectorCopy(ent->s.origin, level.intermission_origin);
|
||||
VectorCopy(ent->s.angles, level.intermission_angle);
|
||||
|
||||
//CW++
|
||||
// Remove weapon entities to avoid server crashes due to delayed player deaths.
|
||||
|
||||
for (i = 0; i < globals.num_edicts; ++i)
|
||||
{
|
||||
wep_ent = &g_edicts[i];
|
||||
|
||||
if (!wep_ent->inuse)
|
||||
continue;
|
||||
|
||||
if ((wep_ent->die == Trap_DieFromDamage) || (wep_ent->die == C4_DieFromDamage))
|
||||
{
|
||||
TList_DelNode(wep_ent);
|
||||
G_FreeEdict(wep_ent);
|
||||
}
|
||||
|
||||
if (wep_ent->wep_proj)
|
||||
G_FreeEdict(wep_ent);
|
||||
}
|
||||
//CW--
|
||||
|
||||
// Move all clients to the intermission point.
|
||||
|
||||
for (i = 0; i < (int)maxclients->value; ++i)
|
||||
{
|
||||
client = g_edicts + 1 + i;
|
||||
if (!client->inuse)
|
||||
continue;
|
||||
//CW++
|
||||
if (client->isabot)
|
||||
continue;
|
||||
//CW--
|
||||
|
||||
MoveClientToIntermission(client);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
==================
|
||||
DeathmatchScoreboardMessage
|
||||
|
||||
==================
|
||||
*/
|
||||
void DeathmatchScoreboardMessage(edict_t *ent, edict_t *killer)
|
||||
{
|
||||
gclient_t *cl;
|
||||
edict_t *cl_ent;
|
||||
char entry[1024];
|
||||
char string[1400];
|
||||
char *tag;
|
||||
char entry2[64]; //CW++
|
||||
int stringlength;
|
||||
int i, j, k;
|
||||
int sorted[MAX_CLIENTS];
|
||||
int sortedscores[MAX_CLIENTS];
|
||||
int score;
|
||||
int total;
|
||||
int picnum;
|
||||
int x, y;
|
||||
|
||||
//CW++
|
||||
if (ent->client->showscores || ent->client->showinventory)
|
||||
{
|
||||
if (ent->client->show_gausstarget)
|
||||
ent->client->show_gausstarget = 2;
|
||||
}
|
||||
|
||||
if (ent->client->showscores)
|
||||
{
|
||||
//CW--
|
||||
|
||||
//ZOID++
|
||||
if (sv_gametype->value == G_CTF) //CW
|
||||
{
|
||||
CTFScoreboardMessage(ent, killer);
|
||||
return;
|
||||
}
|
||||
//ZOID--
|
||||
|
||||
//CW++
|
||||
else if ((sv_gametype->value == G_TDM) || (sv_gametype->value == G_ASLT))
|
||||
{
|
||||
TDMScoreboardMessage(ent, killer);
|
||||
return;
|
||||
}
|
||||
//CW--
|
||||
|
||||
// sort the clients by score
|
||||
total = 0;
|
||||
for (i = 0; i < game.maxclients; i++)
|
||||
{
|
||||
cl_ent = g_edicts + 1 + i;
|
||||
if (!cl_ent->inuse)
|
||||
continue;
|
||||
//CW++
|
||||
if (cl_ent->client->spectator)
|
||||
continue;
|
||||
//CW--
|
||||
score = game.clients[i].resp.score;
|
||||
for (j = 0; j < total; j++)
|
||||
{
|
||||
if (score > sortedscores[j])
|
||||
break;
|
||||
}
|
||||
for (k = total; k > j; k--)
|
||||
{
|
||||
sorted[k] = sorted[k-1];
|
||||
sortedscores[k] = sortedscores[k-1];
|
||||
}
|
||||
sorted[j] = i;
|
||||
sortedscores[j] = score;
|
||||
total++;
|
||||
}
|
||||
|
||||
//CW++
|
||||
// Add spectators to the end of the list.
|
||||
|
||||
for (i = 0; i < game.maxclients; i++)
|
||||
{
|
||||
cl_ent = g_edicts + 1 + i;
|
||||
if (!cl_ent->inuse)
|
||||
continue;
|
||||
if (!cl_ent->client->spectator)
|
||||
continue;
|
||||
|
||||
sorted[total] = i;
|
||||
sortedscores[total] = 0;
|
||||
total++;
|
||||
}
|
||||
//CW--
|
||||
|
||||
// print level name and exit rules
|
||||
string[0] = 0;
|
||||
stringlength = (int)strlen(string);
|
||||
|
||||
// add the clients in sorted order
|
||||
if (total > 12)
|
||||
total = 12;
|
||||
|
||||
for (i = 0; i < total; i++)
|
||||
{
|
||||
cl = &game.clients[sorted[i]];
|
||||
cl_ent = g_edicts + 1 + sorted[i];
|
||||
|
||||
picnum = gi.imageindex("i_fixme");
|
||||
x = (i >= 6) ? 160 : 0;
|
||||
y = 32 + 32 * (i % 6);
|
||||
|
||||
// add a dogtag
|
||||
if (cl_ent == ent)
|
||||
tag = "tag1";
|
||||
else if (cl_ent == killer)
|
||||
tag = "tag2";
|
||||
else
|
||||
tag = NULL;
|
||||
if (tag)
|
||||
{
|
||||
Com_sprintf(entry, sizeof(entry), "xv %i yv %i picn %s ", x+32, y, tag);
|
||||
j = (int)strlen(entry);
|
||||
if (stringlength + j > 1024)
|
||||
break;
|
||||
|
||||
// strcpy(string + stringlength, entry);
|
||||
Com_strcpy(string + stringlength, sizeof(string)-stringlength, entry);
|
||||
stringlength += j;
|
||||
}
|
||||
|
||||
// send the layout
|
||||
//CW++
|
||||
if (cl->spectator)
|
||||
{
|
||||
Com_sprintf(entry, sizeof(entry), "xv %d yv %d string2 \"%s\" ", x+32, y, cl->pers.netname);
|
||||
Com_sprintf(entry2, sizeof(entry2), "xv %d yv %d string \"(Spectator)\" ", x+32, y+8);
|
||||
Com_strcat(entry, sizeof(entry), entry2);
|
||||
if (cl->chase_target)
|
||||
{
|
||||
Com_sprintf(entry2, sizeof(entry2), "xv %d yv %d string \"Watching:\" ", x+32, y+16);
|
||||
Com_strcat(entry, sizeof(entry), entry2);
|
||||
Com_sprintf(entry2, sizeof(entry2), "xv %d yv %d string \"%s\" ", x+32, y+24, cl->chase_target->client->pers.netname);
|
||||
Com_strcat(entry, sizeof(entry), entry2);
|
||||
}
|
||||
}
|
||||
else
|
||||
//CW--
|
||||
Com_sprintf(entry, sizeof(entry), "client %i %i %i %i %i %i ", x, y, sorted[i], cl->resp.score, cl->ping, (int)((level.framenum - cl->resp.enterframe)/600));
|
||||
j = (int)strlen(entry);
|
||||
if (stringlength + j > 1024)
|
||||
break;
|
||||
|
||||
// strcpy(string + stringlength, entry);
|
||||
Com_strcpy(string + stringlength, sizeof(string)-stringlength,entry);
|
||||
stringlength += j;
|
||||
}
|
||||
|
||||
//CW++
|
||||
}
|
||||
else
|
||||
*string = 0;
|
||||
|
||||
if (ent->client->show_gausstarget & 1)
|
||||
ShowGaussTarget(ent, string, sizeof(string));
|
||||
//CW--
|
||||
|
||||
gi.WriteByte(svc_layout);
|
||||
gi.WriteString(string);
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
==================
|
||||
DeathmatchScoreboard
|
||||
|
||||
Draw instead of help message.
|
||||
Note that it isn't that hard to overflow the 1400 byte message limit!
|
||||
==================
|
||||
*/
|
||||
void DeathmatchScoreboard(edict_t *ent)
|
||||
{
|
||||
//Maj++
|
||||
// don't unicast() to bots!
|
||||
if (ent->isabot)
|
||||
return;
|
||||
//Maj--
|
||||
|
||||
DeathmatchScoreboardMessage(ent, ent->enemy);
|
||||
gi.unicast(ent, true);
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
==================
|
||||
Cmd_Score_f
|
||||
|
||||
Display the scoreboard
|
||||
==================
|
||||
*/
|
||||
void Cmd_Score_f(edict_t *ent)
|
||||
{
|
||||
//CW++
|
||||
if (ent->isabot)
|
||||
return;
|
||||
//CW--
|
||||
|
||||
ent->client->showinventory = false;
|
||||
ent->client->showhelp = false;
|
||||
|
||||
//ZOID++
|
||||
if (ent->client->menu)
|
||||
PMenu_Close(ent);
|
||||
//ZOID--
|
||||
|
||||
if (ent->client->showscores)
|
||||
{
|
||||
ent->client->showscores = false;
|
||||
ent->client->update_chase = true;
|
||||
|
||||
//CW++
|
||||
if (ent->client->show_gausstarget & 2)
|
||||
ent->client->show_gausstarget = 1;
|
||||
//CW--
|
||||
return;
|
||||
}
|
||||
|
||||
ent->client->showscores = true;
|
||||
DeathmatchScoreboard(ent);
|
||||
}
|
||||
|
||||
|
||||
//=======================================================================
|
||||
|
||||
//CW++
|
||||
/*
|
||||
===============
|
||||
SetWepIDView
|
||||
|
||||
This is a modified version of the CTFSetIDView() function written by Zoid.
|
||||
===============
|
||||
*/
|
||||
void SetWepIDView(edict_t *ent)
|
||||
{
|
||||
edict_t *index;
|
||||
edict_t *check;
|
||||
vec3_t forward;
|
||||
vec3_t start;
|
||||
vec3_t dir;
|
||||
float dp_best = 0.0;
|
||||
float dp;
|
||||
float range;
|
||||
qboolean finished = false;
|
||||
|
||||
// If the player has no C4 or Traps, don't bother.
|
||||
|
||||
if (!ent->next_node)
|
||||
{
|
||||
ent->client->ps.stats[STAT_CTF_ID_VIEW_COLOR] = 0;
|
||||
return;
|
||||
}
|
||||
|
||||
// Only check every few frames.
|
||||
|
||||
if (level.time - ent->client->resp.id_trap_time < TRAP_ID_CHECKTIME)
|
||||
return;
|
||||
|
||||
// Cycle through the player's linked list of C4 and Trap entities to determine which
|
||||
// visible entity (if any) is closest to the player's facing direction.
|
||||
|
||||
ent->client->resp.id_trap_time = level.time;
|
||||
ent->client->ps.stats[STAT_CTF_ID_VIEW_COLOR] = 0;
|
||||
AngleVectors(ent->client->v_angle, forward, NULL, NULL);
|
||||
start[0] = ent->s.origin[0];
|
||||
start[1] = ent->s.origin[1];
|
||||
start[2] = ent->s.origin[2] + ent->viewheight;
|
||||
|
||||
index = ent->next_node;
|
||||
while (index && !finished)
|
||||
{
|
||||
check = index;
|
||||
if (index->next_node)
|
||||
index = index->next_node;
|
||||
else
|
||||
finished = true;
|
||||
|
||||
VectorSubtract(check->s.origin, start, dir);
|
||||
range = VectorLength(dir);
|
||||
VectorNormalize(dir);
|
||||
dp = DotProduct(forward, dir);
|
||||
if ((dp > dp_best) && (range < TRAP_ID_RANGE) && visible(ent, check))
|
||||
dp_best = dp;
|
||||
}
|
||||
|
||||
if (dp_best > TRAP_ID_DOTPRODUCT)
|
||||
ent->client->ps.stats[STAT_CTF_ID_VIEW_COLOR] = gi.imageindex("i_no");
|
||||
}
|
||||
//CW--
|
||||
|
||||
/*
|
||||
===============
|
||||
G_SetStats
|
||||
===============
|
||||
*/
|
||||
void G_SetStats(edict_t *ent)
|
||||
{
|
||||
gitem_t *item;
|
||||
int index;
|
||||
int cells = 0; //CW
|
||||
int power_armor_type;
|
||||
|
||||
// health
|
||||
ent->client->ps.stats[STAT_HEALTH_ICON] = level.pic_health;
|
||||
ent->client->ps.stats[STAT_HEALTH] = ent->health;
|
||||
#ifdef KMQUAKE2_ENGINE_MOD // for enhanced HUD
|
||||
// ent->client->ps.stats[STAT_MAXHEALTH] = min(max(ent->client->pers.max_health, 0), 10000);
|
||||
ent->client->ps.stats[STAT_MAXHEALTH] = min(max(ent->max_health, 0), 10000);
|
||||
#endif
|
||||
|
||||
// ammo
|
||||
if (!ent->client->ammo_index)
|
||||
{
|
||||
ent->client->ps.stats[STAT_AMMO_ICON] = 0;
|
||||
ent->client->ps.stats[STAT_AMMO] = 0;
|
||||
#ifdef KMQUAKE2_ENGINE_MOD // for enhanced HUD
|
||||
ent->client->ps.stats[STAT_MAXAMMO] = 0;
|
||||
#endif
|
||||
}
|
||||
else
|
||||
{
|
||||
item = &itemlist[ent->client->ammo_index];
|
||||
ent->client->ps.stats[STAT_AMMO_ICON] = gi.imageindex(item->icon);
|
||||
ent->client->ps.stats[STAT_AMMO] = ent->client->pers.inventory[ent->client->ammo_index];
|
||||
#ifdef KMQUAKE2_ENGINE_MOD // for enhanced HUD
|
||||
ent->client->ps.stats[STAT_MAXAMMO] = min(max(GetMaxAmmoByIndex(ent->client, ent->client->ammo_index), 0), 10000);
|
||||
#endif
|
||||
}
|
||||
|
||||
// armor
|
||||
power_armor_type = PowerArmorType(ent);
|
||||
if (power_armor_type)
|
||||
{
|
||||
cells = ent->client->pers.inventory[ITEM_INDEX(FindItem("cells"))];
|
||||
if (cells == 0)
|
||||
{ // ran out of cells for power armor
|
||||
ent->flags &= ~(FL_POWER_SHIELD|FL_POWER_SCREEN);
|
||||
gi.sound(ent, CHAN_ITEM, gi.soundindex("misc/power2.wav"), 1, ATTN_NORM, 0);
|
||||
power_armor_type = 0;
|
||||
}
|
||||
}
|
||||
|
||||
index = ArmorIndex (ent);
|
||||
if (power_armor_type && (!index || (level.framenum & 8)))
|
||||
{ // flash between power armor and other armor icon
|
||||
if (power_armor_type == POWER_ARMOR_SHIELD)
|
||||
ent->client->ps.stats[STAT_ARMOR_ICON] = gi.imageindex("i_powershield");
|
||||
else // POWER_ARMOR_SCREEN
|
||||
ent->client->ps.stats[STAT_ARMOR_ICON] = gi.imageindex ("i_powerscreen");
|
||||
ent->client->ps.stats[STAT_ARMOR] = cells;
|
||||
#ifdef KMQUAKE2_ENGINE_MOD // for enhanced HUD
|
||||
ent->client->ps.stats[STAT_MAXARMOR] = min(max(ent->client->pers.max_cells, 0), 10000);
|
||||
#endif
|
||||
}
|
||||
else if (index)
|
||||
{
|
||||
item = GetItemByIndex(index);
|
||||
ent->client->ps.stats[STAT_ARMOR_ICON] = gi.imageindex(item->icon);
|
||||
ent->client->ps.stats[STAT_ARMOR] = ent->client->pers.inventory[index];
|
||||
#ifdef KMQUAKE2_ENGINE_MOD // for enhanced HUD
|
||||
ent->client->ps.stats[STAT_MAXARMOR] = min(max(GetMaxArmorByIndex(index), 0), 10000);
|
||||
#endif
|
||||
}
|
||||
else
|
||||
{
|
||||
ent->client->ps.stats[STAT_ARMOR_ICON] = 0;
|
||||
ent->client->ps.stats[STAT_ARMOR] = 0;
|
||||
#ifdef KMQUAKE2_ENGINE_MOD // for enhanced HUD
|
||||
ent->client->ps.stats[STAT_MAXARMOR] = 0;
|
||||
#endif
|
||||
}
|
||||
|
||||
// pickup message
|
||||
if (level.time > ent->client->pickup_msg_time)
|
||||
{
|
||||
ent->client->ps.stats[STAT_PICKUP_ICON] = 0;
|
||||
ent->client->ps.stats[STAT_PICKUP_STRING] = 0;
|
||||
}
|
||||
|
||||
// timers
|
||||
//CW++
|
||||
// Show weapon charges before powerups.
|
||||
|
||||
if (ent->client->show_gausscharge)
|
||||
{
|
||||
ent->client->ps.stats[STAT_TIMER_ICON] = gi.imageindex("a_blaster");
|
||||
if (ent->client->pers.inventory[ent->client->ammo_index] > 0)
|
||||
{
|
||||
ent->client->gauss_dmg = (int)((level.framenum - ent->client->gauss_framenum) / (10.0 * sv_gauss_damage_rate->value));
|
||||
ent->client->gauss_dmg *= (int)sv_gauss_damage_step->value;
|
||||
ent->client->gauss_dmg += (int)sv_gauss_damage_base->value;
|
||||
}
|
||||
else
|
||||
ent->client->gauss_dmg = (int)sv_gauss_damage_base->value;
|
||||
|
||||
if (ent->client->gauss_dmg > sv_gauss_damage_max->value)
|
||||
ent->client->gauss_dmg = (int)sv_gauss_damage_max->value;
|
||||
|
||||
ent->client->ps.stats[STAT_TIMER] = ent->client->gauss_dmg;
|
||||
#ifdef KMQUAKE2_ENGINE_MOD // for enhanced HUD
|
||||
ent->client->ps.stats[STAT_TIMER_RANGE] = min(max((int)sv_gauss_damage_max->value, 0), 10000);
|
||||
#endif
|
||||
}
|
||||
else if (ent->client->agm_showcharge)
|
||||
{
|
||||
if (ent->client->agm_tripped)
|
||||
ent->client->ps.stats[STAT_TIMER_ICON] = gi.imageindex("a_refuse");
|
||||
else
|
||||
ent->client->ps.stats[STAT_TIMER_ICON] = gi.imageindex("a_agm");
|
||||
ent->client->ps.stats[STAT_TIMER] = ent->client->agm_charge;
|
||||
#ifdef KMQUAKE2_ENGINE_MOD // for enhanced HUD
|
||||
ent->client->ps.stats[STAT_TIMER_RANGE] = 100;
|
||||
#endif
|
||||
}
|
||||
//CW--
|
||||
else if (ent->client->quad_framenum > level.framenum)
|
||||
{
|
||||
ent->client->ps.stats[STAT_TIMER_ICON] = gi.imageindex("p_quad");
|
||||
ent->client->ps.stats[STAT_TIMER] = (ent->client->quad_framenum - level.framenum) / 10;
|
||||
#ifdef KMQUAKE2_ENGINE_MOD // for enhanced HUD
|
||||
ent->client->ps.stats[STAT_TIMER_RANGE] = min(max(QUAD_TIMEOUT_FRAMES / 10, 0), 10000);
|
||||
#endif
|
||||
}
|
||||
else if (ent->client->invincible_framenum > level.framenum)
|
||||
{
|
||||
ent->client->ps.stats[STAT_TIMER_ICON] = gi.imageindex("p_invulnerability");
|
||||
ent->client->ps.stats[STAT_TIMER] = (ent->client->invincible_framenum - level.framenum) / 10;
|
||||
#ifdef KMQUAKE2_ENGINE_MOD // for enhanced HUD
|
||||
ent->client->ps.stats[STAT_TIMER_RANGE] = min(max(INVINCIBLE_TIMEOUT_FRAMES / 10, 0), 10000);
|
||||
#endif
|
||||
}
|
||||
//CW++
|
||||
else if (ent->client->siphon_framenum > level.framenum)
|
||||
{
|
||||
ent->client->ps.stats[STAT_TIMER_ICON] = gi.imageindex("p_siphon");
|
||||
ent->client->ps.stats[STAT_TIMER] = (ent->client->siphon_framenum - level.framenum) / 10;
|
||||
#ifdef KMQUAKE2_ENGINE_MOD // for enhanced HUD
|
||||
ent->client->ps.stats[STAT_TIMER_RANGE] = min(max(SIPHON_TIMEOUT_FRAMES / 10, 0), 10000);
|
||||
#endif
|
||||
}
|
||||
else if (ent->client->needle_framenum > level.framenum)
|
||||
{
|
||||
ent->client->ps.stats[STAT_TIMER_ICON] = gi.imageindex("p_needle");
|
||||
ent->client->ps.stats[STAT_TIMER] = (ent->client->needle_framenum - level.framenum) / 10;
|
||||
#ifdef KMQUAKE2_ENGINE_MOD // for enhanced HUD
|
||||
ent->client->ps.stats[STAT_TIMER_RANGE] = min(max(NEEDLE_TIMEOUT_FRAMES / 10, 0), 10000);
|
||||
#endif
|
||||
}
|
||||
else if (ent->client->haste_framenum > level.framenum)
|
||||
{
|
||||
ent->client->ps.stats[STAT_TIMER_ICON] = gi.imageindex("p_haste");
|
||||
ent->client->ps.stats[STAT_TIMER] = (ent->client->haste_framenum - level.framenum) / 10;
|
||||
#ifdef KMQUAKE2_ENGINE_MOD // for enhanced HUD
|
||||
ent->client->ps.stats[STAT_TIMER_RANGE] = min(max(HASTE_TIMEOUT_FRAMES / 10, 0), 10000);
|
||||
#endif
|
||||
}
|
||||
//CW--
|
||||
else if (ent->client->enviro_framenum > level.framenum)
|
||||
{
|
||||
ent->client->ps.stats[STAT_TIMER_ICON] = gi.imageindex("p_envirosuit");
|
||||
ent->client->ps.stats[STAT_TIMER] = (ent->client->enviro_framenum - level.framenum) / 10;
|
||||
#ifdef KMQUAKE2_ENGINE_MOD // for enhanced HUD
|
||||
ent->client->ps.stats[STAT_TIMER_RANGE] = min(max(ENVIROSUIT_TIMEOUT_FRAMES / 10, 0), 10000);
|
||||
#endif
|
||||
}
|
||||
else if (ent->client->breather_framenum > level.framenum)
|
||||
{
|
||||
ent->client->ps.stats[STAT_TIMER_ICON] = gi.imageindex("p_rebreather");
|
||||
ent->client->ps.stats[STAT_TIMER] = (ent->client->breather_framenum - level.framenum) / 10;
|
||||
#ifdef KMQUAKE2_ENGINE_MOD // for enhanced HUD
|
||||
ent->client->ps.stats[STAT_TIMER_RANGE] = min(max(BREATHER_TIMEOUT_FRAMES / 10, 0), 10000);
|
||||
#endif
|
||||
}
|
||||
//CW++
|
||||
else if (ent->client->antibeam_framenum > level.framenum)
|
||||
{
|
||||
ent->client->ps.stats[STAT_TIMER_ICON] = gi.imageindex("k_datacd");
|
||||
ent->client->ps.stats[STAT_TIMER] = (ent->client->antibeam_framenum - level.framenum) / 10;
|
||||
#ifdef KMQUAKE2_ENGINE_MOD // for enhanced HUD
|
||||
ent->client->ps.stats[STAT_TIMER_RANGE] = min(max(ANTIBEAM_TIMEOUT_FRAMES / 10, 0), 10000);
|
||||
#endif
|
||||
}
|
||||
//CW--
|
||||
else
|
||||
{
|
||||
ent->client->ps.stats[STAT_TIMER_ICON] = 0;
|
||||
ent->client->ps.stats[STAT_TIMER] = 0;
|
||||
#ifdef KMQUAKE2_ENGINE_MOD // for enhanced HUD
|
||||
ent->client->ps.stats[STAT_TIMER_RANGE] = 0;
|
||||
#endif
|
||||
}
|
||||
|
||||
// selected item
|
||||
if ((ent->client->pers.selected_item == -1) || !ent->client->pers.selected_item) //CW
|
||||
ent->client->ps.stats[STAT_SELECTED_ICON] = 0;
|
||||
else
|
||||
ent->client->ps.stats[STAT_SELECTED_ICON] = gi.imageindex(itemlist[ent->client->pers.selected_item].icon);
|
||||
|
||||
ent->client->ps.stats[STAT_SELECTED_ITEM] = ent->client->pers.selected_item;
|
||||
|
||||
// layouts
|
||||
ent->client->ps.stats[STAT_LAYOUTS] = 0;
|
||||
|
||||
if ((ent->client->pers.health <= 0) || level.intermissiontime || ent->client->showscores || ent->client->show_gausstarget) //CW
|
||||
ent->client->ps.stats[STAT_LAYOUTS] |= 1;
|
||||
if (ent->client->showinventory && (ent->client->pers.health > 0))
|
||||
ent->client->ps.stats[STAT_LAYOUTS] |= 2;
|
||||
|
||||
|
||||
// frags
|
||||
ent->client->ps.stats[STAT_FRAGS] = ent->client->resp.score;
|
||||
|
||||
// help icon / current weapon if not shown
|
||||
if (ent->client->resp.helpchanged && (level.framenum & 8))
|
||||
ent->client->ps.stats[STAT_HELPICON] = gi.imageindex("i_help");
|
||||
else if (((ent->client->pers.hand == CENTER_HANDED) || (ent->client->ps.fov > 91.0)) && ent->client->pers.weapon)
|
||||
ent->client->ps.stats[STAT_HELPICON] = gi.imageindex(ent->client->pers.weapon->icon);
|
||||
else
|
||||
ent->client->ps.stats[STAT_HELPICON] = 0;
|
||||
|
||||
#ifdef KMQUAKE2_ENGINE_MOD // for enhanced HUD
|
||||
if (ent->client->pers.weapon) {
|
||||
ent->client->ps.stats[STAT_WEAPON] = gi.imageindex (ent->client->pers.weapon->icon);
|
||||
}
|
||||
else
|
||||
ent->client->ps.stats[STAT_WEAPON] = 0;
|
||||
#endif
|
||||
|
||||
//ZOID++
|
||||
SetCTFStats(ent);
|
||||
//ZOID--
|
||||
|
||||
//CW++
|
||||
if (((int)sv_gametype->value == G_FFA) && ent->client->resp.id_trap)
|
||||
SetWepIDView(ent);
|
||||
//CW--
|
||||
}
|
||||
|
||||
//CW++
|
||||
/*
|
||||
==================
|
||||
ShowGaussTarget
|
||||
|
||||
Helpful hints for the implementation of this code
|
||||
were given by Damien "Yaya" Slee.
|
||||
==================
|
||||
*/
|
||||
void ShowGaussTarget (edict_t *ent, char *string, size_t stringSize)
|
||||
{
|
||||
edict_t *cl_ent;
|
||||
edict_t *targ = NULL;
|
||||
vec3_t targ_vec;
|
||||
vec3_t forward;
|
||||
vec3_t right;
|
||||
vec3_t offset;
|
||||
vec3_t start;
|
||||
vec3_t vec;
|
||||
vec3_t t_ang;
|
||||
char str_temp[64];
|
||||
float dist;
|
||||
float min_dist = WORLD_SIZE; // was 8192.0
|
||||
int x = 999;
|
||||
int y = 999;
|
||||
int i;
|
||||
|
||||
// Display the targeting area overlay.
|
||||
|
||||
Com_sprintf(str_temp, sizeof(str_temp), "xv 32 yv -4 picn g_scan ");
|
||||
if ((strlen(string) + strlen(str_temp)) < 1024)
|
||||
// strcat(string, str_temp);
|
||||
Com_strcat(string, stringSize, str_temp);
|
||||
|
||||
// Search through the list of entities to determine if any live players are in front of us.
|
||||
// For multiple targets, select the nearest one.
|
||||
|
||||
AngleVectors(ent->client->v_angle, forward, right, NULL);
|
||||
VectorSet(offset, 24.0, 8.0, ent->viewheight-5.0); // NB: should be same as offset in Weapon_GaussPistol_Fire()
|
||||
P_ProjectSource(ent->client, ent->s.origin, offset, forward, right, start);
|
||||
|
||||
for (i = 0; i < globals.num_edicts; ++i)
|
||||
{
|
||||
cl_ent = &g_edicts[i];
|
||||
|
||||
if (!cl_ent->client)
|
||||
continue;
|
||||
if (!cl_ent->inuse)
|
||||
continue;
|
||||
if (cl_ent->movetype == MOVETYPE_NOCLIP)
|
||||
continue;
|
||||
if (cl_ent == ent)
|
||||
continue;
|
||||
if (cl_ent->health < 1)
|
||||
continue;
|
||||
if (((int)sv_gametype->value > G_FFA) && (ent->client->resp.ctf_team == cl_ent->client->resp.ctf_team))
|
||||
continue;
|
||||
|
||||
VectorSubtract(cl_ent->s.origin, start, vec);
|
||||
if ((dist = VectorLength(vec)) > sv_gauss_scan_range->value)
|
||||
continue;
|
||||
|
||||
VectorNormalize(vec);
|
||||
if (DotProduct(vec, forward) > 0.75)
|
||||
{
|
||||
if (dist < min_dist)
|
||||
{
|
||||
targ = cl_ent;
|
||||
VectorCopy(vec, targ_vec);
|
||||
min_dist = dist;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// If a valid target has been found, check that it is within the scanner's field-of-view,
|
||||
// and if so, position the tracking reticle over them.
|
||||
|
||||
if (targ != NULL)
|
||||
{
|
||||
vectoangles(targ_vec, t_ang);
|
||||
x = (int)(GAUSS_AIMCAL * sin(DEG2RAD((ent->client->v_angle[1] - t_ang[1]))));
|
||||
y = (int)(GAUSS_AIMCAL * sin(DEG2RAD((t_ang[0] - ent->client->v_angle[0]))));
|
||||
}
|
||||
else
|
||||
return;
|
||||
|
||||
if ((abs(x) < 70) && (abs(y) < 70))
|
||||
{
|
||||
Com_sprintf(str_temp, sizeof(str_temp), "xv %i yv %i picn g_targ ", 136+x, 100+y);
|
||||
if ((strlen(string) + strlen(str_temp)) < 1024)
|
||||
// strcat(string, str_temp);
|
||||
Com_strcat(string, stringSize, str_temp);
|
||||
|
||||
if (level.time > targ->delay)
|
||||
{
|
||||
targ->delay = level.time + 2.0;
|
||||
if (targ->target_ent && targ->target_ent->client && targ->target_ent->client->spycam)
|
||||
{
|
||||
unicastSound(targ->target_ent, gi.soundindex("weapons/gauss/warn.wav"), 1.0); //r1,CW
|
||||
targ->target_ent->delay = level.time + 2.0;
|
||||
}
|
||||
else
|
||||
unicastSound(targ, gi.soundindex("weapons/gauss/warn.wav"), 1.0); //r1,CW
|
||||
}
|
||||
}
|
||||
}
|
||||
//CW--
|
281
awaken2/p_menu.c
Normal file
281
awaken2/p_menu.c
Normal file
|
@ -0,0 +1,281 @@
|
|||
// p_menu.c
|
||||
|
||||
#include "g_local.h"
|
||||
|
||||
// Note that the pmenu entries are duplicated. This is so that a static set of pmenu entries
|
||||
// can be used for multiple clients and changed without interference.
|
||||
// Note that arg will be freed when the menu is closed; it must be allocated memory.
|
||||
pmenuhnd_t *PMenu_Open(edict_t *ent, pmenu_t *entries, int cur, int num, void *arg)
|
||||
{
|
||||
pmenuhnd_t *hnd;
|
||||
pmenu_t *p;
|
||||
int i;
|
||||
|
||||
//CW++
|
||||
if (ent->isabot)
|
||||
return NULL;
|
||||
//CW--
|
||||
|
||||
if (!ent->client)
|
||||
return NULL;
|
||||
|
||||
if (ent->client->menu)
|
||||
{
|
||||
gi.dprintf("warning, ent already has a menu\n");
|
||||
PMenu_Close(ent);
|
||||
}
|
||||
|
||||
hnd = gi.TagMalloc(sizeof(*hnd), TAG_LEVEL); //CW
|
||||
hnd->arg = arg;
|
||||
hnd->entries = gi.TagMalloc(sizeof(pmenu_t)*num, TAG_LEVEL); //CW
|
||||
memcpy(hnd->entries, entries, sizeof(pmenu_t) * num);
|
||||
|
||||
// duplicate the strings since they may be from static memory
|
||||
for (i = 0; i < num; i++)
|
||||
{
|
||||
if (entries[i].text)
|
||||
hnd->entries[i].text = strdup(entries[i].text);
|
||||
}
|
||||
hnd->num = num;
|
||||
|
||||
if ((cur < 0) || !entries[cur].SelectFunc)
|
||||
{
|
||||
for (i = 0, p = entries; i < num; i++, p++)
|
||||
{
|
||||
if (p->SelectFunc)
|
||||
break;
|
||||
}
|
||||
}
|
||||
else
|
||||
i = cur;
|
||||
|
||||
if (i >= num)
|
||||
hnd->cur = -1;
|
||||
else
|
||||
hnd->cur = i;
|
||||
|
||||
ent->client->showscores = true;
|
||||
ent->client->inmenu = true;
|
||||
ent->client->menu = hnd;
|
||||
|
||||
PMenu_Do_Update(ent);
|
||||
gi.unicast(ent, true);
|
||||
|
||||
return hnd;
|
||||
}
|
||||
|
||||
void PMenu_Close(edict_t *ent)
|
||||
{
|
||||
pmenuhnd_t *hnd;
|
||||
int i;
|
||||
|
||||
if (!ent->client->menu)
|
||||
return;
|
||||
|
||||
hnd = ent->client->menu;
|
||||
for (i = 0; i < hnd->num; i++)
|
||||
{
|
||||
if (hnd->entries[i].text)
|
||||
free(hnd->entries[i].text);
|
||||
}
|
||||
|
||||
gi.TagFree(hnd->entries); //CW
|
||||
|
||||
if (hnd->arg)
|
||||
gi.TagFree(hnd->arg); //CW
|
||||
|
||||
gi.TagFree(hnd); //CW
|
||||
|
||||
ent->client->menu = NULL;
|
||||
ent->client->showscores = false;
|
||||
}
|
||||
|
||||
// only use on pmenu's that have been called with PMenu_Open
|
||||
void PMenu_UpdateEntry(pmenu_t *entry, const char *text, int align, SelectFunc_t SelectFunc)
|
||||
{
|
||||
if (entry->text)
|
||||
free(entry->text);
|
||||
|
||||
entry->text = strdup(text);
|
||||
entry->align = align;
|
||||
entry->SelectFunc = SelectFunc;
|
||||
}
|
||||
|
||||
void PMenu_Do_Update(edict_t *ent)
|
||||
{
|
||||
pmenuhnd_t *hnd;
|
||||
pmenu_t *p;
|
||||
char string[1400];
|
||||
char *t;
|
||||
int x;
|
||||
int i;
|
||||
qboolean alt = false;
|
||||
size_t stringLen;
|
||||
|
||||
if (!ent->client->menu)
|
||||
{
|
||||
gi.dprintf("warning: ent has no menu\n");
|
||||
return;
|
||||
}
|
||||
|
||||
hnd = ent->client->menu;
|
||||
|
||||
Com_strcpy(string, sizeof(string), "xv 32 yv 8 picn inventory ");
|
||||
for (i = 0, p = hnd->entries; i < hnd->num; i++, p++)
|
||||
{
|
||||
if (!p->text || !*(p->text))
|
||||
continue; // blank line
|
||||
|
||||
t = p->text;
|
||||
if (*t == '*')
|
||||
{
|
||||
alt = true;
|
||||
t++;
|
||||
}
|
||||
// sprintf(string + strlen(string), "yv %d ", 32 + i * 8);
|
||||
stringLen = strlen(string);
|
||||
Com_sprintf(string + stringLen, sizeof(string) - stringLen, "yv %d ", 32 + i * 8);
|
||||
if (p->align == PMENU_ALIGN_CENTER)
|
||||
x = 162 - ((int)strlen(t) * 4);
|
||||
else if (p->align == PMENU_ALIGN_RIGHT)
|
||||
x = 260 - ((int)strlen(t) * 8);
|
||||
else
|
||||
x = 58;
|
||||
|
||||
// sprintf(string + strlen(string), "xv %d ", x - ((hnd->cur == i) ? 8 : 0));
|
||||
stringLen = strlen(string);
|
||||
Com_sprintf(string + stringLen, sizeof(string) - stringLen, "xv %d ", x - ((hnd->cur == i) ? 8 : 0));
|
||||
|
||||
if (hnd->cur == i) {
|
||||
// sprintf(string + strlen(string), "string2 \"\x0d%s\" ", t);
|
||||
stringLen = strlen(string);
|
||||
Com_sprintf(string + stringLen, sizeof(string) - stringLen, "string2 \"\x0d%s\" ", t);
|
||||
}
|
||||
else if (alt) {
|
||||
// sprintf(string + strlen(string), "string2 \"%s\" ", t);
|
||||
stringLen = strlen(string);
|
||||
Com_sprintf(string + stringLen, sizeof(string) - stringLen, "string2 \"%s\" ", t);
|
||||
}
|
||||
else {
|
||||
// sprintf(string + strlen(string), "string \"%s\" ", t);
|
||||
stringLen = strlen(string);
|
||||
Com_sprintf(string + stringLen, sizeof(string) - stringLen, "string \"%s\" ", t);
|
||||
}
|
||||
alt = false;
|
||||
}
|
||||
|
||||
gi.WriteByte(svc_layout);
|
||||
gi.WriteString(string);
|
||||
}
|
||||
|
||||
void PMenu_Update(edict_t *ent)
|
||||
{
|
||||
if (!ent->client->menu)
|
||||
{
|
||||
gi.dprintf("warning: ent has no menu\n");
|
||||
return;
|
||||
}
|
||||
|
||||
if (level.time - ent->client->menutime >= 1.0)
|
||||
{
|
||||
// been a second or more since last update, update now
|
||||
PMenu_Do_Update(ent);
|
||||
gi.unicast(ent, true);
|
||||
ent->client->menutime = level.time;
|
||||
ent->client->menudirty = false;
|
||||
}
|
||||
ent->client->menutime = level.time + 0.2;
|
||||
ent->client->menudirty = true;
|
||||
}
|
||||
|
||||
void PMenu_Next(edict_t *ent)
|
||||
{
|
||||
pmenuhnd_t *hnd;
|
||||
pmenu_t *p;
|
||||
int i;
|
||||
|
||||
if (!ent->client->menu)
|
||||
{
|
||||
gi.dprintf("warning: ent has no menu\n");
|
||||
return;
|
||||
}
|
||||
|
||||
hnd = ent->client->menu;
|
||||
|
||||
if (hnd->cur < 0)
|
||||
return; // no selectable entries
|
||||
|
||||
i = hnd->cur;
|
||||
p = hnd->entries + hnd->cur;
|
||||
do
|
||||
{
|
||||
i++, p++;
|
||||
if (i == hnd->num)
|
||||
i = 0, p = hnd->entries;
|
||||
if (p->SelectFunc)
|
||||
break;
|
||||
} while (i != hnd->cur);
|
||||
|
||||
hnd->cur = i;
|
||||
|
||||
PMenu_Update(ent);
|
||||
}
|
||||
|
||||
void PMenu_Prev(edict_t *ent)
|
||||
{
|
||||
pmenuhnd_t *hnd;
|
||||
pmenu_t *p;
|
||||
int i;
|
||||
|
||||
if (!ent->client->menu)
|
||||
{
|
||||
gi.dprintf("warning: ent has no menu\n");
|
||||
return;
|
||||
}
|
||||
|
||||
hnd = ent->client->menu;
|
||||
|
||||
if (hnd->cur < 0)
|
||||
return; // no selectable entries
|
||||
|
||||
i = hnd->cur;
|
||||
p = hnd->entries + hnd->cur;
|
||||
do
|
||||
{
|
||||
if (i == 0)
|
||||
{
|
||||
i = hnd->num - 1;
|
||||
p = hnd->entries + i;
|
||||
}
|
||||
else
|
||||
i--, p--;
|
||||
if (p->SelectFunc)
|
||||
break;
|
||||
} while (i != hnd->cur);
|
||||
|
||||
hnd->cur = i;
|
||||
|
||||
PMenu_Update(ent);
|
||||
}
|
||||
|
||||
void PMenu_Select(edict_t *ent)
|
||||
{
|
||||
pmenuhnd_t *hnd;
|
||||
pmenu_t *p;
|
||||
|
||||
if (!ent->client->menu)
|
||||
{
|
||||
gi.dprintf("warning: ent has no menu\n");
|
||||
return;
|
||||
}
|
||||
|
||||
hnd = ent->client->menu;
|
||||
|
||||
if (hnd->cur < 0)
|
||||
return; // no selectable entries
|
||||
|
||||
p = hnd->entries + hnd->cur;
|
||||
|
||||
if (p->SelectFunc)
|
||||
p->SelectFunc(ent, hnd);
|
||||
}
|
33
awaken2/p_menu.h
Normal file
33
awaken2/p_menu.h
Normal file
|
@ -0,0 +1,33 @@
|
|||
// p_menu.h
|
||||
|
||||
enum {
|
||||
PMENU_ALIGN_LEFT,
|
||||
PMENU_ALIGN_CENTER,
|
||||
PMENU_ALIGN_RIGHT
|
||||
};
|
||||
|
||||
typedef struct pmenuhnd_s
|
||||
{
|
||||
struct pmenu_s *entries;
|
||||
int cur;
|
||||
int num;
|
||||
void *arg;
|
||||
} pmenuhnd_t;
|
||||
|
||||
typedef void (*SelectFunc_t)(edict_t *ent, pmenuhnd_t *hnd);
|
||||
|
||||
typedef struct pmenu_s
|
||||
{
|
||||
char *text;
|
||||
int align;
|
||||
SelectFunc_t SelectFunc;
|
||||
} pmenu_t;
|
||||
|
||||
pmenuhnd_t *PMenu_Open(edict_t *ent, pmenu_t *entries, int cur, int num, void *arg);
|
||||
void PMenu_Close(edict_t *ent);
|
||||
void PMenu_UpdateEntry(pmenu_t *entry, const char *text, int align, SelectFunc_t SelectFunc);
|
||||
void PMenu_Do_Update(edict_t *ent);
|
||||
void PMenu_Update(edict_t *ent);
|
||||
void PMenu_Next(edict_t *ent);
|
||||
void PMenu_Prev(edict_t *ent);
|
||||
void PMenu_Select(edict_t *ent);
|
1631
awaken2/p_view.c
Normal file
1631
awaken2/p_view.c
Normal file
File diff suppressed because it is too large
Load diff
2722
awaken2/p_weapon.c
Normal file
2722
awaken2/p_weapon.c
Normal file
File diff suppressed because it is too large
Load diff
1521
awaken2/q_shared.c
Normal file
1521
awaken2/q_shared.c
Normal file
File diff suppressed because it is too large
Load diff
1070
awaken2/q_shared.h
Normal file
1070
awaken2/q_shared.h
Normal file
File diff suppressed because it is too large
Load diff
6
awaken2/readme.txt
Normal file
6
awaken2/readme.txt
Normal file
|
@ -0,0 +1,6 @@
|
|||
This is the source code to the Awakening II support DLL for KMQuake2.
|
||||
It supports the model_train, model_spawn, and rotating func_train entities from the Lazarus mod,
|
||||
and also the func_plat2 and func_door_secret2 entities from the Ground Zero mission pack.
|
||||
|
||||
Note this source code is under the original "Limited Program Source Code License" from id Software,
|
||||
NOT the GPL. It should not be mixed with GPLed code.
|
|
@ -3815,7 +3815,7 @@ struct {
|
|||
// strncat(buf, "the blue ");
|
||||
Q_strncatz(buf, bufSize, "the blue ");
|
||||
else if (nearteam == CTF_TEAM3)
|
||||
// strncat(buf, "the blue ");
|
||||
// strncat(buf, "the green ");
|
||||
Q_strncatz(buf, bufSize, "the green ");
|
||||
else
|
||||
// strncat(buf, "the ");
|
||||
|
|
Binary file not shown.
|
@ -217,8 +217,8 @@ extern void Info_SetValueForKey ( char * s , char * key , char * value ) ;
|
|||
extern qboolean Info_Validate ( char * s ) ;
|
||||
extern void Info_RemoveKey ( char * s , char * key ) ;
|
||||
extern char * Info_ValueForKey ( char * s , char * key ) ;
|
||||
extern void Com_strcat ( char * dest , size_t destSize , const char * src ) ;
|
||||
extern void Com_strcpy ( char * dest , size_t destSize , const char * src ) ;
|
||||
extern size_t Com_strcat ( char * dest , size_t destSize , const char * src ) ;
|
||||
extern size_t Com_strcpy ( char * dest , size_t destSize , const char * src ) ;
|
||||
extern void Com_sprintf ( char * dest , size_t size , char * fmt , ... ) ;
|
||||
extern int Q_strcasecmp ( char * s1 , char * s2 ) ;
|
||||
extern int Q_strncasecmp ( char * s1 , char * s2 , size_t n ) ;
|
||||
|
|
|
@ -1222,50 +1222,81 @@ void Com_sprintf (char *dest, size_t size, char *fmt, ...)
|
|||
}
|
||||
|
||||
|
||||
void Com_strcpy (char *dest, size_t destSize, const char *src)
|
||||
// Knightmare added
|
||||
size_t Com_strcpy (char *dest, size_t destSize, const char *src)
|
||||
{
|
||||
char *d = dest;
|
||||
const char *s = src;
|
||||
size_t decSize = destSize;
|
||||
|
||||
if (!dest) {
|
||||
Com_Printf ("Com_strcpy: NULL dst\n");
|
||||
return;
|
||||
return 0;
|
||||
}
|
||||
if (!src) {
|
||||
Com_Printf ("Com_strcpy: NULL src\n");
|
||||
return;
|
||||
return 0;
|
||||
}
|
||||
if (destSize < 1) {
|
||||
Com_Printf ("Com_strcpy: dstSize < 1\n");
|
||||
return;
|
||||
return 0;
|
||||
}
|
||||
|
||||
strncpy(dest, src, destSize-1);
|
||||
// strncpy(dest, src, destSize-1);
|
||||
// dest[destSize-1] = 0;
|
||||
|
||||
while (--decSize && *s)
|
||||
*d++ = *s++;
|
||||
*d = 0;
|
||||
dest[destSize-1] = 0;
|
||||
|
||||
if (decSize == 0) // Insufficent room in dst, return count + length of remaining src
|
||||
return (s - src - 1 + strlen(s));
|
||||
else
|
||||
return (s - src - 1); // returned count excludes NULL terminator
|
||||
}
|
||||
|
||||
|
||||
void Com_strcat (char *dest, size_t destSize, const char *src)
|
||||
// Knightmare added
|
||||
size_t Com_strcat (char *dest, size_t destSize, const char *src)
|
||||
{
|
||||
char *d = dest;
|
||||
const char *s = src;
|
||||
size_t decSize = destSize;
|
||||
size_t dLen;
|
||||
|
||||
if (!dest) {
|
||||
Com_Printf ("Com_strcat: NULL dst\n");
|
||||
return;
|
||||
return 0;
|
||||
}
|
||||
if (!src) {
|
||||
Com_Printf ("Com_strcat: NULL src\n");
|
||||
return;
|
||||
return 0;
|
||||
}
|
||||
if (destSize < 1) {
|
||||
Com_Printf ("Com_strcat: dstSize < 1\n");
|
||||
return;
|
||||
return 0;
|
||||
}
|
||||
|
||||
while (--destSize && *dest)
|
||||
/* while (--destSize && *dest)
|
||||
dest++;
|
||||
|
||||
if (destSize > 0) {
|
||||
if (destSize > 0){
|
||||
while (--destSize && *src)
|
||||
*dest++ = *src++;
|
||||
|
||||
*dest = 0;
|
||||
}*/
|
||||
|
||||
while (--decSize && *d)
|
||||
d++;
|
||||
dLen = d - dest;
|
||||
|
||||
if (decSize == 0)
|
||||
return (dLen + strlen(s));
|
||||
|
||||
if (decSize > 0) {
|
||||
while (--decSize && *s)
|
||||
*d++ = *s++;
|
||||
|
||||
*d = 0;
|
||||
}
|
||||
dest[destSize-1] = 0;
|
||||
|
||||
return (dLen + (s - src)); // returned count excludes NULL terminator
|
||||
}
|
||||
|
||||
/*
|
||||
|
|
|
@ -303,8 +303,9 @@ char *COM_Parse (char **data_p);
|
|||
// data is an in/out parm, returns a parsed out token
|
||||
|
||||
void Com_sprintf (char *dest, size_t size, char *fmt, ...);
|
||||
void Com_strcpy (char *dest, size_t destSize, const char *src);
|
||||
void Com_strcat (char *dest, size_t destSize, const char *src);
|
||||
// Knightmare added
|
||||
size_t Com_strcpy (char *dest, size_t destSize, const char *src);
|
||||
size_t Com_strcat (char *dest, size_t destSize, const char *src);
|
||||
|
||||
void Com_PageInMemory (byte *buffer, int size);
|
||||
|
||||
|
|
Binary file not shown.
|
@ -246,8 +246,8 @@ extern void Info_SetValueForKey ( char * s , char * key , char * value ) ;
|
|||
extern qboolean Info_Validate ( char * s ) ;
|
||||
extern void Info_RemoveKey ( char * s , char * key ) ;
|
||||
extern char * Info_ValueForKey ( char * s , char * key ) ;
|
||||
extern void Com_strcat ( char * dest , size_t destSize , const char * src ) ;
|
||||
extern void Com_strcpy ( char * dest , size_t destSize , const char * src ) ;
|
||||
extern size_t Com_strcat ( char * dest , size_t destSize , const char * src ) ;
|
||||
extern size_t Com_strcpy ( char * dest , size_t destSize , const char * src ) ;
|
||||
extern void Com_sprintf ( char * dest , size_t size , char * fmt , ... ) ;
|
||||
extern int Q_strcasecmp ( const char * s1 , const char * s2 ) ;
|
||||
extern int Q_strncasecmp ( const char * s1 , const char * s2 , size_t n ) ;
|
||||
|
|
|
@ -1222,50 +1222,82 @@ void Com_sprintf (char *dest, size_t size, char *fmt, ...)
|
|||
dest[size-1] = 0;
|
||||
}
|
||||
|
||||
void Com_strcpy (char *dest, size_t destSize, const char *src)
|
||||
// Knightmare added
|
||||
size_t Com_strcpy (char *dest, size_t destSize, const char *src)
|
||||
{
|
||||
char *d = dest;
|
||||
const char *s = src;
|
||||
size_t decSize = destSize;
|
||||
|
||||
if (!dest) {
|
||||
Com_Printf ("Com_strcpy: NULL dst\n");
|
||||
return;
|
||||
return 0;
|
||||
}
|
||||
if (!src) {
|
||||
Com_Printf ("Com_strcpy: NULL src\n");
|
||||
return;
|
||||
return 0;
|
||||
}
|
||||
if (destSize < 1) {
|
||||
Com_Printf ("Com_strcpy: dstSize < 1\n");
|
||||
return;
|
||||
return 0;
|
||||
}
|
||||
|
||||
strncpy (dest, src, destSize-1);
|
||||
// strncpy(dest, src, destSize-1);
|
||||
// dest[destSize-1] = 0;
|
||||
|
||||
while (--decSize && *s)
|
||||
*d++ = *s++;
|
||||
*d = 0;
|
||||
dest[destSize-1] = 0;
|
||||
|
||||
if (decSize == 0) // Insufficent room in dst, return count + length of remaining src
|
||||
return (s - src - 1 + strlen(s));
|
||||
else
|
||||
return (s - src - 1); // returned count excludes NULL terminator
|
||||
}
|
||||
|
||||
|
||||
void Com_strcat (char *dest, size_t destSize, const char *src)
|
||||
// Knightmare added
|
||||
size_t Com_strcat (char *dest, size_t destSize, const char *src)
|
||||
{
|
||||
char *d = dest;
|
||||
const char *s = src;
|
||||
size_t decSize = destSize;
|
||||
size_t dLen;
|
||||
|
||||
if (!dest) {
|
||||
Com_Printf ("Com_strcat: NULL dst\n");
|
||||
return;
|
||||
return 0;
|
||||
}
|
||||
if (!src) {
|
||||
Com_Printf ("Com_strcat: NULL src\n");
|
||||
return;
|
||||
return 0;
|
||||
}
|
||||
if (destSize < 1) {
|
||||
Com_Printf ("Com_strcat: dstSize < 1\n");
|
||||
return;
|
||||
return 0;
|
||||
}
|
||||
|
||||
while (--destSize && *dest)
|
||||
/* while (--destSize && *dest)
|
||||
dest++;
|
||||
|
||||
if (destSize > 0) {
|
||||
if (destSize > 0){
|
||||
while (--destSize && *src)
|
||||
*dest++ = *src++;
|
||||
|
||||
*dest = 0;
|
||||
}*/
|
||||
|
||||
while (--decSize && *d)
|
||||
d++;
|
||||
dLen = d - dest;
|
||||
|
||||
if (decSize == 0)
|
||||
return (dLen + strlen(s));
|
||||
|
||||
if (decSize > 0) {
|
||||
while (--decSize && *s)
|
||||
*d++ = *s++;
|
||||
|
||||
*d = 0;
|
||||
}
|
||||
dest[destSize-1] = 0;
|
||||
|
||||
return (dLen + (s - src)); // returned count excludes NULL terminator
|
||||
}
|
||||
|
||||
/*
|
||||
|
|
|
@ -65,7 +65,7 @@ __inline int Q_vsnprintf (char *Dest, size_t Count, const char *Format, va_list
|
|||
#define Q_vsnprintf vsnprintf
|
||||
#endif
|
||||
|
||||
//Knightmare- whether to include new engine enhancements
|
||||
// Knightmare- whether to include new engine enhancements
|
||||
#define KMQUAKE2_ENGINE_MOD
|
||||
|
||||
#ifdef KMQUAKE2_ENGINE_MOD
|
||||
|
@ -261,8 +261,9 @@ char *COM_Parse (char **data_p);
|
|||
// data is an in/out parm, returns a parsed out token
|
||||
|
||||
void Com_sprintf (char *dest, size_t size, char *fmt, ...);
|
||||
void Com_strcpy (char *dest, size_t destSize, const char *src);
|
||||
void Com_strcat (char *dest, size_t destSize, const char *src);
|
||||
// Knightmare added
|
||||
size_t Com_strcpy (char *dest, size_t destSize, const char *src);
|
||||
size_t Com_strcat (char *dest, size_t destSize, const char *src);
|
||||
|
||||
void Com_PageInMemory (byte *buffer, int size);
|
||||
|
||||
|
|
Loading…
Reference in a new issue