Initial commit.

This commit is contained in:
Jim Gray
2013-04-04 14:32:05 -07:00
parent ba5c81da32
commit d71d53e8ec
2180 changed files with 1393544 additions and 1 deletions

View File

@@ -0,0 +1,3 @@
EXPORTS
vmMain
dllEntry

412
codemp/cgame/JK2_cgame.dsp Normal file
View File

@@ -0,0 +1,412 @@
# Microsoft Developer Studio Project File - Name="JK2cgame" - Package Owner=<4>
# Microsoft Developer Studio Generated Build File, Format Version 6.00
# ** DO NOT EDIT **
# TARGTYPE "Win32 (x86) Dynamic-Link Library" 0x0102
CFG=JK2cgame - Win32 Release JK2
!MESSAGE This is not a valid makefile. To build this project using NMAKE,
!MESSAGE use the Export Makefile command and run
!MESSAGE
!MESSAGE NMAKE /f "JK2_cgame.mak".
!MESSAGE
!MESSAGE You can specify a configuration when running NMAKE
!MESSAGE by defining the macro CFG on the command line. For example:
!MESSAGE
!MESSAGE NMAKE /f "JK2_cgame.mak" CFG="JK2cgame - Win32 Release JK2"
!MESSAGE
!MESSAGE Possible choices for configuration are:
!MESSAGE
!MESSAGE "JK2cgame - Win32 Release JK2" (based on "Win32 (x86) Dynamic-Link Library")
!MESSAGE "JK2cgame - Win32 Debug JK2" (based on "Win32 (x86) Dynamic-Link Library")
!MESSAGE "JK2cgame - Win32 Final JK2" (based on "Win32 (x86) Dynamic-Link Library")
!MESSAGE
# Begin Project
# PROP AllowPerConfigDependencies 0
# PROP Scc_ProjName ""$/jedi/codemp/cgame", ICAAAAAA"
# PROP Scc_LocalPath "."
CPP=cl.exe
MTL=midl.exe
RSC=rc.exe
!IF "$(CFG)" == "JK2cgame - Win32 Release JK2"
# PROP BASE Use_MFC 0
# PROP BASE Use_Debug_Libraries 0
# PROP BASE Output_Dir "JK2cgame___Win32_Release_TA"
# PROP BASE Intermediate_Dir "JK2cgame___Win32_Release_TA"
# PROP BASE Ignore_Export_Lib 0
# PROP BASE Target_Dir ""
# PROP Use_MFC 0
# PROP Use_Debug_Libraries 0
# PROP Output_Dir "../Release"
# PROP Intermediate_Dir "../Release/JK2cgame"
# PROP Ignore_Export_Lib 0
# PROP Target_Dir ""
# ADD BASE CPP /nologo /G6 /W4 /GX /O2 /D "WIN32" /D "NDebug" /D "_WINDOWS" /YX /FD /c
# ADD CPP /nologo /G6 /W4 /GX /Zi /O2 /I ".." /I "./../game" /D "NDEBUG" /D "WIN32" /D "_WINDOWS" /D "MISSIONPACK" /D "_JK2" /YX /FD /c
# SUBTRACT CPP /Fr
# ADD BASE MTL /nologo /D "NDebug" /mktyplib203 /o "NUL" /win32
# ADD MTL /nologo /D "NDebug" /mktyplib203 /o "NUL" /win32
# ADD BASE RSC /l 0x409 /d "NDebug"
# ADD RSC /l 0x409 /d "NDebug"
BSC32=bscmake.exe
# ADD BASE BSC32 /nologo
# ADD BSC32 /nologo
LINK32=link.exe
# ADD BASE LINK32 /nologo /base:"0x30000000" /subsystem:windows /dll /map /machine:I386 /def:".\JK2_cgame.def" /out:"../Release/cgamex86.dll"
# SUBTRACT BASE LINK32 /debug
# ADD LINK32 /nologo /base:"0x30000000" /subsystem:windows /dll /map /debug /machine:I386 /def:".\JK2_cgame.def" /out:"../Release/cgamex86.dll"
!ELSEIF "$(CFG)" == "JK2cgame - Win32 Debug JK2"
# PROP BASE Use_MFC 0
# PROP BASE Use_Debug_Libraries 1
# PROP BASE Output_Dir "JK2cgame___Win32_Debug_TA"
# PROP BASE Intermediate_Dir "JK2cgame___Win32_Debug_TA"
# PROP BASE Ignore_Export_Lib 0
# PROP BASE Target_Dir ""
# PROP Use_MFC 0
# PROP Use_Debug_Libraries 1
# PROP Output_Dir "../Debug"
# PROP Intermediate_Dir "../Debug/JK2cgame"
# PROP Ignore_Export_Lib 0
# PROP Target_Dir ""
# ADD BASE CPP /nologo /G5 /MTd /W3 /Gm /GX /ZI /Od /D "WIN32" /D "_Debug" /D "_WINDOWS" /FR /YX /FD /c
# ADD CPP /nologo /G6 /MTd /W3 /Gm /GX /ZI /Od /I ".." /I "./../game" /D "_DEBUG" /D "WIN32" /D "_WINDOWS" /D "MISSIONPACK" /D "_JK2" /D "JK2AWARDS" /FR /YX /FD /GZ /c
# ADD BASE MTL /nologo /D "_Debug" /mktyplib203 /o "NUL" /win32
# ADD MTL /nologo /D "_Debug" /mktyplib203 /o "NUL" /win32
# ADD BASE RSC /l 0x409 /d "_Debug"
# ADD RSC /l 0x409 /d "_Debug"
BSC32=bscmake.exe
# ADD BASE BSC32 /nologo
# ADD BSC32 /nologo
LINK32=link.exe
# ADD BASE LINK32 /nologo /base:"0x30000000" /subsystem:windows /dll /map /debug /machine:I386 /out:"..\Debug/cgamex86.dll"
# SUBTRACT BASE LINK32 /profile /nodefaultlib
# ADD LINK32 /nologo /base:"0x30000000" /subsystem:windows /dll /map /debug /machine:I386 /def:".\JK2_cgame.def" /out:"..\Debug\cgamex86.dll"
# SUBTRACT LINK32 /pdb:none
!ELSEIF "$(CFG)" == "JK2cgame - Win32 Final JK2"
# PROP BASE Use_MFC 0
# PROP BASE Use_Debug_Libraries 0
# PROP BASE Output_Dir "../Final"
# PROP BASE Intermediate_Dir "../Final/JK2cgame"
# PROP BASE Ignore_Export_Lib 0
# PROP BASE Target_Dir ""
# PROP Use_MFC 0
# PROP Use_Debug_Libraries 0
# PROP Output_Dir "../Final"
# PROP Intermediate_Dir "../Final/JK2cgame"
# PROP Ignore_Export_Lib 0
# PROP Target_Dir ""
# ADD BASE CPP /nologo /G6 /W4 /GX /Zi /O2 /I ".." /I "../../jk2/game" /D "NDebug" /D "WIN32" /D "_WINDOWS" /D "MISSIONPACK" /D "_JK2" /YX /FD /c
# SUBTRACT BASE CPP /Fr
# ADD CPP /nologo /G6 /W4 /GX /O2 /I ".." /I "./../game" /D "NDEBUG" /D "_WINDOWS" /D "MISSIONPACK" /D "WIN32" /D "_JK2" /D "FINAL_BUILD" /YX /FD /c
# ADD BASE MTL /nologo /D "NDebug" /mktyplib203 /o "NUL" /win32
# ADD MTL /nologo /D "NDebug" /mktyplib203 /o "NUL" /win32
# ADD BASE RSC /l 0x409 /d "NDebug"
# ADD RSC /l 0x409 /d "NDebug"
BSC32=bscmake.exe
# ADD BASE BSC32 /nologo
# ADD BSC32 /nologo
LINK32=link.exe
# ADD BASE LINK32 /nologo /base:"0x30000000" /subsystem:windows /dll /map /machine:I386 /def:".\JK2_cgame.def" /out:"../Final/cgamex86.dll"
# ADD LINK32 /nologo /base:"0x30000000" /subsystem:windows /dll /map /machine:I386 /def:".\JK2_cgame.def" /out:"../Final/cgamex86.dll"
!ENDIF
# Begin Target
# Name "JK2cgame - Win32 Release JK2"
# Name "JK2cgame - Win32 Debug JK2"
# Name "JK2cgame - Win32 Final JK2"
# Begin Group "Source Files"
# PROP Default_Filter "c"
# Begin Source File
SOURCE=..\game\bg_lib.c
# PROP BASE Exclude_From_Build 1
# PROP Exclude_From_Build 1
# End Source File
# Begin Source File
SOURCE=..\game\bg_misc.c
# End Source File
# Begin Source File
SOURCE=..\game\bg_panimate.c
# End Source File
# Begin Source File
SOURCE=..\game\bg_pmove.c
# End Source File
# Begin Source File
SOURCE=..\game\bg_saber.c
# End Source File
# Begin Source File
SOURCE=..\game\bg_slidemove.c
# End Source File
# Begin Source File
SOURCE=..\game\bg_weapons.c
# End Source File
# Begin Source File
SOURCE=.\cg_consolecmds.c
# End Source File
# Begin Source File
SOURCE=.\cg_draw.c
# End Source File
# Begin Source File
SOURCE=.\cg_drawtools.c
# End Source File
# Begin Source File
SOURCE=.\cg_effects.c
# End Source File
# Begin Source File
SOURCE=.\cg_ents.c
# End Source File
# Begin Source File
SOURCE=.\cg_event.c
# End Source File
# Begin Source File
SOURCE=.\cg_info.c
# End Source File
# Begin Source File
SOURCE=.\cg_light.c
# End Source File
# Begin Source File
SOURCE=.\cg_localents.c
# End Source File
# Begin Source File
SOURCE=.\cg_main.c
# End Source File
# Begin Source File
SOURCE=.\cg_marks.c
# End Source File
# Begin Source File
SOURCE=.\cg_newDraw.c
# End Source File
# Begin Source File
SOURCE=.\cg_players.c
# End Source File
# Begin Source File
SOURCE=.\cg_playerstate.c
# End Source File
# Begin Source File
SOURCE=.\cg_predict.c
# End Source File
# Begin Source File
SOURCE=.\cg_saga.c
# End Source File
# Begin Source File
SOURCE=.\cg_scoreboard.c
# End Source File
# Begin Source File
SOURCE=.\cg_servercmds.c
# End Source File
# Begin Source File
SOURCE=.\cg_snapshot.c
# End Source File
# Begin Source File
SOURCE=.\cg_strap.c
# End Source File
# Begin Source File
SOURCE=.\cg_syscalls.c
# End Source File
# Begin Source File
SOURCE=.\cg_turret.c
# End Source File
# Begin Source File
SOURCE=.\cg_view.c
# End Source File
# Begin Source File
SOURCE=.\cg_weaponinit.c
# End Source File
# Begin Source File
SOURCE=.\cg_weapons.c
# End Source File
# Begin Source File
SOURCE=.\fx_blaster.c
# End Source File
# Begin Source File
SOURCE=.\fx_bowcaster.c
# End Source File
# Begin Source File
SOURCE=.\fx_bryarpistol.c
# End Source File
# Begin Source File
SOURCE=.\fx_demp2.c
# End Source File
# Begin Source File
SOURCE=.\fx_disruptor.c
# End Source File
# Begin Source File
SOURCE=.\fx_flechette.c
# End Source File
# Begin Source File
SOURCE=.\fx_force.c
# End Source File
# Begin Source File
SOURCE=.\fx_heavyrepeater.c
# End Source File
# Begin Source File
SOURCE=.\fx_rocketlauncher.c
# End Source File
# Begin Source File
SOURCE=..\game\q_math.c
# End Source File
# Begin Source File
SOURCE=..\game\q_shared.c
# End Source File
# Begin Source File
SOURCE=..\ui\ui_shared.c
# End Source File
# End Group
# Begin Group "Header Files"
# PROP Default_Filter "h"
# Begin Source File
SOURCE=..\game\anims.h
# End Source File
# Begin Source File
SOURCE=.\animtable.h
# End Source File
# Begin Source File
SOURCE=..\game\bg_local.h
# End Source File
# Begin Source File
SOURCE=..\game\bg_public.h
# End Source File
# Begin Source File
SOURCE=..\game\bg_saga.h
# End Source File
# Begin Source File
SOURCE=..\game\bg_strap.h
# End Source File
# Begin Source File
SOURCE=..\game\bg_weapons.h
# End Source File
# Begin Source File
SOURCE=.\cg_lights.h
# End Source File
# Begin Source File
SOURCE=.\cg_local.h
# End Source File
# Begin Source File
SOURCE=.\cg_public.h
# End Source File
# Begin Source File
SOURCE=..\qcommon\disablewarnings.h
# End Source File
# Begin Source File
SOURCE=.\fx_local.h
# End Source File
# Begin Source File
SOURCE=..\ghoul2\G2.h
# End Source File
# Begin Source File
SOURCE=.\JK2_cgame.def
# PROP Exclude_From_Build 1
# End Source File
# Begin Source File
SOURCE=..\ui\keycodes.h
# End Source File
# Begin Source File
SOURCE=..\..\ui\menudef.h
# End Source File
# Begin Source File
SOURCE=..\game\q_shared.h
# End Source File
# Begin Source File
SOURCE=..\qcommon\qfiles.h
# End Source File
# Begin Source File
SOURCE=..\game\surfaceflags.h
# End Source File
# Begin Source File
SOURCE=..\qcommon\tags.h
# End Source File
# Begin Source File
SOURCE=.\tr_types.h
# End Source File
# Begin Source File
SOURCE=..\ui\ui_shared.h
# End Source File
# End Group
# Begin Source File
SOURCE=.\cgame.bat
# PROP Exclude_From_Build 1
# End Source File
# Begin Source File
SOURCE=.\cgame.q3asm
# PROP Exclude_From_Build 1
# End Source File
# End Target
# End Project

View File

@@ -0,0 +1,563 @@
<?xml version="1.0" encoding = "Windows-1252"?>
<VisualStudioProject
ProjectType="Visual C++"
Version="7.00"
Name="JK2cgame"
SccProjectName="&quot;$/jedi/codemp/cgame&quot;, ICAAAAAA"
SccAuxPath=""
SccLocalPath="."
SccProvider="MSSCCI:Microsoft Visual SourceSafe">
<Platforms>
<Platform
Name="Win32"/>
</Platforms>
<Configurations>
<Configuration
Name="Release|Win32"
OutputDirectory=".\../Release"
IntermediateDirectory=".\../Release/JK2cgame"
ConfigurationType="2"
UseOfMFC="0"
ATLMinimizesCRunTimeLibraryUsage="FALSE">
<Tool
Name="VCCLCompilerTool"
GlobalOptimizations="TRUE"
InlineFunctionExpansion="2"
EnableIntrinsicFunctions="TRUE"
ImproveFloatingPointConsistency="TRUE"
FavorSizeOrSpeed="1"
OptimizeForProcessor="2"
OptimizeForWindowsApplication="TRUE"
AdditionalIncludeDirectories="..,./../game"
PreprocessorDefinitions="NDEBUG;WIN32;_WINDOWS;MISSIONPACK;_JK2;CGAME"
StringPooling="TRUE"
MinimalRebuild="TRUE"
RuntimeLibrary="4"
BufferSecurityCheck="FALSE"
EnableFunctionLevelLinking="TRUE"
UsePrecompiledHeader="2"
PrecompiledHeaderFile=".\../Release/JK2cgame/JK2_cgame.pch"
AssemblerListingLocation=".\../Release/JK2cgame/"
ObjectFile=".\../Release/JK2cgame/"
ProgramDataBaseFileName=".\../Release/JK2cgame/"
WarningLevel="4"
SuppressStartupBanner="TRUE"
DebugInformationFormat="3"
CompileAs="0"/>
<Tool
Name="VCCustomBuildTool"/>
<Tool
Name="VCLinkerTool"
AdditionalOptions="/MACHINE:I386"
AdditionalDependencies="odbc32.lib odbccp32.lib"
OutputFile="../Release/cgamex86.dll"
LinkIncremental="1"
SuppressStartupBanner="TRUE"
ModuleDefinitionFile=".\JK2_cgame.def"
GenerateDebugInformation="TRUE"
ProgramDatabaseFile=".\../Release/cgamex86.pdb"
GenerateMapFile="TRUE"
MapFileName="../Release/cgamex86.map"
SubSystem="2"
OptimizeReferences="2"
EnableCOMDATFolding="2"
SetChecksum="TRUE"
BaseAddress="0x30000000"
ImportLibrary=".\../Release/cgamex86.lib"/>
<Tool
Name="VCMIDLTool"
PreprocessorDefinitions="NDebug"
MkTypLibCompatible="TRUE"
SuppressStartupBanner="TRUE"
TargetEnvironment="1"
TypeLibraryName=".\../Release/JK2_cgame.tlb"/>
<Tool
Name="VCPostBuildEventTool"/>
<Tool
Name="VCPreBuildEventTool"/>
<Tool
Name="VCPreLinkEventTool"/>
<Tool
Name="VCResourceCompilerTool"
PreprocessorDefinitions="NDebug"
Culture="1033"/>
<Tool
Name="VCWebServiceProxyGeneratorTool"/>
<Tool
Name="VCWebDeploymentTool"/>
</Configuration>
<Configuration
Name="Final|Win32"
OutputDirectory=".\../Final"
IntermediateDirectory=".\../Final/JK2cgame"
ConfigurationType="2"
UseOfMFC="0"
ATLMinimizesCRunTimeLibraryUsage="FALSE">
<Tool
Name="VCCLCompilerTool"
GlobalOptimizations="TRUE"
InlineFunctionExpansion="2"
EnableIntrinsicFunctions="TRUE"
ImproveFloatingPointConsistency="TRUE"
FavorSizeOrSpeed="1"
OptimizeForProcessor="2"
OptimizeForWindowsApplication="TRUE"
AdditionalIncludeDirectories="..,./../game"
PreprocessorDefinitions="NDEBUG;_WINDOWS;MISSIONPACK;WIN32;CGAME;_JK2;FINAL_BUILD"
StringPooling="TRUE"
RuntimeLibrary="4"
BufferSecurityCheck="FALSE"
EnableFunctionLevelLinking="TRUE"
UsePrecompiledHeader="2"
PrecompiledHeaderFile=".\../Final/JK2cgame/JK2_cgame.pch"
AssemblerListingLocation=".\../Final/JK2cgame/"
ObjectFile=".\../Final/JK2cgame/"
ProgramDataBaseFileName=".\../Final/JK2cgame/"
WarningLevel="4"
SuppressStartupBanner="TRUE"
CompileAs="0"/>
<Tool
Name="VCCustomBuildTool"/>
<Tool
Name="VCLinkerTool"
AdditionalOptions="/MACHINE:I386"
AdditionalDependencies="odbc32.lib odbccp32.lib"
OutputFile="../Final/cgamex86.dll"
LinkIncremental="1"
SuppressStartupBanner="TRUE"
ModuleDefinitionFile=".\JK2_cgame.def"
ProgramDatabaseFile=""
GenerateMapFile="TRUE"
MapFileName=".\../Final/cgamex86.map"
SubSystem="2"
OptimizeReferences="2"
EnableCOMDATFolding="2"
SetChecksum="TRUE"
BaseAddress="0x30000000"
ImportLibrary=".\../Final/cgamex86.lib"/>
<Tool
Name="VCMIDLTool"
PreprocessorDefinitions="NDebug"
MkTypLibCompatible="TRUE"
SuppressStartupBanner="TRUE"
TargetEnvironment="1"
TypeLibraryName=".\../Final/JK2_cgame.tlb"/>
<Tool
Name="VCPostBuildEventTool"/>
<Tool
Name="VCPreBuildEventTool"/>
<Tool
Name="VCPreLinkEventTool"/>
<Tool
Name="VCResourceCompilerTool"
PreprocessorDefinitions="NDebug"
Culture="1033"/>
<Tool
Name="VCWebServiceProxyGeneratorTool"/>
<Tool
Name="VCWebDeploymentTool"/>
</Configuration>
<Configuration
Name="Debug|Win32"
OutputDirectory=".\../Debug"
IntermediateDirectory=".\../Debug/JK2cgame"
ConfigurationType="2"
UseOfMFC="0"
ATLMinimizesCRunTimeLibraryUsage="FALSE">
<Tool
Name="VCCLCompilerTool"
Optimization="0"
OptimizeForProcessor="2"
AdditionalIncludeDirectories="..,./../game"
PreprocessorDefinitions="_DEBUG;WIN32;_WINDOWS;MISSIONPACK;CGAME;_JK2"
BasicRuntimeChecks="3"
RuntimeLibrary="5"
UsePrecompiledHeader="2"
PrecompiledHeaderFile=".\../Debug/JK2cgame/JK2_cgame.pch"
AssemblerListingLocation=".\../Debug/JK2cgame/"
ObjectFile=".\../Debug/JK2cgame/"
ProgramDataBaseFileName=".\../Debug/JK2cgame/"
BrowseInformation="1"
WarningLevel="3"
SuppressStartupBanner="TRUE"
DebugInformationFormat="4"
CompileAs="0"/>
<Tool
Name="VCCustomBuildTool"/>
<Tool
Name="VCLinkerTool"
AdditionalOptions="/MACHINE:I386"
AdditionalDependencies="odbc32.lib odbccp32.lib"
OutputFile="..\Debug\cgamex86.dll"
LinkIncremental="2"
SuppressStartupBanner="TRUE"
ModuleDefinitionFile=".\JK2_cgame.def"
GenerateDebugInformation="TRUE"
ProgramDatabaseFile=".\../Debug/cgamex86.pdb"
GenerateMapFile="TRUE"
MapFileName=".\../Debug/cgamex86.map"
SubSystem="2"
BaseAddress="0x30000000"
ImportLibrary=".\../Debug/cgamex86.lib"/>
<Tool
Name="VCMIDLTool"
PreprocessorDefinitions="_Debug"
MkTypLibCompatible="TRUE"
SuppressStartupBanner="TRUE"
TargetEnvironment="1"
TypeLibraryName=".\../Debug/JK2_cgame.tlb"/>
<Tool
Name="VCPostBuildEventTool"/>
<Tool
Name="VCPreBuildEventTool"/>
<Tool
Name="VCPreLinkEventTool"/>
<Tool
Name="VCResourceCompilerTool"
PreprocessorDefinitions="_Debug"
Culture="1033"/>
<Tool
Name="VCWebServiceProxyGeneratorTool"/>
<Tool
Name="VCWebDeploymentTool"/>
</Configuration>
<Configuration
Name="Debug(SH)|Win32"
OutputDirectory="Debug(SH)"
IntermediateDirectory="Debug(SH)"
ConfigurationType="2"
UseOfMFC="0"
ATLMinimizesCRunTimeLibraryUsage="FALSE">
<Tool
Name="VCCLCompilerTool"
Optimization="0"
OptimizeForProcessor="2"
AdditionalIncludeDirectories="..,./../game"
PreprocessorDefinitions="_DEBUG;WIN32;_WINDOWS;MISSIONPACK;CGAME;_JK2;JK2AWARDS"
BasicRuntimeChecks="3"
RuntimeLibrary="5"
UsePrecompiledHeader="2"
PrecompiledHeaderFile=".\../Debug/JK2cgame/JK2_cgame.pch"
AssemblerListingLocation=".\../Debug/JK2cgame/"
ObjectFile=".\../Debug/JK2cgame/"
ProgramDataBaseFileName=".\../Debug/JK2cgame/"
BrowseInformation="1"
WarningLevel="3"
SuppressStartupBanner="TRUE"
DebugInformationFormat="4"
CompileAs="0"/>
<Tool
Name="VCCustomBuildTool"/>
<Tool
Name="VCLinkerTool"
AdditionalOptions="/MACHINE:I386"
AdditionalDependencies="odbc32.lib odbccp32.lib"
OutputFile="..\Debug\cgamex86.dll"
LinkIncremental="2"
SuppressStartupBanner="TRUE"
ModuleDefinitionFile=".\JK2_cgame.def"
GenerateDebugInformation="TRUE"
ProgramDatabaseFile=".\../Debug/cgamex86.pdb"
GenerateMapFile="TRUE"
MapFileName=".\../Debug/JK2cgame/cgamex86.map"
SubSystem="2"
BaseAddress="0x30000000"
ImportLibrary=".\../Debug/cgamex86.lib"/>
<Tool
Name="VCMIDLTool"
PreprocessorDefinitions="_Debug"
MkTypLibCompatible="TRUE"
SuppressStartupBanner="TRUE"
TargetEnvironment="1"
TypeLibraryName=".\../Debug/JK2_cgame.tlb"/>
<Tool
Name="VCPostBuildEventTool"/>
<Tool
Name="VCPreBuildEventTool"/>
<Tool
Name="VCPreLinkEventTool"/>
<Tool
Name="VCResourceCompilerTool"
PreprocessorDefinitions="_Debug"
Culture="1033"/>
<Tool
Name="VCWebServiceProxyGeneratorTool"/>
<Tool
Name="VCWebDeploymentTool"/>
</Configuration>
</Configurations>
<Files>
<Filter
Name="Source Files"
Filter="c">
<File
RelativePath="..\game\AnimalNPC.c">
</File>
<File
RelativePath="..\game\FighterNPC.c">
</File>
<File
RelativePath="..\game\SpeederNPC.c">
</File>
<File
RelativePath="..\game\WalkerNPC.c">
</File>
<File
RelativePath="..\game\bg_g2_utils.c">
</File>
<File
RelativePath="..\game\bg_lib.c">
<FileConfiguration
Name="Release|Win32"
ExcludedFromBuild="TRUE">
<Tool
Name="VCCLCompilerTool"/>
</FileConfiguration>
<FileConfiguration
Name="Final|Win32"
ExcludedFromBuild="TRUE">
<Tool
Name="VCCLCompilerTool"/>
</FileConfiguration>
<FileConfiguration
Name="Debug|Win32"
ExcludedFromBuild="TRUE">
<Tool
Name="VCCLCompilerTool"/>
</FileConfiguration>
<FileConfiguration
Name="Debug(SH)|Win32"
ExcludedFromBuild="TRUE">
<Tool
Name="VCCLCompilerTool"/>
</FileConfiguration>
</File>
<File
RelativePath="..\game\bg_misc.c">
</File>
<File
RelativePath="..\game\bg_panimate.c">
</File>
<File
RelativePath="..\game\bg_pmove.c">
</File>
<File
RelativePath="..\game\bg_saber.c">
</File>
<File
RelativePath="..\game\bg_saberLoad.c">
</File>
<File
RelativePath="..\game\bg_saga.c">
</File>
<File
RelativePath="..\game\bg_slidemove.c">
</File>
<File
RelativePath="..\game\bg_vehicleLoad.c">
</File>
<File
RelativePath="..\game\bg_weapons.c">
</File>
<File
RelativePath=".\cg_consolecmds.c">
</File>
<File
RelativePath=".\cg_draw.c">
</File>
<File
RelativePath=".\cg_drawtools.c">
</File>
<File
RelativePath=".\cg_effects.c">
</File>
<File
RelativePath=".\cg_ents.c">
</File>
<File
RelativePath=".\cg_event.c">
</File>
<File
RelativePath=".\cg_info.c">
</File>
<File
RelativePath=".\cg_light.c">
</File>
<File
RelativePath=".\cg_localents.c">
</File>
<File
RelativePath=".\cg_main.c">
</File>
<File
RelativePath=".\cg_marks.c">
</File>
<File
RelativePath=".\cg_newDraw.c">
</File>
<File
RelativePath=".\cg_players.c">
</File>
<File
RelativePath=".\cg_playerstate.c">
</File>
<File
RelativePath=".\cg_predict.c">
</File>
<File
RelativePath=".\cg_saga.c">
</File>
<File
RelativePath=".\cg_scoreboard.c">
</File>
<File
RelativePath=".\cg_servercmds.c">
</File>
<File
RelativePath=".\cg_snapshot.c">
</File>
<File
RelativePath=".\cg_strap.c">
</File>
<File
RelativePath=".\cg_syscalls.c">
</File>
<File
RelativePath=".\cg_turret.c">
</File>
<File
RelativePath=".\cg_view.c">
</File>
<File
RelativePath=".\cg_weaponinit.c">
</File>
<File
RelativePath=".\cg_weapons.c">
</File>
<File
RelativePath=".\fx_blaster.c">
</File>
<File
RelativePath=".\fx_bowcaster.c">
</File>
<File
RelativePath=".\fx_bryarpistol.c">
</File>
<File
RelativePath=".\fx_demp2.c">
</File>
<File
RelativePath=".\fx_disruptor.c">
</File>
<File
RelativePath=".\fx_flechette.c">
</File>
<File
RelativePath=".\fx_force.c">
</File>
<File
RelativePath=".\fx_heavyrepeater.c">
</File>
<File
RelativePath=".\fx_rocketlauncher.c">
</File>
<File
RelativePath="..\game\q_math.c">
</File>
<File
RelativePath="..\game\q_shared.c">
</File>
<File
RelativePath="..\ui\ui_shared.c">
</File>
</Filter>
<Filter
Name="Header Files"
Filter="h">
<File
RelativePath="..\ghoul2\G2.h">
</File>
<File
RelativePath=".\JK2_cgame.def">
</File>
<File
RelativePath="..\game\anims.h">
</File>
<File
RelativePath=".\animtable.h">
</File>
<File
RelativePath="..\game\bg_local.h">
</File>
<File
RelativePath="..\game\bg_public.h">
</File>
<File
RelativePath="..\game\bg_saga.h">
</File>
<File
RelativePath="..\game\bg_strap.h">
</File>
<File
RelativePath="..\game\bg_weapons.h">
</File>
<File
RelativePath=".\cg_lights.h">
</File>
<File
RelativePath=".\cg_local.h">
</File>
<File
RelativePath=".\cg_public.h">
</File>
<File
RelativePath="..\qcommon\disablewarnings.h">
</File>
<File
RelativePath=".\fx_local.h">
</File>
<File
RelativePath="holocronicons.h">
</File>
<File
RelativePath="..\ui\keycodes.h">
</File>
<File
RelativePath="..\..\ui\menudef.h">
</File>
<File
RelativePath="..\game\q_shared.h">
</File>
<File
RelativePath="..\qcommon\qfiles.h">
</File>
<File
RelativePath="..\game\surfaceflags.h">
</File>
<File
RelativePath="..\qcommon\tags.h">
</File>
<File
RelativePath=".\tr_types.h">
</File>
<File
RelativePath="..\ui\ui_shared.h">
</File>
</Filter>
<Filter
Name="win32"
Filter="">
<File
RelativePath="..\win32\JK2cgame.rc">
</File>
</Filter>
<File
RelativePath=".\cgame.bat">
</File>
<File
RelativePath=".\cgame.q3asm">
</File>
</Files>
<Globals>
</Globals>
</VisualStudioProject>

1792
codemp/cgame/animtable.h Normal file

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,416 @@
// Copyright (C) 1999-2000 Id Software, Inc.
//
// cg_consolecmds.c -- text commands typed in at the local console, or
// executed by a key binding
#include "cg_local.h"
#include "../ui/ui_shared.h"
#include "bg_saga.h"
extern menuDef_t *menuScoreboard;
#ifdef _XBOX
#include "../client/cl_data.h"
#endif
void CG_TargetCommand_f( void ) {
int targetNum;
char test[4];
targetNum = CG_CrosshairPlayer();
if (!targetNum ) {
return;
}
trap_Argv( 1, test, 4 );
trap_SendConsoleCommand( va( "gc %i %i", targetNum, atoi( test ) ) );
}
/*
=================
CG_SizeUp_f
Keybinding command
=================
*/
static void CG_SizeUp_f (void) {
trap_Cvar_Set("cg_viewsize", va("%i",(int)(cg_viewsize.integer+10)));
}
/*
=================
CG_SizeDown_f
Keybinding command
=================
*/
static void CG_SizeDown_f (void) {
trap_Cvar_Set("cg_viewsize", va("%i",(int)(cg_viewsize.integer-10)));
}
/*
=============
CG_Viewpos_f
Debugging command to print the current position
=============
*/
static void CG_Viewpos_f (void) {
CG_Printf ("%s (%i %i %i) : %i\n", cgs.mapname, (int)cg->refdef.vieworg[0],
(int)cg->refdef.vieworg[1], (int)cg->refdef.vieworg[2],
(int)cg->refdef.viewangles[YAW]);
}
static void CG_ScoresDown_f( void ) {
CG_BuildSpectatorString();
if ( cg->scoresRequestTime + 2000 < cg->time ) {
// the scores are more than two seconds out of data,
// so request new ones
cg->scoresRequestTime = cg->time;
trap_SendClientCommand( "score" );
// leave the current scores up if they were already
// displayed, but if this is the first hit, clear them out
if ( !cg->showScores ) {
cg->showScores = qtrue;
cg->numScores = 0;
}
} else {
// show the cached contents even if they just pressed if it
// is within two seconds
cg->showScores = qtrue;
}
}
static void CG_ScoresUp_f( void ) {
if ( cg->showScores ) {
cg->showScores = qfalse;
cg->scoreFadeTime = cg->time;
}
}
extern menuDef_t *menuScoreboard;
void Menu_Reset(); // FIXME: add to right include file
static void CG_scrollScoresDown_f( void) {
if (menuScoreboard && cg->scoreBoardShowing) {
Menu_ScrollFeeder(menuScoreboard, FEEDER_SCOREBOARD, qtrue);
Menu_ScrollFeeder(menuScoreboard, FEEDER_REDTEAM_LIST, qtrue);
Menu_ScrollFeeder(menuScoreboard, FEEDER_BLUETEAM_LIST, qtrue);
}
}
static void CG_scrollScoresUp_f( void) {
if (menuScoreboard && cg->scoreBoardShowing) {
Menu_ScrollFeeder(menuScoreboard, FEEDER_SCOREBOARD, qfalse);
Menu_ScrollFeeder(menuScoreboard, FEEDER_REDTEAM_LIST, qfalse);
Menu_ScrollFeeder(menuScoreboard, FEEDER_BLUETEAM_LIST, qfalse);
}
}
static void CG_spWin_f( void) {
trap_Cvar_Set("cg_cameraOrbit", "2");
trap_Cvar_Set("cg_cameraOrbitDelay", "35");
trap_Cvar_Set("cg_thirdPerson", "1");
trap_Cvar_Set("cg_thirdPersonAngle", "0");
trap_Cvar_Set("cg_thirdPersonRange", "100");
#ifdef _XBOX
ClientManager::ActiveClient().cg_thirdPerson = 1;
ClientManager::ActiveClient().cg_thirdPersonRange = 100;
ClientManager::ActiveClient().cg_thirdPersonAngle = 0;
#endif
CG_AddBufferedSound(cgs.media.winnerSound);
//trap_S_StartLocalSound(cgs.media.winnerSound, CHAN_ANNOUNCER);
CG_CenterPrint(CG_GetStringEdString("MP_INGAME", "YOU_WIN"), SCREEN_HEIGHT * .30, 0);
}
static void CG_spLose_f( void) {
trap_Cvar_Set("cg_cameraOrbit", "2");
trap_Cvar_Set("cg_cameraOrbitDelay", "35");
trap_Cvar_Set("cg_thirdPerson", "1");
trap_Cvar_Set("cg_thirdPersonAngle", "0");
trap_Cvar_Set("cg_thirdPersonRange", "100");
#ifdef _XBOX
ClientManager::ActiveClient().cg_thirdPerson = 1;
ClientManager::ActiveClient().cg_thirdPersonRange = 100;
ClientManager::ActiveClient().cg_thirdPersonAngle = 0;
#endif
CG_AddBufferedSound(cgs.media.loserSound);
//trap_S_StartLocalSound(cgs.media.loserSound, CHAN_ANNOUNCER);
CG_CenterPrint(CG_GetStringEdString("MP_INGAME", "YOU_LOSE"), SCREEN_HEIGHT * .30, 0);
}
static void CG_TellTarget_f( void ) {
int clientNum;
char command[128];
char message[128];
clientNum = CG_CrosshairPlayer();
if ( clientNum == -1 ) {
return;
}
trap_Args( message, 128 );
Com_sprintf( command, 128, "tell %i %s", clientNum, message );
trap_SendClientCommand( command );
}
static void CG_TellAttacker_f( void ) {
int clientNum;
char command[128];
char message[128];
clientNum = CG_LastAttacker();
if ( clientNum == -1 ) {
return;
}
trap_Args( message, 128 );
Com_sprintf( command, 128, "tell %i %s", clientNum, message );
trap_SendClientCommand( command );
}
/*
==================
CG_StartOrbit_f
==================
*/
static void CG_StartOrbit_f( void ) {
char var[MAX_TOKEN_CHARS];
trap_Cvar_VariableStringBuffer( "developer", var, sizeof( var ) );
if ( !atoi(var) ) {
return;
}
if (cg_cameraOrbit.value != 0) {
trap_Cvar_Set ("cg_cameraOrbit", "0");
#ifdef _XBOX
ClientManager::ActiveClient().cg_thirdPerson = 0;
#endif
trap_Cvar_Set("cg_thirdPerson", "0");
} else {
trap_Cvar_Set("cg_cameraOrbit", "5");
trap_Cvar_Set("cg_thirdPerson", "1");
trap_Cvar_Set("cg_thirdPersonAngle", "0");
trap_Cvar_Set("cg_thirdPersonRange", "100");
#ifdef _XBOX
ClientManager::ActiveClient().cg_thirdPerson = 1;
ClientManager::ActiveClient().cg_thirdPersonRange = 100;
ClientManager::ActiveClient().cg_thirdPersonAngle = 0;
#endif
}
}
void CG_SiegeBriefingDisplay(int team, int dontshow);
static void CG_SiegeBriefing_f(void)
{
int team;
if (cgs.gametype != GT_SIEGE)
{ //Cannot be displayed unless in this gametype
return;
}
team = cg->predictedPlayerState.persistant[PERS_TEAM];
if (team != SIEGETEAM_TEAM1 &&
team != SIEGETEAM_TEAM2)
{ //cannot be displayed if not on a valid team
return;
}
CG_SiegeBriefingDisplay(team, 0);
}
static void CG_SiegeCvarUpdate_f(void)
{
int team;
if (cgs.gametype != GT_SIEGE)
{ //Cannot be displayed unless in this gametype
return;
}
team = cg->predictedPlayerState.persistant[PERS_TEAM];
if (team != SIEGETEAM_TEAM1 &&
team != SIEGETEAM_TEAM2)
{ //cannot be displayed if not on a valid team
return;
}
CG_SiegeBriefingDisplay(team, 1);
}
static void CG_SiegeCompleteCvarUpdate_f(void)
{
if (cgs.gametype != GT_SIEGE)
{ //Cannot be displayed unless in this gametype
return;
}
// Set up cvars for both teams
CG_SiegeBriefingDisplay(SIEGETEAM_TEAM1, 1);
CG_SiegeBriefingDisplay(SIEGETEAM_TEAM2, 1);
}
/*
static void CG_Camera_f( void ) {
char name[1024];
trap_Argv( 1, name, sizeof(name));
if (trap_loadCamera(name)) {
cg->cameraMode = qtrue;
trap_startCamera(cg->time);
} else {
CG_Printf ("Unable to load camera %s\n",name);
}
}
*/
typedef struct {
char *cmd;
void (*function)(void);
} consoleCommand_t;
static consoleCommand_t commands[] = {
{ "testgun", CG_TestGun_f },
{ "testmodel", CG_TestModel_f },
{ "nextframe", CG_TestModelNextFrame_f },
{ "prevframe", CG_TestModelPrevFrame_f },
{ "nextskin", CG_TestModelNextSkin_f },
{ "prevskin", CG_TestModelPrevSkin_f },
{ "viewpos", CG_Viewpos_f },
{ "+scores", CG_ScoresDown_f },
{ "-scores", CG_ScoresUp_f },
{ "sizeup", CG_SizeUp_f },
{ "sizedown", CG_SizeDown_f },
{ "weapnext", CG_NextWeapon_f },
{ "weapprev", CG_PrevWeapon_f },
{ "weapon", CG_Weapon_f },
{ "weaponclean", CG_WeaponClean_f },
{ "tell_target", CG_TellTarget_f },
{ "tell_attacker", CG_TellAttacker_f },
{ "tcmd", CG_TargetCommand_f },
{ "spWin", CG_spWin_f },
{ "spLose", CG_spLose_f },
{ "scoresDown", CG_scrollScoresDown_f },
{ "scoresUp", CG_scrollScoresUp_f },
{ "startOrbit", CG_StartOrbit_f },
//{ "camera", CG_Camera_f },
{ "loaddeferred", CG_LoadDeferredPlayers },
{ "invnext", CG_NextInventory_f },
{ "invprev", CG_PrevInventory_f },
{ "forcenext", CG_NextForcePower_f },
{ "forceprev", CG_PrevForcePower_f },
{ "briefing", CG_SiegeBriefing_f },
{ "siegeCvarUpdate", CG_SiegeCvarUpdate_f },
{ "siegeCompleteCvarUpdate", CG_SiegeCompleteCvarUpdate_f },
};
/*
=================
CG_ConsoleCommand
The string has been tokenized and can be retrieved with
Cmd_Argc() / Cmd_Argv()
=================
*/
qboolean CG_ConsoleCommand( void ) {
const char *cmd;
int i;
cmd = CG_Argv(0);
for ( i = 0 ; i < sizeof( commands ) / sizeof( commands[0] ) ; i++ ) {
if ( !Q_stricmp( cmd, commands[i].cmd ) ) {
commands[i].function();
return qtrue;
}
}
return qfalse;
}
/*
=================
CG_InitConsoleCommands
Let the client system know about all of our commands
so it can perform tab completion
=================
*/
void CG_InitConsoleCommands( void ) {
int i;
for ( i = 0 ; i < sizeof( commands ) / sizeof( commands[0] ) ; i++ ) {
trap_AddCommand( commands[i].cmd );
}
//
// the game server will interpret these commands, which will be automatically
// forwarded to the server after they are not recognized locally
//
trap_AddCommand ("forcechanged");
trap_AddCommand ("sv_invnext");
trap_AddCommand ("sv_invprev");
trap_AddCommand ("sv_forcenext");
trap_AddCommand ("sv_forceprev");
trap_AddCommand ("sv_saberswitch");
trap_AddCommand ("engage_duel");
trap_AddCommand ("force_heal");
trap_AddCommand ("force_speed");
trap_AddCommand ("force_throw");
trap_AddCommand ("force_pull");
trap_AddCommand ("force_distract");
trap_AddCommand ("force_rage");
trap_AddCommand ("force_protect");
trap_AddCommand ("force_absorb");
trap_AddCommand ("force_healother");
trap_AddCommand ("force_forcepowerother");
trap_AddCommand ("force_seeing");
trap_AddCommand ("use_seeker");
trap_AddCommand ("use_field");
trap_AddCommand ("use_bacta");
trap_AddCommand ("use_electrobinoculars");
trap_AddCommand ("zoom");
trap_AddCommand ("use_sentry");
trap_AddCommand ("bot_order");
trap_AddCommand ("saberAttackCycle");
trap_AddCommand ("kill");
trap_AddCommand ("say");
trap_AddCommand ("say_team");
trap_AddCommand ("tell");
trap_AddCommand ("give");
trap_AddCommand ("god");
trap_AddCommand ("notarget");
trap_AddCommand ("noclip");
trap_AddCommand ("team");
trap_AddCommand ("follow");
trap_AddCommand ("levelshot");
trap_AddCommand ("addbot");
trap_AddCommand ("setviewpos");
trap_AddCommand ("callvote");
trap_AddCommand ("vote");
trap_AddCommand ("callteamvote");
trap_AddCommand ("teamvote");
trap_AddCommand ("stats");
trap_AddCommand ("teamtask");
trap_AddCommand ("loaddefered"); // spelled wrong, but not changing for demo
}

10281
codemp/cgame/cg_draw.c Normal file

File diff suppressed because it is too large Load Diff

544
codemp/cgame/cg_drawtools.c Normal file
View File

@@ -0,0 +1,544 @@
/*
// this line must stay at top so the whole PCH thing works...
#include "cg_headers.h"
//#include "cg_local.h"
#include "cg_media.h"
#include "cg_text.h"
*/
// Copyright (C) 1999-2000 Id Software, Inc.
//
// cg_drawtools.c -- helper functions called by cg_draw, cg_scoreboard, cg_info, etc
#include "cg_local.h"
#include "../game/q_shared.h"
/*
================
UI_DrawRect
Coordinates are 640*480 virtual values
=================
*/
void CG_DrawRect( float x, float y, float width, float height, float size, const float *color ) {
trap_R_SetColor( color );
CG_DrawTopBottom(x, y, width, height, size);
CG_DrawSides(x, y, width, height, size);
trap_R_SetColor( NULL );
}
/*
=================
CG_GetColorForHealth
=================
*/
void CG_GetColorForHealth( int health, int armor, vec4_t hcolor ) {
int count;
int max;
// calculate the total points of damage that can
// be sustained at the current health / armor level
if ( health <= 0 ) {
VectorClear( hcolor ); // black
hcolor[3] = 1;
return;
}
count = armor;
max = health * ARMOR_PROTECTION / ( 1.0 - ARMOR_PROTECTION );
if ( max < count ) {
count = max;
}
health += count;
// set the color based on health
hcolor[0] = 1.0;
hcolor[3] = 1.0;
if ( health >= 100 ) {
hcolor[2] = 1.0;
} else if ( health < 66 ) {
hcolor[2] = 0;
} else {
hcolor[2] = ( health - 66 ) / 33.0;
}
if ( health > 60 ) {
hcolor[1] = 1.0;
} else if ( health < 30 ) {
hcolor[1] = 0;
} else {
hcolor[1] = ( health - 30 ) / 30.0;
}
}
/*
================
CG_DrawSides
Coords are virtual 640x480
================
*/
void CG_DrawSides(float x, float y, float w, float h, float size) {
size *= cgs.screenXScale;
trap_R_DrawStretchPic( x, y, size, h, 0, 0, 0, 0, cgs.media.whiteShader );
trap_R_DrawStretchPic( x + w - size, y, size, h, 0, 0, 0, 0, cgs.media.whiteShader );
}
void CG_DrawTopBottom(float x, float y, float w, float h, float size) {
size *= cgs.screenYScale;
trap_R_DrawStretchPic( x, y, w, size, 0, 0, 0, 0, cgs.media.whiteShader );
trap_R_DrawStretchPic( x, y + h - size, w, size, 0, 0, 0, 0, cgs.media.whiteShader );
}
/*
-------------------------
CGC_FillRect2
real coords
-------------------------
*/
void CG_FillRect2( float x, float y, float width, float height, const float *color ) {
trap_R_SetColor( color );
trap_R_DrawStretchPic( x, y, width, height, 0, 0, 0, 0, cgs.media.whiteShader);
trap_R_SetColor( NULL );
}
/*
================
CG_FillRect
Coordinates are 640*480 virtual values
=================
*/
void CG_FillRect( float x, float y, float width, float height, const float *color ) {
trap_R_SetColor( color );
trap_R_DrawStretchPic( x, y, width, height, 0, 0, 0, 0, cgs.media.whiteShader);
trap_R_SetColor( NULL );
}
/*
================
CG_DrawPic
Coordinates are 640*480 virtual values
A width of 0 will draw with the original image width
=================
*/
void CG_DrawPic( float x, float y, float width, float height, qhandle_t hShader ) {
trap_R_DrawStretchPic( x, y, width, height, 0, 0, 1, 1, hShader );
}
/*
================
CG_DrawRotatePic
Coordinates are 640*480 virtual values
A width of 0 will draw with the original image width
rotates around the upper right corner of the passed in point
=================
*/
void CG_DrawRotatePic( float x, float y, float width, float height,float angle, qhandle_t hShader ) {
trap_R_DrawRotatePic( x, y, width, height, 0, 0, 1, 1, angle, hShader );
}
/*
================
CG_DrawRotatePic2
Coordinates are 640*480 virtual values
A width of 0 will draw with the original image width
Actually rotates around the center point of the passed in coordinates
=================
*/
void CG_DrawRotatePic2( float x, float y, float width, float height,float angle, qhandle_t hShader ) {
trap_R_DrawRotatePic2( x, y, width, height, 0, 0, 1, 1, angle, hShader );
}
/*
=============
CG_TileClearBox
This repeats a 64*64 tile graphic to fill the screen around a sized down
refresh window.
=============
*/
static void CG_TileClearBox( int x, int y, int w, int h, qhandle_t hShader ) {
float s1, t1, s2, t2;
s1 = x/64.0;
t1 = y/64.0;
s2 = (x+w)/64.0;
t2 = (y+h)/64.0;
trap_R_DrawStretchPic( x, y, w, h, s1, t1, s2, t2, hShader );
}
/*
==============
CG_TileClear
Clear around a sized down screen
==============
*/
void CG_TileClear( void ) {
/*
int top, bottom, left, right;
int w, h;
w = cgs.glconfig.vidWidth;
h = cgs.glconfig.vidHeight;
if ( cg->refdef.x == 0 && cg->refdef.y == 0 &&
cg->refdef.width == w && cg->refdef.height == h ) {
return; // full screen rendering
}
top = cg->refdef.y;
bottom = top + cg->refdef.height-1;
left = cg->refdef.x;
right = left + cg->refdef.width-1;
// clear above view screen
CG_TileClearBox( 0, 0, w, top, cgs.media.backTileShader );
// clear below view screen
CG_TileClearBox( 0, bottom, w, h - bottom, cgs.media.backTileShader );
// clear left of view screen
CG_TileClearBox( 0, top, left, bottom - top + 1, cgs.media.backTileShader );
// clear right of view screen
CG_TileClearBox( right, top, w - right, bottom - top + 1, cgs.media.backTileShader );
*/
}
/*
================
CG_FadeColor
================
*/
float *CG_FadeColor( int startMsec, int totalMsec ) {
static vec4_t color;
int t;
if ( startMsec == 0 ) {
return NULL;
}
t = cg->time - startMsec;
if ( t >= totalMsec ) {
return NULL;
}
// fade out
if ( totalMsec - t < FADE_TIME ) {
color[3] = ( totalMsec - t ) * 1.0/FADE_TIME;
} else {
color[3] = 1.0;
}
color[0] = color[1] = color[2] = 1;
return color;
}
/*
=================
CG_ColorForHealth
=================
*/
void CG_ColorForGivenHealth( vec4_t hcolor, int health )
{
// set the color based on health
hcolor[0] = 1.0;
if ( health >= 100 )
{
hcolor[2] = 1.0;
}
else if ( health < 66 )
{
hcolor[2] = 0;
}
else
{
hcolor[2] = ( health - 66 ) / 33.0;
}
if ( health > 60 )
{
hcolor[1] = 1.0;
}
else if ( health < 30 )
{
hcolor[1] = 0;
}
else
{
hcolor[1] = ( health - 30 ) / 30.0;
}
}
/*
=================
CG_ColorForHealth
=================
*/
void CG_ColorForHealth( vec4_t hcolor )
{
int health;
int count;
int max;
// calculate the total points of damage that can
// be sustained at the current health / armor level
health = cg->snap->ps.stats[STAT_HEALTH];
if ( health <= 0 )
{
VectorClear( hcolor ); // black
hcolor[3] = 1;
return;
}
count = cg->snap->ps.stats[STAT_ARMOR];
max = health * ARMOR_PROTECTION / ( 1.0 - ARMOR_PROTECTION );
if ( max < count )
{
count = max;
}
health += count;
hcolor[3] = 1.0;
CG_ColorForGivenHealth( hcolor, health );
}
/*
==============
CG_DrawNumField
Take x,y positions as if 640 x 480 and scales them to the proper resolution
==============
*/
void CG_DrawNumField (int x, int y, int width, int value,int charWidth,int charHeight,int style,qboolean zeroFill)
{
char num[16], *ptr;
int l;
int frame;
int xWidth;
int i = 0;
if (width < 1) {
return;
}
// draw number string
if (width > 5) {
width = 5;
}
switch ( width ) {
case 1:
value = value > 9 ? 9 : value;
value = value < 0 ? 0 : value;
break;
case 2:
value = value > 99 ? 99 : value;
value = value < -9 ? -9 : value;
break;
case 3:
value = value > 999 ? 999 : value;
value = value < -99 ? -99 : value;
break;
case 4:
value = value > 9999 ? 9999 : value;
value = value < -999 ? -999 : value;
break;
}
Com_sprintf (num, sizeof(num), "%i", value);
l = strlen(num);
if (l > width)
l = width;
// FIXME: Might need to do something different for the chunky font??
switch(style)
{
case NUM_FONT_SMALL:
xWidth = charWidth;
break;
// case NUM_FONT_CHUNKY:
// xWidth = (charWidth/1.2f) + 2;
// break;
default:
case NUM_FONT_BIG:
xWidth = (charWidth/2) + 7;//(charWidth/6);
break;
}
#ifndef _XBOX
if ( zeroFill )
{
for (i = 0; i < (width - l); i++ )
{
switch(style)
{
case NUM_FONT_SMALL:
CG_DrawPic( x,y, charWidth, charHeight, cgs.media.smallnumberShaders[0] );
break;
// case NUM_FONT_CHUNKY:
// CG_DrawPic( x,y, charWidth, charHeight, cgs.media.chunkyNumberShaders[0] );
// break;
default:
case NUM_FONT_BIG:
CG_DrawPic( x,y, charWidth, charHeight, cgs.media.numberShaders[0] );
break;
}
x += 2 + (xWidth);
}
}
else
#endif
{
x += 2 + (xWidth)*(width - l);
}
ptr = num;
while (*ptr && l)
{
if (*ptr == '-')
frame = STAT_MINUS;
else
frame = *ptr -'0';
switch(style)
{
case NUM_FONT_SMALL:
if(zeroFill)
{
CG_DrawPic( x-2,y, charWidth, charHeight, cgs.media.smallnumberShaders[frame] );
CG_DrawPic( x+2,y, charWidth, charHeight, cgs.media.smallnumberShaders[frame] );
CG_DrawPic( x,y-2, charWidth, charHeight, cgs.media.smallnumberShaders[frame] );
CG_DrawPic( x,y+2, charWidth, charHeight, cgs.media.smallnumberShaders[frame] );
x++; // For a one line gap
}
else {
CG_DrawPic( x,y, charWidth, charHeight, cgs.media.smallnumberShaders[frame] );
x++; // For a one line gap
}
break;
// case NUM_FONT_CHUNKY:
// CG_DrawPic( x,y, charWidth, charHeight, cgs.media.chunkyNumberShaders[frame] );
// break;
default:
case NUM_FONT_BIG:
CG_DrawPic( x,y, charWidth, charHeight, cgs.media.numberShaders[frame] );
break;
}
x += (xWidth);
ptr++;
l--;
}
}
#include "../ui/ui_shared.h" // for some text style junk
void UI_DrawProportionalString( int x, int y, const char* str, int style, vec4_t color )
{
// having all these different style defines (1 for UI, one for CG, and now one for the re->font stuff)
// is dumb, but for now...
//
int iStyle = 0;
int iMenuFont = (style & UI_SMALLFONT) ? FONT_SMALL : FONT_MEDIUM;
switch (style & (UI_LEFT|UI_CENTER|UI_RIGHT))
{
default:
case UI_LEFT:
{
// nada...
}
break;
case UI_CENTER:
{
x -= CG_Text_Width(str, 1.0, iMenuFont) / 2;
}
break;
case UI_RIGHT:
{
x -= CG_Text_Width(str, 1.0, iMenuFont) / 2;
}
break;
}
if (style & UI_DROPSHADOW)
{
iStyle = ITEM_TEXTSTYLE_SHADOWED;
}
else
if ( style & (UI_BLINK|UI_PULSE) )
{
iStyle = ITEM_TEXTSTYLE_BLINK;
}
CG_Text_Paint(x, y, 1.0, color, str, 0, 0, iStyle, iMenuFont);
}
void UI_DrawScaledProportionalString( int x, int y, const char* str, int style, vec4_t color, float scale)
{
// having all these different style defines (1 for UI, one for CG, and now one for the re->font stuff)
// is dumb, but for now...
//
int iStyle = 0;
switch (style & (UI_LEFT|UI_CENTER|UI_RIGHT))
{
default:
case UI_LEFT:
{
// nada...
}
break;
case UI_CENTER:
{
x -= CG_Text_Width(str, scale, FONT_MEDIUM) / 2;
}
break;
case UI_RIGHT:
{
x -= CG_Text_Width(str, scale, FONT_MEDIUM) / 2;
}
break;
}
if (style & UI_DROPSHADOW)
{
iStyle = ITEM_TEXTSTYLE_SHADOWED;
}
else
if ( style & (UI_BLINK|UI_PULSE) )
{
iStyle = ITEM_TEXTSTYLE_BLINK;
}
CG_Text_Paint(x, y, scale, color, str, 0, 0, iStyle, FONT_MEDIUM);
}

1546
codemp/cgame/cg_effects.c Normal file

File diff suppressed because it is too large Load Diff

3888
codemp/cgame/cg_ents.c Normal file

File diff suppressed because it is too large Load Diff

3572
codemp/cgame/cg_event.c Normal file

File diff suppressed because it is too large Load Diff

412
codemp/cgame/cg_info.c Normal file
View File

@@ -0,0 +1,412 @@
// Copyright (C) 1999-2000 Id Software, Inc.
//
// cg_info.c -- display information while data is being loading
#include "cg_local.h"
#ifdef _XBOX
#include "../client/cl_data.h"
#endif
#define MAX_LOADING_PLAYER_ICONS 16
#define MAX_LOADING_ITEM_ICONS 26
//static int loadingPlayerIconCount;
//static qhandle_t loadingPlayerIcons[MAX_LOADING_PLAYER_ICONS];
void CG_LoadBar(void);
/*
======================
CG_LoadingString
======================
*/
void CG_LoadingString( const char *s ) {
#ifdef _XBOX
if (ClientManager::ActiveClientNum() == 1)
return;
#endif
Q_strncpyz( cg->infoScreenText, s, sizeof( cg->infoScreenText ) );
trap_UpdateScreen();
}
/*
===================
CG_LoadingItem
===================
*/
void CG_LoadingItem( int itemNum ) {
gitem_t *item;
char upperKey[1024];
item = &bg_itemlist[itemNum];
if (!item->classname || !item->classname[0])
{
// CG_LoadingString( "Unknown item" );
return;
}
strcpy(upperKey, item->classname);
CG_LoadingString( CG_GetStringEdString("SP_INGAME",Q_strupr(upperKey)) );
}
/*
===================
CG_LoadingClient
===================
*/
void CG_LoadingClient( int clientNum ) {
const char *info;
char personality[MAX_QPATH];
info = CG_ConfigString( CS_PLAYERS + clientNum );
/*
char model[MAX_QPATH];
char iconName[MAX_QPATH];
char *skin;
if ( loadingPlayerIconCount < MAX_LOADING_PLAYER_ICONS ) {
Q_strncpyz( model, Info_ValueForKey( info, "model" ), sizeof( model ) );
skin = Q_strrchr( model, '/' );
if ( skin ) {
*skin++ = '\0';
} else {
skin = "default";
}
Com_sprintf( iconName, MAX_QPATH, "models/players/%s/icon_%s.tga", model, skin );
loadingPlayerIcons[loadingPlayerIconCount] = trap_R_RegisterShaderNoMip( iconName );
if ( !loadingPlayerIcons[loadingPlayerIconCount] ) {
Com_sprintf( iconName, MAX_QPATH, "models/players/characters/%s/icon_%s.tga", model, skin );
loadingPlayerIcons[loadingPlayerIconCount] = trap_R_RegisterShaderNoMip( iconName );
}
if ( !loadingPlayerIcons[loadingPlayerIconCount] ) {
Com_sprintf( iconName, MAX_QPATH, "models/players/%s/icon_%s.tga", DEFAULT_MODEL, "default" );
loadingPlayerIcons[loadingPlayerIconCount] = trap_R_RegisterShaderNoMip( iconName );
}
if ( loadingPlayerIcons[loadingPlayerIconCount] ) {
loadingPlayerIconCount++;
}
}
*/
Q_strncpyz( personality, Info_ValueForKey( info, "n" ), sizeof(personality) );
Q_CleanStr( personality );
/*
if( cgs.gametype == GT_SINGLE_PLAYER ) {
trap_S_RegisterSound( va( "sound/player/announce/%s.wav", personality ));
}
*/
CG_LoadingString( personality );
}
/*
====================
CG_DrawInformation
Draw all the status / pacifier stuff during level loading
====================
overlays UI_DrawConnectScreen
*/
#define UI_INFOFONT (UI_BIGFONT)
void CG_DrawInformation( void ) {
const char *s;
const char *info;
const char *sysInfo;
int y;
int value, valueNOFP;
qhandle_t levelshot;
char buf[1024];
int iPropHeight = 18; // I know, this is total crap, but as a post release asian-hack.... -Ste
info = CG_ConfigString( CS_SERVERINFO );
sysInfo = CG_ConfigString( CS_SYSTEMINFO );
s = Info_ValueForKey( info, "mapname" );
levelshot = trap_R_RegisterShaderNoMip( va( "levelshots/%s", s ) );
if ( !levelshot ) {
levelshot = trap_R_RegisterShaderNoMip( "menu/art/unknownmap_mp" );
}
trap_R_SetColor( NULL );
// Levelshot in bottom-right frame
CG_DrawPic( 371, 279, 189, 141, levelshot );
switch( cgs.gametype )
{
case GT_FFA:
levelshot = trap_R_RegisterShaderNoMip( "levelshots/mp_ffa" ); break;
case GT_DUEL:
levelshot = trap_R_RegisterShaderNoMip( "levelshots/mp_duel" ); break;
case GT_POWERDUEL:
levelshot = trap_R_RegisterShaderNoMip( "levelshots/mp_pduel" ); break;
case GT_TEAM:
levelshot = trap_R_RegisterShaderNoMip( "levelshots/mp_tffa" ); break;
case GT_SIEGE:
levelshot = trap_R_RegisterShaderNoMip( "levelshots/mp_siege" ); break;
case GT_CTF:
levelshot = trap_R_RegisterShaderNoMip( "levelshots/mp_ctf" ); break;
default:
levelshot = trap_R_RegisterShaderNoMip( "levelshots/mp_ffa" ); break;
}
CG_DrawPic( 75, 279, 189, 141, levelshot );
CG_LoadBar();
// draw the icons of things as they are loaded
// CG_DrawLoadingIcons();
// the first 150 rows are reserved for the client connection
// screen to write into
// if ( cg->infoScreenText[0] ) {
// const char *psLoading = CG_GetStringEdString("MENUS", "LOADING_MAPNAME");
// UI_DrawProportionalString( 320, 128-32, va(/*"Loading... %s"*/ psLoading, cg->infoScreenText),
// UI_CENTER|UI_INFOFONT|UI_DROPSHADOW, colorWhite );
// } else {
// const char *psAwaitingSnapshot = CG_GetStringEdString("MENUS", "AWAITING_SNAPSHOT");
// UI_DrawProportionalString( 320, 128-32, /*"Awaiting snapshot..."*/psAwaitingSnapshot,
// UI_CENTER|UI_INFOFONT|UI_DROPSHADOW, colorWhite );
// }
// draw info string information
y = 60;
// don't print server lines if playing a local game
trap_Cvar_VariableStringBuffer( "sv_running", buf, sizeof( buf ) );
/*
if ( !atoi( buf ) ) {
// server hostname
Q_strncpyz(buf, Info_ValueForKey( info, "sv_hostname" ), 1024);
Q_CleanStr(buf);
UI_DrawProportionalString( 320, y, buf,
UI_CENTER|UI_INFOFONT|UI_DROPSHADOW, colorWhite );
y += iPropHeight;
// some extra space after hostname and motd
y += 10;
}
*/
// Long map name
s = CG_ConfigString( CS_MESSAGE );
if ( s[0] ) {
UI_DrawProportionalString( 320, y, s,
UI_CENTER|UI_INFOFONT|UI_DROPSHADOW, colorWhite );
y += iPropHeight;
}
// Game type
switch ( cgs.gametype ) {
case GT_FFA:
s = CG_GetStringEdString("MENUS", "FREE_FOR_ALL"); break;
case GT_DUEL:
s = CG_GetStringEdString("MENUS", "DUEL"); break;
case GT_POWERDUEL:
s = CG_GetStringEdString("MENUS", "POWERDUEL"); break;
case GT_TEAM:
s = CG_GetStringEdString("MENUS", "TEAM_FFA"); break;
case GT_SIEGE:
s = CG_GetStringEdString("MENUS", "SIEGE"); break;
case GT_CTF:
s = CG_GetStringEdString("MENUS", "CAPTURE_THE_FLAG"); break;
default:
s = CG_GetStringEdString("MENUS", "FREE_FOR_ALL"); break;
}
UI_DrawProportionalString( 320, y, s, UI_CENTER|UI_INFOFONT|UI_DROPSHADOW, colorWhite );
y += iPropHeight;
// Rules
if (cgs.gametype != GT_SIEGE)
{
value = atoi( Info_ValueForKey( info, "timelimit" ) );
if ( value ) {
UI_DrawProportionalString( 320, y, va( "%s %i", CG_GetStringEdString("MP_INGAME", "TIMELIMIT"), value ),
UI_CENTER|UI_INFOFONT|UI_DROPSHADOW, colorWhite );
y += iPropHeight;
}
if (cgs.gametype < GT_CTF ) {
value = atoi( Info_ValueForKey( info, "fraglimit" ) );
if ( value ) {
UI_DrawProportionalString( 320, y, va( "%s %i", CG_GetStringEdString("MP_INGAME", "FRAGLIMIT"), value ),
UI_CENTER|UI_INFOFONT|UI_DROPSHADOW, colorWhite );
y += iPropHeight;
}
if (cgs.gametype == GT_DUEL || cgs.gametype == GT_POWERDUEL)
{
value = atoi( Info_ValueForKey( info, "duel_fraglimit" ) );
if ( value ) {
UI_DrawProportionalString( 320, y, va( "%s %i", CG_GetStringEdString("MP_INGAME", "WINLIMIT"), value ),
UI_CENTER|UI_INFOFONT|UI_DROPSHADOW, colorWhite );
y += iPropHeight;
}
}
}
}
if (cgs.gametype >= GT_CTF) {
value = atoi( Info_ValueForKey( info, "capturelimit" ) );
if ( value ) {
UI_DrawProportionalString( 320, y, va( "%s %i", CG_GetStringEdString("MP_INGAME", "CAPTURELIMIT"), value ),
UI_CENTER|UI_INFOFONT|UI_DROPSHADOW, colorWhite );
y += iPropHeight;
}
}
if (cgs.gametype >= GT_TEAM)
{
value = atoi( Info_ValueForKey( info, "g_forceBasedTeams" ) );
if ( value ) {
UI_DrawProportionalString( 320, y, CG_GetStringEdString("MP_INGAME", "FORCEBASEDTEAMS"),
UI_CENTER|UI_INFOFONT|UI_DROPSHADOW, colorWhite );
y += iPropHeight;
}
}
if (cgs.gametype != GT_SIEGE)
{
valueNOFP = atoi( Info_ValueForKey( info, "g_forcePowerDisable" ) );
value = atoi( Info_ValueForKey( info, "g_maxForceRank" ) );
if ( value && !valueNOFP ) {
char fmStr[1024];
trap_SP_GetStringTextString("MP_INGAME_MAXFORCERANK",fmStr, sizeof(fmStr));
UI_DrawProportionalString( 320, y, va( "%s %s", fmStr, CG_GetStringEdString("MP_INGAME", forceMasteryLevels[value]) ),
UI_CENTER|UI_INFOFONT|UI_DROPSHADOW, colorWhite );
y += iPropHeight;
}
else if (!valueNOFP)
{
char fmStr[1024];
trap_SP_GetStringTextString("MP_INGAME_MAXFORCERANK",fmStr, sizeof(fmStr));
UI_DrawProportionalString( 320, y, va( "%s %s", fmStr, (char *)CG_GetStringEdString("MP_INGAME", forceMasteryLevels[7]) ),
UI_CENTER|UI_INFOFONT|UI_DROPSHADOW, colorWhite );
y += iPropHeight;
}
if (cgs.gametype == GT_DUEL || cgs.gametype == GT_POWERDUEL)
{
value = atoi( Info_ValueForKey( info, "g_duelWeaponDisable" ) );
}
else
{
value = atoi( Info_ValueForKey( info, "g_weaponDisable" ) );
}
if ( cgs.gametype != GT_JEDIMASTER && value ) {
UI_DrawProportionalString( 320, y, va( "%s", (char *)CG_GetStringEdString("MP_INGAME", "SABERONLYSET") ),
UI_CENTER|UI_INFOFONT|UI_DROPSHADOW, colorWhite );
y += iPropHeight;
}
if ( valueNOFP ) {
UI_DrawProportionalString( 320, y, va( "%s", (char *)CG_GetStringEdString("MP_INGAME", "NOFPSET") ),
UI_CENTER|UI_INFOFONT|UI_DROPSHADOW, colorWhite );
y += iPropHeight;
}
}
// Display the rules based on type
y += iPropHeight;
switch ( cgs.gametype ) {
case GT_FFA:
UI_DrawProportionalString( 320, y, va( "%s", (char *)CG_GetStringEdString("MP_INGAME", "RULES_FFA_1")),
UI_CENTER|UI_INFOFONT|UI_DROPSHADOW, colorWhite );
y += iPropHeight;
break;
case GT_DUEL:
UI_DrawProportionalString( 320, y, va( "%s", (char *)CG_GetStringEdString("MP_INGAME", "RULES_DUEL_1")),
UI_CENTER|UI_INFOFONT|UI_DROPSHADOW, colorWhite );
y += iPropHeight;
UI_DrawProportionalString( 320, y, va( "%s", (char *)CG_GetStringEdString("MP_INGAME", "RULES_DUEL_2")),
UI_CENTER|UI_INFOFONT|UI_DROPSHADOW, colorWhite );
y += iPropHeight;
break;
case GT_POWERDUEL:
UI_DrawProportionalString( 320, y, va( "%s", (char *)CG_GetStringEdString("MP_INGAME", "RULES_POWERDUEL_1")),
UI_CENTER|UI_INFOFONT|UI_DROPSHADOW, colorWhite );
y += iPropHeight;
UI_DrawProportionalString( 320, y, va( "%s", (char *)CG_GetStringEdString("MP_INGAME", "RULES_POWERDUEL_2")),
UI_CENTER|UI_INFOFONT|UI_DROPSHADOW, colorWhite );
y += iPropHeight;
UI_DrawProportionalString( 320, y, va( "%s", (char *)CG_GetStringEdString("MP_INGAME", "RULES_POWERDUEL_3")),
UI_CENTER|UI_INFOFONT|UI_DROPSHADOW, colorWhite );
y += iPropHeight;
break;
case GT_TEAM:
UI_DrawProportionalString( 320, y, va( "%s", (char *)CG_GetStringEdString("MP_INGAME", "RULES_TEAM_1")),
UI_CENTER|UI_INFOFONT|UI_DROPSHADOW, colorWhite );
y += iPropHeight;
UI_DrawProportionalString( 320, y, va( "%s", (char *)CG_GetStringEdString("MP_INGAME", "RULES_TEAM_2")),
UI_CENTER|UI_INFOFONT|UI_DROPSHADOW, colorWhite );
y += iPropHeight;
break;
case GT_SIEGE:
break;
case GT_CTF:
UI_DrawProportionalString( 320, y, va( "%s", (char *)CG_GetStringEdString("MP_INGAME", "RULES_CTF_1")),
UI_CENTER|UI_INFOFONT|UI_DROPSHADOW, colorWhite );
y += iPropHeight;
UI_DrawProportionalString( 320, y, va( "%s", (char *)CG_GetStringEdString("MP_INGAME", "RULES_CTF_2")),
UI_CENTER|UI_INFOFONT|UI_DROPSHADOW, colorWhite );
y += iPropHeight;
UI_DrawProportionalString( 320, y, va( "%s", (char *)CG_GetStringEdString("MP_INGAME", "RULES_CTF_3")),
UI_CENTER|UI_INFOFONT|UI_DROPSHADOW, colorWhite );
y += iPropHeight;
break;
default:
break;
}
}
/*
===================
CG_LoadBar
===================
*/
void CG_LoadBar(void)
{
trap_R_SetColor( colorTable[CT_WHITE] );
int glowHeight = (cg->loadLCARSStage / 9.0f) * 147;
int glowTop = (280 + 147) - glowHeight;
// Draw glow:
CG_DrawPic(280, glowTop, 73, glowHeight, cgs.media.loadTick);
// Draw saber:
CG_DrawPic(280, 265, 73, 147, cgs.media.levelLoad);
/*
const int numticks = 9, tickwidth = 40, tickheight = 8;
const int tickpadx = 20, tickpady = 12;
const int capwidth = 8;
const int barwidth = numticks*tickwidth+tickpadx*2+capwidth*2, barleft = ((640-barwidth)/2);
const int barheight = tickheight + tickpady*2, bartop = 480-barheight;
const int capleft = barleft+tickpadx, tickleft = capleft+capwidth, ticktop = bartop+tickpady;
trap_R_SetColor( colorWhite );
// Draw background
CG_DrawPic(barleft, bartop, barwidth, barheight, cgs.media.loadBarLEDSurround);
// Draw left cap (backwards)
CG_DrawPic(tickleft, ticktop, -capwidth, tickheight, cgs.media.loadBarLEDCap);
// Draw bar
CG_DrawPic(tickleft, ticktop, tickwidth*cg->loadLCARSStage, tickheight, cgs.media.loadBarLED);
// Draw right cap
CG_DrawPic(tickleft+tickwidth*cg->loadLCARSStage, ticktop, capwidth, tickheight, cgs.media.loadBarLEDCap);
*/
}

85
codemp/cgame/cg_light.c Normal file
View File

@@ -0,0 +1,85 @@
#include "cg_local.h"
#if !defined(CG_LIGHTS_H_INC)
#include "cg_lights.h"
#endif
static clightstyle_t cl_lightstyle[MAX_LIGHT_STYLES];
static int lastofs;
/*
================
FX_ClearLightStyles
================
*/
void CG_ClearLightStyles (void)
{
int i;
memset (cl_lightstyle, 0, sizeof(cl_lightstyle));
lastofs = -1;
for(i=0;i<MAX_LIGHT_STYLES*3;i++)
{
CG_SetLightstyle (i);
}
}
/*
================
FX_RunLightStyles
================
*/
void CG_RunLightStyles (void)
{
int ofs;
int i;
clightstyle_t *ls;
ofs = cg->time / 50;
// if (ofs == lastofs)
// return;
lastofs = ofs;
for (i=0,ls=cl_lightstyle ; i<MAX_LIGHT_STYLES ; i++, ls++)
{
if (!ls->length)
{
ls->value[0] = ls->value[1] = ls->value[2] = ls->value[3] = 255;
}
else if (ls->length == 1)
{
ls->value[0] = ls->map[0][0];
ls->value[1] = ls->map[0][1];
ls->value[2] = ls->map[0][2];
ls->value[3] = 255; //ls->map[0][3];
}
else
{
ls->value[0] = ls->map[ofs%ls->length][0];
ls->value[1] = ls->map[ofs%ls->length][1];
ls->value[2] = ls->map[ofs%ls->length][2];
ls->value[3] = 255; //ls->map[ofs%ls->length][3];
}
trap_R_SetLightStyle(i, *(int*)ls->value);
}
}
void CG_SetLightstyle (int i)
{
const char *s;
int j, k;
s = CG_ConfigString( i+CS_LIGHT_STYLES );
j = strlen (s);
if (j >= MAX_QPATH)
{
Com_Error (ERR_DROP, "svc_lightstyle length=%i", j);
}
cl_lightstyle[(i/3)].length = j;
for (k=0 ; k<j ; k++)
{
cl_lightstyle[(i/3)].map[k][(i%3)] = (float)(s[k]-'a')/(float)('z'-'a') * 255.0;
}
}

16
codemp/cgame/cg_lights.h Normal file
View File

@@ -0,0 +1,16 @@
#pragma once
#if !defined(CG_LIGHTS_H_INC)
#define CG_LIGHTS_H_INC
typedef struct
{
int length;
color4ub_t value;
color4ub_t map[MAX_QPATH];
} clightstyle_t;
void CG_ClearLightStyles (void);
void CG_RunLightStyles (void);
void CG_SetLightstyle (int i);
#endif // CG_LIGHTS_H_INC

2631
codemp/cgame/cg_local.h Normal file

File diff suppressed because it is too large Load Diff

869
codemp/cgame/cg_localents.c Normal file
View File

@@ -0,0 +1,869 @@
// Copyright (C) 1999-2000 Id Software, Inc.
//
// cg_localents.c -- every frame, generate renderer commands for locally
// processed entities, like smoke puffs, gibs, shells, etc.
#include "cg_local.h"
#define MAX_LOCAL_ENTITIES 512
localEntity_t cg_localEntities[MAX_LOCAL_ENTITIES];
localEntity_t cg_activeLocalEntities; // double linked list
localEntity_t *cg_freeLocalEntities; // single linked list
/*
===================
CG_InitLocalEntities
This is called at startup and for tournement restarts
===================
*/
void CG_InitLocalEntities( void ) {
int i;
memset( cg_localEntities, 0, sizeof( cg_localEntities ) );
cg_activeLocalEntities.next = &cg_activeLocalEntities;
cg_activeLocalEntities.prev = &cg_activeLocalEntities;
cg_freeLocalEntities = cg_localEntities;
for ( i = 0 ; i < MAX_LOCAL_ENTITIES - 1 ; i++ ) {
cg_localEntities[i].next = &cg_localEntities[i+1];
}
}
/*
==================
CG_FreeLocalEntity
==================
*/
void CG_FreeLocalEntity( localEntity_t *le ) {
if ( !le->prev ) {
CG_Error( "CG_FreeLocalEntity: not active" );
}
// remove from the doubly linked active list
le->prev->next = le->next;
le->next->prev = le->prev;
// the free list is only singly linked
le->next = cg_freeLocalEntities;
cg_freeLocalEntities = le;
}
/*
===================
CG_AllocLocalEntity
Will allways succeed, even if it requires freeing an old active entity
===================
*/
localEntity_t *CG_AllocLocalEntity( void ) {
localEntity_t *le;
if ( !cg_freeLocalEntities ) {
// no free entities, so free the one at the end of the chain
// remove the oldest active entity
CG_FreeLocalEntity( cg_activeLocalEntities.prev );
}
le = cg_freeLocalEntities;
cg_freeLocalEntities = cg_freeLocalEntities->next;
memset( le, 0, sizeof( *le ) );
// link into the active list
le->next = cg_activeLocalEntities.next;
le->prev = &cg_activeLocalEntities;
cg_activeLocalEntities.next->prev = le;
cg_activeLocalEntities.next = le;
return le;
}
/*
====================================================================================
FRAGMENT PROCESSING
A fragment localentity interacts with the environment in some way (hitting walls),
or generates more localentities along a trail.
====================================================================================
*/
/*
================
CG_BloodTrail
Leave expanding blood puffs behind gibs
================
*/
void CG_BloodTrail( localEntity_t *le ) {
int t;
int t2;
int step;
vec3_t newOrigin;
localEntity_t *blood;
step = 150;
t = step * ( (cg->time - cg->frametime + step ) / step );
t2 = step * ( cg->time / step );
for ( ; t <= t2; t += step ) {
BG_EvaluateTrajectory( &le->pos, t, newOrigin );
blood = CG_SmokePuff( newOrigin, vec3_origin,
20, // radius
1, 1, 1, 1, // color
2000, // trailTime
t, // startTime
0, // fadeInTime
0, // flags
/*cgs.media.bloodTrailShader*/0 );
// use the optimized version
blood->leType = LE_FALL_SCALE_FADE;
// drop a total of 40 units over its lifetime
blood->pos.trDelta[2] = 40;
}
}
/*
================
CG_FragmentBounceMark
================
*/
void CG_FragmentBounceMark( localEntity_t *le, trace_t *trace ) {
int radius;
if ( le->leMarkType == LEMT_BLOOD ) {
radius = 16 + (rand()&31);
// CG_ImpactMark( cgs.media.bloodMarkShader, trace->endpos, trace->plane.normal, random()*360,
// 1,1,1,1, qtrue, radius, qfalse );
} else if ( le->leMarkType == LEMT_BURN ) {
radius = 8 + (rand()&15);
// CG_ImpactMark( cgs.media.burnMarkShader, trace->endpos, trace->plane.normal, random()*360,
// 1,1,1,1, qtrue, radius, qfalse );
}
// don't allow a fragment to make multiple marks, or they
// pile up while settling
le->leMarkType = LEMT_NONE;
}
/*
================
CG_FragmentBounceSound
================
*/
void CG_FragmentBounceSound( localEntity_t *le, trace_t *trace ) {
// half the fragments will make a bounce sounds
if ( rand() & 1 )
{
sfxHandle_t s = 0;
switch( le->leBounceSoundType )
{
case LEBS_ROCK:
s = cgs.media.rockBounceSound[Q_irand(0,1)];
break;
case LEBS_METAL:
s = cgs.media.metalBounceSound[Q_irand(0,1)];// FIXME: make sure that this sound is registered properly...might still be rock bounce sound....
break;
default:
return;
}
if ( s )
{
trap_S_StartSound( trace->endpos, ENTITYNUM_WORLD, CHAN_AUTO, s );
}
// bouncers only make the sound once...
// FIXME: arbitrary...change if it bugs you
le->leBounceSoundType = LEBS_NONE;
}
else if ( rand() & 1 )
{
// we may end up bouncing again, but each bounce reduces the chance of playing the sound again or they may make a lot of noise when they settle
// FIXME: maybe just always do this??
le->leBounceSoundType = LEBS_NONE;
}
}
/*
================
CG_ReflectVelocity
================
*/
void CG_ReflectVelocity( localEntity_t *le, trace_t *trace ) {
vec3_t velocity;
float dot;
int hitTime;
// reflect the velocity on the trace plane
hitTime = cg->time - cg->frametime + cg->frametime * trace->fraction;
BG_EvaluateTrajectoryDelta( &le->pos, hitTime, velocity );
dot = DotProduct( velocity, trace->plane.normal );
VectorMA( velocity, -2*dot, trace->plane.normal, le->pos.trDelta );
VectorScale( le->pos.trDelta, le->bounceFactor, le->pos.trDelta );
VectorCopy( trace->endpos, le->pos.trBase );
le->pos.trTime = cg->time;
// check for stop, making sure that even on low FPS systems it doesn't bobble
if ( trace->allsolid ||
( trace->plane.normal[2] > 0 &&
( le->pos.trDelta[2] < 40 || le->pos.trDelta[2] < -cg->frametime * le->pos.trDelta[2] ) ) ) {
le->pos.trType = TR_STATIONARY;
} else {
}
}
/*
================
CG_AddFragment
================
*/
void CG_AddFragment( localEntity_t *le ) {
vec3_t newOrigin;
trace_t trace;
if (le->forceAlpha)
{
le->refEntity.renderfx |= RF_FORCE_ENT_ALPHA;
le->refEntity.shaderRGBA[3] = le->forceAlpha;
}
if ( le->pos.trType == TR_STATIONARY ) {
// sink into the ground if near the removal time
int t;
float t_e;
t = le->endTime - cg->time;
if ( t < (SINK_TIME*2) ) {
le->refEntity.renderfx |= RF_FORCE_ENT_ALPHA;
t_e = (float)((float)(le->endTime - cg->time)/(SINK_TIME*2));
t_e = (int)((t_e)*255);
if (t_e > 255)
{
t_e = 255;
}
if (t_e < 1)
{
t_e = 1;
}
if (le->refEntity.shaderRGBA[3] && t_e > le->refEntity.shaderRGBA[3])
{
t_e = le->refEntity.shaderRGBA[3];
}
le->refEntity.shaderRGBA[3] = t_e;
trap_R_AddRefEntityToScene( &le->refEntity );
} else {
trap_R_AddRefEntityToScene( &le->refEntity );
}
return;
}
// calculate new position
BG_EvaluateTrajectory( &le->pos, cg->time, newOrigin );
// trace a line from previous position to new position
CG_Trace( &trace, le->refEntity.origin, NULL, NULL, newOrigin, -1, CONTENTS_SOLID );
if ( trace.fraction == 1.0 ) {
// still in free fall
VectorCopy( newOrigin, le->refEntity.origin );
if ( le->leFlags & LEF_TUMBLE ) {
vec3_t angles;
BG_EvaluateTrajectory( &le->angles, cg->time, angles );
AnglesToAxis( angles, le->refEntity.axis );
ScaleModelAxis(&le->refEntity);
}
trap_R_AddRefEntityToScene( &le->refEntity );
// add a blood trail
if ( le->leBounceSoundType == LEBS_BLOOD ) {
CG_BloodTrail( le );
}
return;
}
// if it is in a nodrop zone, remove it
// this keeps gibs from waiting at the bottom of pits of death
// and floating levels
if ( trap_CM_PointContents( trace.endpos, 0 ) & CONTENTS_NODROP ) {
CG_FreeLocalEntity( le );
return;
}
if (!trace.startsolid)
{
// leave a mark
CG_FragmentBounceMark( le, &trace );
// do a bouncy sound
CG_FragmentBounceSound( le, &trace );
if (le->bounceSound)
{ //specified bounce sound (debris)
trap_S_StartSound(le->pos.trBase, ENTITYNUM_WORLD, CHAN_AUTO, le->bounceSound);
}
// reflect the velocity on the trace plane
CG_ReflectVelocity( le, &trace );
trap_R_AddRefEntityToScene( &le->refEntity );
}
}
/*
=====================================================================
TRIVIAL LOCAL ENTITIES
These only do simple scaling or modulation before passing to the renderer
=====================================================================
*/
/*
====================
CG_AddFadeRGB
====================
*/
void CG_AddFadeRGB( localEntity_t *le ) {
refEntity_t *re;
float c;
re = &le->refEntity;
c = ( le->endTime - cg->time ) * le->lifeRate;
c *= 0xff;
re->shaderRGBA[0] = le->color[0] * c;
re->shaderRGBA[1] = le->color[1] * c;
re->shaderRGBA[2] = le->color[2] * c;
re->shaderRGBA[3] = le->color[3] * c;
trap_R_AddRefEntityToScene( re );
}
static void CG_AddFadeScaleModel( localEntity_t *le )
{
refEntity_t *ent = &le->refEntity;
float frac = ( cg->time - le->startTime )/((float)( le->endTime - le->startTime ));
frac *= frac * frac; // yes, this is completely ridiculous...but it causes the shell to grow slowly then "explode" at the end
ent->nonNormalizedAxes = qtrue;
AxisCopy( axisDefault, ent->axis );
VectorScale( ent->axis[0], le->radius * frac, ent->axis[0] );
VectorScale( ent->axis[1], le->radius * frac, ent->axis[1] );
VectorScale( ent->axis[2], le->radius * 0.5f * frac, ent->axis[2] );
frac = 1.0f - frac;
ent->shaderRGBA[0] = le->color[0] * frac;
ent->shaderRGBA[1] = le->color[1] * frac;
ent->shaderRGBA[2] = le->color[2] * frac;
ent->shaderRGBA[3] = le->color[3] * frac;
// add the entity
trap_R_AddRefEntityToScene( ent );
}
/*
==================
CG_AddMoveScaleFade
==================
*/
static void CG_AddMoveScaleFade( localEntity_t *le ) {
refEntity_t *re;
float c;
vec3_t delta;
float len;
re = &le->refEntity;
if ( le->fadeInTime > le->startTime && cg->time < le->fadeInTime ) {
// fade / grow time
c = 1.0 - (float) ( le->fadeInTime - cg->time ) / ( le->fadeInTime - le->startTime );
}
else {
// fade / grow time
c = ( le->endTime - cg->time ) * le->lifeRate;
}
re->shaderRGBA[3] = 0xff * c * le->color[3];
if ( !( le->leFlags & LEF_PUFF_DONT_SCALE ) ) {
re->radius = le->radius * ( 1.0 - c ) + 8;
}
BG_EvaluateTrajectory( &le->pos, cg->time, re->origin );
// if the view would be "inside" the sprite, kill the sprite
// so it doesn't add too much overdraw
VectorSubtract( re->origin, cg->refdef.vieworg, delta );
len = VectorLength( delta );
if ( len < le->radius ) {
CG_FreeLocalEntity( le );
return;
}
trap_R_AddRefEntityToScene( re );
}
/*
==================
CG_AddPuff
==================
*/
static void CG_AddPuff( localEntity_t *le ) {
refEntity_t *re;
float c;
vec3_t delta;
float len;
re = &le->refEntity;
// fade / grow time
c = ( le->endTime - cg->time ) / (float)( le->endTime - le->startTime );
re->shaderRGBA[0] = le->color[0] * c;
re->shaderRGBA[1] = le->color[1] * c;
re->shaderRGBA[2] = le->color[2] * c;
if ( !( le->leFlags & LEF_PUFF_DONT_SCALE ) ) {
re->radius = le->radius * ( 1.0 - c ) + 8;
}
BG_EvaluateTrajectory( &le->pos, cg->time, re->origin );
// if the view would be "inside" the sprite, kill the sprite
// so it doesn't add too much overdraw
VectorSubtract( re->origin, cg->refdef.vieworg, delta );
len = VectorLength( delta );
if ( len < le->radius ) {
CG_FreeLocalEntity( le );
return;
}
trap_R_AddRefEntityToScene( re );
}
/*
===================
CG_AddScaleFade
For rocket smokes that hang in place, fade out, and are
removed if the view passes through them.
There are often many of these, so it needs to be simple.
===================
*/
static void CG_AddScaleFade( localEntity_t *le ) {
refEntity_t *re;
float c;
vec3_t delta;
float len;
re = &le->refEntity;
// fade / grow time
c = ( le->endTime - cg->time ) * le->lifeRate;
re->shaderRGBA[3] = 0xff * c * le->color[3];
re->radius = le->radius * ( 1.0 - c ) + 8;
// if the view would be "inside" the sprite, kill the sprite
// so it doesn't add too much overdraw
VectorSubtract( re->origin, cg->refdef.vieworg, delta );
len = VectorLength( delta );
if ( len < le->radius ) {
CG_FreeLocalEntity( le );
return;
}
trap_R_AddRefEntityToScene( re );
}
/*
=================
CG_AddFallScaleFade
This is just an optimized CG_AddMoveScaleFade
For blood mists that drift down, fade out, and are
removed if the view passes through them.
There are often 100+ of these, so it needs to be simple.
=================
*/
static void CG_AddFallScaleFade( localEntity_t *le ) {
refEntity_t *re;
float c;
vec3_t delta;
float len;
re = &le->refEntity;
// fade time
c = ( le->endTime - cg->time ) * le->lifeRate;
re->shaderRGBA[3] = 0xff * c * le->color[3];
re->origin[2] = le->pos.trBase[2] - ( 1.0 - c ) * le->pos.trDelta[2];
re->radius = le->radius * ( 1.0 - c ) + 16;
// if the view would be "inside" the sprite, kill the sprite
// so it doesn't add too much overdraw
VectorSubtract( re->origin, cg->refdef.vieworg, delta );
len = VectorLength( delta );
if ( len < le->radius ) {
CG_FreeLocalEntity( le );
return;
}
trap_R_AddRefEntityToScene( re );
}
/*
================
CG_AddExplosion
================
*/
static void CG_AddExplosion( localEntity_t *ex ) {
refEntity_t *ent;
ent = &ex->refEntity;
// add the entity
trap_R_AddRefEntityToScene(ent);
// add the dlight
if ( ex->light ) {
float light;
light = (float)( cg->time - ex->startTime ) / ( ex->endTime - ex->startTime );
if ( light < 0.5 ) {
light = 1.0;
} else {
light = 1.0 - ( light - 0.5 ) * 2;
}
light = ex->light * light;
trap_R_AddLightToScene(ent->origin, light, ex->lightColor[0], ex->lightColor[1], ex->lightColor[2] );
}
}
/*
================
CG_AddSpriteExplosion
================
*/
static void CG_AddSpriteExplosion( localEntity_t *le ) {
refEntity_t re;
float c;
re = le->refEntity;
c = ( le->endTime - cg->time ) / ( float ) ( le->endTime - le->startTime );
if ( c > 1 ) {
c = 1.0; // can happen during connection problems
}
re.shaderRGBA[0] = 0xff;
re.shaderRGBA[1] = 0xff;
re.shaderRGBA[2] = 0xff;
re.shaderRGBA[3] = 0xff * c * 0.33;
re.reType = RT_SPRITE;
re.radius = 42 * ( 1.0 - c ) + 30;
trap_R_AddRefEntityToScene( &re );
// add the dlight
if ( le->light ) {
float light;
light = (float)( cg->time - le->startTime ) / ( le->endTime - le->startTime );
if ( light < 0.5 ) {
light = 1.0;
} else {
light = 1.0 - ( light - 0.5 ) * 2;
}
light = le->light * light;
trap_R_AddLightToScene(re.origin, light, le->lightColor[0], le->lightColor[1], le->lightColor[2] );
}
}
/*
===================
CG_AddRefEntity
===================
*/
void CG_AddRefEntity( localEntity_t *le ) {
if (le->endTime < cg->time) {
CG_FreeLocalEntity( le );
return;
}
trap_R_AddRefEntityToScene( &le->refEntity );
}
/*
===================
CG_AddScorePlum
===================
*/
#define NUMBER_SIZE 8
void CG_AddScorePlum( localEntity_t *le ) {
refEntity_t *re;
vec3_t origin, delta, dir, vec, up = {0, 0, 1};
float c, len;
int i, score, digits[10], numdigits, negative;
re = &le->refEntity;
c = ( le->endTime - cg->time ) * le->lifeRate;
score = le->radius;
if (score < 0) {
re->shaderRGBA[0] = 0xff;
re->shaderRGBA[1] = 0x11;
re->shaderRGBA[2] = 0x11;
}
else {
re->shaderRGBA[0] = 0xff;
re->shaderRGBA[1] = 0xff;
re->shaderRGBA[2] = 0xff;
if (score >= 50) {
re->shaderRGBA[1] = 0;
} else if (score >= 20) {
re->shaderRGBA[0] = re->shaderRGBA[1] = 0;
} else if (score >= 10) {
re->shaderRGBA[2] = 0;
} else if (score >= 2) {
re->shaderRGBA[0] = re->shaderRGBA[2] = 0;
}
}
if (c < 0.25)
re->shaderRGBA[3] = 0xff * 4 * c;
else
re->shaderRGBA[3] = 0xff;
re->radius = NUMBER_SIZE / 2;
VectorCopy(le->pos.trBase, origin);
origin[2] += 110 - c * 100;
VectorSubtract(cg->refdef.vieworg, origin, dir);
CrossProduct(dir, up, vec);
VectorNormalize(vec);
VectorMA(origin, -10 + 20 * sin(c * 2 * M_PI), vec, origin);
// if the view would be "inside" the sprite, kill the sprite
// so it doesn't add too much overdraw
VectorSubtract( origin, cg->refdef.vieworg, delta );
len = VectorLength( delta );
if ( len < 20 ) {
CG_FreeLocalEntity( le );
return;
}
negative = qfalse;
if (score < 0) {
negative = qtrue;
score = -score;
}
for (numdigits = 0; !(numdigits && !score); numdigits++) {
digits[numdigits] = score % 10;
score = score / 10;
}
if (negative) {
digits[numdigits] = 10;
numdigits++;
}
for (i = 0; i < numdigits; i++) {
VectorMA(origin, (float) (((float) numdigits / 2) - i) * NUMBER_SIZE, vec, re->origin);
re->customShader = cgs.media.numberShaders[digits[numdigits-1-i]];
trap_R_AddRefEntityToScene( re );
}
}
/*
===================
CG_AddOLine
For forcefields/other rectangular things
===================
*/
void CG_AddOLine( localEntity_t *le )
{
refEntity_t *re;
float frac, alpha;
re = &le->refEntity;
frac = (cg->time - le->startTime) / ( float ) ( le->endTime - le->startTime );
if ( frac > 1 )
frac = 1.0; // can happen during connection problems
else if (frac < 0)
frac = 0.0;
// Use the liferate to set the scale over time.
re->data.line.width = le->data.line.width + (le->data.line.dwidth * frac);
if (re->data.line.width <= 0)
{
CG_FreeLocalEntity( le );
return;
}
// We will assume here that we want additive transparency effects.
alpha = le->alpha + (le->dalpha * frac);
re->shaderRGBA[0] = 0xff * alpha;
re->shaderRGBA[1] = 0xff * alpha;
re->shaderRGBA[2] = 0xff * alpha;
re->shaderRGBA[3] = 0xff * alpha; // Yes, we could apply c to this too, but fading the color is better for lines.
re->shaderTexCoord[0] = 1;
re->shaderTexCoord[1] = 1;
re->rotation = 90;
re->reType = RT_ORIENTEDLINE;
trap_R_AddRefEntityToScene( re );
}
/*
===================
CG_AddLine
for beams and the like.
===================
*/
void CG_AddLine( localEntity_t *le )
{
refEntity_t *re;
re = &le->refEntity;
re->reType = RT_LINE;
trap_R_AddRefEntityToScene( re );
}
//==============================================================================
/*
===================
CG_AddLocalEntities
===================
*/
void CG_AddLocalEntities( void ) {
localEntity_t *le, *next;
// walk the list backwards, so any new local entities generated
// (trails, marks, etc) will be present this frame
le = cg_activeLocalEntities.prev;
for ( ; le != &cg_activeLocalEntities ; le = next ) {
// grab next now, so if the local entity is freed we
// still have it
next = le->prev;
if ( cg->time >= le->endTime ) {
CG_FreeLocalEntity( le );
continue;
}
switch ( le->leType ) {
default:
CG_Error( "Bad leType: %i", le->leType );
break;
case LE_MARK:
break;
case LE_SPRITE_EXPLOSION:
CG_AddSpriteExplosion( le );
break;
case LE_EXPLOSION:
CG_AddExplosion( le );
break;
case LE_FADE_SCALE_MODEL:
CG_AddFadeScaleModel( le );
break;
case LE_FRAGMENT: // gibs and brass
CG_AddFragment( le );
break;
case LE_PUFF:
CG_AddPuff( le );
break;
case LE_MOVE_SCALE_FADE: // water bubbles
CG_AddMoveScaleFade( le );
break;
case LE_FADE_RGB: // teleporters, railtrails
CG_AddFadeRGB( le );
break;
case LE_FALL_SCALE_FADE: // gib blood trails
CG_AddFallScaleFade( le );
break;
case LE_SCALE_FADE: // rocket trails
CG_AddScaleFade( le );
break;
case LE_SCOREPLUM:
CG_AddScorePlum( le );
break;
case LE_OLINE:
CG_AddOLine( le );
break;
case LE_SHOWREFENTITY:
CG_AddRefEntity( le );
break;
case LE_LINE: // oriented lines for FX
CG_AddLine( le );
break;
}
}
}

4319
codemp/cgame/cg_main.c Normal file

File diff suppressed because it is too large Load Diff

2279
codemp/cgame/cg_marks.c Normal file

File diff suppressed because it is too large Load Diff

0
codemp/cgame/cg_media.h Normal file
View File

893
codemp/cgame/cg_newDraw.c Normal file
View File

@@ -0,0 +1,893 @@
#include "cg_local.h"
#include "../ui/ui_shared.h"
extern displayContextDef_t cgDC;
int CG_GetSelectedPlayer() {
if (cg_currentSelectedPlayer.integer < 0 || cg_currentSelectedPlayer.integer >= numSortedTeamPlayers) {
cg_currentSelectedPlayer.integer = 0;
}
return cg_currentSelectedPlayer.integer;
}
qhandle_t CG_StatusHandle(int task) {
qhandle_t h = cgs.media.assaultShader;
switch (task) {
case TEAMTASK_OFFENSE :
h = cgs.media.assaultShader;
break;
case TEAMTASK_DEFENSE :
h = cgs.media.defendShader;
break;
case TEAMTASK_PATROL :
h = cgs.media.patrolShader;
break;
case TEAMTASK_FOLLOW :
h = cgs.media.followShader;
break;
case TEAMTASK_CAMP :
h = cgs.media.campShader;
break;
case TEAMTASK_RETRIEVE :
h = cgs.media.retrieveShader;
break;
case TEAMTASK_ESCORT :
h = cgs.media.escortShader;
break;
default :
h = cgs.media.assaultShader;
break;
}
return h;
}
float CG_GetValue(int ownerDraw) {
centity_t *cent;
clientInfo_t *ci;
playerState_t *ps;
cent = &cg_entities[cg->snap->ps.clientNum];
ps = &cg->snap->ps;
switch (ownerDraw) {
case CG_SELECTEDPLAYER_ARMOR:
ci = cgs.clientinfo + sortedTeamPlayers[CG_GetSelectedPlayer()];
return ci->armor;
break;
case CG_SELECTEDPLAYER_HEALTH:
ci = cgs.clientinfo + sortedTeamPlayers[CG_GetSelectedPlayer()];
return ci->health;
break;
case CG_PLAYER_ARMOR_VALUE:
return ps->stats[STAT_ARMOR];
break;
case CG_PLAYER_AMMO_VALUE:
if ( cent->currentState.weapon )
{
return ps->ammo[weaponData[cent->currentState.weapon].ammoIndex];
}
break;
case CG_PLAYER_SCORE:
return cg->snap->ps.persistant[PERS_SCORE];
break;
case CG_PLAYER_HEALTH:
return ps->stats[STAT_HEALTH];
break;
case CG_RED_SCORE:
return cgs.scores1;
break;
case CG_BLUE_SCORE:
return cgs.scores2;
break;
case CG_PLAYER_FORCE_VALUE:
return ps->fd.forcePower;
break;
default:
break;
}
return -1;
}
qboolean CG_OtherTeamHasFlag(void) {
if (cgs.gametype == GT_CTF || cgs.gametype == GT_CTY) {
int team = cg->snap->ps.persistant[PERS_TEAM];
if (team == TEAM_RED && cgs.redflag == FLAG_TAKEN) {
return qtrue;
} else if (team == TEAM_BLUE && cgs.blueflag == FLAG_TAKEN) {
return qtrue;
} else {
return qfalse;
}
}
return qfalse;
}
qboolean CG_YourTeamHasFlag(void) {
if (cgs.gametype == GT_CTF || cgs.gametype == GT_CTY) {
int team = cg->snap->ps.persistant[PERS_TEAM];
if (team == TEAM_RED && cgs.blueflag == FLAG_TAKEN) {
return qtrue;
} else if (team == TEAM_BLUE && cgs.redflag == FLAG_TAKEN) {
return qtrue;
} else {
return qfalse;
}
}
return qfalse;
}
// THINKABOUTME: should these be exclusive or inclusive..
//
qboolean CG_OwnerDrawVisible(int flags) {
if (flags & CG_SHOW_TEAMINFO) {
return (cg_currentSelectedPlayer.integer == numSortedTeamPlayers);
}
if (flags & CG_SHOW_NOTEAMINFO) {
return !(cg_currentSelectedPlayer.integer == numSortedTeamPlayers);
}
if (flags & CG_SHOW_OTHERTEAMHASFLAG) {
return CG_OtherTeamHasFlag();
}
if (flags & CG_SHOW_YOURTEAMHASENEMYFLAG) {
return CG_YourTeamHasFlag();
}
if (flags & (CG_SHOW_BLUE_TEAM_HAS_REDFLAG | CG_SHOW_RED_TEAM_HAS_BLUEFLAG)) {
if (flags & CG_SHOW_BLUE_TEAM_HAS_REDFLAG && (cgs.redflag == FLAG_TAKEN || cgs.flagStatus == FLAG_TAKEN_RED)) {
return qtrue;
} else if (flags & CG_SHOW_RED_TEAM_HAS_BLUEFLAG && (cgs.blueflag == FLAG_TAKEN || cgs.flagStatus == FLAG_TAKEN_BLUE)) {
return qtrue;
}
return qfalse;
}
if (flags & CG_SHOW_ANYTEAMGAME) {
if( cgs.gametype >= GT_TEAM) {
return qtrue;
}
}
if (flags & CG_SHOW_ANYNONTEAMGAME) {
if( cgs.gametype < GT_TEAM) {
return qtrue;
}
}
if (flags & CG_SHOW_CTF) {
if( cgs.gametype == GT_CTF || cgs.gametype == GT_CTY ) {
return qtrue;
}
}
if (flags & CG_SHOW_HEALTHCRITICAL) {
if (cg->snap->ps.stats[STAT_HEALTH] < 25) {
return qtrue;
}
}
if (flags & CG_SHOW_HEALTHOK) {
if (cg->snap->ps.stats[STAT_HEALTH] >= 25) {
return qtrue;
}
}
if (flags & CG_SHOW_SINGLEPLAYER) {
if( cgs.gametype == GT_SINGLE_PLAYER ) {
return qtrue;
}
}
if (flags & CG_SHOW_TOURNAMENT) {
if( cgs.gametype == GT_DUEL || cgs.gametype == GT_POWERDUEL ) {
return qtrue;
}
}
if (flags & CG_SHOW_DURINGINCOMINGVOICE) {
}
if (flags & CG_SHOW_IF_PLAYER_HAS_FLAG) {
if (cg->snap->ps.powerups[PW_REDFLAG] || cg->snap->ps.powerups[PW_BLUEFLAG] || cg->snap->ps.powerups[PW_NEUTRALFLAG]) {
return qtrue;
}
}
return qfalse;
}
const char *CG_GetKillerText(void) {
static const char *s = "";
if ( cg->killerName[0] ) {
s = va("%s %s", CG_GetStringEdString("MP_INGAME", "KILLEDBY"), cg->killerName );
}
return s;
}
const char *CG_GetGameStatusText(void) {
static const char *s = "";
if (cgs.gametype == GT_POWERDUEL)
{
s = "";
}
else if ( cgs.gametype < GT_TEAM)
{
if (cg->snap->ps.persistant[PERS_TEAM] != TEAM_SPECTATOR )
{
char sPlaceWith[256];
trap_SP_GetStringTextString("MP_INGAME_PLACE_WITH", sPlaceWith, sizeof(sPlaceWith));
s = va("%s %s %i",CG_PlaceString( cg->snap->ps.persistant[PERS_RANK] + 1 ), sPlaceWith, cg->snap->ps.persistant[PERS_SCORE] );
}
}
else
{
if ( cg->teamScores[0] == cg->teamScores[1] ) {
s = va("%s %i", CG_GetStringEdString("MP_INGAME", "TIEDAT"), cg->teamScores[0] );
} else if ( cg->teamScores[0] >= cg->teamScores[1] ) {
s = va("%s, %i / %i", CG_GetStringEdString("MP_INGAME", "RED_LEADS"), cg->teamScores[0], cg->teamScores[1] );
} else {
s = va("%s, %i / %i", CG_GetStringEdString("MP_INGAME", "BLUE_LEADS"), cg->teamScores[1], cg->teamScores[0] );
}
}
return s;
}
const char *CG_GameTypeString(void) {
if ( cgs.gametype == GT_FFA ) {
return "Free For All";
} else if ( cgs.gametype == GT_HOLOCRON ) {
return "Holocron FFA";
} else if ( cgs.gametype == GT_JEDIMASTER ) {
return "Jedi Master";
} else if ( cgs.gametype == GT_TEAM ) {
return "Team FFA";
} else if ( cgs.gametype == GT_SIEGE ) {
return "Siege";
} else if ( cgs.gametype == GT_CTF ) {
return "Capture the Flag";
} else if ( cgs.gametype == GT_CTY ) {
return "Capture the Ysalamiri";
}
return "";
}
#include "../namespace_begin.h"
extern int MenuFontToHandle(int iMenuFont);
#include "../namespace_end.h"
// maxX param is initially an X limit, but is also used as feedback. 0 = text was clipped to fit within, else maxX = next pos
//
static void CG_Text_Paint_Limit(float *maxX, float x, float y, float scale, vec4_t color, const char* text, float adjust, int limit, int iMenuFont)
{
qboolean bIsTrailingPunctuation;
// this is kinda dirty, but...
//
int iFontIndex = MenuFontToHandle(iMenuFont);
//float fMax = *maxX;
int iPixelLen = trap_R_Font_StrLenPixels(text, iFontIndex, scale);
if (x + iPixelLen > *maxX)
{
// whole text won't fit, so we need to print just the amount that does...
// Ok, this is slow and tacky, but only called occasionally, and it works...
//
char sTemp[4096]={0}; // lazy assumption
const char *psText = text;
char *psOut = &sTemp[0];
char *psOutLastGood = psOut;
unsigned int uiLetter;
while (*psText && (x + trap_R_Font_StrLenPixels(sTemp, iFontIndex, scale)<=*maxX)
&& psOut < &sTemp[sizeof(sTemp)-1] // sanity
)
{
int iAdvanceCount;
psOutLastGood = psOut;
uiLetter = trap_AnyLanguage_ReadCharFromString(psText, &iAdvanceCount, &bIsTrailingPunctuation);
psText += iAdvanceCount;
if (uiLetter > 255)
{
*psOut++ = uiLetter>>8;
*psOut++ = uiLetter&0xFF;
}
else
{
*psOut++ = uiLetter&0xFF;
}
}
*psOutLastGood = '\0';
*maxX = 0; // feedback
CG_Text_Paint(x, y, scale, color, sTemp, adjust, limit, ITEM_TEXTSTYLE_NORMAL, iMenuFont);
}
else
{
// whole text fits fine, so print it all...
//
*maxX = x + iPixelLen; // feedback the next position, as the caller expects
CG_Text_Paint(x, y, scale, color, text, adjust, limit, ITEM_TEXTSTYLE_NORMAL, iMenuFont);
}
}
#define PIC_WIDTH 12
extern const char *CG_GetLocationString(const char *loc); //cg_main.c
void CG_DrawNewTeamInfo(rectDef_t *rect, float text_x, float text_y, float scale, vec4_t color, qhandle_t shader) {
int xx;
float y;
int i, j, len, count;
const char *p;
vec4_t hcolor;
float pwidth, lwidth, maxx, leftOver;
clientInfo_t *ci;
gitem_t *item;
qhandle_t h;
// max player name width
pwidth = 0;
count = (numSortedTeamPlayers > 8) ? 8 : numSortedTeamPlayers;
for (i = 0; i < count; i++) {
ci = cgs.clientinfo + sortedTeamPlayers[i];
if ( ci->infoValid && ci->team == cg->snap->ps.persistant[PERS_TEAM]) {
len = CG_Text_Width( ci->name, scale, 0);
if (len > pwidth)
pwidth = len;
}
}
// max location name width
lwidth = 0;
for (i = 1; i < MAX_LOCATIONS; i++) {
p = CG_GetLocationString(CG_ConfigString(CS_LOCATIONS+i));
if (p && *p) {
len = CG_Text_Width(p, scale, 0);
if (len > lwidth)
lwidth = len;
}
}
y = rect->y;
for (i = 0; i < count; i++) {
ci = cgs.clientinfo + sortedTeamPlayers[i];
if ( ci->infoValid && ci->team == cg->snap->ps.persistant[PERS_TEAM]) {
xx = rect->x + 1;
for (j = 0; j <= PW_NUM_POWERUPS; j++) {
if (ci->powerups & (1 << j)) {
item = BG_FindItemForPowerup( j );
if (item) {
CG_DrawPic( xx, y, PIC_WIDTH, PIC_WIDTH, trap_R_RegisterShader( item->icon ) );
xx += PIC_WIDTH;
}
}
}
// FIXME: max of 3 powerups shown properly
xx = rect->x + (PIC_WIDTH * 3) + 2;
CG_GetColorForHealth( ci->health, ci->armor, hcolor );
trap_R_SetColor(hcolor);
CG_DrawPic( xx, y + 1, PIC_WIDTH - 2, PIC_WIDTH - 2, cgs.media.heartShader );
//Com_sprintf (st, sizeof(st), "%3i %3i", ci->health, ci->armor);
//CG_Text_Paint(xx, y + text_y, scale, hcolor, st, 0, 0);
// draw weapon icon
xx += PIC_WIDTH + 1;
// weapon used is not that useful, use the space for task
#if 0
if ( cg_weapons[ci->curWeapon].weaponIcon ) {
CG_DrawPic( xx, y, PIC_WIDTH, PIC_WIDTH, cg_weapons[ci->curWeapon].weaponIcon );
} else {
CG_DrawPic( xx, y, PIC_WIDTH, PIC_WIDTH, cgs.media.deferShader );
}
#endif
trap_R_SetColor(NULL);
h = CG_StatusHandle(ci->teamTask);
if (h) {
CG_DrawPic( xx, y, PIC_WIDTH, PIC_WIDTH, h);
}
xx += PIC_WIDTH + 1;
leftOver = rect->w - xx;
maxx = xx + leftOver / 3;
CG_Text_Paint_Limit(&maxx, xx, y + text_y, scale, color, ci->name, 0, 0, FONT_MEDIUM);
p = CG_GetLocationString(CG_ConfigString(CS_LOCATIONS+ci->location));
if (!p || !*p) {
p = "unknown";
}
xx += leftOver / 3 + 2;
maxx = rect->w - 4;
CG_Text_Paint_Limit(&maxx, xx, y + text_y, scale, color, p, 0, 0, FONT_MEDIUM);
y += text_y + 2;
if ( y + text_y + 2 > rect->y + rect->h ) {
break;
}
}
}
}
void CG_DrawTeamSpectators(rectDef_t *rect, float scale, vec4_t color, qhandle_t shader) {
if (cg->spectatorLen) {
float maxX;
if (cg->spectatorWidth == -1) {
cg->spectatorWidth = 0;
cg->spectatorPaintX = rect->x + 1;
cg->spectatorPaintX2 = -1;
}
if (cg->spectatorOffset > cg->spectatorLen) {
cg->spectatorOffset = 0;
cg->spectatorPaintX = rect->x + 1;
cg->spectatorPaintX2 = -1;
}
if (cg->time > cg->spectatorTime) {
cg->spectatorTime = cg->time + 10;
if (cg->spectatorPaintX <= rect->x + 2) {
if (cg->spectatorOffset < cg->spectatorLen) {
cg->spectatorPaintX += CG_Text_Width(&cg->spectatorList[cg->spectatorOffset], scale, 1) - 1;
cg->spectatorOffset++;
} else {
cg->spectatorOffset = 0;
if (cg->spectatorPaintX2 >= 0) {
cg->spectatorPaintX = cg->spectatorPaintX2;
} else {
cg->spectatorPaintX = rect->x + rect->w - 2;
}
cg->spectatorPaintX2 = -1;
}
} else {
cg->spectatorPaintX--;
if (cg->spectatorPaintX2 >= 0) {
cg->spectatorPaintX2--;
}
}
}
maxX = rect->x + rect->w - 2;
CG_Text_Paint_Limit(&maxX, cg->spectatorPaintX, rect->y + rect->h - 3, scale, color, &cg->spectatorList[cg->spectatorOffset], 0, 0, FONT_MEDIUM);
if (cg->spectatorPaintX2 >= 0) {
float maxX2 = rect->x + rect->w - 2;
CG_Text_Paint_Limit(&maxX2, cg->spectatorPaintX2, rect->y + rect->h - 3, scale, color, cg->spectatorList, 0, cg->spectatorOffset, FONT_MEDIUM);
}
if (cg->spectatorOffset && maxX > 0) {
// if we have an offset ( we are skipping the first part of the string ) and we fit the string
if (cg->spectatorPaintX2 == -1) {
cg->spectatorPaintX2 = rect->x + rect->w - 2;
}
} else {
cg->spectatorPaintX2 = -1;
}
}
}
void CG_DrawMedal(int ownerDraw, rectDef_t *rect, float scale, vec4_t color, qhandle_t shader) {
score_t *score = &cg->scores[cg->selectedScore];
float value = 0;
char *text = NULL;
color[3] = 0.25;
switch (ownerDraw) {
case CG_ACCURACY:
value = score->accuracy;
break;
case CG_ASSISTS:
value = score->assistCount;
break;
case CG_DEFEND:
value = score->defendCount;
break;
case CG_EXCELLENT:
value = score->excellentCount;
break;
case CG_IMPRESSIVE:
value = score->impressiveCount;
break;
case CG_PERFECT:
value = score->perfect;
break;
case CG_GAUNTLET:
value = score->guantletCount;
break;
case CG_CAPTURES:
value = score->captures;
break;
}
if (value > 0) {
if (ownerDraw != CG_PERFECT) {
if (ownerDraw == CG_ACCURACY) {
text = va("%i%%", (int)value);
if (value > 50) {
color[3] = 1.0;
}
} else {
text = va("%i", (int)value);
color[3] = 1.0;
}
} else {
if (value) {
color[3] = 1.0;
}
text = "Wow";
}
}
trap_R_SetColor(color);
CG_DrawPic( rect->x, rect->y, rect->w, rect->h, shader );
if (text) {
color[3] = 1.0;
value = CG_Text_Width(text, scale, 0);
CG_Text_Paint(rect->x + (rect->w - value) / 2, rect->y + rect->h + 10 , scale, color, text, 0, 0, 0, FONT_MEDIUM);
}
trap_R_SetColor(NULL);
}
//
void CG_OwnerDraw(float x, float y, float w, float h, float text_x, float text_y, int ownerDraw, int ownerDrawFlags, int align, float special, float scale, vec4_t color, qhandle_t shader, int textStyle,int font) {
//Ignore all this, at least for now. May put some stat stuff back in menu files later.
#if 0
rectDef_t rect;
if ( cg_drawStatus.integer == 0 ) {
return;
}
//if (ownerDrawFlags != 0 && !CG_OwnerDrawVisible(ownerDrawFlags)) {
// return;
//}
rect.x = x;
rect.y = y;
rect.w = w;
rect.h = h;
switch (ownerDraw) {
case CG_PLAYER_ARMOR_ICON:
CG_DrawPlayerArmorIcon(&rect, ownerDrawFlags & CG_SHOW_2DONLY);
break;
case CG_PLAYER_ARMOR_ICON2D:
CG_DrawPlayerArmorIcon(&rect, qtrue);
break;
case CG_PLAYER_ARMOR_VALUE:
CG_DrawPlayerArmorValue(&rect, scale, color, shader, textStyle);
break;
case CG_PLAYER_FORCE_VALUE:
CG_DrawPlayerForceValue(&rect, scale, color, shader, textStyle);
return ;
case CG_PLAYER_AMMO_ICON:
CG_DrawPlayerAmmoIcon(&rect, ownerDrawFlags & CG_SHOW_2DONLY);
break;
case CG_PLAYER_AMMO_ICON2D:
CG_DrawPlayerAmmoIcon(&rect, qtrue);
break;
case CG_PLAYER_AMMO_VALUE:
CG_DrawPlayerAmmoValue(&rect, scale, color, shader, textStyle);
break;
case CG_SELECTEDPLAYER_HEAD:
CG_DrawSelectedPlayerHead(&rect, ownerDrawFlags & CG_SHOW_2DONLY, qfalse);
break;
case CG_VOICE_HEAD:
CG_DrawSelectedPlayerHead(&rect, ownerDrawFlags & CG_SHOW_2DONLY, qtrue);
break;
case CG_VOICE_NAME:
CG_DrawSelectedPlayerName(&rect, scale, color, qtrue, textStyle);
break;
case CG_SELECTEDPLAYER_STATUS:
CG_DrawSelectedPlayerStatus(&rect);
break;
case CG_SELECTEDPLAYER_ARMOR:
CG_DrawSelectedPlayerArmor(&rect, scale, color, shader, textStyle);
break;
case CG_SELECTEDPLAYER_HEALTH:
CG_DrawSelectedPlayerHealth(&rect, scale, color, shader, textStyle);
break;
case CG_SELECTEDPLAYER_NAME:
CG_DrawSelectedPlayerName(&rect, scale, color, qfalse, textStyle);
break;
case CG_SELECTEDPLAYER_LOCATION:
CG_DrawSelectedPlayerLocation(&rect, scale, color, textStyle);
break;
case CG_SELECTEDPLAYER_WEAPON:
CG_DrawSelectedPlayerWeapon(&rect);
break;
case CG_SELECTEDPLAYER_POWERUP:
CG_DrawSelectedPlayerPowerup(&rect, ownerDrawFlags & CG_SHOW_2DONLY);
break;
case CG_PLAYER_HEAD:
CG_DrawPlayerHead(&rect, ownerDrawFlags & CG_SHOW_2DONLY);
break;
case CG_PLAYER_ITEM:
CG_DrawPlayerItem(&rect, scale, ownerDrawFlags & CG_SHOW_2DONLY);
break;
case CG_PLAYER_SCORE:
CG_DrawPlayerScore(&rect, scale, color, shader, textStyle);
break;
case CG_PLAYER_HEALTH:
CG_DrawPlayerHealth(&rect, scale, color, shader, textStyle);
break;
case CG_RED_SCORE:
CG_DrawRedScore(&rect, scale, color, shader, textStyle);
break;
case CG_BLUE_SCORE:
CG_DrawBlueScore(&rect, scale, color, shader, textStyle);
break;
case CG_RED_NAME:
CG_DrawRedName(&rect, scale, color, textStyle);
break;
case CG_BLUE_NAME:
CG_DrawBlueName(&rect, scale, color, textStyle);
break;
case CG_BLUE_FLAGHEAD:
CG_DrawBlueFlagHead(&rect);
break;
case CG_BLUE_FLAGSTATUS:
CG_DrawBlueFlagStatus(&rect, shader);
break;
case CG_BLUE_FLAGNAME:
CG_DrawBlueFlagName(&rect, scale, color, textStyle);
break;
case CG_RED_FLAGHEAD:
CG_DrawRedFlagHead(&rect);
break;
case CG_RED_FLAGSTATUS:
CG_DrawRedFlagStatus(&rect, shader);
break;
case CG_RED_FLAGNAME:
CG_DrawRedFlagName(&rect, scale, color, textStyle);
break;
case CG_PLAYER_LOCATION:
CG_DrawPlayerLocation(&rect, scale, color, textStyle);
break;
case CG_TEAM_COLOR:
CG_DrawTeamColor(&rect, color);
break;
case CG_CTF_POWERUP:
CG_DrawCTFPowerUp(&rect);
break;
case CG_AREA_POWERUP:
CG_DrawAreaPowerUp(&rect, align, special, scale, color);
break;
case CG_PLAYER_STATUS:
CG_DrawPlayerStatus(&rect);
break;
case CG_PLAYER_HASFLAG:
CG_DrawPlayerHasFlag(&rect, qfalse);
break;
case CG_PLAYER_HASFLAG2D:
CG_DrawPlayerHasFlag(&rect, qtrue);
break;
case CG_AREA_SYSTEMCHAT:
CG_DrawAreaSystemChat(&rect, scale, color, shader);
break;
case CG_AREA_TEAMCHAT:
CG_DrawAreaTeamChat(&rect, scale, color, shader);
break;
case CG_AREA_CHAT:
CG_DrawAreaChat(&rect, scale, color, shader);
break;
case CG_GAME_TYPE:
CG_DrawGameType(&rect, scale, color, shader, textStyle);
break;
case CG_GAME_STATUS:
CG_DrawGameStatus(&rect, scale, color, shader, textStyle);
break;
case CG_KILLER:
CG_DrawKiller(&rect, scale, color, shader, textStyle);
break;
case CG_ACCURACY:
case CG_ASSISTS:
case CG_DEFEND:
case CG_EXCELLENT:
case CG_IMPRESSIVE:
case CG_PERFECT:
case CG_GAUNTLET:
case CG_CAPTURES:
CG_DrawMedal(ownerDraw, &rect, scale, color, shader);
break;
case CG_SPECTATORS:
CG_DrawTeamSpectators(&rect, scale, color, shader);
break;
case CG_TEAMINFO:
if (cg_currentSelectedPlayer.integer == numSortedTeamPlayers) {
CG_DrawNewTeamInfo(&rect, text_x, text_y, scale, color, shader);
}
break;
case CG_CAPFRAGLIMIT:
CG_DrawCapFragLimit(&rect, scale, color, shader, textStyle);
break;
case CG_1STPLACE:
CG_Draw1stPlace(&rect, scale, color, shader, textStyle);
break;
case CG_2NDPLACE:
CG_Draw2ndPlace(&rect, scale, color, shader, textStyle);
break;
default:
break;
}
#endif
}
void CG_MouseEvent(int x, int y) {
int n;
if ( (cg->predictedPlayerState.pm_type == PM_NORMAL || cg->predictedPlayerState.pm_type == PM_JETPACK || cg->predictedPlayerState.pm_type == PM_FLOAT || cg->predictedPlayerState.pm_type == PM_SPECTATOR) && cg->showScores == qfalse) {
trap_Key_SetCatcher(0);
return;
}
cgs.cursorX+= x;
if (cgs.cursorX < 0)
cgs.cursorX = 0;
else if (cgs.cursorX > 640)
cgs.cursorX = 640;
cgs.cursorY += y;
if (cgs.cursorY < 0)
cgs.cursorY = 0;
else if (cgs.cursorY > 480)
cgs.cursorY = 480;
n = Display_CursorType(cgs.cursorX, cgs.cursorY);
cgs.activeCursor = 0;
if (n == CURSOR_ARROW) {
cgs.activeCursor = cgs.media.selectCursor;
} else if (n == CURSOR_SIZER) {
cgs.activeCursor = cgs.media.sizeCursor;
}
if (cgs.capturedItem) {
Display_MouseMove(cgs.capturedItem, x, y);
} else {
Display_MouseMove(NULL, cgs.cursorX, cgs.cursorY);
}
}
/*
==================
CG_HideTeamMenus
==================
*/
void CG_HideTeamMenu() {
Menus_CloseByName("teamMenu");
Menus_CloseByName("getMenu");
}
/*
==================
CG_ShowTeamMenus
==================
*/
void CG_ShowTeamMenu() {
Menus_OpenByName("teamMenu");
}
/*
==================
CG_EventHandling
==================
type 0 - no event handling
1 - team menu
2 - hud editor
*/
void CG_EventHandling(int type) {
cgs.eventHandling = type;
if (type == CGAME_EVENT_NONE) {
CG_HideTeamMenu();
} else if (type == CGAME_EVENT_TEAMMENU) {
//CG_ShowTeamMenu();
} else if (type == CGAME_EVENT_SCOREBOARD) {
}
}
void CG_KeyEvent(int key, qboolean down) {
if (!down) {
return;
}
if ( cg->predictedPlayerState.pm_type == PM_NORMAL || cg->predictedPlayerState.pm_type == PM_JETPACK || cg->predictedPlayerState.pm_type == PM_NORMAL || (cg->predictedPlayerState.pm_type == PM_SPECTATOR && cg->showScores == qfalse)) {
CG_EventHandling(CGAME_EVENT_NONE);
trap_Key_SetCatcher(0);
return;
}
//if (key == trap_Key_GetKey("teamMenu") || !Display_CaptureItem(cgs.cursorX, cgs.cursorY)) {
// if we see this then we should always be visible
// CG_EventHandling(CGAME_EVENT_NONE);
// trap_Key_SetCatcher(0);
//}
Display_HandleKey(key, down, cgs.cursorX, cgs.cursorY);
if (cgs.capturedItem) {
cgs.capturedItem = NULL;
} else {
if (key == A_MOUSE2 && down) {
cgs.capturedItem = Display_CaptureItem(cgs.cursorX, cgs.cursorY);
}
}
}
int CG_ClientNumFromName(const char *p) {
int i;
for (i = 0; i < cgs.maxclients; i++) {
if (cgs.clientinfo[i].infoValid && Q_stricmp(cgs.clientinfo[i].name, p) == 0) {
return i;
}
}
return -1;
}
void CG_RunMenuScript(char **args) {
}
qboolean CG_DeferMenuScript (char **args)
{
return qfalse;
}
void CG_GetTeamColor(vec4_t *color) {
if (cg->snap->ps.persistant[PERS_TEAM] == TEAM_RED) {
(*color)[0] = 1.0f;
(*color)[3] = 0.25f;
(*color)[1] = (*color)[2] = 0.0f;
} else if (cg->snap->ps.persistant[PERS_TEAM] == TEAM_BLUE) {
(*color)[0] = (*color)[1] = 0.0f;
(*color)[2] = 1.0f;
(*color)[3] = 0.25f;
} else {
(*color)[0] = (*color)[2] = 0.0f;
(*color)[1] = 0.17f;
(*color)[3] = 0.25f;
}
}

View File

11435
codemp/cgame/cg_players.c Normal file

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,537 @@
// Copyright (C) 1999-2000 Id Software, Inc.
//
// cg_playerstate.c -- this file acts on changes in a new playerState_t
// With normal play, this will be done after local prediction, but when
// following another player or playing back a demo, it will be checked
// when the snapshot transitions like all the other entities
#include "cg_local.h"
/*
==============
CG_CheckAmmo
If the ammo has gone low enough to generate the warning, play a sound
==============
*/
void CG_CheckAmmo( void ) {
#if 0
int i;
int total;
int previous;
int weapons;
// see about how many seconds of ammo we have remaining
weapons = cg->snap->ps.stats[ STAT_WEAPONS ];
total = 0;
for ( i = WP_BRYAR_PISTOL; i < WP_NUM_WEAPONS ; i++ ) {
if ( ! ( weapons & ( 1 << i ) ) ) {
continue;
}
switch ( i )
{
case WP_BRYAR_PISTOL:
case WP_CONCUSSION:
case WP_BRYAR_OLD:
case WP_BLASTER:
case WP_DISRUPTOR:
case WP_BOWCASTER:
case WP_REPEATER:
case WP_DEMP2:
case WP_FLECHETTE:
case WP_ROCKET_LAUNCHER:
case WP_THERMAL:
case WP_TRIP_MINE:
case WP_DET_PACK:
case WP_EMPLACED_GUN:
total += cg->snap->ps.ammo[weaponData[i].ammoIndex] * 1000;
break;
default:
total += cg->snap->ps.ammo[weaponData[i].ammoIndex] * 200;
break;
}
if ( total >= 5000 ) {
cg->lowAmmoWarning = 0;
return;
}
}
previous = cg->lowAmmoWarning;
if ( total == 0 ) {
cg->lowAmmoWarning = 2;
} else {
cg->lowAmmoWarning = 1;
}
if (cg->snap->ps.weapon == WP_SABER)
{
cg->lowAmmoWarning = 0;
}
// play a sound on transitions
if ( cg->lowAmmoWarning != previous ) {
trap_S_StartLocalSound( cgs.media.noAmmoSound, CHAN_LOCAL_SOUND );
}
#endif
//disabled silly ammo warning stuff for now
}
/*
==============
CG_DamageFeedback
==============
*/
void CG_DamageFeedback( int yawByte, int pitchByte, int damage ) {
float left = 0.0f, front, up;
float kick;
int health;
float scale;
vec3_t dir;
vec3_t angles;
float dist;
float yaw, pitch;
// show the attacking player's head and name in corner
cg->attackerTime = cg->time;
// the lower on health you are, the greater the view kick will be
health = cg->snap->ps.stats[STAT_HEALTH];
if ( health < 40 ) {
scale = 1;
} else {
scale = 40.0 / health;
}
kick = damage * scale;
if (kick < 5)
kick = 5;
if (kick > 10)
kick = 10;
// if yaw and pitch are both 255, make the damage always centered (falling, etc)
if ( yawByte == 255 && pitchByte == 255 ) {
cg->damageX = 0;
cg->damageY = 0;
cg->v_dmg_roll = 0;
cg->v_dmg_pitch = -kick;
} else {
// positional
pitch = pitchByte / 255.0 * 360;
yaw = yawByte / 255.0 * 360;
angles[PITCH] = pitch;
angles[YAW] = yaw;
angles[ROLL] = 0;
AngleVectors( angles, dir, NULL, NULL );
VectorSubtract( vec3_origin, dir, dir );
front = DotProduct (dir, cg->refdef.viewaxis[0] );
left = DotProduct (dir, cg->refdef.viewaxis[1] );
up = DotProduct (dir, cg->refdef.viewaxis[2] );
dir[0] = front;
dir[1] = left;
dir[2] = 0;
dist = VectorLength( dir );
if ( dist < 0.1 ) {
dist = 0.1f;
}
cg->v_dmg_roll = kick * left;
cg->v_dmg_pitch = -kick * front;
if ( front <= 0.1 ) {
front = 0.1f;
}
cg->damageX = -left / front;
cg->damageY = up / dist;
}
// clamp the position
if ( cg->damageX > 1.0 ) {
cg->damageX = 1.0;
}
if ( cg->damageX < - 1.0 ) {
cg->damageX = -1.0;
}
if ( cg->damageY > 1.0 ) {
cg->damageY = 1.0;
}
if ( cg->damageY < - 1.0 ) {
cg->damageY = -1.0;
}
// don't let the screen flashes vary as much
if ( kick > 10 ) {
kick = 10;
}
cg->damageValue = kick;
cg->v_dmg_time = cg->time + DAMAGE_TIME;
cg->damageTime = cg->snap->serverTime;
//JLFRUMBLE
#ifdef _XBOX
extern void FF_XboxShake(float intensity, int duration);
extern void FF_XboxDamage(int damage, float xpos);
//FF_XboxShake(kick, 500);
FF_XboxDamage(damage, -left);
#endif
}
/*
================
CG_Respawn
A respawn happened this snapshot
================
*/
void CG_Respawn( void ) {
// no error decay on player movement
cg->thisFrameTeleport = qtrue;
// display weapons available
cg->weaponSelectTime = cg->time;
// select the weapon the server says we are using
cg->weaponSelect = cg->snap->ps.weapon;
}
extern char *eventnames[];
/*
==============
CG_CheckPlayerstateEvents
==============
*/
void CG_CheckPlayerstateEvents( playerState_t *ps, playerState_t *ops ) {
int i;
int event;
centity_t *cent;
if ( ps->externalEvent && ps->externalEvent != ops->externalEvent ) {
cent = &cg_entities[ ps->clientNum ];
cent->currentState.event = ps->externalEvent;
cent->currentState.eventParm = ps->externalEventParm;
CG_EntityEvent( cent, cent->lerpOrigin );
}
cent = &cg_entities[ ps->clientNum ];
// go through the predictable events buffer
for ( i = ps->eventSequence - MAX_PS_EVENTS ; i < ps->eventSequence ; i++ ) {
// if we have a new predictable event
if ( i >= ops->eventSequence
// or the server told us to play another event instead of a predicted event we already issued
// or something the server told us changed our prediction causing a different event
|| (i > ops->eventSequence - MAX_PS_EVENTS && ps->events[i & (MAX_PS_EVENTS-1)] != ops->events[i & (MAX_PS_EVENTS-1)]) ) {
event = ps->events[ i & (MAX_PS_EVENTS-1) ];
cent->currentState.event = event;
cent->currentState.eventParm = ps->eventParms[ i & (MAX_PS_EVENTS-1) ];
//JLF ADDED to hopefully mark events as player event
cent->playerState = ps;
CG_EntityEvent( cent, cent->lerpOrigin );
cg->predictableEvents[ i & (MAX_PREDICTED_EVENTS-1) ] = event;
cg->eventSequence++;
}
}
}
/*
==================
CG_CheckChangedPredictableEvents
==================
*/
void CG_CheckChangedPredictableEvents( playerState_t *ps ) {
int i;
int event;
centity_t *cent;
cent = &cg_entities[ps->clientNum];
for ( i = ps->eventSequence - MAX_PS_EVENTS ; i < ps->eventSequence ; i++ ) {
//
if (i >= cg->eventSequence) {
continue;
}
// if this event is not further back in than the maximum predictable events we remember
if (i > cg->eventSequence - MAX_PREDICTED_EVENTS) {
// if the new playerstate event is different from a previously predicted one
if ( ps->events[i & (MAX_PS_EVENTS-1)] != cg->predictableEvents[i & (MAX_PREDICTED_EVENTS-1) ] ) {
event = ps->events[ i & (MAX_PS_EVENTS-1) ];
cent->currentState.event = event;
cent->currentState.eventParm = ps->eventParms[ i & (MAX_PS_EVENTS-1) ];
CG_EntityEvent( cent, cent->lerpOrigin );
cg->predictableEvents[ i & (MAX_PREDICTED_EVENTS-1) ] = event;
if ( cg_showmiss.integer ) {
#ifndef FINAL_BUILD
CG_Printf("WARNING: changed predicted event\n");
#endif
}
}
}
}
}
/*
==================
pushReward
==================
*/
#ifdef JK2AWARDS
static void pushReward(sfxHandle_t sfx, qhandle_t shader, int rewardCount) {
if (cg->rewardStack < (MAX_REWARDSTACK-1)) {
cg->rewardStack++;
cg->rewardSound[cg->rewardStack] = sfx;
cg->rewardShader[cg->rewardStack] = shader;
cg->rewardCount[cg->rewardStack] = rewardCount;
}
}
#endif
int cgAnnouncerTime = 0; //to prevent announce sounds from playing on top of each other
/*
==================
CG_CheckLocalSounds
==================
*/
void CG_CheckLocalSounds( playerState_t *ps, playerState_t *ops ) {
int highScore, health, armor, reward;
#ifdef JK2AWARDS
sfxHandle_t sfx;
#endif
// don't play the sounds if the player just changed teams
if ( ps->persistant[PERS_TEAM] != ops->persistant[PERS_TEAM] ) {
return;
}
// hit changes
if ( ps->persistant[PERS_HITS] > ops->persistant[PERS_HITS] ) {
armor = ps->persistant[PERS_ATTACKEE_ARMOR] & 0xff;
health = ps->persistant[PERS_ATTACKEE_ARMOR] >> 8;
if (armor > health/2)
{ // We also hit shields along the way, so consider them "pierced".
// trap_S_StartLocalSound( cgs.media.shieldPierceSound, CHAN_LOCAL_SOUND );
}
else
{ // Shields didn't really stand in our way.
// trap_S_StartLocalSound( cgs.media.hitSound, CHAN_LOCAL_SOUND );
}
//FIXME: Hit sounds?
/*
if (armor > 50 ) {
trap_S_StartLocalSound( cgs.media.hitSoundHighArmor, CHAN_LOCAL_SOUND );
} else if (armor || health > 100) {
trap_S_StartLocalSound( cgs.media.hitSoundLowArmor, CHAN_LOCAL_SOUND );
} else {
trap_S_StartLocalSound( cgs.media.hitSound, CHAN_LOCAL_SOUND );
}
*/
} else if ( ps->persistant[PERS_HITS] < ops->persistant[PERS_HITS] ) {
//trap_S_StartLocalSound( cgs.media.hitTeamSound, CHAN_LOCAL_SOUND );
}
// health changes of more than -3 should make pain sounds
if (cg_oldPainSounds.integer)
{
if ( ps->stats[STAT_HEALTH] < (ops->stats[STAT_HEALTH] - 3))
{
if ( ps->stats[STAT_HEALTH] > 0 )
{
CG_PainEvent( &cg_entities[cg->predictedPlayerState.clientNum], ps->stats[STAT_HEALTH] );
}
}
}
// if we are going into the intermission, don't start any voices
if ( cg->intermissionStarted ) {
return;
}
#ifdef JK2AWARDS
// reward sounds
reward = qfalse;
if (ps->persistant[PERS_CAPTURES] != ops->persistant[PERS_CAPTURES]) {
pushReward(cgs.media.captureAwardSound, cgs.media.medalCapture, ps->persistant[PERS_CAPTURES]);
reward = qtrue;
//Com_Printf("capture\n");
}
if (ps->persistant[PERS_IMPRESSIVE_COUNT] != ops->persistant[PERS_IMPRESSIVE_COUNT]) {
sfx = cgs.media.impressiveSound;
pushReward(sfx, cgs.media.medalImpressive, ps->persistant[PERS_IMPRESSIVE_COUNT]);
reward = qtrue;
//Com_Printf("impressive\n");
}
if (ps->persistant[PERS_EXCELLENT_COUNT] != ops->persistant[PERS_EXCELLENT_COUNT]) {
sfx = cgs.media.excellentSound;
pushReward(sfx, cgs.media.medalExcellent, ps->persistant[PERS_EXCELLENT_COUNT]);
reward = qtrue;
//Com_Printf("excellent\n");
}
if (ps->persistant[PERS_GAUNTLET_FRAG_COUNT] != ops->persistant[PERS_GAUNTLET_FRAG_COUNT]) {
sfx = cgs.media.humiliationSound;
pushReward(sfx, cgs.media.medalGauntlet, ps->persistant[PERS_GAUNTLET_FRAG_COUNT]);
reward = qtrue;
//Com_Printf("guantlet frag\n");
}
if (ps->persistant[PERS_DEFEND_COUNT] != ops->persistant[PERS_DEFEND_COUNT]) {
pushReward(cgs.media.defendSound, cgs.media.medalDefend, ps->persistant[PERS_DEFEND_COUNT]);
reward = qtrue;
//Com_Printf("defend\n");
}
if (ps->persistant[PERS_ASSIST_COUNT] != ops->persistant[PERS_ASSIST_COUNT]) {
//pushReward(cgs.media.assistSound, cgs.media.medalAssist, ps->persistant[PERS_ASSIST_COUNT]);
//reward = qtrue;
//Com_Printf("assist\n");
}
// if any of the player event bits changed
if (ps->persistant[PERS_PLAYEREVENTS] != ops->persistant[PERS_PLAYEREVENTS]) {
if ((ps->persistant[PERS_PLAYEREVENTS] & PLAYEREVENT_DENIEDREWARD) !=
(ops->persistant[PERS_PLAYEREVENTS] & PLAYEREVENT_DENIEDREWARD)) {
trap_S_StartLocalSound( cgs.media.deniedSound, CHAN_ANNOUNCER );
}
else if ((ps->persistant[PERS_PLAYEREVENTS] & PLAYEREVENT_GAUNTLETREWARD) !=
(ops->persistant[PERS_PLAYEREVENTS] & PLAYEREVENT_GAUNTLETREWARD)) {
trap_S_StartLocalSound( cgs.media.humiliationSound, CHAN_ANNOUNCER );
}
reward = qtrue;
}
#else
reward = qfalse;
#endif
// lead changes
if (!reward && cgAnnouncerTime < cg->time) {
//
if ( !cg->warmup && cgs.gametype != GT_POWERDUEL ) {
// never play lead changes during warmup and powerduel
if ( ps->persistant[PERS_RANK] != ops->persistant[PERS_RANK] ) {
if ( cgs.gametype < GT_TEAM) {
/*
if ( ps->persistant[PERS_RANK] == 0 ) {
CG_AddBufferedSound(cgs.media.takenLeadSound);
cgAnnouncerTime = cg->time + 3000;
} else if ( ps->persistant[PERS_RANK] == RANK_TIED_FLAG ) {
//CG_AddBufferedSound(cgs.media.tiedLeadSound);
} else if ( ( ops->persistant[PERS_RANK] & ~RANK_TIED_FLAG ) == 0 ) {
//rww - only bother saying this if you have more than 1 kill already.
//joining the server and hearing "the force is not with you" is silly.
if (ps->persistant[PERS_SCORE] > 0)
{
CG_AddBufferedSound(cgs.media.lostLeadSound);
cgAnnouncerTime = cg->time + 3000;
}
}
*/
}
}
}
}
// timelimit warnings
if ( cgs.timelimit > 0 && cgAnnouncerTime < cg->time ) {
int msec;
msec = cg->time - cgs.levelStartTime;
if ( !( cg->timelimitWarnings & 4 ) && msec > ( cgs.timelimit * 60 + 2 ) * 1000 ) {
cg->timelimitWarnings |= 1 | 2 | 4;
//trap_S_StartLocalSound( cgs.media.suddenDeathSound, CHAN_ANNOUNCER );
}
else if ( !( cg->timelimitWarnings & 2 ) && msec > (cgs.timelimit - 1) * 60 * 1000 ) {
cg->timelimitWarnings |= 1 | 2;
trap_S_StartLocalSound( cgs.media.oneMinuteSound, CHAN_ANNOUNCER );
cgAnnouncerTime = cg->time + 3000;
}
else if ( cgs.timelimit > 5 && !( cg->timelimitWarnings & 1 ) && msec > (cgs.timelimit - 5) * 60 * 1000 ) {
cg->timelimitWarnings |= 1;
trap_S_StartLocalSound( cgs.media.fiveMinuteSound, CHAN_ANNOUNCER );
cgAnnouncerTime = cg->time + 3000;
}
}
// fraglimit warnings
if ( cgs.fraglimit > 0 && cgs.gametype < GT_CTF && cgs.gametype != GT_DUEL && cgs.gametype != GT_POWERDUEL && cgs.gametype != GT_SIEGE && cgAnnouncerTime < cg->time) {
highScore = cgs.scores1;
if ( !( cg->fraglimitWarnings & 4 ) && highScore == (cgs.fraglimit - 1) ) {
cg->fraglimitWarnings |= 1 | 2 | 4;
CG_AddBufferedSound(cgs.media.oneFragSound);
cgAnnouncerTime = cg->time + 3000;
}
else if ( cgs.fraglimit > 2 && !( cg->fraglimitWarnings & 2 ) && highScore == (cgs.fraglimit - 2) ) {
cg->fraglimitWarnings |= 1 | 2;
CG_AddBufferedSound(cgs.media.twoFragSound);
cgAnnouncerTime = cg->time + 3000;
}
else if ( cgs.fraglimit > 3 && !( cg->fraglimitWarnings & 1 ) && highScore == (cgs.fraglimit - 3) ) {
cg->fraglimitWarnings |= 1;
CG_AddBufferedSound(cgs.media.threeFragSound);
cgAnnouncerTime = cg->time + 3000;
}
}
}
/*
===============
CG_TransitionPlayerState
===============
*/
void CG_TransitionPlayerState( playerState_t *ps, playerState_t *ops ) {
// check for changing follow mode
if ( ps->clientNum != ops->clientNum ) {
cg->thisFrameTeleport = qtrue;
// make sure we don't get any unwanted transition effects
*ops = *ps;
}
// damage events (player is getting wounded)
if ( ps->damageEvent != ops->damageEvent && ps->damageCount ) {
CG_DamageFeedback( ps->damageYaw, ps->damagePitch, ps->damageCount );
}
// respawning
if ( ps->persistant[PERS_SPAWN_COUNT] != ops->persistant[PERS_SPAWN_COUNT] ) {
CG_Respawn();
}
if ( cg->mapRestart ) {
CG_Respawn();
cg->mapRestart = qfalse;
}
if ( cg->snap->ps.pm_type != PM_INTERMISSION
&& ps->persistant[PERS_TEAM] != TEAM_SPECTATOR ) {
CG_CheckLocalSounds( ps, ops );
}
// check for going low on ammo
CG_CheckAmmo();
// run events
CG_CheckPlayerstateEvents( ps, ops );
// smooth the ducking viewheight change
if ( ps->viewheight != ops->viewheight ) {
cg->duckChange = ps->viewheight - ops->viewheight;
cg->duckTime = cg->time;
}
}

1539
codemp/cgame/cg_predict.c Normal file

File diff suppressed because it is too large Load Diff

596
codemp/cgame/cg_public.h Normal file
View File

@@ -0,0 +1,596 @@
// Copyright (C) 1999-2000 Id Software, Inc.
//
#ifndef __CG_PUBLIC_H
#define __CG_PUBLIC_H
#define CMD_BACKUP 64
#define CMD_MASK (CMD_BACKUP - 1)
// allow a lot of command backups for very fast systems
// multiple commands may be combined into a single packet, so this
// needs to be larger than PACKET_BACKUP
#define MAX_ENTITIES_IN_SNAPSHOT 256
// snapshots are a view of the server at a given time
// Snapshots are generated at regular time intervals by the server,
// but they may not be sent if a client's rate level is exceeded, or
// they may be dropped by the network.
typedef struct {
int snapFlags; // SNAPFLAG_RATE_DELAYED, etc
int ping;
int serverTime; // server time the message is valid for (in msec)
byte areamask[MAX_MAP_AREA_BYTES]; // portalarea visibility bits
playerState_t ps; // complete information about the current player at this time
playerState_t vps; //vehicle I'm riding's playerstate (if applicable) -rww
int numEntities; // all of the entities that need to be presented
entityState_t entities[MAX_ENTITIES_IN_SNAPSHOT]; // at the time of this snapshot
int numServerCommands; // text based server commands to execute when this
int serverCommandSequence; // snapshot becomes current
} snapshot_t;
enum {
CGAME_EVENT_NONE,
CGAME_EVENT_TEAMMENU,
CGAME_EVENT_SCOREBOARD,
CGAME_EVENT_EDITHUD
};
/*
==================================================================
functions imported from the main executable
==================================================================
*/
#define CGAME_IMPORT_API_VERSION 5
typedef enum {
CG_PRINT = 0,
CG_ERROR,
CG_MILLISECONDS,
//Also for profiling.. do not use for game related tasks.
CG_PRECISIONTIMER_START,
CG_PRECISIONTIMER_END,
CG_PRINTALWAYS,
CG_CVAR_REGISTER,
CG_CVAR_UPDATE,
CG_CVAR_SET,
CG_CVAR_VARIABLESTRINGBUFFER,
CG_CVAR_GETHIDDENVALUE,
CG_ARGC,
CG_ARGV,
CG_ARGS,
CG_FS_FOPENFILE,
CG_FS_READ,
CG_FS_WRITE,
CG_FS_FCLOSEFILE,
CG_FS_GETFILELIST,
CG_SENDCONSOLECOMMAND,
CG_ADDCOMMAND,
CG_REMOVECOMMAND,
CG_SENDCLIENTCOMMAND,
CG_UPDATESCREEN,
CG_CM_LOADMAP,
CG_CM_NUMINLINEMODELS,
CG_CM_INLINEMODEL,
CG_CM_TEMPBOXMODEL,
CG_CM_TEMPCAPSULEMODEL,
CG_CM_POINTCONTENTS,
CG_CM_TRANSFORMEDPOINTCONTENTS,
CG_CM_BOXTRACE,
CG_CM_CAPSULETRACE,
CG_CM_TRANSFORMEDBOXTRACE,
CG_CM_TRANSFORMEDCAPSULETRACE,
CG_CM_MARKFRAGMENTS,
CG_S_GETVOICEVOLUME,
CG_S_MUTESOUND,
CG_S_STARTSOUND,
CG_S_STARTLOCALSOUND,
CG_S_CLEARLOOPINGSOUNDS,
CG_S_ADDLOOPINGSOUND,
CG_S_UPDATEENTITYPOSITION,
CG_S_ADDREALLOOPINGSOUND,
CG_S_STOPLOOPINGSOUND,
CG_S_RESPATIALIZE,
CG_S_SHUTUP,
CG_S_REGISTERSOUND,
CG_S_STARTBACKGROUNDTRACK,
//rww - AS trap implem
CG_S_UPDATEAMBIENTSET,
CG_AS_PARSESETS,
CG_AS_ADDPRECACHEENTRY,
CG_S_ADDLOCALSET,
CG_AS_GETBMODELSOUND,
CG_R_LOADWORLDMAP,
CG_R_REGISTERMODEL,
CG_R_REGISTERSKIN,
CG_R_REGISTERSHADER,
CG_R_REGISTERSHADERNOMIP,
CG_R_REGISTERFONT,
CG_R_FONT_STRLENPIXELS,
CG_R_FONT_STRLENCHARS,
CG_R_FONT_STRHEIGHTPIXELS,
CG_R_FONT_DRAWSTRING,
CG_LANGUAGE_ISASIAN,
CG_LANGUAGE_USESSPACES,
CG_ANYLANGUAGE_READCHARFROMSTRING,
CGAME_MEMSET = 100,
CGAME_MEMCPY,
CGAME_STRNCPY,
CGAME_SIN,
CGAME_COS,
CGAME_ATAN2,
CGAME_SQRT,
CGAME_MATRIXMULTIPLY,
CGAME_ANGLEVECTORS,
CGAME_PERPENDICULARVECTOR,
CGAME_FLOOR,
CGAME_CEIL,
CGAME_TESTPRINTINT,
CGAME_TESTPRINTFLOAT,
CGAME_ACOS,
CGAME_ASIN,
CG_R_CLEARSCENE = 200,
CG_R_CLEARDECALS,
CG_R_ADDREFENTITYTOSCENE,
CG_R_ADDPOLYTOSCENE,
CG_R_ADDPOLYSTOSCENE,
CG_R_ADDDECALTOSCENE,
CG_R_LIGHTFORPOINT,
CG_R_ADDLIGHTTOSCENE,
CG_R_ADDADDITIVELIGHTTOSCENE,
CG_R_RENDERSCENE,
CG_R_SETCOLOR,
CG_R_DRAWSTRETCHPIC,
CG_R_MODELBOUNDS,
CG_R_LERPTAG,
CG_R_DRAWROTATEPIC,
CG_R_DRAWROTATEPIC2,
CG_R_SETRANGEFOG, //linear fogging, with settable range -rww
CG_R_SETREFRACTIONPROP, //set some properties for the draw layer for my refractive effect (here primarily for mod authors) -rww
CG_R_REMAP_SHADER,
CG_R_GET_LIGHT_STYLE,
CG_R_SET_LIGHT_STYLE,
CG_R_GET_BMODEL_VERTS,
CG_R_GETDISTANCECULL,
CG_R_GETREALRES,
CG_R_AUTOMAPELEVADJ,
CG_R_INITWIREFRAMEAUTO,
CG_FX_ADDLINE,
CG_GETGLCONFIG,
CG_GETGAMESTATE,
CG_GETCURRENTSNAPSHOTNUMBER,
CG_GETSNAPSHOT,
CG_GETDEFAULTSTATE,
CG_GETSERVERCOMMAND,
CG_GETCURRENTCMDNUMBER,
CG_GETUSERCMD,
CG_SETUSERCMDVALUE,
CG_SETCLIENTFORCEANGLE,
CG_SETCLIENTTURNEXTENT,
CG_OPENUIMENU,
CG_TESTPRINTINT,
CG_TESTPRINTFLOAT,
CG_MEMORY_REMAINING,
CG_KEY_ISDOWN,
CG_KEY_GETCATCHER,
CG_KEY_SETCATCHER,
CG_KEY_GETKEY,
CG_PC_ADD_GLOBAL_DEFINE,
CG_PC_LOAD_SOURCE,
CG_PC_FREE_SOURCE,
CG_PC_READ_TOKEN,
CG_PC_SOURCE_FILE_AND_LINE,
CG_PC_LOAD_GLOBAL_DEFINES,
CG_PC_REMOVE_ALL_GLOBAL_DEFINES,
CG_S_STOPBACKGROUNDTRACK,
CG_REAL_TIME,
CG_SNAPVECTOR,
CG_CIN_PLAYCINEMATIC,
CG_CIN_STOPCINEMATIC,
CG_CIN_RUNCINEMATIC,
CG_CIN_DRAWCINEMATIC,
CG_CIN_SETEXTENTS,
CG_GET_ENTITY_TOKEN,
CG_R_INPVS,
CG_FX_REGISTER_EFFECT,
CG_FX_PLAY_EFFECT,
CG_FX_PLAY_ENTITY_EFFECT,
CG_FX_PLAY_EFFECT_ID,
CG_FX_PLAY_PORTAL_EFFECT_ID,
CG_FX_PLAY_ENTITY_EFFECT_ID,
CG_FX_PLAY_BOLTED_EFFECT_ID,
CG_FX_ADD_SCHEDULED_EFFECTS,
CG_FX_INIT_SYSTEM,
CG_FX_SET_REFDEF,
CG_FX_FREE_SYSTEM,
CG_FX_ADJUST_TIME,
CG_FX_DRAW_2D_EFFECTS,
CG_FX_RESET,
CG_FX_ADDPOLY,
CG_FX_ADDBEZIER,
CG_FX_ADDPRIMITIVE,
CG_FX_ADDSPRITE,
CG_FX_ADDELECTRICITY,
// CG_SP_PRINT,
CG_SP_GETSTRINGTEXTSTRING,
CG_ROFF_CLEAN,
CG_ROFF_UPDATE_ENTITIES,
CG_ROFF_CACHE,
CG_ROFF_PLAY,
CG_ROFF_PURGE_ENT,
//rww - dynamic vm memory allocation!
CG_TRUEMALLOC,
CG_TRUEFREE,
/*
Ghoul2 Insert Start
*/
CG_G2_GETMODELNAME,
CG_G2_LISTSURFACES,
CG_G2_LISTBONES,
CG_G2_SETMODELS,
CG_G2_HAVEWEGHOULMODELS,
CG_G2_GETBOLT,
CG_G2_GETBOLT_NOREC,
CG_G2_GETBOLT_NOREC_NOROT,
CG_G2_INITGHOUL2MODEL,
CG_G2_SETSKIN,
CG_G2_COLLISIONDETECT,
CG_G2_CLEANMODELS,
CG_G2_ANGLEOVERRIDE,
CG_G2_PLAYANIM,
CG_G2_GETBONEANIM,
CG_G2_GETBONEFRAME, //trimmed down version of GBA, so I don't have to pass all those unused args across the VM-exe border
CG_G2_GETGLANAME,
CG_G2_COPYGHOUL2INSTANCE,
CG_G2_COPYSPECIFICGHOUL2MODEL,
CG_G2_DUPLICATEGHOUL2INSTANCE,
CG_G2_HASGHOUL2MODELONINDEX,
CG_G2_REMOVEGHOUL2MODEL,
CG_G2_SKINLESSMODEL,
CG_G2_GETNUMGOREMARKS,
CG_G2_ADDSKINGORE,
CG_G2_CLEARSKINGORE,
CG_G2_SIZE,
CG_G2_ADDBOLT,
CG_G2_ATTACHENT,
CG_G2_SETBOLTON,
CG_G2_SETROOTSURFACE,
CG_G2_SETSURFACEONOFF,
CG_G2_SETNEWORIGIN,
CG_G2_DOESBONEEXIST,
CG_G2_GETSURFACERENDERSTATUS,
CG_G2_GETTIME,
CG_G2_SETTIME,
CG_G2_ABSURDSMOOTHING,
/*
//rww - RAGDOLL_BEGIN
*/
CG_G2_SETRAGDOLL,
CG_G2_ANIMATEG2MODELS,
/*
//rww - RAGDOLL_END
*/
//additional ragdoll options -rww
CG_G2_RAGPCJCONSTRAINT,
CG_G2_RAGPCJGRADIENTSPEED,
CG_G2_RAGEFFECTORGOAL,
CG_G2_GETRAGBONEPOS,
CG_G2_RAGEFFECTORKICK,
CG_G2_RAGFORCESOLVE,
//rww - ik move method, allows you to specify a bone and move it to a world point (within joint constraints)
//by using the majority of gil's existing bone angling stuff from the ragdoll code.
CG_G2_SETBONEIKSTATE,
CG_G2_IKMOVE,
CG_G2_REMOVEBONE,
CG_G2_ATTACHINSTANCETOENTNUM,
CG_G2_CLEARATTACHEDINSTANCE,
CG_G2_CLEANENTATTACHMENTS,
CG_G2_OVERRIDESERVER,
CG_G2_GETSURFACENAME,
CG_SET_SHARED_BUFFER,
CG_CM_REGISTER_TERRAIN,
CG_RMG_INIT,
CG_RE_INIT_RENDERER_TERRAIN,
CG_R_WEATHER_CONTENTS_OVERRIDE,
CG_R_WORLDEFFECTCOMMAND,
//Adding trap to get weather working
CG_WE_ADDWEATHERZONE
/*
Ghoul2 Insert End
*/
} cgameImport_t;
/*
==================================================================
functions exported to the main executable
==================================================================
*/
typedef enum {
CG_INIT,
// void CG_Init( int serverMessageNum, int serverCommandSequence, int clientNum )
// called when the level loads or when the renderer is restarted
// all media should be registered at this time
// cgame will display loading status by calling SCR_Update, which
// will call CG_DrawInformation during the loading process
// reliableCommandSequence will be 0 on fresh loads, but higher for
// demos, tourney restarts, or vid_restarts
CG_SHUTDOWN,
// void (*CG_Shutdown)( void );
// oportunity to flush and close any open files
CG_CONSOLE_COMMAND,
// qboolean (*CG_ConsoleCommand)( void );
// a console command has been issued locally that is not recognized by the
// main game system.
// use Cmd_Argc() / Cmd_Argv() to read the command, return qfalse if the
// command is not known to the game
CG_DRAW_ACTIVE_FRAME,
// void (*CG_DrawActiveFrame)( int serverTime, stereoFrame_t stereoView, qboolean demoPlayback );
// Generates and draws a game scene and status information at the given time.
// If demoPlayback is set, local movement prediction will not be enabled
CG_CROSSHAIR_PLAYER,
// int (*CG_CrosshairPlayer)( void );
CG_LAST_ATTACKER,
// int (*CG_LastAttacker)( void );
CG_KEY_EVENT,
// void (*CG_KeyEvent)( int key, qboolean down );
CG_MOUSE_EVENT,
// void (*CG_MouseEvent)( int dx, int dy );
CG_EVENT_HANDLING,
// void (*CG_EventHandling)(int type);
CG_POINT_CONTENTS,
// int CG_PointContents( const vec3_t point, int passEntityNum );
CG_GET_LERP_ORIGIN,
// void CG_LerpOrigin(int num, vec3_t result);
CG_GET_LERP_DATA,
CG_GET_GHOUL2,
CG_GET_MODEL_LIST,
CG_CALC_LERP_POSITIONS,
// void CG_CalcEntityLerpPositions(int num);
CG_TRACE,
CG_G2TRACE,
//void CG_Trace( trace_t *result, const vec3_t start, const vec3_t mins, const vec3_t maxs, const vec3_t end,
// int skipNumber, int mask );
CG_G2MARK,
CG_RAG_CALLBACK,
CG_INCOMING_CONSOLE_COMMAND,
CG_GET_USEABLE_FORCE,
CG_GET_ORIGIN, // int entnum, vec3_t origin
CG_GET_ANGLES, // int entnum, vec3_t angle
CG_GET_ORIGIN_TRAJECTORY, // int entnum
CG_GET_ANGLE_TRAJECTORY, // int entnum
CG_ROFF_NOTETRACK_CALLBACK, // int entnum, char *notetrack
CG_IMPACT_MARK,
//void CG_ImpactMark( qhandle_t markShader, const vec3_t origin, const vec3_t dir,
// float orientation, float red, float green, float blue, float alpha,
// qboolean alphaFade, float radius, qboolean temporary )
CG_MAP_CHANGE,
CG_AUTOMAP_INPUT,
CG_MISC_ENT, //rwwRMG - added
CG_GET_SORTED_FORCE_POWER,
} cgameExport_t;
typedef struct
{
float up;
float down;
float yaw;
float pitch;
qboolean goToDefaults;
} autoMapInput_t;
// CG_POINT_CONTENTS
typedef struct
{
vec3_t mPoint; // input
int mPassEntityNum; // input
} TCGPointContents;
// CG_GET_BOLT_POS
typedef struct
{
vec3_t mOrigin; // output
vec3_t mAngles; // output
vec3_t mScale; // output
int mEntityNum; // input
} TCGGetBoltData;
// CG_IMPACT_MARK
typedef struct
{
int mHandle;
vec3_t mPoint;
vec3_t mAngle;
float mRotation;
float mRed;
float mGreen;
float mBlue;
float mAlphaStart;
float mSizeStart;
} TCGImpactMark;
// CG_GET_LERP_ORIGIN
// CG_GET_LERP_ANGLES
// CG_GET_MODEL_SCALE
typedef struct
{
int mEntityNum; // input
vec3_t mPoint; // output
} TCGVectorData;
// CG_TRACE/CG_G2TRACE
typedef struct
{
trace_t mResult; // output
vec3_t mStart, mMins, mMaxs, mEnd; // input
int mSkipNumber, mMask; // input
} TCGTrace;
// CG_G2MARK
typedef struct
{
int shader;
float size;
vec3_t start, dir;
} TCGG2Mark;
// CG_INCOMING_CONSOLE_COMMAND
typedef struct
{
char conCommand[1024];
} TCGIncomingConsoleCommand;
// CG_FX_CAMERASHAKE
typedef struct
{
vec3_t mOrigin; // input
float mIntensity; // input
int mRadius; // input
int mTime; // input
} TCGCameraShake;
// CG_MISC_ENT
typedef struct
{
char mModel[MAX_QPATH]; // input
vec3_t mOrigin, mAngles, mScale; // input
} TCGMiscEnt;
typedef struct
{
refEntity_t ent; // output
void *ghoul2; // input
int modelIndex; // input
int boltIndex; // input
vec3_t origin; // input
vec3_t angles; // input
vec3_t modelScale; // input
} TCGPositionOnBolt;
//ragdoll callback structs -rww
#define RAG_CALLBACK_NONE 0
#define RAG_CALLBACK_DEBUGBOX 1
typedef struct
{
vec3_t mins;
vec3_t maxs;
int duration;
} ragCallbackDebugBox_t;
#define RAG_CALLBACK_DEBUGLINE 2
typedef struct
{
vec3_t start;
vec3_t end;
int time;
int color;
int radius;
} ragCallbackDebugLine_t;
#define RAG_CALLBACK_BONESNAP 3
typedef struct
{
char boneName[128]; //name of the bone in question
int entNum; //index of entity who owns the bone in question
} ragCallbackBoneSnap_t;
#define RAG_CALLBACK_BONEIMPACT 4
typedef struct
{
char boneName[128]; //name of the bone in question
int entNum; //index of entity who owns the bone in question
} ragCallbackBoneImpact_t;
#define RAG_CALLBACK_BONEINSOLID 5
typedef struct
{
vec3_t bonePos; //world coordinate position of the bone
int entNum; //index of entity who owns the bone in question
int solidCount; //higher the count, the longer we've been in solid (the worse off we are)
} ragCallbackBoneInSolid_t;
#define RAG_CALLBACK_TRACELINE 6
typedef struct
{
trace_t tr;
vec3_t start;
vec3_t end;
vec3_t mins;
vec3_t maxs;
int ignore;
int mask;
} ragCallbackTraceLine_t;
#define MAX_CG_SHARED_BUFFER_SIZE 2048
//----------------------------------------------
#endif // __CG_PUBLIC_H

1106
codemp/cgame/cg_saga.c Normal file

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,854 @@
// Copyright (C) 1999-2000 Id Software, Inc.
//
// cg_scoreboard -- draw the scoreboard on top of the game screen
#include "cg_local.h"
#include "../ui/ui_shared.h"
#include "../game/bg_saga.h"
#ifdef _XBOX
#include "../client/cl_data.h"
#endif
#define SCOREBOARD_X (0)
#define SB_HEADER 86
#define SB_TOP (SB_HEADER+32)
// Where the status bar starts, so we don't overwrite it
#define SB_STATUSBAR 420
#define SB_NORMAL_HEIGHT 25
#define SB_INTER_HEIGHT 15 // interleaved height
#define SB_MAXCLIENTS_NORMAL ((SB_STATUSBAR - SB_TOP) / SB_NORMAL_HEIGHT)
#define SB_MAXCLIENTS_INTER ((SB_STATUSBAR - SB_TOP) / SB_INTER_HEIGHT - 1)
// Used when interleaved
#define SB_LEFT_BOTICON_X (SCOREBOARD_X+0)
#define SB_LEFT_HEAD_X (SCOREBOARD_X+32)
#define SB_RIGHT_BOTICON_X (SCOREBOARD_X+64)
#define SB_RIGHT_HEAD_X (SCOREBOARD_X+96)
// Normal
#define SB_BOTICON_X (SCOREBOARD_X+32)
#define SB_HEAD_X (SCOREBOARD_X+64)
#define SB_SCORELINE_X 100
#define SB_SCORELINE_WIDTH (640 - SB_SCORELINE_X * 2)
#define SB_RATING_WIDTH 0 // (6 * BIGCHAR_WIDTH)
#define SB_NAME_X (SB_SCORELINE_X)
#define SB_SCORE_X (SB_SCORELINE_X + .55 * SB_SCORELINE_WIDTH)
//#define SB_PING_X (SB_SCORELINE_X + .70 * SB_SCORELINE_WIDTH)
#define SB_TIME_X (SB_SCORELINE_X + .85 * SB_SCORELINE_WIDTH)
//JLF
#define TITLE_SAFE_SHIFT 30
// The new and improved score board
//
// In cases where the number of clients is high, the score board heads are interleaved
// here's the layout
//
// 0 32 80 112 144 240 320 400 <-- pixel position
// bot head bot head score ping time name
//
// wins/losses are drawn on bot icon now
static qboolean localClient; // true if local client has been displayed
/*
=================
CG_DrawScoreboard
=================
*/
static void CG_DrawClientScore( int y, score_t *score, float *color, float fade, qboolean largeFormat )
{
//vec3_t headAngles;
clientInfo_t *ci;
int iconx, headx;
float scale;
if ( largeFormat )
{
scale = 1.0f;
}
else
{
scale = 0.75f;
}
if ( score->client < 0 || score->client >= cgs.maxclients ) {
Com_Printf( "Bad score->client: %i\n", score->client );
return;
}
ci = &cgs.clientinfo[score->client];
iconx = SB_BOTICON_X + (SB_RATING_WIDTH / 2)+/*JLF*/TITLE_SAFE_SHIFT;
headx = SB_HEAD_X + (SB_RATING_WIDTH / 2);
// draw the handicap or bot skill marker (unless player has flag)
if ( ci->powerups & ( 1 << PW_NEUTRALFLAG ) )
{
if( largeFormat )
{
CG_DrawFlagModel( iconx, y - ( 32 - BIGCHAR_HEIGHT ) / 2, 32, 32, TEAM_FREE, qfalse );
}
else
{
CG_DrawFlagModel( iconx, y, 16, 16, TEAM_FREE, qfalse );
}
}
else if ( ci->powerups & ( 1 << PW_REDFLAG ) )
{
if( largeFormat )
{
CG_DrawFlagModel( iconx*cgs.screenXScale, y*cgs.screenYScale, 32*cgs.screenXScale, 32*cgs.screenYScale, TEAM_RED, qfalse );
}
else
{
CG_DrawFlagModel( iconx*cgs.screenXScale, y*cgs.screenYScale, 32*cgs.screenXScale, 32*cgs.screenYScale, TEAM_RED, qfalse );
}
}
else if ( ci->powerups & ( 1 << PW_BLUEFLAG ) )
{
if( largeFormat )
{
CG_DrawFlagModel( iconx*cgs.screenXScale, y*cgs.screenYScale, 32*cgs.screenXScale, 32*cgs.screenYScale, TEAM_BLUE, qfalse );
}
else
{
CG_DrawFlagModel( iconx*cgs.screenXScale, y*cgs.screenYScale, 32*cgs.screenXScale, 32*cgs.screenYScale, TEAM_BLUE, qfalse );
}
}
else if (cgs.gametype == GT_POWERDUEL &&
(ci->duelTeam == DUELTEAM_LONE || ci->duelTeam == DUELTEAM_DOUBLE))
{
if (ci->duelTeam == DUELTEAM_LONE)
{
#ifdef _XBOX
if(cg->widescreen)
CG_DrawPic ( iconx + 40, y, 32, 32, trap_R_RegisterShaderNoMip ( "gfx/mp/pduel_icon_lone" ) );
else
#endif
CG_DrawPic ( iconx, y, 32, 32, trap_R_RegisterShaderNoMip ( "gfx/mp/pduel_icon_lone" ) );
}
else
{
#ifdef _XBOX
if(cg->widescreen)
CG_DrawPic ( iconx + 40, y, 32, 32, trap_R_RegisterShaderNoMip ( "gfx/mp/pduel_icon_double" ) );
else
#endif
CG_DrawPic ( iconx, y, 32, 32, trap_R_RegisterShaderNoMip ( "gfx/mp/pduel_icon_double" ) );
}
}
else if (cgs.gametype == GT_SIEGE)
{ //try to draw the shader for this class on the scoreboard
if (ci->siegeIndex != -1)
{
siegeClass_t *scl = &bgSiegeClasses[ci->siegeIndex];
if (scl->classShader)
{
#ifdef _XBOX
if(cg->widescreen)
CG_DrawPic (iconx + 40, y, largeFormat?24:12, largeFormat?24:12, scl->classShader);
else
#endif
CG_DrawPic (iconx, y, largeFormat?24:12, largeFormat?24:12, scl->classShader);
}
}
}
else
{
//rww - in duel, we now show wins/losses in place of "frags". This is because duel now defaults to 1 kill per round.
}
// highlight your position
if ( score->client == cg->snap->ps.clientNum )
{
float hcolor[4];
int rank;
localClient = qtrue;
if ( cg->snap->ps.persistant[PERS_TEAM] == TEAM_SPECTATOR
|| cgs.gametype >= GT_TEAM ) {
rank = -1;
} else {
rank = cg->snap->ps.persistant[PERS_RANK] & ~RANK_TIED_FLAG;
}
if ( rank == 0 ) {
hcolor[0] = 0;
hcolor[1] = 0;
hcolor[2] = 0.7f;
} else if ( rank == 1 ) {
hcolor[0] = 0.7f;
hcolor[1] = 0;
hcolor[2] = 0;
} else if ( rank == 2 ) {
hcolor[0] = 0.7f;
hcolor[1] = 0.7f;
hcolor[2] = 0;
} else {
hcolor[0] = 0.7f;
hcolor[1] = 0.7f;
hcolor[2] = 0.7f;
}
hcolor[3] = fade * 0.7;
#ifdef _XBOX
if(cg->widescreen)
CG_FillRect( SB_SCORELINE_X - 5 + 40, y + 2, 640 - SB_SCORELINE_X * 2 + 10, largeFormat?SB_NORMAL_HEIGHT:SB_INTER_HEIGHT, hcolor );
else
#endif
CG_FillRect( SB_SCORELINE_X - 5, y + 2, 640 - SB_SCORELINE_X * 2 + 10, largeFormat?SB_NORMAL_HEIGHT:SB_INTER_HEIGHT, hcolor );
}
#ifdef _XBOX
if(cg->widescreen)
CG_Text_Paint (SB_NAME_X + 40, y, 0.9f * scale, colorWhite, ci->name,0, 0, ITEM_TEXTSTYLE_OUTLINED, FONT_MEDIUM );
else
#endif
CG_Text_Paint (SB_NAME_X, y, 0.9f * scale, colorWhite, ci->name,0, 0, ITEM_TEXTSTYLE_OUTLINED, FONT_MEDIUM );
if ( score->ping != -1 )
{
if ( ci->team != TEAM_SPECTATOR || cgs.gametype == GT_DUEL || cgs.gametype == GT_POWERDUEL )
{
if (cgs.gametype == GT_DUEL || cgs.gametype == GT_POWERDUEL)
{
#ifdef _XBOX
if(cg->widescreen)
CG_Text_Paint (SB_SCORE_X + 40, y, 1.0f * scale, colorWhite, va("%i/%i", ci->wins, ci->losses),0, 0, ITEM_TEXTSTYLE_OUTLINED, FONT_SMALL );
else
#endif
CG_Text_Paint (SB_SCORE_X, y, 1.0f * scale, colorWhite, va("%i/%i", ci->wins, ci->losses),0, 0, ITEM_TEXTSTYLE_OUTLINED, FONT_SMALL );
}
else
{
#ifdef _XBOX
if(cg->widescreen)
CG_Text_Paint (SB_SCORE_X + 40, y, 1.0f * scale, colorWhite, va("%i", score->score),0, 0, ITEM_TEXTSTYLE_OUTLINED, FONT_SMALL );
else
#endif
CG_Text_Paint (SB_SCORE_X, y, 1.0f * scale, colorWhite, va("%i", score->score),0, 0, ITEM_TEXTSTYLE_OUTLINED, FONT_SMALL );
}
}
// CG_Text_Paint (SB_PING_X, y, 1.0f * scale, colorWhite, va("%i", score->ping),0, 0, ITEM_TEXTSTYLE_OUTLINED, FONT_SMALL );
#ifdef _XBOX
if(cg->widescreen)
CG_Text_Paint (SB_TIME_X + 40, y, 1.0f * scale, colorWhite, va("%i", score->time),0, 0, ITEM_TEXTSTYLE_OUTLINED, FONT_SMALL );
else
#endif
CG_Text_Paint (SB_TIME_X, y, 1.0f * scale, colorWhite, va("%i", score->time),0, 0, ITEM_TEXTSTYLE_OUTLINED, FONT_SMALL );
}
else
{
#ifdef _XBOX
if(cg->widescreen)
CG_Text_Paint (SB_SCORE_X + 40, y, 1.0f * scale, colorWhite, "-",0, 0, ITEM_TEXTSTYLE_OUTLINED, FONT_SMALL );
else
#endif
CG_Text_Paint (SB_SCORE_X, y, 1.0f * scale, colorWhite, "-",0, 0, ITEM_TEXTSTYLE_OUTLINED, FONT_SMALL );
// CG_Text_Paint (SB_PING_X, y, 1.0f * scale, colorWhite, "-",0, 0, ITEM_TEXTSTYLE_OUTLINED, FONT_SMALL );
#ifdef _XBOX
if(cg->widescreen)
CG_Text_Paint (SB_TIME_X + 40, y, 1.0f * scale, colorWhite, "-",0, 0, ITEM_TEXTSTYLE_OUTLINED, FONT_SMALL );
else
#endif
CG_Text_Paint (SB_TIME_X, y, 1.0f * scale, colorWhite, "-",0, 0, ITEM_TEXTSTYLE_OUTLINED, FONT_SMALL );
}
// add the "ready" marker for intermission exiting
if ( cg->snap->ps.stats[ STAT_CLIENTS_READY ] & ( 1 << score->client ) )
{
#ifdef _XBOX
if(cg->widescreen)
CG_Text_Paint (SB_NAME_X - 64 + 40, y + 2, 0.7f * scale, colorWhite, CG_GetStringEdString("MP_INGAME", "READY"),0, 0, ITEM_TEXTSTYLE_OUTLINED, FONT_MEDIUM );
else
#endif
CG_Text_Paint (SB_NAME_X - 64 + 15, y + 2, 0.7f * scale, colorWhite, CG_GetStringEdString("MP_INGAME", "READY"),0, 0, ITEM_TEXTSTYLE_OUTLINED, FONT_MEDIUM );
}
}
/*
=================
CG_TeamScoreboard
=================
*/
static int CG_TeamScoreboard( int y, team_t team, float fade, int maxClients, int lineHeight, qboolean countOnly )
{
int i;
score_t *score;
float color[4];
int count;
clientInfo_t *ci;
color[0] = color[1] = color[2] = 1.0;
color[3] = fade;
count = 0;
for ( i = 0 ; i < cg->numScores && count < maxClients ; i++ ) {
score = &cg->scores[i];
ci = &cgs.clientinfo[ score->client ];
if ( team != ci->team ) {
continue;
}
if ( !countOnly )
{
CG_DrawClientScore( y + lineHeight * count, score, color, fade, lineHeight == SB_NORMAL_HEIGHT );
}
count++;
}
return count;
}
int CG_GetClassCount(team_t team,int siegeClass )
{
int i = 0;
int count = 0;
clientInfo_t *ci;
siegeClass_t *scl;
for ( i = 0 ; i < cgs.maxclients ; i++ )
{
ci = &cgs.clientinfo[ i ];
if ((!ci->infoValid) || ( team != ci->team ))
{
continue;
}
scl = &bgSiegeClasses[ci->siegeIndex];
// Correct class?
if ( siegeClass != scl->classShader )
{
continue;
}
count++;
}
return count;
}
int CG_GetTeamNonScoreCount(team_t team)
{
int i = 0,count=0;
clientInfo_t *ci;
for ( i = 0 ; i < cgs.maxclients ; i++ )
{
ci = &cgs.clientinfo[ i ];
if ( (!ci->infoValid) || (team != ci->team && team != ci->siegeDesiredTeam) )
{
continue;
}
count++;
}
return count;
}
int CG_GetTeamCount(team_t team, int maxClients)
{
int i = 0;
int count = 0;
clientInfo_t *ci;
score_t *score;
for ( i = 0 ; i < cg->numScores && count < maxClients ; i++ )
{
score = &cg->scores[i];
ci = &cgs.clientinfo[ score->client ];
if ( team != ci->team )
{
continue;
}
count++;
}
return count;
}
/*
=================
CG_DrawScoreboard
Draw the normal in-game scoreboard
=================
*/
int cg_siegeWinTeam = 0;
qboolean CG_DrawOldScoreboard( void ) {
int x, y, w, i, n1, n2;
float fade;
float *fadeColor;
char *s;
int maxClients;
int lineHeight;
int topBorderSize, bottomBorderSize;
// don't draw amuthing if the menu or console is up
if ( cg_paused.integer ) {
cg->deferredPlayerLoading = 0;
return qfalse;
}
// don't draw scoreboard during death while warmup up
if ( cg->warmup && !cg->showScores ) {
return qfalse;
}
if ( cg->showScores || cg->predictedPlayerState.pm_type == PM_DEAD ||
cg->predictedPlayerState.pm_type == PM_INTERMISSION ) {
fade = 1.0;
fadeColor = colorWhite;
} else {
fadeColor = CG_FadeColor( cg->scoreFadeTime, FADE_TIME );
if ( !fadeColor ) {
// next time scoreboard comes up, don't print killer
cg->deferredPlayerLoading = 0;
cg->killerName[0] = 0;
return qfalse;
}
fade = *fadeColor;
}
// fragged by ... line
// or if in intermission and duel, prints the winner of the duel round
if ((cgs.gametype == GT_DUEL || cgs.gametype == GT_POWERDUEL) && cgs.duelWinner != -1 &&
cg->predictedPlayerState.pm_type == PM_INTERMISSION)
{
s = va("%s^7 %s", cgs.clientinfo[cgs.duelWinner].name, CG_GetStringEdString("MP_INGAME", "DUEL_WINS") );
/*w = CG_DrawStrlen( s ) * BIGCHAR_WIDTH;
x = ( SCREEN_WIDTH - w ) / 2;
y = 40;
CG_DrawBigString( x, y, s, fade );
*/
x = ( SCREEN_WIDTH ) / 2;
if(ClientManager::splitScreenMode == qtrue) {
y = 20;
if(ClientManager::ActiveClientNum() == 1)
y = 240;
}
else
y = 40;
if(cg->widescreen)
CG_Text_Paint ( x - CG_Text_Width ( s, 1.0f, FONT_MEDIUM ) / 2 + 40, y, 1.0f, colorWhite, s, 0, 0, ITEM_TEXTSTYLE_OUTLINED, FONT_MEDIUM );
else
CG_Text_Paint ( x - CG_Text_Width ( s, 1.0f, FONT_MEDIUM ) / 2, y, 1.0f, colorWhite, s, 0, 0, ITEM_TEXTSTYLE_OUTLINED, FONT_MEDIUM );
}
else if ((cgs.gametype == GT_DUEL || cgs.gametype == GT_POWERDUEL) && cgs.duelist1 != -1 && cgs.duelist2 != -1 &&
cg->predictedPlayerState.pm_type == PM_INTERMISSION)
{
if (cgs.gametype == GT_POWERDUEL && cgs.duelist3 != -1)
{
s = va("%s^7 %s %s^7 %s %s", cgs.clientinfo[cgs.duelist1].name, CG_GetStringEdString("MP_INGAME", "SPECHUD_VERSUS"), cgs.clientinfo[cgs.duelist2].name, CG_GetStringEdString("MP_INGAME", "AND"), cgs.clientinfo[cgs.duelist3].name );
}
else
{
s = va("%s^7 %s %s", cgs.clientinfo[cgs.duelist1].name, CG_GetStringEdString("MP_INGAME", "SPECHUD_VERSUS"), cgs.clientinfo[cgs.duelist2].name );
}
/*w = CG_DrawStrlen( s ) * BIGCHAR_WIDTH;
x = ( SCREEN_WIDTH - w ) / 2;
y = 40;
CG_DrawBigString( x, y, s, fade );
*/
x = ( SCREEN_WIDTH ) / 2;
if(ClientManager::splitScreenMode == qtrue) {
y = 20;
if(ClientManager::ActiveClientNum() == 1)
y = 240;
}
else
y = 40;
if(cg->widescreen)
CG_Text_Paint ( x - CG_Text_Width ( s, 1.0f, FONT_MEDIUM ) / 2 + 40, y, 1.0f, colorWhite, s, 0, 0, ITEM_TEXTSTYLE_OUTLINED, FONT_MEDIUM );
else
CG_Text_Paint ( x - CG_Text_Width ( s, 1.0f, FONT_MEDIUM ) / 2, y, 1.0f, colorWhite, s, 0, 0, ITEM_TEXTSTYLE_OUTLINED, FONT_MEDIUM );
}
else if ( cg->killerName[0] ) {
s = " "; //va("%s %s", CG_GetStringEdString("MP_INGAME", "KILLEDBY"), cg->killerName );
/*w = CG_DrawStrlen( s ) * BIGCHAR_WIDTH;
x = ( SCREEN_WIDTH - w ) / 2;
y = 40;
CG_DrawBigString( x, y, s, fade );
*/
x = ( SCREEN_WIDTH ) / 2;
if(ClientManager::splitScreenMode == qtrue) {
y = 20;
if(ClientManager::ActiveClientNum() == 1)
y = 240;
// If not displaying the scoreboard in splitscreen, move the text down
// so that it doesn't interfere with console messages
if(!cg->showScores)
y += 80;
}
else
y = 40;
if(cg->widescreen)
CG_Text_Paint ( x - CG_Text_Width ( s, 1.0f, FONT_MEDIUM ) / 2 + 40, y, 1.0f, colorWhite, s, 0, 0, ITEM_TEXTSTYLE_OUTLINED, FONT_MEDIUM );
else
CG_Text_Paint ( x - CG_Text_Width ( s, 1.0f, FONT_MEDIUM ) / 2, y, 1.0f, colorWhite, s, 0, 0, ITEM_TEXTSTYLE_OUTLINED, FONT_MEDIUM );
}
// current rank
if (cgs.gametype == GT_POWERDUEL)
{ //do nothing?
}
else if ( cgs.gametype < GT_TEAM) {
#ifdef _XBOX
// Don't want place ranking text in splitscreen Duel
if(ClientManager::NumClients() == 2 && cgs.gametype == GT_DUEL) {
}
else
#endif
if (cg->snap->ps.persistant[PERS_TEAM] != TEAM_SPECTATOR )
{
char sPlace[256];
char sOf[256];
char sWith[256];
trap_SP_GetStringTextString("MP_INGAME_PLACE", sPlace, sizeof(sPlace));
trap_SP_GetStringTextString("MP_INGAME_OF", sOf, sizeof(sOf));
trap_SP_GetStringTextString("MP_INGAME_WITH", sWith, sizeof(sWith));
s = va("%s %s (%s %i) %s %i",
CG_PlaceString( cg->snap->ps.persistant[PERS_RANK] + 1 ),
sPlace,
sOf,
cg->numScores,
sWith,
cg->snap->ps.persistant[PERS_SCORE] );
// w = CG_DrawStrlen( s ) * BIGCHAR_WIDTH;
x = ( SCREEN_WIDTH ) / 2;
if(ClientManager::splitScreenMode == qtrue) {
y = 40;
if(ClientManager::ActiveClientNum() == 1)
y = 260;
// If not displaying the scoreboard in splitscreen, move the text down
// so that it doesn't interfere with console messages
if(!cg->showScores)
y += 80;
}
else
y = 60;
if(cg->widescreen)
UI_DrawProportionalString(x + 40, y, s, UI_CENTER|UI_DROPSHADOW, colorTable[CT_WHITE]);
else
UI_DrawProportionalString(x, y, s, UI_CENTER|UI_DROPSHADOW, colorTable[CT_WHITE]);
}
}
else if (cgs.gametype != GT_SIEGE)
{
#ifdef _XBOX
if(ClientManager::splitScreenMode == qtrue && cg->showScores == qfalse) {
}
else {
#endif
if ( cg->teamScores[0] == cg->teamScores[1] ) {
s = va("%s %i", CG_GetStringEdString("MP_INGAME", "TIEDAT"), cg->teamScores[0] );
} else if ( cg->teamScores[0] >= cg->teamScores[1] ) {
s = va("%s, %i / %i", CG_GetStringEdString("MP_INGAME", "RED_LEADS"), cg->teamScores[0], cg->teamScores[1] );
} else {
s = va("%s, %i / %i", CG_GetStringEdString("MP_INGAME", "BLUE_LEADS"), cg->teamScores[1], cg->teamScores[0] );
}
x = ( SCREEN_WIDTH ) / 2;
if(ClientManager::splitScreenMode == qtrue) {
y = 40;
if(ClientManager::ActiveClientNum() == 1)
y = 260;
}
else
y = 60;
if(cg->widescreen)
CG_Text_Paint ( x - CG_Text_Width ( s, 1.0f, FONT_MEDIUM ) / 2 + 40, y, 1.0f, colorWhite, s, 0, 0, ITEM_TEXTSTYLE_OUTLINED, FONT_MEDIUM );
else
CG_Text_Paint ( x - CG_Text_Width ( s, 1.0f, FONT_MEDIUM ) / 2, y, 1.0f, colorWhite, s, 0, 0, ITEM_TEXTSTYLE_OUTLINED, FONT_MEDIUM );
#ifdef _XBOX
}
#endif
}
else if (cgs.gametype == GT_SIEGE && (cg_siegeWinTeam == 1 || cg_siegeWinTeam == 2))
{
if (cg_siegeWinTeam == 1)
{
s = va("%s", CG_GetStringEdString("MP_INGAME", "SIEGETEAM1WIN") );
}
else
{
s = va("%s", CG_GetStringEdString("MP_INGAME", "SIEGETEAM2WIN") );
}
x = ( SCREEN_WIDTH ) / 2;
if(ClientManager::splitScreenMode == qtrue) {
y = 40;
if(ClientManager::ActiveClientNum() == 1)
y = 260;
}
else
y = 60;
if(cg->widescreen)
CG_Text_Paint ( x - CG_Text_Width ( s, 1.0f, FONT_MEDIUM ) / 2 + 40, y, 1.0f, colorWhite, s, 0, 0, ITEM_TEXTSTYLE_OUTLINED, FONT_MEDIUM );
else
CG_Text_Paint ( x - CG_Text_Width ( s, 1.0f, FONT_MEDIUM ) / 2, y, 1.0f, colorWhite, s, 0, 0, ITEM_TEXTSTYLE_OUTLINED, FONT_MEDIUM );
}
#ifdef _XBOX
// In splitscreen mode, the scoreboard should only come up when requested (back button)
// or at the end of a round
if(ClientManager::splitScreenMode == qtrue && cg->showScores == qfalse &&
cg->predictedPlayerState.pm_type != PM_INTERMISSION)
return qfalse;
#endif
// scoreboard
if(ClientManager::splitScreenMode == qtrue) {
y = SB_HEADER - 20;
if(ClientManager::ActiveClientNum() == 1)
y = SB_HEADER - 20 + 220;
}
else
y = SB_HEADER;
if(cg->widescreen)
CG_DrawPic ( SB_SCORELINE_X - 40 + 40, y - 5, SB_SCORELINE_WIDTH + 80, 40, trap_R_RegisterShaderNoMip ( "gfx/menus/menu_buttonback.tga" ) );
else
CG_DrawPic ( SB_SCORELINE_X - 40, y - 5, SB_SCORELINE_WIDTH + 80, 40, trap_R_RegisterShaderNoMip ( "gfx/menus/menu_buttonback.tga" ) );
if(cg->widescreen)
CG_Text_Paint ( SB_NAME_X + 40, y, 1.0f, colorWhite, CG_GetStringEdString("MP_INGAME", "NAME"),0, 0, ITEM_TEXTSTYLE_OUTLINED, FONT_MEDIUM );
else
CG_Text_Paint ( SB_NAME_X, y, 1.0f, colorWhite, CG_GetStringEdString("MP_INGAME", "NAME"),0, 0, ITEM_TEXTSTYLE_OUTLINED, FONT_MEDIUM );
if (cgs.gametype == GT_DUEL || cgs.gametype == GT_POWERDUEL)
{
char sWL[100];
trap_SP_GetStringTextString("MP_INGAME_W_L", sWL, sizeof(sWL));
if(cg->widescreen)
CG_Text_Paint ( SB_SCORE_X + 40, y, 1.0f, colorWhite, sWL, 0, 0, ITEM_TEXTSTYLE_OUTLINED, FONT_MEDIUM );
else
CG_Text_Paint ( SB_SCORE_X, y, 1.0f, colorWhite, sWL, 0, 0, ITEM_TEXTSTYLE_OUTLINED, FONT_MEDIUM );
}
else
{
#ifdef _XBOX
if(cg->widescreen)
CG_Text_Paint ( SB_SCORE_X + 40, y, 1.0f, colorWhite, CG_GetStringEdString("MP_INGAME", "SCORE"), 0, 0, ITEM_TEXTSTYLE_OUTLINED, FONT_MEDIUM );
else
#endif
CG_Text_Paint ( SB_SCORE_X, y, 1.0f, colorWhite, CG_GetStringEdString("MP_INGAME", "SCORE"), 0, 0, ITEM_TEXTSTYLE_OUTLINED, FONT_MEDIUM );
}
// CG_Text_Paint ( SB_PING_X, y, 1.0f, colorWhite, CG_GetStringEdString("MP_INGAME", "PING"), 0, 0, ITEM_TEXTSTYLE_OUTLINED, FONT_MEDIUM );
#ifdef _XBOX
if(cg->widescreen)
CG_Text_Paint ( SB_TIME_X + 40, y, 1.0f, colorWhite, CG_GetStringEdString("MP_INGAME", "TIME"), 0, 0, ITEM_TEXTSTYLE_OUTLINED, FONT_MEDIUM );
else
#endif
CG_Text_Paint ( SB_TIME_X, y, 1.0f, colorWhite, CG_GetStringEdString("MP_INGAME", "TIME"), 0, 0, ITEM_TEXTSTYLE_OUTLINED, FONT_MEDIUM );
if(ClientManager::splitScreenMode == qtrue) {
y = SB_TOP - 20;
if(ClientManager::ActiveClientNum() == 1)
y = SB_TOP - 20 + 220;
}
else
y = SB_TOP;
// If there are more than SB_MAXCLIENTS_NORMAL, use the interleaved scores
if ( cg->numScores > SB_MAXCLIENTS_NORMAL || ClientManager::splitScreenMode == qtrue) {
maxClients = SB_MAXCLIENTS_INTER;
lineHeight = SB_INTER_HEIGHT;
topBorderSize = 8;
bottomBorderSize = 16;
} else {
maxClients = SB_MAXCLIENTS_NORMAL;
lineHeight = SB_NORMAL_HEIGHT;
topBorderSize = 8;
bottomBorderSize = 8;
}
localClient = qfalse;
//I guess this should end up being able to display 19 clients at once.
//In a team game, if there are 9 or more clients on the team not in the lead,
//we only want to show 10 of the clients on the team in the lead, so that we
//have room to display the clients in the lead on the losing team.
//I guess this can be accomplished simply by printing the first teams score with a maxClients
//value passed in related to how many players are on both teams.
if ( cgs.gametype >= GT_TEAM ) {
//
// teamplay scoreboard
//
y += lineHeight/2;
if ( cg->teamScores[0] >= cg->teamScores[1] ) {
int team1MaxCl = CG_GetTeamCount(TEAM_RED, maxClients);
int team2MaxCl = CG_GetTeamCount(TEAM_BLUE, maxClients);
if (team1MaxCl > 10 && (team1MaxCl+team2MaxCl) > maxClients)
{
team1MaxCl -= team2MaxCl;
//subtract as many as you have to down to 10, once we get there
//we just set it to 10
if (team1MaxCl < 10)
{
team1MaxCl = 10;
}
}
team2MaxCl = (maxClients-team1MaxCl); //team2 can display however many is left over after team1's display
n1 = CG_TeamScoreboard( y, TEAM_RED, fade, team1MaxCl, lineHeight, qtrue );
#ifdef _XBOX
if(cg->widescreen)
CG_DrawTeamBackground( SB_SCORELINE_X - 5 + 40, y - topBorderSize, 640 - SB_SCORELINE_X * 2 + 10, n1 * lineHeight + bottomBorderSize, 0.33f, TEAM_RED );
else
#endif
CG_DrawTeamBackground( SB_SCORELINE_X - 5, y - topBorderSize, 640 - SB_SCORELINE_X * 2 + 10, n1 * lineHeight + bottomBorderSize, 0.33f, TEAM_RED );
CG_TeamScoreboard( y, TEAM_RED, fade, team1MaxCl, lineHeight, qfalse );
y += (n1 * lineHeight) + BIGCHAR_HEIGHT;
//maxClients -= n1;
n2 = CG_TeamScoreboard( y, TEAM_BLUE, fade, team2MaxCl, lineHeight, qtrue );
#ifdef _XBOX
if(cg->widescreen)
CG_DrawTeamBackground( SB_SCORELINE_X - 5 + 40, y - topBorderSize, 640 - SB_SCORELINE_X * 2 + 10, n2 * lineHeight + bottomBorderSize, 0.33f, TEAM_BLUE );
else
#endif
CG_DrawTeamBackground( SB_SCORELINE_X - 5, y - topBorderSize, 640 - SB_SCORELINE_X * 2 + 10, n2 * lineHeight + bottomBorderSize, 0.33f, TEAM_BLUE );
CG_TeamScoreboard( y, TEAM_BLUE, fade, team2MaxCl, lineHeight, qfalse );
y += (n2 * lineHeight) + BIGCHAR_HEIGHT;
//maxClients -= n2;
maxClients -= (team1MaxCl+team2MaxCl);
} else {
int team1MaxCl = CG_GetTeamCount(TEAM_BLUE, maxClients);
int team2MaxCl = CG_GetTeamCount(TEAM_RED, maxClients);
if (team1MaxCl > 10 && (team1MaxCl+team2MaxCl) > maxClients)
{
team1MaxCl -= team2MaxCl;
//subtract as many as you have to down to 10, once we get there
//we just set it to 10
if (team1MaxCl < 10)
{
team1MaxCl = 10;
}
}
team2MaxCl = (maxClients-team1MaxCl); //team2 can display however many is left over after team1's display
n1 = CG_TeamScoreboard( y, TEAM_BLUE, fade, team1MaxCl, lineHeight, qtrue );
#ifdef _XBOX
if(cg->widescreen)
CG_DrawTeamBackground( SB_SCORELINE_X - 5 + 40, y - topBorderSize, 640 - SB_SCORELINE_X * 2 + 10, n1 * lineHeight + bottomBorderSize, 0.33f, TEAM_BLUE );
else
#endif
CG_DrawTeamBackground( SB_SCORELINE_X - 5, y - topBorderSize, 640 - SB_SCORELINE_X * 2 + 10, n1 * lineHeight + bottomBorderSize, 0.33f, TEAM_BLUE );
CG_TeamScoreboard( y, TEAM_BLUE, fade, team1MaxCl, lineHeight, qfalse );
y += (n1 * lineHeight) + BIGCHAR_HEIGHT;
//maxClients -= n1;
n2 = CG_TeamScoreboard( y, TEAM_RED, fade, team2MaxCl, lineHeight, qtrue );
#ifdef _XBOX
if(cg->widescreen)
CG_DrawTeamBackground( SB_SCORELINE_X - 5 + 40, y - topBorderSize, 640 - SB_SCORELINE_X * 2 + 10, n2 * lineHeight + bottomBorderSize, 0.33f, TEAM_RED );
else
#endif
CG_DrawTeamBackground( SB_SCORELINE_X - 5, y - topBorderSize, 640 - SB_SCORELINE_X * 2 + 10, n2 * lineHeight + bottomBorderSize, 0.33f, TEAM_RED );
CG_TeamScoreboard( y, TEAM_RED, fade, team2MaxCl, lineHeight, qfalse );
y += (n2 * lineHeight) + BIGCHAR_HEIGHT;
//maxClients -= n2;
maxClients -= (team1MaxCl+team2MaxCl);
}
n1 = CG_TeamScoreboard( y, TEAM_SPECTATOR, fade, maxClients, lineHeight, qfalse );
y += (n1 * lineHeight) + BIGCHAR_HEIGHT;
} else {
//
// free for all scoreboard
//
n1 = CG_TeamScoreboard( y, TEAM_FREE, fade, maxClients, lineHeight, qfalse );
y += (n1 * lineHeight) + BIGCHAR_HEIGHT;
n2 = CG_TeamScoreboard( y, TEAM_SPECTATOR, fade, maxClients - n1, lineHeight, qfalse );
y += (n2 * lineHeight) + BIGCHAR_HEIGHT;
}
if (!localClient && ClientManager::splitScreenMode == qfalse) {
// draw local client at the bottom
for ( i = 0 ; i < cg->numScores ; i++ ) {
if ( cg->scores[i].client == cg->snap->ps.clientNum ) {
CG_DrawClientScore( y, &cg->scores[i], fadeColor, fade, lineHeight == SB_NORMAL_HEIGHT );
break;
}
}
}
//If in intermission, draw "press fire to continue" string.
if(cg->predictedPlayerState.pm_type == PM_INTERMISSION) {
const char *s = CG_GetStringEdString("SP_INGAME", "CONTINUE");
#ifdef _XBOX
if(cg->widescreen)
CG_Text_Paint ( (720 - CG_Text_Width(s, 1.0f, FONT_MEDIUM)) / 2 , y, 1.0f, colorWhite, s, 0, 0, ITEM_TEXTSTYLE_OUTLINED, FONT_MEDIUM );
else
#endif
CG_Text_Paint ( (640 - CG_Text_Width(s, 1.0f, FONT_MEDIUM)) / 2 , y, 1.0f, colorWhite, s, 0, 0, ITEM_TEXTSTYLE_OUTLINED, FONT_MEDIUM );
}
// load any models that have been deferred
if ( ++cg->deferredPlayerLoading > 10 ) {
CG_LoadDeferredPlayers();
}
return qtrue;
}
//================================================================================

1764
codemp/cgame/cg_servercmds.c Normal file

File diff suppressed because it is too large Load Diff

497
codemp/cgame/cg_snapshot.c Normal file
View File

@@ -0,0 +1,497 @@
// Copyright (C) 1999-2000 Id Software, Inc.
//
// cg_snapshot.c -- things that happen on snapshot transition,
// not necessarily every single rendered frame
#include "cg_local.h"
#ifdef _XBOX
#include "../client/cl_data.h"
#endif
/*
==================
CG_ResetEntity
==================
*/
static void CG_ResetEntity( centity_t *cent ) {
// if the previous snapshot this entity was updated in is at least
// an event window back in time then we can reset the previous event
if ( cent->snapShotTime < cg->time - EVENT_VALID_MSEC ) {
#ifdef _XBOX
cent->previousEvent[0] = 0;
cent->previousEvent[1] = 0;
#else
cent->previousEvent = 0;
#endif
}
cent->trailTime = cg->snap->serverTime;
VectorCopy (cent->currentState.origin, cent->lerpOrigin);
VectorCopy (cent->currentState.angles, cent->lerpAngles);
if (cent->currentState.eFlags & EF_G2ANIMATING)
{ //reset the animation state
cent->pe.torso.animationNumber = -1;
cent->pe.legs.animationNumber = -1;
}
#if 0
if (cent->isRagging && (cent->currentState.eFlags & EF_DEAD))
{
VectorAdd(cent->lerpOrigin, cent->lerpOriginOffset, cent->lerpOrigin);
}
#endif
if ( cent->currentState.eType == ET_PLAYER || cent->currentState.eType == ET_NPC ) {
CG_ResetPlayerEntity( cent );
}
}
/*
===============
CG_TransitionEntity
cent->nextState is moved to cent->currentState and events are fired
===============
*/
static void CG_TransitionEntity( centity_t *cent ) {
cent->currentState = cent->nextState;
#ifdef _XBOX
cent->currentValid[ClientManager::ActiveClientNum()] = qtrue;
// reset if the entity wasn't in the last frame or was teleported
if ( !cent->interpolate[ClientManager::ActiveClientNum()] ) {
CG_ResetEntity( cent );
}
// clear the next state. if will be set by the next CG_SetNextSnap
cent->interpolate[ClientManager::ActiveClientNum()] = qfalse;
#else
cent->currentValid = qtrue;
// reset if the entity wasn't in the last frame or was teleported
if ( !cent->interpolate ) {
CG_ResetEntity( cent );
}
// clear the next state. if will be set by the next CG_SetNextSnap
cent->interpolate = qfalse;
#endif
// check for events
CG_CheckEvents( cent );
}
/*
==================
CG_SetInitialSnapshot
This will only happen on the very first snapshot, or
on tourney restarts. All other times will use
CG_TransitionSnapshot instead.
FIXME: Also called by map_restart?
==================
*/
void CG_SetInitialSnapshot( snapshot_t *snap ) {
int i;
centity_t *cent;
entityState_t *state;
cg->snap = snap;
if ((cg_entities[snap->ps.clientNum].ghoul2 == NULL) && trap_G2_HaveWeGhoul2Models(cgs.clientinfo[snap->ps.clientNum].ghoul2Model))
{
trap_G2API_DuplicateGhoul2Instance(cgs.clientinfo[snap->ps.clientNum].ghoul2Model, &cg_entities[snap->ps.clientNum].ghoul2);
CG_CopyG2WeaponInstance(&cg_entities[snap->ps.clientNum], FIRST_WEAPON, cg_entities[snap->ps.clientNum].ghoul2);
if (trap_G2API_AddBolt(cg_entities[snap->ps.clientNum].ghoul2, 0, "face") == -1)
{ //check now to see if we have this bone for setting anims and such
cg_entities[snap->ps.clientNum].noFace = qtrue;
}
}
BG_PlayerStateToEntityState( &snap->ps, &cg_entities[ snap->ps.clientNum ].currentState, qfalse );
// sort out solid entities
CG_BuildSolidList();
CG_ExecuteNewServerCommands( snap->serverCommandSequence );
// set our local weapon selection pointer to
// what the server has indicated the current weapon is
CG_Respawn();
for ( i = 0 ; i < cg->snap->numEntities ; i++ ) {
state = &cg->snap->entities[ i ];
cent = &cg_entities[ state->number ];
memcpy(&cent->currentState, state, sizeof(entityState_t));
//cent->currentState = *state;
#ifdef _XBOX
cent->interpolate[ClientManager::ActiveClientNum()] = qfalse;
cent->currentValid[ClientManager::ActiveClientNum()] = qtrue;
#else
cent->interpolate = qfalse;
cent->currentValid = qtrue;
#endif
CG_ResetEntity( cent );
// check for events
CG_CheckEvents( cent );
}
}
/*
===================
CG_TransitionSnapshot
The transition point from snap to nextSnap has passed
===================
*/
extern qboolean CG_UsingEWeb(void); //cg_predict.c
static void CG_TransitionSnapshot( void ) {
centity_t *cent;
snapshot_t *oldFrame;
int i;
if ( !cg->snap ) {
CG_Error( "CG_TransitionSnapshot: NULL cg->snap" );
}
if ( !cg->nextSnap ) {
CG_Error( "CG_TransitionSnapshot: NULL cg->nextSnap" );
}
// execute any server string commands before transitioning entities
CG_ExecuteNewServerCommands( cg->nextSnap->serverCommandSequence );
// if we had a map_restart, set everthing with initial
if ( !cg->snap ) {
}
// clear the currentValid flag for all entities in the existing snapshot
for ( i = 0 ; i < cg->snap->numEntities ; i++ ) {
cent = &cg_entities[ cg->snap->entities[ i ].number ];
#ifdef _XBOX
cent->currentValid[ClientManager::ActiveClientNum()] = qfalse;
#else
cent->currentValid = qfalse;
#endif
}
// move nextSnap to snap and do the transitions
oldFrame = cg->snap;
cg->snap = cg->nextSnap;
//CG_CheckPlayerG2Weapons(&cg->snap->ps, &cg_entities[cg->snap->ps.clientNum]);
//CG_CheckPlayerG2Weapons(&cg->snap->ps, &cg->predictedPlayerEntity);
BG_PlayerStateToEntityState( &cg->snap->ps, &cg_entities[ cg->snap->ps.clientNum ].currentState, qfalse );
#ifdef _XBOX
cg_entities[ cg->snap->ps.clientNum ].interpolate[ClientManager::ActiveClientNum()] = qfalse;
#else
cg_entities[ cg->snap->ps.clientNum ].interpolate = qfalse;
#endif
for ( i = 0 ; i < cg->snap->numEntities ; i++ ) {
cent = &cg_entities[ cg->snap->entities[ i ].number ];
CG_TransitionEntity( cent );
// remember time of snapshot this entity was last updated in
cent->snapShotTime = cg->snap->serverTime;
}
cg->nextSnap = NULL;
// check for playerstate transition events
if ( oldFrame ) {
playerState_t *ops, *ps;
ops = &oldFrame->ps;
ps = &cg->snap->ps;
// teleporting checks are irrespective of prediction
if ( ( ps->eFlags ^ ops->eFlags ) & EF_TELEPORT_BIT ) {
cg->thisFrameTeleport = qtrue; // will be cleared by prediction code
}
#ifdef _XBOX
if ( ClientManager::splitScreenMode == qtrue ) {
CG_TransitionPlayerState( ps, ops );
}
else
#endif
// if we are not doing client side movement prediction for any
// reason, then the client events and view changes will be issued now
if ( cg->demoPlayback || (cg->snap->ps.pm_flags & PMF_FOLLOW)
|| cg_nopredict.integer || cg_synchronousClients.integer || CG_UsingEWeb() ) {
CG_TransitionPlayerState( ps, ops );
}
}
}
/*
===================
CG_SetNextSnap
A new snapshot has just been read in from the client system.
===================
*/
static void CG_SetNextSnap( snapshot_t *snap ) {
int num;
entityState_t *es;
centity_t *cent;
cg->nextSnap = snap;
//CG_CheckPlayerG2Weapons(&cg->snap->ps, &cg_entities[cg->snap->ps.clientNum]);
//CG_CheckPlayerG2Weapons(&cg->snap->ps, &cg->predictedPlayerEntity);
BG_PlayerStateToEntityState( &snap->ps, &cg_entities[ snap->ps.clientNum ].nextState, qfalse );
//cg_entities[ cg->snap->ps.clientNum ].interpolate = qtrue;
//No longer want to do this, as the cg_entities[clnum] and cg->predictedPlayerEntity are one in the same.
// check for extrapolation errors
for ( num = 0 ; num < snap->numEntities ; num++ )
{
es = &snap->entities[num];
cent = &cg_entities[ es->number ];
memcpy(&cent->nextState, es, sizeof(entityState_t));
//cent->nextState = *es;
// if this frame is a teleport, or the entity wasn't in the
// previous frame, don't interpolate
#ifdef _XBOX
if ( !cent->currentValid[ClientManager::ActiveClientNum()] || ( ( cent->currentState.eFlags ^ es->eFlags ) & EF_TELEPORT_BIT ) ) {
cent->interpolate[ClientManager::ActiveClientNum()] = qfalse;
} else {
cent->interpolate[ClientManager::ActiveClientNum()] = qtrue;
}
#else
if ( !cent->currentValid || ( ( cent->currentState.eFlags ^ es->eFlags ) & EF_TELEPORT_BIT ) ) {
cent->interpolate = qfalse;
} else {
cent->interpolate = qtrue;
}
#endif
}
// if the next frame is a teleport for the playerstate, we
// can't interpolate during demos
if ( cg->snap && ( ( snap->ps.eFlags ^ cg->snap->ps.eFlags ) & EF_TELEPORT_BIT ) ) {
cg->nextFrameTeleport = qtrue;
} else {
cg->nextFrameTeleport = qfalse;
}
// if changing follow mode, don't interpolate
if ( cg->nextSnap->ps.clientNum != cg->snap->ps.clientNum ) {
cg->nextFrameTeleport = qtrue;
}
// if changing server restarts, don't interpolate
if ( ( cg->nextSnap->snapFlags ^ cg->snap->snapFlags ) & SNAPFLAG_SERVERCOUNT ) {
cg->nextFrameTeleport = qtrue;
}
// sort out solid entities
CG_BuildSolidList();
}
/*
========================
CG_ReadNextSnapshot
This is the only place new snapshots are requested
This may increment cgs.processedSnapshotNum multiple
times if the client system fails to return a
valid snapshot.
========================
*/
static snapshot_t *CG_ReadNextSnapshot( void ) {
qboolean r;
snapshot_t *dest;
#ifdef _XBOX
if(ClientManager::splitScreenMode == qtrue)
{
if ( cg->latestSnapshotNum > cgs.processedSnapshotNum[ClientManager::ActiveClientNum()] + 1000 ) {
#ifndef FINAL_BUILD
CG_Printf( "WARNING: CG_ReadNextSnapshot: way out of range, %i > %i",
cg->latestSnapshotNum, cgs.processedSnapshotNum[ClientManager::ActiveClientNum()] );
#endif
}
}
else
{
if ( cg->latestSnapshotNum > cgs.processedSnapshotNum[0] + 1000 ) {
#ifndef FINAL_BUILD
CG_Printf( "WARNING: CG_ReadNextSnapshot: way out of range, %i > %i",
cg->latestSnapshotNum, cgs.processedSnapshotNum[0] );
#endif
}
}
#else
if ( cg->latestSnapshotNum > cgs.processedSnapshotNum + 1000 ) {
#ifndef FINAL_BUILD
CG_Printf( "WARNING: CG_ReadNextSnapshot: way out of range, %i > %i",
cg->latestSnapshotNum, cgs.processedSnapshotNum );
#endif
}
#endif
#ifdef _XBOX
int clnum = 0;
if(ClientManager::splitScreenMode == qtrue)
clnum = ClientManager::ActiveClientNum();
while ( cgs.processedSnapshotNum[clnum] < cg->latestSnapshotNum ) {
#else
while ( cgs.processedSnapshotNum < cg->latestSnapshotNum ) {
#endif
// decide which of the two slots to load it into
if ( cg->snap == &cg->activeSnapshots[0] ) {
dest = &cg->activeSnapshots[1];
} else {
dest = &cg->activeSnapshots[0];
}
// try to read the snapshot from the client system
#ifdef _XBOX
cgs.processedSnapshotNum[clnum]++;
r = trap_GetSnapshot( cgs.processedSnapshotNum[clnum], dest );
#else
cgs.processedSnapshotNum++;
r = trap_GetSnapshot( cgs.processedSnapshotNum, dest );
#endif
// FIXME: why would trap_GetSnapshot return a snapshot with the same server time
if ( cg->snap && r && dest->serverTime == cg->snap->serverTime ) {
//continue;
}
// if it succeeded, return
if ( r ) {
// CG_AddLagometerSnapshotInfo( dest );
return dest;
}
// a GetSnapshot will return failure if the snapshot
// never arrived, or is so old that its entities
// have been shoved off the end of the circular
// buffer in the client system.
// record as a dropped packet
// CG_AddLagometerSnapshotInfo( NULL );
// If there are additional snapshots, continue trying to
// read them.
}
// nothing left to read
return NULL;
}
/*
============
CG_ProcessSnapshots
We are trying to set up a renderable view, so determine
what the simulated time is, and try to get snapshots
both before and after that time if available.
If we don't have a valid cg->snap after exiting this function,
then a 3D game view cannot be rendered. This should only happen
right after the initial connection. After cg->snap has been valid
once, it will never turn invalid.
Even if cg->snap is valid, cg->nextSnap may not be, if the snapshot
hasn't arrived yet (it becomes an extrapolating situation instead
of an interpolating one)
============
*/
void CG_ProcessSnapshots( void ) {
snapshot_t *snap;
int n;
// see what the latest snapshot the client system has is
trap_GetCurrentSnapshotNumber( &n, &cg->latestSnapshotTime );
if ( n != cg->latestSnapshotNum ) {
if ( n < cg->latestSnapshotNum ) {
// this should never happen
CG_Error( "CG_ProcessSnapshots: n < cg->latestSnapshotNum" );
}
cg->latestSnapshotNum = n;
}
// If we have yet to receive a snapshot, check for it.
// Once we have gotten the first snapshot, cg->snap will
// always have valid data for the rest of the game
while ( !cg->snap ) {
snap = CG_ReadNextSnapshot();
if ( !snap ) {
// we can't continue until we get a snapshot
return;
}
// set our weapon selection to what
// the playerstate is currently using
if ( !( snap->snapFlags & SNAPFLAG_NOT_ACTIVE ) ) {
CG_SetInitialSnapshot( snap );
}
}
// loop until we either have a valid nextSnap with a serverTime
// greater than cg->time to interpolate towards, or we run
// out of available snapshots
do {
// if we don't have a nextframe, try and read a new one in
if ( !cg->nextSnap ) {
snap = CG_ReadNextSnapshot();
// if we still don't have a nextframe, we will just have to
// extrapolate
if ( !snap ) {
break;
}
CG_SetNextSnap( snap );
// if time went backwards, we have a level restart
if ( cg->nextSnap->serverTime < cg->snap->serverTime ) {
CG_Error( "CG_ProcessSnapshots: Server time went backwards" );
}
}
// if our time is < nextFrame's, we have a nice interpolating state
if ( cg->time >= cg->snap->serverTime && cg->time < cg->nextSnap->serverTime ) {
break;
}
// we have passed the transition from nextFrame to frame
CG_TransitionSnapshot();
} while ( 1 );
// assert our valid conditions upon exiting
if ( cg->snap == NULL ) {
CG_Error( "CG_ProcessSnapshots: cg->snap == NULL" );
}
if ( cg->time < cg->snap->serverTime ) {
// this can happen right after a vid_restart
cg->time = cg->snap->serverTime;
}
if ( cg->nextSnap != NULL && cg->nextSnap->serverTime <= cg->time ) {
CG_Error( "CG_ProcessSnapshots: cg->nextSnap->serverTime <= cg->time" );
}
}

73
codemp/cgame/cg_strap.c Normal file
View File

@@ -0,0 +1,73 @@
//rww - shared trap call system
#include "cg_local.h"
#include "../namespace_begin.h"
qboolean strap_G2API_GetBoltMatrix(void *ghoul2, const int modelIndex, const int boltIndex, mdxaBone_t *matrix,
const vec3_t angles, const vec3_t position, const int frameNum, qhandle_t *modelList, vec3_t scale)
{
return trap_G2API_GetBoltMatrix(ghoul2, modelIndex, boltIndex, matrix, angles, position, frameNum, modelList, scale);
}
qboolean strap_G2API_GetBoltMatrix_NoReconstruct(void *ghoul2, const int modelIndex, const int boltIndex, mdxaBone_t *matrix,
const vec3_t angles, const vec3_t position, const int frameNum, qhandle_t *modelList, vec3_t scale)
{
return trap_G2API_GetBoltMatrix_NoReconstruct(ghoul2, modelIndex, boltIndex, matrix, angles, position, frameNum, modelList, scale);
}
qboolean strap_G2API_GetBoltMatrix_NoRecNoRot(void *ghoul2, const int modelIndex, const int boltIndex, mdxaBone_t *matrix,
const vec3_t angles, const vec3_t position, const int frameNum, qhandle_t *modelList, vec3_t scale)
{
return trap_G2API_GetBoltMatrix_NoRecNoRot(ghoul2, modelIndex, boltIndex, matrix, angles, position, frameNum, modelList, scale);
}
qboolean strap_G2API_SetBoneAngles(void *ghoul2, int modelIndex, const char *boneName, const vec3_t angles, const int flags,
const int up, const int right, const int forward, qhandle_t *modelList,
int blendTime , int currentTime )
{
return trap_G2API_SetBoneAngles(ghoul2, modelIndex, boneName, angles, flags, up, right, forward, modelList, blendTime, currentTime);
}
qboolean strap_G2API_SetBoneAnim(void *ghoul2, const int modelIndex, const char *boneName, const int startFrame, const int endFrame,
const int flags, const float animSpeed, const int currentTime, const float setFrame , const int blendTime )
{
return trap_G2API_SetBoneAnim(ghoul2, modelIndex, boneName, startFrame, endFrame, flags, animSpeed, currentTime, setFrame, blendTime);
}
qboolean strap_G2API_GetBoneAnim(void *ghoul2, const char *boneName, const int currentTime, float *currentFrame,
int *startFrame, int *endFrame, int *flags, float *animSpeed, int *modelList, const int modelIndex)
{
return trap_G2API_GetBoneAnim(ghoul2, boneName, currentTime, currentFrame, startFrame, endFrame, flags, animSpeed, modelList, modelIndex);
}
void strap_G2API_SetRagDoll(void *ghoul2, sharedRagDollParams_t *params)
{
trap_G2API_SetRagDoll(ghoul2, params);
}
void strap_G2API_AnimateG2Models(void *ghoul2, int time, sharedRagDollUpdateParams_t *params)
{
trap_G2API_AnimateG2Models(ghoul2, time, params);
}
qboolean strap_G2API_SetBoneIKState(void *ghoul2, int time, const char *boneName, int ikState, sharedSetBoneIKStateParams_t *params)
{
return trap_G2API_SetBoneIKState(ghoul2, time, boneName, ikState, params);
}
qboolean strap_G2API_IKMove(void *ghoul2, int time, sharedIKMoveParams_t *params)
{
return trap_G2API_IKMove(ghoul2, time, params);
}
void strap_TrueMalloc(void **ptr, int size)
{
trap_TrueMalloc(ptr, size);
}
void strap_TrueFree(void **ptr)
{
trap_TrueFree(ptr);
}
#include "../namespace_end.h"

View File

@@ -0,0 +1,203 @@
code
equ trap_Print -1 ; CG_PRINT
equ trap_Error -2 ; CG_ERROR
equ trap_Milliseconds -3 ; CG_MILLISECONDS
equ trap_PrecisionTimer_Start -4 ; CG_PRECISIONTIMER_START
equ trap_PrecisionTimer_End -5 ; CG_PRECISIONTIMER_END
equ trap_Cvar_Register -6 ; CG_CVAR_REGISTER
equ trap_Cvar_Update -7 ; CG_CVAR_UPDATE
equ trap_Cvar_Set -8 ; CG_CVAR_SET
equ trap_Cvar_VariableStringBuffer -9 ; CG_CVAR_VARIABLESTRINGBUFFER
equ trap_Argc -10 ; CG_ARGC
equ trap_Argv -11 ; CG_ARGV
equ trap_Args -12 ; CG_ARGS
equ trap_FS_FOpenFile -13 ; CG_FS_FOPENFILE
equ trap_FS_Read -14 ; CG_FS_READ
equ trap_FS_Write -15 ; CG_FS_WRITE
equ trap_FS_FCloseFile -16 ; CG_FS_FCLOSEFILE
equ trap_FS_GetFileList -17 ; CG_FS_GETFILELIST
equ trap_SendConsoleCommand -18 ; CG_SENDCONSOLECOMMAND
equ trap_AddCommand -19 ; CG_ADDCOMMAND
equ trap_RemoveCommand -20 ; CG_REMOVECOMMAND
equ trap_SendClientCommand -21 ; CG_SENDCLIENTCOMMAND
equ trap_UpdateScreen -22 ; CG_UPDATESCREEN
equ trap_CM_LoadMap -23 ; CG_CM_LOADMAP
equ trap_CM_NumInlineModels -24 ; CG_CM_NUMINLINEMODELS
equ trap_CM_InlineModel -25 ; CG_CM_INLINEMODEL
equ trap_CM_TempBoxModel -26 ; CG_CM_TEMPBOXMODEL
equ trap_CM_TempCapsuleModel -27 ; CG_CM_TEMPCAPSULEMODEL
equ trap_CM_PointContents -28 ; CG_CM_POINTCONTENTS
equ trap_CM_TransformedPointContents -29 ; CG_CM_TRANSFORMEDPOINTCONTENTS
equ trap_CM_BoxTrace -30 ; CG_CM_BOXTRACE
equ trap_CM_CapsuleTrace -31 ; CG_CM_CAPSULETRACE
equ trap_CM_TransformedBoxTrace -32 ; CG_CM_TRANSFORMEDBOXTRACE
equ trap_CM_TransformedCapsuleTrace -33 ; CG_CM_TRANSFORMEDCAPSULETRACE
equ trap_CM_MarkFragments -34 ; CG_CM_MARKFRAGMENTS
equ trap_S_GetVoiceVolume -35 ; CG_S_GETVOICEVOLUME
equ trap_S_MuteSound -36 ; CG_S_MUTESOUND
equ trap_S_StartSound -37 ; CG_S_STARTSOUND
equ trap_S_StartLocalSound -38 ; CG_S_STARTLOCALSOUND
equ trap_S_ClearLoopingSounds -39 ; CG_S_CLEARLOOPINGSOUNDS
equ trap_S_AddLoopingSound -40 ; CG_S_ADDLOOPINGSOUND
equ trap_S_UpdateEntityPosition -41 ; CG_S_UPDATEENTITYPOSITION
equ trap_S_AddRealLoopingSound -42 ; CG_S_ADDREALLOOPINGSOUND
equ trap_S_StopLoopingSound -43 ; CG_S_STOPLOOPINGSOUND
equ trap_S_Respatialize -44 ; CG_S_RESPATIALIZE
equ trap_S_RegisterSound -45 ; CG_S_REGISTERSOUND
equ trap_S_StartBackgroundTrack -46 ; CG_S_STARTBACKGROUNDTRACK
equ trap_S_UpdateAmbientSet -47 ; CG_S_UPDATEAMBIENTSET
equ trap_AS_ParseSets -48 ; CG_AS_PARSESETS
equ trap_AS_AddPrecacheEntry -49 ; CG_AS_ADDPRECACHEENTRY
equ trap_S_AddLocalSet -50 ; CG_S_ADDLOCALSET
equ trap_AS_GetBModelSound -51 ; CG_AS_GETBMODELSOUND
equ trap_R_LoadWorldMap -52 ; CG_R_LOADWORLDMAP
equ trap_R_RegisterModel -53 ; CG_R_REGISTERMODEL
equ trap_R_RegisterSkin -54 ; CG_R_REGISTERSKIN
equ trap_R_RegisterShader -55 ; CG_R_REGISTERSHADER
equ trap_R_RegisterShaderNoMip -56 ; CG_R_REGISTERSHADERNOMIP
equ trap_R_RegisterFont -57 ; CG_R_REGISTERFONT
equ trap_R_Font_StrLenPixels -58 ; CG_R_FONT_STRLENPIXELS
equ trap_R_Font_StrLenChars -59 ; CG_R_FONT_STRLENCHARS
equ trap_R_Font_HeightPixels -60 ; CG_R_FONT_STRHEIGHTPIXELS
equ trap_R_Font_DrawString -61 ; CG_R_FONT_DRAWSTRING
equ trap_Language_IsAsian -62 ; CG_LANGUAGE_ISASIAN
equ trap_Language_UsesSpaces -63 ; CG_LANGUAGE_USESSPACES
equ trap_AnyLanguage_ReadCharFromString -64 ; CG_ANYLANGUAGE_READCHARFROMSTRING
equ trap_R_ClearScene -201 ; CG_R_CLEARSCENE
equ trap_R_AddRefEntityToScene -202 ; CG_R_ADDREFENTITYTOSCENE
equ trap_R_AddPolyToScene -203 ; CG_R_ADDPOLYTOSCENE
equ trap_R_AddPolysToScene -204 ; CG_R_ADDPOLYSTOSCENE
equ trap_R_LightForPoint -205 ; CG_R_LIGHTFORPOINT
equ trap_R_AddLightToScene -206 ; CG_R_ADDLIGHTTOSCENE
equ trap_R_AddAdditiveLightToScene -207 ; CG_R_ADDADDITIVELIGHTTOSCENE
equ trap_R_RenderScene -208 ; CG_R_RENDERSCENE
equ trap_R_SetColor -209 ; CG_R_SETCOLOR
equ trap_R_DrawStretchPic -210 ; CG_R_DRAWSTRETCHPIC
equ trap_R_ModelBounds -211 ; CG_R_MODELBOUNDS
equ trap_R_LerpTag -212 ; CG_R_LERPTAG
equ trap_R_DrawRotatePic -213 ; CG_R_DRAWROTATEPIC
equ trap_R_DrawRotatePic2 -214 ; CG_R_DRAWROTATEPIC2
equ trap_R_RemapShader -215 ; CG_R_REMAP_SHADER
equ trap_R_GetLightStyle -216 ; CG_R_GET_LIGHT_STYLE
equ trap_R_SetLightStyle -217 ; CG_R_SET_LIGHT_STYLE
equ trap_R_GetBModelVerts -218 ; CG_R_GET_BMODEL_VERTS
equ trap_FX_AddLine -219 ; CG_FX_ADDLINE
equ trap_GetGlconfig -220 ; CG_GETGLCONFIG
equ trap_GetGameState -221 ; CG_GETGAMESTATE
equ trap_GetCurrentSnapshotNumber -222 ; CG_GETCURRENTSNAPSHOTNUMBER
equ trap_GetSnapshot -223 ; CG_GETSNAPSHOT
equ trap_GetDefaultState -224 ; CG_GETDEFAULTSTATE
equ trap_GetServerCommand -225 ; CG_GETSERVERCOMMAND
equ trap_GetCurrentCmdNumber -226 ; CG_GETCURRENTCMDNUMBER
equ trap_GetUserCmd -227 ; CG_GETUSERCMD
equ trap_SetUserCmdValue -228 ; CG_SETUSERCMDVALUE
equ trap_SetClientForceAngle -229 ; CG_SETCLIENTFORCEANGLE
equ trap_SetClientTurnExtent -230 ; CG_SETCLIENTTURNEXTENT
equ trap_OpenUIMenu -231 ; CG_OPENUIMENU
equ trap_MemoryRemaining -234 ; CG_MEMORY_REMAINING
equ trap_Key_IsDown -235 ; CG_KEY_ISDOWN
equ trap_Key_GetCatcher -236 ; CG_KEY_GETCATCHER
equ trap_Key_SetCatcher -237 ; CG_KEY_SETCATCHER
equ trap_Key_GetKey -238 ; CG_KEY_GETKEY
equ trap_PC_AddGlobalDefine -239 ; CG_PC_ADD_GLOBAL_DEFINE
equ trap_PC_LoadSource -240 ; CG_PC_LOAD_SOURCE
equ trap_PC_FreeSource -241 ; CG_PC_FREE_SOURCE
equ trap_PC_ReadToken -242 ; CG_PC_READ_TOKEN
equ trap_PC_SourceFileAndLine -243 ; CG_PC_SOURCE_FILE_AND_LINE
equ trap_PC_LoadGlobalDefines -244 ; CG_PC_LOAD_GLOBAL_DEFINES
equ trap_PC_RemoveAllGlobalDefines -245 ; CG_PC_REMOVE_ALL_GLOBAL_DEFINES
equ trap_S_StopBackgroundTrack -246 ; CG_S_STOPBACKGROUNDTRACK
equ trap_RealTime -247 ; CG_REAL_TIME
equ trap_SnapVector -248 ; CG_SNAPVECTOR
equ trap_CIN_PlayCinematic -249 ; CG_CIN_PLAYCINEMATIC
equ trap_CIN_StopCinematic -250 ; CG_CIN_STOPCINEMATIC
equ trap_CIN_RunCinematic -251 ; CG_CIN_RUNCINEMATIC
equ trap_CIN_DrawCinematic -252 ; CG_CIN_DRAWCINEMATIC
equ trap_CIN_SetExtents -253 ; CG_CIN_SETEXTENTS
equ trap_GetEntityToken -254 ; CG_GET_ENTITY_TOKEN
equ trap_R_inPVS -255 ; CG_R_INPVS
equ trap_FX_RegisterEffect -256 ; CG_FX_REGISTER_EFFECT
equ trap_FX_PlaySimpleEffect -257 ; CG_FX_PLAY_SIMPLE_EFFECT
equ trap_FX_PlayEffect -258 ; CG_FX_PLAY_EFFECT
equ trap_FX_PlayEntityEffect -259 ; CG_FX_PLAY_ENTITY_EFFECT
equ trap_FX_PlaySimpleEffectID -260 ; CG_FX_PLAY_SIMPLE_EFFECT_ID
equ trap_FX_PlayEffectID -261 ; CG_FX_PLAY_EFFECT_ID
equ trap_FX_PlayPortalEffectID -262 ; CG_FX_PLAY_PORTAL_EFFECT_ID
equ trap_FX_PlayEntityEffectID -263 ; CG_FX_PLAY_ENTITY_EFFECT_ID
equ trap_FX_PlayBoltedEffectID -264 ; CG_FX_PLAY_BOLTED_EFFECT_ID
equ trap_FX_AddScheduledEffects -265 ; CG_FX_ADD_SCHEDULED_EFFECTS
equ trap_FX_InitSystem -266 ; CG_FX_INIT_SYSTEM
equ trap_FX_FreeSystem -267 ; CG_FX_FREE_SYSTEM
equ trap_FX_AdjustTime -268 ; CG_FX_ADJUST_TIME
equ trap_FX_AddPoly -269 ; CG_FX_ADDPOLY
equ trap_FX_AddBezier -270 ; CG_FX_ADDBEZIER
equ trap_FX_AddPrimitive -271 ; CG_FX_ADDPRIMITIVE
equ trap_FX_AddSprite -272 ; CG_FX_ADDSPRITE
equ trap_FX_AddElectricity -273 ; CG_FX_ADDELECTRICITY
equ trap_SP_GetStringTextString -274 ; CG_SP_GETSTRINGTEXTSTRING
equ trap_SP_Register -275 ; CG_SP_REGISTER
equ trap_ROFF_Clean -276 ; CG_ROFF_CLEAN
equ trap_ROFF_UpdateEntities -277 ; CG_ROFF_UPDATE_ENTITIES
equ trap_ROFF_Cache -278 ; CG_ROFF_CACHE
equ trap_ROFF_Play -279 ; CG_ROFF_PLAY
equ trap_ROFF_Purge_Ent -280 ; CG_ROFF_PURGE_ENT
equ trap_TrueMalloc -281 ; CG_TRUEMALLOC
equ trap_TrueFree -282 ; CG_TRUEFREE
equ trap_G2_ListModelSurfaces -283 ; CG_G2_LISTSURFACES
equ trap_G2_ListModelBones -284 ; CG_G2_LISTBONES
equ trap_G2_SetGhoul2ModelIndexes -285 ; CG_G2_SETMODELS
equ trap_G2_HaveWeGhoul2Models -286 ; CG_G2_HAVEWEGHOULMODELS
equ trap_G2API_GiveMeVectorFromMatrix -287 ; CG_G2_GIVEMEVECTORFROMMATRIX
equ trap_G2API_GetBoltMatrix -288 ; CG_G2_GETBOLT
equ trap_G2API_GetBoltMatrix_NoReconstruct -289 ; CG_G2_GETBOLT_NOREC
equ trap_G2API_GetBoltMatrix_NoRecNoRot -290 ; CG_G2_GETBOLT_NOREC_NOROT
equ trap_G2API_InitGhoul2Model -291 ; CG_G2_INITGHOUL2MODEL
equ trap_G2API_SetSkin -292 ; CG_G2_SETSKIN
equ trap_G2API_CollisionDetect -293 ; CG_G2_COLLISIONDETECT
equ trap_G2API_CleanGhoul2Models -294 ; CG_G2_CLEANMODELS
equ trap_G2API_SetBoneAngles -295 ; CG_G2_ANGLEOVERRIDE
equ trap_G2API_SetBoneAnim -296 ; CG_G2_PLAYANIM
equ trap_G2API_GetBoneAnim -297 ; CG_G2_GETBONEANIM
equ trap_G2API_GetBoneFrame -298 ; CG_G2_GETBONEFRAME
equ trap_G2API_GetGLAName -299 ; CG_G2_GETGLANAME
equ trap_G2API_CopyGhoul2Instance -300 ; CG_G2_COPYGHOUL2INSTANCE
equ trap_G2API_CopySpecificGhoul2Model -301 ; CG_G2_COPYSPECIFICGHOUL2MODEL
equ trap_G2API_DuplicateGhoul2Instance -302 ; CG_G2_DUPLICATEGHOUL2INSTANCE
equ trap_G2API_HasGhoul2ModelOnIndex -303 ; CG_G2_HASGHOUL2MODELONINDEX
equ trap_G2API_RemoveGhoul2Model -304 ; CG_G2_REMOVEGHOUL2MODEL
equ trap_G2API_AddBolt -305 ; CG_G2_ADDBOLT
equ trap_G2API_SetBoltInfo -306 ; CG_G2_SETBOLTON
equ trap_G2API_SetRootSurface -307 ; CG_G2_SETROOTSURFACE
equ trap_G2API_SetSurfaceOnOff -308 ; CG_G2_SETSURFACEONOFF
equ trap_G2API_SetNewOrigin -309 ; CG_G2_SETNEWORIGIN
equ trap_G2API_GetSurfaceRenderStatus -310 ; CG_G2_GETSURFACERENDERSTATUS
equ trap_G2API_GetTime -311 ; CG_G2_GETTIME
equ trap_G2API_SetTime -312 ; CG_G2_SETTIME
equ trap_G2API_SetRagDoll -313 ; CG_G2_SETRAGDOLL
equ trap_G2API_AnimateG2Models -314 ; CG_G2_ANIMATEG2MODELS
equ trap_G2API_SetBoneIKState -315 ; CG_G2_SETBONEIKSTATE
equ trap_G2API_IKMove -316 ; CG_G2_IKMOVE
equ trap_G2API_GetSurfaceName -317 ; CG_G2_GETSURFACENAME
equ trap_CG_RegisterSharedMemory -318 ; CG_SET_SHARED_BUFFER
equ trap_CM_RegisterTerrain -319 ; CG_CM_REGISTER_TERRAIN
equ trap_RMG_Init -320 ; CG_RMG_INIT
equ trap_RE_InitRendererTerrain -321 ; CG_RE_INIT_RENDERER_TERRAIN
equ trap_R_WeatherContentsOverride -322 ; CG_R_WEATHER_CONTENTS_OVERRIDE
; hardcoded functions
equ memset -101 ; CGAME_MEMSET
equ memcpy -102 ; CGAME_MEMCPY
equ strncpy -103 ; CGAME_STRNCPY
equ sin -104 ; CGAME_SIN
equ cos -105 ; CGAME_COS
equ atan2 -106 ; CGAME_ATAN2
equ sqrt -107 ; CGAME_SQRT
equ matrixmultiply -108 ; CGAME_MATRIXMULTIPLY
equ anglevectors -109 ; CGAME_ANGLEVECTORS
equ perpendicularvector -110 ; CGAME_PERPENDICULARVECTOR
equ floor -111 ; CGAME_FLOOR
equ ceil -112 ; CGAME_CEIL
equ acos -115 ; CGAME_ACOS
equ asin -116 ; CGAME_ASIN

1118
codemp/cgame/cg_syscalls.c Normal file

File diff suppressed because it is too large Load Diff

242
codemp/cgame/cg_turret.c Normal file
View File

@@ -0,0 +1,242 @@
#include "cg_local.h"
#include "..\game\q_shared.h"
#include "..\ghoul2\g2.h"
//rww - The turret is heavily dependant on bone angles. We can't happily set that on the server, so it is done client-only.
void CreepToPosition(vec3_t ideal, vec3_t current)
{
float max_degree_switch = 90;
int degrees_negative = 0;
int degrees_positive = 0;
int doNegative = 0;
int angle_ideal;
int angle_current;
angle_ideal = (int)ideal[YAW];
angle_current = (int)current[YAW];
if (angle_ideal <= angle_current)
{
degrees_negative = (angle_current - angle_ideal);
degrees_positive = (360 - angle_current) + angle_ideal;
}
else
{
degrees_negative = angle_current + (360 - angle_ideal);
degrees_positive = (angle_ideal - angle_current);
}
if (degrees_negative < degrees_positive)
{
doNegative = 1;
}
if (doNegative)
{
current[YAW] -= max_degree_switch;
if (current[YAW] < ideal[YAW] && (current[YAW]+(max_degree_switch*2)) >= ideal[YAW])
{
current[YAW] = ideal[YAW];
}
if (current[YAW] < 0)
{
current[YAW] += 361;
}
}
else
{
current[YAW] += max_degree_switch;
if (current[YAW] > ideal[YAW] && (current[YAW]-(max_degree_switch*2)) <= ideal[YAW])
{
current[YAW] = ideal[YAW];
}
if (current[YAW] > 360)
{
current[YAW] -= 361;
}
}
if (ideal[PITCH] < 0)
{
ideal[PITCH] += 360;
}
angle_ideal = (int)ideal[PITCH];
angle_current = (int)current[PITCH];
doNegative = 0;
if (angle_ideal <= angle_current)
{
degrees_negative = (angle_current - angle_ideal);
degrees_positive = (360 - angle_current) + angle_ideal;
}
else
{
degrees_negative = angle_current + (360 - angle_ideal);
degrees_positive = (angle_ideal - angle_current);
}
if (degrees_negative < degrees_positive)
{
doNegative = 1;
}
if (doNegative)
{
current[PITCH] -= max_degree_switch;
if (current[PITCH] < ideal[PITCH] && (current[PITCH]+(max_degree_switch*2)) >= ideal[PITCH])
{
current[PITCH] = ideal[PITCH];
}
if (current[PITCH] < 0)
{
current[PITCH] += 361;
}
}
else
{
current[PITCH] += max_degree_switch;
if (current[PITCH] > ideal[PITCH] && (current[PITCH]-(max_degree_switch*2)) <= ideal[PITCH])
{
current[PITCH] = ideal[PITCH];
}
if (current[PITCH] > 360)
{
current[PITCH] -= 361;
}
}
}
void TurretClientRun(centity_t *ent)
{
if (!ent->ghoul2)
{
weaponInfo_t *weaponInfo;
trap_G2API_InitGhoul2Model(&ent->ghoul2, CG_ConfigString( CS_MODELS+ent->currentState.modelindex ), 0, 0, 0, 0, 0);
if (!ent->ghoul2)
{ //bad
return;
}
ent->torsoBolt = trap_G2API_AddBolt( ent->ghoul2, 0, "*flash02" );
trap_G2API_SetBoneAngles( ent->ghoul2, 0, "bone_hinge", vec3_origin, BONE_ANGLES_POSTMULT, POSITIVE_Y, POSITIVE_Z, POSITIVE_X, NULL, 100, cg->time );
trap_G2API_SetBoneAngles( ent->ghoul2, 0, "bone_gback", vec3_origin, BONE_ANGLES_POSTMULT, POSITIVE_Y, POSITIVE_Z, POSITIVE_X, NULL, 100, cg->time );
trap_G2API_SetBoneAngles( ent->ghoul2, 0, "bone_barrel", vec3_origin, BONE_ANGLES_POSTMULT, POSITIVE_Y, POSITIVE_Z, POSITIVE_X, NULL, 100, cg->time );
trap_G2API_SetBoneAnim( ent->ghoul2, 0, "model_root", 0, 11, BONE_ANIM_OVERRIDE_FREEZE, 0.8f, cg->time, 0, 0 );
ent->turAngles[ROLL] = 0;
ent->turAngles[PITCH] = 90;
ent->turAngles[YAW] = 0;
weaponInfo = &cg_weapons[WP_TURRET];
if ( !weaponInfo->registered )
{
CG_RegisterWeapon(WP_TURRET);
}
}
if (ent->currentState.fireflag == 2)
{ //I'm about to blow
if (ent->turAngles)
{
trap_G2API_SetBoneAngles( ent->ghoul2, 0, "bone_hinge", ent->turAngles, BONE_ANGLES_REPLACE, NEGATIVE_Y, NEGATIVE_Z, NEGATIVE_X, NULL, 100, cg->time );
}
return;
}
else if (ent->currentState.fireflag && ent->bolt4 != ent->currentState.fireflag)
{
vec3_t muzzleOrg, muzzleDir;
mdxaBone_t boltMatrix;
trap_G2API_GetBoltMatrix(ent->ghoul2, 0, ent->torsoBolt, &boltMatrix, /*ent->lerpAngles*/vec3_origin, ent->lerpOrigin, cg->time, cgs.gameModels, ent->modelScale);
BG_GiveMeVectorFromMatrix(&boltMatrix, ORIGIN, muzzleOrg);
BG_GiveMeVectorFromMatrix(&boltMatrix, NEGATIVE_X, muzzleDir);
trap_FX_PlayEffectID(cgs.effects.mTurretMuzzleFlash, muzzleOrg, muzzleDir, -1, -1);
ent->bolt4 = ent->currentState.fireflag;
}
else if (!ent->currentState.fireflag)
{
ent->bolt4 = 0;
}
if (ent->currentState.bolt2 != ENTITYNUM_NONE)
{ //turn toward the enemy
centity_t *enemy = &cg_entities[ent->currentState.bolt2];
if (enemy)
{
vec3_t enAng;
vec3_t enPos;
VectorCopy(enemy->currentState.pos.trBase, enPos);
VectorSubtract(enPos, ent->lerpOrigin, enAng);
VectorNormalize(enAng);
vectoangles(enAng, enAng);
enAng[ROLL] = 0;
enAng[PITCH] += 90;
CreepToPosition(enAng, ent->turAngles);
}
}
else
{
vec3_t idleAng;
float turnAmount;
if (ent->turAngles[YAW] > 360)
{
ent->turAngles[YAW] -= 361;
}
if (!ent->dustTrailTime)
{
ent->dustTrailTime = cg->time;
}
turnAmount = (cg->time-ent->dustTrailTime)*0.03;
if (turnAmount > 360)
{
turnAmount = 360;
}
idleAng[PITCH] = 90;
idleAng[ROLL] = 0;
idleAng[YAW] = ent->turAngles[YAW] + turnAmount;
ent->dustTrailTime = cg->time;
CreepToPosition(idleAng, ent->turAngles);
}
if (cg->time < ent->frame_minus1_refreshed)
{
ent->frame_minus1_refreshed = cg->time;
return;
}
ent->frame_minus1_refreshed = cg->time;
trap_G2API_SetBoneAngles( ent->ghoul2, 0, "bone_hinge", ent->turAngles, BONE_ANGLES_REPLACE, NEGATIVE_Y, NEGATIVE_Z, NEGATIVE_X, NULL, 100, cg->time );
}

3454
codemp/cgame/cg_view.c Normal file

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,592 @@
//
// cg_weaponinit.c -- events and effects dealing with weapons
#include "cg_local.h"
#include "fx_local.h"
/*
=================
CG_RegisterWeapon
The server says this item is used on this level
=================
*/
void CG_RegisterWeapon( int weaponNum) {
weaponInfo_t *weaponInfo;
gitem_t *item, *ammo;
char path[MAX_QPATH];
vec3_t mins, maxs;
int i;
weaponInfo = &cg_weapons[weaponNum];
if ( weaponNum == 0 ) {
return;
}
if ( weaponInfo->registered ) {
return;
}
memset( weaponInfo, 0, sizeof( *weaponInfo ) );
weaponInfo->registered = qtrue;
for ( item = bg_itemlist + 1 ; item->classname ; item++ ) {
if ( item->giType == IT_WEAPON && item->giTag == weaponNum ) {
weaponInfo->item = item;
break;
}
}
if ( !item->classname ) {
CG_Error( "Couldn't find weapon %i", weaponNum );
}
CG_RegisterItemVisuals( item - bg_itemlist );
// load cmodel before model so filecache works
weaponInfo->weaponModel = trap_R_RegisterModel( item->world_model[0] );
// load in-view model also
weaponInfo->viewModel = trap_R_RegisterModel(item->view_model);
// calc midpoint for rotation
trap_R_ModelBounds( weaponInfo->weaponModel, mins, maxs );
for ( i = 0 ; i < 3 ; i++ ) {
weaponInfo->weaponMidpoint[i] = mins[i] + 0.5 * ( maxs[i] - mins[i] );
}
weaponInfo->weaponIcon = trap_R_RegisterShader( item->icon );
weaponInfo->ammoIcon = trap_R_RegisterShader( item->icon );
for ( ammo = bg_itemlist + 1 ; ammo->classname ; ammo++ ) {
if ( ammo->giType == IT_AMMO && ammo->giTag == weaponNum ) {
break;
}
}
if ( ammo->classname && ammo->world_model[0] ) {
weaponInfo->ammoModel = trap_R_RegisterModel( ammo->world_model[0] );
}
// strcpy( path, item->view_model );
// COM_StripExtension( path, path );
// strcat( path, "_flash.md3" );
weaponInfo->flashModel = 0;//trap_R_RegisterModel( path );
if (weaponNum == WP_DISRUPTOR ||
weaponNum == WP_FLECHETTE ||
weaponNum == WP_REPEATER ||
weaponNum == WP_ROCKET_LAUNCHER)
{
strcpy( path, item->view_model );
COM_StripExtension( path, path );
strcat( path, "_barrel.md3" );
weaponInfo->barrelModel = trap_R_RegisterModel( path );
}
else if (weaponNum == WP_STUN_BATON)
{ //only weapon with more than 1 barrel..
trap_R_RegisterModel("models/weapons2/stun_baton/baton_barrel.md3");
trap_R_RegisterModel("models/weapons2/stun_baton/baton_barrel2.md3");
trap_R_RegisterModel("models/weapons2/stun_baton/baton_barrel3.md3");
}
else
{
weaponInfo->barrelModel = 0;
}
if (weaponNum != WP_SABER)
{
strcpy( path, item->view_model );
COM_StripExtension( path, path );
strcat( path, "_hand.md3" );
weaponInfo->handsModel = trap_R_RegisterModel( path );
}
else
{
weaponInfo->handsModel = 0;
}
// if ( !weaponInfo->handsModel ) {
// weaponInfo->handsModel = trap_R_RegisterModel( "models/weapons2/shotgun/shotgun_hand.md3" );
// }
switch ( weaponNum ) {
case WP_STUN_BATON:
case WP_MELEE:
/* MAKERGB( weaponInfo->flashDlightColor, 0.6f, 0.6f, 1.0f );
weaponInfo->firingSound = trap_S_RegisterSound( "sound/weapons/saber/saberhum.wav" );
// weaponInfo->flashSound[0] = trap_S_RegisterSound( "sound/weapons/melee/fstatck.wav" );
*/
//trap_R_RegisterShader( "gfx/effects/stunPass" );
trap_FX_RegisterEffect( "stunBaton/flesh_impact" );
if (weaponNum == WP_STUN_BATON)
{
trap_S_RegisterSound( "sound/weapons/baton/idle.wav" );
weaponInfo->flashSound[0] = trap_S_RegisterSound( "sound/weapons/baton/fire.mp3" );
weaponInfo->altFlashSound[0] = trap_S_RegisterSound( "sound/weapons/baton/fire.mp3" );
}
else
{
/*
int j = 0;
while (j < 4)
{
weaponInfo->flashSound[j] = trap_S_RegisterSound( va("sound/weapons/melee/swing%i", j+1) );
weaponInfo->altFlashSound[j] = weaponInfo->flashSound[j];
j++;
}
*/
//No longer needed, animsound config plays them for us
}
break;
case WP_SABER:
MAKERGB( weaponInfo->flashDlightColor, 0.6f, 0.6f, 1.0f );
weaponInfo->firingSound = trap_S_RegisterSound( "sound/weapons/saber/saberhum1.wav" );
weaponInfo->missileModel = trap_R_RegisterModel( "models/weapons2/saber/saber_w.glm" );
break;
case WP_CONCUSSION:
weaponInfo->selectSound = trap_S_RegisterSound("sound/weapons/concussion/select.wav");
weaponInfo->flashSound[0] = NULL_SOUND;
weaponInfo->firingSound = NULL_SOUND;
weaponInfo->chargeSound = NULL_SOUND;
weaponInfo->muzzleEffect = trap_FX_RegisterEffect( "concussion/muzzle_flash" );
weaponInfo->missileModel = NULL_HANDLE;
weaponInfo->missileSound = NULL_SOUND;
weaponInfo->missileDlight = 0;
//weaponInfo->missileDlightColor= {0,0,0};
weaponInfo->missileHitSound = NULL_SOUND;
weaponInfo->missileTrailFunc = FX_ConcussionProjectileThink;
weaponInfo->altFlashSound[0] = NULL_SOUND;
weaponInfo->altFiringSound = NULL_SOUND;
weaponInfo->altChargeSound = trap_S_RegisterSound( "sound/weapons/bryar/altcharge.wav");
weaponInfo->altMuzzleEffect = trap_FX_RegisterEffect( "concussion/altmuzzle_flash" );
weaponInfo->altMissileModel = NULL_HANDLE;
weaponInfo->altMissileSound = NULL_SOUND;
weaponInfo->altMissileDlight = 0;
//weaponInfo->altMissileDlightColor= {0,0,0};
weaponInfo->altMissileHitSound = NULL_SOUND;
weaponInfo->altMissileTrailFunc = FX_ConcussionProjectileThink;
cgs.effects.disruptorAltMissEffect = trap_FX_RegisterEffect( "disruptor/alt_miss" );
cgs.effects.concussionShotEffect = trap_FX_RegisterEffect( "concussion/shot" );
cgs.effects.concussionImpactEffect = trap_FX_RegisterEffect( "concussion/explosion" );
trap_R_RegisterShader("gfx/effects/blueLine");
trap_R_RegisterShader("gfx/misc/whiteline2");
break;
case WP_BRYAR_PISTOL:
case WP_BRYAR_OLD:
weaponInfo->selectSound = trap_S_RegisterSound("sound/weapons/bryar/select.wav");
weaponInfo->flashSound[0] = trap_S_RegisterSound( "sound/weapons/bryar/fire.wav");
weaponInfo->firingSound = NULL_SOUND;
weaponInfo->chargeSound = NULL_SOUND;
weaponInfo->muzzleEffect = trap_FX_RegisterEffect( "bryar/muzzle_flash" );
weaponInfo->missileModel = NULL_HANDLE;
weaponInfo->missileSound = NULL_SOUND;
weaponInfo->missileDlight = 0;
//weaponInfo->missileDlightColor= {0,0,0};
weaponInfo->missileHitSound = NULL_SOUND;
weaponInfo->missileTrailFunc = FX_BryarProjectileThink;
weaponInfo->altFlashSound[0] = trap_S_RegisterSound( "sound/weapons/bryar/alt_fire.wav");
weaponInfo->altFiringSound = NULL_SOUND;
weaponInfo->altChargeSound = trap_S_RegisterSound( "sound/weapons/bryar/altcharge.wav");
weaponInfo->altMuzzleEffect = trap_FX_RegisterEffect( "bryar/muzzle_flash" );
weaponInfo->altMissileModel = NULL_HANDLE;
weaponInfo->altMissileSound = NULL_SOUND;
weaponInfo->altMissileDlight = 0;
//weaponInfo->altMissileDlightColor= {0,0,0};
weaponInfo->altMissileHitSound = NULL_SOUND;
weaponInfo->altMissileTrailFunc = FX_BryarAltProjectileThink;
cgs.effects.bryarShotEffect = trap_FX_RegisterEffect( "bryar/shot" );
cgs.effects.bryarPowerupShotEffect = trap_FX_RegisterEffect( "bryar/crackleShot" );
cgs.effects.bryarWallImpactEffect = trap_FX_RegisterEffect( "bryar/wall_impact" );
cgs.effects.bryarWallImpactEffect2 = trap_FX_RegisterEffect( "bryar/wall_impact2" );
cgs.effects.bryarWallImpactEffect3 = trap_FX_RegisterEffect( "bryar/wall_impact3" );
cgs.effects.bryarFleshImpactEffect = trap_FX_RegisterEffect( "bryar/flesh_impact" );
cgs.effects.bryarDroidImpactEffect = trap_FX_RegisterEffect( "bryar/droid_impact" );
cgs.media.bryarFrontFlash = trap_R_RegisterShader( "gfx/effects/bryarFrontFlash" );
// Note these are temp shared effects
trap_FX_RegisterEffect("blaster/wall_impact.efx");
trap_FX_RegisterEffect("blaster/flesh_impact.efx");
break;
case WP_BLASTER:
case WP_EMPLACED_GUN: //rww - just use the same as this for now..
weaponInfo->selectSound = trap_S_RegisterSound("sound/weapons/blaster/select.wav");
weaponInfo->flashSound[0] = trap_S_RegisterSound( "sound/weapons/blaster/fire.wav");
weaponInfo->firingSound = NULL_SOUND;
weaponInfo->chargeSound = NULL_SOUND;
weaponInfo->muzzleEffect = trap_FX_RegisterEffect( "blaster/muzzle_flash" );
weaponInfo->missileModel = NULL_HANDLE;
weaponInfo->missileSound = NULL_SOUND;
weaponInfo->missileDlight = 0;
// weaponInfo->missileDlightColor = {0,0,0};
weaponInfo->missileHitSound = NULL_SOUND;
weaponInfo->missileTrailFunc = FX_BlasterProjectileThink;
weaponInfo->altFlashSound[0] = trap_S_RegisterSound( "sound/weapons/blaster/alt_fire.wav");
weaponInfo->altFiringSound = NULL_SOUND;
weaponInfo->altChargeSound = NULL_SOUND;
weaponInfo->altMuzzleEffect = trap_FX_RegisterEffect( "blaster/muzzle_flash" );
weaponInfo->altMissileModel = NULL_HANDLE;
weaponInfo->altMissileSound = NULL_SOUND;
weaponInfo->altMissileDlight = 0;
// weaponInfo->altMissileDlightColor= {0,0,0};
weaponInfo->altMissileHitSound = NULL_SOUND;
weaponInfo->altMissileTrailFunc = FX_BlasterProjectileThink;
trap_FX_RegisterEffect( "blaster/deflect" );
cgs.effects.blasterShotEffect = trap_FX_RegisterEffect( "blaster/shot" );
cgs.effects.blasterWallImpactEffect = trap_FX_RegisterEffect( "blaster/wall_impact" );
cgs.effects.blasterFleshImpactEffect = trap_FX_RegisterEffect( "blaster/flesh_impact" );
cgs.effects.blasterDroidImpactEffect = trap_FX_RegisterEffect( "blaster/droid_impact" );
break;
case WP_DISRUPTOR:
weaponInfo->selectSound = trap_S_RegisterSound("sound/weapons/disruptor/select.wav");
weaponInfo->flashSound[0] = trap_S_RegisterSound( "sound/weapons/disruptor/fire.wav");
weaponInfo->firingSound = NULL_SOUND;
weaponInfo->chargeSound = NULL_SOUND;
weaponInfo->muzzleEffect = trap_FX_RegisterEffect( "disruptor/muzzle_flash" );
weaponInfo->missileModel = NULL_HANDLE;
weaponInfo->missileSound = NULL_SOUND;
weaponInfo->missileDlight = 0;
// weaponInfo->missileDlightColor = {0,0,0};
weaponInfo->missileHitSound = NULL_SOUND;
weaponInfo->missileTrailFunc = 0;
weaponInfo->altFlashSound[0] = trap_S_RegisterSound( "sound/weapons/disruptor/alt_fire.wav");
weaponInfo->altFiringSound = NULL_SOUND;
weaponInfo->altChargeSound = trap_S_RegisterSound("sound/weapons/disruptor/altCharge.wav");
weaponInfo->altMuzzleEffect = trap_FX_RegisterEffect( "disruptor/muzzle_flash" );
weaponInfo->altMissileModel = NULL_HANDLE;
weaponInfo->altMissileSound = NULL_SOUND;
weaponInfo->altMissileDlight = 0;
// weaponInfo->altMissileDlightColor= {0,0,0};
weaponInfo->altMissileHitSound = NULL_SOUND;
weaponInfo->altMissileTrailFunc = 0;
cgs.effects.disruptorRingsEffect = trap_FX_RegisterEffect( "disruptor/rings" );
cgs.effects.disruptorProjectileEffect = trap_FX_RegisterEffect( "disruptor/projectile" );
cgs.effects.disruptorWallImpactEffect = trap_FX_RegisterEffect( "disruptor/wall_impact" );
cgs.effects.disruptorFleshImpactEffect = trap_FX_RegisterEffect( "disruptor/flesh_impact" );
cgs.effects.disruptorAltMissEffect = trap_FX_RegisterEffect( "disruptor/alt_miss" );
cgs.effects.disruptorAltHitEffect = trap_FX_RegisterEffect( "disruptor/alt_hit" );
trap_R_RegisterShader( "gfx/effects/redLine" );
trap_R_RegisterShader( "gfx/misc/whiteline2" );
trap_R_RegisterShader( "gfx/effects/smokeTrail" );
trap_S_RegisterSound("sound/weapons/disruptor/zoomstart.wav");
trap_S_RegisterSound("sound/weapons/disruptor/zoomend.wav");
// Disruptor gun zoom interface
cgs.media.disruptorMask = trap_R_RegisterShader( "gfx/2d/cropCircle2");
cgs.media.disruptorInsert = trap_R_RegisterShader( "gfx/2d/cropCircle");
cgs.media.disruptorLight = trap_R_RegisterShader( "gfx/2d/cropCircleGlow" );
cgs.media.disruptorInsertTick = trap_R_RegisterShader( "gfx/2d/insertTick" );
cgs.media.disruptorChargeShader = trap_R_RegisterShaderNoMip("gfx/2d/crop_charge");
cgs.media.disruptorZoomLoop = trap_S_RegisterSound( "sound/weapons/disruptor/zoomloop.wav" );
break;
case WP_BOWCASTER:
weaponInfo->selectSound = trap_S_RegisterSound("sound/weapons/bowcaster/select.wav");
weaponInfo->altFlashSound[0] = trap_S_RegisterSound( "sound/weapons/bowcaster/fire.wav");
weaponInfo->altFiringSound = NULL_SOUND;
weaponInfo->altChargeSound = NULL_SOUND;
weaponInfo->altMuzzleEffect = trap_FX_RegisterEffect( "bowcaster/muzzle_flash" );
weaponInfo->altMissileModel = NULL_HANDLE;
weaponInfo->altMissileSound = NULL_SOUND;
weaponInfo->altMissileDlight = 0;
// weaponInfo->altMissileDlightColor = {0,0,0};
weaponInfo->altMissileHitSound = NULL_SOUND;
weaponInfo->altMissileTrailFunc = FX_BowcasterProjectileThink;
weaponInfo->flashSound[0] = trap_S_RegisterSound( "sound/weapons/bowcaster/fire.wav");
weaponInfo->firingSound = NULL_SOUND;
weaponInfo->chargeSound = trap_S_RegisterSound( "sound/weapons/bowcaster/altcharge.wav");
weaponInfo->muzzleEffect = trap_FX_RegisterEffect( "bowcaster/muzzle_flash" );
weaponInfo->missileModel = NULL_HANDLE;
weaponInfo->missileSound = NULL_SOUND;
weaponInfo->missileDlight = 0;
// weaponInfo->missileDlightColor= {0,0,0};
weaponInfo->missileHitSound = NULL_SOUND;
weaponInfo->missileTrailFunc = FX_BowcasterAltProjectileThink;
cgs.effects.bowcasterShotEffect = trap_FX_RegisterEffect( "bowcaster/shot" );
cgs.effects.bowcasterImpactEffect = trap_FX_RegisterEffect( "bowcaster/explosion" );
trap_FX_RegisterEffect( "bowcaster/deflect" );
cgs.media.greenFrontFlash = trap_R_RegisterShader( "gfx/effects/greenFrontFlash" );
break;
case WP_REPEATER:
weaponInfo->selectSound = trap_S_RegisterSound("sound/weapons/repeater/select.wav");
weaponInfo->flashSound[0] = trap_S_RegisterSound( "sound/weapons/repeater/fire.wav");
weaponInfo->firingSound = NULL_SOUND;
weaponInfo->chargeSound = NULL_SOUND;
weaponInfo->muzzleEffect = trap_FX_RegisterEffect( "repeater/muzzle_flash" );
weaponInfo->missileModel = NULL_HANDLE;
weaponInfo->missileSound = NULL_SOUND;
weaponInfo->missileDlight = 0;
// weaponInfo->missileDlightColor = {0,0,0};
weaponInfo->missileHitSound = NULL_SOUND;
weaponInfo->missileTrailFunc = FX_RepeaterProjectileThink;
weaponInfo->altFlashSound[0] = trap_S_RegisterSound( "sound/weapons/repeater/alt_fire.wav");
weaponInfo->altFiringSound = NULL_SOUND;
weaponInfo->altChargeSound = NULL_SOUND;
weaponInfo->altMuzzleEffect = trap_FX_RegisterEffect( "repeater/muzzle_flash" );
weaponInfo->altMissileModel = NULL_HANDLE;
weaponInfo->altMissileSound = NULL_SOUND;
weaponInfo->altMissileDlight = 0;
// weaponInfo->altMissileDlightColor= {0,0,0};
weaponInfo->altMissileHitSound = NULL_SOUND;
weaponInfo->altMissileTrailFunc = FX_RepeaterAltProjectileThink;
cgs.effects.repeaterProjectileEffect = trap_FX_RegisterEffect( "repeater/projectile" );
cgs.effects.repeaterAltProjectileEffect = trap_FX_RegisterEffect( "repeater/alt_projectile" );
cgs.effects.repeaterWallImpactEffect = trap_FX_RegisterEffect( "repeater/wall_impact" );
cgs.effects.repeaterFleshImpactEffect = trap_FX_RegisterEffect( "repeater/flesh_impact" );
//cgs.effects.repeaterAltWallImpactEffect = trap_FX_RegisterEffect( "repeater/alt_wall_impact" );
cgs.effects.repeaterAltWallImpactEffect = trap_FX_RegisterEffect( "repeater/concussion" );
break;
case WP_DEMP2:
weaponInfo->selectSound = trap_S_RegisterSound("sound/weapons/demp2/select.wav");
weaponInfo->flashSound[0] = trap_S_RegisterSound("sound/weapons/demp2/fire.wav");
weaponInfo->firingSound = NULL_SOUND;
weaponInfo->chargeSound = NULL_SOUND;
weaponInfo->muzzleEffect = trap_FX_RegisterEffect("demp2/muzzle_flash");
weaponInfo->missileModel = NULL_HANDLE;
weaponInfo->missileSound = NULL_SOUND;
weaponInfo->missileDlight = 0;
// weaponInfo->missileDlightColor = {0,0,0};
weaponInfo->missileHitSound = NULL_SOUND;
weaponInfo->missileTrailFunc = FX_DEMP2_ProjectileThink;
weaponInfo->altFlashSound[0] = trap_S_RegisterSound("sound/weapons/demp2/altfire.wav");
weaponInfo->altFiringSound = NULL_SOUND;
weaponInfo->altChargeSound = trap_S_RegisterSound("sound/weapons/demp2/altCharge.wav");
weaponInfo->altMuzzleEffect = trap_FX_RegisterEffect("demp2/muzzle_flash");
weaponInfo->altMissileModel = NULL_HANDLE;
weaponInfo->altMissileSound = NULL_SOUND;
weaponInfo->altMissileDlight = 0;
// weaponInfo->altMissileDlightColor= {0,0,0};
weaponInfo->altMissileHitSound = NULL_SOUND;
weaponInfo->altMissileTrailFunc = 0;
cgs.effects.demp2ProjectileEffect = trap_FX_RegisterEffect( "demp2/projectile" );
cgs.effects.demp2WallImpactEffect = trap_FX_RegisterEffect( "demp2/wall_impact" );
cgs.effects.demp2FleshImpactEffect = trap_FX_RegisterEffect( "demp2/flesh_impact" );
cgs.media.demp2Shell = trap_R_RegisterModel( "models/items/sphere.md3" );
cgs.media.demp2ShellShader = trap_R_RegisterShader( "gfx/effects/demp2shell" );
cgs.media.lightningFlash = trap_R_RegisterShader("gfx/misc/lightningFlash");
break;
case WP_FLECHETTE:
weaponInfo->selectSound = trap_S_RegisterSound("sound/weapons/flechette/select.wav");
weaponInfo->flashSound[0] = trap_S_RegisterSound( "sound/weapons/flechette/fire.wav");
weaponInfo->firingSound = NULL_SOUND;
weaponInfo->chargeSound = NULL_SOUND;
weaponInfo->muzzleEffect = trap_FX_RegisterEffect( "flechette/muzzle_flash" );
weaponInfo->missileModel = trap_R_RegisterModel("models/weapons2/golan_arms/projectileMain.md3");
weaponInfo->missileSound = NULL_SOUND;
weaponInfo->missileDlight = 0;
// weaponInfo->missileDlightColor = {0,0,0};
weaponInfo->missileHitSound = NULL_SOUND;
weaponInfo->missileTrailFunc = FX_FlechetteProjectileThink;
weaponInfo->altFlashSound[0] = trap_S_RegisterSound( "sound/weapons/flechette/alt_fire.wav");
weaponInfo->altFiringSound = NULL_SOUND;
weaponInfo->altChargeSound = NULL_SOUND;
weaponInfo->altMuzzleEffect = trap_FX_RegisterEffect( "flechette/muzzle_flash" );
weaponInfo->altMissileModel = trap_R_RegisterModel( "models/weapons2/golan_arms/projectile.md3" );
weaponInfo->altMissileSound = NULL_SOUND;
weaponInfo->altMissileDlight = 0;
// weaponInfo->altMissileDlightColor= {0,0,0};
weaponInfo->altMissileHitSound = NULL_SOUND;
weaponInfo->altMissileTrailFunc = FX_FlechetteAltProjectileThink;
cgs.effects.flechetteShotEffect = trap_FX_RegisterEffect( "flechette/shot" );
cgs.effects.flechetteAltShotEffect = trap_FX_RegisterEffect( "flechette/alt_shot" );
cgs.effects.flechetteWallImpactEffect = trap_FX_RegisterEffect( "flechette/wall_impact" );
cgs.effects.flechetteFleshImpactEffect = trap_FX_RegisterEffect( "flechette/flesh_impact" );
break;
case WP_ROCKET_LAUNCHER:
weaponInfo->selectSound = trap_S_RegisterSound("sound/weapons/rocket/select.wav");
weaponInfo->flashSound[0] = trap_S_RegisterSound( "sound/weapons/rocket/fire.wav");
weaponInfo->firingSound = NULL_SOUND;
weaponInfo->chargeSound = NULL_SOUND;
weaponInfo->muzzleEffect = trap_FX_RegisterEffect( "rocket/muzzle_flash" ); //trap_FX_RegisterEffect( "rocket/muzzle_flash2" );
//flash2 still looks crappy with the fx bolt stuff. Because the fx bolt stuff doesn't work entirely right.
weaponInfo->missileModel = trap_R_RegisterModel( "models/weapons2/merr_sonn/projectile.md3" );
weaponInfo->missileSound = trap_S_RegisterSound( "sound/weapons/rocket/missleloop.wav");
weaponInfo->missileDlight = 125;
VectorSet(weaponInfo->missileDlightColor, 1.0, 1.0, 0.5);
weaponInfo->missileHitSound = NULL_SOUND;
weaponInfo->missileTrailFunc = FX_RocketProjectileThink;
weaponInfo->altFlashSound[0] = trap_S_RegisterSound( "sound/weapons/rocket/alt_fire.wav");
weaponInfo->altFiringSound = NULL_SOUND;
weaponInfo->altChargeSound = NULL_SOUND;
weaponInfo->altMuzzleEffect = trap_FX_RegisterEffect( "rocket/altmuzzle_flash" );
weaponInfo->altMissileModel = trap_R_RegisterModel( "models/weapons2/merr_sonn/projectile.md3" );
weaponInfo->altMissileSound = trap_S_RegisterSound( "sound/weapons/rocket/missleloop.wav");
weaponInfo->altMissileDlight = 125;
VectorSet(weaponInfo->altMissileDlightColor, 1.0, 1.0, 0.5);
weaponInfo->altMissileHitSound = NULL_SOUND;
weaponInfo->altMissileTrailFunc = FX_RocketAltProjectileThink;
cgs.effects.rocketShotEffect = trap_FX_RegisterEffect( "rocket/shot" );
cgs.effects.rocketExplosionEffect = trap_FX_RegisterEffect( "rocket/explosion" );
trap_R_RegisterShaderNoMip( "gfx/2d/wedge" );
trap_R_RegisterShaderNoMip( "gfx/2d/lock" );
trap_S_RegisterSound( "sound/weapons/rocket/lock.wav" );
trap_S_RegisterSound( "sound/weapons/rocket/tick.wav" );
break;
case WP_THERMAL:
weaponInfo->selectSound = trap_S_RegisterSound("sound/weapons/thermal/select.wav");
weaponInfo->flashSound[0] = trap_S_RegisterSound( "sound/weapons/thermal/fire.wav");
weaponInfo->firingSound = NULL_SOUND;
weaponInfo->chargeSound = trap_S_RegisterSound( "sound/weapons/thermal/charge.wav");
weaponInfo->muzzleEffect = NULL_FX;
weaponInfo->missileModel = trap_R_RegisterModel( "models/weapons2/thermal/thermal_proj.md3" );
weaponInfo->missileSound = NULL_SOUND;
weaponInfo->missileDlight = 0;
// weaponInfo->missileDlightColor = {0,0,0};
weaponInfo->missileHitSound = NULL_SOUND;
weaponInfo->missileTrailFunc = 0;
weaponInfo->altFlashSound[0] = trap_S_RegisterSound( "sound/weapons/thermal/fire.wav");
weaponInfo->altFiringSound = NULL_SOUND;
weaponInfo->altChargeSound = trap_S_RegisterSound( "sound/weapons/thermal/charge.wav");
weaponInfo->altMuzzleEffect = NULL_FX;
weaponInfo->altMissileModel = trap_R_RegisterModel( "models/weapons2/thermal/thermal_proj.md3" );
weaponInfo->altMissileSound = NULL_SOUND;
weaponInfo->altMissileDlight = 0;
// weaponInfo->altMissileDlightColor= {0,0,0};
weaponInfo->altMissileHitSound = NULL_SOUND;
weaponInfo->altMissileTrailFunc = 0;
cgs.effects.thermalExplosionEffect = trap_FX_RegisterEffect( "thermal/explosion" );
cgs.effects.thermalShockwaveEffect = trap_FX_RegisterEffect( "thermal/shockwave" );
cgs.media.grenadeBounce1 = trap_S_RegisterSound( "sound/weapons/thermal/bounce1.wav" );
cgs.media.grenadeBounce2 = trap_S_RegisterSound( "sound/weapons/thermal/bounce2.wav" );
trap_S_RegisterSound( "sound/weapons/thermal/thermloop.wav" );
trap_S_RegisterSound( "sound/weapons/thermal/warning.wav" );
break;
case WP_TRIP_MINE:
weaponInfo->selectSound = trap_S_RegisterSound("sound/weapons/detpack/select.wav");
weaponInfo->flashSound[0] = trap_S_RegisterSound( "sound/weapons/laser_trap/fire.wav");
weaponInfo->firingSound = NULL_SOUND;
weaponInfo->chargeSound = NULL_SOUND;
weaponInfo->muzzleEffect = NULL_FX;
weaponInfo->missileModel = 0;//trap_R_RegisterModel( "models/weapons2/laser_trap/laser_trap_w.md3" );
weaponInfo->missileSound = NULL_SOUND;
weaponInfo->missileDlight = 0;
// weaponInfo->missileDlightColor = {0,0,0};
weaponInfo->missileHitSound = NULL_SOUND;
weaponInfo->missileTrailFunc = 0;
weaponInfo->altFlashSound[0] = trap_S_RegisterSound( "sound/weapons/laser_trap/fire.wav");
weaponInfo->altFiringSound = NULL_SOUND;
weaponInfo->altChargeSound = NULL_SOUND;
weaponInfo->altMuzzleEffect = NULL_FX;
weaponInfo->altMissileModel = 0;//trap_R_RegisterModel( "models/weapons2/laser_trap/laser_trap_w.md3" );
weaponInfo->altMissileSound = NULL_SOUND;
weaponInfo->altMissileDlight = 0;
// weaponInfo->altMissileDlightColor= {0,0,0};
weaponInfo->altMissileHitSound = NULL_SOUND;
weaponInfo->altMissileTrailFunc = 0;
cgs.effects.tripmineLaserFX = trap_FX_RegisterEffect("tripMine/laserMP.efx");
cgs.effects.tripmineGlowFX = trap_FX_RegisterEffect("tripMine/glowbit.efx");
trap_FX_RegisterEffect( "tripMine/explosion" );
// NOTENOTE temp stuff
trap_S_RegisterSound( "sound/weapons/laser_trap/stick.wav" );
trap_S_RegisterSound( "sound/weapons/laser_trap/warning.wav" );
break;
case WP_DET_PACK:
weaponInfo->selectSound = trap_S_RegisterSound("sound/weapons/detpack/select.wav");
weaponInfo->flashSound[0] = trap_S_RegisterSound( "sound/weapons/detpack/fire.wav");
weaponInfo->firingSound = NULL_SOUND;
weaponInfo->chargeSound = NULL_SOUND;
weaponInfo->muzzleEffect = NULL_FX;
weaponInfo->missileModel = trap_R_RegisterModel( "models/weapons2/detpack/det_pack.md3" );
weaponInfo->missileSound = NULL_SOUND;
weaponInfo->missileDlight = 0;
// weaponInfo->missileDlightColor = {0,0,0};
weaponInfo->missileHitSound = NULL_SOUND;
weaponInfo->missileTrailFunc = 0;
weaponInfo->altFlashSound[0] = trap_S_RegisterSound( "sound/weapons/detpack/fire.wav");
weaponInfo->altFiringSound = NULL_SOUND;
weaponInfo->altChargeSound = NULL_SOUND;
weaponInfo->altMuzzleEffect = NULL_FX;
weaponInfo->altMissileModel = trap_R_RegisterModel( "models/weapons2/detpack/det_pack.md3" );
weaponInfo->altMissileSound = NULL_SOUND;
weaponInfo->altMissileDlight = 0;
// weaponInfo->altMissileDlightColor= {0,0,0};
weaponInfo->altMissileHitSound = NULL_SOUND;
weaponInfo->altMissileTrailFunc = 0;
trap_R_RegisterModel( "models/weapons2/detpack/det_pack.md3" );
trap_S_RegisterSound( "sound/weapons/detpack/stick.wav" );
trap_S_RegisterSound( "sound/weapons/detpack/warning.wav" );
trap_S_RegisterSound( "sound/weapons/explosions/explode5.wav" );
break;
case WP_TURRET:
weaponInfo->flashSound[0] = NULL_SOUND;
weaponInfo->firingSound = NULL_SOUND;
weaponInfo->chargeSound = NULL_SOUND;
weaponInfo->muzzleEffect = NULL_HANDLE;
weaponInfo->missileModel = NULL_HANDLE;
weaponInfo->missileSound = NULL_SOUND;
weaponInfo->missileDlight = 0;
weaponInfo->missileHitSound = NULL_SOUND;
weaponInfo->missileTrailFunc = FX_TurretProjectileThink;
trap_FX_RegisterEffect("effects/blaster/wall_impact.efx");
trap_FX_RegisterEffect("effects/blaster/flesh_impact.efx");
break;
default:
MAKERGB( weaponInfo->flashDlightColor, 1, 1, 1 );
weaponInfo->flashSound[0] = trap_S_RegisterSound( "sound/weapons/rocket/rocklf1a.wav" );
break;
}
}

2750
codemp/cgame/cg_weapons.c Normal file

File diff suppressed because it is too large Load Diff

19
codemp/cgame/cgame.bat Normal file
View File

@@ -0,0 +1,19 @@
echo off
REM del /q vm
REM rww - removed this.. point of makefile is not have to rebuild all of it
mkdir vm
del vm\bg_lib.asm
asm2mak cgame makefile
make cgame
cd vm
mkdir "..\..\base\vm"
copy *.map "..\..\base\vm"
copy *.qvm "..\..\base\vm"
:quit
cd ..

65
codemp/cgame/fx_blaster.c Normal file
View File

@@ -0,0 +1,65 @@
// Blaster Weapon
#include "cg_local.h"
/*
-------------------------
FX_BlasterProjectileThink
-------------------------
*/
void FX_BlasterProjectileThink( centity_t *cent, const struct weaponInfo_s *weapon )
{
vec3_t forward;
if ( VectorNormalize2( cent->currentState.pos.trDelta, forward ) == 0.0f )
{
forward[2] = 1.0f;
}
trap_FX_PlayEffectID( cgs.effects.blasterShotEffect, cent->lerpOrigin, forward, -1, -1 );
}
/*
-------------------------
FX_BlasterAltFireThink
-------------------------
*/
void FX_BlasterAltFireThink( centity_t *cent, const struct weaponInfo_s *weapon )
{
vec3_t forward;
if ( VectorNormalize2( cent->currentState.pos.trDelta, forward ) == 0.0f )
{
forward[2] = 1.0f;
}
trap_FX_PlayEffectID( cgs.effects.blasterShotEffect, cent->lerpOrigin, forward, -1, -1 );
}
/*
-------------------------
FX_BlasterWeaponHitWall
-------------------------
*/
void FX_BlasterWeaponHitWall( vec3_t origin, vec3_t normal )
{
trap_FX_PlayEffectID( cgs.effects.blasterWallImpactEffect, origin, normal, -1, -1 );
}
/*
-------------------------
FX_BlasterWeaponHitPlayer
-------------------------
*/
void FX_BlasterWeaponHitPlayer( vec3_t origin, vec3_t normal, qboolean humanoid )
{
if ( humanoid )
{
trap_FX_PlayEffectID( cgs.effects.blasterFleshImpactEffect, origin, normal, -1, -1 );
}
else
{
trap_FX_PlayEffectID( cgs.effects.blasterDroidImpactEffect, origin, normal, -1, -1 );
}
}

View File

@@ -0,0 +1,62 @@
// Bowcaster Weapon
#include "cg_local.h"
/*
---------------------------
FX_BowcasterProjectileThink
---------------------------
*/
void FX_BowcasterProjectileThink( centity_t *cent, const struct weaponInfo_s *weapon )
{
vec3_t forward;
if ( VectorNormalize2( cent->currentState.pos.trDelta, forward ) == 0.0f )
{
forward[2] = 1.0f;
}
trap_FX_PlayEffectID( cgs.effects.bowcasterShotEffect, cent->lerpOrigin, forward, -1, -1 );
}
/*
---------------------------
FX_BowcasterHitWall
---------------------------
*/
void FX_BowcasterHitWall( vec3_t origin, vec3_t normal )
{
trap_FX_PlayEffectID( cgs.effects.bowcasterImpactEffect, origin, normal, -1, -1 );
}
/*
---------------------------
FX_BowcasterHitPlayer
---------------------------
*/
void FX_BowcasterHitPlayer( vec3_t origin, vec3_t normal, qboolean humanoid )
{
trap_FX_PlayEffectID( cgs.effects.bowcasterImpactEffect, origin, normal, -1, -1 );
}
/*
------------------------------
FX_BowcasterAltProjectileThink
------------------------------
*/
void FX_BowcasterAltProjectileThink( centity_t *cent, const struct weaponInfo_s *weapon )
{
vec3_t forward;
if ( VectorNormalize2( cent->currentState.pos.trDelta, forward ) == 0.0f )
{
forward[2] = 1.0f;
}
trap_FX_PlayEffectID( cgs.effects.bowcasterShotEffect, cent->lerpOrigin, forward, -1, -1 );
}

View File

@@ -0,0 +1,237 @@
// Bryar Pistol Weapon Effects
#include "cg_local.h"
#include "fx_local.h"
/*
-------------------------
MAIN FIRE
-------------------------
FX_BryarProjectileThink
-------------------------
*/
void FX_BryarProjectileThink( centity_t *cent, const struct weaponInfo_s *weapon )
{
vec3_t forward;
if ( VectorNormalize2( cent->currentState.pos.trDelta, forward ) == 0.0f )
{
forward[2] = 1.0f;
}
trap_FX_PlayEffectID( cgs.effects.bryarShotEffect, cent->lerpOrigin, forward, -1, -1 );
}
/*
-------------------------
FX_BryarHitWall
-------------------------
*/
void FX_BryarHitWall( vec3_t origin, vec3_t normal )
{
trap_FX_PlayEffectID( cgs.effects.bryarWallImpactEffect, origin, normal, -1, -1 );
}
/*
-------------------------
FX_BryarHitPlayer
-------------------------
*/
void FX_BryarHitPlayer( vec3_t origin, vec3_t normal, qboolean humanoid )
{
if ( humanoid )
{
trap_FX_PlayEffectID( cgs.effects.bryarFleshImpactEffect, origin, normal, -1, -1 );
}
else
{
trap_FX_PlayEffectID( cgs.effects.bryarDroidImpactEffect, origin, normal, -1, -1 );
}
}
/*
-------------------------
ALT FIRE
-------------------------
FX_BryarAltProjectileThink
-------------------------
*/
void FX_BryarAltProjectileThink( centity_t *cent, const struct weaponInfo_s *weapon )
{
vec3_t forward;
int t;
if ( VectorNormalize2( cent->currentState.pos.trDelta, forward ) == 0.0f )
{
forward[2] = 1.0f;
}
// see if we have some sort of extra charge going on
for (t = 1; t < cent->currentState.generic1; t++ )
{
// just add ourselves over, and over, and over when we are charged
trap_FX_PlayEffectID( cgs.effects.bryarPowerupShotEffect, cent->lerpOrigin, forward, -1, -1 );
}
// for ( int t = 1; t < cent->gent->count; t++ ) // The single player stores the charge in count, which isn't accessible on the client
trap_FX_PlayEffectID( cgs.effects.bryarShotEffect, cent->lerpOrigin, forward, -1, -1 );
}
/*
-------------------------
FX_BryarAltHitWall
-------------------------
*/
void FX_BryarAltHitWall( vec3_t origin, vec3_t normal, int power )
{
switch( power )
{
case 4:
case 5:
trap_FX_PlayEffectID( cgs.effects.bryarWallImpactEffect3, origin, normal, -1, -1 );
break;
case 2:
case 3:
trap_FX_PlayEffectID( cgs.effects.bryarWallImpactEffect2, origin, normal, -1, -1 );
break;
default:
trap_FX_PlayEffectID( cgs.effects.bryarWallImpactEffect, origin, normal, -1, -1 );
break;
}
}
/*
-------------------------
FX_BryarAltHitPlayer
-------------------------
*/
void FX_BryarAltHitPlayer( vec3_t origin, vec3_t normal, qboolean humanoid )
{
if ( humanoid )
{
trap_FX_PlayEffectID( cgs.effects.bryarFleshImpactEffect, origin, normal, -1, -1 );
}
else
{
trap_FX_PlayEffectID( cgs.effects.bryarDroidImpactEffect, origin, normal, -1, -1 );
}
}
//TURRET
/*
-------------------------
FX_TurretProjectileThink
-------------------------
*/
void FX_TurretProjectileThink( centity_t *cent, const struct weaponInfo_s *weapon )
{
vec3_t forward;
if ( VectorNormalize2( cent->currentState.pos.trDelta, forward ) == 0.0f )
{
forward[2] = 1.0f;
}
trap_FX_PlayEffectID( cgs.effects.turretShotEffect, cent->lerpOrigin, forward, -1, -1 );
}
/*
-------------------------
FX_TurretHitWall
-------------------------
*/
void FX_TurretHitWall( vec3_t origin, vec3_t normal )
{
trap_FX_PlayEffectID( cgs.effects.bryarWallImpactEffect, origin, normal, -1, -1 );
}
/*
-------------------------
FX_TurretHitPlayer
-------------------------
*/
void FX_TurretHitPlayer( vec3_t origin, vec3_t normal, qboolean humanoid )
{
if ( humanoid )
{
trap_FX_PlayEffectID( cgs.effects.bryarFleshImpactEffect, origin, normal, -1, -1 );
}
else
{
trap_FX_PlayEffectID( cgs.effects.bryarDroidImpactEffect, origin, normal, -1, -1 );
}
}
//CONCUSSION (yeah, should probably make a new file for this.. or maybe just move all these stupid semi-redundant fx_ functions into one file)
/*
-------------------------
FX_ConcussionHitWall
-------------------------
*/
void FX_ConcussionHitWall( vec3_t origin, vec3_t normal )
{
trap_FX_PlayEffectID( cgs.effects.concussionImpactEffect, origin, normal, -1, -1 );
}
/*
-------------------------
FX_ConcussionHitPlayer
-------------------------
*/
void FX_ConcussionHitPlayer( vec3_t origin, vec3_t normal, qboolean humanoid )
{
trap_FX_PlayEffectID( cgs.effects.concussionImpactEffect, origin, normal, -1, -1 );
}
/*
-------------------------
FX_ConcussionProjectileThink
-------------------------
*/
void FX_ConcussionProjectileThink( centity_t *cent, const struct weaponInfo_s *weapon )
{
vec3_t forward;
if ( VectorNormalize2( cent->currentState.pos.trDelta, forward ) == 0.0f )
{
forward[2] = 1.0f;
}
trap_FX_PlayEffectID( cgs.effects.concussionShotEffect, cent->lerpOrigin, forward, -1, -1 );
}
/*
---------------------------
FX_ConcAltShot
---------------------------
*/
static vec3_t WHITE ={1.0f,1.0f,1.0f};
static vec3_t BRIGHT={0.75f,0.5f,1.0f};
void FX_ConcAltShot( vec3_t start, vec3_t end )
{
//"concussion/beam"
trap_FX_AddLine( start, end, 0.1f, 10.0f, 0.0f,
1.0f, 0.0f, 0.0f,
WHITE, WHITE, 0.0f,
175, trap_R_RegisterShader( "gfx/effects/blueLine" ),
FX_SIZE_LINEAR | FX_ALPHA_LINEAR );
// add some beef
trap_FX_AddLine( start, end, 0.1f, 7.0f, 0.0f,
1.0f, 0.0f, 0.0f,
BRIGHT, BRIGHT, 0.0f,
150, trap_R_RegisterShader( "gfx/misc/whiteline2" ),
FX_SIZE_LINEAR | FX_ALPHA_LINEAR );
}

259
codemp/cgame/fx_demp2.c Normal file
View File

@@ -0,0 +1,259 @@
// DEMP2 Weapon
#include "cg_local.h"
/*
---------------------------
FX_DEMP2_ProjectileThink
---------------------------
*/
void FX_DEMP2_ProjectileThink( centity_t *cent, const struct weaponInfo_s *weapon )
{
vec3_t forward;
if ( VectorNormalize2( cent->currentState.pos.trDelta, forward ) == 0.0f )
{
forward[2] = 1.0f;
}
trap_FX_PlayEffectID( cgs.effects.demp2ProjectileEffect, cent->lerpOrigin, forward, -1, -1 );
}
/*
---------------------------
FX_DEMP2_HitWall
---------------------------
*/
void FX_DEMP2_HitWall( vec3_t origin, vec3_t normal )
{
trap_FX_PlayEffectID( cgs.effects.demp2WallImpactEffect, origin, normal, -1, -1 );
}
/*
---------------------------
FX_DEMP2_HitPlayer
---------------------------
*/
void FX_DEMP2_HitPlayer( vec3_t origin, vec3_t normal, qboolean humanoid )
{
trap_FX_PlayEffectID( cgs.effects.demp2FleshImpactEffect, origin, normal, -1, -1 );
}
/*
---------------------------
FX_DEMP2_AltBeam
---------------------------
*/
void FX_DEMP2_AltBeam( vec3_t start, vec3_t end, vec3_t normal, //qboolean spark,
vec3_t targ1, vec3_t targ2 )
{
//NOTENOTE Fix this after trap calls for all primitives are created.
/*
vec3_t dir, chaos,
c1, c2,
v1, v2;
float len,
s1, s2, s3;
VectorSubtract( end, start, dir );
len = VectorNormalize( dir );
// Get the base control points, we'll work from there
VectorMA( start, 0.3333f * len, dir, c1 );
VectorMA( start, 0.6666f * len, dir, c2 );
// get some chaos values that really aren't very chaotic :)
s1 = sin( cg->time * 0.005f ) * 2 + crandom() * 0.2f;
s2 = sin( cg->time * 0.001f );
s3 = sin( cg->time * 0.011f );
VectorSet( chaos, len * 0.01f * s1,
len * 0.02f * s2,
len * 0.04f * (s1 + s2 + s3));
VectorAdd( c1, chaos, c1 );
VectorScale( chaos, 4.0f, v1 );
VectorSet( chaos, -len * 0.02f * s3,
len * 0.01f * (s1 * s2),
-len * 0.02f * (s1 + s2 * s3));
VectorAdd( c2, chaos, c2 );
VectorScale( chaos, 2.0f, v2 );
VectorSet( chaos, 1.0f, 1.0f, 1.0f );
FX_AddBezier( start, targ1,
c1, v1, c2, v2,
5.0f + s1 * 2, 8.0f, 0.0f,
1.0f, 0.0f, 0.0f,
chaos, chaos, 0.0f,
1.0f, trap_R_RegisterShader( "gfx/misc/electric2" ), FX_ALPHA_LINEAR );
FX_AddBezier( start, targ1,
c2, v2, c1, v1,
3.0f + s3, 3.0f, 0.0f,
1.0f, 0.0f, 0.0f,
chaos, chaos, 0.0f,
1.0f, trap_R_RegisterShader( "gfx/misc/electric2" ), FX_ALPHA_LINEAR );
s1 = sin( cg->time * 0.0005f ) + crandom() * 0.1f;
s2 = sin( cg->time * 0.0025f );
float cc2 = cos( cg->time * 0.0025f );
s3 = sin( cg->time * 0.01f ) + crandom() * 0.1f;
VectorSet( chaos, len * 0.08f * s2,
len * 0.04f * cc2,//s1 * -s3,
len * 0.06f * s3 );
VectorAdd( c1, chaos, c1 );
VectorScale( chaos, 4.0f, v1 );
VectorSet( chaos, len * 0.02f * s1 * s3,
len * 0.04f * s2,
len * 0.03f * s1 * s2 );
VectorAdd( c2, chaos, c2 );
VectorScale( chaos, 3.0f, v2 );
VectorSet( chaos, 1.0f, 1.0f, 1.0f );
FX_AddBezier( start, targ1,
c1, v1, c2, v2,
4.0f + s3, 8.0f, 0.0f,
1.0f, 0.0f, 0.0f,
chaos, chaos, 0.0f,
1.0f, trap_R_RegisterShader( "gfx/misc/electric2" ), FX_ALPHA_LINEAR );
FX_AddBezier( start, targ1,
c2, v1, c1, v2,
5.0f + s1 * 2, 8.0f, 0.0f,
1.0f, 0.0f, 0.0f,
chaos, chaos, 0.0f,
1.0f, trap_R_RegisterShader( "gfx/misc/electric2" ), FX_ALPHA_LINEAR );
VectorMA( start, 14.0f, dir, c1 );
FX_AddSprite( c1, NULL, NULL, 12.0f + crandom() * 4, 0.0f, 1.0f, 1.0f, random() * 360, 0.0f, 1.0f,
trap_R_RegisterShader( "gfx/misc/lightningFlash" ));
FX_AddSprite( c1, NULL, NULL, 6.0f + crandom() * 2, 0.0f, 1.0f, 1.0f, random() * 360, 0.0f, 1.0f,
trap_R_RegisterShader( "gfx/misc/lightningFlash" ));
FX_AddSprite( targ1, NULL, NULL, 4.0f + crandom(), 0.0f, 1.0f, 0.0f, chaos, chaos, random() * 360, 0.0f, 10,
trap_R_RegisterShader( "gfx/misc/lightningFlash" ));
FX_AddSprite( targ1, NULL, NULL, 8.0f + crandom() * 2, 0.0f, 1.0f, 0.0f, chaos, chaos, random() * 360, 0.0f, 10,
trap_R_RegisterShader( "gfx/misc/lightningFlash" ));
//--------------------------------------------
VectorSubtract( targ2, targ1, dir );
len = VectorNormalize( dir );
// Get the base control points, we'll work from there
VectorMA( targ1, 0.3333f * len, dir, c1 );
VectorMA( targ1, 0.6666f * len, dir, c2 );
// get some chaos values that really aren't very chaotic :)
s1 = sin( cg->time * 0.005f ) * 2 + crandom() * 0.2f;
s2 = sin( cg->time * 0.001f );
s3 = sin( cg->time * 0.011f );
VectorSet( chaos, len * 0.01f * s1,
len * 0.02f * s2,
len * 0.04f * (s1 + s2 + s3));
VectorAdd( c1, chaos, c1 );
VectorScale( chaos, 4.0f, v1 );
VectorSet( chaos, -len * 0.02f * s3,
len * 0.01f * (s1 * s2),
-len * 0.02f * (s1 + s2 * s3));
VectorAdd( c2, chaos, c2 );
VectorScale( chaos, 2.0f, v2 );
VectorSet( chaos, 1.0f, 1.0f, 1.0f );
FX_AddBezier( targ1, targ2,
c1, v1, c2, v2,
5.0f + s1 * 2, 8.0f, 0.0f,
1.0f, 0.0f, 0.0f,
chaos, chaos, 0.0f,
1.0f, trap_R_RegisterShader( "gfx/misc/electric2" ), FX_ALPHA_LINEAR );
FX_AddBezier( targ1, targ2,
c2, v2, c1, v1,
3.0f + s3, 3.0f, 0.0f,
1.0f, 0.0f, 0.0f,
chaos, chaos, 0.0f,
1.0f, trap_R_RegisterShader( "gfx/misc/electric2" ), FX_ALPHA_LINEAR );
s1 = sin( cg->time * 0.0005f ) + crandom() * 0.1f;
s2 = sin( cg->time * 0.0025f );
cc2 = cos( cg->time * 0.0025f );
s3 = sin( cg->time * 0.01f ) + crandom() * 0.1f;
VectorSet( chaos, len * 0.08f * s2,
len * 0.04f * cc2,//s1 * -s3,
len * 0.06f * s3 );
VectorAdd( c1, chaos, c1 );
VectorScale( chaos, 4.0f, v1 );
VectorSet( chaos, len * 0.02f * s1 * s3,
len * 0.04f * s2,
len * 0.03f * s1 * s2 );
VectorAdd( c2, chaos, c2 );
VectorScale( chaos, 3.0f, v2 );
VectorSet( chaos, 1.0f, 1.0f, 1.0f );
FX_AddBezier( targ1, targ2,
c1, v1, c2, v2,
4.0f + s3, 8.0f, 0.0f,
1.0f, 0.0f, 0.0f,
chaos, chaos, 0.0f,
1.0f, trap_R_RegisterShader( "gfx/misc/electric2" ), FX_ALPHA_LINEAR );
FX_AddBezier( targ1, targ2,
c2, v1, c1, v2,
5.0f + s1 * 2, 8.0f, 0.0f,
1.0f, 0.0f, 0.0f,
chaos, chaos, 0.0f,
1.0f, trap_R_RegisterShader( "gfx/misc/electric2" ), FX_ALPHA_LINEAR );
FX_AddSprite( targ2, NULL, NULL, 4.0f + crandom(), 0.0f, 1.0f, 0.0f, chaos, chaos, random() * 360, 0.0f, 10,
trap_R_RegisterShader( "gfx/misc/lightningFlash" ));
FX_AddSprite( targ2, NULL, NULL, 8.0f + crandom() * 2, 0.0f, 1.0f, 0.0f, chaos, chaos, random() * 360, 0.0f, 10,
trap_R_RegisterShader( "gfx/misc/lightningFlash" ));
*/
}
//---------------------------------------------
void FX_DEMP2_AltDetonate( vec3_t org, float size )
{
localEntity_t *ex;
ex = CG_AllocLocalEntity();
ex->leType = LE_FADE_SCALE_MODEL;
memset( &ex->refEntity, 0, sizeof( refEntity_t ));
ex->refEntity.renderfx |= RF_VOLUMETRIC;
ex->startTime = cg->time;
ex->endTime = ex->startTime + 800;//1600;
ex->radius = size;
ex->refEntity.customShader = cgs.media.demp2ShellShader;
ex->refEntity.hModel = cgs.media.demp2Shell;
VectorCopy( org, ex->refEntity.origin );
ex->color[0] = ex->color[1] = ex->color[2] = 255.0f;
}

148
codemp/cgame/fx_disruptor.c Normal file
View File

@@ -0,0 +1,148 @@
// Disruptor Weapon
#include "cg_local.h"
#include "fx_local.h"
/*
---------------------------
FX_DisruptorMainShot
---------------------------
*/
static vec3_t WHITE={1.0f,1.0f,1.0f};
void FX_DisruptorMainShot( vec3_t start, vec3_t end )
{
// vec3_t dir;
// float len;
trap_FX_AddLine( start, end, 0.1f, 6.0f, 0.0f,
1.0f, 0.0f, 0.0f,
WHITE, WHITE, 0.0f,
150, trap_R_RegisterShader( "gfx/effects/redLine" ),
FX_SIZE_LINEAR | FX_ALPHA_LINEAR );
// VectorSubtract( end, start, dir );
// len = VectorNormalize( dir );
// FX_AddCylinder( start, dir, 5.0f, 5.0f, 0.0f,
// 5.0f, 5.0f, 0.0f,
// len, len, 0.0f,
// 1.0f, 1.0f, 0.0f,
// WHITE, WHITE, 0.0f,
// 400, cgi_R_RegisterShader( "gfx/effects/spiral" ), 0 );
}
/*
---------------------------
FX_DisruptorAltShot
---------------------------
*/
void FX_DisruptorAltShot( vec3_t start, vec3_t end, qboolean fullCharge )
{
trap_FX_AddLine( start, end, 0.1f, 10.0f, 0.0f,
1.0f, 0.0f, 0.0f,
WHITE, WHITE, 0.0f,
175, trap_R_RegisterShader( "gfx/effects/redLine" ),
FX_SIZE_LINEAR | FX_ALPHA_LINEAR );
if ( fullCharge )
{
vec3_t YELLER={0.8f,0.7f,0.0f};
// add some beef
trap_FX_AddLine( start, end, 0.1f, 7.0f, 0.0f,
1.0f, 0.0f, 0.0f,
YELLER, YELLER, 0.0f,
150, trap_R_RegisterShader( "gfx/misc/whiteline2" ),
FX_SIZE_LINEAR | FX_ALPHA_LINEAR );
}
}
/*
---------------------------
FX_DisruptorAltMiss
---------------------------
*/
#define FX_ALPHA_WAVE 0x00000008
void FX_DisruptorAltMiss( vec3_t origin, vec3_t normal )
{
vec3_t pos, c1, c2;
addbezierArgStruct_t b;
VectorMA( origin, 4.0f, normal, c1 );
VectorCopy( c1, c2 );
c1[2] += 4;
c2[2] += 12;
VectorAdd( origin, normal, pos );
pos[2] += 28;
/*
FX_AddBezier( origin, pos, c1, vec3_origin, c2, vec3_origin, 6.0f, 6.0f, 0.0f, 0.0f, 0.2f, 0.5f,
WHITE, WHITE, 0.0f, 4000, trap_R_RegisterShader( "gfx/effects/smokeTrail" ), FX_ALPHA_WAVE );
*/
VectorCopy(origin, b.start);
VectorCopy(pos, b.end);
VectorCopy(c1, b.control1);
VectorCopy(vec3_origin, b.control1Vel);
VectorCopy(c2, b.control2);
VectorCopy(vec3_origin, b.control2Vel);
b.size1 = 6.0f;
b.size2 = 6.0f;
b.sizeParm = 0.0f;
b.alpha1 = 0.0f;
b.alpha2 = 0.2f;
b.alphaParm = 0.5f;
VectorCopy(WHITE, b.sRGB);
VectorCopy(WHITE, b.eRGB);
b.rgbParm = 0.0f;
b.killTime = 4000;
b.shader = trap_R_RegisterShader( "gfx/effects/smokeTrail" );
b.flags = FX_ALPHA_WAVE;
trap_FX_AddBezier(&b);
trap_FX_PlayEffectID( cgs.effects.disruptorAltMissEffect, origin, normal, -1, -1 );
}
/*
---------------------------
FX_DisruptorAltHit
---------------------------
*/
void FX_DisruptorAltHit( vec3_t origin, vec3_t normal )
{
trap_FX_PlayEffectID( cgs.effects.disruptorAltHitEffect, origin, normal, -1, -1 );
}
/*
---------------------------
FX_DisruptorHitWall
---------------------------
*/
void FX_DisruptorHitWall( vec3_t origin, vec3_t normal )
{
trap_FX_PlayEffectID( cgs.effects.disruptorWallImpactEffect, origin, normal, -1, -1 );
}
/*
---------------------------
FX_DisruptorHitPlayer
---------------------------
*/
void FX_DisruptorHitPlayer( vec3_t origin, vec3_t normal, qboolean humanoid )
{
trap_FX_PlayEffectID( cgs.effects.disruptorFleshImpactEffect, origin, normal, -1, -1 );
}

View File

@@ -0,0 +1,67 @@
// Golan Arms Flechette Weapon
#include "cg_local.h"
/*
-------------------------
FX_FlechetteProjectileThink
-------------------------
*/
void FX_FlechetteProjectileThink( centity_t *cent, const struct weaponInfo_s *weapon )
{
vec3_t forward;
if ( VectorNormalize2( cent->currentState.pos.trDelta, forward ) == 0.0f )
{
forward[2] = 1.0f;
}
trap_FX_PlayEffectID( cgs.effects.flechetteShotEffect, cent->lerpOrigin, forward, -1, -1 );
}
/*
-------------------------
FX_FlechetteWeaponHitWall
-------------------------
*/
void FX_FlechetteWeaponHitWall( vec3_t origin, vec3_t normal )
{
trap_FX_PlayEffectID( cgs.effects.flechetteWallImpactEffect, origin, normal, -1, -1 );
}
/*
-------------------------
FX_FlechetteWeaponHitPlayer
-------------------------
*/
void FX_FlechetteWeaponHitPlayer( vec3_t origin, vec3_t normal, qboolean humanoid )
{
// if ( humanoid )
// {
trap_FX_PlayEffectID( cgs.effects.flechetteFleshImpactEffect, origin, normal, -1, -1 );
// }
// else
// {
// trap_FX_PlayEffect( "blaster/droid_impact", origin, normal );
// }
}
/*
-------------------------
FX_FlechetteProjectileThink
-------------------------
*/
void FX_FlechetteAltProjectileThink( centity_t *cent, const struct weaponInfo_s *weapon )
{
vec3_t forward;
if ( VectorNormalize2( cent->currentState.pos.trDelta, forward ) == 0.0f )
{
forward[2] = 1.0f;
}
trap_FX_PlayEffectID( cgs.effects.flechetteAltShotEffect, cent->lerpOrigin, forward, -1, -1 );
}

16
codemp/cgame/fx_force.c Normal file
View File

@@ -0,0 +1,16 @@
// Any dedicated force oriented effects
#include "cg_local.h"
/*
-------------------------
FX_ForceDrained
-------------------------
*/
// This effect is not generic because of possible enhancements
void FX_ForceDrained(vec3_t origin, vec3_t dir)
{
VectorScale(dir, -1.0, dir);
trap_FX_PlayEffectID(cgs.effects.forceDrained, origin, dir, -1, -1);
}

View File

@@ -0,0 +1,165 @@
// Heavy Repeater Weapon
#include "cg_local.h"
#ifdef _XBOX
#include "../client/cl_data.h"
#endif
/*
---------------------------
FX_RepeaterProjectileThink
---------------------------
*/
void FX_RepeaterProjectileThink( centity_t *cent, const struct weaponInfo_s *weapon )
{
vec3_t forward;
if ( VectorNormalize2( cent->currentState.pos.trDelta, forward ) == 0.0f )
{
forward[2] = 1.0f;
}
trap_FX_PlayEffectID( cgs.effects.repeaterProjectileEffect, cent->lerpOrigin, forward, -1, -1 );
}
/*
------------------------
FX_RepeaterHitWall
------------------------
*/
void FX_RepeaterHitWall( vec3_t origin, vec3_t normal )
{
trap_FX_PlayEffectID( cgs.effects.repeaterWallImpactEffect, origin, normal, -1, -1 );
}
/*
------------------------
FX_RepeaterHitPlayer
------------------------
*/
void FX_RepeaterHitPlayer( vec3_t origin, vec3_t normal, qboolean humanoid )
{
trap_FX_PlayEffectID( cgs.effects.repeaterFleshImpactEffect, origin, normal, -1, -1 );
}
static void CG_DistortionOrb( centity_t *cent )
{
refEntity_t ent;
vec3_t ang;
float scale = 0.5f;
float vLen;
if (!cg_renderToTextureFX.integer)
{
return;
}
memset( &ent, 0, sizeof( ent ) );
VectorCopy( cent->lerpOrigin, ent.origin );
VectorSubtract(ent.origin, cg->refdef.vieworg, ent.axis[0]);
vLen = VectorLength(ent.axis[0]);
if (VectorNormalize(ent.axis[0]) <= 0.1f)
{ // Entity is right on vieworg. quit.
return;
}
// VectorCopy(cg->refdef.viewaxis[2], ent.axis[2]);
// CrossProduct(ent.axis[0], ent.axis[2], ent.axis[1]);
vectoangles(ent.axis[0], ang);
#ifdef _XBOX
ang[ROLL] = cent->trickAlpha[ClientManager::ActiveClientNum()];
cent->trickAlpha[ClientManager::ActiveClientNum()] += 16; //spin the half-sphere to give a "screwdriver" effect
#else
ang[ROLL] = cent->trickAlpha;
cent->trickAlpha += 16; //spin the half-sphere to give a "screwdriver" effect
#endif
AnglesToAxis(ang, ent.axis);
//radius must be a power of 2, and is the actual captured texture size
if (vLen < 128)
{
ent.radius = 256;
}
else if (vLen < 256)
{
ent.radius = 128;
}
else if (vLen < 512)
{
ent.radius = 64;
}
else
{
ent.radius = 32;
}
VectorScale(ent.axis[0], scale, ent.axis[0]);
VectorScale(ent.axis[1], scale, ent.axis[1]);
VectorScale(ent.axis[2], -scale, ent.axis[2]);
ent.hModel = cgs.media.halfShieldModel;
ent.customShader = 0;//cgs.media.halfShieldShader;
#if 1
ent.renderfx = (RF_DISTORTION|RF_RGB_TINT);
//tint the whole thing a shade of blue
ent.shaderRGBA[0] = 200.0f;
ent.shaderRGBA[1] = 200.0f;
ent.shaderRGBA[2] = 255.0f;
#else //no tint
ent.renderfx = RF_DISTORTION;
#endif
trap_R_AddRefEntityToScene( &ent );
}
/*
------------------------------
FX_RepeaterAltProjectileThink
-----------------------------
*/
void FX_RepeaterAltProjectileThink( centity_t *cent, const struct weaponInfo_s *weapon )
{
vec3_t forward;
if ( VectorNormalize2( cent->currentState.pos.trDelta, forward ) == 0.0f )
{
forward[2] = 1.0f;
}
if (cg_repeaterOrb.integer)
{
CG_DistortionOrb(cent);
}
trap_FX_PlayEffectID( cgs.effects.repeaterAltProjectileEffect, cent->lerpOrigin, forward, -1, -1 );
}
/*
------------------------
FX_RepeaterAltHitWall
------------------------
*/
void FX_RepeaterAltHitWall( vec3_t origin, vec3_t normal )
{
trap_FX_PlayEffectID( cgs.effects.repeaterAltWallImpactEffect, origin, normal, -1, -1 );
}
/*
------------------------
FX_RepeaterAltHitPlayer
------------------------
*/
void FX_RepeaterAltHitPlayer( vec3_t origin, vec3_t normal, qboolean humanoid )
{
trap_FX_PlayEffectID( cgs.effects.repeaterAltWallImpactEffect, origin, normal, -1, -1 );
}

63
codemp/cgame/fx_local.h Normal file
View File

@@ -0,0 +1,63 @@
//
// fx_*.c
//
// NOTENOTE This is not the best, DO NOT CHANGE THESE!
#define FX_ALPHA_LINEAR 0x00000001
#define FX_SIZE_LINEAR 0x00000100
// Bryar
void FX_BryarProjectileThink( centity_t *cent, const struct weaponInfo_s *weapon );
void FX_BryarAltProjectileThink( centity_t *cent, const struct weaponInfo_s *weapon );
void FX_BryarHitWall( vec3_t origin, vec3_t normal );
void FX_BryarAltHitWall( vec3_t origin, vec3_t normal, int power );
void FX_BryarHitPlayer( vec3_t origin, vec3_t normal, qboolean humanoid );
void FX_BryarAltHitPlayer( vec3_t origin, vec3_t normal, qboolean humanoid );
// Blaster
void FX_BlasterProjectileThink( centity_t *cent, const struct weaponInfo_s *weapon );
void FX_BlasterAltFireThink( centity_t *cent, const struct weaponInfo_s *weapon );
void FX_BlasterWeaponHitWall( vec3_t origin, vec3_t normal );
void FX_BlasterWeaponHitPlayer( vec3_t origin, vec3_t normal, qboolean humanoid );
// Disruptor
void FX_DisruptorMainShot( vec3_t start, vec3_t end );
void FX_DisruptorAltShot( vec3_t start, vec3_t end, qboolean fullCharge );
void FX_DisruptorAltMiss( vec3_t origin, vec3_t normal );
void FX_DisruptorAltHit( vec3_t origin, vec3_t normal );
void FX_DisruptorHitWall( vec3_t origin, vec3_t normal );
void FX_DisruptorHitPlayer( vec3_t origin, vec3_t normal, qboolean humanoid );
// Bowcaster
void FX_BowcasterProjectileThink( centity_t *cent, const struct weaponInfo_s *weapon );
void FX_BowcasterAltProjectileThink( centity_t *cent, const struct weaponInfo_s *weapon );
void FX_BowcasterHitWall( vec3_t origin, vec3_t normal );
void FX_BowcasterHitPlayer( vec3_t origin, vec3_t normal, qboolean humanoid );
// Heavy Repeater
void FX_RepeaterProjectileThink( centity_t *cent, const struct weaponInfo_s *weapon );
void FX_RepeaterAltProjectileThink( centity_t *cent, const struct weaponInfo_s *weapon );
void FX_RepeaterHitWall( vec3_t origin, vec3_t normal );
void FX_RepeaterAltHitWall( vec3_t origin, vec3_t normal );
void FX_RepeaterHitPlayer( vec3_t origin, vec3_t normal, qboolean humanoid );
void FX_RepeaterAltHitPlayer( vec3_t origin, vec3_t normal, qboolean humanoid );
// DEMP2
void FX_DEMP2_ProjectileThink( centity_t *cent, const struct weaponInfo_s *weapon );
void FX_DEMP2_HitWall( vec3_t origin, vec3_t normal );
void FX_DEMP2_HitPlayer( vec3_t origin, vec3_t normal, qboolean humanoid );
void FX_DEMP2_AltDetonate( vec3_t org, float size );
// Golan Arms Flechette
void FX_FlechetteProjectileThink( centity_t *cent, const struct weaponInfo_s *weapon );
void FX_FlechetteWeaponHitWall( vec3_t origin, vec3_t normal );
void FX_FlechetteWeaponHitPlayer( vec3_t origin, vec3_t normal, qboolean humanoid );
void FX_FlechetteAltProjectileThink( centity_t *cent, const struct weaponInfo_s *weapon );
// Personal Rocket Launcher
void FX_RocketProjectileThink( centity_t *cent, const struct weaponInfo_s *weapon );
void FX_RocketAltProjectileThink( centity_t *cent, const struct weaponInfo_s *weapon );
void FX_RocketHitWall( vec3_t origin, vec3_t normal );
void FX_RocketHitPlayer( vec3_t origin, vec3_t normal, qboolean humanoid );

View File

@@ -0,0 +1,61 @@
// Rocket Launcher Weapon
#include "cg_local.h"
/*
---------------------------
FX_RocketProjectileThink
---------------------------
*/
void FX_RocketProjectileThink( centity_t *cent, const struct weaponInfo_s *weapon )
{
vec3_t forward;
if ( VectorNormalize2( cent->currentState.pos.trDelta, forward ) == 0.0f )
{
forward[2] = 1.0f;
}
trap_FX_PlayEffectID( cgs.effects.rocketShotEffect, cent->lerpOrigin, forward, -1, -1 );
}
/*
---------------------------
FX_RocketHitWall
---------------------------
*/
void FX_RocketHitWall( vec3_t origin, vec3_t normal )
{
trap_FX_PlayEffectID( cgs.effects.rocketExplosionEffect, origin, normal, -1, -1 );
}
/*
---------------------------
FX_RocketHitPlayer
---------------------------
*/
void FX_RocketHitPlayer( vec3_t origin, vec3_t normal, qboolean humanoid )
{
trap_FX_PlayEffectID( cgs.effects.rocketExplosionEffect, origin, normal, -1, -1 );
}
/*
---------------------------
FX_RocketAltProjectileThink
---------------------------
*/
void FX_RocketAltProjectileThink( centity_t *cent, const struct weaponInfo_s *weapon )
{
vec3_t forward;
if ( VectorNormalize2( cent->currentState.pos.trDelta, forward ) == 0.0f )
{
forward[2] = 1.0f;
}
trap_FX_PlayEffectID( cgs.effects.rocketShotEffect, cent->lerpOrigin, forward, -1, -1 );
}

View File

@@ -0,0 +1,24 @@
#if defined(_XBOX) && defined(_UI)
extern char *HolocronIcons[];
#else
char *HolocronIcons[] = {
"gfx/mp/f_icon_lt_heal", //FP_HEAL,
"gfx/mp/f_icon_levitation", //FP_LEVITATION,
"gfx/mp/f_icon_speed", //FP_SPEED,
"gfx/mp/f_icon_push", //FP_PUSH,
"gfx/mp/f_icon_pull", //FP_PULL,
"gfx/mp/f_icon_lt_telepathy", //FP_TELEPATHY,
"gfx/mp/f_icon_dk_grip", //FP_GRIP,
"gfx/mp/f_icon_dk_l1", //FP_LIGHTNING,
"gfx/mp/f_icon_dk_rage", //FP_RAGE,
"gfx/mp/f_icon_lt_protect", //FP_PROTECT,
"gfx/mp/f_icon_lt_absorb", //FP_ABSORB,
"gfx/mp/f_icon_lt_healother", //FP_TEAM_HEAL,
"gfx/mp/f_icon_dk_forceother", //FP_TEAM_FORCE,
"gfx/mp/f_icon_dk_drain", //FP_DRAIN,
"gfx/mp/f_icon_sight", //FP_SEE,
"gfx/mp/f_icon_saber_attack", //FP_SABER_OFFENSE,
"gfx/mp/f_icon_saber_defend", //FP_SABER_DEFENSE,
"gfx/mp/f_icon_saber_throw" //FP_SABERTHROW
};
#endif

352
codemp/cgame/tr_types.h Normal file
View File

@@ -0,0 +1,352 @@
// Copyright (C) 1999-2000 Id Software, Inc.
//
#ifndef __TR_TYPES_H
#define __TR_TYPES_H
#define MAX_DLIGHTS 32 // can't be increased, because bit flags are used on surfaces
#ifdef _XBOX
#define MAX_ENTITIES 1024 // 11 bits, can't be increased without changing drawsurf bit packing (QSORT_ENTITYNUM_SHIFT)
#else
#define MAX_ENTITIES 2048 // 11 bits, can't be increased without changing drawsurf bit packing (QSORT_ENTITYNUM_SHIFT)
#endif
#define MAX_MINI_ENTITIES 1024
#define TR_WORLDENT (MAX_ENTITIES-1)
// renderfx flags
#define RF_MINLIGHT 0x00001 // allways have some light (viewmodel, some items)
#define RF_THIRD_PERSON 0x00002 // don't draw through eyes, only mirrors (player bodies, chat sprites)
#define RF_FIRST_PERSON 0x00004 // only draw through eyes (view weapon, damage blood blob)
#define RF_DEPTHHACK 0x00008 // for view weapon Z crunching
#define RF_NODEPTH 0x00010 // No depth at all (seeing through walls)
#define RF_VOLUMETRIC 0x00020 // fake volumetric shading
#define RF_NOSHADOW 0x00040 // don't add stencil shadows
#define RF_LIGHTING_ORIGIN 0x00080 // use refEntity->lightingOrigin instead of refEntity->origin
// for lighting. This allows entities to sink into the floor
// with their origin going solid, and allows all parts of a
// player to get the same lighting
#define RF_SHADOW_PLANE 0x00100 // use refEntity->shadowPlane
#define RF_WRAP_FRAMES 0x00200 // mod the model frames by the maxframes to allow continuous
// animation without needing to know the frame count
#define RF_FORCE_ENT_ALPHA 0x00400 // override shader alpha settings
#define RF_RGB_TINT 0x00800 // override shader rgb settings
#define RF_SHADOW_ONLY 0x01000 //add surfs for shadowing but don't draw them -rww
#define RF_DISTORTION 0x02000 //area distortion effect -rww
#define RF_FORKED 0x04000 // override lightning to have forks
#define RF_TAPERED 0x08000 // lightning tapers
#define RF_GROW 0x10000 // lightning grows from start to end during its life
#define RF_DISINTEGRATE1 0x20000 // does a procedural hole-ripping thing.
#define RF_DISINTEGRATE2 0x40000 // does a procedural hole-ripping thing with scaling at the ripping point
#define RF_SETANIMINDEX 0x80000 //use backEnd.currentEntity->e.skinNum for R_BindAnimatedImage
#define RF_ALPHA_DEPTH 0x100000 //depth write on alpha model
#define RF_FORCEPOST 0x200000 //force it to post-render -rww
// refdef flags
#define RDF_NOWORLDMODEL 1 // used for player configuration screen
#define RDF_HYPERSPACE 4 // teleportation effect
#define RDF_SKYBOXPORTAL 8
#define RDF_DRAWSKYBOX 16 // the above marks a scene as being a 'portal sky'. this flag says to draw it or not
#define RDF_AUTOMAP 32 //means this scene is to draw the automap -rww
#define RDF_NOFOG 64 //no global fog in this scene (but still brush fog) -rww
extern int skyboxportal;
extern int drawskyboxportal;
typedef byte color4ub_t[4];
typedef struct {
vec3_t xyz;
float st[2];
byte modulate[4];
} polyVert_t;
typedef struct poly_s {
qhandle_t hShader;
int numVerts;
polyVert_t *verts;
} poly_t;
typedef enum {
RT_MODEL,
RT_POLY,
RT_SPRITE,
RT_ORIENTED_QUAD,
RT_BEAM,
RT_SABER_GLOW,
RT_ELECTRICITY,
RT_PORTALSURFACE, // doesn't draw anything, just info for portals
RT_LINE,
RT_ORIENTEDLINE,
RT_CYLINDER,
RT_ENT_CHAIN,
RT_MAX_REF_ENTITY_TYPE
} refEntityType_t;
typedef struct miniRefEntity_s
{
refEntityType_t reType;
int renderfx;
qhandle_t hModel; // opaque type outside refresh
// most recent data
vec3_t axis[3]; // rotation vectors
qboolean nonNormalizedAxes; // axis are not normalized, i.e. they have scale
vec3_t origin; // also used as MODEL_BEAM's "from"
// previous data for frame interpolation
vec3_t oldorigin; // also used as MODEL_BEAM's "to"
// texturing
qhandle_t customShader; // use one image for the entire thing
// misc
byte shaderRGBA[4]; // colors used by rgbgen entity shaders
vec2_t shaderTexCoord; // texture coordinates used by tcMod entity modifiers
// extra sprite information
float radius;
float rotation; // size 2 for RT_CYLINDER or number of verts in RT_ELECTRICITY
// misc
float shaderTime; // subtracted from refdef time to control effect start times
int frame; // also used as MODEL_BEAM's diameter
} miniRefEntity_t;
#pragma warning (disable : 4201 )
typedef struct {
// this stucture must remain identical as the miniRefEntity_t
//
//
refEntityType_t reType;
int renderfx;
qhandle_t hModel; // opaque type outside refresh
// most recent data
vec3_t axis[3]; // rotation vectors
qboolean nonNormalizedAxes; // axis are not normalized, i.e. they have scale
vec3_t origin; // also used as MODEL_BEAM's "from"
// previous data for frame interpolation
vec3_t oldorigin; // also used as MODEL_BEAM's "to"
// texturing
qhandle_t customShader; // use one image for the entire thing
// misc
byte shaderRGBA[4]; // colors used by rgbgen entity shaders
vec2_t shaderTexCoord; // texture coordinates used by tcMod entity modifiers
// extra sprite information
float radius;
float rotation;
// misc
float shaderTime; // subtracted from refdef time to control effect start times
int frame; // also used as MODEL_BEAM's diameter
//
//
// end miniRefEntity_t
//
//
// specific full refEntity_t data
//
//
// most recent data
vec3_t lightingOrigin; // so multi-part models can be lit identically (RF_LIGHTING_ORIGIN)
float shadowPlane; // projection shadows go here, stencils go slightly lower
// previous data for frame interpolation
int oldframe;
float backlerp; // 0.0 = current, 1.0 = old
// texturing
int skinNum; // inline skin index
qhandle_t customSkin; // NULL for default skin
// texturing
/*
union
{
// int skinNum; // inline skin index
// ivec3_t terxelCoords; // coords of patch for RT_TERXELS
struct
{
int miniStart;
int miniCount;
} uMini;
} uRefEnt;
*/
// extra sprite information
union {
/*
struct
{
float rotation;
float radius;
byte vertRGBA[4][4];
} sprite;
*/
struct
{
float width;
float width2;
float stscale;
} line;
/*
struct // that whole put-the-opening-brace-on-the-same-line-as-the-beginning-of-the-definition coding style is fecal
{
float width;
vec3_t control1;
vec3_t control2;
} bezier;
*/
/*
struct
{
float width;
float width2;
float stscale;
float height;
float bias;
qboolean wrap;
} cylinder;
*/
/*
struct
{
float width;
float deviation;
float stscale;
qboolean wrap;
qboolean taper;
} electricity;
*/
} data;
float endTime;
float saberLength;
/*
Ghoul2 Insert Start
*/
vec3_t angles; // rotation angles - used for Ghoul2
vec3_t modelScale; // axis scale for models
// CGhoul2Info_v *ghoul2; // has to be at the end of the ref-ent in order for it to be created properly
void *ghoul2; // has to be at the end of the ref-ent in order for it to be created properly
/*
Ghoul2 Insert End
*/
#ifdef _XBOX
bool skipForPlayer2;
#endif
} refEntity_t;
#define MAX_RENDER_STRINGS 8
#define MAX_RENDER_STRING_LENGTH 32
typedef struct {
int x, y, width, height;
float fov_x, fov_y;
vec3_t vieworg;
vec3_t viewangles;
vec3_t viewaxis[3]; // transformation matrix
int viewContents; // world contents at vieworg
// time in milliseconds for shader effects and other time dependent rendering issues
int time;
int rdflags; // RDF_NOWORLDMODEL, etc
// 1 bits will prevent the associated area from rendering at all
byte areamask[MAX_MAP_AREA_BYTES];
// text messages for deform text shaders
char text[MAX_RENDER_STRINGS][MAX_RENDER_STRING_LENGTH];
} refdef_t;
typedef enum {
STEREO_CENTER,
STEREO_LEFT,
STEREO_RIGHT
};
typedef int stereoFrame_t;
/*
** glconfig_t
**
** Contains variables specific to the OpenGL configuration
** being run right now. These are constant once the OpenGL
** subsystem is initialized.
*/
typedef enum {
TC_NONE,
TC_S3TC,
TC_S3TC_DXT
} textureCompression_t;
typedef struct {
const char *renderer_string;
const char *vendor_string;
const char *version_string;
const char *extensions_string;
int maxTextureSize; // queried from GL
int maxActiveTextures; // multitexture ability
float maxTextureFilterAnisotropy;
int colorBits, depthBits, stencilBits;
qboolean deviceSupportsGamma;
textureCompression_t textureCompression;
qboolean textureEnvAddAvailable;
qboolean clampToEdgeAvailable;
int vidWidth, vidHeight;
int displayFrequency;
// synonymous with "does rendering consume the entire screen?", therefore
// a Voodoo or Voodoo2 will have this set to TRUE, as will a Win32 ICD that
// used CDS.
qboolean isFullscreen;
qboolean stereoEnabled;
} glconfig_t;
#if !defined _WIN32
#define OPENGL_DRIVER_NAME "libGL.so"
#else
#define OPENGL_DRIVER_NAME "opengl32"
#endif // !defined _WIN32
#endif // __TR_TYPES_H